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