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