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/ClangASTType.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 ClangASTType &type) : 33 m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(), 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->GetClangASTType(false).GetByteSize(nullptr); 147 148 } 149 150 bool 151 SBType::IsPointerType() 152 { 153 if (!IsValid()) 154 return false; 155 return m_opaque_sp->GetClangASTType(true).IsPointerType(); 156 } 157 158 bool 159 SBType::IsArrayType() 160 { 161 if (!IsValid()) 162 return false; 163 return m_opaque_sp->GetClangASTType(true).IsArrayType(nullptr, nullptr, nullptr); 164 } 165 166 bool 167 SBType::IsVectorType() 168 { 169 if (!IsValid()) 170 return false; 171 return m_opaque_sp->GetClangASTType(true).IsVectorType(nullptr, nullptr); 172 } 173 174 bool 175 SBType::IsReferenceType() 176 { 177 if (!IsValid()) 178 return false; 179 return m_opaque_sp->GetClangASTType(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->GetClangASTType(true).GetArrayElementType()))); 229 } 230 231 SBType 232 SBType::GetVectorElementType () 233 { 234 SBType type_sb; 235 if (IsValid()) 236 { 237 ClangASTType vector_element_type; 238 if (m_opaque_sp->GetClangASTType(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->GetClangASTType(true).IsFunctionType(); 250 } 251 252 bool 253 SBType::IsPolymorphicClass () 254 { 255 if (!IsValid()) 256 return false; 257 return m_opaque_sp->GetClangASTType(true).IsPolymorphicClass(); 258 } 259 260 bool 261 SBType::IsTypedefType () 262 { 263 if (!IsValid()) 264 return false; 265 return m_opaque_sp->GetClangASTType(true).IsTypedefType(); 266 } 267 268 lldb::SBType 269 SBType::GetFunctionReturnType () 270 { 271 if (IsValid()) 272 { 273 ClangASTType return_clang_type (m_opaque_sp->GetClangASTType(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 ClangASTType func_type(m_opaque_sp->GetClangASTType(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->GetClangASTType(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->GetClangASTType(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->GetClangASTType(false).GetBasicTypeEnumeration (); 339 return eBasicTypeInvalid; 340 } 341 342 SBType 343 SBType::GetBasicType(lldb::BasicType basic_type) 344 { 345 if (IsValid()) 346 return SBType (ClangASTContext::GetBasicType (m_opaque_sp->GetClangASTContext(false), basic_type)); 347 return SBType(); 348 } 349 350 uint32_t 351 SBType::GetNumberOfDirectBaseClasses () 352 { 353 if (IsValid()) 354 return m_opaque_sp->GetClangASTType(true).GetNumDirectBaseClasses(); 355 return 0; 356 } 357 358 uint32_t 359 SBType::GetNumberOfVirtualBaseClasses () 360 { 361 if (IsValid()) 362 return m_opaque_sp->GetClangASTType(true).GetNumVirtualBaseClasses(); 363 return 0; 364 } 365 366 uint32_t 367 SBType::GetNumberOfFields () 368 { 369 if (IsValid()) 370 return m_opaque_sp->GetClangASTType(true).GetNumFields(); 371 return 0; 372 } 373 374 bool 375 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) 376 { 377 Stream &strm = description.ref(); 378 379 if (m_opaque_sp) 380 { 381 m_opaque_sp->GetDescription (strm, description_level); 382 } 383 else 384 strm.PutCString ("No value"); 385 386 return true; 387 } 388 389 390 391 SBTypeMember 392 SBType::GetDirectBaseClassAtIndex (uint32_t idx) 393 { 394 SBTypeMember sb_type_member; 395 if (IsValid()) 396 { 397 ClangASTType this_type (m_opaque_sp->GetClangASTType (true)); 398 if (this_type.IsValid()) 399 { 400 uint32_t bit_offset = 0; 401 ClangASTType base_class_type (this_type.GetDirectBaseClassAtIndex(idx, &bit_offset)); 402 if (base_class_type.IsValid()) 403 { 404 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); 405 } 406 } 407 } 408 return sb_type_member; 409 410 } 411 412 SBTypeMember 413 SBType::GetVirtualBaseClassAtIndex (uint32_t idx) 414 { 415 SBTypeMember sb_type_member; 416 if (IsValid()) 417 { 418 ClangASTType this_type (m_opaque_sp->GetClangASTType (true)); 419 if (this_type.IsValid()) 420 { 421 uint32_t bit_offset = 0; 422 ClangASTType base_class_type (this_type.GetVirtualBaseClassAtIndex(idx, &bit_offset)); 423 if (base_class_type.IsValid()) 424 { 425 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); 426 } 427 } 428 } 429 return sb_type_member; 430 } 431 432 SBTypeEnumMemberList 433 SBType::GetEnumMembers () 434 { 435 SBTypeEnumMemberList sb_enum_member_list; 436 if (IsValid()) 437 { 438 const clang::EnumDecl *enum_decl = m_opaque_sp->GetClangASTType(true).GetFullyUnqualifiedType().GetAsEnumDecl(); 439 if (enum_decl) 440 { 441 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos; 442 for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos) 443 { 444 SBTypeEnumMember enum_member; 445 enum_member.reset(new TypeEnumMemberImpl(*enum_pos, ClangASTType(m_opaque_sp->GetClangASTContext(true), enum_decl->getIntegerType()))); 446 sb_enum_member_list.Append(enum_member); 447 } 448 } 449 } 450 return sb_enum_member_list; 451 } 452 453 SBTypeMember 454 SBType::GetFieldAtIndex (uint32_t idx) 455 { 456 SBTypeMember sb_type_member; 457 if (IsValid()) 458 { 459 ClangASTType this_type (m_opaque_sp->GetClangASTType (false)); 460 if (this_type.IsValid()) 461 { 462 uint64_t bit_offset = 0; 463 uint32_t bitfield_bit_size = 0; 464 bool is_bitfield = false; 465 std::string name_sstr; 466 ClangASTType field_type (this_type.GetFieldAtIndex (idx, 467 name_sstr, 468 &bit_offset, 469 &bitfield_bit_size, 470 &is_bitfield)); 471 if (field_type.IsValid()) 472 { 473 ConstString name; 474 if (!name_sstr.empty()) 475 name.SetCString(name_sstr.c_str()); 476 sb_type_member.reset (new TypeMemberImpl (TypeImplSP (new TypeImpl(field_type)), 477 bit_offset, 478 name, 479 bitfield_bit_size, 480 is_bitfield)); 481 } 482 } 483 } 484 return sb_type_member; 485 } 486 487 bool 488 SBType::IsTypeComplete() 489 { 490 if (!IsValid()) 491 return false; 492 return m_opaque_sp->GetClangASTType(false).IsCompleteType(); 493 } 494 495 uint32_t 496 SBType::GetTypeFlags () 497 { 498 if (!IsValid()) 499 return 0; 500 return m_opaque_sp->GetClangASTType(true).GetTypeInfo(); 501 } 502 503 const char* 504 SBType::GetName() 505 { 506 if (!IsValid()) 507 return ""; 508 return m_opaque_sp->GetName().GetCString(); 509 } 510 511 const char * 512 SBType::GetDisplayTypeName () 513 { 514 if (!IsValid()) 515 return ""; 516 return m_opaque_sp->GetDisplayTypeName().GetCString(); 517 } 518 519 lldb::TypeClass 520 SBType::GetTypeClass () 521 { 522 if (IsValid()) 523 return m_opaque_sp->GetClangASTType(true).GetTypeClass(); 524 return lldb::eTypeClassInvalid; 525 } 526 527 uint32_t 528 SBType::GetNumberOfTemplateArguments () 529 { 530 if (IsValid()) 531 return m_opaque_sp->GetClangASTType(false).GetNumTemplateArguments(); 532 return 0; 533 } 534 535 lldb::SBType 536 SBType::GetTemplateArgumentType (uint32_t idx) 537 { 538 if (IsValid()) 539 { 540 TemplateArgumentKind kind = eTemplateArgumentKindNull; 541 ClangASTType template_arg_type = m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind); 542 if (template_arg_type.IsValid()) 543 return SBType(template_arg_type); 544 } 545 return SBType(); 546 } 547 548 549 lldb::TemplateArgumentKind 550 SBType::GetTemplateArgumentKind (uint32_t idx) 551 { 552 TemplateArgumentKind kind = eTemplateArgumentKindNull; 553 if (IsValid()) 554 m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind); 555 return kind; 556 } 557 558 559 SBTypeList::SBTypeList() : 560 m_opaque_ap(new TypeListImpl()) 561 { 562 } 563 564 SBTypeList::SBTypeList(const SBTypeList& rhs) : 565 m_opaque_ap(new TypeListImpl()) 566 { 567 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 568 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 569 } 570 571 bool 572 SBTypeList::IsValid () 573 { 574 return (m_opaque_ap.get() != NULL); 575 } 576 577 SBTypeList& 578 SBTypeList::operator = (const SBTypeList& rhs) 579 { 580 if (this != &rhs) 581 { 582 m_opaque_ap.reset (new TypeListImpl()); 583 for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) 584 Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); 585 } 586 return *this; 587 } 588 589 void 590 SBTypeList::Append (SBType type) 591 { 592 if (type.IsValid()) 593 m_opaque_ap->Append (type.m_opaque_sp); 594 } 595 596 SBType 597 SBTypeList::GetTypeAtIndex(uint32_t index) 598 { 599 if (m_opaque_ap.get()) 600 return SBType(m_opaque_ap->GetTypeAtIndex(index)); 601 return SBType(); 602 } 603 604 uint32_t 605 SBTypeList::GetSize() 606 { 607 return m_opaque_ap->GetSize(); 608 } 609 610 SBTypeList::~SBTypeList() 611 { 612 } 613 614 SBTypeMember::SBTypeMember() : 615 m_opaque_ap() 616 { 617 } 618 619 SBTypeMember::~SBTypeMember() 620 { 621 } 622 623 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) : 624 m_opaque_ap() 625 { 626 if (this != &rhs) 627 { 628 if (rhs.IsValid()) 629 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 630 } 631 } 632 633 lldb::SBTypeMember& 634 SBTypeMember::operator = (const lldb::SBTypeMember& rhs) 635 { 636 if (this != &rhs) 637 { 638 if (rhs.IsValid()) 639 m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); 640 } 641 return *this; 642 } 643 644 bool 645 SBTypeMember::IsValid() const 646 { 647 return m_opaque_ap.get(); 648 } 649 650 const char * 651 SBTypeMember::GetName () 652 { 653 if (m_opaque_ap.get()) 654 return m_opaque_ap->GetName().GetCString(); 655 return NULL; 656 } 657 658 SBType 659 SBTypeMember::GetType () 660 { 661 SBType sb_type; 662 if (m_opaque_ap.get()) 663 { 664 sb_type.SetSP (m_opaque_ap->GetTypeImpl()); 665 } 666 return sb_type; 667 668 } 669 670 uint64_t 671 SBTypeMember::GetOffsetInBytes() 672 { 673 if (m_opaque_ap.get()) 674 return m_opaque_ap->GetBitOffset() / 8u; 675 return 0; 676 } 677 678 uint64_t 679 SBTypeMember::GetOffsetInBits() 680 { 681 if (m_opaque_ap.get()) 682 return m_opaque_ap->GetBitOffset(); 683 return 0; 684 } 685 686 bool 687 SBTypeMember::IsBitfield() 688 { 689 if (m_opaque_ap.get()) 690 return m_opaque_ap->GetIsBitfield(); 691 return false; 692 } 693 694 uint32_t 695 SBTypeMember::GetBitfieldSizeInBits() 696 { 697 if (m_opaque_ap.get()) 698 return m_opaque_ap->GetBitfieldBitSize(); 699 return 0; 700 } 701 702 703 bool 704 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) 705 { 706 Stream &strm = description.ref(); 707 708 if (m_opaque_ap.get()) 709 { 710 const uint32_t bit_offset = m_opaque_ap->GetBitOffset(); 711 const uint32_t byte_offset = bit_offset / 8u; 712 const uint32_t byte_bit_offset = bit_offset % 8u; 713 const char *name = m_opaque_ap->GetName().GetCString(); 714 if (byte_bit_offset) 715 strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset); 716 else 717 strm.Printf ("+%u: (", byte_offset); 718 719 TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl()); 720 if (type_impl_sp) 721 type_impl_sp->GetDescription(strm, description_level); 722 723 strm.Printf (") %s", name); 724 if (m_opaque_ap->GetIsBitfield()) 725 { 726 const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize(); 727 strm.Printf (" : %u", bitfield_bit_size); 728 } 729 } 730 else 731 { 732 strm.PutCString ("No value"); 733 } 734 return true; 735 } 736 737 738 void 739 SBTypeMember::reset(TypeMemberImpl *type_member_impl) 740 { 741 m_opaque_ap.reset(type_member_impl); 742 } 743 744 TypeMemberImpl & 745 SBTypeMember::ref () 746 { 747 if (m_opaque_ap.get() == NULL) 748 m_opaque_ap.reset (new TypeMemberImpl()); 749 return *m_opaque_ap.get(); 750 } 751 752 const TypeMemberImpl & 753 SBTypeMember::ref () const 754 { 755 return *m_opaque_ap.get(); 756 } 757 758 SBTypeMemberFunction::SBTypeMemberFunction() : 759 m_opaque_sp() 760 { 761 } 762 763 SBTypeMemberFunction::~SBTypeMemberFunction() 764 { 765 } 766 767 SBTypeMemberFunction::SBTypeMemberFunction (const SBTypeMemberFunction& rhs) : 768 m_opaque_sp(rhs.m_opaque_sp) 769 { 770 } 771 772 lldb::SBTypeMemberFunction& 773 SBTypeMemberFunction::operator = (const lldb::SBTypeMemberFunction& rhs) 774 { 775 if (this != &rhs) 776 m_opaque_sp = rhs.m_opaque_sp; 777 return *this; 778 } 779 780 bool 781 SBTypeMemberFunction::IsValid() const 782 { 783 return m_opaque_sp.get(); 784 } 785 786 const char * 787 SBTypeMemberFunction::GetName () 788 { 789 if (m_opaque_sp) 790 return m_opaque_sp->GetName().GetCString(); 791 return NULL; 792 } 793 794 SBType 795 SBTypeMemberFunction::GetType () 796 { 797 SBType sb_type; 798 if (m_opaque_sp) 799 { 800 sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType()))); 801 } 802 return sb_type; 803 } 804 805 lldb::SBType 806 SBTypeMemberFunction::GetReturnType () 807 { 808 SBType sb_type; 809 if (m_opaque_sp) 810 { 811 sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType()))); 812 } 813 return sb_type; 814 } 815 816 uint32_t 817 SBTypeMemberFunction::GetNumberOfArguments () 818 { 819 if (m_opaque_sp) 820 return m_opaque_sp->GetNumArguments(); 821 return 0; 822 } 823 824 lldb::SBType 825 SBTypeMemberFunction::GetArgumentTypeAtIndex (uint32_t i) 826 { 827 SBType sb_type; 828 if (m_opaque_sp) 829 { 830 sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i)))); 831 } 832 return sb_type; 833 } 834 835 lldb::MemberFunctionKind 836 SBTypeMemberFunction::GetKind () 837 { 838 if (m_opaque_sp) 839 return m_opaque_sp->GetKind(); 840 return lldb::eMemberFunctionKindUnknown; 841 842 } 843 844 bool 845 SBTypeMemberFunction::GetDescription (lldb::SBStream &description, 846 lldb::DescriptionLevel description_level) 847 { 848 Stream &strm = description.ref(); 849 850 if (m_opaque_sp) 851 return m_opaque_sp->GetDescription(strm); 852 853 return false; 854 } 855 856 void 857 SBTypeMemberFunction::reset(TypeMemberFunctionImpl *type_member_impl) 858 { 859 m_opaque_sp.reset(type_member_impl); 860 } 861 862 TypeMemberFunctionImpl & 863 SBTypeMemberFunction::ref () 864 { 865 if (!m_opaque_sp) 866 m_opaque_sp.reset (new TypeMemberFunctionImpl()); 867 return *m_opaque_sp.get(); 868 } 869 870 const TypeMemberFunctionImpl & 871 SBTypeMemberFunction::ref () const 872 { 873 return *m_opaque_sp.get(); 874 } 875