10b57cec5SDimitry Andric //===-- CompilerType.h ------------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 95ffd83dbSDimitry Andric #ifndef LLDB_SYMBOL_COMPILERTYPE_H 105ffd83dbSDimitry Andric #define LLDB_SYMBOL_COMPILERTYPE_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include <functional> 13bdd1243dSDimitry Andric #include <optional> 140b57cec5SDimitry Andric #include <string> 150b57cec5SDimitry Andric #include <vector> 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "lldb/lldb-private.h" 180b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h" 19bdd1243dSDimitry Andric #include "llvm/Support/Casting.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace lldb_private { 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric class DataExtractor; 24bdd1243dSDimitry Andric class TypeSystem; 250b57cec5SDimitry Andric 26e8d8bef9SDimitry Andric /// Generic representation of a type in a programming language. 27480093f4SDimitry Andric /// 28480093f4SDimitry Andric /// This class serves as an abstraction for a type inside one of the TypeSystems 29480093f4SDimitry Andric /// implemented by the language plugins. It does not have any actual logic in it 30480093f4SDimitry Andric /// but only stores an opaque pointer and a pointer to the TypeSystem that 31480093f4SDimitry Andric /// gives meaning to this opaque pointer. All methods of this class should call 32480093f4SDimitry Andric /// their respective method in the TypeSystem interface and pass the opaque 33480093f4SDimitry Andric /// pointer along. 34480093f4SDimitry Andric /// 35480093f4SDimitry Andric /// \see lldb_private::TypeSystem 360b57cec5SDimitry Andric class CompilerType { 370b57cec5SDimitry Andric public: 38480093f4SDimitry Andric /// Creates a CompilerType with the given TypeSystem and opaque compiler type. 39480093f4SDimitry Andric /// 40480093f4SDimitry Andric /// This constructor should only be called from the respective TypeSystem 41480093f4SDimitry Andric /// implementation. 42480093f4SDimitry Andric /// 435ffd83dbSDimitry Andric /// \see lldb_private::TypeSystemClang::GetType(clang::QualType) 44bdd1243dSDimitry Andric CompilerType(lldb::TypeSystemWP type_system, 455f757f3fSDimitry Andric lldb::opaque_compiler_type_t type); 46bdd1243dSDimitry Andric 47bdd1243dSDimitry Andric /// This is a minimal wrapper of a TypeSystem shared pointer as 48bdd1243dSDimitry Andric /// returned by CompilerType which conventien dyn_cast support. 49bdd1243dSDimitry Andric class TypeSystemSPWrapper { 50bdd1243dSDimitry Andric lldb::TypeSystemSP m_typesystem_sp; 51bdd1243dSDimitry Andric 52bdd1243dSDimitry Andric public: 53bdd1243dSDimitry Andric TypeSystemSPWrapper() = default; TypeSystemSPWrapper(lldb::TypeSystemSP typesystem_sp)54bdd1243dSDimitry Andric TypeSystemSPWrapper(lldb::TypeSystemSP typesystem_sp) 55bdd1243dSDimitry Andric : m_typesystem_sp(typesystem_sp) {} 56bdd1243dSDimitry Andric isa_and_nonnull()57bdd1243dSDimitry Andric template <class TypeSystemType> bool isa_and_nonnull() { 58bdd1243dSDimitry Andric if (auto *ts = m_typesystem_sp.get()) 59bdd1243dSDimitry Andric return llvm::isa<TypeSystemType>(ts); 60bdd1243dSDimitry Andric return false; 61bdd1243dSDimitry Andric } 62bdd1243dSDimitry Andric 63bdd1243dSDimitry Andric /// Return a shared_ptr<TypeSystemType> if dyn_cast succeeds. 64bdd1243dSDimitry Andric template <class TypeSystemType> dyn_cast_or_null()65bdd1243dSDimitry Andric std::shared_ptr<TypeSystemType> dyn_cast_or_null() { 66bdd1243dSDimitry Andric if (isa_and_nonnull<TypeSystemType>()) 67bdd1243dSDimitry Andric return std::shared_ptr<TypeSystemType>( 68bdd1243dSDimitry Andric m_typesystem_sp, llvm::cast<TypeSystemType>(m_typesystem_sp.get())); 69bdd1243dSDimitry Andric return nullptr; 70bdd1243dSDimitry Andric } 71bdd1243dSDimitry Andric 72bdd1243dSDimitry Andric explicit operator bool() const { 73bdd1243dSDimitry Andric return static_cast<bool>(m_typesystem_sp); 74bdd1243dSDimitry Andric } 75bdd1243dSDimitry Andric bool operator==(const TypeSystemSPWrapper &other) const; 76bdd1243dSDimitry Andric bool operator!=(const TypeSystemSPWrapper &other) const { 77bdd1243dSDimitry Andric return !(*this == other); 78bdd1243dSDimitry Andric } 79bdd1243dSDimitry Andric 80bdd1243dSDimitry Andric /// Only to be used in a one-off situations like 81bdd1243dSDimitry Andric /// if (typesystem && typesystem->method()) 82bdd1243dSDimitry Andric /// Do not store this pointer! 83bdd1243dSDimitry Andric TypeSystem *operator->() const; 84bdd1243dSDimitry Andric GetSharedPointer()85bdd1243dSDimitry Andric lldb::TypeSystemSP GetSharedPointer() const { return m_typesystem_sp; } 86bdd1243dSDimitry Andric }; 87bdd1243dSDimitry Andric 885f757f3fSDimitry Andric CompilerType(TypeSystemSPWrapper type_system, 895f757f3fSDimitry Andric lldb::opaque_compiler_type_t type); 900b57cec5SDimitry Andric CompilerType(const CompilerType & rhs)910b57cec5SDimitry Andric CompilerType(const CompilerType &rhs) 92bdd1243dSDimitry Andric : m_type_system(rhs.m_type_system), m_type(rhs.m_type) {} 930b57cec5SDimitry Andric 94480093f4SDimitry Andric CompilerType() = default; 950b57cec5SDimitry Andric 965ffd83dbSDimitry Andric /// Operators. 975ffd83dbSDimitry Andric /// \{ 980b57cec5SDimitry Andric const CompilerType &operator=(const CompilerType &rhs) { 990b57cec5SDimitry Andric m_type_system = rhs.m_type_system; 100bdd1243dSDimitry Andric m_type = rhs.m_type; 1010b57cec5SDimitry Andric return *this; 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric bool operator<(const CompilerType &rhs) const { 105bdd1243dSDimitry Andric auto lts = m_type_system.lock(); 106bdd1243dSDimitry Andric auto rts = rhs.m_type_system.lock(); 107bdd1243dSDimitry Andric if (lts.get() == rts.get()) 1080b57cec5SDimitry Andric return m_type < rhs.m_type; 109bdd1243dSDimitry Andric return lts.get() < rts.get(); 1100b57cec5SDimitry Andric } 1115ffd83dbSDimitry Andric /// \} 1125ffd83dbSDimitry Andric 1135ffd83dbSDimitry Andric /// Tests. 1145ffd83dbSDimitry Andric /// \{ 1155ffd83dbSDimitry Andric explicit operator bool() const { 116bdd1243dSDimitry Andric return m_type_system.lock() && m_type; 1175ffd83dbSDimitry Andric } 1180b57cec5SDimitry Andric IsValid()119bdd1243dSDimitry Andric bool IsValid() const { return (bool)*this; } 1200b57cec5SDimitry Andric 121fe6060f1SDimitry Andric bool IsArrayType(CompilerType *element_type = nullptr, 122fe6060f1SDimitry Andric uint64_t *size = nullptr, 123fe6060f1SDimitry Andric bool *is_incomplete = nullptr) const; 1240b57cec5SDimitry Andric 125fe6060f1SDimitry Andric bool IsVectorType(CompilerType *element_type = nullptr, 126fe6060f1SDimitry Andric uint64_t *size = nullptr) const; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric bool IsArrayOfScalarType() const; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric bool IsAggregateType() const; 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric bool IsAnonymousType() const; 1330b57cec5SDimitry Andric 134e8d8bef9SDimitry Andric bool IsScopedEnumerationType() const; 135e8d8bef9SDimitry Andric 1360b57cec5SDimitry Andric bool IsBeingDefined() const; 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric bool IsCharType() const; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric bool IsCompleteType() const; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric bool IsConst() const; 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric bool IsDefined() const; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric bool IsFloatingPointType(uint32_t &count, bool &is_complex) const; 1470b57cec5SDimitry Andric 148e8d8bef9SDimitry Andric bool IsFunctionType() const; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric size_t GetNumberOfFunctionArguments() const; 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric CompilerType GetFunctionArgumentAtIndex(const size_t index) const; 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric bool IsVariadicFunctionType() const; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric bool IsFunctionPointerType() const; 1590b57cec5SDimitry Andric 16006c3fb27SDimitry Andric bool IsMemberFunctionPointerType() const; 16106c3fb27SDimitry Andric 162fe6060f1SDimitry Andric bool 163fe6060f1SDimitry Andric IsBlockPointerType(CompilerType *function_pointer_type_ptr = nullptr) const; 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric bool IsIntegerType(bool &is_signed) const; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric bool IsEnumerationType(bool &is_signed) const; 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric bool IsIntegerOrEnumerationType(bool &is_signed) const; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric bool IsPolymorphicClass() const; 1720b57cec5SDimitry Andric 1735ffd83dbSDimitry Andric /// \param target_type Can pass nullptr. 1745ffd83dbSDimitry Andric bool IsPossibleDynamicType(CompilerType *target_type, bool check_cplusplus, 1755ffd83dbSDimitry Andric bool check_objc) const; 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric bool IsPointerToScalarType() const; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric bool IsRuntimeGeneratedType() const; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric bool IsPointerType(CompilerType *pointee_type = nullptr) const; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric bool IsPointerOrReferenceType(CompilerType *pointee_type = nullptr) const; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric bool IsReferenceType(CompilerType *pointee_type = nullptr, 1860b57cec5SDimitry Andric bool *is_rvalue = nullptr) const; 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric bool ShouldTreatScalarValueAsAddress() const; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric bool IsScalarType() const; 1910b57cec5SDimitry Andric 192bdd1243dSDimitry Andric bool IsTemplateType() const; 193bdd1243dSDimitry Andric 1940b57cec5SDimitry Andric bool IsTypedefType() const; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric bool IsVoidType() const; 1975f757f3fSDimitry Andric 1985f757f3fSDimitry Andric /// This is used when you don't care about the signedness of the integer. 1995f757f3fSDimitry Andric bool IsInteger() const; 2005f757f3fSDimitry Andric 2015f757f3fSDimitry Andric bool IsFloat() const; 2025f757f3fSDimitry Andric 2035f757f3fSDimitry Andric /// This is used when you don't care about the signedness of the enum. 2045f757f3fSDimitry Andric bool IsEnumerationType() const; 2055f757f3fSDimitry Andric 2065f757f3fSDimitry Andric bool IsUnscopedEnumerationType() const; 2075f757f3fSDimitry Andric 2085f757f3fSDimitry Andric bool IsIntegerOrUnscopedEnumerationType() const; 2095f757f3fSDimitry Andric 2105f757f3fSDimitry Andric bool IsSigned() const; 2115f757f3fSDimitry Andric 2125f757f3fSDimitry Andric bool IsNullPtrType() const; 2135f757f3fSDimitry Andric 2145f757f3fSDimitry Andric bool IsBoolean() const; 2155f757f3fSDimitry Andric 2165f757f3fSDimitry Andric bool IsEnumerationIntegerTypeSigned() const; 2175f757f3fSDimitry Andric 2185f757f3fSDimitry Andric bool IsScalarOrUnscopedEnumerationType() const; 2195f757f3fSDimitry Andric 2205f757f3fSDimitry Andric bool IsPromotableIntegerType() const; 2215f757f3fSDimitry Andric 2225f757f3fSDimitry Andric bool IsPointerToVoid() const; 2235f757f3fSDimitry Andric 2245f757f3fSDimitry Andric bool IsRecordType() const; 2255f757f3fSDimitry Andric 2265f757f3fSDimitry Andric //// Checks whether `target_base` is a virtual base of `type` (direct or 2275f757f3fSDimitry Andric /// indirect). If it is, stores the first virtual base type on the path from 2285f757f3fSDimitry Andric /// `type` to `target_type`. Parameter "virtual_base" is where the first 2295f757f3fSDimitry Andric /// virtual base type gets stored. Parameter "carry_virtual" is used to 2305f757f3fSDimitry Andric /// denote that we're in a recursive check of virtual base classes and we 2315f757f3fSDimitry Andric /// have already seen a virtual base class (so should only check direct 2325f757f3fSDimitry Andric /// base classes). 2335f757f3fSDimitry Andric /// Note: This may only be defined in TypeSystemClang. 2345f757f3fSDimitry Andric bool IsVirtualBase(CompilerType target_base, CompilerType *virtual_base, 2355f757f3fSDimitry Andric bool carry_virtual = false) const; 2365f757f3fSDimitry Andric 2375f757f3fSDimitry Andric /// This may only be defined in TypeSystemClang. 2385f757f3fSDimitry Andric bool IsContextuallyConvertibleToBool() const; 2395f757f3fSDimitry Andric 2405f757f3fSDimitry Andric bool IsBasicType() const; 2415f757f3fSDimitry Andric 2425f757f3fSDimitry Andric std::string TypeDescription(); 2435f757f3fSDimitry Andric 2445f757f3fSDimitry Andric bool CompareTypes(CompilerType rhs) const; 2455f757f3fSDimitry Andric 2465f757f3fSDimitry Andric const char *GetTypeTag(); 2475f757f3fSDimitry Andric 2485f757f3fSDimitry Andric /// Go through the base classes and count non-empty ones. 2495f757f3fSDimitry Andric uint32_t GetNumberOfNonEmptyBaseClasses(); 2505f757f3fSDimitry Andric 2515ffd83dbSDimitry Andric /// \} 2520b57cec5SDimitry Andric 2535ffd83dbSDimitry Andric /// Type Completion. 2545ffd83dbSDimitry Andric /// \{ 2550b57cec5SDimitry Andric bool GetCompleteType() const; 2565ffd83dbSDimitry Andric /// \} 2570b57cec5SDimitry Andric 258bdd1243dSDimitry Andric bool IsForcefullyCompleted() const; 259bdd1243dSDimitry Andric 2605ffd83dbSDimitry Andric /// AST related queries. 2615ffd83dbSDimitry Andric /// \{ 2620b57cec5SDimitry Andric size_t GetPointerByteSize() const; 2635ffd83dbSDimitry Andric /// \} 2640b57cec5SDimitry Andric 2655ffd83dbSDimitry Andric /// Accessors. 2665ffd83dbSDimitry Andric /// \{ 2670b57cec5SDimitry Andric 268bdd1243dSDimitry Andric /// Returns a shared pointer to the type system. The 269bdd1243dSDimitry Andric /// TypeSystem::TypeSystemSPWrapper can be compared for equality. 270bdd1243dSDimitry Andric TypeSystemSPWrapper GetTypeSystem() const; 271bdd1243dSDimitry Andric 272bdd1243dSDimitry Andric ConstString GetTypeName(bool BaseOnly = false) const; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric ConstString GetDisplayTypeName() const; 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric uint32_t 2770b57cec5SDimitry Andric GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) const; 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric lldb::LanguageType GetMinimumLanguage(); 2800b57cec5SDimitry Andric GetOpaqueQualType()2810b57cec5SDimitry Andric lldb::opaque_compiler_type_t GetOpaqueQualType() const { return m_type; } 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric lldb::TypeClass GetTypeClass() const; 2840b57cec5SDimitry Andric 285bdd1243dSDimitry Andric void SetCompilerType(lldb::TypeSystemWP type_system, 286bdd1243dSDimitry Andric lldb::opaque_compiler_type_t type); 287bdd1243dSDimitry Andric void SetCompilerType(TypeSystemSPWrapper type_system, 2880b57cec5SDimitry Andric lldb::opaque_compiler_type_t type); 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric unsigned GetTypeQualifiers() const; 2915ffd83dbSDimitry Andric /// \} 2920b57cec5SDimitry Andric 2935ffd83dbSDimitry Andric /// Creating related types. 2945ffd83dbSDimitry Andric /// \{ 295e8d8bef9SDimitry Andric CompilerType GetArrayElementType(ExecutionContextScope *exe_scope) const; 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric CompilerType GetArrayType(uint64_t size) const; 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric CompilerType GetCanonicalType() const; 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric CompilerType GetFullyUnqualifiedType() const; 3020b57cec5SDimitry Andric 303e8d8bef9SDimitry Andric CompilerType GetEnumerationIntegerType() const; 304e8d8bef9SDimitry Andric 3055ffd83dbSDimitry Andric /// Returns -1 if this isn't a function of if the function doesn't 3065ffd83dbSDimitry Andric /// have a prototype Returns a value >= 0 if there is a prototype. 3070b57cec5SDimitry Andric int GetFunctionArgumentCount() const; 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric CompilerType GetFunctionArgumentTypeAtIndex(size_t idx) const; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric CompilerType GetFunctionReturnType() const; 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric size_t GetNumMemberFunctions() const; 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric TypeMemberFunctionImpl GetMemberFunctionAtIndex(size_t idx); 3160b57cec5SDimitry Andric 3175ffd83dbSDimitry Andric /// If this type is a reference to a type (L value or R value reference), 3185ffd83dbSDimitry Andric /// return a new type with the reference removed, else return the current type 3195ffd83dbSDimitry Andric /// itself. 3200b57cec5SDimitry Andric CompilerType GetNonReferenceType() const; 3210b57cec5SDimitry Andric 3225ffd83dbSDimitry Andric /// If this type is a pointer type, return the type that the pointer points 3235ffd83dbSDimitry Andric /// to, else return an invalid type. 3240b57cec5SDimitry Andric CompilerType GetPointeeType() const; 3250b57cec5SDimitry Andric 3265ffd83dbSDimitry Andric /// Return a new CompilerType that is a pointer to this type 3270b57cec5SDimitry Andric CompilerType GetPointerType() const; 3280b57cec5SDimitry Andric 3295ffd83dbSDimitry Andric /// Return a new CompilerType that is a L value reference to this type if this 3305ffd83dbSDimitry Andric /// type is valid and the type system supports L value references, else return 3315ffd83dbSDimitry Andric /// an invalid type. 3320b57cec5SDimitry Andric CompilerType GetLValueReferenceType() const; 3330b57cec5SDimitry Andric 3345ffd83dbSDimitry Andric /// Return a new CompilerType that is a R value reference to this type if this 3355ffd83dbSDimitry Andric /// type is valid and the type system supports R value references, else return 3365ffd83dbSDimitry Andric /// an invalid type. 3370b57cec5SDimitry Andric CompilerType GetRValueReferenceType() const; 3380b57cec5SDimitry Andric 3395ffd83dbSDimitry Andric /// Return a new CompilerType adds a const modifier to this type if this type 3405ffd83dbSDimitry Andric /// is valid and the type system supports const modifiers, else return an 3415ffd83dbSDimitry Andric /// invalid type. 3420b57cec5SDimitry Andric CompilerType AddConstModifier() const; 3430b57cec5SDimitry Andric 3445ffd83dbSDimitry Andric /// Return a new CompilerType adds a volatile modifier to this type if this 3455ffd83dbSDimitry Andric /// type is valid and the type system supports volatile modifiers, else return 3465ffd83dbSDimitry Andric /// an invalid type. 3470b57cec5SDimitry Andric CompilerType AddVolatileModifier() const; 3480b57cec5SDimitry Andric 3495ffd83dbSDimitry Andric /// Return a new CompilerType that is the atomic type of this type. If this 3505ffd83dbSDimitry Andric /// type is not valid or the type system doesn't support atomic types, this 3515ffd83dbSDimitry Andric /// returns an invalid type. 352480093f4SDimitry Andric CompilerType GetAtomicType() const; 353480093f4SDimitry Andric 3545ffd83dbSDimitry Andric /// Return a new CompilerType adds a restrict modifier to this type if this 3555ffd83dbSDimitry Andric /// type is valid and the type system supports restrict modifiers, else return 3565ffd83dbSDimitry Andric /// an invalid type. 3570b57cec5SDimitry Andric CompilerType AddRestrictModifier() const; 3580b57cec5SDimitry Andric 3595ffd83dbSDimitry Andric /// Create a typedef to this type using "name" as the name of the typedef this 3605ffd83dbSDimitry Andric /// type is valid and the type system supports typedefs, else return an 3615ffd83dbSDimitry Andric /// invalid type. 3625ffd83dbSDimitry Andric /// \param payload The typesystem-specific \p lldb::Type payload. 3630b57cec5SDimitry Andric CompilerType CreateTypedef(const char *name, 3645ffd83dbSDimitry Andric const CompilerDeclContext &decl_ctx, 3655ffd83dbSDimitry Andric uint32_t payload) const; 3660b57cec5SDimitry Andric 3675ffd83dbSDimitry Andric /// If the current object represents a typedef type, get the underlying type 3680b57cec5SDimitry Andric CompilerType GetTypedefedType() const; 3690b57cec5SDimitry Andric 3705ffd83dbSDimitry Andric /// Create related types using the current type's AST 3710b57cec5SDimitry Andric CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const; 3725ffd83dbSDimitry Andric /// \} 3730b57cec5SDimitry Andric 3745ffd83dbSDimitry Andric /// Exploring the type. 3755ffd83dbSDimitry Andric /// \{ 3760b57cec5SDimitry Andric struct IntegralTemplateArgument; 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric /// Return the size of the type in bytes. 379bdd1243dSDimitry Andric std::optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope) const; 3800b57cec5SDimitry Andric /// Return the size of the type in bits. 381bdd1243dSDimitry Andric std::optional<uint64_t> GetBitSize(ExecutionContextScope *exe_scope) const; 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric lldb::Encoding GetEncoding(uint64_t &count) const; 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric lldb::Format GetFormat() const; 3860b57cec5SDimitry Andric 387bdd1243dSDimitry Andric std::optional<size_t> GetTypeBitAlign(ExecutionContextScope *exe_scope) const; 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric uint32_t GetNumChildren(bool omit_empty_base_classes, 3900b57cec5SDimitry Andric const ExecutionContext *exe_ctx) const; 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric lldb::BasicType GetBasicTypeEnumeration() const; 3930b57cec5SDimitry Andric 3945ffd83dbSDimitry Andric /// If this type is an enumeration, iterate through all of its enumerators 3955ffd83dbSDimitry Andric /// using a callback. If the callback returns true, keep iterating, else abort 3965ffd83dbSDimitry Andric /// the iteration. 3970b57cec5SDimitry Andric void ForEachEnumerator( 3985ffd83dbSDimitry Andric std::function<bool(const CompilerType &integer_type, ConstString name, 3990b57cec5SDimitry Andric const llvm::APSInt &value)> const &callback) const; 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric uint32_t GetNumFields() const; 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric CompilerType GetFieldAtIndex(size_t idx, std::string &name, 4040b57cec5SDimitry Andric uint64_t *bit_offset_ptr, 4050b57cec5SDimitry Andric uint32_t *bitfield_bit_size_ptr, 4060b57cec5SDimitry Andric bool *is_bitfield_ptr) const; 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric uint32_t GetNumDirectBaseClasses() const; 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric uint32_t GetNumVirtualBaseClasses() const; 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric CompilerType GetDirectBaseClassAtIndex(size_t idx, 4130b57cec5SDimitry Andric uint32_t *bit_offset_ptr) const; 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric CompilerType GetVirtualBaseClassAtIndex(size_t idx, 4160b57cec5SDimitry Andric uint32_t *bit_offset_ptr) const; 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric uint32_t GetIndexOfFieldWithName(const char *name, 4190b57cec5SDimitry Andric CompilerType *field_compiler_type = nullptr, 4200b57cec5SDimitry Andric uint64_t *bit_offset_ptr = nullptr, 4210b57cec5SDimitry Andric uint32_t *bitfield_bit_size_ptr = nullptr, 4220b57cec5SDimitry Andric bool *is_bitfield_ptr = nullptr) const; 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric CompilerType GetChildCompilerTypeAtIndex( 4250b57cec5SDimitry Andric ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, 4260b57cec5SDimitry Andric bool omit_empty_base_classes, bool ignore_array_bounds, 4270b57cec5SDimitry Andric std::string &child_name, uint32_t &child_byte_size, 4280b57cec5SDimitry Andric int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, 4290b57cec5SDimitry Andric uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, 4300b57cec5SDimitry Andric bool &child_is_deref_of_parent, ValueObject *valobj, 4310b57cec5SDimitry Andric uint64_t &language_flags) const; 4320b57cec5SDimitry Andric 4335ffd83dbSDimitry Andric /// Lookup a child given a name. This function will match base class names and 4345ffd83dbSDimitry Andric /// member member names in "clang_type" only, not descendants. 43506c3fb27SDimitry Andric uint32_t GetIndexOfChildWithName(llvm::StringRef name, 4360b57cec5SDimitry Andric bool omit_empty_base_classes) const; 4370b57cec5SDimitry Andric 4385ffd83dbSDimitry Andric /// Lookup a child member given a name. This function will match member names 4395ffd83dbSDimitry Andric /// only and will descend into "clang_type" children in search for the first 4405ffd83dbSDimitry Andric /// member in this class, or any base class that matches "name". 4415ffd83dbSDimitry Andric /// TODO: Return all matches for a given name by returning a 4425ffd83dbSDimitry Andric /// vector<vector<uint32_t>> 4435ffd83dbSDimitry Andric /// so we catch all names that match a given child name, not just the first. 4440b57cec5SDimitry Andric size_t 44506c3fb27SDimitry Andric GetIndexOfChildMemberWithName(llvm::StringRef name, 44606c3fb27SDimitry Andric bool omit_empty_base_classes, 4470b57cec5SDimitry Andric std::vector<uint32_t> &child_indexes) const; 4480b57cec5SDimitry Andric 449f3fd488fSDimitry Andric /// Return the number of template arguments the type has. 450f3fd488fSDimitry Andric /// If expand_pack is true, then variadic argument packs are automatically 451f3fd488fSDimitry Andric /// expanded to their supplied arguments. If it is false an argument pack 452f3fd488fSDimitry Andric /// will only count as 1 argument. 453f3fd488fSDimitry Andric size_t GetNumTemplateArguments(bool expand_pack = false) const; 4540b57cec5SDimitry Andric 455f3fd488fSDimitry Andric // Return the TemplateArgumentKind of the template argument at index idx. 456f3fd488fSDimitry Andric // If expand_pack is true, then variadic argument packs are automatically 457f3fd488fSDimitry Andric // expanded to their supplied arguments. With expand_pack set to false, an 458f3fd488fSDimitry Andric // arguement pack will count as 1 argument and return a type of Pack. 459f3fd488fSDimitry Andric lldb::TemplateArgumentKind 460f3fd488fSDimitry Andric GetTemplateArgumentKind(size_t idx, bool expand_pack = false) const; 461f3fd488fSDimitry Andric CompilerType GetTypeTemplateArgument(size_t idx, 462f3fd488fSDimitry Andric bool expand_pack = false) const; 4630b57cec5SDimitry Andric 4645ffd83dbSDimitry Andric /// Returns the value of the template argument and its type. 465f3fd488fSDimitry Andric /// If expand_pack is true, then variadic argument packs are automatically 466f3fd488fSDimitry Andric /// expanded to their supplied arguments. With expand_pack set to false, an 467f3fd488fSDimitry Andric /// arguement pack will count as 1 argument and it is invalid to call this 468f3fd488fSDimitry Andric /// method on the pack argument. 469bdd1243dSDimitry Andric std::optional<IntegralTemplateArgument> 470f3fd488fSDimitry Andric GetIntegralTemplateArgument(size_t idx, bool expand_pack = false) const; 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric CompilerType GetTypeForFormatters() const; 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric LazyBool ShouldPrintAsOneLiner(ValueObject *valobj) const; 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric bool IsMeaninglessWithoutDynamicResolution() const; 4775ffd83dbSDimitry Andric /// \} 4780b57cec5SDimitry Andric 4795ffd83dbSDimitry Andric /// Dumping types. 4805ffd83dbSDimitry Andric /// \{ 4810b57cec5SDimitry Andric #ifndef NDEBUG 4820b57cec5SDimitry Andric /// Convenience LLVM-style dump method for use in the debugger only. 4830b57cec5SDimitry Andric /// Don't call this function from actual code. 4840b57cec5SDimitry Andric LLVM_DUMP_METHOD void dump() const; 4850b57cec5SDimitry Andric #endif 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric bool DumpTypeValue(Stream *s, lldb::Format format, const DataExtractor &data, 4880b57cec5SDimitry Andric lldb::offset_t data_offset, size_t data_byte_size, 4890b57cec5SDimitry Andric uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, 4900b57cec5SDimitry Andric ExecutionContextScope *exe_scope); 4910b57cec5SDimitry Andric 4925ffd83dbSDimitry Andric /// Dump to stdout. 4935ffd83dbSDimitry Andric void DumpTypeDescription(lldb::DescriptionLevel level = 4945ffd83dbSDimitry Andric lldb::eDescriptionLevelFull) const; 4950b57cec5SDimitry Andric 4965ffd83dbSDimitry Andric /// Print a description of the type to a stream. The exact implementation 4975ffd83dbSDimitry Andric /// varies, but the expectation is that eDescriptionLevelFull returns a 4985ffd83dbSDimitry Andric /// source-like representation of the type, whereas eDescriptionLevelVerbose 4995ffd83dbSDimitry Andric /// does a dump of the underlying AST if applicable. 5005ffd83dbSDimitry Andric void DumpTypeDescription(Stream *s, lldb::DescriptionLevel level = 5015ffd83dbSDimitry Andric lldb::eDescriptionLevelFull) const; 5025ffd83dbSDimitry Andric /// \} 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric bool GetValueAsScalar(const DataExtractor &data, lldb::offset_t data_offset, 505e8d8bef9SDimitry Andric size_t data_byte_size, Scalar &value, 506e8d8bef9SDimitry Andric ExecutionContextScope *exe_scope) const; Clear()5070b57cec5SDimitry Andric void Clear() { 508bdd1243dSDimitry Andric m_type_system = {}; 5090b57cec5SDimitry Andric m_type = nullptr; 5100b57cec5SDimitry Andric } 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric private: 5135ffd83dbSDimitry Andric #ifndef NDEBUG 5145ffd83dbSDimitry Andric /// If the type is valid, ask the TypeSystem to verify the integrity 5155ffd83dbSDimitry Andric /// of the type to catch CompilerTypes that mix and match invalid 5165ffd83dbSDimitry Andric /// TypeSystem/Opaque type pairs. 5175ffd83dbSDimitry Andric bool Verify() const; 5185ffd83dbSDimitry Andric #endif 5195ffd83dbSDimitry Andric 520bdd1243dSDimitry Andric lldb::TypeSystemWP m_type_system; 521480093f4SDimitry Andric lldb::opaque_compiler_type_t m_type = nullptr; 5220b57cec5SDimitry Andric }; 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric bool operator==(const CompilerType &lhs, const CompilerType &rhs); 5250b57cec5SDimitry Andric bool operator!=(const CompilerType &lhs, const CompilerType &rhs); 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric struct CompilerType::IntegralTemplateArgument { 5280b57cec5SDimitry Andric llvm::APSInt value; 5290b57cec5SDimitry Andric CompilerType type; 5300b57cec5SDimitry Andric }; 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric } // namespace lldb_private 5330b57cec5SDimitry Andric 5345ffd83dbSDimitry Andric #endif // LLDB_SYMBOL_COMPILERTYPE_H 535