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