1//===-- Type.cpp ------------------------------------------------*- 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// Other libraries and framework includes 11 12#include "lldb/Core/DataExtractor.h" 13#include "lldb/Core/DataBufferHeap.h" 14#include "lldb/Core/Module.h" 15#include "lldb/Core/Scalar.h" 16#include "lldb/Core/StreamString.h" 17 18#include "lldb/Symbol/ClangASTType.h" 19#include "lldb/Symbol/ClangASTContext.h" 20#include "lldb/Symbol/ObjectFile.h" 21#include "lldb/Symbol/SymbolContextScope.h" 22#include "lldb/Symbol/SymbolFile.h" 23#include "lldb/Symbol/SymbolVendor.h" 24#include "lldb/Symbol/Type.h" 25#include "lldb/Symbol/TypeList.h" 26 27#include "lldb/Target/ExecutionContext.h" 28#include "lldb/Target/Process.h" 29#include "lldb/Target/Target.h" 30 31#include "llvm/ADT/StringRef.h" 32 33using namespace lldb; 34using namespace lldb_private; 35 36class TypeAppendVisitor 37{ 38public: 39 TypeAppendVisitor(TypeListImpl &type_list) : 40 m_type_list(type_list) 41 { 42 } 43 44 bool 45 operator() (const lldb::TypeSP& type) 46 { 47 m_type_list.Append(TypeImplSP(new TypeImpl(type))); 48 return true; 49 } 50 51private: 52 TypeListImpl &m_type_list; 53}; 54 55void 56TypeListImpl::Append (const lldb_private::TypeList &type_list) 57{ 58 TypeAppendVisitor cb(*this); 59 type_list.ForEach(cb); 60} 61 62 63Type * 64SymbolFileType::GetType () 65{ 66 if (!m_type_sp) 67 { 68 Type *resolved_type = m_symbol_file.ResolveTypeUID (GetID()); 69 if (resolved_type) 70 m_type_sp = resolved_type->shared_from_this(); 71 } 72 return m_type_sp.get(); 73} 74 75 76Type::Type 77( 78 lldb::user_id_t uid, 79 SymbolFile* symbol_file, 80 const ConstString &name, 81 uint64_t byte_size, 82 SymbolContextScope *context, 83 user_id_t encoding_uid, 84 EncodingDataType encoding_uid_type, 85 const Declaration& decl, 86 const ClangASTType &clang_type, 87 ResolveState clang_type_resolve_state 88) : 89 std::enable_shared_from_this<Type> (), 90 UserID (uid), 91 m_name (name), 92 m_symbol_file (symbol_file), 93 m_context (context), 94 m_encoding_type (NULL), 95 m_encoding_uid (encoding_uid), 96 m_encoding_uid_type (encoding_uid_type), 97 m_byte_size (byte_size), 98 m_decl (decl), 99 m_clang_type (clang_type) 100{ 101 m_flags.clang_type_resolve_state = (clang_type ? clang_type_resolve_state : eResolveStateUnresolved); 102 m_flags.is_complete_objc_class = false; 103} 104 105Type::Type () : 106 std::enable_shared_from_this<Type> (), 107 UserID (0), 108 m_name ("<INVALID TYPE>"), 109 m_symbol_file (NULL), 110 m_context (NULL), 111 m_encoding_type (NULL), 112 m_encoding_uid (LLDB_INVALID_UID), 113 m_encoding_uid_type (eEncodingInvalid), 114 m_byte_size (0), 115 m_decl (), 116 m_clang_type () 117{ 118 m_flags.clang_type_resolve_state = eResolveStateUnresolved; 119 m_flags.is_complete_objc_class = false; 120} 121 122 123Type::Type (const Type &rhs) : 124 std::enable_shared_from_this<Type> (rhs), 125 UserID (rhs), 126 m_name (rhs.m_name), 127 m_symbol_file (rhs.m_symbol_file), 128 m_context (rhs.m_context), 129 m_encoding_type (rhs.m_encoding_type), 130 m_encoding_uid (rhs.m_encoding_uid), 131 m_encoding_uid_type (rhs.m_encoding_uid_type), 132 m_byte_size (rhs.m_byte_size), 133 m_decl (rhs.m_decl), 134 m_clang_type (rhs.m_clang_type), 135 m_flags (rhs.m_flags) 136{ 137} 138 139const Type& 140Type::operator= (const Type& rhs) 141{ 142 if (this != &rhs) 143 { 144 } 145 return *this; 146} 147 148 149void 150Type::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name) 151{ 152 *s << "id = " << (const UserID&)*this; 153 154 // Call the name accessor to make sure we resolve the type name 155 if (show_name) 156 { 157 const ConstString &type_name = GetName(); 158 if (type_name) 159 { 160 *s << ", name = \"" << type_name << '"'; 161 ConstString qualified_type_name (GetQualifiedName()); 162 if (qualified_type_name != type_name) 163 { 164 *s << ", qualified = \"" << qualified_type_name << '"'; 165 } 166 } 167 } 168 169 // Call the get byte size accesor so we resolve our byte size 170 if (GetByteSize()) 171 s->Printf(", byte-size = %" PRIu64, m_byte_size); 172 bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose); 173 m_decl.Dump(s, show_fullpaths); 174 175 if (m_clang_type.IsValid()) 176 { 177 *s << ", clang_type = \""; 178 GetClangForwardType().DumpTypeDescription(s); 179 *s << '"'; 180 } 181 else if (m_encoding_uid != LLDB_INVALID_UID) 182 { 183 s->Printf(", type_uid = 0x%8.8" PRIx64, m_encoding_uid); 184 switch (m_encoding_uid_type) 185 { 186 case eEncodingInvalid: break; 187 case eEncodingIsUID: s->PutCString(" (unresolved type)"); break; 188 case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break; 189 case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break; 190 case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break; 191 case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break; 192 case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break; 193 case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break; 194 case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break; 195 case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break; 196 } 197 } 198} 199 200 201void 202Type::Dump (Stream *s, bool show_context) 203{ 204 s->Printf("%p: ", this); 205 s->Indent(); 206 *s << "Type" << (const UserID&)*this << ' '; 207 if (m_name) 208 *s << ", name = \"" << m_name << "\""; 209 210 if (m_byte_size != 0) 211 s->Printf(", size = %" PRIu64, m_byte_size); 212 213 if (show_context && m_context != NULL) 214 { 215 s->PutCString(", context = ( "); 216 m_context->DumpSymbolContext(s); 217 s->PutCString(" )"); 218 } 219 220 bool show_fullpaths = false; 221 m_decl.Dump (s,show_fullpaths); 222 223 if (m_clang_type.IsValid()) 224 { 225 *s << ", clang_type = " << m_clang_type.GetOpaqueQualType() << ' '; 226 GetClangForwardType().DumpTypeDescription (s); 227 } 228 else if (m_encoding_uid != LLDB_INVALID_UID) 229 { 230 *s << ", type_data = " << (uint64_t)m_encoding_uid; 231 switch (m_encoding_uid_type) 232 { 233 case eEncodingInvalid: break; 234 case eEncodingIsUID: s->PutCString(" (unresolved type)"); break; 235 case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break; 236 case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break; 237 case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break; 238 case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break; 239 case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break; 240 case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break; 241 case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break; 242 case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break; 243 } 244 } 245 246// 247// if (m_access) 248// s->Printf(", access = %u", m_access); 249 s->EOL(); 250} 251 252const ConstString & 253Type::GetName() 254{ 255 if (!m_name) 256 m_name = GetClangForwardType().GetConstTypeName(); 257 return m_name; 258} 259 260void 261Type::DumpTypeName(Stream *s) 262{ 263 GetName().Dump(s, "<invalid-type-name>"); 264} 265 266 267void 268Type::DumpValue 269( 270 ExecutionContext *exe_ctx, 271 Stream *s, 272 const DataExtractor &data, 273 uint32_t data_byte_offset, 274 bool show_types, 275 bool show_summary, 276 bool verbose, 277 lldb::Format format 278) 279{ 280 if (ResolveClangType(eResolveStateForward)) 281 { 282 if (show_types) 283 { 284 s->PutChar('('); 285 if (verbose) 286 s->Printf("Type{0x%8.8" PRIx64 "} ", GetID()); 287 DumpTypeName (s); 288 s->PutCString(") "); 289 } 290 291 GetClangForwardType().DumpValue (exe_ctx, 292 s, 293 format == lldb::eFormatDefault ? GetFormat() : format, 294 data, 295 data_byte_offset, 296 GetByteSize(), 297 0, // Bitfield bit size 298 0, // Bitfield bit offset 299 show_types, 300 show_summary, 301 verbose, 302 0); 303 } 304} 305 306Type * 307Type::GetEncodingType () 308{ 309 if (m_encoding_type == NULL && m_encoding_uid != LLDB_INVALID_UID) 310 m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid); 311 return m_encoding_type; 312} 313 314 315 316uint64_t 317Type::GetByteSize() 318{ 319 if (m_byte_size == 0) 320 { 321 switch (m_encoding_uid_type) 322 { 323 case eEncodingInvalid: 324 case eEncodingIsSyntheticUID: 325 break; 326 case eEncodingIsUID: 327 case eEncodingIsConstUID: 328 case eEncodingIsRestrictUID: 329 case eEncodingIsVolatileUID: 330 case eEncodingIsTypedefUID: 331 { 332 Type *encoding_type = GetEncodingType (); 333 if (encoding_type) 334 m_byte_size = encoding_type->GetByteSize(); 335 if (m_byte_size == 0) 336 m_byte_size = GetClangLayoutType().GetByteSize(); 337 } 338 break; 339 340 // If we are a pointer or reference, then this is just a pointer size; 341 case eEncodingIsPointerUID: 342 case eEncodingIsLValueReferenceUID: 343 case eEncodingIsRValueReferenceUID: 344 m_byte_size = m_symbol_file->GetClangASTContext().GetPointerByteSize(); 345 break; 346 } 347 } 348 return m_byte_size; 349} 350 351 352uint32_t 353Type::GetNumChildren (bool omit_empty_base_classes) 354{ 355 return GetClangForwardType().GetNumChildren(omit_empty_base_classes); 356} 357 358bool 359Type::IsAggregateType () 360{ 361 return GetClangForwardType().IsAggregateType(); 362} 363 364lldb::TypeSP 365Type::GetTypedefType() 366{ 367 lldb::TypeSP type_sp; 368 if (IsTypedef()) 369 { 370 Type *typedef_type = m_symbol_file->ResolveTypeUID(m_encoding_uid); 371 if (typedef_type) 372 type_sp = typedef_type->shared_from_this(); 373 } 374 return type_sp; 375} 376 377 378 379lldb::Format 380Type::GetFormat () 381{ 382 return GetClangForwardType().GetFormat(); 383} 384 385 386 387lldb::Encoding 388Type::GetEncoding (uint64_t &count) 389{ 390 // Make sure we resolve our type if it already hasn't been. 391 return GetClangForwardType().GetEncoding(count); 392} 393 394bool 395Type::DumpValueInMemory 396( 397 ExecutionContext *exe_ctx, 398 Stream *s, 399 lldb::addr_t address, 400 AddressType address_type, 401 bool show_types, 402 bool show_summary, 403 bool verbose 404) 405{ 406 if (address != LLDB_INVALID_ADDRESS) 407 { 408 DataExtractor data; 409 Target *target = NULL; 410 if (exe_ctx) 411 target = exe_ctx->GetTargetPtr(); 412 if (target) 413 data.SetByteOrder (target->GetArchitecture().GetByteOrder()); 414 if (ReadFromMemory (exe_ctx, address, address_type, data)) 415 { 416 DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose); 417 return true; 418 } 419 } 420 return false; 421} 422 423 424bool 425Type::ReadFromMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data) 426{ 427 if (address_type == eAddressTypeFile) 428 { 429 // Can't convert a file address to anything valid without more 430 // context (which Module it came from) 431 return false; 432 } 433 434 const uint64_t byte_size = GetByteSize(); 435 if (data.GetByteSize() < byte_size) 436 { 437 lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0')); 438 data.SetData(data_sp); 439 } 440 441 uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size); 442 if (dst != NULL) 443 { 444 if (address_type == eAddressTypeHost) 445 { 446 // The address is an address in this process, so just copy it 447 if (addr == 0) 448 return false; 449 memcpy (dst, (uint8_t*)NULL + addr, byte_size); 450 return true; 451 } 452 else 453 { 454 if (exe_ctx) 455 { 456 Process *process = exe_ctx->GetProcessPtr(); 457 if (process) 458 { 459 Error error; 460 return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size, error) == byte_size; 461 } 462 } 463 } 464 } 465 return false; 466} 467 468 469bool 470Type::WriteToMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data) 471{ 472 return false; 473} 474 475 476TypeList* 477Type::GetTypeList() 478{ 479 return GetSymbolFile()->GetTypeList(); 480} 481 482const Declaration & 483Type::GetDeclaration () const 484{ 485 return m_decl; 486} 487 488bool 489Type::ResolveClangType (ResolveState clang_type_resolve_state) 490{ 491 Type *encoding_type = NULL; 492 if (!m_clang_type.IsValid()) 493 { 494 encoding_type = GetEncodingType(); 495 if (encoding_type) 496 { 497 switch (m_encoding_uid_type) 498 { 499 case eEncodingIsUID: 500 { 501 ClangASTType encoding_clang_type = encoding_type->GetClangForwardType(); 502 if (encoding_clang_type.IsValid()) 503 { 504 m_clang_type = encoding_clang_type; 505 m_flags.clang_type_resolve_state = encoding_type->m_flags.clang_type_resolve_state; 506 } 507 } 508 break; 509 510 case eEncodingIsConstUID: 511 m_clang_type = encoding_type->GetClangForwardType().AddConstModifier(); 512 break; 513 514 case eEncodingIsRestrictUID: 515 m_clang_type = encoding_type->GetClangForwardType().AddRestrictModifier(); 516 break; 517 518 case eEncodingIsVolatileUID: 519 m_clang_type = encoding_type->GetClangForwardType().AddVolatileModifier(); 520 break; 521 522 case eEncodingIsTypedefUID: 523 m_clang_type = encoding_type->GetClangForwardType().CreateTypedefType (GetName().AsCString(), 524 GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID())); 525 m_name.Clear(); 526 break; 527 528 case eEncodingIsPointerUID: 529 m_clang_type = encoding_type->GetClangForwardType().GetPointerType(); 530 break; 531 532 case eEncodingIsLValueReferenceUID: 533 m_clang_type = encoding_type->GetClangForwardType().GetLValueReferenceType(); 534 break; 535 536 case eEncodingIsRValueReferenceUID: 537 m_clang_type = encoding_type->GetClangForwardType().GetRValueReferenceType(); 538 break; 539 540 default: 541 assert(!"Unhandled encoding_data_type."); 542 break; 543 } 544 } 545 else 546 { 547 // We have no encoding type, return void? 548 ClangASTType void_clang_type (ClangASTContext::GetBasicType(GetClangASTContext().getASTContext(), eBasicTypeVoid)); 549 switch (m_encoding_uid_type) 550 { 551 case eEncodingIsUID: 552 m_clang_type = void_clang_type; 553 break; 554 555 case eEncodingIsConstUID: 556 m_clang_type = void_clang_type.AddConstModifier (); 557 break; 558 559 case eEncodingIsRestrictUID: 560 m_clang_type = void_clang_type.AddRestrictModifier (); 561 break; 562 563 case eEncodingIsVolatileUID: 564 m_clang_type = void_clang_type.AddVolatileModifier (); 565 break; 566 567 case eEncodingIsTypedefUID: 568 m_clang_type = void_clang_type.CreateTypedefType (GetName().AsCString(), 569 GetSymbolFile()->GetClangDeclContextContainingTypeUID(GetID())); 570 break; 571 572 case eEncodingIsPointerUID: 573 m_clang_type = void_clang_type.GetPointerType (); 574 break; 575 576 case eEncodingIsLValueReferenceUID: 577 m_clang_type = void_clang_type.GetLValueReferenceType (); 578 break; 579 580 case eEncodingIsRValueReferenceUID: 581 m_clang_type = void_clang_type.GetRValueReferenceType (); 582 break; 583 584 default: 585 assert(!"Unhandled encoding_data_type."); 586 break; 587 } 588 } 589 } 590 591 // Check if we have a forward reference to a class/struct/union/enum? 592 if (m_clang_type.IsValid() && m_flags.clang_type_resolve_state < clang_type_resolve_state) 593 { 594 m_flags.clang_type_resolve_state = eResolveStateFull; 595 if (!m_clang_type.IsDefined ()) 596 { 597 // We have a forward declaration, we need to resolve it to a complete definition. 598 m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type); 599 } 600 } 601 602 // If we have an encoding type, then we need to make sure it is 603 // resolved appropriately. 604 if (m_encoding_uid != LLDB_INVALID_UID) 605 { 606 if (encoding_type == NULL) 607 encoding_type = GetEncodingType(); 608 if (encoding_type) 609 { 610 ResolveState encoding_clang_type_resolve_state = clang_type_resolve_state; 611 612 if (clang_type_resolve_state == eResolveStateLayout) 613 { 614 switch (m_encoding_uid_type) 615 { 616 case eEncodingIsPointerUID: 617 case eEncodingIsLValueReferenceUID: 618 case eEncodingIsRValueReferenceUID: 619 encoding_clang_type_resolve_state = eResolveStateForward; 620 break; 621 default: 622 break; 623 } 624 } 625 encoding_type->ResolveClangType (encoding_clang_type_resolve_state); 626 } 627 } 628 return m_clang_type.IsValid(); 629} 630uint32_t 631Type::GetEncodingMask () 632{ 633 uint32_t encoding_mask = 1u << m_encoding_uid_type; 634 Type *encoding_type = GetEncodingType(); 635 assert (encoding_type != this); 636 if (encoding_type) 637 encoding_mask |= encoding_type->GetEncodingMask (); 638 return encoding_mask; 639} 640 641ClangASTType 642Type::GetClangFullType () 643{ 644 ResolveClangType(eResolveStateFull); 645 return m_clang_type; 646} 647 648ClangASTType 649Type::GetClangLayoutType () 650{ 651 ResolveClangType(eResolveStateLayout); 652 return m_clang_type; 653} 654 655ClangASTType 656Type::GetClangForwardType () 657{ 658 ResolveClangType (eResolveStateForward); 659 return m_clang_type; 660} 661 662ClangASTContext & 663Type::GetClangASTContext () 664{ 665 return m_symbol_file->GetClangASTContext(); 666} 667 668int 669Type::Compare(const Type &a, const Type &b) 670{ 671 // Just compare the UID values for now... 672 lldb::user_id_t a_uid = a.GetID(); 673 lldb::user_id_t b_uid = b.GetID(); 674 if (a_uid < b_uid) 675 return -1; 676 if (a_uid > b_uid) 677 return 1; 678 return 0; 679// if (a.getQualType() == b.getQualType()) 680// return 0; 681} 682 683 684#if 0 // START REMOVE 685// Move this into ClangASTType 686void * 687Type::CreateClangPointerType (Type *type) 688{ 689 assert(type); 690 return GetClangASTContext().CreatePointerType(type->GetClangForwardType()); 691} 692 693void * 694Type::CreateClangTypedefType (Type *typedef_type, Type *base_type) 695{ 696 assert(typedef_type && base_type); 697 return GetClangASTContext().CreateTypedefType (typedef_type->GetName().AsCString(), 698 base_type->GetClangForwardType(), 699 typedef_type->GetSymbolFile()->GetClangDeclContextContainingTypeUID(typedef_type->GetID())); 700} 701 702void * 703Type::CreateClangLValueReferenceType (Type *type) 704{ 705 assert(type); 706 return GetClangASTContext().CreateLValueReferenceType(type->GetClangForwardType()); 707} 708 709void * 710Type::CreateClangRValueReferenceType (Type *type) 711{ 712 assert(type); 713 return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType()); 714} 715#endif // END REMOVE 716 717bool 718Type::IsRealObjCClass() 719{ 720 // For now we are just skipping ObjC classes that get made by hand from the runtime, because 721 // those don't have any information. We could extend this to only return true for "full 722 // definitions" if we can figure that out. 723 724 if (m_clang_type.IsObjCObjectOrInterfaceType() && GetByteSize() != 0) 725 return true; 726 else 727 return false; 728} 729 730ConstString 731Type::GetQualifiedName () 732{ 733 return GetClangForwardType().GetConstTypeName(); 734} 735 736 737bool 738Type::GetTypeScopeAndBasename (const char* &name_cstr, 739 std::string &scope, 740 std::string &basename, 741 TypeClass &type_class) 742{ 743 // Protect against null c string. 744 745 type_class = eTypeClassAny; 746 747 if (name_cstr && name_cstr[0]) 748 { 749 llvm::StringRef name_strref(name_cstr); 750 if (name_strref.startswith("struct ")) 751 { 752 name_cstr += 7; 753 type_class = eTypeClassStruct; 754 } 755 else if (name_strref.startswith("class ")) 756 { 757 name_cstr += 6; 758 type_class = eTypeClassClass; 759 } 760 else if (name_strref.startswith("union ")) 761 { 762 name_cstr += 6; 763 type_class = eTypeClassUnion; 764 } 765 else if (name_strref.startswith("enum ")) 766 { 767 name_cstr += 5; 768 type_class = eTypeClassEnumeration; 769 } 770 else if (name_strref.startswith("typedef ")) 771 { 772 name_cstr += 8; 773 type_class = eTypeClassTypedef; 774 } 775 const char *basename_cstr = name_cstr; 776 const char* namespace_separator = ::strstr (basename_cstr, "::"); 777 if (namespace_separator) 778 { 779 const char* template_arg_char = ::strchr (basename_cstr, '<'); 780 while (namespace_separator != NULL) 781 { 782 if (template_arg_char && namespace_separator > template_arg_char) // but namespace'd template arguments are still good to go 783 break; 784 basename_cstr = namespace_separator + 2; 785 namespace_separator = strstr(basename_cstr, "::"); 786 } 787 if (basename_cstr > name_cstr) 788 { 789 scope.assign (name_cstr, basename_cstr - name_cstr); 790 basename.assign (basename_cstr); 791 return true; 792 } 793 } 794 } 795 return false; 796} 797 798 799 800 801TypeAndOrName::TypeAndOrName () : m_type_pair(), m_type_name() 802{ 803 804} 805 806TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_pair(in_type_sp) 807{ 808 if (in_type_sp) 809 m_type_name = in_type_sp->GetName(); 810} 811 812TypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str) 813{ 814} 815 816TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_pair (rhs.m_type_pair), m_type_name (rhs.m_type_name) 817{ 818 819} 820 821TypeAndOrName::TypeAndOrName (ConstString &in_type_const_string) : m_type_name (in_type_const_string) 822{ 823} 824 825TypeAndOrName & 826TypeAndOrName::operator= (const TypeAndOrName &rhs) 827{ 828 if (this != &rhs) 829 { 830 m_type_name = rhs.m_type_name; 831 m_type_pair = rhs.m_type_pair; 832 } 833 return *this; 834} 835 836bool 837TypeAndOrName::operator==(const TypeAndOrName &other) const 838{ 839 if (m_type_pair != other.m_type_pair) 840 return false; 841 if (m_type_name != other.m_type_name) 842 return false; 843 return true; 844} 845 846bool 847TypeAndOrName::operator!=(const TypeAndOrName &other) const 848{ 849 if (m_type_pair != other.m_type_pair) 850 return true; 851 if (m_type_name != other.m_type_name) 852 return true; 853 return false; 854} 855 856ConstString 857TypeAndOrName::GetName () const 858{ 859 if (m_type_name) 860 return m_type_name; 861 if (m_type_pair) 862 return m_type_pair.GetName(); 863 return ConstString("<invalid>"); 864} 865 866void 867TypeAndOrName::SetName (const ConstString &type_name) 868{ 869 m_type_name = type_name; 870} 871 872void 873TypeAndOrName::SetName (const char *type_name_cstr) 874{ 875 m_type_name.SetCString (type_name_cstr); 876} 877 878void 879TypeAndOrName::SetTypeSP (lldb::TypeSP type_sp) 880{ 881 m_type_pair.SetType(type_sp); 882 if (m_type_pair) 883 m_type_name = m_type_pair.GetName(); 884} 885 886void 887TypeAndOrName::SetClangASTType (ClangASTType clang_type) 888{ 889 m_type_pair.SetType(clang_type); 890 if (m_type_pair) 891 m_type_name = m_type_pair.GetName(); 892} 893 894bool 895TypeAndOrName::IsEmpty() const 896{ 897 if ((bool)m_type_name || (bool)m_type_pair) 898 return false; 899 else 900 return true; 901} 902 903void 904TypeAndOrName::Clear () 905{ 906 m_type_name.Clear(); 907 m_type_pair.Clear(); 908} 909 910bool 911TypeAndOrName::HasName () const 912{ 913 return (bool)m_type_name; 914} 915 916bool 917TypeAndOrName::HasTypeSP () const 918{ 919 return m_type_pair.GetTypeSP().get() != nullptr; 920} 921 922bool 923TypeAndOrName::HasClangASTType () const 924{ 925 return m_type_pair.GetClangASTType().IsValid(); 926} 927 928 929TypeImpl::TypeImpl() : 930m_static_type(), 931m_dynamic_type() 932{ 933} 934 935TypeImpl::TypeImpl(const TypeImpl& rhs) : 936m_static_type(rhs.m_static_type), 937m_dynamic_type(rhs.m_dynamic_type) 938{ 939} 940 941TypeImpl::TypeImpl (lldb::TypeSP type_sp) : 942m_static_type(type_sp), 943m_dynamic_type() 944{ 945} 946 947TypeImpl::TypeImpl (ClangASTType clang_type) : 948m_static_type(clang_type), 949m_dynamic_type() 950{ 951} 952 953TypeImpl::TypeImpl (lldb::TypeSP type_sp, ClangASTType dynamic) : 954m_static_type (type_sp), 955m_dynamic_type(dynamic) 956{ 957} 958 959TypeImpl::TypeImpl (ClangASTType clang_type, ClangASTType dynamic) : 960m_static_type (clang_type), 961m_dynamic_type(dynamic) 962{ 963} 964 965TypeImpl::TypeImpl (TypePair pair, ClangASTType dynamic) : 966m_static_type (pair), 967m_dynamic_type(dynamic) 968{ 969} 970 971void 972TypeImpl::SetType (lldb::TypeSP type_sp) 973{ 974 m_static_type.SetType(type_sp); 975} 976 977void 978TypeImpl::SetType (ClangASTType clang_type) 979{ 980 m_static_type.SetType (clang_type); 981} 982 983void 984TypeImpl::SetType (lldb::TypeSP type_sp, ClangASTType dynamic) 985{ 986 m_static_type.SetType (type_sp); 987 m_dynamic_type = dynamic; 988} 989 990void 991TypeImpl::SetType (ClangASTType clang_type, ClangASTType dynamic) 992{ 993 m_static_type.SetType (clang_type); 994 m_dynamic_type = dynamic; 995} 996 997void 998TypeImpl::SetType (TypePair pair, ClangASTType dynamic) 999{ 1000 m_static_type = pair; 1001 m_dynamic_type = dynamic; 1002} 1003 1004TypeImpl& 1005TypeImpl::operator = (const TypeImpl& rhs) 1006{ 1007 if (rhs != *this) 1008 { 1009 m_static_type = rhs.m_static_type; 1010 m_dynamic_type = rhs.m_dynamic_type; 1011 } 1012 return *this; 1013} 1014 1015bool 1016TypeImpl::operator == (const TypeImpl& rhs) const 1017{ 1018 return m_static_type == rhs.m_static_type && 1019 m_dynamic_type == rhs.m_dynamic_type; 1020} 1021 1022bool 1023TypeImpl::operator != (const TypeImpl& rhs) const 1024{ 1025 return m_static_type != rhs.m_static_type || 1026 m_dynamic_type != rhs.m_dynamic_type; 1027} 1028 1029bool 1030TypeImpl::IsValid() const 1031{ 1032 // just a name is not valid 1033 return m_static_type.IsValid() || m_dynamic_type.IsValid(); 1034} 1035 1036TypeImpl::operator bool () const 1037{ 1038 return IsValid(); 1039} 1040 1041void 1042TypeImpl::Clear() 1043{ 1044 m_static_type.Clear(); 1045 m_dynamic_type.Clear(); 1046} 1047 1048ConstString 1049TypeImpl::GetName () const 1050{ 1051 if (m_dynamic_type) 1052 return m_dynamic_type.GetTypeName(); 1053 return m_static_type.GetName (); 1054} 1055 1056TypeImpl 1057TypeImpl::GetPointerType () const 1058{ 1059 if (m_dynamic_type.IsValid()) 1060 { 1061 return TypeImpl(m_static_type, m_dynamic_type.GetPointerType()); 1062 } 1063 return TypeImpl(m_static_type.GetPointerType()); 1064} 1065 1066TypeImpl 1067TypeImpl::GetPointeeType () const 1068{ 1069 if (m_dynamic_type.IsValid()) 1070 { 1071 return TypeImpl(m_static_type, m_dynamic_type.GetPointeeType()); 1072 } 1073 return TypeImpl(m_static_type.GetPointeeType()); 1074} 1075 1076TypeImpl 1077TypeImpl::GetReferenceType () const 1078{ 1079 if (m_dynamic_type.IsValid()) 1080 { 1081 return TypeImpl(m_static_type, m_dynamic_type.GetLValueReferenceType()); 1082 } 1083 return TypeImpl(m_static_type.GetReferenceType()); 1084} 1085 1086TypeImpl 1087TypeImpl::GetTypedefedType () const 1088{ 1089 if (m_dynamic_type.IsValid()) 1090 { 1091 return TypeImpl(m_static_type, m_dynamic_type.GetTypedefedType()); 1092 } 1093 return TypeImpl(m_static_type.GetTypedefedType()); 1094} 1095 1096TypeImpl 1097TypeImpl::GetDereferencedType () const 1098{ 1099 if (m_dynamic_type.IsValid()) 1100 { 1101 return TypeImpl(m_static_type, m_dynamic_type.GetNonReferenceType()); 1102 } 1103 return TypeImpl(m_static_type.GetDereferencedType()); 1104} 1105 1106TypeImpl 1107TypeImpl::GetUnqualifiedType() const 1108{ 1109 if (m_dynamic_type.IsValid()) 1110 { 1111 return TypeImpl(m_static_type, m_dynamic_type.GetFullyUnqualifiedType()); 1112 } 1113 return TypeImpl(m_static_type.GetUnqualifiedType()); 1114} 1115 1116TypeImpl 1117TypeImpl::GetCanonicalType() const 1118{ 1119 if (m_dynamic_type.IsValid()) 1120 { 1121 return TypeImpl(m_static_type, m_dynamic_type.GetCanonicalType()); 1122 } 1123 return TypeImpl(m_static_type.GetCanonicalType()); 1124} 1125 1126ClangASTType 1127TypeImpl::GetClangASTType (bool prefer_dynamic) 1128{ 1129 if (prefer_dynamic) 1130 { 1131 if (m_dynamic_type.IsValid()) 1132 return m_dynamic_type; 1133 } 1134 return m_static_type.GetClangASTType(); 1135} 1136 1137clang::ASTContext * 1138TypeImpl::GetClangASTContext (bool prefer_dynamic) 1139{ 1140 if (prefer_dynamic) 1141 { 1142 if (m_dynamic_type.IsValid()) 1143 return m_dynamic_type.GetASTContext(); 1144 } 1145 return m_static_type.GetClangASTContext(); 1146} 1147 1148bool 1149TypeImpl::GetDescription (lldb_private::Stream &strm, 1150 lldb::DescriptionLevel description_level) 1151{ 1152 if (m_dynamic_type.IsValid()) 1153 { 1154 strm.Printf("Dynamic:\n"); 1155 m_dynamic_type.DumpTypeDescription(&strm); 1156 strm.Printf("\nStatic:\n"); 1157 } 1158 m_static_type.GetClangASTType().DumpTypeDescription(&strm); 1159 return true; 1160} 1161