| //===-- SBType.cpp ----------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "lldb/API/SBType.h" |
| #include "lldb/API/SBDefines.h" |
| #include "lldb/API/SBStream.h" |
| #include "lldb/API/SBTypeEnumMember.h" |
| #include "lldb/Core/Mangled.h" |
| #include "lldb/Symbol/CompilerType.h" |
| #include "lldb/Symbol/Type.h" |
| #include "lldb/Symbol/TypeSystem.h" |
| #include "lldb/Utility/ConstString.h" |
| #include "lldb/Utility/Log.h" |
| #include "lldb/Utility/Stream.h" |
| |
| #include "llvm/ADT/APSInt.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| SBType::SBType() : m_opaque_sp() {} |
| |
| SBType::SBType(const CompilerType &type) |
| : m_opaque_sp(new TypeImpl( |
| CompilerType(type.GetTypeSystem(), type.GetOpaqueQualType()))) {} |
| |
| SBType::SBType(const lldb::TypeSP &type_sp) |
| : m_opaque_sp(new TypeImpl(type_sp)) {} |
| |
| SBType::SBType(const lldb::TypeImplSP &type_impl_sp) |
| : m_opaque_sp(type_impl_sp) {} |
| |
| SBType::SBType(const SBType &rhs) : m_opaque_sp() { |
| if (this != &rhs) { |
| m_opaque_sp = rhs.m_opaque_sp; |
| } |
| } |
| |
| // SBType::SBType (TypeImpl* impl) : |
| // m_opaque_ap(impl) |
| //{} |
| // |
| bool SBType::operator==(SBType &rhs) { |
| if (IsValid() == false) |
| return !rhs.IsValid(); |
| |
| if (rhs.IsValid() == false) |
| return false; |
| |
| return *m_opaque_sp.get() == *rhs.m_opaque_sp.get(); |
| } |
| |
| bool SBType::operator!=(SBType &rhs) { |
| if (IsValid() == false) |
| return rhs.IsValid(); |
| |
| if (rhs.IsValid() == false) |
| return true; |
| |
| return *m_opaque_sp.get() != *rhs.m_opaque_sp.get(); |
| } |
| |
| lldb::TypeImplSP SBType::GetSP() { return m_opaque_sp; } |
| |
| void SBType::SetSP(const lldb::TypeImplSP &type_impl_sp) { |
| m_opaque_sp = type_impl_sp; |
| } |
| |
| SBType &SBType::operator=(const SBType &rhs) { |
| if (this != &rhs) { |
| m_opaque_sp = rhs.m_opaque_sp; |
| } |
| return *this; |
| } |
| |
| SBType::~SBType() {} |
| |
| TypeImpl &SBType::ref() { |
| if (m_opaque_sp.get() == NULL) |
| m_opaque_sp.reset(new TypeImpl()); |
| return *m_opaque_sp; |
| } |
| |
| const TypeImpl &SBType::ref() const { |
| // "const SBAddress &addr" should already have checked "addr.IsValid()" prior |
| // to calling this function. In case you didn't we will assert and die to let |
| // you know. |
| assert(m_opaque_sp.get()); |
| return *m_opaque_sp; |
| } |
| |
| bool SBType::IsValid() const { |
| if (m_opaque_sp.get() == NULL) |
| return false; |
| |
| return m_opaque_sp->IsValid(); |
| } |
| |
| uint64_t SBType::GetByteSize() { |
| if (!IsValid()) |
| return 0; |
| |
| return m_opaque_sp->GetCompilerType(false).GetByteSize(nullptr); |
| } |
| |
| bool SBType::IsPointerType() { |
| if (!IsValid()) |
| return false; |
| return m_opaque_sp->GetCompilerType(true).IsPointerType(); |
| } |
| |
| bool SBType::IsArrayType() { |
| if (!IsValid()) |
| return false; |
| return m_opaque_sp->GetCompilerType(true).IsArrayType(nullptr, nullptr, |
| nullptr); |
| } |
| |
| bool SBType::IsVectorType() { |
| if (!IsValid()) |
| return false; |
| return m_opaque_sp->GetCompilerType(true).IsVectorType(nullptr, nullptr); |
| } |
| |
| bool SBType::IsReferenceType() { |
| if (!IsValid()) |
| return false; |
| return m_opaque_sp->GetCompilerType(true).IsReferenceType(); |
| } |
| |
| SBType SBType::GetPointerType() { |
| if (!IsValid()) |
| return SBType(); |
| |
| return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointerType()))); |
| } |
| |
| SBType SBType::GetPointeeType() { |
| if (!IsValid()) |
| return SBType(); |
| return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointeeType()))); |
| } |
| |
| SBType SBType::GetReferenceType() { |
| if (!IsValid()) |
| return SBType(); |
| return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetReferenceType()))); |
| } |
| |
| SBType SBType::GetTypedefedType() { |
| if (!IsValid()) |
| return SBType(); |
| return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetTypedefedType()))); |
| } |
| |
| SBType SBType::GetDereferencedType() { |
| if (!IsValid()) |
| return SBType(); |
| return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetDereferencedType()))); |
| } |
| |
| SBType SBType::GetArrayElementType() { |
| if (!IsValid()) |
| return SBType(); |
| return SBType(TypeImplSP( |
| new TypeImpl(m_opaque_sp->GetCompilerType(true).GetArrayElementType()))); |
| } |
| |
| SBType SBType::GetArrayType(uint64_t size) { |
| if (!IsValid()) |
| return SBType(); |
| return SBType(TypeImplSP( |
| new TypeImpl(m_opaque_sp->GetCompilerType(true).GetArrayType(size)))); |
| } |
| |
| SBType SBType::GetVectorElementType() { |
| SBType type_sb; |
| if (IsValid()) { |
| CompilerType vector_element_type; |
| if (m_opaque_sp->GetCompilerType(true).IsVectorType(&vector_element_type, |
| nullptr)) |
| type_sb.SetSP(TypeImplSP(new TypeImpl(vector_element_type))); |
| } |
| return type_sb; |
| } |
| |
| bool SBType::IsFunctionType() { |
| if (!IsValid()) |
| return false; |
| return m_opaque_sp->GetCompilerType(true).IsFunctionType(); |
| } |
| |
| bool SBType::IsPolymorphicClass() { |
| if (!IsValid()) |
| return false; |
| return m_opaque_sp->GetCompilerType(true).IsPolymorphicClass(); |
| } |
| |
| bool SBType::IsTypedefType() { |
| if (!IsValid()) |
| return false; |
| return m_opaque_sp->GetCompilerType(true).IsTypedefType(); |
| } |
| |
| bool SBType::IsAnonymousType() { |
| if (!IsValid()) |
| return false; |
| return m_opaque_sp->GetCompilerType(true).IsAnonymousType(); |
| } |
| |
| lldb::SBType SBType::GetFunctionReturnType() { |
| if (IsValid()) { |
| CompilerType return_type( |
| m_opaque_sp->GetCompilerType(true).GetFunctionReturnType()); |
| if (return_type.IsValid()) |
| return SBType(return_type); |
| } |
| return lldb::SBType(); |
| } |
| |
| lldb::SBTypeList SBType::GetFunctionArgumentTypes() { |
| SBTypeList sb_type_list; |
| if (IsValid()) { |
| CompilerType func_type(m_opaque_sp->GetCompilerType(true)); |
| size_t count = func_type.GetNumberOfFunctionArguments(); |
| for (size_t i = 0; i < count; i++) { |
| sb_type_list.Append(SBType(func_type.GetFunctionArgumentAtIndex(i))); |
| } |
| } |
| return sb_type_list; |
| } |
| |
| uint32_t SBType::GetNumberOfMemberFunctions() { |
| if (IsValid()) { |
| return m_opaque_sp->GetCompilerType(true).GetNumMemberFunctions(); |
| } |
| return 0; |
| } |
| |
| lldb::SBTypeMemberFunction SBType::GetMemberFunctionAtIndex(uint32_t idx) { |
| SBTypeMemberFunction sb_func_type; |
| if (IsValid()) |
| sb_func_type.reset(new TypeMemberFunctionImpl( |
| m_opaque_sp->GetCompilerType(true).GetMemberFunctionAtIndex(idx))); |
| return sb_func_type; |
| } |
| |
| lldb::SBType SBType::GetUnqualifiedType() { |
| if (!IsValid()) |
| return SBType(); |
| return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetUnqualifiedType()))); |
| } |
| |
| lldb::SBType SBType::GetCanonicalType() { |
| if (IsValid()) |
| return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetCanonicalType()))); |
| return SBType(); |
| } |
| |
| lldb::BasicType SBType::GetBasicType() { |
| if (IsValid()) |
| return m_opaque_sp->GetCompilerType(false).GetBasicTypeEnumeration(); |
| return eBasicTypeInvalid; |
| } |
| |
| SBType SBType::GetBasicType(lldb::BasicType basic_type) { |
| if (IsValid() && m_opaque_sp->IsValid()) |
| return SBType( |
| m_opaque_sp->GetTypeSystem(false)->GetBasicTypeFromAST(basic_type)); |
| return SBType(); |
| } |
| |
| uint32_t SBType::GetNumberOfDirectBaseClasses() { |
| if (IsValid()) |
| return m_opaque_sp->GetCompilerType(true).GetNumDirectBaseClasses(); |
| return 0; |
| } |
| |
| uint32_t SBType::GetNumberOfVirtualBaseClasses() { |
| if (IsValid()) |
| return m_opaque_sp->GetCompilerType(true).GetNumVirtualBaseClasses(); |
| return 0; |
| } |
| |
| uint32_t SBType::GetNumberOfFields() { |
| if (IsValid()) |
| return m_opaque_sp->GetCompilerType(true).GetNumFields(); |
| return 0; |
| } |
| |
| bool SBType::GetDescription(SBStream &description, |
| lldb::DescriptionLevel description_level) { |
| Stream &strm = description.ref(); |
| |
| if (m_opaque_sp) { |
| m_opaque_sp->GetDescription(strm, description_level); |
| } else |
| strm.PutCString("No value"); |
| |
| return true; |
| } |
| |
| SBTypeMember SBType::GetDirectBaseClassAtIndex(uint32_t idx) { |
| SBTypeMember sb_type_member; |
| if (IsValid()) { |
| uint32_t bit_offset = 0; |
| CompilerType base_class_type = |
| m_opaque_sp->GetCompilerType(true).GetDirectBaseClassAtIndex( |
| idx, &bit_offset); |
| if (base_class_type.IsValid()) |
| sb_type_member.reset(new TypeMemberImpl( |
| TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); |
| } |
| return sb_type_member; |
| } |
| |
| SBTypeMember SBType::GetVirtualBaseClassAtIndex(uint32_t idx) { |
| SBTypeMember sb_type_member; |
| if (IsValid()) { |
| uint32_t bit_offset = 0; |
| CompilerType base_class_type = |
| m_opaque_sp->GetCompilerType(true).GetVirtualBaseClassAtIndex( |
| idx, &bit_offset); |
| if (base_class_type.IsValid()) |
| sb_type_member.reset(new TypeMemberImpl( |
| TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); |
| } |
| return sb_type_member; |
| } |
| |
| SBTypeEnumMemberList SBType::GetEnumMembers() { |
| SBTypeEnumMemberList sb_enum_member_list; |
| if (IsValid()) { |
| CompilerType this_type(m_opaque_sp->GetCompilerType(true)); |
| if (this_type.IsValid()) { |
| this_type.ForEachEnumerator([&sb_enum_member_list]( |
| const CompilerType &integer_type, |
| const ConstString &name, |
| const llvm::APSInt &value) -> bool { |
| SBTypeEnumMember enum_member( |
| lldb::TypeEnumMemberImplSP(new TypeEnumMemberImpl( |
| lldb::TypeImplSP(new TypeImpl(integer_type)), name, value))); |
| sb_enum_member_list.Append(enum_member); |
| return true; // Keep iterating |
| }); |
| } |
| } |
| return sb_enum_member_list; |
| } |
| |
| SBTypeMember SBType::GetFieldAtIndex(uint32_t idx) { |
| SBTypeMember sb_type_member; |
| if (IsValid()) { |
| CompilerType this_type(m_opaque_sp->GetCompilerType(false)); |
| if (this_type.IsValid()) { |
| uint64_t bit_offset = 0; |
| uint32_t bitfield_bit_size = 0; |
| bool is_bitfield = false; |
| std::string name_sstr; |
| CompilerType field_type(this_type.GetFieldAtIndex( |
| idx, name_sstr, &bit_offset, &bitfield_bit_size, &is_bitfield)); |
| if (field_type.IsValid()) { |
| ConstString name; |
| if (!name_sstr.empty()) |
| name.SetCString(name_sstr.c_str()); |
| sb_type_member.reset( |
| new TypeMemberImpl(TypeImplSP(new TypeImpl(field_type)), bit_offset, |
| name, bitfield_bit_size, is_bitfield)); |
| } |
| } |
| } |
| return sb_type_member; |
| } |
| |
| bool SBType::IsTypeComplete() { |
| if (!IsValid()) |
| return false; |
| return m_opaque_sp->GetCompilerType(false).IsCompleteType(); |
| } |
| |
| uint32_t SBType::GetTypeFlags() { |
| if (!IsValid()) |
| return 0; |
| return m_opaque_sp->GetCompilerType(true).GetTypeInfo(); |
| } |
| |
| const char *SBType::GetName() { |
| if (!IsValid()) |
| return ""; |
| return m_opaque_sp->GetName().GetCString(); |
| } |
| |
| const char *SBType::GetDisplayTypeName() { |
| if (!IsValid()) |
| return ""; |
| return m_opaque_sp->GetDisplayTypeName().GetCString(); |
| } |
| |
| lldb::TypeClass SBType::GetTypeClass() { |
| if (IsValid()) |
| return m_opaque_sp->GetCompilerType(true).GetTypeClass(); |
| return lldb::eTypeClassInvalid; |
| } |
| |
| uint32_t SBType::GetNumberOfTemplateArguments() { |
| if (IsValid()) |
| return m_opaque_sp->GetCompilerType(false).GetNumTemplateArguments(); |
| return 0; |
| } |
| |
| lldb::SBType SBType::GetTemplateArgumentType(uint32_t idx) { |
| if (!IsValid()) |
| return SBType(); |
| |
| CompilerType type; |
| switch(GetTemplateArgumentKind(idx)) { |
| case eTemplateArgumentKindType: |
| type = m_opaque_sp->GetCompilerType(false).GetTypeTemplateArgument(idx); |
| break; |
| case eTemplateArgumentKindIntegral: |
| type = m_opaque_sp->GetCompilerType(false) |
| .GetIntegralTemplateArgument(idx) |
| ->type; |
| break; |
| default: |
| break; |
| } |
| if (type.IsValid()) |
| return SBType(type); |
| return SBType(); |
| } |
| |
| lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) { |
| if (IsValid()) |
| return m_opaque_sp->GetCompilerType(false).GetTemplateArgumentKind(idx); |
| return eTemplateArgumentKindNull; |
| } |
| |
| SBTypeList::SBTypeList() : m_opaque_ap(new TypeListImpl()) {} |
| |
| SBTypeList::SBTypeList(const SBTypeList &rhs) |
| : m_opaque_ap(new TypeListImpl()) { |
| for (uint32_t i = 0, rhs_size = const_cast<SBTypeList &>(rhs).GetSize(); |
| i < rhs_size; i++) |
| Append(const_cast<SBTypeList &>(rhs).GetTypeAtIndex(i)); |
| } |
| |
| bool SBTypeList::IsValid() { return (m_opaque_ap.get() != NULL); } |
| |
| SBTypeList &SBTypeList::operator=(const SBTypeList &rhs) { |
| if (this != &rhs) { |
| m_opaque_ap.reset(new TypeListImpl()); |
| for (uint32_t i = 0, rhs_size = const_cast<SBTypeList &>(rhs).GetSize(); |
| i < rhs_size; i++) |
| Append(const_cast<SBTypeList &>(rhs).GetTypeAtIndex(i)); |
| } |
| return *this; |
| } |
| |
| void SBTypeList::Append(SBType type) { |
| if (type.IsValid()) |
| m_opaque_ap->Append(type.m_opaque_sp); |
| } |
| |
| SBType SBTypeList::GetTypeAtIndex(uint32_t index) { |
| if (m_opaque_ap.get()) |
| return SBType(m_opaque_ap->GetTypeAtIndex(index)); |
| return SBType(); |
| } |
| |
| uint32_t SBTypeList::GetSize() { return m_opaque_ap->GetSize(); } |
| |
| SBTypeList::~SBTypeList() {} |
| |
| SBTypeMember::SBTypeMember() : m_opaque_ap() {} |
| |
| SBTypeMember::~SBTypeMember() {} |
| |
| SBTypeMember::SBTypeMember(const SBTypeMember &rhs) : m_opaque_ap() { |
| if (this != &rhs) { |
| if (rhs.IsValid()) |
| m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); |
| } |
| } |
| |
| lldb::SBTypeMember &SBTypeMember::operator=(const lldb::SBTypeMember &rhs) { |
| if (this != &rhs) { |
| if (rhs.IsValid()) |
| m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); |
| } |
| return *this; |
| } |
| |
| bool SBTypeMember::IsValid() const { return m_opaque_ap.get(); } |
| |
| const char *SBTypeMember::GetName() { |
| if (m_opaque_ap.get()) |
| return m_opaque_ap->GetName().GetCString(); |
| return NULL; |
| } |
| |
| SBType SBTypeMember::GetType() { |
| SBType sb_type; |
| if (m_opaque_ap.get()) { |
| sb_type.SetSP(m_opaque_ap->GetTypeImpl()); |
| } |
| return sb_type; |
| } |
| |
| uint64_t SBTypeMember::GetOffsetInBytes() { |
| if (m_opaque_ap.get()) |
| return m_opaque_ap->GetBitOffset() / 8u; |
| return 0; |
| } |
| |
| uint64_t SBTypeMember::GetOffsetInBits() { |
| if (m_opaque_ap.get()) |
| return m_opaque_ap->GetBitOffset(); |
| return 0; |
| } |
| |
| bool SBTypeMember::IsBitfield() { |
| if (m_opaque_ap.get()) |
| return m_opaque_ap->GetIsBitfield(); |
| return false; |
| } |
| |
| uint32_t SBTypeMember::GetBitfieldSizeInBits() { |
| if (m_opaque_ap.get()) |
| return m_opaque_ap->GetBitfieldBitSize(); |
| return 0; |
| } |
| |
| bool SBTypeMember::GetDescription(lldb::SBStream &description, |
| lldb::DescriptionLevel description_level) { |
| Stream &strm = description.ref(); |
| |
| if (m_opaque_ap.get()) { |
| const uint32_t bit_offset = m_opaque_ap->GetBitOffset(); |
| const uint32_t byte_offset = bit_offset / 8u; |
| const uint32_t byte_bit_offset = bit_offset % 8u; |
| const char *name = m_opaque_ap->GetName().GetCString(); |
| if (byte_bit_offset) |
| strm.Printf("+%u + %u bits: (", byte_offset, byte_bit_offset); |
| else |
| strm.Printf("+%u: (", byte_offset); |
| |
| TypeImplSP type_impl_sp(m_opaque_ap->GetTypeImpl()); |
| if (type_impl_sp) |
| type_impl_sp->GetDescription(strm, description_level); |
| |
| strm.Printf(") %s", name); |
| if (m_opaque_ap->GetIsBitfield()) { |
| const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize(); |
| strm.Printf(" : %u", bitfield_bit_size); |
| } |
| } else { |
| strm.PutCString("No value"); |
| } |
| return true; |
| } |
| |
| void SBTypeMember::reset(TypeMemberImpl *type_member_impl) { |
| m_opaque_ap.reset(type_member_impl); |
| } |
| |
| TypeMemberImpl &SBTypeMember::ref() { |
| if (m_opaque_ap.get() == NULL) |
| m_opaque_ap.reset(new TypeMemberImpl()); |
| return *m_opaque_ap.get(); |
| } |
| |
| const TypeMemberImpl &SBTypeMember::ref() const { return *m_opaque_ap.get(); } |
| |
| SBTypeMemberFunction::SBTypeMemberFunction() : m_opaque_sp() {} |
| |
| SBTypeMemberFunction::~SBTypeMemberFunction() {} |
| |
| SBTypeMemberFunction::SBTypeMemberFunction(const SBTypeMemberFunction &rhs) |
| : m_opaque_sp(rhs.m_opaque_sp) {} |
| |
| lldb::SBTypeMemberFunction &SBTypeMemberFunction:: |
| operator=(const lldb::SBTypeMemberFunction &rhs) { |
| if (this != &rhs) |
| m_opaque_sp = rhs.m_opaque_sp; |
| return *this; |
| } |
| |
| bool SBTypeMemberFunction::IsValid() const { return m_opaque_sp.get(); } |
| |
| const char *SBTypeMemberFunction::GetName() { |
| if (m_opaque_sp) |
| return m_opaque_sp->GetName().GetCString(); |
| return NULL; |
| } |
| |
| const char *SBTypeMemberFunction::GetDemangledName() { |
| if (m_opaque_sp) { |
| ConstString mangled_str = m_opaque_sp->GetMangledName(); |
| if (mangled_str) { |
| Mangled mangled(mangled_str, true); |
| return mangled.GetDemangledName(mangled.GuessLanguage()).GetCString(); |
| } |
| } |
| return NULL; |
| } |
| |
| const char *SBTypeMemberFunction::GetMangledName() { |
| if (m_opaque_sp) |
| return m_opaque_sp->GetMangledName().GetCString(); |
| return NULL; |
| } |
| |
| SBType SBTypeMemberFunction::GetType() { |
| SBType sb_type; |
| if (m_opaque_sp) { |
| sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType()))); |
| } |
| return sb_type; |
| } |
| |
| lldb::SBType SBTypeMemberFunction::GetReturnType() { |
| SBType sb_type; |
| if (m_opaque_sp) { |
| sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType()))); |
| } |
| return sb_type; |
| } |
| |
| uint32_t SBTypeMemberFunction::GetNumberOfArguments() { |
| if (m_opaque_sp) |
| return m_opaque_sp->GetNumArguments(); |
| return 0; |
| } |
| |
| lldb::SBType SBTypeMemberFunction::GetArgumentTypeAtIndex(uint32_t i) { |
| SBType sb_type; |
| if (m_opaque_sp) { |
| sb_type.SetSP( |
| lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i)))); |
| } |
| return sb_type; |
| } |
| |
| lldb::MemberFunctionKind SBTypeMemberFunction::GetKind() { |
| if (m_opaque_sp) |
| return m_opaque_sp->GetKind(); |
| return lldb::eMemberFunctionKindUnknown; |
| } |
| |
| bool SBTypeMemberFunction::GetDescription( |
| lldb::SBStream &description, lldb::DescriptionLevel description_level) { |
| Stream &strm = description.ref(); |
| |
| if (m_opaque_sp) |
| return m_opaque_sp->GetDescription(strm); |
| |
| return false; |
| } |
| |
| void SBTypeMemberFunction::reset(TypeMemberFunctionImpl *type_member_impl) { |
| m_opaque_sp.reset(type_member_impl); |
| } |
| |
| TypeMemberFunctionImpl &SBTypeMemberFunction::ref() { |
| if (!m_opaque_sp) |
| m_opaque_sp.reset(new TypeMemberFunctionImpl()); |
| return *m_opaque_sp.get(); |
| } |
| |
| const TypeMemberFunctionImpl &SBTypeMemberFunction::ref() const { |
| return *m_opaque_sp.get(); |
| } |