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 uint64_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 = %" PRIu64, 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 = %" PRIu64, 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 uint64_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 (uint64_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 uint64_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 if (addr == 0) 443 return false; 444 memcpy (dst, (uint8_t*)NULL + addr, byte_size); 445 return true; 446 } 447 else 448 { 449 if (exe_ctx) 450 { 451 Process *process = exe_ctx->GetProcessPtr(); 452 if (process) 453 { 454 Error error; 455 return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size, error) == byte_size; 456 } 457 } 458 } 459 } 460 return false; 461 } 462 463 464 bool 465 Type::WriteToMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data) 466 { 467 return false; 468 } 469 470 471 TypeList* 472 Type::GetTypeList() 473 { 474 return GetSymbolFile()->GetTypeList(); 475 } 476 477 const Declaration & 478 Type::GetDeclaration () const 479 { 480 return m_decl; 481 } 482 483 bool 484 Type::ResolveClangType (ResolveState clang_type_resolve_state) 485 { 486 Type *encoding_type = NULL; 487 if (m_clang_type == NULL) 488 { 489 encoding_type = GetEncodingType(); 490 if (encoding_type) 491 { 492 switch (m_encoding_uid_type) 493 { 494 case eEncodingIsUID: 495 if (encoding_type->ResolveClangType(clang_type_resolve_state)) 496 { 497 m_clang_type = encoding_type->m_clang_type; 498 m_flags.clang_type_resolve_state = encoding_type->m_flags.clang_type_resolve_state; 499 } 500 break; 501 502 case eEncodingIsConstUID: 503 m_clang_type = ClangASTContext::AddConstModifier (encoding_type->GetClangForwardType()); 504 break; 505 506 case eEncodingIsRestrictUID: 507 m_clang_type = ClangASTContext::AddRestrictModifier (encoding_type->GetClangForwardType()); 508 break; 509 510 case eEncodingIsVolatileUID: 511 m_clang_type = ClangASTContext::AddVolatileModifier (encoding_type->GetClangForwardType()); 512 break; 513 514 case eEncodingIsTypedefUID: 515 m_clang_type = CreateClangTypedefType (this, encoding_type); 516 // Clear the name so it can get fully qualified in case the 517 // typedef is in a namespace. 518 m_name.Clear(); 519 break; 520 521 case eEncodingIsPointerUID: 522 m_clang_type = CreateClangPointerType (encoding_type); 523 break; 524 525 case eEncodingIsLValueReferenceUID: 526 m_clang_type = CreateClangLValueReferenceType (encoding_type); 527 break; 528 529 case eEncodingIsRValueReferenceUID: 530 m_clang_type = CreateClangRValueReferenceType (encoding_type); 531 break; 532 533 default: 534 assert(!"Unhandled encoding_data_type."); 535 break; 536 } 537 } 538 else 539 { 540 // We have no encoding type, return void? 541 clang_type_t void_clang_type = GetClangASTContext().GetBuiltInType_void(); 542 switch (m_encoding_uid_type) 543 { 544 case eEncodingIsUID: 545 m_clang_type = void_clang_type; 546 break; 547 548 case eEncodingIsConstUID: 549 m_clang_type = ClangASTContext::AddConstModifier (void_clang_type); 550 break; 551 552 case eEncodingIsRestrictUID: 553 m_clang_type = ClangASTContext::AddRestrictModifier (void_clang_type); 554 break; 555 556 case eEncodingIsVolatileUID: 557 m_clang_type = ClangASTContext::AddVolatileModifier (void_clang_type); 558 break; 559 560 case eEncodingIsTypedefUID: 561 m_clang_type = GetClangASTContext().CreateTypedefType (m_name.AsCString(), void_clang_type, NULL); 562 break; 563 564 case eEncodingIsPointerUID: 565 m_clang_type = GetClangASTContext().CreatePointerType (void_clang_type); 566 break; 567 568 case eEncodingIsLValueReferenceUID: 569 m_clang_type = GetClangASTContext().CreateLValueReferenceType (void_clang_type); 570 break; 571 572 case eEncodingIsRValueReferenceUID: 573 m_clang_type = GetClangASTContext().CreateRValueReferenceType (void_clang_type); 574 break; 575 576 default: 577 assert(!"Unhandled encoding_data_type."); 578 break; 579 } 580 } 581 } 582 583 // Check if we have a forward reference to a class/struct/union/enum? 584 if (m_clang_type && m_flags.clang_type_resolve_state < clang_type_resolve_state) 585 { 586 m_flags.clang_type_resolve_state = eResolveStateFull; 587 if (!ClangASTType::IsDefined (m_clang_type)) 588 { 589 // We have a forward declaration, we need to resolve it to a complete 590 // definition. 591 m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type); 592 } 593 } 594 595 // If we have an encoding type, then we need to make sure it is 596 // resolved appropriately. 597 if (m_encoding_uid != LLDB_INVALID_UID) 598 { 599 if (encoding_type == NULL) 600 encoding_type = GetEncodingType(); 601 if (encoding_type) 602 { 603 ResolveState encoding_clang_type_resolve_state = clang_type_resolve_state; 604 605 if (clang_type_resolve_state == eResolveStateLayout) 606 { 607 switch (m_encoding_uid_type) 608 { 609 case eEncodingIsPointerUID: 610 case eEncodingIsLValueReferenceUID: 611 case eEncodingIsRValueReferenceUID: 612 encoding_clang_type_resolve_state = eResolveStateForward; 613 break; 614 default: 615 break; 616 } 617 } 618 encoding_type->ResolveClangType (encoding_clang_type_resolve_state); 619 } 620 } 621 return m_clang_type != NULL; 622 } 623 uint32_t 624 Type::GetEncodingMask () 625 { 626 uint32_t encoding_mask = 1u << m_encoding_uid_type; 627 Type *encoding_type = GetEncodingType(); 628 assert (encoding_type != this); 629 if (encoding_type) 630 encoding_mask |= encoding_type->GetEncodingMask (); 631 return encoding_mask; 632 } 633 634 clang_type_t 635 Type::GetClangFullType () 636 { 637 ResolveClangType(eResolveStateFull); 638 return m_clang_type; 639 } 640 641 clang_type_t 642 Type::GetClangLayoutType () 643 { 644 ResolveClangType(eResolveStateLayout); 645 return m_clang_type; 646 } 647 648 clang_type_t 649 Type::GetClangForwardType () 650 { 651 ResolveClangType (eResolveStateForward); 652 return m_clang_type; 653 } 654 655 clang::ASTContext * 656 Type::GetClangAST () 657 { 658 return GetClangASTContext().getASTContext(); 659 } 660 661 ClangASTContext & 662 Type::GetClangASTContext () 663 { 664 return m_symbol_file->GetClangASTContext(); 665 } 666 667 int 668 Type::Compare(const Type &a, const Type &b) 669 { 670 // Just compare the UID values for now... 671 lldb::user_id_t a_uid = a.GetID(); 672 lldb::user_id_t b_uid = b.GetID(); 673 if (a_uid < b_uid) 674 return -1; 675 if (a_uid > b_uid) 676 return 1; 677 return 0; 678 // if (a.getQualType() == b.getQualType()) 679 // return 0; 680 } 681 682 683 void * 684 Type::CreateClangPointerType (Type *type) 685 { 686 assert(type); 687 return GetClangASTContext().CreatePointerType(type->GetClangForwardType()); 688 } 689 690 void * 691 Type::CreateClangTypedefType (Type *typedef_type, Type *base_type) 692 { 693 assert(typedef_type && base_type); 694 return GetClangASTContext().CreateTypedefType (typedef_type->GetName().AsCString(), 695 base_type->GetClangForwardType(), 696 typedef_type->GetSymbolFile()->GetClangDeclContextContainingTypeUID(typedef_type->GetID())); 697 } 698 699 void * 700 Type::CreateClangLValueReferenceType (Type *type) 701 { 702 assert(type); 703 return GetClangASTContext().CreateLValueReferenceType(type->GetClangForwardType()); 704 } 705 706 void * 707 Type::CreateClangRValueReferenceType (Type *type) 708 { 709 assert(type); 710 return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType()); 711 } 712 713 bool 714 Type::IsRealObjCClass() 715 { 716 // For now we are just skipping ObjC classes that get made by hand from the runtime, because 717 // those don't have any information. We could extend this to only return true for "full 718 // definitions" if we can figure that out. 719 720 if (ClangASTContext::IsObjCClassType(m_clang_type) && GetByteSize() != 0) 721 return true; 722 else 723 return false; 724 } 725 726 ConstString 727 Type::GetQualifiedName () 728 { 729 ConstString qualified_name (ClangASTType::GetTypeNameForOpaqueQualType (GetClangASTContext ().getASTContext(), GetClangForwardType()).c_str()); 730 return qualified_name; 731 } 732 733 734 bool 735 Type::GetTypeScopeAndBasename (const char* &name_cstr, 736 std::string &scope, 737 std::string &basename, 738 TypeClass &type_class) 739 { 740 // Protect against null c string. 741 742 type_class = eTypeClassAny; 743 744 if (name_cstr && name_cstr[0]) 745 { 746 llvm::StringRef name_strref(name_cstr); 747 if (name_strref.startswith("struct ")) 748 { 749 name_cstr += 7; 750 type_class = eTypeClassStruct; 751 } 752 else if (name_strref.startswith("class ")) 753 { 754 name_cstr += 6; 755 type_class = eTypeClassClass; 756 } 757 else if (name_strref.startswith("union ")) 758 { 759 name_cstr += 6; 760 type_class = eTypeClassUnion; 761 } 762 else if (name_strref.startswith("enum ")) 763 { 764 name_cstr += 5; 765 type_class = eTypeClassEnumeration; 766 } 767 else if (name_strref.startswith("typedef ")) 768 { 769 name_cstr += 8; 770 type_class = eTypeClassTypedef; 771 } 772 const char *basename_cstr = name_cstr; 773 const char* namespace_separator = ::strstr (basename_cstr, "::"); 774 if (namespace_separator) 775 { 776 const char* template_arg_char = ::strchr (basename_cstr, '<'); 777 while (namespace_separator != NULL) 778 { 779 if (template_arg_char && namespace_separator > template_arg_char) // but namespace'd template arguments are still good to go 780 break; 781 basename_cstr = namespace_separator + 2; 782 namespace_separator = strstr(basename_cstr, "::"); 783 } 784 if (basename_cstr > name_cstr) 785 { 786 scope.assign (name_cstr, basename_cstr - name_cstr); 787 basename.assign (basename_cstr); 788 return true; 789 } 790 } 791 } 792 return false; 793 } 794 795 796 797 798 TypeAndOrName::TypeAndOrName () : m_type_sp(), m_type_name() 799 { 800 801 } 802 803 TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_sp(in_type_sp) 804 { 805 if (in_type_sp) 806 m_type_name = in_type_sp->GetName(); 807 } 808 809 TypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str) 810 { 811 } 812 813 TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_sp (rhs.m_type_sp), m_type_name (rhs.m_type_name) 814 { 815 816 } 817 818 TypeAndOrName::TypeAndOrName (ConstString &in_type_const_string) : m_type_name (in_type_const_string) 819 { 820 } 821 822 TypeAndOrName & 823 TypeAndOrName::operator= (const TypeAndOrName &rhs) 824 { 825 if (this != &rhs) 826 { 827 m_type_name = rhs.m_type_name; 828 m_type_sp = rhs.m_type_sp; 829 } 830 return *this; 831 } 832 833 bool 834 TypeAndOrName::operator==(const TypeAndOrName &other) const 835 { 836 if (m_type_sp != other.m_type_sp) 837 return false; 838 if (m_type_name != other.m_type_name) 839 return false; 840 return true; 841 } 842 843 bool 844 TypeAndOrName::operator!=(const TypeAndOrName &other) const 845 { 846 if (m_type_sp != other.m_type_sp) 847 return true; 848 if (m_type_name != other.m_type_name) 849 return true; 850 return false; 851 } 852 853 ConstString 854 TypeAndOrName::GetName () const 855 { 856 if (m_type_sp) 857 return m_type_sp->GetName(); 858 else 859 return m_type_name; 860 } 861 862 void 863 TypeAndOrName::SetName (const ConstString &type_name) 864 { 865 m_type_name = type_name; 866 } 867 868 void 869 TypeAndOrName::SetName (const char *type_name_cstr) 870 { 871 m_type_name.SetCString (type_name_cstr); 872 } 873 874 void 875 TypeAndOrName::SetTypeSP (lldb::TypeSP type_sp) 876 { 877 m_type_sp = type_sp; 878 if (type_sp) 879 m_type_name = type_sp->GetName(); 880 } 881 882 bool 883 TypeAndOrName::IsEmpty() 884 { 885 if (m_type_name || m_type_sp) 886 return false; 887 else 888 return true; 889 } 890 891 void 892 TypeAndOrName::Clear () 893 { 894 m_type_name.Clear(); 895 m_type_sp.reset(); 896 } 897 898 bool 899 TypeAndOrName::HasName () 900 { 901 return (bool)m_type_name; 902 } 903 904 bool 905 TypeAndOrName::HasTypeSP () 906 { 907 return m_type_sp.get() != NULL; 908 } 909 910 TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) : 911 m_clang_ast_type(clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType()), 912 m_type_sp() 913 {} 914 915 TypeImpl::TypeImpl(const lldb::TypeSP& type) : 916 m_clang_ast_type(type->GetClangAST(), type->GetClangFullType()), 917 m_type_sp(type) 918 { 919 } 920 921 void 922 TypeImpl::SetType (const lldb::TypeSP &type_sp) 923 { 924 if (type_sp) 925 { 926 m_clang_ast_type.SetClangType (type_sp->GetClangAST(), type_sp->GetClangFullType()); 927 m_type_sp = type_sp; 928 } 929 else 930 { 931 m_clang_ast_type.Clear(); 932 m_type_sp.reset(); 933 } 934 } 935 936 TypeImpl& 937 TypeImpl::operator = (const TypeImpl& rhs) 938 { 939 if (*this != rhs) 940 { 941 m_clang_ast_type = rhs.m_clang_ast_type; 942 m_type_sp = rhs.m_type_sp; 943 } 944 return *this; 945 } 946 947 clang::ASTContext* 948 TypeImpl::GetASTContext() 949 { 950 if (!IsValid()) 951 return NULL; 952 953 return m_clang_ast_type.GetASTContext(); 954 } 955 956 lldb::clang_type_t 957 TypeImpl::GetOpaqueQualType() 958 { 959 if (!IsValid()) 960 return NULL; 961 962 return m_clang_ast_type.GetOpaqueQualType(); 963 } 964 965 bool 966 TypeImpl::GetDescription (lldb_private::Stream &strm, 967 lldb::DescriptionLevel description_level) 968 { 969 if (m_clang_ast_type.IsValid()) 970 { 971 ClangASTType::DumpTypeDescription (m_clang_ast_type.GetASTContext(), 972 m_clang_ast_type.GetOpaqueQualType(), 973 &strm); 974 } 975 else 976 { 977 strm.PutCString ("No value"); 978 } 979 return true; 980 } 981 982