Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===-- CompilerType.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_COMPILERTYPE_H
0010 #define LLDB_SYMBOL_COMPILERTYPE_H
0011 
0012 #include <functional>
0013 #include <optional>
0014 #include <string>
0015 #include <vector>
0016 
0017 #include "lldb/lldb-private.h"
0018 #include "llvm/ADT/APSInt.h"
0019 #include "llvm/Support/Casting.h"
0020 
0021 namespace lldb_private {
0022 
0023 class DataExtractor;
0024 class TypeSystem;
0025 
0026 /// Generic representation of a type in a programming language.
0027 ///
0028 /// This class serves as an abstraction for a type inside one of the TypeSystems
0029 /// implemented by the language plugins. It does not have any actual logic in it
0030 /// but only stores an opaque pointer and a pointer to the TypeSystem that
0031 /// gives meaning to this opaque pointer. All methods of this class should call
0032 /// their respective method in the TypeSystem interface and pass the opaque
0033 /// pointer along.
0034 ///
0035 /// \see lldb_private::TypeSystem
0036 class CompilerType {
0037 public:
0038   /// Creates a CompilerType with the given TypeSystem and opaque compiler type.
0039   ///
0040   /// This constructor should only be called from the respective TypeSystem
0041   /// implementation.
0042   ///
0043   /// \see lldb_private::TypeSystemClang::GetType(clang::QualType)
0044   CompilerType(lldb::TypeSystemWP type_system,
0045                lldb::opaque_compiler_type_t type);
0046 
0047   /// This is a minimal wrapper of a TypeSystem shared pointer as
0048   /// returned by CompilerType which conventien dyn_cast support.
0049   class TypeSystemSPWrapper {
0050     lldb::TypeSystemSP m_typesystem_sp;
0051 
0052   public:
0053     TypeSystemSPWrapper() = default;
0054     TypeSystemSPWrapper(lldb::TypeSystemSP typesystem_sp)
0055         : m_typesystem_sp(typesystem_sp) {}
0056 
0057     template <class TypeSystemType> bool isa_and_nonnull() {
0058       if (auto *ts = m_typesystem_sp.get())
0059         return llvm::isa<TypeSystemType>(ts);
0060       return false;
0061     }
0062 
0063     /// Return a shared_ptr<TypeSystemType> if dyn_cast succeeds.
0064     template <class TypeSystemType>
0065     std::shared_ptr<TypeSystemType> dyn_cast_or_null() {
0066       if (isa_and_nonnull<TypeSystemType>())
0067         return std::shared_ptr<TypeSystemType>(
0068             m_typesystem_sp, llvm::cast<TypeSystemType>(m_typesystem_sp.get()));
0069       return nullptr;
0070     }
0071 
0072     explicit operator bool() const {
0073       return static_cast<bool>(m_typesystem_sp);
0074     }
0075     bool operator==(const TypeSystemSPWrapper &other) const;
0076     bool operator!=(const TypeSystemSPWrapper &other) const {
0077       return !(*this == other);
0078     }
0079 
0080     /// Only to be used in a one-off situations like
0081     ///    if (typesystem && typesystem->method())
0082     /// Do not store this pointer!
0083     TypeSystem *operator->() const;
0084 
0085     lldb::TypeSystemSP GetSharedPointer() const { return m_typesystem_sp; }
0086   };
0087 
0088   CompilerType(TypeSystemSPWrapper type_system,
0089                lldb::opaque_compiler_type_t type);
0090 
0091   CompilerType(const CompilerType &rhs)
0092       : m_type_system(rhs.m_type_system), m_type(rhs.m_type) {}
0093 
0094   CompilerType() = default;
0095 
0096   /// Operators.
0097   /// \{
0098   const CompilerType &operator=(const CompilerType &rhs) {
0099     m_type_system = rhs.m_type_system;
0100     m_type = rhs.m_type;
0101     return *this;
0102   }
0103 
0104   bool operator<(const CompilerType &rhs) const {
0105     auto lts = m_type_system.lock();
0106     auto rts = rhs.m_type_system.lock();
0107     if (lts.get() == rts.get())
0108       return m_type < rhs.m_type;
0109     return lts.get() < rts.get();
0110   }
0111   /// \}
0112 
0113   /// Tests.
0114   /// \{
0115   explicit operator bool() const {
0116     return m_type_system.lock() && m_type;
0117   }
0118 
0119   bool IsValid() const { return (bool)*this; }
0120 
0121   bool IsArrayType(CompilerType *element_type = nullptr,
0122                    uint64_t *size = nullptr,
0123                    bool *is_incomplete = nullptr) const;
0124 
0125   bool IsVectorType(CompilerType *element_type = nullptr,
0126                     uint64_t *size = nullptr) const;
0127 
0128   bool IsArrayOfScalarType() const;
0129 
0130   bool IsAggregateType() const;
0131 
0132   bool IsAnonymousType() const;
0133 
0134   bool IsScopedEnumerationType() const;
0135 
0136   bool IsBeingDefined() const;
0137 
0138   bool IsCharType() const;
0139 
0140   bool IsCompleteType() const;
0141 
0142   bool IsConst() const;
0143 
0144   bool IsDefined() const;
0145 
0146   bool IsFloatingPointType(uint32_t &count, bool &is_complex) const;
0147 
0148   bool IsFunctionType() const;
0149 
0150   uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const;
0151 
0152   size_t GetNumberOfFunctionArguments() const;
0153 
0154   CompilerType GetFunctionArgumentAtIndex(const size_t index) const;
0155 
0156   bool IsVariadicFunctionType() const;
0157 
0158   bool IsFunctionPointerType() const;
0159 
0160   bool IsMemberFunctionPointerType() const;
0161 
0162   bool
0163   IsBlockPointerType(CompilerType *function_pointer_type_ptr = nullptr) const;
0164 
0165   bool IsIntegerType(bool &is_signed) const;
0166 
0167   bool IsEnumerationType(bool &is_signed) const;
0168 
0169   bool IsIntegerOrEnumerationType(bool &is_signed) const;
0170 
0171   bool IsPolymorphicClass() const;
0172 
0173   /// \param target_type    Can pass nullptr.
0174   bool IsPossibleDynamicType(CompilerType *target_type, bool check_cplusplus,
0175                              bool check_objc) const;
0176 
0177   bool IsPointerToScalarType() const;
0178 
0179   bool IsRuntimeGeneratedType() const;
0180 
0181   bool IsPointerType(CompilerType *pointee_type = nullptr) const;
0182 
0183   bool IsPointerOrReferenceType(CompilerType *pointee_type = nullptr) const;
0184 
0185   bool IsReferenceType(CompilerType *pointee_type = nullptr,
0186                        bool *is_rvalue = nullptr) const;
0187 
0188   bool ShouldTreatScalarValueAsAddress() const;
0189 
0190   bool IsScalarType() const;
0191 
0192   bool IsTemplateType() const;
0193 
0194   bool IsTypedefType() const;
0195 
0196   bool IsVoidType() const;
0197 
0198   /// This is used when you don't care about the signedness of the integer.
0199   bool IsInteger() const;
0200 
0201   bool IsFloat() const;
0202 
0203   /// This is used when you don't care about the signedness of the enum.
0204   bool IsEnumerationType() const;
0205 
0206   bool IsUnscopedEnumerationType() const;
0207 
0208   bool IsIntegerOrUnscopedEnumerationType() const;
0209 
0210   bool IsSigned() const;
0211 
0212   bool IsNullPtrType() const;
0213 
0214   bool IsBoolean() const;
0215 
0216   bool IsEnumerationIntegerTypeSigned() const;
0217 
0218   bool IsScalarOrUnscopedEnumerationType() const;
0219 
0220   bool IsPromotableIntegerType() const;
0221 
0222   bool IsPointerToVoid() const;
0223 
0224   bool IsRecordType() const;
0225 
0226   //// Checks whether `target_base` is a virtual base of `type` (direct or
0227   /// indirect). If it is, stores the first virtual base type on the path from
0228   /// `type` to `target_type`. Parameter "virtual_base" is where the first
0229   /// virtual base type gets stored. Parameter "carry_virtual" is used to
0230   /// denote that we're in a recursive check of virtual base classes and we
0231   /// have already seen a virtual base class (so should only check direct
0232   /// base classes).
0233   /// Note: This may only be defined in TypeSystemClang.
0234   bool IsVirtualBase(CompilerType target_base, CompilerType *virtual_base,
0235                      bool carry_virtual = false) const;
0236 
0237   /// This may only be defined in TypeSystemClang.
0238   bool IsContextuallyConvertibleToBool() const;
0239 
0240   bool IsBasicType() const;
0241 
0242   std::string TypeDescription();
0243 
0244   bool CompareTypes(CompilerType rhs) const;
0245 
0246   const char *GetTypeTag();
0247 
0248   /// Go through the base classes and count non-empty ones.
0249   uint32_t GetNumberOfNonEmptyBaseClasses();
0250 
0251   /// \}
0252 
0253   /// Type Completion.
0254   /// \{
0255   bool GetCompleteType() const;
0256   /// \}
0257 
0258   bool IsForcefullyCompleted() const;
0259 
0260   /// AST related queries.
0261   /// \{
0262   size_t GetPointerByteSize() const;
0263   /// \}
0264 
0265   unsigned GetPtrAuthKey() const;
0266 
0267   unsigned GetPtrAuthDiscriminator() const;
0268 
0269   bool GetPtrAuthAddressDiversity() const;
0270 
0271   /// Accessors.
0272   /// \{
0273 
0274   /// Returns a shared pointer to the type system. The
0275   /// TypeSystem::TypeSystemSPWrapper can be compared for equality.
0276   TypeSystemSPWrapper GetTypeSystem() const;
0277 
0278   ConstString GetTypeName(bool BaseOnly = false) const;
0279 
0280   ConstString GetDisplayTypeName() const;
0281 
0282   ConstString GetMangledTypeName() const;
0283 
0284   uint32_t
0285   GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) const;
0286 
0287   lldb::LanguageType GetMinimumLanguage();
0288 
0289   lldb::opaque_compiler_type_t GetOpaqueQualType() const { return m_type; }
0290 
0291   lldb::TypeClass GetTypeClass() const;
0292 
0293   void SetCompilerType(lldb::TypeSystemWP type_system,
0294                        lldb::opaque_compiler_type_t type);
0295   void SetCompilerType(TypeSystemSPWrapper type_system,
0296                        lldb::opaque_compiler_type_t type);
0297 
0298   unsigned GetTypeQualifiers() const;
0299   /// \}
0300 
0301   /// Creating related types.
0302   /// \{
0303   CompilerType GetArrayElementType(ExecutionContextScope *exe_scope) const;
0304 
0305   CompilerType GetArrayType(uint64_t size) const;
0306 
0307   CompilerType GetCanonicalType() const;
0308 
0309   CompilerType GetFullyUnqualifiedType() const;
0310 
0311   CompilerType GetEnumerationIntegerType() const;
0312 
0313   /// Returns -1 if this isn't a function of if the function doesn't
0314   /// have a prototype Returns a value >= 0 if there is a prototype.
0315   int GetFunctionArgumentCount() const;
0316 
0317   CompilerType GetFunctionArgumentTypeAtIndex(size_t idx) const;
0318 
0319   CompilerType GetFunctionReturnType() const;
0320 
0321   size_t GetNumMemberFunctions() const;
0322 
0323   TypeMemberFunctionImpl GetMemberFunctionAtIndex(size_t idx);
0324 
0325   /// If this type is a reference to a type (L value or R value reference),
0326   /// return a new type with the reference removed, else return the current type
0327   /// itself.
0328   CompilerType GetNonReferenceType() const;
0329 
0330   /// If this type is a pointer type, return the type that the pointer points
0331   /// to, else return an invalid type.
0332   CompilerType GetPointeeType() const;
0333 
0334   /// Return a new CompilerType that is a pointer to this type
0335   CompilerType GetPointerType() const;
0336 
0337   /// Return a new CompilerType that is a L value reference to this type if this
0338   /// type is valid and the type system supports L value references, else return
0339   /// an invalid type.
0340   CompilerType GetLValueReferenceType() const;
0341 
0342   /// Return a new CompilerType that is a R value reference to this type if this
0343   /// type is valid and the type system supports R value references, else return
0344   /// an invalid type.
0345   CompilerType GetRValueReferenceType() const;
0346 
0347   /// Return a new CompilerType adds a const modifier to this type if this type
0348   /// is valid and the type system supports const modifiers, else return an
0349   /// invalid type.
0350   CompilerType AddConstModifier() const;
0351 
0352   /// Return a new CompilerType adds a volatile modifier to this type if this
0353   /// type is valid and the type system supports volatile modifiers, else return
0354   /// an invalid type.
0355   CompilerType AddVolatileModifier() const;
0356 
0357   /// Return a new CompilerType that is the atomic type of this type. If this
0358   /// type is not valid or the type system doesn't support atomic types, this
0359   /// returns an invalid type.
0360   CompilerType GetAtomicType() const;
0361 
0362   /// Return a new CompilerType adds a restrict modifier to this type if this
0363   /// type is valid and the type system supports restrict modifiers, else return
0364   /// an invalid type.
0365   CompilerType AddRestrictModifier() const;
0366 
0367   /// Create a typedef to this type using "name" as the name of the typedef this
0368   /// type is valid and the type system supports typedefs, else return an
0369   /// invalid type.
0370   /// \param payload   The typesystem-specific \p lldb::Type payload.
0371   CompilerType CreateTypedef(const char *name,
0372                              const CompilerDeclContext &decl_ctx,
0373                              uint32_t payload) const;
0374 
0375   /// If the current object represents a typedef type, get the underlying type
0376   CompilerType GetTypedefedType() const;
0377 
0378   /// Create related types using the current type's AST
0379   CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const;
0380 
0381   /// Return a new CompilerType adds a ptrauth modifier from the given 32-bit
0382   /// opaque payload to this type if this type is valid and the type system
0383   /// supports ptrauth modifiers, else return an invalid type. Note that this
0384   /// does not check if this type is a pointer.
0385   CompilerType AddPtrAuthModifier(uint32_t payload) const;
0386   /// \}
0387 
0388   /// Exploring the type.
0389   /// \{
0390   struct IntegralTemplateArgument;
0391 
0392   /// Return the size of the type in bytes.
0393   std::optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope) const;
0394   /// Return the size of the type in bits.
0395   std::optional<uint64_t> GetBitSize(ExecutionContextScope *exe_scope) const;
0396 
0397   lldb::Encoding GetEncoding(uint64_t &count) const;
0398 
0399   lldb::Format GetFormat() const;
0400 
0401   std::optional<size_t> GetTypeBitAlign(ExecutionContextScope *exe_scope) const;
0402 
0403   llvm::Expected<uint32_t>
0404   GetNumChildren(bool omit_empty_base_classes,
0405                  const ExecutionContext *exe_ctx) const;
0406 
0407   lldb::BasicType GetBasicTypeEnumeration() const;
0408 
0409   /// If this type is an enumeration, iterate through all of its enumerators
0410   /// using a callback. If the callback returns true, keep iterating, else abort
0411   /// the iteration.
0412   void ForEachEnumerator(
0413       std::function<bool(const CompilerType &integer_type, ConstString name,
0414                          const llvm::APSInt &value)> const &callback) const;
0415 
0416   uint32_t GetNumFields() const;
0417 
0418   CompilerType GetFieldAtIndex(size_t idx, std::string &name,
0419                                uint64_t *bit_offset_ptr,
0420                                uint32_t *bitfield_bit_size_ptr,
0421                                bool *is_bitfield_ptr) const;
0422 
0423   uint32_t GetNumDirectBaseClasses() const;
0424 
0425   uint32_t GetNumVirtualBaseClasses() const;
0426 
0427   CompilerType GetDirectBaseClassAtIndex(size_t idx,
0428                                          uint32_t *bit_offset_ptr) const;
0429 
0430   CompilerType GetVirtualBaseClassAtIndex(size_t idx,
0431                                           uint32_t *bit_offset_ptr) const;
0432 
0433   CompilerDecl GetStaticFieldWithName(llvm::StringRef name) const;
0434 
0435   uint32_t GetIndexOfFieldWithName(const char *name,
0436                                    CompilerType *field_compiler_type = nullptr,
0437                                    uint64_t *bit_offset_ptr = nullptr,
0438                                    uint32_t *bitfield_bit_size_ptr = nullptr,
0439                                    bool *is_bitfield_ptr = nullptr) const;
0440 
0441   llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex(
0442       ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
0443       bool omit_empty_base_classes, bool ignore_array_bounds,
0444       std::string &child_name, uint32_t &child_byte_size,
0445       int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size,
0446       uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
0447       bool &child_is_deref_of_parent, ValueObject *valobj,
0448       uint64_t &language_flags) const;
0449 
0450   /// Lookup a child given a name. This function will match base class names and
0451   /// member member names in "clang_type" only, not descendants.
0452   uint32_t GetIndexOfChildWithName(llvm::StringRef name,
0453                                    bool omit_empty_base_classes) const;
0454 
0455   /// Lookup a child member given a name. This function will match member names
0456   /// only and will descend into "clang_type" children in search for the first
0457   /// member in this class, or any base class that matches "name".
0458   /// TODO: Return all matches for a given name by returning a
0459   /// vector<vector<uint32_t>>
0460   /// so we catch all names that match a given child name, not just the first.
0461   size_t
0462   GetIndexOfChildMemberWithName(llvm::StringRef name,
0463                                 bool omit_empty_base_classes,
0464                                 std::vector<uint32_t> &child_indexes) const;
0465 
0466   CompilerType GetDirectNestedTypeWithName(llvm::StringRef name) const;
0467 
0468   /// Return the number of template arguments the type has.
0469   /// If expand_pack is true, then variadic argument packs are automatically
0470   /// expanded to their supplied arguments. If it is false an argument pack
0471   /// will only count as 1 argument.
0472   size_t GetNumTemplateArguments(bool expand_pack = false) const;
0473 
0474   // Return the TemplateArgumentKind of the template argument at index idx.
0475   // If expand_pack is true, then variadic argument packs are automatically
0476   // expanded to their supplied arguments. With expand_pack set to false, an
0477   // arguement pack will count as 1 argument and return a type of Pack.
0478   lldb::TemplateArgumentKind
0479   GetTemplateArgumentKind(size_t idx, bool expand_pack = false) const;
0480   CompilerType GetTypeTemplateArgument(size_t idx,
0481                                        bool expand_pack = false) const;
0482 
0483   /// Returns the value of the template argument and its type.
0484   /// If expand_pack is true, then variadic argument packs are automatically
0485   /// expanded to their supplied arguments. With expand_pack set to false, an
0486   /// arguement pack will count as 1 argument and it is invalid to call this
0487   /// method on the pack argument.
0488   std::optional<IntegralTemplateArgument>
0489   GetIntegralTemplateArgument(size_t idx, bool expand_pack = false) const;
0490 
0491   CompilerType GetTypeForFormatters() const;
0492 
0493   LazyBool ShouldPrintAsOneLiner(ValueObject *valobj) const;
0494 
0495   bool IsMeaninglessWithoutDynamicResolution() const;
0496   /// \}
0497 
0498   /// Dumping types.
0499   /// \{
0500 #ifndef NDEBUG
0501   /// Convenience LLVM-style dump method for use in the debugger only.
0502   /// Don't call this function from actual code.
0503   LLVM_DUMP_METHOD void dump() const;
0504 #endif
0505 
0506   bool DumpTypeValue(Stream *s, lldb::Format format, const DataExtractor &data,
0507                      lldb::offset_t data_offset, size_t data_byte_size,
0508                      uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
0509                      ExecutionContextScope *exe_scope);
0510 
0511   /// Dump to stdout.
0512   void DumpTypeDescription(lldb::DescriptionLevel level =
0513                            lldb::eDescriptionLevelFull) const;
0514 
0515   /// Print a description of the type to a stream. The exact implementation
0516   /// varies, but the expectation is that eDescriptionLevelFull returns a
0517   /// source-like representation of the type, whereas eDescriptionLevelVerbose
0518   /// does a dump of the underlying AST if applicable.
0519   void DumpTypeDescription(Stream *s, lldb::DescriptionLevel level =
0520                                           lldb::eDescriptionLevelFull) const;
0521   /// \}
0522 
0523   bool GetValueAsScalar(const DataExtractor &data, lldb::offset_t data_offset,
0524                         size_t data_byte_size, Scalar &value,
0525                         ExecutionContextScope *exe_scope) const;
0526   void Clear() {
0527     m_type_system = {};
0528     m_type = nullptr;
0529   }
0530 
0531 private:
0532 #ifndef NDEBUG
0533   /// If the type is valid, ask the TypeSystem to verify the integrity
0534   /// of the type to catch CompilerTypes that mix and match invalid
0535   /// TypeSystem/Opaque type pairs.
0536   bool Verify() const;
0537 #endif
0538 
0539   lldb::TypeSystemWP m_type_system;
0540   lldb::opaque_compiler_type_t m_type = nullptr;
0541 };
0542 
0543 bool operator==(const CompilerType &lhs, const CompilerType &rhs);
0544 bool operator!=(const CompilerType &lhs, const CompilerType &rhs);
0545 
0546 struct CompilerType::IntegralTemplateArgument {
0547   llvm::APSInt value;
0548   CompilerType type;
0549 };
0550 
0551 } // namespace lldb_private
0552 
0553 #endif // LLDB_SYMBOL_COMPILERTYPE_H