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