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