1 //===-- Type.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_TYPE_H 10 #define LLDB_SYMBOL_TYPE_H 11 12 #include "lldb/Core/Declaration.h" 13 #include "lldb/Symbol/CompilerDecl.h" 14 #include "lldb/Symbol/CompilerType.h" 15 #include "lldb/Symbol/TypeList.h" 16 #include "lldb/Symbol/TypeMap.h" 17 #include "lldb/Symbol/TypeSystem.h" 18 #include "lldb/Utility/ConstString.h" 19 #include "lldb/Utility/UserID.h" 20 #include "lldb/lldb-private.h" 21 22 #include "llvm/ADT/APSInt.h" 23 #include "llvm/ADT/DenseSet.h" 24 #include "llvm/ADT/STLForwardCompat.h" 25 #include "llvm/Support/raw_ostream.h" 26 27 #include <optional> 28 #include <set> 29 30 namespace lldb_private { 31 class SymbolFileCommon; 32 33 /// A SmallBitVector that represents a set of source languages (\p 34 /// lldb::LanguageType). Each lldb::LanguageType is represented by 35 /// the bit with the position of its enumerator. The largest 36 /// LanguageType is < 64, so this is space-efficient and on 64-bit 37 /// architectures a LanguageSet can be completely stack-allocated. 38 struct LanguageSet { 39 llvm::SmallBitVector bitvector; 40 LanguageSet(); 41 42 /// If the set contains a single language only, return it. 43 std::optional<lldb::LanguageType> GetSingularLanguage(); 44 void Insert(lldb::LanguageType language); 45 bool Empty() const; 46 size_t Size() const; 47 bool operator[](unsigned i) const; 48 }; 49 50 /// CompilerContext allows an array of these items to be passed to perform 51 /// detailed lookups in SymbolVendor and SymbolFile functions. 52 struct CompilerContext { 53 CompilerContext(CompilerContextKind t, ConstString n) : kind(t), name(n) {} 54 55 bool operator==(const CompilerContext &rhs) const { 56 return kind == rhs.kind && name == rhs.name; 57 } 58 bool operator!=(const CompilerContext &rhs) const { return !(*this == rhs); } 59 60 void Dump(Stream &s) const; 61 62 CompilerContextKind kind; 63 ConstString name; 64 }; 65 llvm::raw_ostream &operator<<(llvm::raw_ostream &os, 66 const CompilerContext &rhs); 67 68 /// Match \p context_chain against \p pattern, which may contain "Any" 69 /// kinds. The \p context_chain should *not* contain any "Any" kinds. 70 bool contextMatches(llvm::ArrayRef<CompilerContext> context_chain, 71 llvm::ArrayRef<CompilerContext> pattern); 72 73 FLAGS_ENUM(TypeQueryOptions){ 74 e_none = 0u, 75 /// If set, TypeQuery::m_context contains an exact context that must match 76 /// the full context. If not set, TypeQuery::m_context can contain a partial 77 /// type match where the full context isn't fully specified. 78 e_exact_match = (1u << 0), 79 /// If set, TypeQuery::m_context is a clang module compiler context. If not 80 /// set TypeQuery::m_context is normal type lookup context. 81 e_module_search = (1u << 1), 82 /// When true, the find types call should stop the query as soon as a single 83 /// matching type is found. When false, the type query should find all 84 /// matching types. 85 e_find_one = (1u << 2), 86 }; 87 LLDB_MARK_AS_BITMASK_ENUM(TypeQueryOptions) 88 89 /// A class that contains all state required for type lookups. 90 /// 91 /// Using a TypeQuery class for matching types simplifies the internal APIs we 92 /// need to implement type lookups in LLDB. Type lookups can fully specify the 93 /// exact typename by filling out a complete or partial CompilerContext array. 94 /// This technique allows for powerful searches and also allows the SymbolFile 95 /// classes to use the m_context array to lookup types by basename, then 96 /// eliminate potential matches without having to resolve types into each 97 /// TypeSystem. This makes type lookups vastly more efficient and allows the 98 /// SymbolFile objects to stop looking up types when the type matching is 99 /// complete, like if we are looking for only a single type in our search. 100 class TypeQuery { 101 public: 102 TypeQuery() = delete; 103 104 /// Construct a type match object using a fully- or partially-qualified name. 105 /// 106 /// The specified \a type_name will be chopped up and the m_context will be 107 /// populated by separating the string by looking for "::". We do this because 108 /// symbol files have indexes that contain only the type's basename. This also 109 /// allows symbol files to efficiently not realize types that don't match the 110 /// specified context. Example of \a type_name values that can be specified 111 /// include: 112 /// "foo": Look for any type whose basename matches "foo". 113 /// If \a exact_match is true, then the type can't be contained in any 114 /// declaration context like a namespace, class, or other containing 115 /// scope. 116 /// If \a exact match is false, then we will find all matches including 117 /// ones that are contained in other declaration contexts, including top 118 /// level types. 119 /// "foo::bar": Look for any type whose basename matches "bar" but make sure 120 /// its parent declaration context is any named declaration context 121 /// (namespace, class, struct, etc) whose name matches "foo". 122 /// If \a exact_match is true, then the "foo" declaration context must 123 /// appear at the source file level or inside of a function. 124 /// If \a exact match is false, then the "foo" declaration context can 125 /// be contained in any other declaration contexts. 126 /// "class foo": Only match types that are classes whose basename matches 127 /// "foo". 128 /// "struct foo": Only match types that are structures whose basename 129 /// matches "foo". 130 /// "class foo::bar": Only match types that are classes whose basename 131 /// matches "bar" and that are contained in any named declaration context 132 /// named "foo". 133 /// 134 /// \param[in] type_name 135 /// A fully- or partially-qualified type name. This name will be parsed and 136 /// broken up and the m_context will be populated with the various parts of 137 /// the name. This typename can be prefixed with "struct ", "class ", 138 /// "union", "enum " or "typedef " before the actual type name to limit the 139 /// results of the types that match. The declaration context can be 140 /// specified with the "::" string. For example, "a::b::my_type". 141 /// 142 /// \param[in] options A set of boolean enumeration flags from the 143 /// TypeQueryOptions enumerations. \see TypeQueryOptions. 144 TypeQuery(llvm::StringRef name, TypeQueryOptions options = e_none); 145 146 /// Construct a type-match object that matches a type basename that exists 147 /// in the specified declaration context. 148 /// 149 /// This allows the m_context to be first populated using a declaration 150 /// context to exactly identify the containing declaration context of a type. 151 /// This can be used when you have a forward declaration to a type and you 152 /// need to search for its complete type. 153 /// 154 /// \param[in] decl_ctx 155 /// A declaration context object that comes from a TypeSystem plug-in. This 156 /// object will be asked to populate the array of CompilerContext objects 157 /// by adding the top most declaration context first into the array and then 158 /// adding any containing declaration contexts. 159 /// 160 /// \param[in] type_basename 161 /// The basename of the type to lookup in the specified declaration context. 162 /// 163 /// \param[in] options A set of boolean enumeration flags from the 164 /// TypeQueryOptions enumerations. \see TypeQueryOptions. 165 TypeQuery(const CompilerDeclContext &decl_ctx, ConstString type_basename, 166 TypeQueryOptions options = e_none); 167 /// Construct a type-match object using a compiler declaration that specifies 168 /// a typename and a declaration context to use when doing exact type lookups. 169 /// 170 /// This allows the m_context to be first populated using a type declaration. 171 /// The type declaration might have a declaration context and each TypeSystem 172 /// plug-in can populate the declaration context needed to perform an exact 173 /// lookup for a type. 174 /// This can be used when you have a forward declaration to a type and you 175 /// need to search for its complete type. 176 /// 177 /// \param[in] decl 178 /// A type declaration context object that comes from a TypeSystem plug-in. 179 /// This object will be asked to full the array of CompilerContext objects 180 /// by adding the top most declaration context first into the array and then 181 /// adding any containing declaration contexts, and ending with the exact 182 /// typename and the kind of type it is (class, struct, union, enum, etc). 183 /// 184 /// \param[in] options A set of boolean enumeration flags from the 185 /// TypeQueryOptions enumerations. \see TypeQueryOptions. 186 TypeQuery(const CompilerDecl &decl, TypeQueryOptions options = e_none); 187 188 /// Construct a type-match object using a CompilerContext array. 189 /// 190 /// Clients can manually create compiler contexts and use these to find 191 /// matches when searching for types. There are two types of contexts that 192 /// are supported when doing type searchs: type contexts and clang module 193 /// contexts. Type contexts have contexts that specify the type and its 194 /// containing declaration context like namespaces and classes. Clang module 195 /// contexts specify contexts more completely to find exact matches within 196 /// clang module debug information. They will include the modules that the 197 /// type is included in and any functions that the type might be defined in. 198 /// This allows very fine-grained type resolution. 199 /// 200 /// \param[in] context The compiler context to use when doing the search. 201 /// 202 /// \param[in] options A set of boolean enumeration flags from the 203 /// TypeQueryOptions enumerations. \see TypeQueryOptions. 204 TypeQuery(const llvm::ArrayRef<lldb_private::CompilerContext> &context, 205 TypeQueryOptions options = e_none); 206 207 /// Construct a type-match object that duplicates all matching criterea, 208 /// but not any searched symbol files or the type map for matches. This allows 209 /// the m_context to be modified prior to performing another search. 210 TypeQuery(const TypeQuery &rhs) = default; 211 /// Assign a type-match object that duplicates all matching criterea, 212 /// but not any searched symbol files or the type map for matches. This allows 213 /// the m_context to be modified prior to performing another search. 214 TypeQuery &operator=(const TypeQuery &rhs) = default; 215 216 /// Check of a CompilerContext array from matching type from a symbol file 217 /// matches the \a m_context. 218 /// 219 /// \param[in] context 220 /// A fully qualified CompilerContext array for a potential match that is 221 /// created by the symbol file prior to trying to actually resolve a type. 222 /// 223 /// \returns 224 /// True if the context matches, false if it doesn't. If e_exact_match 225 /// is set in m_options, then \a context must exactly match \a m_context. If 226 /// e_exact_match is not set, then the bottom m_context.size() objects in 227 /// \a context must match. This allows SymbolFile objects the fill in a 228 /// potential type basename match from the index into \a context, and see if 229 /// it matches prior to having to resolve a lldb_private::Type object for 230 /// the type from the index. This allows type parsing to be as efficient as 231 /// possible and only realize the types that match the query. 232 bool 233 ContextMatches(llvm::ArrayRef<lldb_private::CompilerContext> context) const; 234 235 /// Get the type basename to use when searching the type indexes in each 236 /// SymbolFile object. 237 /// 238 /// Debug information indexes often contain indexes that track the basename 239 /// of types only, not a fully qualified path. This allows the indexes to be 240 /// smaller and allows for efficient lookups. 241 /// 242 /// \returns 243 /// The type basename to use when doing lookups as a constant string. 244 ConstString GetTypeBasename() const; 245 246 /// Returns true if any matching languages have been specified in this type 247 /// matching object. 248 bool HasLanguage() const { return m_languages.has_value(); } 249 250 /// Add a language family to the list of languages that should produce a 251 /// match. 252 void AddLanguage(lldb::LanguageType language); 253 254 /// Set the list of languages that should produce a match to only the ones 255 /// specified in \ref languages. 256 void SetLanguages(LanguageSet languages); 257 258 /// Check if the language matches any languages that have been added to this 259 /// match object. 260 /// 261 /// \returns 262 /// True if no language have been specified, or if some language have been 263 /// added using AddLanguage(...) and they match. False otherwise. 264 bool LanguageMatches(lldb::LanguageType language) const; 265 266 bool GetExactMatch() const { return (m_options & e_exact_match) != 0; } 267 /// The \a m_context can be used in two ways: normal types searching with 268 /// the context containing a stanadard declaration context for a type, or 269 /// with the context being more complete for exact matches in clang modules. 270 /// Set this to true if you wish to search for a type in clang module. 271 bool GetModuleSearch() const { return (m_options & e_module_search) != 0; } 272 273 /// Returns true if the type query is supposed to find only a single matching 274 /// type. Returns false if the type query should find all matches. 275 bool GetFindOne() const { return (m_options & e_find_one) != 0; } 276 void SetFindOne(bool b) { 277 if (b) 278 m_options |= e_find_one; 279 else 280 m_options &= (e_exact_match | e_find_one); 281 } 282 283 /// Access the internal compiler context array. 284 /// 285 /// Clients can use this to populate the context manually. 286 std::vector<lldb_private::CompilerContext> &GetContextRef() { 287 return m_context; 288 } 289 290 protected: 291 /// A full or partial compiler context array where the parent declaration 292 /// contexts appear at the top of the array starting at index zero and the 293 /// last entry contains the type and name of the type we are looking for. 294 std::vector<lldb_private::CompilerContext> m_context; 295 /// An options bitmask that contains enabled options for the type query. 296 /// \see TypeQueryOptions. 297 TypeQueryOptions m_options; 298 /// If this variable has a value, then the language family must match at least 299 /// one of the specified languages. If this variable has no value, then the 300 /// language of the type doesn't need to match any types that are searched. 301 std::optional<LanguageSet> m_languages; 302 }; 303 304 /// This class tracks the state and results of a \ref TypeQuery. 305 /// 306 /// Any mutable state required for type lookups and the results are tracked in 307 /// this object. 308 class TypeResults { 309 public: 310 /// Construct a type results object 311 TypeResults() = default; 312 313 /// When types that match a TypeQuery are found, this API is used to insert 314 /// the matching types. 315 /// 316 /// \return 317 /// True if the type was added, false if the \a type_sp was already in the 318 /// results. 319 bool InsertUnique(const lldb::TypeSP &type_sp); 320 321 /// Check if the type matching has found all of the matches that it needs. 322 bool Done(const TypeQuery &query) const; 323 324 /// Check if a SymbolFile object has already been searched by this type match 325 /// object. 326 /// 327 /// This function will add \a sym_file to the set of SymbolFile objects if it 328 /// isn't already in the set and return \a false. Returns true if \a sym_file 329 /// was already in the set and doesn't need to be searched. 330 /// 331 /// Any clients that search for types should first check that the symbol file 332 /// has not already been searched. If this function returns true, the type 333 /// search function should early return to avoid duplicating type searchihng 334 /// efforts. 335 /// 336 /// \param[in] sym_file 337 /// A SymbolFile pointer that will be used to track which symbol files have 338 /// already been searched. 339 /// 340 /// \returns 341 /// True if the symbol file has been search already, false otherwise. 342 bool AlreadySearched(lldb_private::SymbolFile *sym_file); 343 344 /// Access the set of searched symbol files. 345 llvm::DenseSet<lldb_private::SymbolFile *> &GetSearchedSymbolFiles() { 346 return m_searched_symbol_files; 347 } 348 349 lldb::TypeSP GetFirstType() const { return m_type_map.FirstType(); } 350 TypeMap &GetTypeMap() { return m_type_map; } 351 const TypeMap &GetTypeMap() const { return m_type_map; } 352 353 private: 354 /// Matching types get added to this map as type search continues. 355 TypeMap m_type_map; 356 /// This set is used to track and make sure we only perform lookups in a 357 /// symbol file one time. 358 llvm::DenseSet<lldb_private::SymbolFile *> m_searched_symbol_files; 359 }; 360 361 class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>, 362 public UserID { 363 public: 364 SymbolFileType(SymbolFile &symbol_file, lldb::user_id_t uid) 365 : UserID(uid), m_symbol_file(symbol_file) {} 366 367 SymbolFileType(SymbolFile &symbol_file, const lldb::TypeSP &type_sp); 368 369 ~SymbolFileType() = default; 370 371 Type *operator->() { return GetType(); } 372 373 Type *GetType(); 374 SymbolFile &GetSymbolFile() const { return m_symbol_file; } 375 376 protected: 377 SymbolFile &m_symbol_file; 378 lldb::TypeSP m_type_sp; 379 }; 380 381 class Type : public std::enable_shared_from_this<Type>, public UserID { 382 public: 383 enum EncodingDataType { 384 /// Invalid encoding. 385 eEncodingInvalid, 386 /// This type is the type whose UID is m_encoding_uid. 387 eEncodingIsUID, 388 /// This type is the type whose UID is m_encoding_uid with the const 389 /// qualifier added. 390 eEncodingIsConstUID, 391 /// This type is the type whose UID is m_encoding_uid with the restrict 392 /// qualifier added. 393 eEncodingIsRestrictUID, 394 /// This type is the type whose UID is m_encoding_uid with the volatile 395 /// qualifier added. 396 eEncodingIsVolatileUID, 397 /// This type is alias to a type whose UID is m_encoding_uid. 398 eEncodingIsTypedefUID, 399 /// This type is pointer to a type whose UID is m_encoding_uid. 400 eEncodingIsPointerUID, 401 /// This type is L value reference to a type whose UID is m_encoding_uid. 402 eEncodingIsLValueReferenceUID, 403 /// This type is R value reference to a type whose UID is m_encoding_uid. 404 eEncodingIsRValueReferenceUID, 405 /// This type is the type whose UID is m_encoding_uid as an atomic type. 406 eEncodingIsAtomicUID, 407 /// This type is the synthetic type whose UID is m_encoding_uid. 408 eEncodingIsSyntheticUID, 409 /// This type is a signed pointer. 410 eEncodingIsLLVMPtrAuthUID 411 }; 412 413 enum class ResolveState : unsigned char { 414 Unresolved = 0, 415 Forward = 1, 416 Layout = 2, 417 Full = 3 418 }; 419 420 void Dump(Stream *s, bool show_context, 421 lldb::DescriptionLevel level = lldb::eDescriptionLevelFull); 422 423 void DumpTypeName(Stream *s); 424 425 /// Since Type instances only keep a "SymbolFile *" internally, other classes 426 /// like TypeImpl need make sure the module is still around before playing 427 /// with 428 /// Type instances. They can store a weak pointer to the Module; 429 lldb::ModuleSP GetModule(); 430 431 /// GetModule may return module for compile unit's object file. 432 /// GetExeModule returns module for executable object file that contains 433 /// compile unit where type was actually defined. 434 /// GetModule and GetExeModule may return the same value. 435 lldb::ModuleSP GetExeModule(); 436 437 void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name, 438 ExecutionContextScope *exe_scope); 439 440 SymbolFile *GetSymbolFile() { return m_symbol_file; } 441 const SymbolFile *GetSymbolFile() const { return m_symbol_file; } 442 443 ConstString GetName(); 444 445 ConstString GetBaseName(); 446 447 std::optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope); 448 449 llvm::Expected<uint32_t> GetNumChildren(bool omit_empty_base_classes); 450 451 bool IsAggregateType(); 452 453 // Returns if the type is a templated decl. Does not look through typedefs. 454 bool IsTemplateType(); 455 456 bool IsValidType() { return m_encoding_uid_type != eEncodingInvalid; } 457 458 bool IsTypedef() { return m_encoding_uid_type == eEncodingIsTypedefUID; } 459 460 lldb::TypeSP GetTypedefType(); 461 462 ConstString GetName() const { return m_name; } 463 464 ConstString GetQualifiedName(); 465 466 bool ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t address, 467 AddressType address_type, DataExtractor &data); 468 469 bool WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t address, 470 AddressType address_type, DataExtractor &data); 471 472 lldb::Format GetFormat(); 473 474 lldb::Encoding GetEncoding(uint64_t &count); 475 476 SymbolContextScope *GetSymbolContextScope() { return m_context; } 477 const SymbolContextScope *GetSymbolContextScope() const { return m_context; } 478 void SetSymbolContextScope(SymbolContextScope *context) { 479 m_context = context; 480 } 481 482 const lldb_private::Declaration &GetDeclaration() const; 483 484 // Get the clang type, and resolve definitions for any 485 // class/struct/union/enum types completely. 486 CompilerType GetFullCompilerType(); 487 488 // Get the clang type, and resolve definitions enough so that the type could 489 // have layout performed. This allows ptrs and refs to 490 // class/struct/union/enum types remain forward declarations. 491 CompilerType GetLayoutCompilerType(); 492 493 // Get the clang type and leave class/struct/union/enum types as forward 494 // declarations if they haven't already been fully defined. 495 CompilerType GetForwardCompilerType(); 496 497 static int Compare(const Type &a, const Type &b); 498 499 // Represents a parsed type name coming out of GetTypeScopeAndBasename. The 500 // structure holds StringRefs pointing to portions of the original name, and 501 // so must not be used after the name is destroyed. 502 struct ParsedName { 503 lldb::TypeClass type_class = lldb::eTypeClassAny; 504 505 // Scopes of the type, starting with the outermost. Absolute type references 506 // have a "::" as the first scope. 507 llvm::SmallVector<llvm::StringRef> scope; 508 509 llvm::StringRef basename; 510 511 friend bool operator==(const ParsedName &lhs, const ParsedName &rhs) { 512 return lhs.type_class == rhs.type_class && lhs.scope == rhs.scope && 513 lhs.basename == rhs.basename; 514 } 515 516 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, 517 const ParsedName &name) { 518 return os << llvm::formatv( 519 "Type::ParsedName({0:x}, [{1}], {2})", 520 llvm::to_underlying(name.type_class), 521 llvm::make_range(name.scope.begin(), name.scope.end()), 522 name.basename); 523 } 524 }; 525 // From a fully qualified typename, split the type into the type basename and 526 // the remaining type scope (namespaces/classes). 527 static std::optional<ParsedName> 528 GetTypeScopeAndBasename(llvm::StringRef name); 529 530 void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; } 531 532 uint32_t GetEncodingMask(); 533 534 typedef uint32_t Payload; 535 /// Return the language-specific payload. 536 Payload GetPayload() { return m_payload; } 537 /// Return the language-specific payload. 538 void SetPayload(Payload opaque_payload) { m_payload = opaque_payload; } 539 540 protected: 541 ConstString m_name; 542 SymbolFile *m_symbol_file = nullptr; 543 /// The symbol context in which this type is defined. 544 SymbolContextScope *m_context = nullptr; 545 Type *m_encoding_type = nullptr; 546 lldb::user_id_t m_encoding_uid = LLDB_INVALID_UID; 547 EncodingDataType m_encoding_uid_type = eEncodingInvalid; 548 uint64_t m_byte_size : 63; 549 uint64_t m_byte_size_has_value : 1; 550 Declaration m_decl; 551 CompilerType m_compiler_type; 552 ResolveState m_compiler_type_resolve_state = ResolveState::Unresolved; 553 /// Language-specific flags. 554 Payload m_payload; 555 556 Type *GetEncodingType(); 557 558 bool ResolveCompilerType(ResolveState compiler_type_resolve_state); 559 private: 560 /// Only allow Symbol File to create types, as they should own them by keeping 561 /// them in their TypeList. \see SymbolFileCommon::MakeType() reference in the 562 /// header documentation here so users will know what function to use if the 563 /// get a compile error. 564 friend class lldb_private::SymbolFileCommon; 565 566 Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name, 567 std::optional<uint64_t> byte_size, SymbolContextScope *context, 568 lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type, 569 const Declaration &decl, const CompilerType &compiler_qual_type, 570 ResolveState compiler_type_resolve_state, uint32_t opaque_payload = 0); 571 572 // This makes an invalid type. Used for functions that return a Type when 573 // they get an error. 574 Type(); 575 576 Type(Type &t) = default; 577 578 Type(Type &&t) = default; 579 580 Type &operator=(const Type &t) = default; 581 582 Type &operator=(Type &&t) = default; 583 }; 584 585 // the two classes here are used by the public API as a backend to the SBType 586 // and SBTypeList classes 587 588 class TypeImpl { 589 public: 590 TypeImpl() = default; 591 592 ~TypeImpl() = default; 593 594 TypeImpl(const lldb::TypeSP &type_sp); 595 596 TypeImpl(const CompilerType &compiler_type); 597 598 TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic); 599 600 TypeImpl(const CompilerType &compiler_type, const CompilerType &dynamic); 601 602 void SetType(const lldb::TypeSP &type_sp); 603 604 void SetType(const CompilerType &compiler_type); 605 606 void SetType(const lldb::TypeSP &type_sp, const CompilerType &dynamic); 607 608 void SetType(const CompilerType &compiler_type, const CompilerType &dynamic); 609 610 bool operator==(const TypeImpl &rhs) const; 611 612 bool operator!=(const TypeImpl &rhs) const; 613 614 bool IsValid() const; 615 616 explicit operator bool() const; 617 618 void Clear(); 619 620 lldb::ModuleSP GetModule() const; 621 622 ConstString GetName() const; 623 624 ConstString GetDisplayTypeName() const; 625 626 TypeImpl GetPointerType() const; 627 628 TypeImpl GetPointeeType() const; 629 630 TypeImpl GetReferenceType() const; 631 632 TypeImpl GetTypedefedType() const; 633 634 TypeImpl GetDereferencedType() const; 635 636 TypeImpl GetUnqualifiedType() const; 637 638 TypeImpl GetCanonicalType() const; 639 640 CompilerType GetCompilerType(bool prefer_dynamic); 641 642 CompilerType::TypeSystemSPWrapper GetTypeSystem(bool prefer_dynamic); 643 644 bool GetDescription(lldb_private::Stream &strm, 645 lldb::DescriptionLevel description_level); 646 647 CompilerType FindDirectNestedType(llvm::StringRef name); 648 649 private: 650 bool CheckModule(lldb::ModuleSP &module_sp) const; 651 bool CheckExeModule(lldb::ModuleSP &module_sp) const; 652 bool CheckModuleCommon(const lldb::ModuleWP &input_module_wp, 653 lldb::ModuleSP &module_sp) const; 654 655 lldb::ModuleWP m_module_wp; 656 lldb::ModuleWP m_exe_module_wp; 657 CompilerType m_static_type; 658 CompilerType m_dynamic_type; 659 }; 660 661 class TypeListImpl { 662 public: 663 TypeListImpl() = default; 664 665 void Append(const lldb::TypeImplSP &type) { m_content.push_back(type); } 666 667 class AppendVisitor { 668 public: 669 AppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {} 670 671 void operator()(const lldb::TypeImplSP &type) { m_type_list.Append(type); } 672 673 private: 674 TypeListImpl &m_type_list; 675 }; 676 677 void Append(const lldb_private::TypeList &type_list); 678 679 lldb::TypeImplSP GetTypeAtIndex(size_t idx) { 680 lldb::TypeImplSP type_sp; 681 if (idx < GetSize()) 682 type_sp = m_content[idx]; 683 return type_sp; 684 } 685 686 size_t GetSize() { return m_content.size(); } 687 688 private: 689 std::vector<lldb::TypeImplSP> m_content; 690 }; 691 692 class TypeMemberImpl { 693 public: 694 TypeMemberImpl() = default; 695 696 TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset, 697 ConstString name, uint32_t bitfield_bit_size = 0, 698 bool is_bitfield = false) 699 : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(name), 700 m_bitfield_bit_size(bitfield_bit_size), m_is_bitfield(is_bitfield) {} 701 702 TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset) 703 : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), 704 m_bitfield_bit_size(0), m_is_bitfield(false) { 705 if (m_type_impl_sp) 706 m_name = m_type_impl_sp->GetName(); 707 } 708 709 const lldb::TypeImplSP &GetTypeImpl() { return m_type_impl_sp; } 710 711 ConstString GetName() const { return m_name; } 712 713 uint64_t GetBitOffset() const { return m_bit_offset; } 714 715 uint32_t GetBitfieldBitSize() const { return m_bitfield_bit_size; } 716 717 void SetBitfieldBitSize(uint32_t bitfield_bit_size) { 718 m_bitfield_bit_size = bitfield_bit_size; 719 } 720 721 bool GetIsBitfield() const { return m_is_bitfield; } 722 723 void SetIsBitfield(bool is_bitfield) { m_is_bitfield = is_bitfield; } 724 725 protected: 726 lldb::TypeImplSP m_type_impl_sp; 727 uint64_t m_bit_offset = 0; 728 ConstString m_name; 729 uint32_t m_bitfield_bit_size = 0; // Bit size for bitfield members only 730 bool m_is_bitfield = false; 731 }; 732 733 /// 734 /// Sometimes you can find the name of the type corresponding to an object, but 735 /// we don't have debug 736 /// information for it. If that is the case, you can return one of these 737 /// objects, and then if it 738 /// has a full type, you can use that, but if not at least you can print the 739 /// name for informational 740 /// purposes. 741 /// 742 743 class TypeAndOrName { 744 public: 745 TypeAndOrName() = default; 746 TypeAndOrName(lldb::TypeSP &type_sp); 747 TypeAndOrName(const CompilerType &compiler_type); 748 TypeAndOrName(const char *type_str); 749 TypeAndOrName(ConstString &type_const_string); 750 751 bool operator==(const TypeAndOrName &other) const; 752 753 bool operator!=(const TypeAndOrName &other) const; 754 755 ConstString GetName() const; 756 757 CompilerType GetCompilerType() const { return m_compiler_type; } 758 759 void SetName(ConstString type_name); 760 761 void SetName(const char *type_name_cstr); 762 763 void SetName(llvm::StringRef name); 764 765 void SetTypeSP(lldb::TypeSP type_sp); 766 767 void SetCompilerType(CompilerType compiler_type); 768 769 bool IsEmpty() const; 770 771 bool HasName() const; 772 773 bool HasCompilerType() const; 774 775 bool HasType() const { return HasCompilerType(); } 776 777 void Clear(); 778 779 explicit operator bool() { return !IsEmpty(); } 780 781 private: 782 CompilerType m_compiler_type; 783 ConstString m_type_name; 784 }; 785 786 class TypeMemberFunctionImpl { 787 public: 788 TypeMemberFunctionImpl() = default; 789 790 TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl, 791 const std::string &name, 792 const lldb::MemberFunctionKind &kind) 793 : m_type(type), m_decl(decl), m_name(name), m_kind(kind) {} 794 795 bool IsValid(); 796 797 ConstString GetName() const; 798 799 ConstString GetMangledName() const; 800 801 CompilerType GetType() const; 802 803 CompilerType GetReturnType() const; 804 805 size_t GetNumArguments() const; 806 807 CompilerType GetArgumentAtIndex(size_t idx) const; 808 809 lldb::MemberFunctionKind GetKind() const; 810 811 bool GetDescription(Stream &stream); 812 813 protected: 814 std::string GetPrintableTypeName(); 815 816 private: 817 CompilerType m_type; 818 CompilerDecl m_decl; 819 ConstString m_name; 820 lldb::MemberFunctionKind m_kind = lldb::eMemberFunctionKindUnknown; 821 }; 822 823 class TypeEnumMemberImpl { 824 public: 825 TypeEnumMemberImpl() : m_name("<invalid>") {} 826 827 TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, ConstString name, 828 const llvm::APSInt &value); 829 830 TypeEnumMemberImpl(const TypeEnumMemberImpl &rhs) = default; 831 832 TypeEnumMemberImpl &operator=(const TypeEnumMemberImpl &rhs); 833 834 bool IsValid() { return m_valid; } 835 836 ConstString GetName() const { return m_name; } 837 838 const lldb::TypeImplSP &GetIntegerType() const { return m_integer_type_sp; } 839 840 uint64_t GetValueAsUnsigned() const { return m_value.getZExtValue(); } 841 842 int64_t GetValueAsSigned() const { return m_value.getSExtValue(); } 843 844 protected: 845 lldb::TypeImplSP m_integer_type_sp; 846 ConstString m_name; 847 llvm::APSInt m_value; 848 bool m_valid = false; 849 }; 850 851 class TypeEnumMemberListImpl { 852 public: 853 TypeEnumMemberListImpl() = default; 854 855 void Append(const lldb::TypeEnumMemberImplSP &type) { 856 m_content.push_back(type); 857 } 858 859 void Append(const lldb_private::TypeEnumMemberListImpl &type_list); 860 861 lldb::TypeEnumMemberImplSP GetTypeEnumMemberAtIndex(size_t idx) { 862 lldb::TypeEnumMemberImplSP enum_member; 863 if (idx < GetSize()) 864 enum_member = m_content[idx]; 865 return enum_member; 866 } 867 868 size_t GetSize() { return m_content.size(); } 869 870 private: 871 std::vector<lldb::TypeEnumMemberImplSP> m_content; 872 }; 873 874 } // namespace lldb_private 875 876 #endif // LLDB_SYMBOL_TYPE_H 877