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