Type.h revision 263363
1//===-- Type.h --------------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef liblldb_Type_h_ 11#define liblldb_Type_h_ 12 13#include "lldb/lldb-private.h" 14#include "lldb/Core/ClangForward.h" 15#include "lldb/Core/ConstString.h" 16#include "lldb/Core/UserID.h" 17#include "lldb/Symbol/ClangASTType.h" 18#include "lldb/Symbol/Declaration.h" 19 20#include <set> 21 22namespace lldb_private { 23 24class SymbolFileType : 25 public std::enable_shared_from_this<SymbolFileType>, 26 public UserID 27 { 28 public: 29 SymbolFileType (SymbolFile &symbol_file, lldb::user_id_t uid) : 30 UserID (uid), 31 m_symbol_file (symbol_file) 32 { 33 } 34 35 ~SymbolFileType () 36 { 37 } 38 39 Type * 40 operator->() 41 { 42 return GetType (); 43 } 44 45 Type * 46 GetType (); 47 48 protected: 49 SymbolFile &m_symbol_file; 50 lldb::TypeSP m_type_sp; 51 }; 52 53class Type : 54 public std::enable_shared_from_this<Type>, 55 public UserID 56{ 57public: 58 typedef enum EncodingDataTypeTag 59 { 60 eEncodingInvalid, 61 eEncodingIsUID, ///< This type is the type whose UID is m_encoding_uid 62 eEncodingIsConstUID, ///< This type is the type whose UID is m_encoding_uid with the const qualifier added 63 eEncodingIsRestrictUID, ///< This type is the type whose UID is m_encoding_uid with the restrict qualifier added 64 eEncodingIsVolatileUID, ///< This type is the type whose UID is m_encoding_uid with the volatile qualifier added 65 eEncodingIsTypedefUID, ///< This type is pointer to a type whose UID is m_encoding_uid 66 eEncodingIsPointerUID, ///< This type is pointer to a type whose UID is m_encoding_uid 67 eEncodingIsLValueReferenceUID, ///< This type is L value reference to a type whose UID is m_encoding_uid 68 eEncodingIsRValueReferenceUID, ///< This type is R value reference to a type whose UID is m_encoding_uid 69 eEncodingIsSyntheticUID 70 } EncodingDataType; 71 72 typedef enum ResolveStateTag 73 { 74 eResolveStateUnresolved = 0, 75 eResolveStateForward = 1, 76 eResolveStateLayout = 2, 77 eResolveStateFull = 3 78 } ResolveState; 79 80 Type (lldb::user_id_t uid, 81 SymbolFile* symbol_file, 82 const ConstString &name, 83 uint64_t byte_size, 84 SymbolContextScope *context, 85 lldb::user_id_t encoding_uid, 86 EncodingDataType encoding_uid_type, 87 const Declaration& decl, 88 const ClangASTType &clang_qual_type, 89 ResolveState clang_type_resolve_state); 90 91 // This makes an invalid type. Used for functions that return a Type when they 92 // get an error. 93 Type(); 94 95 Type (const Type &rhs); 96 97 const Type& 98 operator= (const Type& rhs); 99 100 void 101 Dump(Stream *s, bool show_context); 102 103 void 104 DumpTypeName(Stream *s); 105 106 107 void 108 GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name); 109 110 SymbolFile * 111 GetSymbolFile() 112 { 113 return m_symbol_file; 114 } 115 const SymbolFile * 116 GetSymbolFile() const 117 { 118 return m_symbol_file; 119 } 120 121 TypeList* 122 GetTypeList(); 123 124 const ConstString& 125 GetName(); 126 127 uint64_t 128 GetByteSize(); 129 130 uint32_t 131 GetNumChildren (bool omit_empty_base_classes); 132 133 bool 134 IsAggregateType (); 135 136 bool 137 IsValidType () 138 { 139 return m_encoding_uid_type != eEncodingInvalid; 140 } 141 142 bool 143 IsTypedef () 144 { 145 return m_encoding_uid_type == eEncodingIsTypedefUID; 146 } 147 148 lldb::TypeSP 149 GetTypedefType(); 150 151 const ConstString & 152 GetName () const 153 { 154 return m_name; 155 } 156 157 ConstString 158 GetQualifiedName (); 159 160 void 161 DumpValue(ExecutionContext *exe_ctx, 162 Stream *s, 163 const DataExtractor &data, 164 uint32_t data_offset, 165 bool show_type, 166 bool show_summary, 167 bool verbose, 168 lldb::Format format = lldb::eFormatDefault); 169 170 bool 171 DumpValueInMemory(ExecutionContext *exe_ctx, 172 Stream *s, 173 lldb::addr_t address, 174 AddressType address_type, 175 bool show_types, 176 bool show_summary, 177 bool verbose); 178 179 bool 180 ReadFromMemory (ExecutionContext *exe_ctx, 181 lldb::addr_t address, 182 AddressType address_type, 183 DataExtractor &data); 184 185 bool 186 WriteToMemory (ExecutionContext *exe_ctx, 187 lldb::addr_t address, 188 AddressType address_type, 189 DataExtractor &data); 190 191 bool 192 GetIsDeclaration() const; 193 194 void 195 SetIsDeclaration(bool b); 196 197 bool 198 GetIsExternal() const; 199 200 void 201 SetIsExternal(bool b); 202 203 lldb::Format 204 GetFormat (); 205 206 lldb::Encoding 207 GetEncoding (uint64_t &count); 208 209 SymbolContextScope * 210 GetSymbolContextScope() 211 { 212 return m_context; 213 } 214 const SymbolContextScope * 215 GetSymbolContextScope() const 216 { 217 return m_context; 218 } 219 void 220 SetSymbolContextScope(SymbolContextScope *context) 221 { 222 m_context = context; 223 } 224 225 const lldb_private::Declaration & 226 GetDeclaration () const; 227 228 // Get the clang type, and resolve definitions for any 229 // class/struct/union/enum types completely. 230 ClangASTType 231 GetClangFullType (); 232 233 // Get the clang type, and resolve definitions enough so that the type could 234 // have layout performed. This allows ptrs and refs to class/struct/union/enum 235 // types remain forward declarations. 236 ClangASTType 237 GetClangLayoutType (); 238 239 // Get the clang type and leave class/struct/union/enum types as forward 240 // declarations if they haven't already been fully defined. 241 ClangASTType 242 GetClangForwardType (); 243 244 ClangASTContext & 245 GetClangASTContext (); 246 247 static int 248 Compare(const Type &a, const Type &b); 249 250 // From a fully qualified typename, split the type into the type basename 251 // and the remaining type scope (namespaces/classes). 252 static bool 253 GetTypeScopeAndBasename (const char* &name_cstr, 254 std::string &scope, 255 std::string &basename, 256 lldb::TypeClass &type_class); 257 void 258 SetEncodingType (Type *encoding_type) 259 { 260 m_encoding_type = encoding_type; 261 } 262 263 uint32_t 264 GetEncodingMask (); 265 266 ClangASTType 267 CreateClangTypedefType (Type *typedef_type, Type *base_type); 268 269 bool 270 IsRealObjCClass(); 271 272 bool 273 IsCompleteObjCClass() 274 { 275 return m_flags.is_complete_objc_class; 276 } 277 278 void 279 SetIsCompleteObjCClass(bool is_complete_objc_class) 280 { 281 m_flags.is_complete_objc_class = is_complete_objc_class; 282 } 283 284protected: 285 ConstString m_name; 286 SymbolFile *m_symbol_file; 287 SymbolContextScope *m_context; // The symbol context in which this type is defined 288 Type *m_encoding_type; 289 lldb::user_id_t m_encoding_uid; 290 EncodingDataType m_encoding_uid_type; 291 uint64_t m_byte_size; 292 Declaration m_decl; 293 ClangASTType m_clang_type; 294 295 struct Flags { 296 ResolveState clang_type_resolve_state : 2; 297 bool is_complete_objc_class : 1; 298 } m_flags; 299 300 Type * 301 GetEncodingType (); 302 303 bool 304 ResolveClangType (ResolveState clang_type_resolve_state); 305}; 306 307// these classes are used to back the SBType* objects 308 309class TypePair { 310private: 311 ClangASTType clang_type; 312 lldb::TypeSP type_sp; 313 314public: 315 TypePair () : clang_type(), type_sp() {} 316 TypePair (ClangASTType type) : 317 clang_type(type), 318 type_sp() 319 { 320 } 321 322 TypePair (lldb::TypeSP type) : 323 clang_type(), 324 type_sp(type) 325 { 326 clang_type = type_sp->GetClangForwardType(); 327 } 328 329 bool 330 IsValid () const 331 { 332 return clang_type.IsValid() || (type_sp.get() != nullptr); 333 } 334 335 explicit operator bool () const 336 { 337 return IsValid(); 338 } 339 340 bool 341 operator == (const TypePair& rhs) const 342 { 343 return clang_type == rhs.clang_type && 344 type_sp.get() == rhs.type_sp.get(); 345 } 346 347 bool 348 operator != (const TypePair& rhs) const 349 { 350 return clang_type != rhs.clang_type || 351 type_sp.get() != rhs.type_sp.get(); 352 } 353 354 void 355 Clear () 356 { 357 clang_type.Clear(); 358 type_sp.reset(); 359 } 360 361 ConstString 362 GetName () const 363 { 364 if (type_sp) 365 return type_sp->GetName(); 366 if (clang_type) 367 return clang_type.GetTypeName(); 368 return ConstString (); 369 } 370 371 void 372 SetType (ClangASTType type) 373 { 374 type_sp.reset(); 375 clang_type = type; 376 } 377 378 void 379 SetType (lldb::TypeSP type) 380 { 381 type_sp = type; 382 clang_type = type_sp->GetClangForwardType(); 383 } 384 385 lldb::TypeSP 386 GetTypeSP () const 387 { 388 return type_sp; 389 } 390 391 ClangASTType 392 GetClangASTType () const 393 { 394 return clang_type; 395 } 396 397 ClangASTType 398 GetPointerType () const 399 { 400 if (type_sp) 401 return type_sp->GetClangLayoutType().GetPointerType(); 402 return clang_type.GetPointerType(); 403 } 404 405 ClangASTType 406 GetPointeeType () const 407 { 408 if (type_sp) 409 return type_sp->GetClangFullType().GetPointeeType(); 410 return clang_type.GetPointeeType(); 411 } 412 413 ClangASTType 414 GetReferenceType () const 415 { 416 if (type_sp) 417 return type_sp->GetClangLayoutType().GetLValueReferenceType(); 418 return clang_type.GetLValueReferenceType(); 419 } 420 421 ClangASTType 422 GetDereferencedType () const 423 { 424 if (type_sp) 425 return type_sp->GetClangFullType().GetNonReferenceType(); 426 return clang_type.GetNonReferenceType(); 427 } 428 429 ClangASTType 430 GetUnqualifiedType () const 431 { 432 if (type_sp) 433 return type_sp->GetClangLayoutType().GetFullyUnqualifiedType(); 434 return clang_type.GetFullyUnqualifiedType(); 435 } 436 437 ClangASTType 438 GetCanonicalType () const 439 { 440 if (type_sp) 441 return type_sp->GetClangFullType().GetCanonicalType(); 442 return clang_type.GetCanonicalType(); 443 } 444 445 clang::ASTContext * 446 GetClangASTContext () const 447 { 448 return clang_type.GetASTContext(); 449 } 450}; 451 452class TypeImpl 453{ 454public: 455 456 TypeImpl(); 457 458 ~TypeImpl () {} 459 460 TypeImpl(const TypeImpl& rhs); 461 462 TypeImpl (lldb::TypeSP type_sp); 463 464 TypeImpl (ClangASTType clang_type); 465 466 TypeImpl (lldb::TypeSP type_sp, ClangASTType dynamic); 467 468 TypeImpl (ClangASTType clang_type, ClangASTType dynamic); 469 470 TypeImpl (TypePair pair, ClangASTType dynamic); 471 472 void 473 SetType (lldb::TypeSP type_sp); 474 475 void 476 SetType (ClangASTType clang_type); 477 478 void 479 SetType (lldb::TypeSP type_sp, ClangASTType dynamic); 480 481 void 482 SetType (ClangASTType clang_type, ClangASTType dynamic); 483 484 void 485 SetType (TypePair pair, ClangASTType dynamic); 486 487 TypeImpl& 488 operator = (const TypeImpl& rhs); 489 490 bool 491 operator == (const TypeImpl& rhs) const; 492 493 bool 494 operator != (const TypeImpl& rhs) const; 495 496 bool 497 IsValid() const; 498 499 explicit operator bool () const; 500 501 void Clear(); 502 503 ConstString 504 GetName () const; 505 506 TypeImpl 507 GetPointerType () const; 508 509 TypeImpl 510 GetPointeeType () const; 511 512 TypeImpl 513 GetReferenceType () const; 514 515 TypeImpl 516 GetDereferencedType () const; 517 518 TypeImpl 519 GetUnqualifiedType() const; 520 521 TypeImpl 522 GetCanonicalType() const; 523 524 ClangASTType 525 GetClangASTType (bool prefer_dynamic); 526 527 clang::ASTContext * 528 GetClangASTContext (bool prefer_dynamic); 529 530 bool 531 GetDescription (lldb_private::Stream &strm, 532 lldb::DescriptionLevel description_level); 533 534private: 535 TypePair m_static_type; 536 ClangASTType m_dynamic_type; 537}; 538 539class TypeListImpl 540{ 541public: 542 TypeListImpl() : 543 m_content() 544 { 545 } 546 547 void 548 Append (const lldb::TypeImplSP& type) 549 { 550 m_content.push_back(type); 551 } 552 553 class AppendVisitor 554 { 555 public: 556 AppendVisitor(TypeListImpl &type_list) : 557 m_type_list(type_list) 558 { 559 } 560 561 void 562 operator() (const lldb::TypeImplSP& type) 563 { 564 m_type_list.Append(type); 565 } 566 567 private: 568 TypeListImpl &m_type_list; 569 }; 570 571 void 572 Append (const lldb_private::TypeList &type_list); 573 574 lldb::TypeImplSP 575 GetTypeAtIndex(size_t idx) 576 { 577 lldb::TypeImplSP type_sp; 578 if (idx < GetSize()) 579 type_sp = m_content[idx]; 580 return type_sp; 581 } 582 583 size_t 584 GetSize() 585 { 586 return m_content.size(); 587 } 588 589private: 590 std::vector<lldb::TypeImplSP> m_content; 591}; 592 593class TypeMemberImpl 594{ 595public: 596 TypeMemberImpl () : 597 m_type_impl_sp (), 598 m_bit_offset (0), 599 m_name (), 600 m_bitfield_bit_size (0), 601 m_is_bitfield (false) 602 603 { 604 } 605 606 TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp, 607 uint64_t bit_offset, 608 const ConstString &name, 609 uint32_t bitfield_bit_size = 0, 610 bool is_bitfield = false) : 611 m_type_impl_sp (type_impl_sp), 612 m_bit_offset (bit_offset), 613 m_name (name), 614 m_bitfield_bit_size (bitfield_bit_size), 615 m_is_bitfield (is_bitfield) 616 { 617 } 618 619 TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp, 620 uint64_t bit_offset): 621 m_type_impl_sp (type_impl_sp), 622 m_bit_offset (bit_offset), 623 m_name (), 624 m_bitfield_bit_size (0), 625 m_is_bitfield (false) 626 { 627 if (m_type_impl_sp) 628 m_name = m_type_impl_sp->GetName(); 629 } 630 631 const lldb::TypeImplSP & 632 GetTypeImpl () 633 { 634 return m_type_impl_sp; 635 } 636 637 const ConstString & 638 GetName () const 639 { 640 return m_name; 641 } 642 643 uint64_t 644 GetBitOffset () const 645 { 646 return m_bit_offset; 647 } 648 649 uint32_t 650 GetBitfieldBitSize () const 651 { 652 return m_bitfield_bit_size; 653 } 654 655 void 656 SetBitfieldBitSize (uint32_t bitfield_bit_size) 657 { 658 m_bitfield_bit_size = bitfield_bit_size; 659 } 660 661 bool 662 GetIsBitfield () const 663 { 664 return m_is_bitfield; 665 } 666 667 void 668 SetIsBitfield (bool is_bitfield) 669 { 670 m_is_bitfield = is_bitfield; 671 } 672 673protected: 674 lldb::TypeImplSP m_type_impl_sp; 675 uint64_t m_bit_offset; 676 ConstString m_name; 677 uint32_t m_bitfield_bit_size; // Bit size for bitfield members only 678 bool m_is_bitfield; 679}; 680 681 682/// 683/// Sometimes you can find the name of the type corresponding to an object, but we don't have debug 684/// information for it. If that is the case, you can return one of these objects, and then if it 685/// has a full type, you can use that, but if not at least you can print the name for informational 686/// purposes. 687/// 688 689class TypeAndOrName 690{ 691public: 692 TypeAndOrName (); 693 TypeAndOrName (lldb::TypeSP &type_sp); 694 TypeAndOrName (const ClangASTType &clang_type); 695 TypeAndOrName (const char *type_str); 696 TypeAndOrName (const TypeAndOrName &rhs); 697 TypeAndOrName (ConstString &type_const_string); 698 699 TypeAndOrName & 700 operator= (const TypeAndOrName &rhs); 701 702 bool 703 operator==(const TypeAndOrName &other) const; 704 705 bool 706 operator!=(const TypeAndOrName &other) const; 707 708 ConstString GetName () const; 709 710 lldb::TypeSP 711 GetTypeSP () const 712 { 713 return m_type_pair.GetTypeSP(); 714 } 715 716 ClangASTType 717 GetClangASTType () const 718 { 719 return m_type_pair.GetClangASTType(); 720 } 721 722 void 723 SetName (const ConstString &type_name); 724 725 void 726 SetName (const char *type_name_cstr); 727 728 void 729 SetTypeSP (lldb::TypeSP type_sp); 730 731 void 732 SetClangASTType (ClangASTType clang_type); 733 734 bool 735 IsEmpty () const; 736 737 bool 738 HasName () const; 739 740 bool 741 HasTypeSP () const; 742 743 bool 744 HasClangASTType () const; 745 746 bool 747 HasType () const 748 { 749 return HasTypeSP() || HasClangASTType(); 750 } 751 752 void 753 Clear (); 754 755 explicit operator bool () 756 { 757 return !IsEmpty(); 758 } 759 760private: 761 TypePair m_type_pair; 762 ConstString m_type_name; 763}; 764 765} // namespace lldb_private 766 767#endif // liblldb_Type_h_ 768 769