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