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