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