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