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