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