Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:52

0001 //===-- Type.h --------------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_SYMBOL_TYPE_H
0010 #define LLDB_SYMBOL_TYPE_H
0011 
0012 #include "lldb/Core/Declaration.h"
0013 #include "lldb/Symbol/CompilerDecl.h"
0014 #include "lldb/Symbol/CompilerType.h"
0015 #include "lldb/Symbol/TypeList.h"
0016 #include "lldb/Symbol/TypeMap.h"
0017 #include "lldb/Symbol/TypeSystem.h"
0018 #include "lldb/Utility/ConstString.h"
0019 #include "lldb/Utility/UserID.h"
0020 #include "lldb/lldb-private.h"
0021 
0022 #include "llvm/ADT/APSInt.h"
0023 #include "llvm/ADT/DenseSet.h"
0024 #include "llvm/ADT/STLForwardCompat.h"
0025 #include "llvm/Support/raw_ostream.h"
0026 
0027 #include <optional>
0028 #include <set>
0029 
0030 namespace lldb_private {
0031 class SymbolFileCommon;
0032 
0033 /// A SmallBitVector that represents a set of source languages (\p
0034 /// lldb::LanguageType).  Each lldb::LanguageType is represented by
0035 /// the bit with the position of its enumerator. The largest
0036 /// LanguageType is < 64, so this is space-efficient and on 64-bit
0037 /// architectures a LanguageSet can be completely stack-allocated.
0038 struct LanguageSet {
0039   llvm::SmallBitVector bitvector;
0040   LanguageSet();
0041 
0042   /// If the set contains a single language only, return it.
0043   std::optional<lldb::LanguageType> GetSingularLanguage();
0044   void Insert(lldb::LanguageType language);
0045   bool Empty() const;
0046   size_t Size() const;
0047   bool operator[](unsigned i) const;
0048 };
0049 
0050 /// CompilerContext allows an array of these items to be passed to perform
0051 /// detailed lookups in SymbolVendor and SymbolFile functions.
0052 struct CompilerContext {
0053   CompilerContext(CompilerContextKind t, ConstString n) : kind(t), name(n) {}
0054 
0055   bool operator==(const CompilerContext &rhs) const {
0056     return kind == rhs.kind && name == rhs.name;
0057   }
0058   bool operator!=(const CompilerContext &rhs) const { return !(*this == rhs); }
0059 
0060   void Dump(Stream &s) const;
0061 
0062   CompilerContextKind kind;
0063   ConstString name;
0064 };
0065 llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
0066                               const CompilerContext &rhs);
0067 
0068 FLAGS_ENUM(TypeQueryOptions){
0069     e_none = 0u,
0070     /// If set, TypeQuery::m_context contains an exact context that must match
0071     /// the full context. If not set, TypeQuery::m_context can contain a partial
0072     /// type match where the full context isn't fully specified.
0073     e_exact_match = (1u << 0),
0074     /// If set, TypeQuery::m_context is a clang module compiler context. If not
0075     /// set TypeQuery::m_context is normal type lookup context.
0076     e_module_search = (1u << 1),
0077     /// If set, the query will ignore all Module entries in the type context,
0078     /// even for exact matches.
0079     e_ignore_modules = (1u << 2),
0080     /// If set, all anonymous namespaces in the context must be matched exactly
0081     /// by the pattern. Otherwise, superfluous namespaces are skipped.
0082     e_strict_namespaces = (1u << 3),
0083     /// When true, the find types call should stop the query as soon as a single
0084     /// matching type is found. When false, the type query should find all
0085     /// matching types.
0086     e_find_one = (1u << 4),
0087     // If set, treat TypeQuery::m_name as a mangled name that should be
0088     // searched.
0089     e_search_by_mangled_name = (1u << 5),
0090 };
0091 LLDB_MARK_AS_BITMASK_ENUM(TypeQueryOptions)
0092 
0093 /// A class that contains all state required for type lookups.
0094 ///
0095 /// Using a TypeQuery class for matching types simplifies the internal APIs we
0096 /// need to implement type lookups in LLDB. Type lookups can fully specify the
0097 /// exact typename by filling out a complete or partial CompilerContext array.
0098 /// This technique allows for powerful searches and also allows the SymbolFile
0099 /// classes to use the m_context array to lookup types by basename, then
0100 /// eliminate potential matches without having to resolve types into each
0101 /// TypeSystem. This makes type lookups vastly more efficient and allows the
0102 /// SymbolFile objects to stop looking up types when the type matching is
0103 /// complete, like if we are looking for only a single type in our search.
0104 class TypeQuery {
0105 public:
0106   TypeQuery() = delete;
0107 
0108   /// Construct a type match object using a fully- or partially-qualified name.
0109   ///
0110   /// The specified \a type_name will be chopped up and the m_context will be
0111   /// populated by separating the string by looking for "::". We do this because
0112   /// symbol files have indexes that contain only the type's basename. This also
0113   /// allows symbol files to efficiently not realize types that don't match the
0114   /// specified context. Example of \a type_name values that can be specified
0115   /// include:
0116   ///   "foo": Look for any type whose basename matches "foo".
0117   ///     If \a exact_match is true, then the type can't be contained in any
0118   ///     declaration context like a namespace, class, or other containing
0119   ///     scope.
0120   ///     If \a exact match is false, then we will find all matches including
0121   ///     ones that are contained in other declaration contexts, including top
0122   ///     level types.
0123   ///   "foo::bar": Look for any type whose basename matches "bar" but make sure
0124   ///     its parent declaration context is any named declaration context
0125   ///     (namespace, class, struct, etc) whose name matches "foo".
0126   ///     If \a exact_match is true, then the "foo" declaration context must
0127   ///     appear at the source file level or inside of a function.
0128   ///     If \a exact match is false, then the "foo" declaration context can
0129   ///     be contained in any other declaration contexts.
0130   ///   "class foo": Only match types that are classes whose basename matches
0131   ///     "foo".
0132   ///   "struct foo": Only match types that are structures whose basename
0133   ///     matches "foo".
0134   ///   "class foo::bar": Only match types that are classes whose basename
0135   ///     matches "bar" and that are contained in any named declaration context
0136   ///     named "foo".
0137   ///
0138   /// \param[in] type_name
0139   ///   A fully- or partially-qualified type name. This name will be parsed and
0140   ///   broken up and the m_context will be populated with the various parts of
0141   ///   the name. This typename can be prefixed with "struct ", "class ",
0142   ///   "union", "enum " or "typedef " before the actual type name to limit the
0143   ///   results of the types that match. The declaration context can be
0144   ///   specified with the "::" string. For example, "a::b::my_type".
0145   ///
0146   /// \param[in] options A set of boolean enumeration flags from the
0147   ///   TypeQueryOptions enumerations. \see TypeQueryOptions.
0148   TypeQuery(llvm::StringRef name, TypeQueryOptions options = e_none);
0149 
0150   /// Construct a type-match object that matches a type basename that exists
0151   /// in the specified declaration context.
0152   ///
0153   /// This allows the m_context to be first populated using a declaration
0154   /// context to exactly identify the containing declaration context of a type.
0155   /// This can be used when you have a forward declaration to a type and you
0156   /// need to search for its complete type.
0157   ///
0158   /// \param[in] decl_ctx
0159   ///   A declaration context object that comes from a TypeSystem plug-in. This
0160   ///   object will be asked to populate the array of CompilerContext objects
0161   ///   by adding the top most declaration context first into the array and then
0162   ///   adding any containing declaration contexts.
0163   ///
0164   /// \param[in] type_basename
0165   ///   The basename of the type to lookup in the specified declaration context.
0166   ///
0167   /// \param[in] options A set of boolean enumeration flags from the
0168   ///   TypeQueryOptions enumerations. \see TypeQueryOptions.
0169   TypeQuery(const CompilerDeclContext &decl_ctx, ConstString type_basename,
0170             TypeQueryOptions options = e_none);
0171   /// Construct a type-match object using a compiler declaration that specifies
0172   /// a typename and a declaration context to use when doing exact type lookups.
0173   ///
0174   /// This allows the m_context to be first populated using a type declaration.
0175   /// The type declaration might have a declaration context and each TypeSystem
0176   /// plug-in can populate the declaration context needed to perform an exact
0177   /// lookup for a type.
0178   /// This can be used when you have a forward declaration to a type and you
0179   /// need to search for its complete type.
0180   ///
0181   /// \param[in] decl
0182   ///   A type declaration context object that comes from a TypeSystem plug-in.
0183   ///   This object will be asked to full the array of CompilerContext objects
0184   ///   by adding the top most declaration context first into the array and then
0185   ///   adding any containing declaration contexts, and ending with the exact
0186   ///   typename and the kind of type it is (class, struct, union, enum, etc).
0187   ///
0188   /// \param[in] options A set of boolean enumeration flags from the
0189   ///   TypeQueryOptions enumerations. \see TypeQueryOptions.
0190   TypeQuery(const CompilerDecl &decl, TypeQueryOptions options = e_none);
0191 
0192   /// Construct a type-match object using a CompilerContext array.
0193   ///
0194   /// Clients can manually create compiler contexts and use these to find
0195   /// matches when searching for types. There are two types of contexts that
0196   /// are supported when doing type searchs: type contexts and clang module
0197   /// contexts. Type contexts have contexts that specify the type and its
0198   /// containing declaration context like namespaces and classes. Clang module
0199   /// contexts specify contexts more completely to find exact matches within
0200   /// clang module debug information. They will include the modules that the
0201   /// type is included in and any functions that the type might be defined in.
0202   /// This allows very fine-grained type resolution.
0203   ///
0204   /// \param[in] context The compiler context to use when doing the search.
0205   ///
0206   /// \param[in] options A set of boolean enumeration flags from the
0207   ///   TypeQueryOptions enumerations. \see TypeQueryOptions.
0208   TypeQuery(const llvm::ArrayRef<lldb_private::CompilerContext> &context,
0209             TypeQueryOptions options = e_none);
0210 
0211   /// Construct a type-match object that duplicates all matching criterea,
0212   /// but not any searched symbol files or the type map for matches. This allows
0213   /// the m_context to be modified prior to performing another search.
0214   TypeQuery(const TypeQuery &rhs) = default;
0215   /// Assign a type-match object that duplicates all matching criterea,
0216   /// but not any searched symbol files or the type map for matches. This allows
0217   /// the m_context to be modified prior to performing another search.
0218   TypeQuery &operator=(const TypeQuery &rhs) = default;
0219 
0220   /// Check of a CompilerContext array from matching type from a symbol file
0221   /// matches the \a m_context.
0222   ///
0223   /// \param[in] context
0224   ///   A fully qualified CompilerContext array for a potential match that is
0225   ///   created by the symbol file prior to trying to actually resolve a type.
0226   ///
0227   /// \returns
0228   ///   True if the context matches, false if it doesn't. If e_exact_match
0229   ///   is set in m_options, then \a context must exactly match \a m_context. If
0230   ///   e_exact_match is not set, then the bottom m_context.size() objects in
0231   ///   \a context must match. This allows SymbolFile objects the fill in a
0232   ///   potential type basename match from the index into \a context, and see if
0233   ///   it matches prior to having to resolve a lldb_private::Type object for
0234   ///   the type from the index. This allows type parsing to be as efficient as
0235   ///   possible and only realize the types that match the query.
0236   bool
0237   ContextMatches(llvm::ArrayRef<lldb_private::CompilerContext> context) const;
0238 
0239   /// Get the type basename to use when searching the type indexes in each
0240   /// SymbolFile object.
0241   ///
0242   /// Debug information indexes often contain indexes that track the basename
0243   /// of types only, not a fully qualified path. This allows the indexes to be
0244   /// smaller and allows for efficient lookups.
0245   ///
0246   /// \returns
0247   ///   The type basename to use when doing lookups as a constant string.
0248   ConstString GetTypeBasename() const;
0249 
0250   /// Returns true if any matching languages have been specified in this type
0251   /// matching object.
0252   bool HasLanguage() const { return m_languages.has_value(); }
0253 
0254   /// Add a language family to the list of languages that should produce a
0255   /// match.
0256   void AddLanguage(lldb::LanguageType language);
0257 
0258   /// Set the list of languages that should produce a match to only the ones
0259   /// specified in \ref languages.
0260   void SetLanguages(LanguageSet languages);
0261 
0262   /// Check if the language matches any languages that have been added to this
0263   /// match object.
0264   ///
0265   /// \returns
0266   ///   True if no language have been specified, or if some language have been
0267   ///   added using AddLanguage(...) and they match. False otherwise.
0268   bool LanguageMatches(lldb::LanguageType language) const;
0269 
0270   bool GetExactMatch() const { return (m_options & e_exact_match) != 0; }
0271 
0272   bool GetIgnoreModules() const { return (m_options & e_ignore_modules) != 0; }
0273   void SetIgnoreModules(bool b) {
0274     if (b)
0275       m_options |= e_ignore_modules;
0276     else
0277       m_options &= ~e_ignore_modules;
0278   }
0279 
0280   bool GetStrictNamespaces() const {
0281     return (m_options & e_strict_namespaces) != 0;
0282   }
0283   void SetStrictNamespaces(bool b) {
0284     if (b)
0285       m_options |= e_strict_namespaces;
0286     else
0287       m_options &= ~e_strict_namespaces;
0288   }
0289 
0290   /// The \a m_context can be used in two ways: normal types searching with
0291   /// the context containing a stanadard declaration context for a type, or
0292   /// with the context being more complete for exact matches in clang modules.
0293   /// Set this to true if you wish to search for a type in clang module.
0294   bool GetModuleSearch() const { return (m_options & e_module_search) != 0; }
0295 
0296   /// Returns true if the type query is supposed to find only a single matching
0297   /// type. Returns false if the type query should find all matches.
0298   bool GetFindOne() const { return (m_options & e_find_one) != 0; }
0299   void SetFindOne(bool b) {
0300     if (b)
0301       m_options |= e_find_one;
0302     else
0303       m_options &= ~e_find_one;
0304   }
0305 
0306   /// Returns true if the type query is supposed to treat the name to be
0307   /// searched as a mangled name.
0308   bool GetSearchByMangledName() const {
0309     return (m_options & e_search_by_mangled_name) != 0;
0310   }
0311 
0312   void SetSearchByMangledName(bool b) {
0313     if (b)
0314       m_options |= e_search_by_mangled_name;
0315     else
0316       m_options &= ~e_search_by_mangled_name;
0317   }
0318 
0319   /// Access the internal compiler context array.
0320   ///
0321   /// Clients can use this to populate the context manually.
0322   std::vector<lldb_private::CompilerContext> &GetContextRef() {
0323     return m_context;
0324   }
0325 
0326 protected:
0327   /// A full or partial compiler context array where the parent declaration
0328   /// contexts appear at the top of the array starting at index zero and the
0329   /// last entry contains the type and name of the type we are looking for.
0330   std::vector<lldb_private::CompilerContext> m_context;
0331   /// An options bitmask that contains enabled options for the type query.
0332   /// \see TypeQueryOptions.
0333   TypeQueryOptions m_options;
0334   /// If this variable has a value, then the language family must match at least
0335   /// one of the specified languages. If this variable has no value, then the
0336   /// language of the type doesn't need to match any types that are searched.
0337   std::optional<LanguageSet> m_languages;
0338 };
0339 
0340 /// This class tracks the state and results of a \ref TypeQuery.
0341 ///
0342 /// Any mutable state required for type lookups and the results are tracked in
0343 /// this object.
0344 class TypeResults {
0345 public:
0346   /// Construct a type results object
0347   TypeResults() = default;
0348 
0349   /// When types that match a TypeQuery are found, this API is used to insert
0350   /// the matching types.
0351   ///
0352   /// \return
0353   ///   True if the type was added, false if the \a type_sp was already in the
0354   ///   results.
0355   bool InsertUnique(const lldb::TypeSP &type_sp);
0356 
0357   /// Check if the type matching has found all of the matches that it needs.
0358   bool Done(const TypeQuery &query) const;
0359 
0360   /// Check if a SymbolFile object has already been searched by this type match
0361   /// object.
0362   ///
0363   /// This function will add \a sym_file to the set of SymbolFile objects if it
0364   /// isn't already in the set and return \a false. Returns true if \a sym_file
0365   /// was already in the set and doesn't need to be searched.
0366   ///
0367   /// Any clients that search for types should first check that the symbol file
0368   /// has not already been searched. If this function returns true, the type
0369   /// search function should early return to avoid duplicating type searchihng
0370   /// efforts.
0371   ///
0372   /// \param[in] sym_file
0373   ///   A SymbolFile pointer that will be used to track which symbol files have
0374   ///   already been searched.
0375   ///
0376   /// \returns
0377   ///   True if the symbol file has been search already, false otherwise.
0378   bool AlreadySearched(lldb_private::SymbolFile *sym_file);
0379 
0380   /// Access the set of searched symbol files.
0381   llvm::DenseSet<lldb_private::SymbolFile *> &GetSearchedSymbolFiles() {
0382     return m_searched_symbol_files;
0383   }
0384 
0385   lldb::TypeSP GetFirstType() const { return m_type_map.FirstType(); }
0386   TypeMap &GetTypeMap() { return m_type_map; }
0387   const TypeMap &GetTypeMap() const { return m_type_map; }
0388 
0389 private:
0390   /// Matching types get added to this map as type search continues.
0391   TypeMap m_type_map;
0392   /// This set is used to track and make sure we only perform lookups in a
0393   /// symbol file one time.
0394   llvm::DenseSet<lldb_private::SymbolFile *> m_searched_symbol_files;
0395 };
0396 
0397 class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>,
0398                        public UserID {
0399 public:
0400   SymbolFileType(SymbolFile &symbol_file, lldb::user_id_t uid)
0401       : UserID(uid), m_symbol_file(symbol_file) {}
0402 
0403   SymbolFileType(SymbolFile &symbol_file, const lldb::TypeSP &type_sp);
0404 
0405   ~SymbolFileType() = default;
0406 
0407   Type *operator->() { return GetType(); }
0408 
0409   Type *GetType();
0410   SymbolFile &GetSymbolFile() const { return m_symbol_file; }
0411 
0412 protected:
0413   SymbolFile &m_symbol_file;
0414   lldb::TypeSP m_type_sp;
0415 };
0416 
0417 class Type : public std::enable_shared_from_this<Type>, public UserID {
0418 public:
0419   enum EncodingDataType {
0420     /// Invalid encoding.
0421     eEncodingInvalid,
0422     /// This type is the type whose UID is m_encoding_uid.
0423     eEncodingIsUID,
0424     /// This type is the type whose UID is m_encoding_uid with the const
0425     /// qualifier added.
0426     eEncodingIsConstUID,
0427     /// This type is the type whose UID is m_encoding_uid with the restrict
0428     /// qualifier added.
0429     eEncodingIsRestrictUID,
0430     /// This type is the type whose UID is m_encoding_uid with the volatile
0431     /// qualifier added.
0432     eEncodingIsVolatileUID,
0433     /// This type is alias to a type whose UID is m_encoding_uid.
0434     eEncodingIsTypedefUID,
0435     /// This type is pointer to a type whose UID is m_encoding_uid.
0436     eEncodingIsPointerUID,
0437     /// This type is L value reference to a type whose UID is m_encoding_uid.
0438     eEncodingIsLValueReferenceUID,
0439     /// This type is R value reference to a type whose UID is m_encoding_uid.
0440     eEncodingIsRValueReferenceUID,
0441     /// This type is the type whose UID is m_encoding_uid as an atomic type.
0442     eEncodingIsAtomicUID,
0443     /// This type is the synthetic type whose UID is m_encoding_uid.
0444     eEncodingIsSyntheticUID,
0445     /// This type is a signed pointer.
0446     eEncodingIsLLVMPtrAuthUID
0447   };
0448 
0449   enum class ResolveState : unsigned char {
0450     Unresolved = 0,
0451     Forward = 1,
0452     Layout = 2,
0453     Full = 3
0454   };
0455 
0456   void Dump(Stream *s, bool show_context,
0457             lldb::DescriptionLevel level = lldb::eDescriptionLevelFull);
0458 
0459   void DumpTypeName(Stream *s);
0460 
0461   /// Since Type instances only keep a "SymbolFile *" internally, other classes
0462   /// like TypeImpl need make sure the module is still around before playing
0463   /// with
0464   /// Type instances. They can store a weak pointer to the Module;
0465   lldb::ModuleSP GetModule();
0466 
0467   /// GetModule may return module for compile unit's object file.
0468   /// GetExeModule returns module for executable object file that contains
0469   /// compile unit where type was actually defined.
0470   /// GetModule and GetExeModule may return the same value.
0471   lldb::ModuleSP GetExeModule();
0472 
0473   void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name,
0474                       ExecutionContextScope *exe_scope);
0475 
0476   SymbolFile *GetSymbolFile() { return m_symbol_file; }
0477   const SymbolFile *GetSymbolFile() const { return m_symbol_file; }
0478 
0479   ConstString GetName();
0480 
0481   ConstString GetBaseName();
0482 
0483   std::optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope);
0484 
0485   llvm::Expected<uint32_t> GetNumChildren(bool omit_empty_base_classes);
0486 
0487   bool IsAggregateType();
0488 
0489   // Returns if the type is a templated decl. Does not look through typedefs.
0490   bool IsTemplateType();
0491 
0492   bool IsValidType() { return m_encoding_uid_type != eEncodingInvalid; }
0493 
0494   bool IsTypedef() { return m_encoding_uid_type == eEncodingIsTypedefUID; }
0495 
0496   lldb::TypeSP GetTypedefType();
0497 
0498   ConstString GetName() const { return m_name; }
0499 
0500   ConstString GetQualifiedName();
0501 
0502   bool ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t address,
0503                       AddressType address_type, DataExtractor &data);
0504 
0505   bool WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t address,
0506                      AddressType address_type, DataExtractor &data);
0507 
0508   lldb::Format GetFormat();
0509 
0510   lldb::Encoding GetEncoding(uint64_t &count);
0511 
0512   SymbolContextScope *GetSymbolContextScope() { return m_context; }
0513   const SymbolContextScope *GetSymbolContextScope() const { return m_context; }
0514   void SetSymbolContextScope(SymbolContextScope *context) {
0515     m_context = context;
0516   }
0517 
0518   const lldb_private::Declaration &GetDeclaration() const;
0519 
0520   // Get the clang type, and resolve definitions for any
0521   // class/struct/union/enum types completely.
0522   CompilerType GetFullCompilerType();
0523 
0524   // Get the clang type, and resolve definitions enough so that the type could
0525   // have layout performed. This allows ptrs and refs to
0526   // class/struct/union/enum types remain forward declarations.
0527   CompilerType GetLayoutCompilerType();
0528 
0529   // Get the clang type and leave class/struct/union/enum types as forward
0530   // declarations if they haven't already been fully defined.
0531   CompilerType GetForwardCompilerType();
0532 
0533   static int Compare(const Type &a, const Type &b);
0534 
0535   // Represents a parsed type name coming out of GetTypeScopeAndBasename. The
0536   // structure holds StringRefs pointing to portions of the original name, and
0537   // so must not be used after the name is destroyed.
0538   struct ParsedName {
0539     lldb::TypeClass type_class = lldb::eTypeClassAny;
0540 
0541     // Scopes of the type, starting with the outermost. Absolute type references
0542     // have a "::" as the first scope.
0543     llvm::SmallVector<llvm::StringRef> scope;
0544 
0545     llvm::StringRef basename;
0546 
0547     friend bool operator==(const ParsedName &lhs, const ParsedName &rhs) {
0548       return lhs.type_class == rhs.type_class && lhs.scope == rhs.scope &&
0549              lhs.basename == rhs.basename;
0550     }
0551 
0552     friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
0553                                          const ParsedName &name) {
0554       return os << llvm::formatv(
0555                  "Type::ParsedName({0:x}, [{1}], {2})",
0556                  llvm::to_underlying(name.type_class),
0557                  llvm::make_range(name.scope.begin(), name.scope.end()),
0558                  name.basename);
0559     }
0560   };
0561   // From a fully qualified typename, split the type into the type basename and
0562   // the remaining type scope (namespaces/classes).
0563   static std::optional<ParsedName>
0564   GetTypeScopeAndBasename(llvm::StringRef name);
0565 
0566   void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; }
0567 
0568   uint32_t GetEncodingMask();
0569 
0570   typedef uint32_t Payload;
0571   /// Return the language-specific payload.
0572   Payload GetPayload() { return m_payload; }
0573   /// Return the language-specific payload.
0574   void SetPayload(Payload opaque_payload) { m_payload = opaque_payload; }
0575 
0576 protected:
0577   ConstString m_name;
0578   SymbolFile *m_symbol_file = nullptr;
0579   /// The symbol context in which this type is defined.
0580   SymbolContextScope *m_context = nullptr;
0581   Type *m_encoding_type = nullptr;
0582   lldb::user_id_t m_encoding_uid = LLDB_INVALID_UID;
0583   EncodingDataType m_encoding_uid_type = eEncodingInvalid;
0584   uint64_t m_byte_size : 63;
0585   uint64_t m_byte_size_has_value : 1;
0586   Declaration m_decl;
0587   CompilerType m_compiler_type;
0588   ResolveState m_compiler_type_resolve_state = ResolveState::Unresolved;
0589   /// Language-specific flags.
0590   Payload m_payload;
0591 
0592   Type *GetEncodingType();
0593 
0594   bool ResolveCompilerType(ResolveState compiler_type_resolve_state);
0595 private:
0596   /// Only allow Symbol File to create types, as they should own them by keeping
0597   /// them in their TypeList. \see SymbolFileCommon::MakeType() reference in the
0598   /// header documentation here so users will know what function to use if the
0599   /// get a compile error.
0600   friend class lldb_private::SymbolFileCommon;
0601 
0602   Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name,
0603        std::optional<uint64_t> byte_size, SymbolContextScope *context,
0604        lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type,
0605        const Declaration &decl, const CompilerType &compiler_qual_type,
0606        ResolveState compiler_type_resolve_state, uint32_t opaque_payload = 0);
0607 
0608   // This makes an invalid type.  Used for functions that return a Type when
0609   // they get an error.
0610   Type();
0611 
0612   Type(Type &t) = default;
0613 
0614   Type(Type &&t) = default;
0615 
0616   Type &operator=(const Type &t) = default;
0617 
0618   Type &operator=(Type &&t) = default;
0619 };
0620 
0621 // the two classes here are used by the public API as a backend to the SBType
0622 // and SBTypeList classes
0623 
0624 class TypeImpl {
0625 public:
0626   TypeImpl() = default;
0627 
0628   ~TypeImpl() = default;
0629 
0630   TypeImpl(const lldb::TypeSP &type_sp);
0631 
0632   TypeImpl(const CompilerType &compiler_type);
0633 
0634   TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic);
0635 
0636   TypeImpl(const CompilerType &compiler_type, const CompilerType &dynamic);
0637 
0638   void SetType(const lldb::TypeSP &type_sp);
0639 
0640   void SetType(const CompilerType &compiler_type);
0641 
0642   void SetType(const lldb::TypeSP &type_sp, const CompilerType &dynamic);
0643 
0644   void SetType(const CompilerType &compiler_type, const CompilerType &dynamic);
0645 
0646   bool operator==(const TypeImpl &rhs) const;
0647 
0648   bool operator!=(const TypeImpl &rhs) const;
0649 
0650   bool IsValid() const;
0651 
0652   explicit operator bool() const;
0653 
0654   void Clear();
0655 
0656   lldb::ModuleSP GetModule() const;
0657 
0658   ConstString GetName() const;
0659 
0660   ConstString GetDisplayTypeName() const;
0661 
0662   TypeImpl GetPointerType() const;
0663 
0664   TypeImpl GetPointeeType() const;
0665 
0666   TypeImpl GetReferenceType() const;
0667 
0668   TypeImpl GetTypedefedType() const;
0669 
0670   TypeImpl GetDereferencedType() const;
0671 
0672   TypeImpl GetUnqualifiedType() const;
0673 
0674   TypeImpl GetCanonicalType() const;
0675 
0676   CompilerType GetCompilerType(bool prefer_dynamic);
0677 
0678   CompilerType::TypeSystemSPWrapper GetTypeSystem(bool prefer_dynamic);
0679 
0680   bool GetDescription(lldb_private::Stream &strm,
0681                       lldb::DescriptionLevel description_level);
0682 
0683   CompilerType FindDirectNestedType(llvm::StringRef name);
0684 
0685 private:
0686   bool CheckModule(lldb::ModuleSP &module_sp) const;
0687   bool CheckExeModule(lldb::ModuleSP &module_sp) const;
0688   bool CheckModuleCommon(const lldb::ModuleWP &input_module_wp,
0689                          lldb::ModuleSP &module_sp) const;
0690 
0691   lldb::ModuleWP m_module_wp;
0692   lldb::ModuleWP m_exe_module_wp;
0693   CompilerType m_static_type;
0694   CompilerType m_dynamic_type;
0695 };
0696 
0697 class TypeListImpl {
0698 public:
0699   TypeListImpl() = default;
0700 
0701   void Append(const lldb::TypeImplSP &type) { m_content.push_back(type); }
0702 
0703   class AppendVisitor {
0704   public:
0705     AppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {}
0706 
0707     void operator()(const lldb::TypeImplSP &type) { m_type_list.Append(type); }
0708 
0709   private:
0710     TypeListImpl &m_type_list;
0711   };
0712 
0713   void Append(const lldb_private::TypeList &type_list);
0714 
0715   lldb::TypeImplSP GetTypeAtIndex(size_t idx) {
0716     lldb::TypeImplSP type_sp;
0717     if (idx < GetSize())
0718       type_sp = m_content[idx];
0719     return type_sp;
0720   }
0721 
0722   size_t GetSize() { return m_content.size(); }
0723 
0724 private:
0725   std::vector<lldb::TypeImplSP> m_content;
0726 };
0727 
0728 class TypeMemberImpl {
0729 public:
0730   TypeMemberImpl() = default;
0731 
0732   TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset,
0733                  ConstString name, uint32_t bitfield_bit_size = 0,
0734                  bool is_bitfield = false)
0735       : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(name),
0736         m_bitfield_bit_size(bitfield_bit_size), m_is_bitfield(is_bitfield) {}
0737 
0738   TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset)
0739       : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset),
0740         m_bitfield_bit_size(0), m_is_bitfield(false) {
0741     if (m_type_impl_sp)
0742       m_name = m_type_impl_sp->GetName();
0743   }
0744 
0745   const lldb::TypeImplSP &GetTypeImpl() { return m_type_impl_sp; }
0746 
0747   ConstString GetName() const { return m_name; }
0748 
0749   uint64_t GetBitOffset() const { return m_bit_offset; }
0750 
0751   uint32_t GetBitfieldBitSize() const { return m_bitfield_bit_size; }
0752 
0753   void SetBitfieldBitSize(uint32_t bitfield_bit_size) {
0754     m_bitfield_bit_size = bitfield_bit_size;
0755   }
0756 
0757   bool GetIsBitfield() const { return m_is_bitfield; }
0758 
0759   void SetIsBitfield(bool is_bitfield) { m_is_bitfield = is_bitfield; }
0760 
0761 protected:
0762   lldb::TypeImplSP m_type_impl_sp;
0763   uint64_t m_bit_offset = 0;
0764   ConstString m_name;
0765   uint32_t m_bitfield_bit_size = 0; // Bit size for bitfield members only
0766   bool m_is_bitfield = false;
0767 };
0768 
0769 ///
0770 /// Sometimes you can find the name of the type corresponding to an object, but
0771 /// we don't have debug
0772 /// information for it.  If that is the case, you can return one of these
0773 /// objects, and then if it
0774 /// has a full type, you can use that, but if not at least you can print the
0775 /// name for informational
0776 /// purposes.
0777 ///
0778 
0779 class TypeAndOrName {
0780 public:
0781   TypeAndOrName() = default;
0782   TypeAndOrName(lldb::TypeSP &type_sp);
0783   TypeAndOrName(const CompilerType &compiler_type);
0784   TypeAndOrName(const char *type_str);
0785   TypeAndOrName(ConstString &type_const_string);
0786 
0787   bool operator==(const TypeAndOrName &other) const;
0788 
0789   bool operator!=(const TypeAndOrName &other) const;
0790 
0791   ConstString GetName() const;
0792 
0793   CompilerType GetCompilerType() const { return m_compiler_type; }
0794 
0795   void SetName(ConstString type_name);
0796 
0797   void SetName(const char *type_name_cstr);
0798 
0799   void SetName(llvm::StringRef name);
0800 
0801   void SetTypeSP(lldb::TypeSP type_sp);
0802 
0803   void SetCompilerType(CompilerType compiler_type);
0804 
0805   bool IsEmpty() const;
0806 
0807   bool HasName() const;
0808 
0809   bool HasCompilerType() const;
0810 
0811   bool HasType() const { return HasCompilerType(); }
0812 
0813   void Clear();
0814 
0815   explicit operator bool() { return !IsEmpty(); }
0816 
0817 private:
0818   CompilerType m_compiler_type;
0819   ConstString m_type_name;
0820 };
0821 
0822 class TypeMemberFunctionImpl {
0823 public:
0824   TypeMemberFunctionImpl() = default;
0825 
0826   TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl,
0827                          const std::string &name,
0828                          const lldb::MemberFunctionKind &kind)
0829       : m_type(type), m_decl(decl), m_name(name), m_kind(kind) {}
0830 
0831   bool IsValid();
0832 
0833   ConstString GetName() const;
0834 
0835   ConstString GetMangledName() const;
0836 
0837   CompilerType GetType() const;
0838 
0839   CompilerType GetReturnType() const;
0840 
0841   size_t GetNumArguments() const;
0842 
0843   CompilerType GetArgumentAtIndex(size_t idx) const;
0844 
0845   lldb::MemberFunctionKind GetKind() const;
0846 
0847   bool GetDescription(Stream &stream);
0848 
0849 protected:
0850   std::string GetPrintableTypeName();
0851 
0852 private:
0853   CompilerType m_type;
0854   CompilerDecl m_decl;
0855   ConstString m_name;
0856   lldb::MemberFunctionKind m_kind = lldb::eMemberFunctionKindUnknown;
0857 };
0858 
0859 class TypeEnumMemberImpl {
0860 public:
0861   TypeEnumMemberImpl() : m_name("<invalid>") {}
0862 
0863   TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, ConstString name,
0864                      const llvm::APSInt &value);
0865 
0866   TypeEnumMemberImpl(const TypeEnumMemberImpl &rhs) = default;
0867 
0868   TypeEnumMemberImpl &operator=(const TypeEnumMemberImpl &rhs);
0869 
0870   bool IsValid() { return m_valid; }
0871 
0872   ConstString GetName() const { return m_name; }
0873 
0874   const lldb::TypeImplSP &GetIntegerType() const { return m_integer_type_sp; }
0875 
0876   uint64_t GetValueAsUnsigned() const { return m_value.getZExtValue(); }
0877 
0878   int64_t GetValueAsSigned() const { return m_value.getSExtValue(); }
0879 
0880 protected:
0881   lldb::TypeImplSP m_integer_type_sp;
0882   ConstString m_name;
0883   llvm::APSInt m_value;
0884   bool m_valid = false;
0885 };
0886 
0887 class TypeEnumMemberListImpl {
0888 public:
0889   TypeEnumMemberListImpl() = default;
0890 
0891   void Append(const lldb::TypeEnumMemberImplSP &type) {
0892     m_content.push_back(type);
0893   }
0894 
0895   void Append(const lldb_private::TypeEnumMemberListImpl &type_list);
0896 
0897   lldb::TypeEnumMemberImplSP GetTypeEnumMemberAtIndex(size_t idx) {
0898     lldb::TypeEnumMemberImplSP enum_member;
0899     if (idx < GetSize())
0900       enum_member = m_content[idx];
0901     return enum_member;
0902   }
0903 
0904   size_t GetSize() { return m_content.size(); }
0905 
0906 private:
0907   std::vector<lldb::TypeEnumMemberImplSP> m_content;
0908 };
0909 
0910 } // namespace lldb_private
0911 
0912 #endif // LLDB_SYMBOL_TYPE_H