1 | //===-- TypeSystem.h ------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_SYMBOL_TYPESYSTEM_H |
10 | #define LLDB_SYMBOL_TYPESYSTEM_H |
11 | |
12 | #include <functional> |
13 | #include <mutex> |
14 | #include <optional> |
15 | #include <string> |
16 | |
17 | #include "llvm/ADT/APFloat.h" |
18 | #include "llvm/ADT/APSInt.h" |
19 | #include "llvm/ADT/DenseMap.h" |
20 | #include "llvm/ADT/SmallBitVector.h" |
21 | #include "llvm/Support/Casting.h" |
22 | #include "llvm/Support/Error.h" |
23 | #include "llvm/Support/JSON.h" |
24 | |
25 | #include "lldb/Core/PluginInterface.h" |
26 | #include "lldb/Expression/Expression.h" |
27 | #include "lldb/Symbol/CompilerDecl.h" |
28 | #include "lldb/Symbol/CompilerDeclContext.h" |
29 | #include "lldb/Symbol/Type.h" |
30 | #include "lldb/lldb-private.h" |
31 | |
32 | class PDBASTParser; |
33 | |
34 | namespace lldb_private { |
35 | |
36 | namespace plugin { |
37 | namespace dwarf { |
38 | class DWARFDIE; |
39 | class DWARFASTParser; |
40 | } // namespace dwarf |
41 | } // namespace plugin |
42 | |
43 | namespace npdb { |
44 | class PdbAstBuilder; |
45 | } // namespace npdb |
46 | |
47 | /// Interface for representing a type system. |
48 | /// |
49 | /// Implemented by language plugins to define the type system for a given |
50 | /// language. |
51 | /// |
52 | /// This interface extensively used opaque pointers to prevent that generic |
53 | /// LLDB code has dependencies on language plugins. The type and semantics of |
54 | /// these opaque pointers are defined by the TypeSystem implementation inside |
55 | /// the respective language plugin. Opaque pointers from one TypeSystem |
56 | /// instance should never be passed to a different TypeSystem instance (even |
57 | /// when the language plugin for both TypeSystem instances is the same). |
58 | /// |
59 | /// Most of the functions in this class should not be called directly but only |
60 | /// called by their respective counterparts in CompilerType, CompilerDecl and |
61 | /// CompilerDeclContext. |
62 | /// |
63 | /// \see lldb_private::CompilerType |
64 | /// \see lldb_private::CompilerDecl |
65 | /// \see lldb_private::CompilerDeclContext |
66 | class TypeSystem : public PluginInterface, |
67 | public std::enable_shared_from_this<TypeSystem> { |
68 | public: |
69 | // Constructors and Destructors |
70 | TypeSystem(); |
71 | ~TypeSystem() override; |
72 | |
73 | // LLVM RTTI support |
74 | virtual bool isA(const void *ClassID) const = 0; |
75 | |
76 | static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, |
77 | Module *module); |
78 | |
79 | static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, |
80 | Target *target); |
81 | |
82 | /// Free up any resources associated with this TypeSystem. Done before |
83 | /// removing all the TypeSystems from the TypeSystemMap. |
84 | virtual void Finalize() {} |
85 | |
86 | virtual plugin::dwarf::DWARFASTParser *GetDWARFParser() { return nullptr; } |
87 | |
88 | virtual PDBASTParser *GetPDBParser() { return nullptr; } |
89 | virtual npdb::PdbAstBuilder *GetNativePDBParser() { return nullptr; } |
90 | |
91 | virtual SymbolFile *GetSymbolFile() const { return m_sym_file; } |
92 | |
93 | virtual void SetSymbolFile(SymbolFile *sym_file) { m_sym_file = sym_file; } |
94 | |
95 | // CompilerDecl functions |
96 | virtual ConstString DeclGetName(void *opaque_decl) = 0; |
97 | |
98 | virtual ConstString DeclGetMangledName(void *opaque_decl); |
99 | |
100 | virtual CompilerDeclContext DeclGetDeclContext(void *opaque_decl); |
101 | |
102 | virtual CompilerType DeclGetFunctionReturnType(void *opaque_decl); |
103 | |
104 | virtual size_t DeclGetFunctionNumArguments(void *opaque_decl); |
105 | |
106 | virtual CompilerType DeclGetFunctionArgumentType(void *opaque_decl, |
107 | size_t arg_idx); |
108 | |
109 | virtual std::vector<lldb_private::CompilerContext> |
110 | DeclGetCompilerContext(void *opaque_decl); |
111 | |
112 | virtual CompilerType GetTypeForDecl(void *opaque_decl) = 0; |
113 | |
114 | // CompilerDeclContext functions |
115 | |
116 | virtual std::vector<CompilerDecl> |
117 | DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, |
118 | const bool ignore_imported_decls); |
119 | |
120 | virtual ConstString DeclContextGetName(void *opaque_decl_ctx) = 0; |
121 | |
122 | virtual ConstString |
123 | DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) = 0; |
124 | |
125 | virtual bool DeclContextIsClassMethod(void *opaque_decl_ctx) = 0; |
126 | |
127 | virtual bool DeclContextIsContainedInLookup(void *opaque_decl_ctx, |
128 | void *other_opaque_decl_ctx) = 0; |
129 | |
130 | virtual lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) = 0; |
131 | |
132 | /// Returns the direct parent context of specified type |
133 | virtual CompilerDeclContext |
134 | GetCompilerDeclContextForType(const CompilerType &type); |
135 | |
136 | virtual std::vector<lldb_private::CompilerContext> |
137 | DeclContextGetCompilerContext(void *opaque_decl_ctx); |
138 | |
139 | // Tests |
140 | #ifndef NDEBUG |
141 | /// Verify the integrity of the type to catch CompilerTypes that mix |
142 | /// and match invalid TypeSystem/Opaque type pairs. |
143 | virtual bool Verify(lldb::opaque_compiler_type_t type) = 0; |
144 | #endif |
145 | |
146 | virtual bool IsArrayType(lldb::opaque_compiler_type_t type, |
147 | CompilerType *element_type, uint64_t *size, |
148 | bool *is_incomplete) = 0; |
149 | |
150 | virtual bool IsAggregateType(lldb::opaque_compiler_type_t type) = 0; |
151 | |
152 | virtual bool IsAnonymousType(lldb::opaque_compiler_type_t type); |
153 | |
154 | virtual bool IsCharType(lldb::opaque_compiler_type_t type) = 0; |
155 | |
156 | virtual bool IsCompleteType(lldb::opaque_compiler_type_t type) = 0; |
157 | |
158 | virtual bool IsDefined(lldb::opaque_compiler_type_t type) = 0; |
159 | |
160 | virtual bool IsFloatingPointType(lldb::opaque_compiler_type_t type, |
161 | uint32_t &count, bool &is_complex) = 0; |
162 | |
163 | virtual bool IsFunctionType(lldb::opaque_compiler_type_t type) = 0; |
164 | |
165 | virtual size_t |
166 | GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) = 0; |
167 | |
168 | virtual CompilerType |
169 | GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, |
170 | const size_t index) = 0; |
171 | |
172 | virtual bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) = 0; |
173 | |
174 | virtual bool |
175 | IsMemberFunctionPointerType(lldb::opaque_compiler_type_t type) = 0; |
176 | |
177 | virtual bool IsBlockPointerType(lldb::opaque_compiler_type_t type, |
178 | CompilerType *function_pointer_type_ptr) = 0; |
179 | |
180 | virtual bool IsIntegerType(lldb::opaque_compiler_type_t type, |
181 | bool &is_signed) = 0; |
182 | |
183 | virtual bool IsEnumerationType(lldb::opaque_compiler_type_t type, |
184 | bool &is_signed) { |
185 | is_signed = false; |
186 | return false; |
187 | } |
188 | |
189 | virtual bool IsScopedEnumerationType(lldb::opaque_compiler_type_t type) = 0; |
190 | |
191 | virtual bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, |
192 | CompilerType *target_type, // Can pass NULL |
193 | bool check_cplusplus, bool check_objc) = 0; |
194 | |
195 | virtual bool IsPointerType(lldb::opaque_compiler_type_t type, |
196 | CompilerType *pointee_type) = 0; |
197 | |
198 | virtual bool IsScalarType(lldb::opaque_compiler_type_t type) = 0; |
199 | |
200 | virtual bool IsVoidType(lldb::opaque_compiler_type_t type) = 0; |
201 | |
202 | virtual bool CanPassInRegisters(const CompilerType &type) = 0; |
203 | |
204 | // TypeSystems can support more than one language |
205 | virtual bool SupportsLanguage(lldb::LanguageType language) = 0; |
206 | |
207 | // Type Completion |
208 | |
209 | virtual bool GetCompleteType(lldb::opaque_compiler_type_t type) = 0; |
210 | |
211 | virtual bool IsForcefullyCompleted(lldb::opaque_compiler_type_t type) { |
212 | return false; |
213 | } |
214 | |
215 | // AST related queries |
216 | |
217 | virtual uint32_t GetPointerByteSize() = 0; |
218 | |
219 | // Accessors |
220 | |
221 | virtual ConstString GetTypeName(lldb::opaque_compiler_type_t type, |
222 | bool BaseOnly) = 0; |
223 | |
224 | virtual ConstString GetDisplayTypeName(lldb::opaque_compiler_type_t type) = 0; |
225 | |
226 | virtual uint32_t |
227 | GetTypeInfo(lldb::opaque_compiler_type_t type, |
228 | CompilerType *pointee_or_element_compiler_type) = 0; |
229 | |
230 | virtual lldb::LanguageType |
231 | GetMinimumLanguage(lldb::opaque_compiler_type_t type) = 0; |
232 | |
233 | virtual lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) = 0; |
234 | |
235 | // Creating related types |
236 | |
237 | virtual CompilerType |
238 | GetArrayElementType(lldb::opaque_compiler_type_t type, |
239 | ExecutionContextScope *exe_scope) = 0; |
240 | |
241 | virtual CompilerType GetArrayType(lldb::opaque_compiler_type_t type, |
242 | uint64_t size); |
243 | |
244 | virtual CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) = 0; |
245 | |
246 | virtual CompilerType |
247 | GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) = 0; |
248 | |
249 | // Returns -1 if this isn't a function of if the function doesn't have a |
250 | // prototype Returns a value >= 0 if there is a prototype. |
251 | virtual int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) = 0; |
252 | |
253 | virtual CompilerType |
254 | GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, |
255 | size_t idx) = 0; |
256 | |
257 | virtual CompilerType |
258 | GetFunctionReturnType(lldb::opaque_compiler_type_t type) = 0; |
259 | |
260 | virtual size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) = 0; |
261 | |
262 | virtual TypeMemberFunctionImpl |
263 | GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx) = 0; |
264 | |
265 | virtual CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) = 0; |
266 | |
267 | virtual CompilerType GetPointerType(lldb::opaque_compiler_type_t type) = 0; |
268 | |
269 | virtual CompilerType |
270 | GetLValueReferenceType(lldb::opaque_compiler_type_t type); |
271 | |
272 | virtual CompilerType |
273 | GetRValueReferenceType(lldb::opaque_compiler_type_t type); |
274 | |
275 | virtual CompilerType GetAtomicType(lldb::opaque_compiler_type_t type); |
276 | |
277 | virtual CompilerType AddConstModifier(lldb::opaque_compiler_type_t type); |
278 | |
279 | virtual CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type); |
280 | |
281 | virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type); |
282 | |
283 | /// \param opaque_payload The m_payload field of Type, which may |
284 | /// carry TypeSystem-specific extra information. |
285 | virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, |
286 | const char *name, |
287 | const CompilerDeclContext &decl_ctx, |
288 | uint32_t opaque_payload); |
289 | |
290 | // Exploring the type |
291 | |
292 | virtual const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) = 0; |
293 | |
294 | virtual std::optional<uint64_t> |
295 | GetBitSize(lldb::opaque_compiler_type_t type, |
296 | ExecutionContextScope *exe_scope) = 0; |
297 | |
298 | virtual lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, |
299 | uint64_t &count) = 0; |
300 | |
301 | virtual lldb::Format GetFormat(lldb::opaque_compiler_type_t type) = 0; |
302 | |
303 | virtual uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, |
304 | bool omit_empty_base_classes, |
305 | const ExecutionContext *exe_ctx) = 0; |
306 | |
307 | virtual CompilerType GetBuiltinTypeByName(ConstString name); |
308 | |
309 | virtual lldb::BasicType |
310 | GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) = 0; |
311 | |
312 | virtual void ForEachEnumerator( |
313 | lldb::opaque_compiler_type_t type, |
314 | std::function<bool(const CompilerType &integer_type, |
315 | ConstString name, |
316 | const llvm::APSInt &value)> const &callback) {} |
317 | |
318 | virtual uint32_t GetNumFields(lldb::opaque_compiler_type_t type) = 0; |
319 | |
320 | virtual CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, |
321 | size_t idx, std::string &name, |
322 | uint64_t *bit_offset_ptr, |
323 | uint32_t *bitfield_bit_size_ptr, |
324 | bool *is_bitfield_ptr) = 0; |
325 | |
326 | virtual uint32_t |
327 | GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) = 0; |
328 | |
329 | virtual uint32_t |
330 | GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) = 0; |
331 | |
332 | virtual CompilerType |
333 | GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, |
334 | uint32_t *bit_offset_ptr) = 0; |
335 | |
336 | virtual CompilerType |
337 | GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, |
338 | uint32_t *bit_offset_ptr) = 0; |
339 | |
340 | virtual CompilerType GetChildCompilerTypeAtIndex( |
341 | lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, |
342 | bool transparent_pointers, bool omit_empty_base_classes, |
343 | bool ignore_array_bounds, std::string &child_name, |
344 | uint32_t &child_byte_size, int32_t &child_byte_offset, |
345 | uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, |
346 | bool &child_is_base_class, bool &child_is_deref_of_parent, |
347 | ValueObject *valobj, uint64_t &language_flags) = 0; |
348 | |
349 | // Lookup a child given a name. This function will match base class names and |
350 | // member member names in "clang_type" only, not descendants. |
351 | virtual uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, |
352 | llvm::StringRef name, |
353 | bool omit_empty_base_classes) = 0; |
354 | |
355 | // Lookup a child member given a name. This function will match member names |
356 | // only and will descend into "clang_type" children in search for the first |
357 | // member in this class, or any base class that matches "name". |
358 | // TODO: Return all matches for a given name by returning a |
359 | // vector<vector<uint32_t>> |
360 | // so we catch all names that match a given child name, not just the first. |
361 | virtual size_t GetIndexOfChildMemberWithName( |
362 | lldb::opaque_compiler_type_t type, llvm::StringRef name, |
363 | bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) = 0; |
364 | |
365 | virtual bool IsTemplateType(lldb::opaque_compiler_type_t type); |
366 | |
367 | virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type, |
368 | bool expand_pack); |
369 | |
370 | virtual lldb::TemplateArgumentKind |
371 | GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx, |
372 | bool expand_pack); |
373 | virtual CompilerType |
374 | GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, |
375 | bool expand_pack); |
376 | virtual std::optional<CompilerType::IntegralTemplateArgument> |
377 | GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, |
378 | bool expand_pack); |
379 | |
380 | // Dumping types |
381 | |
382 | #ifndef NDEBUG |
383 | /// Convenience LLVM-style dump method for use in the debugger only. |
384 | LLVM_DUMP_METHOD virtual void |
385 | dump(lldb::opaque_compiler_type_t type) const = 0; |
386 | #endif |
387 | |
388 | virtual bool (lldb::opaque_compiler_type_t type, Stream &s, |
389 | lldb::Format format, const DataExtractor &data, |
390 | lldb::offset_t data_offset, size_t data_byte_size, |
391 | uint32_t bitfield_bit_size, |
392 | uint32_t bitfield_bit_offset, |
393 | ExecutionContextScope *exe_scope) = 0; |
394 | |
395 | /// Dump the type to stdout. |
396 | virtual void DumpTypeDescription( |
397 | lldb::opaque_compiler_type_t type, |
398 | lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) = 0; |
399 | |
400 | /// Print a description of the type to a stream. The exact implementation |
401 | /// varies, but the expectation is that eDescriptionLevelFull returns a |
402 | /// source-like representation of the type, whereas eDescriptionLevelVerbose |
403 | /// does a dump of the underlying AST if applicable. |
404 | virtual void DumpTypeDescription( |
405 | lldb::opaque_compiler_type_t type, Stream &s, |
406 | lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) = 0; |
407 | |
408 | /// Dump a textual representation of the internal TypeSystem state to the |
409 | /// given stream. |
410 | /// |
411 | /// This should not modify the state of the TypeSystem if possible. |
412 | virtual void Dump(llvm::raw_ostream &output) = 0; |
413 | |
414 | /// This is used by swift. |
415 | virtual bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) = 0; |
416 | |
417 | // TODO: Determine if these methods should move to TypeSystemClang. |
418 | |
419 | virtual bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, |
420 | CompilerType *pointee_type) = 0; |
421 | |
422 | virtual unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) = 0; |
423 | |
424 | virtual std::optional<size_t> |
425 | GetTypeBitAlign(lldb::opaque_compiler_type_t type, |
426 | ExecutionContextScope *exe_scope) = 0; |
427 | |
428 | virtual CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) = 0; |
429 | |
430 | virtual CompilerType CreateGenericFunctionPrototype() { |
431 | return CompilerType(); |
432 | } |
433 | |
434 | virtual CompilerType |
435 | GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, |
436 | size_t bit_size) = 0; |
437 | |
438 | virtual bool IsBeingDefined(lldb::opaque_compiler_type_t type) = 0; |
439 | |
440 | virtual bool IsConst(lldb::opaque_compiler_type_t type) = 0; |
441 | |
442 | virtual uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, |
443 | CompilerType *base_type_ptr) = 0; |
444 | |
445 | virtual bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) = 0; |
446 | |
447 | virtual bool IsTypedefType(lldb::opaque_compiler_type_t type) = 0; |
448 | |
449 | // If the current object represents a typedef type, get the underlying type |
450 | virtual CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) = 0; |
451 | |
452 | virtual bool IsVectorType(lldb::opaque_compiler_type_t type, |
453 | CompilerType *element_type, uint64_t *size) = 0; |
454 | |
455 | virtual CompilerType |
456 | GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) = 0; |
457 | |
458 | virtual CompilerType |
459 | GetNonReferenceType(lldb::opaque_compiler_type_t type) = 0; |
460 | |
461 | virtual bool IsReferenceType(lldb::opaque_compiler_type_t type, |
462 | CompilerType *pointee_type, bool *is_rvalue) = 0; |
463 | |
464 | virtual bool |
465 | ShouldTreatScalarValueAsAddress(lldb::opaque_compiler_type_t type) { |
466 | return IsPointerOrReferenceType(type, pointee_type: nullptr); |
467 | } |
468 | |
469 | virtual UserExpression * |
470 | GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix, |
471 | lldb::LanguageType language, |
472 | Expression::ResultType desired_type, |
473 | const EvaluateExpressionOptions &options, |
474 | ValueObject *ctx_obj) { |
475 | return nullptr; |
476 | } |
477 | |
478 | virtual FunctionCaller *GetFunctionCaller(const CompilerType &return_type, |
479 | const Address &function_address, |
480 | const ValueList &arg_value_list, |
481 | const char *name) { |
482 | return nullptr; |
483 | } |
484 | |
485 | virtual std::unique_ptr<UtilityFunction> |
486 | CreateUtilityFunction(std::string text, std::string name); |
487 | |
488 | virtual PersistentExpressionState *GetPersistentExpressionState() { |
489 | return nullptr; |
490 | } |
491 | |
492 | virtual CompilerType GetTypeForFormatters(void *type); |
493 | |
494 | virtual LazyBool ShouldPrintAsOneLiner(void *type, ValueObject *valobj); |
495 | |
496 | // Type systems can have types that are placeholder types, which are meant to |
497 | // indicate the presence of a type, but offer no actual information about |
498 | // said types, and leave the burden of actually figuring type information out |
499 | // to dynamic type resolution. For instance a language with a generics |
500 | // system, can use placeholder types to indicate "type argument goes here", |
501 | // without promising uniqueness of the placeholder, nor attaching any |
502 | // actually idenfiable information to said placeholder. This API allows type |
503 | // systems to tell LLDB when such a type has been encountered In response, |
504 | // the debugger can react by not using this type as a cache entry in any |
505 | // type-specific way For instance, LLDB will currently not cache any |
506 | // formatters that are discovered on such a type as attributable to the |
507 | // meaningless type itself, instead preferring to use the dynamic type |
508 | virtual bool IsMeaninglessWithoutDynamicResolution(void *type); |
509 | |
510 | virtual std::optional<llvm::json::Value> ReportStatistics(); |
511 | |
512 | bool GetHasForcefullyCompletedTypes() const { |
513 | return m_has_forcefully_completed_types; |
514 | } |
515 | protected: |
516 | SymbolFile *m_sym_file = nullptr; |
517 | /// Used for reporting statistics. |
518 | bool m_has_forcefully_completed_types = false; |
519 | }; |
520 | |
521 | class TypeSystemMap { |
522 | public: |
523 | TypeSystemMap(); |
524 | ~TypeSystemMap(); |
525 | |
526 | // Clear calls Finalize on all the TypeSystems managed by this map, and then |
527 | // empties the map. |
528 | void Clear(); |
529 | |
530 | // Iterate through all of the type systems that are created. Return true from |
531 | // callback to keep iterating, false to stop iterating. |
532 | void ForEach(std::function<bool(lldb::TypeSystemSP)> const &callback); |
533 | |
534 | llvm::Expected<lldb::TypeSystemSP> |
535 | GetTypeSystemForLanguage(lldb::LanguageType language, Module *module, |
536 | bool can_create); |
537 | |
538 | llvm::Expected<lldb::TypeSystemSP> |
539 | GetTypeSystemForLanguage(lldb::LanguageType language, Target *target, |
540 | bool can_create); |
541 | |
542 | /// Check all type systems in the map to see if any have forcefully completed |
543 | /// types; |
544 | bool GetHasForcefullyCompletedTypes() const; |
545 | protected: |
546 | typedef llvm::DenseMap<uint16_t, lldb::TypeSystemSP> collection; |
547 | mutable std::mutex m_mutex; ///< A mutex to keep this object happy in |
548 | /// multi-threaded environments. |
549 | collection m_map; |
550 | bool m_clear_in_progress = false; |
551 | |
552 | private: |
553 | typedef llvm::function_ref<lldb::TypeSystemSP()> CreateCallback; |
554 | /// Finds the type system for the given language. If no type system could be |
555 | /// found for a language and a CreateCallback was provided, the value |
556 | /// returned by the callback will be treated as the TypeSystem for the |
557 | /// language. |
558 | /// |
559 | /// \param language The language for which the type system should be found. |
560 | /// \param create_callback A callback that will be called if no previously |
561 | /// created TypeSystem that fits the given language |
562 | /// could found. Can be omitted if a non-existent |
563 | /// type system should be treated as an error |
564 | /// instead. |
565 | /// \return The found type system or an error. |
566 | llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage( |
567 | lldb::LanguageType language, |
568 | std::optional<CreateCallback> create_callback = std::nullopt); |
569 | }; |
570 | |
571 | } // namespace lldb_private |
572 | |
573 | #endif // LLDB_SYMBOL_TYPESYSTEM_H |
574 | |