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