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 using namespace lldb; 34 using namespace lldb_private; 35 36 class TypeAppendVisitor 37 { 38 public: 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 51 private: 52 TypeListImpl &m_type_list; 53 }; 54 55 void 56 TypeListImpl::Append (const lldb_private::TypeList &type_list) 57 { 58 TypeAppendVisitor cb(*this); 59 type_list.ForEach(cb); 60 } 61 62 63 Type * 64 SymbolFileType::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 76 Type::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 105 Type::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 123 Type::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 139 const Type& 140 Type::operator= (const Type& rhs) 141 { 142 if (this != &rhs) 143 { 144 } 145 return *this; 146 } 147 148 149 void 150 Type::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 201 void 202 Type::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 252 const ConstString & 253 Type::GetName() 254 { 255 if (!m_name) 256 m_name = GetClangForwardType().GetConstTypeName(); 257 return m_name; 258 } 259 260 void 261 Type::DumpTypeName(Stream *s) 262 { 263 GetName().Dump(s, "<invalid-type-name>"); 264 } 265 266 267 void 268 Type::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 306 Type * 307 Type::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 316 uint64_t 317 Type::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 352 uint32_t 353 Type::GetNumChildren (bool omit_empty_base_classes) 354 { 355 return GetClangForwardType().GetNumChildren(omit_empty_base_classes); 356 } 357 358 bool 359 Type::IsAggregateType () 360 { 361 return GetClangForwardType().IsAggregateType(); 362 } 363 364 lldb::TypeSP 365 Type::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 379 lldb::Format 380 Type::GetFormat () 381 { 382 return GetClangForwardType().GetFormat(); 383 } 384 385 386 387 lldb::Encoding 388 Type::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 394 bool 395 Type::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 424 bool 425 Type::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 469 bool 470 Type::WriteToMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data) 471 { 472 return false; 473 } 474 475 476 TypeList* 477 Type::GetTypeList() 478 { 479 return GetSymbolFile()->GetTypeList(); 480 } 481 482 const Declaration & 483 Type::GetDeclaration () const 484 { 485 return m_decl; 486 } 487 488 bool 489 Type::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 } 630 uint32_t 631 Type::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 641 ClangASTType 642 Type::GetClangFullType () 643 { 644 ResolveClangType(eResolveStateFull); 645 return m_clang_type; 646 } 647 648 ClangASTType 649 Type::GetClangLayoutType () 650 { 651 ResolveClangType(eResolveStateLayout); 652 return m_clang_type; 653 } 654 655 ClangASTType 656 Type::GetClangForwardType () 657 { 658 ResolveClangType (eResolveStateForward); 659 return m_clang_type; 660 } 661 662 ClangASTContext & 663 Type::GetClangASTContext () 664 { 665 return m_symbol_file->GetClangASTContext(); 666 } 667 668 int 669 Type::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 686 void * 687 Type::CreateClangPointerType (Type *type) 688 { 689 assert(type); 690 return GetClangASTContext().CreatePointerType(type->GetClangForwardType()); 691 } 692 693 void * 694 Type::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 702 void * 703 Type::CreateClangLValueReferenceType (Type *type) 704 { 705 assert(type); 706 return GetClangASTContext().CreateLValueReferenceType(type->GetClangForwardType()); 707 } 708 709 void * 710 Type::CreateClangRValueReferenceType (Type *type) 711 { 712 assert(type); 713 return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType()); 714 } 715 #endif // END REMOVE 716 717 bool 718 Type::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 730 ConstString 731 Type::GetQualifiedName () 732 { 733 return GetClangForwardType().GetConstTypeName(); 734 } 735 736 737 bool 738 Type::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 801 TypeAndOrName::TypeAndOrName () : m_type_sp(), m_type_name() 802 { 803 804 } 805 806 TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_sp(in_type_sp) 807 { 808 if (in_type_sp) 809 m_type_name = in_type_sp->GetName(); 810 } 811 812 TypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str) 813 { 814 } 815 816 TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_sp (rhs.m_type_sp), m_type_name (rhs.m_type_name) 817 { 818 819 } 820 821 TypeAndOrName::TypeAndOrName (ConstString &in_type_const_string) : m_type_name (in_type_const_string) 822 { 823 } 824 825 TypeAndOrName & 826 TypeAndOrName::operator= (const TypeAndOrName &rhs) 827 { 828 if (this != &rhs) 829 { 830 m_type_name = rhs.m_type_name; 831 m_type_sp = rhs.m_type_sp; 832 } 833 return *this; 834 } 835 836 bool 837 TypeAndOrName::operator==(const TypeAndOrName &other) const 838 { 839 if (m_type_sp != other.m_type_sp) 840 return false; 841 if (m_type_name != other.m_type_name) 842 return false; 843 return true; 844 } 845 846 bool 847 TypeAndOrName::operator!=(const TypeAndOrName &other) const 848 { 849 if (m_type_sp != other.m_type_sp) 850 return true; 851 if (m_type_name != other.m_type_name) 852 return true; 853 return false; 854 } 855 856 ConstString 857 TypeAndOrName::GetName () const 858 { 859 if (m_type_sp) 860 return m_type_sp->GetName(); 861 else 862 return m_type_name; 863 } 864 865 void 866 TypeAndOrName::SetName (const ConstString &type_name) 867 { 868 m_type_name = type_name; 869 } 870 871 void 872 TypeAndOrName::SetName (const char *type_name_cstr) 873 { 874 m_type_name.SetCString (type_name_cstr); 875 } 876 877 void 878 TypeAndOrName::SetTypeSP (lldb::TypeSP type_sp) 879 { 880 m_type_sp = type_sp; 881 if (type_sp) 882 m_type_name = type_sp->GetName(); 883 } 884 885 bool 886 TypeAndOrName::IsEmpty() 887 { 888 if (m_type_name || m_type_sp) 889 return false; 890 else 891 return true; 892 } 893 894 void 895 TypeAndOrName::Clear () 896 { 897 m_type_name.Clear(); 898 m_type_sp.reset(); 899 } 900 901 bool 902 TypeAndOrName::HasName () 903 { 904 return (bool)m_type_name; 905 } 906 907 bool 908 TypeAndOrName::HasTypeSP () 909 { 910 return m_type_sp.get() != NULL; 911 } 912 913 TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) : 914 m_clang_ast_type(clang_ast_type), 915 m_type_sp() 916 { 917 } 918 919 TypeImpl::TypeImpl(const lldb::TypeSP& type) : 920 m_clang_ast_type(type->GetClangForwardType()), 921 m_type_sp(type) 922 { 923 } 924 925 void 926 TypeImpl::SetType (const lldb::TypeSP &type_sp) 927 { 928 if (type_sp) 929 { 930 m_clang_ast_type = type_sp->GetClangForwardType(); 931 m_type_sp = type_sp; 932 } 933 else 934 { 935 m_clang_ast_type.Clear(); 936 m_type_sp.reset(); 937 } 938 } 939 940 TypeImpl& 941 TypeImpl::operator = (const TypeImpl& rhs) 942 { 943 if (*this != rhs) 944 { 945 m_clang_ast_type = rhs.m_clang_ast_type; 946 m_type_sp = rhs.m_type_sp; 947 } 948 return *this; 949 } 950 951 clang::ASTContext* 952 TypeImpl::GetASTContext() 953 { 954 if (!IsValid()) 955 return NULL; 956 957 return m_clang_ast_type.GetASTContext(); 958 } 959 960 lldb::clang_type_t 961 TypeImpl::GetOpaqueQualType() 962 { 963 if (!IsValid()) 964 return NULL; 965 966 return m_clang_ast_type.GetOpaqueQualType(); 967 } 968 969 bool 970 TypeImpl::GetDescription (lldb_private::Stream &strm, 971 lldb::DescriptionLevel description_level) 972 { 973 if (m_clang_ast_type.IsValid()) 974 { 975 m_clang_ast_type.DumpTypeDescription (&strm); 976 } 977 else 978 { 979 strm.PutCString ("No value"); 980 } 981 return true; 982 } 983 984 ConstString 985 TypeImpl::GetName () 986 { 987 if (m_clang_ast_type.IsValid()) 988 return m_clang_ast_type.GetConstTypeName(); 989 return ConstString(); 990 } 991