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 <optional> 14 #include <string> 15 #include <vector> 16 17 #include "lldb/Utility/Scalar.h" 18 #include "lldb/lldb-private.h" 19 #include "llvm/ADT/APSInt.h" 20 #include "llvm/Support/Casting.h" 21 22 namespace lldb_private { 23 24 class DataExtractor; 25 class TypeSystem; 26 27 /// Generic representation of a type in a programming language. 28 /// 29 /// This class serves as an abstraction for a type inside one of the TypeSystems 30 /// implemented by the language plugins. It does not have any actual logic in it 31 /// but only stores an opaque pointer and a pointer to the TypeSystem that 32 /// gives meaning to this opaque pointer. All methods of this class should call 33 /// their respective method in the TypeSystem interface and pass the opaque 34 /// pointer along. 35 /// 36 /// \see lldb_private::TypeSystem 37 class CompilerType { 38 public: 39 /// Creates a CompilerType with the given TypeSystem and opaque compiler type. 40 /// 41 /// This constructor should only be called from the respective TypeSystem 42 /// implementation. 43 /// 44 /// \see lldb_private::TypeSystemClang::GetType(clang::QualType) 45 CompilerType(lldb::TypeSystemWP type_system, 46 lldb::opaque_compiler_type_t type); 47 48 /// This is a minimal wrapper of a TypeSystem shared pointer as 49 /// returned by CompilerType which conventien dyn_cast support. 50 class TypeSystemSPWrapper { 51 lldb::TypeSystemSP m_typesystem_sp; 52 53 public: 54 TypeSystemSPWrapper() = default; TypeSystemSPWrapper(lldb::TypeSystemSP typesystem_sp)55 TypeSystemSPWrapper(lldb::TypeSystemSP typesystem_sp) 56 : m_typesystem_sp(typesystem_sp) {} 57 isa_and_nonnull()58 template <class TypeSystemType> bool isa_and_nonnull() { 59 if (auto *ts = m_typesystem_sp.get()) 60 return llvm::isa<TypeSystemType>(ts); 61 return false; 62 } 63 64 /// Return a shared_ptr<TypeSystemType> if dyn_cast succeeds. 65 template <class TypeSystemType> dyn_cast_or_null()66 std::shared_ptr<TypeSystemType> dyn_cast_or_null() { 67 if (isa_and_nonnull<TypeSystemType>()) 68 return std::shared_ptr<TypeSystemType>( 69 m_typesystem_sp, llvm::cast<TypeSystemType>(m_typesystem_sp.get())); 70 return nullptr; 71 } 72 73 explicit operator bool() const { 74 return static_cast<bool>(m_typesystem_sp); 75 } 76 bool operator==(const TypeSystemSPWrapper &other) const; 77 bool operator!=(const TypeSystemSPWrapper &other) const { 78 return !(*this == other); 79 } 80 81 /// Only to be used in a one-off situations like 82 /// if (typesystem && typesystem->method()) 83 /// Do not store this pointer! 84 TypeSystem *operator->() const; 85 GetSharedPointer()86 lldb::TypeSystemSP GetSharedPointer() const { return m_typesystem_sp; } 87 }; 88 89 CompilerType(TypeSystemSPWrapper type_system, 90 lldb::opaque_compiler_type_t type); 91 CompilerType(const CompilerType & rhs)92 CompilerType(const CompilerType &rhs) 93 : m_type_system(rhs.m_type_system), m_type(rhs.m_type) {} 94 95 CompilerType() = default; 96 97 /// Operators. 98 /// \{ 99 const CompilerType &operator=(const CompilerType &rhs) { 100 m_type_system = rhs.m_type_system; 101 m_type = rhs.m_type; 102 return *this; 103 } 104 105 bool operator<(const CompilerType &rhs) const { 106 auto lts = m_type_system.lock(); 107 auto rts = rhs.m_type_system.lock(); 108 if (lts.get() == rts.get()) 109 return m_type < rhs.m_type; 110 return lts.get() < rts.get(); 111 } 112 /// \} 113 114 /// Tests. 115 /// \{ 116 explicit operator bool() const { 117 return m_type_system.lock() && m_type; 118 } 119 IsValid()120 bool IsValid() const { return (bool)*this; } 121 122 bool IsArrayType(CompilerType *element_type = nullptr, 123 uint64_t *size = nullptr, 124 bool *is_incomplete = nullptr) const; 125 126 bool IsVectorType(CompilerType *element_type = nullptr, 127 uint64_t *size = nullptr) const; 128 129 bool IsArrayOfScalarType() const; 130 131 bool IsAggregateType() const; 132 133 bool IsAnonymousType() const; 134 135 bool IsScopedEnumerationType() const; 136 137 bool IsBeingDefined() const; 138 139 bool IsCharType() const; 140 141 bool IsCompleteType() const; 142 143 bool IsConst() const; 144 145 bool IsDefined() const; 146 147 bool IsFloatingPointType(uint32_t &count, bool &is_complex) const; 148 149 bool IsFunctionType() const; 150 151 uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const; 152 153 size_t GetNumberOfFunctionArguments() const; 154 155 CompilerType GetFunctionArgumentAtIndex(const size_t index) const; 156 157 bool IsVariadicFunctionType() const; 158 159 bool IsFunctionPointerType() const; 160 161 bool IsMemberFunctionPointerType() const; 162 163 bool 164 IsBlockPointerType(CompilerType *function_pointer_type_ptr = nullptr) const; 165 166 bool IsIntegerType(bool &is_signed) const; 167 168 bool IsEnumerationType(bool &is_signed) const; 169 170 bool IsIntegerOrEnumerationType(bool &is_signed) const; 171 172 bool IsPolymorphicClass() const; 173 174 /// \param target_type Can pass nullptr. 175 bool IsPossibleDynamicType(CompilerType *target_type, bool check_cplusplus, 176 bool check_objc) const; 177 178 bool IsPointerToScalarType() const; 179 180 bool IsRuntimeGeneratedType() const; 181 182 bool IsPointerType(CompilerType *pointee_type = nullptr) const; 183 184 bool IsPointerOrReferenceType(CompilerType *pointee_type = nullptr) const; 185 186 bool IsReferenceType(CompilerType *pointee_type = nullptr, 187 bool *is_rvalue = nullptr) const; 188 189 bool ShouldTreatScalarValueAsAddress() const; 190 191 bool IsScalarType() const; 192 193 bool IsTemplateType() const; 194 195 bool IsTypedefType() const; 196 197 bool IsVoidType() const; 198 199 /// This is used when you don't care about the signedness of the integer. 200 bool IsInteger() const; 201 202 bool IsFloat() const; 203 204 /// This is used when you don't care about the signedness of the enum. 205 bool IsEnumerationType() const; 206 207 bool IsUnscopedEnumerationType() const; 208 209 bool IsIntegerOrUnscopedEnumerationType() const; 210 211 bool IsSigned() const; 212 213 bool IsNullPtrType() const; 214 215 bool IsBoolean() const; 216 217 bool IsEnumerationIntegerTypeSigned() const; 218 219 bool IsScalarOrUnscopedEnumerationType() const; 220 221 bool IsPromotableIntegerType() const; 222 223 bool IsPointerToVoid() const; 224 225 bool IsRecordType() const; 226 227 //// Checks whether `target_base` is a virtual base of `type` (direct or 228 /// indirect). If it is, stores the first virtual base type on the path from 229 /// `type` to `target_type`. Parameter "virtual_base" is where the first 230 /// virtual base type gets stored. Parameter "carry_virtual" is used to 231 /// denote that we're in a recursive check of virtual base classes and we 232 /// have already seen a virtual base class (so should only check direct 233 /// base classes). 234 /// Note: This may only be defined in TypeSystemClang. 235 bool IsVirtualBase(CompilerType target_base, CompilerType *virtual_base, 236 bool carry_virtual = false) const; 237 238 /// This may only be defined in TypeSystemClang. 239 bool IsContextuallyConvertibleToBool() const; 240 241 bool IsBasicType() const; 242 243 std::string TypeDescription(); 244 245 bool CompareTypes(CompilerType rhs) const; 246 247 const char *GetTypeTag(); 248 249 /// Go through the base classes and count non-empty ones. 250 uint32_t GetNumberOfNonEmptyBaseClasses(); 251 252 /// \} 253 254 /// Type Completion. 255 /// \{ 256 bool GetCompleteType() const; 257 /// \} 258 259 bool IsForcefullyCompleted() const; 260 261 /// AST related queries. 262 /// \{ 263 size_t GetPointerByteSize() const; 264 /// \} 265 266 unsigned GetPtrAuthKey() const; 267 268 unsigned GetPtrAuthDiscriminator() const; 269 270 bool GetPtrAuthAddressDiversity() const; 271 272 /// Accessors. 273 /// \{ 274 275 /// Returns a shared pointer to the type system. The 276 /// TypeSystem::TypeSystemSPWrapper can be compared for equality. 277 TypeSystemSPWrapper GetTypeSystem() const; 278 279 template <typename TypeSystemType> GetTypeSystem()280 std::shared_ptr<TypeSystemType> GetTypeSystem() const { 281 return GetTypeSystem().dyn_cast_or_null<TypeSystemType>(); 282 } 283 284 ConstString GetTypeName(bool BaseOnly = false) const; 285 286 ConstString GetDisplayTypeName() const; 287 288 ConstString GetMangledTypeName() const; 289 290 uint32_t 291 GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) const; 292 293 lldb::LanguageType GetMinimumLanguage(); 294 GetOpaqueQualType()295 lldb::opaque_compiler_type_t GetOpaqueQualType() const { return m_type; } 296 297 lldb::TypeClass GetTypeClass() const; 298 299 void SetCompilerType(lldb::TypeSystemWP type_system, 300 lldb::opaque_compiler_type_t type); 301 void SetCompilerType(TypeSystemSPWrapper type_system, 302 lldb::opaque_compiler_type_t type); 303 304 unsigned GetTypeQualifiers() const; 305 /// \} 306 307 /// Creating related types. 308 /// \{ 309 CompilerType GetArrayElementType(ExecutionContextScope *exe_scope) const; 310 311 CompilerType GetArrayType(uint64_t size) const; 312 313 CompilerType GetCanonicalType() const; 314 315 CompilerType GetFullyUnqualifiedType() const; 316 317 CompilerType GetEnumerationIntegerType() const; 318 319 /// Returns -1 if this isn't a function of if the function doesn't 320 /// have a prototype Returns a value >= 0 if there is a prototype. 321 int GetFunctionArgumentCount() const; 322 323 CompilerType GetFunctionArgumentTypeAtIndex(size_t idx) const; 324 325 CompilerType GetFunctionReturnType() const; 326 327 size_t GetNumMemberFunctions() const; 328 329 TypeMemberFunctionImpl GetMemberFunctionAtIndex(size_t idx); 330 331 /// If this type is a reference to a type (L value or R value reference), 332 /// return a new type with the reference removed, else return the current type 333 /// itself. 334 CompilerType GetNonReferenceType() const; 335 336 /// If this type is a pointer type, return the type that the pointer points 337 /// to, else return an invalid type. 338 CompilerType GetPointeeType() const; 339 340 /// Return a new CompilerType that is a pointer to this type 341 CompilerType GetPointerType() const; 342 343 /// Return a new CompilerType that is a L value reference to this type if this 344 /// type is valid and the type system supports L value references, else return 345 /// an invalid type. 346 CompilerType GetLValueReferenceType() const; 347 348 /// Return a new CompilerType that is a R value reference to this type if this 349 /// type is valid and the type system supports R value references, else return 350 /// an invalid type. 351 CompilerType GetRValueReferenceType() const; 352 353 /// Return a new CompilerType adds a const modifier to this type if this type 354 /// is valid and the type system supports const modifiers, else return an 355 /// invalid type. 356 CompilerType AddConstModifier() const; 357 358 /// Return a new CompilerType adds a volatile modifier to this type if this 359 /// type is valid and the type system supports volatile modifiers, else return 360 /// an invalid type. 361 CompilerType AddVolatileModifier() const; 362 363 /// Return a new CompilerType that is the atomic type of this type. If this 364 /// type is not valid or the type system doesn't support atomic types, this 365 /// returns an invalid type. 366 CompilerType GetAtomicType() const; 367 368 /// Return a new CompilerType adds a restrict modifier to this type if this 369 /// type is valid and the type system supports restrict modifiers, else return 370 /// an invalid type. 371 CompilerType AddRestrictModifier() const; 372 373 /// Create a typedef to this type using "name" as the name of the typedef this 374 /// type is valid and the type system supports typedefs, else return an 375 /// invalid type. 376 /// \param payload The typesystem-specific \p lldb::Type payload. 377 CompilerType CreateTypedef(const char *name, 378 const CompilerDeclContext &decl_ctx, 379 uint32_t payload) const; 380 381 /// If the current object represents a typedef type, get the underlying type 382 CompilerType GetTypedefedType() const; 383 384 /// Create related types using the current type's AST 385 CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const; 386 387 /// Return a new CompilerType adds a ptrauth modifier from the given 32-bit 388 /// opaque payload to this type if this type is valid and the type system 389 /// supports ptrauth modifiers, else return an invalid type. Note that this 390 /// does not check if this type is a pointer. 391 CompilerType AddPtrAuthModifier(uint32_t payload) const; 392 /// \} 393 394 /// Exploring the type. 395 /// \{ 396 struct IntegralTemplateArgument; 397 398 /// Return the size of the type in bytes. 399 llvm::Expected<uint64_t> GetByteSize(ExecutionContextScope *exe_scope) const; 400 /// Return the size of the type in bits. 401 llvm::Expected<uint64_t> GetBitSize(ExecutionContextScope *exe_scope) const; 402 403 lldb::Encoding GetEncoding(uint64_t &count) const; 404 405 lldb::Format GetFormat() const; 406 407 std::optional<size_t> GetTypeBitAlign(ExecutionContextScope *exe_scope) const; 408 409 llvm::Expected<uint32_t> 410 GetNumChildren(bool omit_empty_base_classes, 411 const ExecutionContext *exe_ctx) const; 412 413 lldb::BasicType GetBasicTypeEnumeration() const; 414 415 /// If this type is an enumeration, iterate through all of its enumerators 416 /// using a callback. If the callback returns true, keep iterating, else abort 417 /// the iteration. 418 void ForEachEnumerator( 419 std::function<bool(const CompilerType &integer_type, ConstString name, 420 const llvm::APSInt &value)> const &callback) const; 421 422 uint32_t GetNumFields() const; 423 424 CompilerType GetFieldAtIndex(size_t idx, std::string &name, 425 uint64_t *bit_offset_ptr, 426 uint32_t *bitfield_bit_size_ptr, 427 bool *is_bitfield_ptr) const; 428 429 uint32_t GetNumDirectBaseClasses() const; 430 431 uint32_t GetNumVirtualBaseClasses() const; 432 433 CompilerType GetDirectBaseClassAtIndex(size_t idx, 434 uint32_t *bit_offset_ptr) const; 435 436 CompilerType GetVirtualBaseClassAtIndex(size_t idx, 437 uint32_t *bit_offset_ptr) const; 438 439 CompilerDecl GetStaticFieldWithName(llvm::StringRef name) const; 440 441 llvm::Expected<CompilerType> 442 GetDereferencedType(ExecutionContext *exe_ctx, std::string &deref_name, 443 uint32_t &deref_byte_size, int32_t &deref_byte_offset, 444 ValueObject *valobj, uint64_t &language_flags) const; 445 446 llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( 447 ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, 448 bool omit_empty_base_classes, bool ignore_array_bounds, 449 std::string &child_name, uint32_t &child_byte_size, 450 int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, 451 uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, 452 bool &child_is_deref_of_parent, ValueObject *valobj, 453 uint64_t &language_flags) const; 454 455 /// Lookup a child given a name. This function will match base class names and 456 /// member member names in "clang_type" only, not descendants. 457 llvm::Expected<uint32_t> 458 GetIndexOfChildWithName(llvm::StringRef name, 459 bool omit_empty_base_classes) const; 460 461 /// Lookup a child member given a name. This function will match member names 462 /// only and will descend into "clang_type" children in search for the first 463 /// member in this class, or any base class that matches "name". 464 /// 465 /// \param child_indexes returns an index path for the result. 466 /// \returns 0 if unsuccessful, otherwise the length of the index path. 467 /// 468 /// TODO: Return all matches for a given name by returning a 469 /// vector<vector<uint32_t>> so we catch all names that match a 470 /// given child name, not just the first. 471 size_t 472 GetIndexOfChildMemberWithName(llvm::StringRef name, 473 bool omit_empty_base_classes, 474 std::vector<uint32_t> &child_indexes) const; 475 476 CompilerType GetDirectNestedTypeWithName(llvm::StringRef name) const; 477 478 /// Return the number of template arguments the type has. 479 /// If expand_pack is true, then variadic argument packs are automatically 480 /// expanded to their supplied arguments. If it is false an argument pack 481 /// will only count as 1 argument. 482 size_t GetNumTemplateArguments(bool expand_pack = false) const; 483 484 // Return the TemplateArgumentKind of the template argument at index idx. 485 // If expand_pack is true, then variadic argument packs are automatically 486 // expanded to their supplied arguments. With expand_pack set to false, an 487 // arguement pack will count as 1 argument and return a type of Pack. 488 lldb::TemplateArgumentKind 489 GetTemplateArgumentKind(size_t idx, bool expand_pack = false) const; 490 CompilerType GetTypeTemplateArgument(size_t idx, 491 bool expand_pack = false) const; 492 493 /// Returns the value of the template argument and its type. 494 /// If expand_pack is true, then variadic argument packs are automatically 495 /// expanded to their supplied arguments. With expand_pack set to false, an 496 /// arguement pack will count as 1 argument and it is invalid to call this 497 /// method on the pack argument. 498 std::optional<IntegralTemplateArgument> 499 GetIntegralTemplateArgument(size_t idx, bool expand_pack = false) const; 500 501 CompilerType GetTypeForFormatters() const; 502 503 LazyBool ShouldPrintAsOneLiner(ValueObject *valobj) const; 504 505 bool IsMeaninglessWithoutDynamicResolution() const; 506 /// \} 507 508 /// Dumping types. 509 /// \{ 510 #ifndef NDEBUG 511 /// Convenience LLVM-style dump method for use in the debugger only. 512 /// Don't call this function from actual code. 513 LLVM_DUMP_METHOD void dump() const; 514 #endif 515 516 bool DumpTypeValue(Stream *s, lldb::Format format, const DataExtractor &data, 517 lldb::offset_t data_offset, size_t data_byte_size, 518 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, 519 ExecutionContextScope *exe_scope); 520 521 /// Dump to stdout. 522 void DumpTypeDescription(lldb::DescriptionLevel level = 523 lldb::eDescriptionLevelFull) const; 524 525 /// Print a description of the type to a stream. The exact implementation 526 /// varies, but the expectation is that eDescriptionLevelFull returns a 527 /// source-like representation of the type, whereas eDescriptionLevelVerbose 528 /// does a dump of the underlying AST if applicable. 529 void DumpTypeDescription(Stream *s, lldb::DescriptionLevel level = 530 lldb::eDescriptionLevelFull) const; 531 /// \} 532 533 bool GetValueAsScalar(const DataExtractor &data, lldb::offset_t data_offset, 534 size_t data_byte_size, Scalar &value, 535 ExecutionContextScope *exe_scope) const; Clear()536 void Clear() { 537 m_type_system = {}; 538 m_type = nullptr; 539 } 540 541 private: 542 #ifndef NDEBUG 543 /// If the type is valid, ask the TypeSystem to verify the integrity 544 /// of the type to catch CompilerTypes that mix and match invalid 545 /// TypeSystem/Opaque type pairs. 546 bool Verify() const; 547 #endif 548 549 lldb::TypeSystemWP m_type_system; 550 lldb::opaque_compiler_type_t m_type = nullptr; 551 }; 552 553 bool operator==(const CompilerType &lhs, const CompilerType &rhs); 554 bool operator!=(const CompilerType &lhs, const CompilerType &rhs); 555 556 struct CompilerType::IntegralTemplateArgument { 557 Scalar value; 558 CompilerType type; 559 }; 560 561 } // namespace lldb_private 562 563 #endif // LLDB_SYMBOL_COMPILERTYPE_H 564