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 
20 #include "llvm/ADT/APSInt.h"
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         return SBType(m_opaque_sp->GetTypeSystem(false)->GetBasicTypeFromAST(basic_type));
347     return SBType();
348 }
349 
350 uint32_t
351 SBType::GetNumberOfDirectBaseClasses ()
352 {
353     if (IsValid())
354         return m_opaque_sp->GetCompilerType(true).GetNumDirectBaseClasses();
355     return 0;
356 }
357 
358 uint32_t
359 SBType::GetNumberOfVirtualBaseClasses ()
360 {
361     if (IsValid())
362         return m_opaque_sp->GetCompilerType(true).GetNumVirtualBaseClasses();
363     return 0;
364 }
365 
366 uint32_t
367 SBType::GetNumberOfFields ()
368 {
369     if (IsValid())
370         return m_opaque_sp->GetCompilerType(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         uint32_t bit_offset = 0;
398         CompilerType base_class_type = m_opaque_sp->GetCompilerType (true).GetDirectBaseClassAtIndex(idx, &bit_offset);
399         if (base_class_type.IsValid())
400             sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
401     }
402     return sb_type_member;
403 
404 }
405 
406 SBTypeMember
407 SBType::GetVirtualBaseClassAtIndex (uint32_t idx)
408 {
409     SBTypeMember sb_type_member;
410     if (IsValid())
411     {
412         uint32_t bit_offset = 0;
413         CompilerType base_class_type = m_opaque_sp->GetCompilerType (true).GetVirtualBaseClassAtIndex(idx, &bit_offset);
414         if (base_class_type.IsValid())
415             sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
416     }
417     return sb_type_member;
418 }
419 
420 SBTypeEnumMemberList
421 SBType::GetEnumMembers ()
422 {
423     SBTypeEnumMemberList sb_enum_member_list;
424     if (IsValid())
425     {
426         CompilerType this_type (m_opaque_sp->GetCompilerType (true));
427         if (this_type.IsValid())
428         {
429             this_type.ForEachEnumerator([&sb_enum_member_list] (const CompilerType &integer_type, const ConstString &name, const llvm::APSInt &value) -> bool {
430                 SBTypeEnumMember enum_member (lldb::TypeEnumMemberImplSP (new TypeEnumMemberImpl(lldb::TypeImplSP(new TypeImpl(integer_type)), name, value)));
431                 sb_enum_member_list.Append(enum_member);
432                 return true; // Keep iterating
433             });
434         }
435     }
436     return sb_enum_member_list;
437 }
438 
439 SBTypeMember
440 SBType::GetFieldAtIndex (uint32_t idx)
441 {
442     SBTypeMember sb_type_member;
443     if (IsValid())
444     {
445         CompilerType this_type (m_opaque_sp->GetCompilerType (false));
446         if (this_type.IsValid())
447         {
448             uint64_t bit_offset = 0;
449             uint32_t bitfield_bit_size = 0;
450             bool is_bitfield = false;
451             std::string name_sstr;
452             CompilerType field_type (this_type.GetFieldAtIndex (idx,
453                                                                 name_sstr,
454                                                                 &bit_offset,
455                                                                 &bitfield_bit_size,
456                                                                 &is_bitfield));
457             if (field_type.IsValid())
458             {
459                 ConstString name;
460                 if (!name_sstr.empty())
461                     name.SetCString(name_sstr.c_str());
462                 sb_type_member.reset (new TypeMemberImpl (TypeImplSP (new TypeImpl(field_type)),
463                                                           bit_offset,
464                                                           name,
465                                                           bitfield_bit_size,
466                                                           is_bitfield));
467             }
468         }
469     }
470     return sb_type_member;
471 }
472 
473 bool
474 SBType::IsTypeComplete()
475 {
476     if (!IsValid())
477         return false;
478     return m_opaque_sp->GetCompilerType(false).IsCompleteType();
479 }
480 
481 uint32_t
482 SBType::GetTypeFlags ()
483 {
484     if (!IsValid())
485         return 0;
486     return m_opaque_sp->GetCompilerType(true).GetTypeInfo();
487 }
488 
489 const char*
490 SBType::GetName()
491 {
492     if (!IsValid())
493         return "";
494     return m_opaque_sp->GetName().GetCString();
495 }
496 
497 const char *
498 SBType::GetDisplayTypeName ()
499 {
500     if (!IsValid())
501         return "";
502     return m_opaque_sp->GetDisplayTypeName().GetCString();
503 }
504 
505 lldb::TypeClass
506 SBType::GetTypeClass ()
507 {
508     if (IsValid())
509         return m_opaque_sp->GetCompilerType(true).GetTypeClass();
510     return lldb::eTypeClassInvalid;
511 }
512 
513 uint32_t
514 SBType::GetNumberOfTemplateArguments ()
515 {
516     if (IsValid())
517         return m_opaque_sp->GetCompilerType(false).GetNumTemplateArguments();
518     return 0;
519 }
520 
521 lldb::SBType
522 SBType::GetTemplateArgumentType (uint32_t idx)
523 {
524     if (IsValid())
525     {
526         TemplateArgumentKind kind = eTemplateArgumentKindNull;
527         CompilerType template_arg_type = m_opaque_sp->GetCompilerType(false).GetTemplateArgument(idx, kind);
528         if (template_arg_type.IsValid())
529             return SBType(template_arg_type);
530     }
531     return SBType();
532 }
533 
534 
535 lldb::TemplateArgumentKind
536 SBType::GetTemplateArgumentKind (uint32_t idx)
537 {
538     TemplateArgumentKind kind = eTemplateArgumentKindNull;
539     if (IsValid())
540         m_opaque_sp->GetCompilerType(false).GetTemplateArgument(idx, kind);
541     return kind;
542 }
543 
544 
545 SBTypeList::SBTypeList() :
546     m_opaque_ap(new TypeListImpl())
547 {
548 }
549 
550 SBTypeList::SBTypeList(const SBTypeList& rhs) :
551     m_opaque_ap(new TypeListImpl())
552 {
553     for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
554         Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
555 }
556 
557 bool
558 SBTypeList::IsValid ()
559 {
560     return (m_opaque_ap.get() != NULL);
561 }
562 
563 SBTypeList&
564 SBTypeList::operator = (const SBTypeList& rhs)
565 {
566     if (this != &rhs)
567     {
568         m_opaque_ap.reset (new TypeListImpl());
569         for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
570             Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
571     }
572     return *this;
573 }
574 
575 void
576 SBTypeList::Append (SBType type)
577 {
578     if (type.IsValid())
579         m_opaque_ap->Append (type.m_opaque_sp);
580 }
581 
582 SBType
583 SBTypeList::GetTypeAtIndex(uint32_t index)
584 {
585     if (m_opaque_ap.get())
586         return SBType(m_opaque_ap->GetTypeAtIndex(index));
587     return SBType();
588 }
589 
590 uint32_t
591 SBTypeList::GetSize()
592 {
593     return m_opaque_ap->GetSize();
594 }
595 
596 SBTypeList::~SBTypeList()
597 {
598 }
599 
600 SBTypeMember::SBTypeMember() :
601     m_opaque_ap()
602 {
603 }
604 
605 SBTypeMember::~SBTypeMember()
606 {
607 }
608 
609 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) :
610     m_opaque_ap()
611 {
612     if (this != &rhs)
613     {
614         if (rhs.IsValid())
615             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
616     }
617 }
618 
619 lldb::SBTypeMember&
620 SBTypeMember::operator = (const lldb::SBTypeMember& rhs)
621 {
622     if (this != &rhs)
623     {
624         if (rhs.IsValid())
625             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
626     }
627     return *this;
628 }
629 
630 bool
631 SBTypeMember::IsValid() const
632 {
633     return m_opaque_ap.get();
634 }
635 
636 const char *
637 SBTypeMember::GetName ()
638 {
639     if (m_opaque_ap.get())
640         return m_opaque_ap->GetName().GetCString();
641     return NULL;
642 }
643 
644 SBType
645 SBTypeMember::GetType ()
646 {
647     SBType sb_type;
648     if (m_opaque_ap.get())
649     {
650         sb_type.SetSP (m_opaque_ap->GetTypeImpl());
651     }
652     return sb_type;
653 
654 }
655 
656 uint64_t
657 SBTypeMember::GetOffsetInBytes()
658 {
659     if (m_opaque_ap.get())
660         return m_opaque_ap->GetBitOffset() / 8u;
661     return 0;
662 }
663 
664 uint64_t
665 SBTypeMember::GetOffsetInBits()
666 {
667     if (m_opaque_ap.get())
668         return m_opaque_ap->GetBitOffset();
669     return 0;
670 }
671 
672 bool
673 SBTypeMember::IsBitfield()
674 {
675     if (m_opaque_ap.get())
676         return m_opaque_ap->GetIsBitfield();
677     return false;
678 }
679 
680 uint32_t
681 SBTypeMember::GetBitfieldSizeInBits()
682 {
683     if (m_opaque_ap.get())
684         return m_opaque_ap->GetBitfieldBitSize();
685     return 0;
686 }
687 
688 
689 bool
690 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level)
691 {
692     Stream &strm = description.ref();
693 
694     if (m_opaque_ap.get())
695     {
696         const uint32_t bit_offset = m_opaque_ap->GetBitOffset();
697         const uint32_t byte_offset = bit_offset / 8u;
698         const uint32_t byte_bit_offset = bit_offset % 8u;
699         const char *name = m_opaque_ap->GetName().GetCString();
700         if (byte_bit_offset)
701             strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset);
702         else
703             strm.Printf ("+%u: (", byte_offset);
704 
705         TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl());
706         if (type_impl_sp)
707             type_impl_sp->GetDescription(strm, description_level);
708 
709         strm.Printf (") %s", name);
710         if (m_opaque_ap->GetIsBitfield())
711         {
712             const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize();
713             strm.Printf (" : %u", bitfield_bit_size);
714         }
715     }
716     else
717     {
718         strm.PutCString ("No value");
719     }
720     return true;
721 }
722 
723 
724 void
725 SBTypeMember::reset(TypeMemberImpl *type_member_impl)
726 {
727     m_opaque_ap.reset(type_member_impl);
728 }
729 
730 TypeMemberImpl &
731 SBTypeMember::ref ()
732 {
733     if (m_opaque_ap.get() == NULL)
734         m_opaque_ap.reset (new TypeMemberImpl());
735     return *m_opaque_ap.get();
736 }
737 
738 const TypeMemberImpl &
739 SBTypeMember::ref () const
740 {
741     return *m_opaque_ap.get();
742 }
743 
744 SBTypeMemberFunction::SBTypeMemberFunction() :
745 m_opaque_sp()
746 {
747 }
748 
749 SBTypeMemberFunction::~SBTypeMemberFunction()
750 {
751 }
752 
753 SBTypeMemberFunction::SBTypeMemberFunction (const SBTypeMemberFunction& rhs) :
754     m_opaque_sp(rhs.m_opaque_sp)
755 {
756 }
757 
758 lldb::SBTypeMemberFunction&
759 SBTypeMemberFunction::operator = (const lldb::SBTypeMemberFunction& rhs)
760 {
761     if (this != &rhs)
762         m_opaque_sp = rhs.m_opaque_sp;
763     return *this;
764 }
765 
766 bool
767 SBTypeMemberFunction::IsValid() const
768 {
769     return m_opaque_sp.get();
770 }
771 
772 const char *
773 SBTypeMemberFunction::GetName ()
774 {
775     if (m_opaque_sp)
776         return m_opaque_sp->GetName().GetCString();
777     return NULL;
778 }
779 
780 SBType
781 SBTypeMemberFunction::GetType ()
782 {
783     SBType sb_type;
784     if (m_opaque_sp)
785     {
786         sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType())));
787     }
788     return sb_type;
789 }
790 
791 lldb::SBType
792 SBTypeMemberFunction::GetReturnType ()
793 {
794     SBType sb_type;
795     if (m_opaque_sp)
796     {
797         sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType())));
798     }
799     return sb_type;
800 }
801 
802 uint32_t
803 SBTypeMemberFunction::GetNumberOfArguments ()
804 {
805     if (m_opaque_sp)
806         return m_opaque_sp->GetNumArguments();
807     return 0;
808 }
809 
810 lldb::SBType
811 SBTypeMemberFunction::GetArgumentTypeAtIndex (uint32_t i)
812 {
813     SBType sb_type;
814     if (m_opaque_sp)
815     {
816         sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i))));
817     }
818     return sb_type;
819 }
820 
821 lldb::MemberFunctionKind
822 SBTypeMemberFunction::GetKind ()
823 {
824     if (m_opaque_sp)
825         return m_opaque_sp->GetKind();
826     return lldb::eMemberFunctionKindUnknown;
827 
828 }
829 
830 bool
831 SBTypeMemberFunction::GetDescription (lldb::SBStream &description,
832                                       lldb::DescriptionLevel description_level)
833 {
834     Stream &strm = description.ref();
835 
836     if (m_opaque_sp)
837         return m_opaque_sp->GetDescription(strm);
838 
839     return false;
840 }
841 
842 void
843 SBTypeMemberFunction::reset(TypeMemberFunctionImpl *type_member_impl)
844 {
845     m_opaque_sp.reset(type_member_impl);
846 }
847 
848 TypeMemberFunctionImpl &
849 SBTypeMemberFunction::ref ()
850 {
851     if (!m_opaque_sp)
852         m_opaque_sp.reset (new TypeMemberFunctionImpl());
853     return *m_opaque_sp.get();
854 }
855 
856 const TypeMemberFunctionImpl &
857 SBTypeMemberFunction::ref () const
858 {
859     return *m_opaque_sp.get();
860 }
861