1 //===-- CompilerType.h ------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SYMBOL_COMPILERTYPE_H 10 #define LLDB_SYMBOL_COMPILERTYPE_H 11 12 #include <functional> 13 #include <string> 14 #include <vector> 15 16 #include "lldb/lldb-private.h" 17 #include "llvm/ADT/APSInt.h" 18 19 namespace lldb_private { 20 21 class DataExtractor; 22 23 /// Generic representation of a type in a programming language. 24 /// 25 /// This class serves as an abstraction for a type inside one of the TypeSystems 26 /// implemented by the language plugins. It does not have any actual logic in it 27 /// but only stores an opaque pointer and a pointer to the TypeSystem that 28 /// gives meaning to this opaque pointer. All methods of this class should call 29 /// their respective method in the TypeSystem interface and pass the opaque 30 /// pointer along. 31 /// 32 /// \see lldb_private::TypeSystem 33 class CompilerType { 34 public: 35 /// Creates a CompilerType with the given TypeSystem and opaque compiler type. 36 /// 37 /// This constructor should only be called from the respective TypeSystem 38 /// implementation. 39 /// 40 /// \see lldb_private::TypeSystemClang::GetType(clang::QualType) CompilerType(TypeSystem * type_system,lldb::opaque_compiler_type_t type)41 CompilerType(TypeSystem *type_system, lldb::opaque_compiler_type_t type) 42 : m_type(type), m_type_system(type_system) { 43 assert(Verify() && "verification failed"); 44 } 45 CompilerType(const CompilerType & rhs)46 CompilerType(const CompilerType &rhs) 47 : m_type(rhs.m_type), m_type_system(rhs.m_type_system) {} 48 49 CompilerType() = default; 50 51 /// Operators. 52 /// \{ 53 const CompilerType &operator=(const CompilerType &rhs) { 54 m_type = rhs.m_type; 55 m_type_system = rhs.m_type_system; 56 return *this; 57 } 58 59 bool operator<(const CompilerType &rhs) const { 60 if (m_type_system == rhs.m_type_system) 61 return m_type < rhs.m_type; 62 return m_type_system < rhs.m_type_system; 63 } 64 /// \} 65 66 /// Tests. 67 /// \{ 68 explicit operator bool() const { 69 return m_type != nullptr && m_type_system != nullptr; 70 } 71 IsValid()72 bool IsValid() const { return m_type != nullptr && m_type_system != nullptr; } 73 74 bool IsArrayType(CompilerType *element_type, uint64_t *size, 75 bool *is_incomplete) const; 76 77 bool IsVectorType(CompilerType *element_type, uint64_t *size) const; 78 79 bool IsArrayOfScalarType() const; 80 81 bool IsAggregateType() const; 82 83 bool IsAnonymousType() const; 84 85 bool IsBeingDefined() const; 86 87 bool IsCharType() const; 88 89 bool IsCompleteType() const; 90 91 bool IsConst() const; 92 93 bool IsCStringType(uint32_t &length) const; 94 95 bool IsDefined() const; 96 97 bool IsFloatingPointType(uint32_t &count, bool &is_complex) const; 98 99 bool IsFunctionType() const; 100 101 uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const; 102 103 size_t GetNumberOfFunctionArguments() const; 104 105 CompilerType GetFunctionArgumentAtIndex(const size_t index) const; 106 107 bool IsVariadicFunctionType() const; 108 109 bool IsFunctionPointerType() const; 110 111 bool IsBlockPointerType(CompilerType *function_pointer_type_ptr) const; 112 113 bool IsIntegerType(bool &is_signed) const; 114 115 bool IsEnumerationType(bool &is_signed) const; 116 117 bool IsIntegerOrEnumerationType(bool &is_signed) const; 118 119 bool IsPolymorphicClass() const; 120 121 /// \param target_type Can pass nullptr. 122 bool IsPossibleDynamicType(CompilerType *target_type, bool check_cplusplus, 123 bool check_objc) const; 124 125 bool IsPointerToScalarType() const; 126 127 bool IsRuntimeGeneratedType() const; 128 129 bool IsPointerType(CompilerType *pointee_type = nullptr) const; 130 131 bool IsPointerOrReferenceType(CompilerType *pointee_type = nullptr) const; 132 133 bool IsReferenceType(CompilerType *pointee_type = nullptr, 134 bool *is_rvalue = nullptr) const; 135 136 bool ShouldTreatScalarValueAsAddress() const; 137 138 bool IsScalarType() const; 139 140 bool IsTypedefType() const; 141 142 bool IsVoidType() const; 143 /// \} 144 145 /// Type Completion. 146 /// \{ 147 bool GetCompleteType() const; 148 /// \} 149 150 /// AST related queries. 151 /// \{ 152 size_t GetPointerByteSize() const; 153 /// \} 154 155 /// Accessors. 156 /// \{ GetTypeSystem()157 TypeSystem *GetTypeSystem() const { return m_type_system; } 158 159 ConstString GetTypeName() const; 160 161 ConstString GetDisplayTypeName() const; 162 163 uint32_t 164 GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) const; 165 166 lldb::LanguageType GetMinimumLanguage(); 167 GetOpaqueQualType()168 lldb::opaque_compiler_type_t GetOpaqueQualType() const { return m_type; } 169 170 lldb::TypeClass GetTypeClass() const; 171 172 void SetCompilerType(TypeSystem *type_system, 173 lldb::opaque_compiler_type_t type); 174 175 unsigned GetTypeQualifiers() const; 176 /// \} 177 178 /// Creating related types. 179 /// \{ 180 CompilerType GetArrayElementType(ExecutionContextScope *exe_scope) const; 181 182 CompilerType GetArrayType(uint64_t size) const; 183 184 CompilerType GetCanonicalType() const; 185 186 CompilerType GetFullyUnqualifiedType() const; 187 188 /// Returns -1 if this isn't a function of if the function doesn't 189 /// have a prototype Returns a value >= 0 if there is a prototype. 190 int GetFunctionArgumentCount() const; 191 192 CompilerType GetFunctionArgumentTypeAtIndex(size_t idx) const; 193 194 CompilerType GetFunctionReturnType() const; 195 196 size_t GetNumMemberFunctions() const; 197 198 TypeMemberFunctionImpl GetMemberFunctionAtIndex(size_t idx); 199 200 /// If this type is a reference to a type (L value or R value reference), 201 /// return a new type with the reference removed, else return the current type 202 /// itself. 203 CompilerType GetNonReferenceType() const; 204 205 /// If this type is a pointer type, return the type that the pointer points 206 /// to, else return an invalid type. 207 CompilerType GetPointeeType() const; 208 209 /// Return a new CompilerType that is a pointer to this type 210 CompilerType GetPointerType() const; 211 212 /// Return a new CompilerType that is a L value reference to this type if this 213 /// type is valid and the type system supports L value references, else return 214 /// an invalid type. 215 CompilerType GetLValueReferenceType() const; 216 217 /// Return a new CompilerType that is a R value reference to this type if this 218 /// type is valid and the type system supports R value references, else return 219 /// an invalid type. 220 CompilerType GetRValueReferenceType() const; 221 222 /// Return a new CompilerType adds a const modifier to this type if this type 223 /// is valid and the type system supports const modifiers, else return an 224 /// invalid type. 225 CompilerType AddConstModifier() const; 226 227 /// Return a new CompilerType adds a volatile modifier to this type if this 228 /// type is valid and the type system supports volatile modifiers, else return 229 /// an invalid type. 230 CompilerType AddVolatileModifier() const; 231 232 /// Return a new CompilerType that is the atomic type of this type. If this 233 /// type is not valid or the type system doesn't support atomic types, this 234 /// returns an invalid type. 235 CompilerType GetAtomicType() const; 236 237 /// Return a new CompilerType adds a restrict modifier to this type if this 238 /// type is valid and the type system supports restrict modifiers, else return 239 /// an invalid type. 240 CompilerType AddRestrictModifier() const; 241 242 /// Create a typedef to this type using "name" as the name of the typedef this 243 /// type is valid and the type system supports typedefs, else return an 244 /// invalid type. 245 /// \param payload The typesystem-specific \p lldb::Type payload. 246 CompilerType CreateTypedef(const char *name, 247 const CompilerDeclContext &decl_ctx, 248 uint32_t payload) const; 249 250 /// If the current object represents a typedef type, get the underlying type 251 CompilerType GetTypedefedType() const; 252 253 /// Create related types using the current type's AST 254 CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const; 255 /// \} 256 257 /// Exploring the type. 258 /// \{ 259 struct IntegralTemplateArgument; 260 261 /// Return the size of the type in bytes. 262 llvm::Optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope) const; 263 /// Return the size of the type in bits. 264 llvm::Optional<uint64_t> GetBitSize(ExecutionContextScope *exe_scope) const; 265 266 lldb::Encoding GetEncoding(uint64_t &count) const; 267 268 lldb::Format GetFormat() const; 269 270 llvm::Optional<size_t> 271 GetTypeBitAlign(ExecutionContextScope *exe_scope) const; 272 273 uint32_t GetNumChildren(bool omit_empty_base_classes, 274 const ExecutionContext *exe_ctx) const; 275 276 lldb::BasicType GetBasicTypeEnumeration() const; 277 278 static lldb::BasicType GetBasicTypeEnumeration(ConstString name); 279 280 /// If this type is an enumeration, iterate through all of its enumerators 281 /// using a callback. If the callback returns true, keep iterating, else abort 282 /// the iteration. 283 void ForEachEnumerator( 284 std::function<bool(const CompilerType &integer_type, ConstString name, 285 const llvm::APSInt &value)> const &callback) const; 286 287 uint32_t GetNumFields() const; 288 289 CompilerType GetFieldAtIndex(size_t idx, std::string &name, 290 uint64_t *bit_offset_ptr, 291 uint32_t *bitfield_bit_size_ptr, 292 bool *is_bitfield_ptr) const; 293 294 uint32_t GetNumDirectBaseClasses() const; 295 296 uint32_t GetNumVirtualBaseClasses() const; 297 298 CompilerType GetDirectBaseClassAtIndex(size_t idx, 299 uint32_t *bit_offset_ptr) const; 300 301 CompilerType GetVirtualBaseClassAtIndex(size_t idx, 302 uint32_t *bit_offset_ptr) const; 303 304 uint32_t GetIndexOfFieldWithName(const char *name, 305 CompilerType *field_compiler_type = nullptr, 306 uint64_t *bit_offset_ptr = nullptr, 307 uint32_t *bitfield_bit_size_ptr = nullptr, 308 bool *is_bitfield_ptr = nullptr) const; 309 310 CompilerType GetChildCompilerTypeAtIndex( 311 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, 312 bool omit_empty_base_classes, bool ignore_array_bounds, 313 std::string &child_name, uint32_t &child_byte_size, 314 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, 315 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, 316 bool &child_is_deref_of_parent, ValueObject *valobj, 317 uint64_t &language_flags) const; 318 319 /// Lookup a child given a name. This function will match base class names and 320 /// member member names in "clang_type" only, not descendants. 321 uint32_t GetIndexOfChildWithName(const char *name, 322 bool omit_empty_base_classes) const; 323 324 /// Lookup a child member given a name. This function will match member names 325 /// only and will descend into "clang_type" children in search for the first 326 /// member in this class, or any base class that matches "name". 327 /// TODO: Return all matches for a given name by returning a 328 /// vector<vector<uint32_t>> 329 /// so we catch all names that match a given child name, not just the first. 330 size_t 331 GetIndexOfChildMemberWithName(const char *name, bool omit_empty_base_classes, 332 std::vector<uint32_t> &child_indexes) const; 333 334 size_t GetNumTemplateArguments() const; 335 336 lldb::TemplateArgumentKind GetTemplateArgumentKind(size_t idx) const; 337 CompilerType GetTypeTemplateArgument(size_t idx) const; 338 339 /// Returns the value of the template argument and its type. 340 llvm::Optional<IntegralTemplateArgument> 341 GetIntegralTemplateArgument(size_t idx) const; 342 343 CompilerType GetTypeForFormatters() const; 344 345 LazyBool ShouldPrintAsOneLiner(ValueObject *valobj) const; 346 347 bool IsMeaninglessWithoutDynamicResolution() const; 348 /// \} 349 350 /// Dumping types. 351 /// \{ 352 #ifndef NDEBUG 353 /// Convenience LLVM-style dump method for use in the debugger only. 354 /// Don't call this function from actual code. 355 LLVM_DUMP_METHOD void dump() const; 356 #endif 357 358 void DumpValue(ExecutionContext *exe_ctx, Stream *s, lldb::Format format, 359 const DataExtractor &data, lldb::offset_t data_offset, 360 size_t data_byte_size, uint32_t bitfield_bit_size, 361 uint32_t bitfield_bit_offset, bool show_types, 362 bool show_summary, bool verbose, uint32_t depth); 363 364 bool DumpTypeValue(Stream *s, lldb::Format format, const DataExtractor &data, 365 lldb::offset_t data_offset, size_t data_byte_size, 366 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, 367 ExecutionContextScope *exe_scope); 368 369 void DumpSummary(ExecutionContext *exe_ctx, Stream *s, 370 const DataExtractor &data, lldb::offset_t data_offset, 371 size_t data_byte_size); 372 373 /// Dump to stdout. 374 void DumpTypeDescription(lldb::DescriptionLevel level = 375 lldb::eDescriptionLevelFull) const; 376 377 /// Print a description of the type to a stream. The exact implementation 378 /// varies, but the expectation is that eDescriptionLevelFull returns a 379 /// source-like representation of the type, whereas eDescriptionLevelVerbose 380 /// does a dump of the underlying AST if applicable. 381 void DumpTypeDescription(Stream *s, lldb::DescriptionLevel level = 382 lldb::eDescriptionLevelFull) const; 383 /// \} 384 385 bool GetValueAsScalar(const DataExtractor &data, lldb::offset_t data_offset, 386 size_t data_byte_size, Scalar &value, 387 ExecutionContextScope *exe_scope) const; Clear()388 void Clear() { 389 m_type = nullptr; 390 m_type_system = nullptr; 391 } 392 393 private: 394 #ifndef NDEBUG 395 /// If the type is valid, ask the TypeSystem to verify the integrity 396 /// of the type to catch CompilerTypes that mix and match invalid 397 /// TypeSystem/Opaque type pairs. 398 bool Verify() const; 399 #endif 400 401 lldb::opaque_compiler_type_t m_type = nullptr; 402 TypeSystem *m_type_system = nullptr; 403 }; 404 405 bool operator==(const CompilerType &lhs, const CompilerType &rhs); 406 bool operator!=(const CompilerType &lhs, const CompilerType &rhs); 407 408 struct CompilerType::IntegralTemplateArgument { 409 llvm::APSInt value; 410 CompilerType type; 411 }; 412 413 } // namespace lldb_private 414 415 #endif // LLDB_SYMBOL_COMPILERTYPE_H 416