1 //===-- SBType.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 #include "lldb/API/SBDefines.h" 11 #include "lldb/API/SBType.h" 12 #include "lldb/API/SBTypeEnumMember.h" 13 #include "lldb/API/SBStream.h" 14 #include "lldb/Core/ConstString.h" 15 #include "lldb/Core/Log.h" 16 #include "lldb/Core/Stream.h" 17 #include "lldb/Symbol/ClangASTContext.h" 18 #include "lldb/Symbol/CompilerType.h" 19 #include "lldb/Symbol/Type.h" 20 21 #include "clang/AST/Decl.h" 22 23 using namespace lldb; 24 using namespace lldb_private; 25 using namespace clang; 26 27 SBType::SBType() : 28 m_opaque_sp() 29 { 30 } 31 32 SBType::SBType (const CompilerType &type) : 33 m_opaque_sp(new TypeImpl(CompilerType(type.GetTypeSystem(), 34 type.GetOpaqueQualType()))) 35 { 36 } 37 38 SBType::SBType (const lldb::TypeSP &type_sp) : 39 m_opaque_sp(new TypeImpl(type_sp)) 40 { 41 } 42 43 SBType::SBType (const lldb::TypeImplSP &type_impl_sp) : 44 m_opaque_sp(type_impl_sp) 45 { 46 } 47 48 49 SBType::SBType (const SBType &rhs) : 50 m_opaque_sp() 51 { 52 if (this != &rhs) 53 { 54 m_opaque_sp = rhs.m_opaque_sp; 55 } 56 } 57 58 59 //SBType::SBType (TypeImpl* impl) : 60 // m_opaque_ap(impl) 61 //{} 62 // 63 bool 64 SBType::operator == (SBType &rhs) 65 { 66 if (IsValid() == false) 67 return !rhs.IsValid(); 68 69 if (rhs.IsValid() == false) 70 return false; 71 72 return *m_opaque_sp.get() == *rhs.m_opaque_sp.get(); 73 } 74 75 bool 76 SBType::operator != (SBType &rhs) 77 { 78 if (IsValid() == false) 79 return rhs.IsValid(); 80 81 if (rhs.IsValid() == false) 82 return true; 83 84 return *m_opaque_sp.get() != *rhs.m_opaque_sp.get(); 85 } 86 87 lldb::TypeImplSP 88 SBType::GetSP () 89 { 90 return m_opaque_sp; 91 } 92 93 94 void 95 SBType::SetSP (const lldb::TypeImplSP &type_impl_sp) 96 { 97 m_opaque_sp = type_impl_sp; 98 } 99 100 SBType & 101 SBType::operator = (const SBType &rhs) 102 { 103 if (this != &rhs) 104 { 105 m_opaque_sp = rhs.m_opaque_sp; 106 } 107 return *this; 108 } 109 110 SBType::~SBType () 111 {} 112 113 TypeImpl & 114 SBType::ref () 115 { 116 if (m_opaque_sp.get() == NULL) 117 m_opaque_sp.reset (new TypeImpl()); 118 return *m_opaque_sp; 119 } 120 121 const TypeImpl & 122 SBType::ref () const 123 { 124 // "const SBAddress &addr" should already have checked "addr.IsValid()" 125 // prior to calling this function. In case you didn't we will assert 126 // and die to let you know. 127 assert (m_opaque_sp.get()); 128 return *m_opaque_sp; 129 } 130 131 bool 132 SBType::IsValid() const 133 { 134 if (m_opaque_sp.get() == NULL) 135 return false; 136 137 return m_opaque_sp->IsValid(); 138 } 139 140 uint64_t 141 SBType::GetByteSize() 142 { 143 if (!IsValid()) 144 return 0; 145 146 return m_opaque_sp->GetCompilerType(false).GetByteSize(nullptr); 147 148 } 149 150 bool 151 SBType::IsPointerType() 152 { 153 if (!IsValid()) 154 return false; 155 return m_opaque_sp->GetCompilerType(true).IsPointerType(); 156 } 157 158 bool 159 SBType::IsArrayType() 160 { 161 if (!IsValid()) 162 return false; 163 return m_opaque_sp->GetCompilerType(true).IsArrayType(nullptr, nullptr, nullptr); 164 } 165 166 bool 167 SBType::IsVectorType() 168 { 169 if (!IsValid()) 170 return false; 171 return m_opaque_sp->GetCompilerType(true).IsVectorType(nullptr, nullptr); 172 } 173 174 bool 175 SBType::IsReferenceType() 176 { 177 if (!IsValid()) 178 return false; 179 return m_opaque_sp->GetCompilerType(true).IsReferenceType(); 180 } 181 182 SBType 183 SBType::GetPointerType() 184 { 185 if (!IsValid()) 186 return SBType(); 187 188 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointerType()))); 189 } 190 191 SBType 192 SBType::GetPointeeType() 193 { 194 if (!IsValid()) 195 return SBType(); 196 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointeeType()))); 197 } 198 199 SBType 200 SBType::GetReferenceType() 201 { 202 if (!IsValid()) 203 return SBType(); 204 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetReferenceType()))); 205 } 206 207 SBType 208 SBType::GetTypedefedType() 209 { 210 if (!IsValid()) 211 return SBType(); 212 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetTypedefedType()))); 213 } 214 215 SBType 216 SBType::GetDereferencedType() 217 { 218 if (!IsValid()) 219 return SBType(); 220 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetDereferencedType()))); 221 } 222 223 SBType 224 SBType::GetArrayElementType() 225 { 226 if (!IsValid()) 227 return SBType(); 228 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetCompilerType(true).GetArrayElementType()))); 229 } 230 231 SBType 232 SBType::GetVectorElementType () 233 { 234 SBType type_sb; 235 if (IsValid()) 236 { 237 CompilerType vector_element_type; 238 if (m_opaque_sp->GetCompilerType(true).IsVectorType(&vector_element_type, nullptr)) 239 type_sb.SetSP(TypeImplSP(new TypeImpl(vector_element_type))); 240 } 241 return type_sb; 242 } 243 244 bool 245 SBType::IsFunctionType () 246 { 247 if (!IsValid()) 248 return false; 249 return m_opaque_sp->GetCompilerType(true).IsFunctionType(); 250 } 251 252 bool 253 SBType::IsPolymorphicClass () 254 { 255 if (!IsValid()) 256 return false; 257 return m_opaque_sp->GetCompilerType(true).IsPolymorphicClass(); 258 } 259 260 bool 261 SBType::IsTypedefType () 262 { 263 if (!IsValid()) 264 return false; 265 return m_opaque_sp->GetCompilerType(true).IsTypedefType(); 266 } 267 268 lldb::SBType 269 SBType::GetFunctionReturnType () 270 { 271 if (IsValid()) 272 { 273 CompilerType return_clang_type (m_opaque_sp->GetCompilerType(true).GetFunctionReturnType()); 274 if (return_clang_type.IsValid()) 275 return SBType(return_clang_type); 276 } 277 return lldb::SBType(); 278 } 279 280 lldb::SBTypeList 281 SBType::GetFunctionArgumentTypes () 282 { 283 SBTypeList sb_type_list; 284 if (IsValid()) 285 { 286 CompilerType func_type(m_opaque_sp->GetCompilerType(true)); 287 size_t count = func_type.GetNumberOfFunctionArguments(); 288 for (size_t i = 0; 289 i < count; 290 i++) 291 { 292 sb_type_list.Append(SBType(func_type.GetFunctionArgumentAtIndex(i))); 293 } 294 } 295 return sb_type_list; 296 } 297 298 uint32_t 299 SBType::GetNumberOfMemberFunctions () 300 { 301 if (IsValid()) 302 { 303 return m_opaque_sp->GetCompilerType(true).GetNumMemberFunctions(); 304 } 305 return 0; 306 } 307 308 lldb::SBTypeMemberFunction 309 SBType::GetMemberFunctionAtIndex (uint32_t idx) 310 { 311 SBTypeMemberFunction sb_func_type; 312 if (IsValid()) 313 sb_func_type.reset(new TypeMemberFunctionImpl(m_opaque_sp->GetCompilerType(true).GetMemberFunctionAtIndex(idx))); 314 return sb_func_type; 315 } 316 317 lldb::SBType 318 SBType::GetUnqualifiedType() 319 { 320 if (!IsValid()) 321 return SBType(); 322 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetUnqualifiedType()))); 323 } 324 325 lldb::SBType 326 SBType::GetCanonicalType() 327 { 328 if (IsValid()) 329 return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetCanonicalType()))); 330 return SBType(); 331 } 332 333 334 lldb::BasicType 335 SBType::GetBasicType() 336 { 337 if (IsValid()) 338 return m_opaque_sp->GetCompilerType(false).GetBasicTypeEnumeration (); 339 return eBasicTypeInvalid; 340 } 341 342 SBType 343 SBType::GetBasicType(lldb::BasicType basic_type) 344 { 345 if (IsValid() && m_opaque_sp->IsValid()) 346 { 347 ClangASTContext* ast = m_opaque_sp->GetTypeSystem(false)->AsClangASTContext(); 348 if (ast) 349 return SBType (ClangASTContext::GetBasicType (ast->getASTContext(), basic_type)); 350 } 351 352 return SBType(); 353 } 354 355 uint32_t 356 SBType::GetNumberOfDirectBaseClasses () 357 { 358 if (IsValid()) 359 return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetCompilerType(true)); 360 return 0; 361 } 362 363 uint32_t 364 SBType::GetNumberOfVirtualBaseClasses () 365 { 366 if (IsValid()) 367 return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetCompilerType(true)); 368 return 0; 369 } 370 371 uint32_t 372 SBType::GetNumberOfFields () 373 { 374 if (IsValid()) 375 return m_opaque_sp->GetCompilerType(true).GetNumFields(); 376 return 0; 377 } 378 379 bool 380 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) 381 { 382 Stream &strm = description.ref(); 383 384 if (m_opaque_sp) 385 { 386 m_opaque_sp->GetDescription (strm, description_level); 387 } 388 else 389 strm.PutCString ("No value"); 390 391 return true; 392 } 393 394 395 396 SBTypeMember 397 SBType::GetDirectBaseClassAtIndex (uint32_t idx) 398 { 399 SBTypeMember sb_type_member; 400 if (IsValid()) 401 { 402 CompilerType this_type (m_opaque_sp->GetCompilerType (true)); 403 if (this_type.IsValid()) 404 { 405 uint32_t bit_offset = 0; 406 CompilerType base_class_type (ClangASTContext::GetDirectBaseClassAtIndex(this_type, idx, &bit_offset)); 407 if (base_class_type.IsValid()) 408 { 409 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); 410 } 411 } 412 } 413 return sb_type_member; 414 415 } 416 417 SBTypeMember 418 SBType::GetVirtualBaseClassAtIndex (uint32_t idx) 419 { 420 SBTypeMember sb_type_member; 421 if (IsValid()) 422 { 423 CompilerType this_type (m_opaque_sp->GetCompilerType (true)); 424 if (this_type.IsValid()) 425 { 426 uint32_t bit_offset = 0; 427 CompilerType base_class_type (ClangASTContext::GetVirtualBaseClassAtIndex(this_type, idx, &bit_offset)); 428 if (base_class_type.IsValid()) 429 { 430 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); 431 } 432 } 433 } 434 return sb_type_member; 435 } 436 437 SBTypeEnumMemberList 438 SBType::GetEnumMembers () 439 { 440 SBTypeEnumMemberList sb_enum_member_list; 441 if (IsValid()) 442 { 443 const clang::EnumDecl *enum_decl = ClangASTContext::GetAsEnumDecl(m_opaque_sp->GetCompilerType(true).GetFullyUnqualifiedType()); 444 if (enum_decl) 445 { 446 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos; 447 for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos) 448 { 449 SBTypeEnumMember enum_member; 450 enum_member.reset(new TypeEnumMemberImpl(*enum_pos, CompilerType(m_opaque_sp->GetTypeSystem(true), enum_decl->getIntegerType().getAsOpaquePtr()))); 451 sb_enum_member_list.Append(enum_member); 452 } 453 } 454 } 455 return sb_enum_member_list; 456 } 457 458 SBTypeMember 459 SBType::GetFieldAtIndex (uint32_t idx) 460 { 461 SBTypeMember sb_type_member; 462 if (IsValid()) 463 { 464 CompilerType this_type (m_opaque_sp->GetCompilerType (false)); 465 if (this_type.IsValid()) 466 { 467 uint64_t bit_offset = 0; 468 uint32_t bitfield_bit_size = 0; 469 bool is_bitfield = false; 470 std::string name_sstr; 471 CompilerType field_type (this_type.GetFieldAtIndex (idx, 472 name_sstr, 473 &bit_offset, 474 &bitfield_bit_size, 475 &is_bitfield)); 476 if (field_type.IsValid()) 477 { 478 ConstString name; 479 if (!name_sstr.empty()) 480 name.SetCString(name_sstr.c_str()); 481 sb_type_member.reset (new TypeMemberImpl (TypeImplSP (new TypeImpl(field_type)), 482 bit_offset, 483 name, 484 bitfield_bit_size, 485 is_bitfield)); 486 } 487 } 488 } 489 return sb_type_member; 490 } 491 492 bool 493 SBType::IsTypeComplete() 494 { 495 if (!IsValid()) 496 return false; 497 return m_opaque_sp->GetCompilerType(false).IsCompleteType(); 498 } 499 500 uint32_t 501 SBType::GetTypeFlags () 502 { 503 if (!IsValid()) 504 return 0; 505 return m_opaque_sp->GetCompilerType(true).GetTypeInfo(); 506 } 507 508 const char* 509 SBType::GetName() 510 { 511 if (!IsValid()) 512 return ""; 513 return m_opaque_sp->GetName().GetCString(); 514 } 515 516 const char * 517 SBType::GetDisplayTypeName () 518 { 519 if (!IsValid()) 520 return ""; 521 return m_opaque_sp->GetDisplayTypeName().GetCString(); 522 } 523 524 lldb::TypeClass 525 SBType::GetTypeClass () 526 { 527 if (IsValid()) 528 return m_opaque_sp->GetCompilerType(true).GetTypeClass(); 529 return lldb::eTypeClassInvalid; 530 } 531 532 uint32_t 533 SBType::GetNumberOfTemplateArguments () 534 { 535 if (IsValid()) 536 return m_opaque_sp->GetCompilerType(false).GetNumTemplateArguments(); 537 return 0; 538 } 539 540 lldb::SBType 541 SBType::GetTemplateArgumentType (uint32_t idx) 542 { 543 if (IsValid()) 544 { 545 TemplateArgumentKind kind = eTemplateArgumentKindNull; 546 CompilerType template_arg_type = m_opaque_sp->GetCompilerType(false).GetTemplateArgument(idx, kind); 547 if (template_arg_type.IsValid()) 548 return SBType(template_arg_type); 549 } 550 return SBType(); 551 } 552 553 554 lldb::TemplateArgumentKind 555 SBType::GetTemplateArgumentKind (uint32_t idx) 556 { 557 TemplateArgumentKind kind = eTemplateArgumentKindNull; 558 if (IsValid()) 559 m_opaque_sp->GetCompilerType(false).GetTemplateArgument(idx, kind); 560 return kind; 561 } 562 563 564 SBTypeList::SBTypeList() : 565 m_opaque_ap(new TypeListImpl()) 566 { 567 } 568 569 SBTypeList::SBTypeList(const SBTypeList& rhs) : 570 m_opaque_ap(new TypeListImpl()) 571 { 572 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 573 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 574 } 575 576 bool 577 SBTypeList::IsValid () 578 { 579 return (m_opaque_ap.get() != NULL); 580 } 581 582 SBTypeList& 583 SBTypeList::operator = (const SBTypeList& rhs) 584 { 585 if (this != &rhs) 586 { 587 m_opaque_ap.reset (new TypeListImpl()); 588 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 589 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 590 } 591 return *this; 592 } 593 594 void 595 SBTypeList::Append (SBType type) 596 { 597 if (type.IsValid()) 598 m_opaque_ap->Append (type.m_opaque_sp); 599 } 600 601 SBType 602 SBTypeList::GetTypeAtIndex(uint32_t index) 603 { 604 if (m_opaque_ap.get()) 605 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 606 return SBType(); 607 } 608 609 uint32_t 610 SBTypeList::GetSize() 611 { 612 return m_opaque_ap->GetSize(); 613 } 614 615 SBTypeList::~SBTypeList() 616 { 617 } 618 619 SBTypeMember::SBTypeMember() : 620 m_opaque_ap() 621 { 622 } 623 624 SBTypeMember::~SBTypeMember() 625 { 626 } 627 628 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) : 629 m_opaque_ap() 630 { 631 if (this != &rhs) 632 { 633 if (rhs.IsValid()) 634 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 635 } 636 } 637 638 lldb::SBTypeMember& 639 SBTypeMember::operator = (const lldb::SBTypeMember& rhs) 640 { 641 if (this != &rhs) 642 { 643 if (rhs.IsValid()) 644 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 645 } 646 return *this; 647 } 648 649 bool 650 SBTypeMember::IsValid() const 651 { 652 return m_opaque_ap.get(); 653 } 654 655 const char * 656 SBTypeMember::GetName () 657 { 658 if (m_opaque_ap.get()) 659 return m_opaque_ap->GetName().GetCString(); 660 return NULL; 661 } 662 663 SBType 664 SBTypeMember::GetType () 665 { 666 SBType sb_type; 667 if (m_opaque_ap.get()) 668 { 669 sb_type.SetSP (m_opaque_ap->GetTypeImpl()); 670 } 671 return sb_type; 672 673 } 674 675 uint64_t 676 SBTypeMember::GetOffsetInBytes() 677 { 678 if (m_opaque_ap.get()) 679 return m_opaque_ap->GetBitOffset() / 8u; 680 return 0; 681 } 682 683 uint64_t 684 SBTypeMember::GetOffsetInBits() 685 { 686 if (m_opaque_ap.get()) 687 return m_opaque_ap->GetBitOffset(); 688 return 0; 689 } 690 691 bool 692 SBTypeMember::IsBitfield() 693 { 694 if (m_opaque_ap.get()) 695 return m_opaque_ap->GetIsBitfield(); 696 return false; 697 } 698 699 uint32_t 700 SBTypeMember::GetBitfieldSizeInBits() 701 { 702 if (m_opaque_ap.get()) 703 return m_opaque_ap->GetBitfieldBitSize(); 704 return 0; 705 } 706 707 708 bool 709 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) 710 { 711 Stream &strm = description.ref(); 712 713 if (m_opaque_ap.get()) 714 { 715 const uint32_t bit_offset = m_opaque_ap->GetBitOffset(); 716 const uint32_t byte_offset = bit_offset / 8u; 717 const uint32_t byte_bit_offset = bit_offset % 8u; 718 const char *name = m_opaque_ap->GetName().GetCString(); 719 if (byte_bit_offset) 720 strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset); 721 else 722 strm.Printf ("+%u: (", byte_offset); 723 724 TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl()); 725 if (type_impl_sp) 726 type_impl_sp->GetDescription(strm, description_level); 727 728 strm.Printf (") %s", name); 729 if (m_opaque_ap->GetIsBitfield()) 730 { 731 const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize(); 732 strm.Printf (" : %u", bitfield_bit_size); 733 } 734 } 735 else 736 { 737 strm.PutCString ("No value"); 738 } 739 return true; 740 } 741 742 743 void 744 SBTypeMember::reset(TypeMemberImpl *type_member_impl) 745 { 746 m_opaque_ap.reset(type_member_impl); 747 } 748 749 TypeMemberImpl & 750 SBTypeMember::ref () 751 { 752 if (m_opaque_ap.get() == NULL) 753 m_opaque_ap.reset (new TypeMemberImpl()); 754 return *m_opaque_ap.get(); 755 } 756 757 const TypeMemberImpl & 758 SBTypeMember::ref () const 759 { 760 return *m_opaque_ap.get(); 761 } 762 763 SBTypeMemberFunction::SBTypeMemberFunction() : 764 m_opaque_sp() 765 { 766 } 767 768 SBTypeMemberFunction::~SBTypeMemberFunction() 769 { 770 } 771 772 SBTypeMemberFunction::SBTypeMemberFunction (const SBTypeMemberFunction& rhs) : 773 m_opaque_sp(rhs.m_opaque_sp) 774 { 775 } 776 777 lldb::SBTypeMemberFunction& 778 SBTypeMemberFunction::operator = (const lldb::SBTypeMemberFunction& rhs) 779 { 780 if (this != &rhs) 781 m_opaque_sp = rhs.m_opaque_sp; 782 return *this; 783 } 784 785 bool 786 SBTypeMemberFunction::IsValid() const 787 { 788 return m_opaque_sp.get(); 789 } 790 791 const char * 792 SBTypeMemberFunction::GetName () 793 { 794 if (m_opaque_sp) 795 return m_opaque_sp->GetName().GetCString(); 796 return NULL; 797 } 798 799 SBType 800 SBTypeMemberFunction::GetType () 801 { 802 SBType sb_type; 803 if (m_opaque_sp) 804 { 805 sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType()))); 806 } 807 return sb_type; 808 } 809 810 lldb::SBType 811 SBTypeMemberFunction::GetReturnType () 812 { 813 SBType sb_type; 814 if (m_opaque_sp) 815 { 816 sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType()))); 817 } 818 return sb_type; 819 } 820 821 uint32_t 822 SBTypeMemberFunction::GetNumberOfArguments () 823 { 824 if (m_opaque_sp) 825 return m_opaque_sp->GetNumArguments(); 826 return 0; 827 } 828 829 lldb::SBType 830 SBTypeMemberFunction::GetArgumentTypeAtIndex (uint32_t i) 831 { 832 SBType sb_type; 833 if (m_opaque_sp) 834 { 835 sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i)))); 836 } 837 return sb_type; 838 } 839 840 lldb::MemberFunctionKind 841 SBTypeMemberFunction::GetKind () 842 { 843 if (m_opaque_sp) 844 return m_opaque_sp->GetKind(); 845 return lldb::eMemberFunctionKindUnknown; 846 847 } 848 849 bool 850 SBTypeMemberFunction::GetDescription (lldb::SBStream &description, 851 lldb::DescriptionLevel description_level) 852 { 853 Stream &strm = description.ref(); 854 855 if (m_opaque_sp) 856 return m_opaque_sp->GetDescription(strm); 857 858 return false; 859 } 860 861 void 862 SBTypeMemberFunction::reset(TypeMemberFunctionImpl *type_member_impl) 863 { 864 m_opaque_sp.reset(type_member_impl); 865 } 866 867 TypeMemberFunctionImpl & 868 SBTypeMemberFunction::ref () 869 { 870 if (!m_opaque_sp) 871 m_opaque_sp.reset (new TypeMemberFunctionImpl()); 872 return *m_opaque_sp.get(); 873 } 874 875 const TypeMemberFunctionImpl & 876 SBTypeMemberFunction::ref () const 877 { 878 return *m_opaque_sp.get(); 879 } 880