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/Symbol/CompilerDecl.h" 13 #include "lldb/Symbol/CompilerType.h" 14 #include "lldb/Symbol/Declaration.h" 15 #include "lldb/Utility/ConstString.h" 16 #include "lldb/Utility/UserID.h" 17 #include "lldb/lldb-private.h" 18 19 #include "llvm/ADT/APSInt.h" 20 21 #include <set> 22 23 namespace lldb_private { 24 25 /// CompilerContext allows an array of these items to be passed to perform 26 /// detailed lookups in SymbolVendor and SymbolFile functions. 27 struct CompilerContext { CompilerContextCompilerContext28 CompilerContext(CompilerContextKind t, ConstString n) : kind(t), name(n) {} 29 30 bool operator==(const CompilerContext &rhs) const { 31 return kind == rhs.kind && name == rhs.name; 32 } 33 bool operator!=(const CompilerContext &rhs) const { return !(*this == rhs); } 34 35 void Dump() const; 36 37 CompilerContextKind kind; 38 ConstString name; 39 }; 40 41 /// Match \p context_chain against \p pattern, which may contain "Any" 42 /// kinds. The \p context_chain should *not* contain any "Any" kinds. 43 bool contextMatches(llvm::ArrayRef<CompilerContext> context_chain, 44 llvm::ArrayRef<CompilerContext> pattern); 45 46 class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>, 47 public UserID { 48 public: SymbolFileType(SymbolFile & symbol_file,lldb::user_id_t uid)49 SymbolFileType(SymbolFile &symbol_file, lldb::user_id_t uid) 50 : UserID(uid), m_symbol_file(symbol_file) {} 51 52 SymbolFileType(SymbolFile &symbol_file, const lldb::TypeSP &type_sp); 53 ~SymbolFileType()54 ~SymbolFileType() {} 55 56 Type *operator->() { return GetType(); } 57 58 Type *GetType(); GetSymbolFile()59 SymbolFile &GetSymbolFile() const { return m_symbol_file; } 60 61 protected: 62 SymbolFile &m_symbol_file; 63 lldb::TypeSP m_type_sp; 64 }; 65 66 class Type : public std::enable_shared_from_this<Type>, public UserID { 67 public: 68 enum EncodingDataType { 69 eEncodingInvalid, 70 eEncodingIsUID, ///< This type is the type whose UID is m_encoding_uid 71 eEncodingIsConstUID, ///< This type is the type whose UID is m_encoding_uid 72 /// with the const qualifier added 73 eEncodingIsRestrictUID, ///< This type is the type whose UID is 74 /// m_encoding_uid with the restrict qualifier added 75 eEncodingIsVolatileUID, ///< This type is the type whose UID is 76 /// m_encoding_uid with the volatile qualifier added 77 eEncodingIsTypedefUID, ///< This type is pointer to a type whose UID is 78 /// m_encoding_uid 79 eEncodingIsPointerUID, ///< This type is pointer to a type whose UID is 80 /// m_encoding_uid 81 eEncodingIsLValueReferenceUID, ///< This type is L value reference to a type 82 /// whose UID is m_encoding_uid 83 eEncodingIsRValueReferenceUID, ///< This type is R value reference to a type 84 /// whose UID is m_encoding_uid, 85 eEncodingIsAtomicUID, ///< This type is the type whose UID is 86 /// m_encoding_uid as an atomic type. 87 eEncodingIsSyntheticUID 88 }; 89 90 enum class ResolveState : unsigned char { 91 Unresolved = 0, 92 Forward = 1, 93 Layout = 2, 94 Full = 3 95 }; 96 97 Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name, 98 llvm::Optional<uint64_t> byte_size, SymbolContextScope *context, 99 lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type, 100 const Declaration &decl, const CompilerType &compiler_qual_type, 101 ResolveState compiler_type_resolve_state, uint32_t opaque_payload = 0); 102 103 // This makes an invalid type. Used for functions that return a Type when 104 // they get an error. 105 Type(); 106 107 void Dump(Stream *s, bool show_context, 108 lldb::DescriptionLevel level = lldb::eDescriptionLevelFull); 109 110 void DumpTypeName(Stream *s); 111 112 /// Since Type instances only keep a "SymbolFile *" internally, other classes 113 /// like TypeImpl need make sure the module is still around before playing 114 /// with 115 /// Type instances. They can store a weak pointer to the Module; 116 lldb::ModuleSP GetModule(); 117 118 /// GetModule may return module for compile unit's object file. 119 /// GetExeModule returns module for executable object file that contains 120 /// compile unit where type was actualy defined. 121 /// GetModule and GetExeModule may return the same value. 122 lldb::ModuleSP GetExeModule(); 123 124 void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name, 125 ExecutionContextScope *exe_scope); 126 GetSymbolFile()127 SymbolFile *GetSymbolFile() { return m_symbol_file; } GetSymbolFile()128 const SymbolFile *GetSymbolFile() const { return m_symbol_file; } 129 130 ConstString GetName(); 131 132 llvm::Optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope); 133 134 uint32_t GetNumChildren(bool omit_empty_base_classes); 135 136 bool IsAggregateType(); 137 IsValidType()138 bool IsValidType() { return m_encoding_uid_type != eEncodingInvalid; } 139 IsTypedef()140 bool IsTypedef() { return m_encoding_uid_type == eEncodingIsTypedefUID; } 141 142 lldb::TypeSP GetTypedefType(); 143 GetName()144 ConstString GetName() const { return m_name; } 145 146 ConstString GetQualifiedName(); 147 148 void DumpValue(ExecutionContext *exe_ctx, Stream *s, 149 const DataExtractor &data, uint32_t data_offset, 150 bool show_type, bool show_summary, bool verbose, 151 lldb::Format format = lldb::eFormatDefault); 152 153 bool DumpValueInMemory(ExecutionContext *exe_ctx, Stream *s, 154 lldb::addr_t address, AddressType address_type, 155 bool show_types, bool show_summary, bool verbose); 156 157 bool ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t address, 158 AddressType address_type, DataExtractor &data); 159 160 bool WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t address, 161 AddressType address_type, DataExtractor &data); 162 163 bool GetIsDeclaration() const; 164 165 void SetIsDeclaration(bool b); 166 167 bool GetIsExternal() const; 168 169 void SetIsExternal(bool b); 170 171 lldb::Format GetFormat(); 172 173 lldb::Encoding GetEncoding(uint64_t &count); 174 GetSymbolContextScope()175 SymbolContextScope *GetSymbolContextScope() { return m_context; } GetSymbolContextScope()176 const SymbolContextScope *GetSymbolContextScope() const { return m_context; } SetSymbolContextScope(SymbolContextScope * context)177 void SetSymbolContextScope(SymbolContextScope *context) { 178 m_context = context; 179 } 180 181 const lldb_private::Declaration &GetDeclaration() const; 182 183 // Get the clang type, and resolve definitions for any 184 // class/struct/union/enum types completely. 185 CompilerType GetFullCompilerType(); 186 187 // Get the clang type, and resolve definitions enough so that the type could 188 // have layout performed. This allows ptrs and refs to 189 // class/struct/union/enum types remain forward declarations. 190 CompilerType GetLayoutCompilerType(); 191 192 // Get the clang type and leave class/struct/union/enum types as forward 193 // declarations if they haven't already been fully defined. 194 CompilerType GetForwardCompilerType(); 195 196 static int Compare(const Type &a, const Type &b); 197 198 // From a fully qualified typename, split the type into the type basename and 199 // the remaining type scope (namespaces/classes). 200 static bool GetTypeScopeAndBasename(const llvm::StringRef& name, 201 llvm::StringRef &scope, 202 llvm::StringRef &basename, 203 lldb::TypeClass &type_class); SetEncodingType(Type * encoding_type)204 void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; } 205 206 uint32_t GetEncodingMask(); 207 208 typedef uint32_t Payload; 209 /// Return the language-specific payload. GetPayload()210 Payload GetPayload() { return m_payload; } 211 /// Return the language-specific payload. SetPayload(Payload opaque_payload)212 void SetPayload(Payload opaque_payload) { m_payload = opaque_payload; } 213 214 protected: 215 ConstString m_name; 216 SymbolFile *m_symbol_file; 217 /// The symbol context in which this type is defined. 218 SymbolContextScope *m_context; 219 Type *m_encoding_type; 220 lldb::user_id_t m_encoding_uid; 221 EncodingDataType m_encoding_uid_type; 222 uint64_t m_byte_size : 63; 223 uint64_t m_byte_size_has_value : 1; 224 Declaration m_decl; 225 CompilerType m_compiler_type; 226 ResolveState m_compiler_type_resolve_state; 227 /// Language-specific flags. 228 Payload m_payload; 229 230 Type *GetEncodingType(); 231 232 bool ResolveCompilerType(ResolveState compiler_type_resolve_state); 233 }; 234 235 // the two classes here are used by the public API as a backend to the SBType 236 // and SBTypeList classes 237 238 class TypeImpl { 239 public: 240 TypeImpl() = default; 241 ~TypeImpl()242 ~TypeImpl() {} 243 244 TypeImpl(const lldb::TypeSP &type_sp); 245 246 TypeImpl(const CompilerType &compiler_type); 247 248 TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic); 249 250 TypeImpl(const CompilerType &compiler_type, const CompilerType &dynamic); 251 252 void SetType(const lldb::TypeSP &type_sp); 253 254 void SetType(const CompilerType &compiler_type); 255 256 void SetType(const lldb::TypeSP &type_sp, const CompilerType &dynamic); 257 258 void SetType(const CompilerType &compiler_type, const CompilerType &dynamic); 259 260 bool operator==(const TypeImpl &rhs) const; 261 262 bool operator!=(const TypeImpl &rhs) const; 263 264 bool IsValid() const; 265 266 explicit operator bool() const; 267 268 void Clear(); 269 270 lldb::ModuleSP GetModule() const; 271 272 ConstString GetName() const; 273 274 ConstString GetDisplayTypeName() const; 275 276 TypeImpl GetPointerType() const; 277 278 TypeImpl GetPointeeType() const; 279 280 TypeImpl GetReferenceType() const; 281 282 TypeImpl GetTypedefedType() const; 283 284 TypeImpl GetDereferencedType() const; 285 286 TypeImpl GetUnqualifiedType() const; 287 288 TypeImpl GetCanonicalType() const; 289 290 CompilerType GetCompilerType(bool prefer_dynamic); 291 292 TypeSystem *GetTypeSystem(bool prefer_dynamic); 293 294 bool GetDescription(lldb_private::Stream &strm, 295 lldb::DescriptionLevel description_level); 296 297 private: 298 bool CheckModule(lldb::ModuleSP &module_sp) const; 299 bool CheckExeModule(lldb::ModuleSP &module_sp) const; 300 bool CheckModuleCommon(const lldb::ModuleWP &input_module_wp, 301 lldb::ModuleSP &module_sp) const; 302 303 lldb::ModuleWP m_module_wp; 304 lldb::ModuleWP m_exe_module_wp; 305 CompilerType m_static_type; 306 CompilerType m_dynamic_type; 307 }; 308 309 class TypeListImpl { 310 public: TypeListImpl()311 TypeListImpl() : m_content() {} 312 Append(const lldb::TypeImplSP & type)313 void Append(const lldb::TypeImplSP &type) { m_content.push_back(type); } 314 315 class AppendVisitor { 316 public: AppendVisitor(TypeListImpl & type_list)317 AppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {} 318 operator()319 void operator()(const lldb::TypeImplSP &type) { m_type_list.Append(type); } 320 321 private: 322 TypeListImpl &m_type_list; 323 }; 324 325 void Append(const lldb_private::TypeList &type_list); 326 GetTypeAtIndex(size_t idx)327 lldb::TypeImplSP GetTypeAtIndex(size_t idx) { 328 lldb::TypeImplSP type_sp; 329 if (idx < GetSize()) 330 type_sp = m_content[idx]; 331 return type_sp; 332 } 333 GetSize()334 size_t GetSize() { return m_content.size(); } 335 336 private: 337 std::vector<lldb::TypeImplSP> m_content; 338 }; 339 340 class TypeMemberImpl { 341 public: TypeMemberImpl()342 TypeMemberImpl() 343 : m_type_impl_sp(), m_bit_offset(0), m_name(), m_bitfield_bit_size(0), 344 m_is_bitfield(false) 345 346 {} 347 348 TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset, 349 ConstString name, uint32_t bitfield_bit_size = 0, 350 bool is_bitfield = false) m_type_impl_sp(type_impl_sp)351 : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(name), 352 m_bitfield_bit_size(bitfield_bit_size), m_is_bitfield(is_bitfield) {} 353 TypeMemberImpl(const lldb::TypeImplSP & type_impl_sp,uint64_t bit_offset)354 TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset) 355 : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(), 356 m_bitfield_bit_size(0), m_is_bitfield(false) { 357 if (m_type_impl_sp) 358 m_name = m_type_impl_sp->GetName(); 359 } 360 GetTypeImpl()361 const lldb::TypeImplSP &GetTypeImpl() { return m_type_impl_sp; } 362 GetName()363 ConstString GetName() const { return m_name; } 364 GetBitOffset()365 uint64_t GetBitOffset() const { return m_bit_offset; } 366 GetBitfieldBitSize()367 uint32_t GetBitfieldBitSize() const { return m_bitfield_bit_size; } 368 SetBitfieldBitSize(uint32_t bitfield_bit_size)369 void SetBitfieldBitSize(uint32_t bitfield_bit_size) { 370 m_bitfield_bit_size = bitfield_bit_size; 371 } 372 GetIsBitfield()373 bool GetIsBitfield() const { return m_is_bitfield; } 374 SetIsBitfield(bool is_bitfield)375 void SetIsBitfield(bool is_bitfield) { m_is_bitfield = is_bitfield; } 376 377 protected: 378 lldb::TypeImplSP m_type_impl_sp; 379 uint64_t m_bit_offset; 380 ConstString m_name; 381 uint32_t m_bitfield_bit_size; // Bit size for bitfield members only 382 bool m_is_bitfield; 383 }; 384 385 /// 386 /// Sometimes you can find the name of the type corresponding to an object, but 387 /// we don't have debug 388 /// information for it. If that is the case, you can return one of these 389 /// objects, and then if it 390 /// has a full type, you can use that, but if not at least you can print the 391 /// name for informational 392 /// purposes. 393 /// 394 395 class TypeAndOrName { 396 public: 397 TypeAndOrName() = default; 398 TypeAndOrName(lldb::TypeSP &type_sp); 399 TypeAndOrName(const CompilerType &compiler_type); 400 TypeAndOrName(const char *type_str); 401 TypeAndOrName(ConstString &type_const_string); 402 403 bool operator==(const TypeAndOrName &other) const; 404 405 bool operator!=(const TypeAndOrName &other) const; 406 407 ConstString GetName() const; 408 GetCompilerType()409 CompilerType GetCompilerType() const { return m_compiler_type; } 410 411 void SetName(ConstString type_name); 412 413 void SetName(const char *type_name_cstr); 414 415 void SetTypeSP(lldb::TypeSP type_sp); 416 417 void SetCompilerType(CompilerType compiler_type); 418 419 bool IsEmpty() const; 420 421 bool HasName() const; 422 423 bool HasCompilerType() const; 424 HasType()425 bool HasType() const { return HasCompilerType(); } 426 427 void Clear(); 428 429 explicit operator bool() { return !IsEmpty(); } 430 431 private: 432 CompilerType m_compiler_type; 433 ConstString m_type_name; 434 }; 435 436 class TypeMemberFunctionImpl { 437 public: TypeMemberFunctionImpl()438 TypeMemberFunctionImpl() 439 : m_type(), m_decl(), m_name(), m_kind(lldb::eMemberFunctionKindUnknown) { 440 } 441 TypeMemberFunctionImpl(const CompilerType & type,const CompilerDecl & decl,const std::string & name,const lldb::MemberFunctionKind & kind)442 TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl, 443 const std::string &name, 444 const lldb::MemberFunctionKind &kind) 445 : m_type(type), m_decl(decl), m_name(name), m_kind(kind) {} 446 447 bool IsValid(); 448 449 ConstString GetName() const; 450 451 ConstString GetMangledName() const; 452 453 CompilerType GetType() const; 454 455 CompilerType GetReturnType() const; 456 457 size_t GetNumArguments() const; 458 459 CompilerType GetArgumentAtIndex(size_t idx) const; 460 461 lldb::MemberFunctionKind GetKind() const; 462 463 bool GetDescription(Stream &stream); 464 465 protected: 466 std::string GetPrintableTypeName(); 467 468 private: 469 CompilerType m_type; 470 CompilerDecl m_decl; 471 ConstString m_name; 472 lldb::MemberFunctionKind m_kind; 473 }; 474 475 class TypeEnumMemberImpl { 476 public: TypeEnumMemberImpl()477 TypeEnumMemberImpl() 478 : m_integer_type_sp(), m_name("<invalid>"), m_value(), m_valid(false) {} 479 480 TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, 481 ConstString name, const llvm::APSInt &value); 482 483 TypeEnumMemberImpl(const TypeEnumMemberImpl &rhs) = default; 484 485 TypeEnumMemberImpl &operator=(const TypeEnumMemberImpl &rhs); 486 IsValid()487 bool IsValid() { return m_valid; } 488 GetName()489 ConstString GetName() const { return m_name; } 490 GetIntegerType()491 const lldb::TypeImplSP &GetIntegerType() const { return m_integer_type_sp; } 492 GetValueAsUnsigned()493 uint64_t GetValueAsUnsigned() const { return m_value.getZExtValue(); } 494 GetValueAsSigned()495 int64_t GetValueAsSigned() const { return m_value.getSExtValue(); } 496 497 protected: 498 lldb::TypeImplSP m_integer_type_sp; 499 ConstString m_name; 500 llvm::APSInt m_value; 501 bool m_valid; 502 }; 503 504 class TypeEnumMemberListImpl { 505 public: TypeEnumMemberListImpl()506 TypeEnumMemberListImpl() : m_content() {} 507 Append(const lldb::TypeEnumMemberImplSP & type)508 void Append(const lldb::TypeEnumMemberImplSP &type) { 509 m_content.push_back(type); 510 } 511 512 void Append(const lldb_private::TypeEnumMemberListImpl &type_list); 513 GetTypeEnumMemberAtIndex(size_t idx)514 lldb::TypeEnumMemberImplSP GetTypeEnumMemberAtIndex(size_t idx) { 515 lldb::TypeEnumMemberImplSP enum_member; 516 if (idx < GetSize()) 517 enum_member = m_content[idx]; 518 return enum_member; 519 } 520 GetSize()521 size_t GetSize() { return m_content.size(); } 522 523 private: 524 std::vector<lldb::TypeEnumMemberImplSP> m_content; 525 }; 526 527 } // namespace lldb_private 528 529 #endif // LLDB_SYMBOL_TYPE_H 530