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