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