xref: /llvm-project/lldb/include/lldb/Symbol/Type.h (revision d6b90282578f607dc18e23197d9494ebbb899437)
1 //===-- Type.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_TYPE_H
10 #define LLDB_SYMBOL_TYPE_H
11 
12 #include "lldb/Core/Declaration.h"
13 #include "lldb/Symbol/CompilerDecl.h"
14 #include "lldb/Symbol/CompilerType.h"
15 #include "lldb/Symbol/TypeList.h"
16 #include "lldb/Symbol/TypeMap.h"
17 #include "lldb/Symbol/TypeSystem.h"
18 #include "lldb/Utility/ConstString.h"
19 #include "lldb/Utility/UserID.h"
20 #include "lldb/lldb-private.h"
21 
22 #include "llvm/ADT/APSInt.h"
23 #include "llvm/ADT/DenseSet.h"
24 #include "llvm/ADT/STLForwardCompat.h"
25 #include "llvm/Support/raw_ostream.h"
26 
27 #include <optional>
28 #include <set>
29 
30 namespace lldb_private {
31 class SymbolFileCommon;
32 
33 /// A SmallBitVector that represents a set of source languages (\p
34 /// lldb::LanguageType).  Each lldb::LanguageType is represented by
35 /// the bit with the position of its enumerator. The largest
36 /// LanguageType is < 64, so this is space-efficient and on 64-bit
37 /// architectures a LanguageSet can be completely stack-allocated.
38 struct LanguageSet {
39   llvm::SmallBitVector bitvector;
40   LanguageSet();
41 
42   /// If the set contains a single language only, return it.
43   std::optional<lldb::LanguageType> GetSingularLanguage();
44   void Insert(lldb::LanguageType language);
45   bool Empty() const;
46   size_t Size() const;
47   bool operator[](unsigned i) const;
48 };
49 
50 /// CompilerContext allows an array of these items to be passed to perform
51 /// detailed lookups in SymbolVendor and SymbolFile functions.
52 struct CompilerContext {
53   CompilerContext(CompilerContextKind t, ConstString n) : kind(t), name(n) {}
54 
55   bool operator==(const CompilerContext &rhs) const {
56     return kind == rhs.kind && name == rhs.name;
57   }
58   bool operator!=(const CompilerContext &rhs) const { return !(*this == rhs); }
59 
60   void Dump(Stream &s) const;
61 
62   CompilerContextKind kind;
63   ConstString name;
64 };
65 llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
66                               const CompilerContext &rhs);
67 
68 FLAGS_ENUM(TypeQueryOptions){
69     e_none = 0u,
70     /// If set, TypeQuery::m_context contains an exact context that must match
71     /// the full context. If not set, TypeQuery::m_context can contain a partial
72     /// type match where the full context isn't fully specified.
73     e_exact_match = (1u << 0),
74     /// If set, TypeQuery::m_context is a clang module compiler context. If not
75     /// set TypeQuery::m_context is normal type lookup context.
76     e_module_search = (1u << 1),
77     /// If set, the query will ignore all Module entries in the type context,
78     /// even for exact matches.
79     e_ignore_modules = (1u << 2),
80     /// If set, all anonymous namespaces in the context must be matched exactly
81     /// by the pattern. Otherwise, superfluous namespaces are skipped.
82     e_strict_namespaces = (1u << 3),
83     /// When true, the find types call should stop the query as soon as a single
84     /// matching type is found. When false, the type query should find all
85     /// matching types.
86     e_find_one = (1u << 4),
87     // If set, treat TypeQuery::m_name as a mangled name that should be
88     // searched.
89     e_search_by_mangled_name = (1u << 5),
90 };
91 LLDB_MARK_AS_BITMASK_ENUM(TypeQueryOptions)
92 
93 /// A class that contains all state required for type lookups.
94 ///
95 /// Using a TypeQuery class for matching types simplifies the internal APIs we
96 /// need to implement type lookups in LLDB. Type lookups can fully specify the
97 /// exact typename by filling out a complete or partial CompilerContext array.
98 /// This technique allows for powerful searches and also allows the SymbolFile
99 /// classes to use the m_context array to lookup types by basename, then
100 /// eliminate potential matches without having to resolve types into each
101 /// TypeSystem. This makes type lookups vastly more efficient and allows the
102 /// SymbolFile objects to stop looking up types when the type matching is
103 /// complete, like if we are looking for only a single type in our search.
104 class TypeQuery {
105 public:
106   TypeQuery() = delete;
107 
108   /// Construct a type match object using a fully- or partially-qualified name.
109   ///
110   /// The specified \a type_name will be chopped up and the m_context will be
111   /// populated by separating the string by looking for "::". We do this because
112   /// symbol files have indexes that contain only the type's basename. This also
113   /// allows symbol files to efficiently not realize types that don't match the
114   /// specified context. Example of \a type_name values that can be specified
115   /// include:
116   ///   "foo": Look for any type whose basename matches "foo".
117   ///     If \a exact_match is true, then the type can't be contained in any
118   ///     declaration context like a namespace, class, or other containing
119   ///     scope.
120   ///     If \a exact match is false, then we will find all matches including
121   ///     ones that are contained in other declaration contexts, including top
122   ///     level types.
123   ///   "foo::bar": Look for any type whose basename matches "bar" but make sure
124   ///     its parent declaration context is any named declaration context
125   ///     (namespace, class, struct, etc) whose name matches "foo".
126   ///     If \a exact_match is true, then the "foo" declaration context must
127   ///     appear at the source file level or inside of a function.
128   ///     If \a exact match is false, then the "foo" declaration context can
129   ///     be contained in any other declaration contexts.
130   ///   "class foo": Only match types that are classes whose basename matches
131   ///     "foo".
132   ///   "struct foo": Only match types that are structures whose basename
133   ///     matches "foo".
134   ///   "class foo::bar": Only match types that are classes whose basename
135   ///     matches "bar" and that are contained in any named declaration context
136   ///     named "foo".
137   ///
138   /// \param[in] type_name
139   ///   A fully- or partially-qualified type name. This name will be parsed and
140   ///   broken up and the m_context will be populated with the various parts of
141   ///   the name. This typename can be prefixed with "struct ", "class ",
142   ///   "union", "enum " or "typedef " before the actual type name to limit the
143   ///   results of the types that match. The declaration context can be
144   ///   specified with the "::" string. For example, "a::b::my_type".
145   ///
146   /// \param[in] options A set of boolean enumeration flags from the
147   ///   TypeQueryOptions enumerations. \see TypeQueryOptions.
148   TypeQuery(llvm::StringRef name, TypeQueryOptions options = e_none);
149 
150   /// Construct a type-match object that matches a type basename that exists
151   /// in the specified declaration context.
152   ///
153   /// This allows the m_context to be first populated using a declaration
154   /// context to exactly identify the containing declaration context of a type.
155   /// This can be used when you have a forward declaration to a type and you
156   /// need to search for its complete type.
157   ///
158   /// \param[in] decl_ctx
159   ///   A declaration context object that comes from a TypeSystem plug-in. This
160   ///   object will be asked to populate the array of CompilerContext objects
161   ///   by adding the top most declaration context first into the array and then
162   ///   adding any containing declaration contexts.
163   ///
164   /// \param[in] type_basename
165   ///   The basename of the type to lookup in the specified declaration context.
166   ///
167   /// \param[in] options A set of boolean enumeration flags from the
168   ///   TypeQueryOptions enumerations. \see TypeQueryOptions.
169   TypeQuery(const CompilerDeclContext &decl_ctx, ConstString type_basename,
170             TypeQueryOptions options = e_none);
171   /// Construct a type-match object using a compiler declaration that specifies
172   /// a typename and a declaration context to use when doing exact type lookups.
173   ///
174   /// This allows the m_context to be first populated using a type declaration.
175   /// The type declaration might have a declaration context and each TypeSystem
176   /// plug-in can populate the declaration context needed to perform an exact
177   /// lookup for a type.
178   /// This can be used when you have a forward declaration to a type and you
179   /// need to search for its complete type.
180   ///
181   /// \param[in] decl
182   ///   A type declaration context object that comes from a TypeSystem plug-in.
183   ///   This object will be asked to full the array of CompilerContext objects
184   ///   by adding the top most declaration context first into the array and then
185   ///   adding any containing declaration contexts, and ending with the exact
186   ///   typename and the kind of type it is (class, struct, union, enum, etc).
187   ///
188   /// \param[in] options A set of boolean enumeration flags from the
189   ///   TypeQueryOptions enumerations. \see TypeQueryOptions.
190   TypeQuery(const CompilerDecl &decl, TypeQueryOptions options = e_none);
191 
192   /// Construct a type-match object using a CompilerContext array.
193   ///
194   /// Clients can manually create compiler contexts and use these to find
195   /// matches when searching for types. There are two types of contexts that
196   /// are supported when doing type searchs: type contexts and clang module
197   /// contexts. Type contexts have contexts that specify the type and its
198   /// containing declaration context like namespaces and classes. Clang module
199   /// contexts specify contexts more completely to find exact matches within
200   /// clang module debug information. They will include the modules that the
201   /// type is included in and any functions that the type might be defined in.
202   /// This allows very fine-grained type resolution.
203   ///
204   /// \param[in] context The compiler context to use when doing the search.
205   ///
206   /// \param[in] options A set of boolean enumeration flags from the
207   ///   TypeQueryOptions enumerations. \see TypeQueryOptions.
208   TypeQuery(const llvm::ArrayRef<lldb_private::CompilerContext> &context,
209             TypeQueryOptions options = e_none);
210 
211   /// Construct a type-match object that duplicates all matching criterea,
212   /// but not any searched symbol files or the type map for matches. This allows
213   /// the m_context to be modified prior to performing another search.
214   TypeQuery(const TypeQuery &rhs) = default;
215   /// Assign a type-match object that duplicates all matching criterea,
216   /// but not any searched symbol files or the type map for matches. This allows
217   /// the m_context to be modified prior to performing another search.
218   TypeQuery &operator=(const TypeQuery &rhs) = default;
219 
220   /// Check of a CompilerContext array from matching type from a symbol file
221   /// matches the \a m_context.
222   ///
223   /// \param[in] context
224   ///   A fully qualified CompilerContext array for a potential match that is
225   ///   created by the symbol file prior to trying to actually resolve a type.
226   ///
227   /// \returns
228   ///   True if the context matches, false if it doesn't. If e_exact_match
229   ///   is set in m_options, then \a context must exactly match \a m_context. If
230   ///   e_exact_match is not set, then the bottom m_context.size() objects in
231   ///   \a context must match. This allows SymbolFile objects the fill in a
232   ///   potential type basename match from the index into \a context, and see if
233   ///   it matches prior to having to resolve a lldb_private::Type object for
234   ///   the type from the index. This allows type parsing to be as efficient as
235   ///   possible and only realize the types that match the query.
236   bool
237   ContextMatches(llvm::ArrayRef<lldb_private::CompilerContext> context) const;
238 
239   /// Get the type basename to use when searching the type indexes in each
240   /// SymbolFile object.
241   ///
242   /// Debug information indexes often contain indexes that track the basename
243   /// of types only, not a fully qualified path. This allows the indexes to be
244   /// smaller and allows for efficient lookups.
245   ///
246   /// \returns
247   ///   The type basename to use when doing lookups as a constant string.
248   ConstString GetTypeBasename() const;
249 
250   /// Returns true if any matching languages have been specified in this type
251   /// matching object.
252   bool HasLanguage() const { return m_languages.has_value(); }
253 
254   /// Add a language family to the list of languages that should produce a
255   /// match.
256   void AddLanguage(lldb::LanguageType language);
257 
258   /// Set the list of languages that should produce a match to only the ones
259   /// specified in \ref languages.
260   void SetLanguages(LanguageSet languages);
261 
262   /// Check if the language matches any languages that have been added to this
263   /// match object.
264   ///
265   /// \returns
266   ///   True if no language have been specified, or if some language have been
267   ///   added using AddLanguage(...) and they match. False otherwise.
268   bool LanguageMatches(lldb::LanguageType language) const;
269 
270   bool GetExactMatch() const { return (m_options & e_exact_match) != 0; }
271 
272   bool GetIgnoreModules() const { return (m_options & e_ignore_modules) != 0; }
273   void SetIgnoreModules(bool b) {
274     if (b)
275       m_options |= e_ignore_modules;
276     else
277       m_options &= ~e_ignore_modules;
278   }
279 
280   bool GetStrictNamespaces() const {
281     return (m_options & e_strict_namespaces) != 0;
282   }
283   void SetStrictNamespaces(bool b) {
284     if (b)
285       m_options |= e_strict_namespaces;
286     else
287       m_options &= ~e_strict_namespaces;
288   }
289 
290   /// The \a m_context can be used in two ways: normal types searching with
291   /// the context containing a stanadard declaration context for a type, or
292   /// with the context being more complete for exact matches in clang modules.
293   /// Set this to true if you wish to search for a type in clang module.
294   bool GetModuleSearch() const { return (m_options & e_module_search) != 0; }
295 
296   /// Returns true if the type query is supposed to find only a single matching
297   /// type. Returns false if the type query should find all matches.
298   bool GetFindOne() const { return (m_options & e_find_one) != 0; }
299   void SetFindOne(bool b) {
300     if (b)
301       m_options |= e_find_one;
302     else
303       m_options &= ~e_find_one;
304   }
305 
306   /// Returns true if the type query is supposed to treat the name to be
307   /// searched as a mangled name.
308   bool GetSearchByMangledName() const {
309     return (m_options & e_search_by_mangled_name) != 0;
310   }
311 
312   void SetSearchByMangledName(bool b) {
313     if (b)
314       m_options |= e_search_by_mangled_name;
315     else
316       m_options &= ~e_search_by_mangled_name;
317   }
318 
319   /// Access the internal compiler context array.
320   ///
321   /// Clients can use this to populate the context manually.
322   std::vector<lldb_private::CompilerContext> &GetContextRef() {
323     return m_context;
324   }
325 
326 protected:
327   /// A full or partial compiler context array where the parent declaration
328   /// contexts appear at the top of the array starting at index zero and the
329   /// last entry contains the type and name of the type we are looking for.
330   std::vector<lldb_private::CompilerContext> m_context;
331   /// An options bitmask that contains enabled options for the type query.
332   /// \see TypeQueryOptions.
333   TypeQueryOptions m_options;
334   /// If this variable has a value, then the language family must match at least
335   /// one of the specified languages. If this variable has no value, then the
336   /// language of the type doesn't need to match any types that are searched.
337   std::optional<LanguageSet> m_languages;
338 };
339 
340 /// This class tracks the state and results of a \ref TypeQuery.
341 ///
342 /// Any mutable state required for type lookups and the results are tracked in
343 /// this object.
344 class TypeResults {
345 public:
346   /// Construct a type results object
347   TypeResults() = default;
348 
349   /// When types that match a TypeQuery are found, this API is used to insert
350   /// the matching types.
351   ///
352   /// \return
353   ///   True if the type was added, false if the \a type_sp was already in the
354   ///   results.
355   bool InsertUnique(const lldb::TypeSP &type_sp);
356 
357   /// Check if the type matching has found all of the matches that it needs.
358   bool Done(const TypeQuery &query) const;
359 
360   /// Check if a SymbolFile object has already been searched by this type match
361   /// object.
362   ///
363   /// This function will add \a sym_file to the set of SymbolFile objects if it
364   /// isn't already in the set and return \a false. Returns true if \a sym_file
365   /// was already in the set and doesn't need to be searched.
366   ///
367   /// Any clients that search for types should first check that the symbol file
368   /// has not already been searched. If this function returns true, the type
369   /// search function should early return to avoid duplicating type searchihng
370   /// efforts.
371   ///
372   /// \param[in] sym_file
373   ///   A SymbolFile pointer that will be used to track which symbol files have
374   ///   already been searched.
375   ///
376   /// \returns
377   ///   True if the symbol file has been search already, false otherwise.
378   bool AlreadySearched(lldb_private::SymbolFile *sym_file);
379 
380   /// Access the set of searched symbol files.
381   llvm::DenseSet<lldb_private::SymbolFile *> &GetSearchedSymbolFiles() {
382     return m_searched_symbol_files;
383   }
384 
385   lldb::TypeSP GetFirstType() const { return m_type_map.FirstType(); }
386   TypeMap &GetTypeMap() { return m_type_map; }
387   const TypeMap &GetTypeMap() const { return m_type_map; }
388 
389 private:
390   /// Matching types get added to this map as type search continues.
391   TypeMap m_type_map;
392   /// This set is used to track and make sure we only perform lookups in a
393   /// symbol file one time.
394   llvm::DenseSet<lldb_private::SymbolFile *> m_searched_symbol_files;
395 };
396 
397 class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>,
398                        public UserID {
399 public:
400   SymbolFileType(SymbolFile &symbol_file, lldb::user_id_t uid)
401       : UserID(uid), m_symbol_file(symbol_file) {}
402 
403   SymbolFileType(SymbolFile &symbol_file, const lldb::TypeSP &type_sp);
404 
405   ~SymbolFileType() = default;
406 
407   Type *operator->() { return GetType(); }
408 
409   Type *GetType();
410   SymbolFile &GetSymbolFile() const { return m_symbol_file; }
411 
412 protected:
413   SymbolFile &m_symbol_file;
414   lldb::TypeSP m_type_sp;
415 };
416 
417 class Type : public std::enable_shared_from_this<Type>, public UserID {
418 public:
419   enum EncodingDataType {
420     /// Invalid encoding.
421     eEncodingInvalid,
422     /// This type is the type whose UID is m_encoding_uid.
423     eEncodingIsUID,
424     /// This type is the type whose UID is m_encoding_uid with the const
425     /// qualifier added.
426     eEncodingIsConstUID,
427     /// This type is the type whose UID is m_encoding_uid with the restrict
428     /// qualifier added.
429     eEncodingIsRestrictUID,
430     /// This type is the type whose UID is m_encoding_uid with the volatile
431     /// qualifier added.
432     eEncodingIsVolatileUID,
433     /// This type is alias to a type whose UID is m_encoding_uid.
434     eEncodingIsTypedefUID,
435     /// This type is pointer to a type whose UID is m_encoding_uid.
436     eEncodingIsPointerUID,
437     /// This type is L value reference to a type whose UID is m_encoding_uid.
438     eEncodingIsLValueReferenceUID,
439     /// This type is R value reference to a type whose UID is m_encoding_uid.
440     eEncodingIsRValueReferenceUID,
441     /// This type is the type whose UID is m_encoding_uid as an atomic type.
442     eEncodingIsAtomicUID,
443     /// This type is the synthetic type whose UID is m_encoding_uid.
444     eEncodingIsSyntheticUID,
445     /// This type is a signed pointer.
446     eEncodingIsLLVMPtrAuthUID
447   };
448 
449   enum class ResolveState : unsigned char {
450     Unresolved = 0,
451     Forward = 1,
452     Layout = 2,
453     Full = 3
454   };
455 
456   void Dump(Stream *s, bool show_context,
457             lldb::DescriptionLevel level = lldb::eDescriptionLevelFull);
458 
459   void DumpTypeName(Stream *s);
460 
461   /// Since Type instances only keep a "SymbolFile *" internally, other classes
462   /// like TypeImpl need make sure the module is still around before playing
463   /// with
464   /// Type instances. They can store a weak pointer to the Module;
465   lldb::ModuleSP GetModule();
466 
467   /// GetModule may return module for compile unit's object file.
468   /// GetExeModule returns module for executable object file that contains
469   /// compile unit where type was actually defined.
470   /// GetModule and GetExeModule may return the same value.
471   lldb::ModuleSP GetExeModule();
472 
473   void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name,
474                       ExecutionContextScope *exe_scope);
475 
476   SymbolFile *GetSymbolFile() { return m_symbol_file; }
477   const SymbolFile *GetSymbolFile() const { return m_symbol_file; }
478 
479   ConstString GetName();
480 
481   ConstString GetBaseName();
482 
483   std::optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope);
484 
485   llvm::Expected<uint32_t> GetNumChildren(bool omit_empty_base_classes);
486 
487   bool IsAggregateType();
488 
489   // Returns if the type is a templated decl. Does not look through typedefs.
490   bool IsTemplateType();
491 
492   bool IsValidType() { return m_encoding_uid_type != eEncodingInvalid; }
493 
494   bool IsTypedef() { return m_encoding_uid_type == eEncodingIsTypedefUID; }
495 
496   lldb::TypeSP GetTypedefType();
497 
498   ConstString GetName() const { return m_name; }
499 
500   ConstString GetQualifiedName();
501 
502   bool ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t address,
503                       AddressType address_type, DataExtractor &data);
504 
505   bool WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t address,
506                      AddressType address_type, DataExtractor &data);
507 
508   lldb::Format GetFormat();
509 
510   lldb::Encoding GetEncoding(uint64_t &count);
511 
512   SymbolContextScope *GetSymbolContextScope() { return m_context; }
513   const SymbolContextScope *GetSymbolContextScope() const { return m_context; }
514   void SetSymbolContextScope(SymbolContextScope *context) {
515     m_context = context;
516   }
517 
518   const lldb_private::Declaration &GetDeclaration() const;
519 
520   // Get the clang type, and resolve definitions for any
521   // class/struct/union/enum types completely.
522   CompilerType GetFullCompilerType();
523 
524   // Get the clang type, and resolve definitions enough so that the type could
525   // have layout performed. This allows ptrs and refs to
526   // class/struct/union/enum types remain forward declarations.
527   CompilerType GetLayoutCompilerType();
528 
529   // Get the clang type and leave class/struct/union/enum types as forward
530   // declarations if they haven't already been fully defined.
531   CompilerType GetForwardCompilerType();
532 
533   static int Compare(const Type &a, const Type &b);
534 
535   // Represents a parsed type name coming out of GetTypeScopeAndBasename. The
536   // structure holds StringRefs pointing to portions of the original name, and
537   // so must not be used after the name is destroyed.
538   struct ParsedName {
539     lldb::TypeClass type_class = lldb::eTypeClassAny;
540 
541     // Scopes of the type, starting with the outermost. Absolute type references
542     // have a "::" as the first scope.
543     llvm::SmallVector<llvm::StringRef> scope;
544 
545     llvm::StringRef basename;
546 
547     friend bool operator==(const ParsedName &lhs, const ParsedName &rhs) {
548       return lhs.type_class == rhs.type_class && lhs.scope == rhs.scope &&
549              lhs.basename == rhs.basename;
550     }
551 
552     friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
553                                          const ParsedName &name) {
554       return os << llvm::formatv(
555                  "Type::ParsedName({0:x}, [{1}], {2})",
556                  llvm::to_underlying(name.type_class),
557                  llvm::make_range(name.scope.begin(), name.scope.end()),
558                  name.basename);
559     }
560   };
561   // From a fully qualified typename, split the type into the type basename and
562   // the remaining type scope (namespaces/classes).
563   static std::optional<ParsedName>
564   GetTypeScopeAndBasename(llvm::StringRef name);
565 
566   void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; }
567 
568   uint32_t GetEncodingMask();
569 
570   typedef uint32_t Payload;
571   /// Return the language-specific payload.
572   Payload GetPayload() { return m_payload; }
573   /// Return the language-specific payload.
574   void SetPayload(Payload opaque_payload) { m_payload = opaque_payload; }
575 
576 protected:
577   ConstString m_name;
578   SymbolFile *m_symbol_file = nullptr;
579   /// The symbol context in which this type is defined.
580   SymbolContextScope *m_context = nullptr;
581   Type *m_encoding_type = nullptr;
582   lldb::user_id_t m_encoding_uid = LLDB_INVALID_UID;
583   EncodingDataType m_encoding_uid_type = eEncodingInvalid;
584   uint64_t m_byte_size : 63;
585   uint64_t m_byte_size_has_value : 1;
586   Declaration m_decl;
587   CompilerType m_compiler_type;
588   ResolveState m_compiler_type_resolve_state = ResolveState::Unresolved;
589   /// Language-specific flags.
590   Payload m_payload;
591 
592   Type *GetEncodingType();
593 
594   bool ResolveCompilerType(ResolveState compiler_type_resolve_state);
595 private:
596   /// Only allow Symbol File to create types, as they should own them by keeping
597   /// them in their TypeList. \see SymbolFileCommon::MakeType() reference in the
598   /// header documentation here so users will know what function to use if the
599   /// get a compile error.
600   friend class lldb_private::SymbolFileCommon;
601 
602   Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name,
603        std::optional<uint64_t> byte_size, SymbolContextScope *context,
604        lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type,
605        const Declaration &decl, const CompilerType &compiler_qual_type,
606        ResolveState compiler_type_resolve_state, uint32_t opaque_payload = 0);
607 
608   // This makes an invalid type.  Used for functions that return a Type when
609   // they get an error.
610   Type();
611 
612   Type(Type &t) = default;
613 
614   Type(Type &&t) = default;
615 
616   Type &operator=(const Type &t) = default;
617 
618   Type &operator=(Type &&t) = default;
619 };
620 
621 // the two classes here are used by the public API as a backend to the SBType
622 // and SBTypeList classes
623 
624 class TypeImpl {
625 public:
626   TypeImpl() = default;
627 
628   ~TypeImpl() = default;
629 
630   TypeImpl(const lldb::TypeSP &type_sp);
631 
632   TypeImpl(const CompilerType &compiler_type);
633 
634   TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic);
635 
636   TypeImpl(const CompilerType &compiler_type, const CompilerType &dynamic);
637 
638   void SetType(const lldb::TypeSP &type_sp);
639 
640   void SetType(const CompilerType &compiler_type);
641 
642   void SetType(const lldb::TypeSP &type_sp, const CompilerType &dynamic);
643 
644   void SetType(const CompilerType &compiler_type, const CompilerType &dynamic);
645 
646   bool operator==(const TypeImpl &rhs) const;
647 
648   bool operator!=(const TypeImpl &rhs) const;
649 
650   bool IsValid() const;
651 
652   explicit operator bool() const;
653 
654   void Clear();
655 
656   lldb::ModuleSP GetModule() const;
657 
658   ConstString GetName() const;
659 
660   ConstString GetDisplayTypeName() const;
661 
662   TypeImpl GetPointerType() const;
663 
664   TypeImpl GetPointeeType() const;
665 
666   TypeImpl GetReferenceType() const;
667 
668   TypeImpl GetTypedefedType() const;
669 
670   TypeImpl GetDereferencedType() const;
671 
672   TypeImpl GetUnqualifiedType() const;
673 
674   TypeImpl GetCanonicalType() const;
675 
676   CompilerType GetCompilerType(bool prefer_dynamic);
677 
678   CompilerType::TypeSystemSPWrapper GetTypeSystem(bool prefer_dynamic);
679 
680   bool GetDescription(lldb_private::Stream &strm,
681                       lldb::DescriptionLevel description_level);
682 
683   CompilerType FindDirectNestedType(llvm::StringRef name);
684 
685 private:
686   bool CheckModule(lldb::ModuleSP &module_sp) const;
687   bool CheckExeModule(lldb::ModuleSP &module_sp) const;
688   bool CheckModuleCommon(const lldb::ModuleWP &input_module_wp,
689                          lldb::ModuleSP &module_sp) const;
690 
691   lldb::ModuleWP m_module_wp;
692   lldb::ModuleWP m_exe_module_wp;
693   CompilerType m_static_type;
694   CompilerType m_dynamic_type;
695 };
696 
697 class TypeListImpl {
698 public:
699   TypeListImpl() = default;
700 
701   void Append(const lldb::TypeImplSP &type) { m_content.push_back(type); }
702 
703   class AppendVisitor {
704   public:
705     AppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {}
706 
707     void operator()(const lldb::TypeImplSP &type) { m_type_list.Append(type); }
708 
709   private:
710     TypeListImpl &m_type_list;
711   };
712 
713   void Append(const lldb_private::TypeList &type_list);
714 
715   lldb::TypeImplSP GetTypeAtIndex(size_t idx) {
716     lldb::TypeImplSP type_sp;
717     if (idx < GetSize())
718       type_sp = m_content[idx];
719     return type_sp;
720   }
721 
722   size_t GetSize() { return m_content.size(); }
723 
724 private:
725   std::vector<lldb::TypeImplSP> m_content;
726 };
727 
728 class TypeMemberImpl {
729 public:
730   TypeMemberImpl() = default;
731 
732   TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset,
733                  ConstString name, uint32_t bitfield_bit_size = 0,
734                  bool is_bitfield = false)
735       : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(name),
736         m_bitfield_bit_size(bitfield_bit_size), m_is_bitfield(is_bitfield) {}
737 
738   TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset)
739       : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset),
740         m_bitfield_bit_size(0), m_is_bitfield(false) {
741     if (m_type_impl_sp)
742       m_name = m_type_impl_sp->GetName();
743   }
744 
745   const lldb::TypeImplSP &GetTypeImpl() { return m_type_impl_sp; }
746 
747   ConstString GetName() const { return m_name; }
748 
749   uint64_t GetBitOffset() const { return m_bit_offset; }
750 
751   uint32_t GetBitfieldBitSize() const { return m_bitfield_bit_size; }
752 
753   void SetBitfieldBitSize(uint32_t bitfield_bit_size) {
754     m_bitfield_bit_size = bitfield_bit_size;
755   }
756 
757   bool GetIsBitfield() const { return m_is_bitfield; }
758 
759   void SetIsBitfield(bool is_bitfield) { m_is_bitfield = is_bitfield; }
760 
761 protected:
762   lldb::TypeImplSP m_type_impl_sp;
763   uint64_t m_bit_offset = 0;
764   ConstString m_name;
765   uint32_t m_bitfield_bit_size = 0; // Bit size for bitfield members only
766   bool m_is_bitfield = false;
767 };
768 
769 ///
770 /// Sometimes you can find the name of the type corresponding to an object, but
771 /// we don't have debug
772 /// information for it.  If that is the case, you can return one of these
773 /// objects, and then if it
774 /// has a full type, you can use that, but if not at least you can print the
775 /// name for informational
776 /// purposes.
777 ///
778 
779 class TypeAndOrName {
780 public:
781   TypeAndOrName() = default;
782   TypeAndOrName(lldb::TypeSP &type_sp);
783   TypeAndOrName(const CompilerType &compiler_type);
784   TypeAndOrName(const char *type_str);
785   TypeAndOrName(ConstString &type_const_string);
786 
787   bool operator==(const TypeAndOrName &other) const;
788 
789   bool operator!=(const TypeAndOrName &other) const;
790 
791   ConstString GetName() const;
792 
793   CompilerType GetCompilerType() const { return m_compiler_type; }
794 
795   void SetName(ConstString type_name);
796 
797   void SetName(const char *type_name_cstr);
798 
799   void SetName(llvm::StringRef name);
800 
801   void SetTypeSP(lldb::TypeSP type_sp);
802 
803   void SetCompilerType(CompilerType compiler_type);
804 
805   bool IsEmpty() const;
806 
807   bool HasName() const;
808 
809   bool HasCompilerType() const;
810 
811   bool HasType() const { return HasCompilerType(); }
812 
813   void Clear();
814 
815   explicit operator bool() { return !IsEmpty(); }
816 
817 private:
818   CompilerType m_compiler_type;
819   ConstString m_type_name;
820 };
821 
822 class TypeMemberFunctionImpl {
823 public:
824   TypeMemberFunctionImpl() = default;
825 
826   TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl,
827                          const std::string &name,
828                          const lldb::MemberFunctionKind &kind)
829       : m_type(type), m_decl(decl), m_name(name), m_kind(kind) {}
830 
831   bool IsValid();
832 
833   ConstString GetName() const;
834 
835   ConstString GetMangledName() const;
836 
837   CompilerType GetType() const;
838 
839   CompilerType GetReturnType() const;
840 
841   size_t GetNumArguments() const;
842 
843   CompilerType GetArgumentAtIndex(size_t idx) const;
844 
845   lldb::MemberFunctionKind GetKind() const;
846 
847   bool GetDescription(Stream &stream);
848 
849 protected:
850   std::string GetPrintableTypeName();
851 
852 private:
853   CompilerType m_type;
854   CompilerDecl m_decl;
855   ConstString m_name;
856   lldb::MemberFunctionKind m_kind = lldb::eMemberFunctionKindUnknown;
857 };
858 
859 class TypeEnumMemberImpl {
860 public:
861   TypeEnumMemberImpl() : m_name("<invalid>") {}
862 
863   TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, ConstString name,
864                      const llvm::APSInt &value);
865 
866   TypeEnumMemberImpl(const TypeEnumMemberImpl &rhs) = default;
867 
868   TypeEnumMemberImpl &operator=(const TypeEnumMemberImpl &rhs);
869 
870   bool IsValid() { return m_valid; }
871 
872   ConstString GetName() const { return m_name; }
873 
874   const lldb::TypeImplSP &GetIntegerType() const { return m_integer_type_sp; }
875 
876   uint64_t GetValueAsUnsigned() const { return m_value.getZExtValue(); }
877 
878   int64_t GetValueAsSigned() const { return m_value.getSExtValue(); }
879 
880 protected:
881   lldb::TypeImplSP m_integer_type_sp;
882   ConstString m_name;
883   llvm::APSInt m_value;
884   bool m_valid = false;
885 };
886 
887 class TypeEnumMemberListImpl {
888 public:
889   TypeEnumMemberListImpl() = default;
890 
891   void Append(const lldb::TypeEnumMemberImplSP &type) {
892     m_content.push_back(type);
893   }
894 
895   void Append(const lldb_private::TypeEnumMemberListImpl &type_list);
896 
897   lldb::TypeEnumMemberImplSP GetTypeEnumMemberAtIndex(size_t idx) {
898     lldb::TypeEnumMemberImplSP enum_member;
899     if (idx < GetSize())
900       enum_member = m_content[idx];
901     return enum_member;
902   }
903 
904   size_t GetSize() { return m_content.size(); }
905 
906 private:
907   std::vector<lldb::TypeEnumMemberImplSP> m_content;
908 };
909 
910 } // namespace lldb_private
911 
912 #endif // LLDB_SYMBOL_TYPE_H
913