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