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 "lldb/API/SBDefines.h"
11 #include "lldb/API/SBStream.h"
12 #include "lldb/API/SBTypeEnumMember.h"
13 #include "lldb/Core/Mangled.h"
14 #include "lldb/Symbol/CompilerType.h"
15 #include "lldb/Symbol/Type.h"
16 #include "lldb/Symbol/TypeSystem.h"
17 #include "lldb/Utility/ConstString.h"
18 #include "lldb/Utility/Log.h"
19 #include "lldb/Utility/Stream.h"
20 
21 #include "llvm/ADT/APSInt.h"
22 
23 #include <memory>
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 
28 SBType::SBType() : m_opaque_sp() {}
29 
30 SBType::SBType(const CompilerType &type)
31     : m_opaque_sp(new TypeImpl(
32           CompilerType(type.GetTypeSystem(), type.GetOpaqueQualType()))) {}
33 
34 SBType::SBType(const lldb::TypeSP &type_sp)
35     : m_opaque_sp(new TypeImpl(type_sp)) {}
36 
37 SBType::SBType(const lldb::TypeImplSP &type_impl_sp)
38     : m_opaque_sp(type_impl_sp) {}
39 
40 SBType::SBType(const SBType &rhs) : m_opaque_sp() {
41   if (this != &rhs) {
42     m_opaque_sp = rhs.m_opaque_sp;
43   }
44 }
45 
46 // SBType::SBType (TypeImpl* impl) :
47 //    m_opaque_up(impl)
48 //{}
49 //
50 bool SBType::operator==(SBType &rhs) {
51   if (!IsValid())
52     return !rhs.IsValid();
53 
54   if (!rhs.IsValid())
55     return false;
56 
57   return *m_opaque_sp.get() == *rhs.m_opaque_sp.get();
58 }
59 
60 bool SBType::operator!=(SBType &rhs) {
61   if (!IsValid())
62     return rhs.IsValid();
63 
64   if (!rhs.IsValid())
65     return true;
66 
67   return *m_opaque_sp.get() != *rhs.m_opaque_sp.get();
68 }
69 
70 lldb::TypeImplSP SBType::GetSP() { return m_opaque_sp; }
71 
72 void SBType::SetSP(const lldb::TypeImplSP &type_impl_sp) {
73   m_opaque_sp = type_impl_sp;
74 }
75 
76 SBType &SBType::operator=(const SBType &rhs) {
77   if (this != &rhs) {
78     m_opaque_sp = rhs.m_opaque_sp;
79   }
80   return *this;
81 }
82 
83 SBType::~SBType() {}
84 
85 TypeImpl &SBType::ref() {
86   if (m_opaque_sp.get() == NULL)
87     m_opaque_sp = std::make_shared<TypeImpl>();
88   return *m_opaque_sp;
89 }
90 
91 const TypeImpl &SBType::ref() const {
92   // "const SBAddress &addr" should already have checked "addr.IsValid()" prior
93   // to calling this function. In case you didn't we will assert and die to let
94   // you know.
95   assert(m_opaque_sp.get());
96   return *m_opaque_sp;
97 }
98 
99 bool SBType::IsValid() const {
100   if (m_opaque_sp.get() == NULL)
101     return false;
102 
103   return m_opaque_sp->IsValid();
104 }
105 
106 uint64_t SBType::GetByteSize() {
107   if (IsValid())
108     if (llvm::Optional<uint64_t> size =
109             m_opaque_sp->GetCompilerType(false).GetByteSize(nullptr))
110       return *size;
111   return 0;
112 }
113 
114 bool SBType::IsPointerType() {
115   if (!IsValid())
116     return false;
117   return m_opaque_sp->GetCompilerType(true).IsPointerType();
118 }
119 
120 bool SBType::IsArrayType() {
121   if (!IsValid())
122     return false;
123   return m_opaque_sp->GetCompilerType(true).IsArrayType(nullptr, nullptr,
124                                                         nullptr);
125 }
126 
127 bool SBType::IsVectorType() {
128   if (!IsValid())
129     return false;
130   return m_opaque_sp->GetCompilerType(true).IsVectorType(nullptr, nullptr);
131 }
132 
133 bool SBType::IsReferenceType() {
134   if (!IsValid())
135     return false;
136   return m_opaque_sp->GetCompilerType(true).IsReferenceType();
137 }
138 
139 SBType SBType::GetPointerType() {
140   if (!IsValid())
141     return SBType();
142 
143   return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointerType())));
144 }
145 
146 SBType SBType::GetPointeeType() {
147   if (!IsValid())
148     return SBType();
149   return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointeeType())));
150 }
151 
152 SBType SBType::GetReferenceType() {
153   if (!IsValid())
154     return SBType();
155   return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetReferenceType())));
156 }
157 
158 SBType SBType::GetTypedefedType() {
159   if (!IsValid())
160     return SBType();
161   return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetTypedefedType())));
162 }
163 
164 SBType SBType::GetDereferencedType() {
165   if (!IsValid())
166     return SBType();
167   return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetDereferencedType())));
168 }
169 
170 SBType SBType::GetArrayElementType() {
171   if (!IsValid())
172     return SBType();
173   return SBType(TypeImplSP(
174       new TypeImpl(m_opaque_sp->GetCompilerType(true).GetArrayElementType())));
175 }
176 
177 SBType SBType::GetArrayType(uint64_t size) {
178   if (!IsValid())
179     return SBType();
180   return SBType(TypeImplSP(
181       new TypeImpl(m_opaque_sp->GetCompilerType(true).GetArrayType(size))));
182 }
183 
184 SBType SBType::GetVectorElementType() {
185   SBType type_sb;
186   if (IsValid()) {
187     CompilerType vector_element_type;
188     if (m_opaque_sp->GetCompilerType(true).IsVectorType(&vector_element_type,
189                                                         nullptr))
190       type_sb.SetSP(TypeImplSP(new TypeImpl(vector_element_type)));
191   }
192   return type_sb;
193 }
194 
195 bool SBType::IsFunctionType() {
196   if (!IsValid())
197     return false;
198   return m_opaque_sp->GetCompilerType(true).IsFunctionType();
199 }
200 
201 bool SBType::IsPolymorphicClass() {
202   if (!IsValid())
203     return false;
204   return m_opaque_sp->GetCompilerType(true).IsPolymorphicClass();
205 }
206 
207 bool SBType::IsTypedefType() {
208   if (!IsValid())
209     return false;
210   return m_opaque_sp->GetCompilerType(true).IsTypedefType();
211 }
212 
213 bool SBType::IsAnonymousType() {
214   if (!IsValid())
215     return false;
216   return m_opaque_sp->GetCompilerType(true).IsAnonymousType();
217 }
218 
219 lldb::SBType SBType::GetFunctionReturnType() {
220   if (IsValid()) {
221     CompilerType return_type(
222         m_opaque_sp->GetCompilerType(true).GetFunctionReturnType());
223     if (return_type.IsValid())
224       return SBType(return_type);
225   }
226   return lldb::SBType();
227 }
228 
229 lldb::SBTypeList SBType::GetFunctionArgumentTypes() {
230   SBTypeList sb_type_list;
231   if (IsValid()) {
232     CompilerType func_type(m_opaque_sp->GetCompilerType(true));
233     size_t count = func_type.GetNumberOfFunctionArguments();
234     for (size_t i = 0; i < count; i++) {
235       sb_type_list.Append(SBType(func_type.GetFunctionArgumentAtIndex(i)));
236     }
237   }
238   return sb_type_list;
239 }
240 
241 uint32_t SBType::GetNumberOfMemberFunctions() {
242   if (IsValid()) {
243     return m_opaque_sp->GetCompilerType(true).GetNumMemberFunctions();
244   }
245   return 0;
246 }
247 
248 lldb::SBTypeMemberFunction SBType::GetMemberFunctionAtIndex(uint32_t idx) {
249   SBTypeMemberFunction sb_func_type;
250   if (IsValid())
251     sb_func_type.reset(new TypeMemberFunctionImpl(
252         m_opaque_sp->GetCompilerType(true).GetMemberFunctionAtIndex(idx)));
253   return sb_func_type;
254 }
255 
256 lldb::SBType SBType::GetUnqualifiedType() {
257   if (!IsValid())
258     return SBType();
259   return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetUnqualifiedType())));
260 }
261 
262 lldb::SBType SBType::GetCanonicalType() {
263   if (IsValid())
264     return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetCanonicalType())));
265   return SBType();
266 }
267 
268 lldb::BasicType SBType::GetBasicType() {
269   if (IsValid())
270     return m_opaque_sp->GetCompilerType(false).GetBasicTypeEnumeration();
271   return eBasicTypeInvalid;
272 }
273 
274 SBType SBType::GetBasicType(lldb::BasicType basic_type) {
275   if (IsValid() && m_opaque_sp->IsValid())
276     return SBType(
277         m_opaque_sp->GetTypeSystem(false)->GetBasicTypeFromAST(basic_type));
278   return SBType();
279 }
280 
281 uint32_t SBType::GetNumberOfDirectBaseClasses() {
282   if (IsValid())
283     return m_opaque_sp->GetCompilerType(true).GetNumDirectBaseClasses();
284   return 0;
285 }
286 
287 uint32_t SBType::GetNumberOfVirtualBaseClasses() {
288   if (IsValid())
289     return m_opaque_sp->GetCompilerType(true).GetNumVirtualBaseClasses();
290   return 0;
291 }
292 
293 uint32_t SBType::GetNumberOfFields() {
294   if (IsValid())
295     return m_opaque_sp->GetCompilerType(true).GetNumFields();
296   return 0;
297 }
298 
299 bool SBType::GetDescription(SBStream &description,
300                             lldb::DescriptionLevel description_level) {
301   Stream &strm = description.ref();
302 
303   if (m_opaque_sp) {
304     m_opaque_sp->GetDescription(strm, description_level);
305   } else
306     strm.PutCString("No value");
307 
308   return true;
309 }
310 
311 SBTypeMember SBType::GetDirectBaseClassAtIndex(uint32_t idx) {
312   SBTypeMember sb_type_member;
313   if (IsValid()) {
314     uint32_t bit_offset = 0;
315     CompilerType base_class_type =
316         m_opaque_sp->GetCompilerType(true).GetDirectBaseClassAtIndex(
317             idx, &bit_offset);
318     if (base_class_type.IsValid())
319       sb_type_member.reset(new TypeMemberImpl(
320           TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
321   }
322   return sb_type_member;
323 }
324 
325 SBTypeMember SBType::GetVirtualBaseClassAtIndex(uint32_t idx) {
326   SBTypeMember sb_type_member;
327   if (IsValid()) {
328     uint32_t bit_offset = 0;
329     CompilerType base_class_type =
330         m_opaque_sp->GetCompilerType(true).GetVirtualBaseClassAtIndex(
331             idx, &bit_offset);
332     if (base_class_type.IsValid())
333       sb_type_member.reset(new TypeMemberImpl(
334           TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
335   }
336   return sb_type_member;
337 }
338 
339 SBTypeEnumMemberList SBType::GetEnumMembers() {
340   SBTypeEnumMemberList sb_enum_member_list;
341   if (IsValid()) {
342     CompilerType this_type(m_opaque_sp->GetCompilerType(true));
343     if (this_type.IsValid()) {
344       this_type.ForEachEnumerator([&sb_enum_member_list](
345                                       const CompilerType &integer_type,
346                                       const ConstString &name,
347                                       const llvm::APSInt &value) -> bool {
348         SBTypeEnumMember enum_member(
349             lldb::TypeEnumMemberImplSP(new TypeEnumMemberImpl(
350                 lldb::TypeImplSP(new TypeImpl(integer_type)), name, value)));
351         sb_enum_member_list.Append(enum_member);
352         return true; // Keep iterating
353       });
354     }
355   }
356   return sb_enum_member_list;
357 }
358 
359 SBTypeMember SBType::GetFieldAtIndex(uint32_t idx) {
360   SBTypeMember sb_type_member;
361   if (IsValid()) {
362     CompilerType this_type(m_opaque_sp->GetCompilerType(false));
363     if (this_type.IsValid()) {
364       uint64_t bit_offset = 0;
365       uint32_t bitfield_bit_size = 0;
366       bool is_bitfield = false;
367       std::string name_sstr;
368       CompilerType field_type(this_type.GetFieldAtIndex(
369           idx, name_sstr, &bit_offset, &bitfield_bit_size, &is_bitfield));
370       if (field_type.IsValid()) {
371         ConstString name;
372         if (!name_sstr.empty())
373           name.SetCString(name_sstr.c_str());
374         sb_type_member.reset(
375             new TypeMemberImpl(TypeImplSP(new TypeImpl(field_type)), bit_offset,
376                                name, bitfield_bit_size, is_bitfield));
377       }
378     }
379   }
380   return sb_type_member;
381 }
382 
383 bool SBType::IsTypeComplete() {
384   if (!IsValid())
385     return false;
386   return m_opaque_sp->GetCompilerType(false).IsCompleteType();
387 }
388 
389 uint32_t SBType::GetTypeFlags() {
390   if (!IsValid())
391     return 0;
392   return m_opaque_sp->GetCompilerType(true).GetTypeInfo();
393 }
394 
395 const char *SBType::GetName() {
396   if (!IsValid())
397     return "";
398   return m_opaque_sp->GetName().GetCString();
399 }
400 
401 const char *SBType::GetDisplayTypeName() {
402   if (!IsValid())
403     return "";
404   return m_opaque_sp->GetDisplayTypeName().GetCString();
405 }
406 
407 lldb::TypeClass SBType::GetTypeClass() {
408   if (IsValid())
409     return m_opaque_sp->GetCompilerType(true).GetTypeClass();
410   return lldb::eTypeClassInvalid;
411 }
412 
413 uint32_t SBType::GetNumberOfTemplateArguments() {
414   if (IsValid())
415     return m_opaque_sp->GetCompilerType(false).GetNumTemplateArguments();
416   return 0;
417 }
418 
419 lldb::SBType SBType::GetTemplateArgumentType(uint32_t idx) {
420   if (!IsValid())
421     return SBType();
422 
423   CompilerType type;
424   switch(GetTemplateArgumentKind(idx)) {
425     case eTemplateArgumentKindType:
426       type = m_opaque_sp->GetCompilerType(false).GetTypeTemplateArgument(idx);
427       break;
428     case eTemplateArgumentKindIntegral:
429       type = m_opaque_sp->GetCompilerType(false)
430                  .GetIntegralTemplateArgument(idx)
431                  ->type;
432       break;
433     default:
434       break;
435   }
436   if (type.IsValid())
437     return SBType(type);
438   return SBType();
439 }
440 
441 lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) {
442   if (IsValid())
443     return m_opaque_sp->GetCompilerType(false).GetTemplateArgumentKind(idx);
444   return eTemplateArgumentKindNull;
445 }
446 
447 SBTypeList::SBTypeList() : m_opaque_up(new TypeListImpl()) {}
448 
449 SBTypeList::SBTypeList(const SBTypeList &rhs)
450     : m_opaque_up(new TypeListImpl()) {
451   for (uint32_t i = 0, rhs_size = const_cast<SBTypeList &>(rhs).GetSize();
452        i < rhs_size; i++)
453     Append(const_cast<SBTypeList &>(rhs).GetTypeAtIndex(i));
454 }
455 
456 bool SBTypeList::IsValid() { return (m_opaque_up != NULL); }
457 
458 SBTypeList &SBTypeList::operator=(const SBTypeList &rhs) {
459   if (this != &rhs) {
460     m_opaque_up.reset(new TypeListImpl());
461     for (uint32_t i = 0, rhs_size = const_cast<SBTypeList &>(rhs).GetSize();
462          i < rhs_size; i++)
463       Append(const_cast<SBTypeList &>(rhs).GetTypeAtIndex(i));
464   }
465   return *this;
466 }
467 
468 void SBTypeList::Append(SBType type) {
469   if (type.IsValid())
470     m_opaque_up->Append(type.m_opaque_sp);
471 }
472 
473 SBType SBTypeList::GetTypeAtIndex(uint32_t index) {
474   if (m_opaque_up)
475     return SBType(m_opaque_up->GetTypeAtIndex(index));
476   return SBType();
477 }
478 
479 uint32_t SBTypeList::GetSize() { return m_opaque_up->GetSize(); }
480 
481 SBTypeList::~SBTypeList() {}
482 
483 SBTypeMember::SBTypeMember() : m_opaque_up() {}
484 
485 SBTypeMember::~SBTypeMember() {}
486 
487 SBTypeMember::SBTypeMember(const SBTypeMember &rhs) : m_opaque_up() {
488   if (this != &rhs) {
489     if (rhs.IsValid())
490       m_opaque_up.reset(new TypeMemberImpl(rhs.ref()));
491   }
492 }
493 
494 lldb::SBTypeMember &SBTypeMember::operator=(const lldb::SBTypeMember &rhs) {
495   if (this != &rhs) {
496     if (rhs.IsValid())
497       m_opaque_up.reset(new TypeMemberImpl(rhs.ref()));
498   }
499   return *this;
500 }
501 
502 bool SBTypeMember::IsValid() const { return m_opaque_up.get(); }
503 
504 const char *SBTypeMember::GetName() {
505   if (m_opaque_up)
506     return m_opaque_up->GetName().GetCString();
507   return NULL;
508 }
509 
510 SBType SBTypeMember::GetType() {
511   SBType sb_type;
512   if (m_opaque_up) {
513     sb_type.SetSP(m_opaque_up->GetTypeImpl());
514   }
515   return sb_type;
516 }
517 
518 uint64_t SBTypeMember::GetOffsetInBytes() {
519   if (m_opaque_up)
520     return m_opaque_up->GetBitOffset() / 8u;
521   return 0;
522 }
523 
524 uint64_t SBTypeMember::GetOffsetInBits() {
525   if (m_opaque_up)
526     return m_opaque_up->GetBitOffset();
527   return 0;
528 }
529 
530 bool SBTypeMember::IsBitfield() {
531   if (m_opaque_up)
532     return m_opaque_up->GetIsBitfield();
533   return false;
534 }
535 
536 uint32_t SBTypeMember::GetBitfieldSizeInBits() {
537   if (m_opaque_up)
538     return m_opaque_up->GetBitfieldBitSize();
539   return 0;
540 }
541 
542 bool SBTypeMember::GetDescription(lldb::SBStream &description,
543                                   lldb::DescriptionLevel description_level) {
544   Stream &strm = description.ref();
545 
546   if (m_opaque_up) {
547     const uint32_t bit_offset = m_opaque_up->GetBitOffset();
548     const uint32_t byte_offset = bit_offset / 8u;
549     const uint32_t byte_bit_offset = bit_offset % 8u;
550     const char *name = m_opaque_up->GetName().GetCString();
551     if (byte_bit_offset)
552       strm.Printf("+%u + %u bits: (", byte_offset, byte_bit_offset);
553     else
554       strm.Printf("+%u: (", byte_offset);
555 
556     TypeImplSP type_impl_sp(m_opaque_up->GetTypeImpl());
557     if (type_impl_sp)
558       type_impl_sp->GetDescription(strm, description_level);
559 
560     strm.Printf(") %s", name);
561     if (m_opaque_up->GetIsBitfield()) {
562       const uint32_t bitfield_bit_size = m_opaque_up->GetBitfieldBitSize();
563       strm.Printf(" : %u", bitfield_bit_size);
564     }
565   } else {
566     strm.PutCString("No value");
567   }
568   return true;
569 }
570 
571 void SBTypeMember::reset(TypeMemberImpl *type_member_impl) {
572   m_opaque_up.reset(type_member_impl);
573 }
574 
575 TypeMemberImpl &SBTypeMember::ref() {
576   if (m_opaque_up == NULL)
577     m_opaque_up.reset(new TypeMemberImpl());
578   return *m_opaque_up;
579 }
580 
581 const TypeMemberImpl &SBTypeMember::ref() const { return *m_opaque_up; }
582 
583 SBTypeMemberFunction::SBTypeMemberFunction() : m_opaque_sp() {}
584 
585 SBTypeMemberFunction::~SBTypeMemberFunction() {}
586 
587 SBTypeMemberFunction::SBTypeMemberFunction(const SBTypeMemberFunction &rhs)
588     : m_opaque_sp(rhs.m_opaque_sp) {}
589 
590 lldb::SBTypeMemberFunction &SBTypeMemberFunction::
591 operator=(const lldb::SBTypeMemberFunction &rhs) {
592   if (this != &rhs)
593     m_opaque_sp = rhs.m_opaque_sp;
594   return *this;
595 }
596 
597 bool SBTypeMemberFunction::IsValid() const { return m_opaque_sp.get(); }
598 
599 const char *SBTypeMemberFunction::GetName() {
600   if (m_opaque_sp)
601     return m_opaque_sp->GetName().GetCString();
602   return NULL;
603 }
604 
605 const char *SBTypeMemberFunction::GetDemangledName() {
606   if (m_opaque_sp) {
607     ConstString mangled_str = m_opaque_sp->GetMangledName();
608     if (mangled_str) {
609       Mangled mangled(mangled_str, true);
610       return mangled.GetDemangledName(mangled.GuessLanguage()).GetCString();
611     }
612   }
613   return NULL;
614 }
615 
616 const char *SBTypeMemberFunction::GetMangledName() {
617   if (m_opaque_sp)
618     return m_opaque_sp->GetMangledName().GetCString();
619   return NULL;
620 }
621 
622 SBType SBTypeMemberFunction::GetType() {
623   SBType sb_type;
624   if (m_opaque_sp) {
625     sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType())));
626   }
627   return sb_type;
628 }
629 
630 lldb::SBType SBTypeMemberFunction::GetReturnType() {
631   SBType sb_type;
632   if (m_opaque_sp) {
633     sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType())));
634   }
635   return sb_type;
636 }
637 
638 uint32_t SBTypeMemberFunction::GetNumberOfArguments() {
639   if (m_opaque_sp)
640     return m_opaque_sp->GetNumArguments();
641   return 0;
642 }
643 
644 lldb::SBType SBTypeMemberFunction::GetArgumentTypeAtIndex(uint32_t i) {
645   SBType sb_type;
646   if (m_opaque_sp) {
647     sb_type.SetSP(
648         lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i))));
649   }
650   return sb_type;
651 }
652 
653 lldb::MemberFunctionKind SBTypeMemberFunction::GetKind() {
654   if (m_opaque_sp)
655     return m_opaque_sp->GetKind();
656   return lldb::eMemberFunctionKindUnknown;
657 }
658 
659 bool SBTypeMemberFunction::GetDescription(
660     lldb::SBStream &description, lldb::DescriptionLevel description_level) {
661   Stream &strm = description.ref();
662 
663   if (m_opaque_sp)
664     return m_opaque_sp->GetDescription(strm);
665 
666   return false;
667 }
668 
669 void SBTypeMemberFunction::reset(TypeMemberFunctionImpl *type_member_impl) {
670   m_opaque_sp.reset(type_member_impl);
671 }
672 
673 TypeMemberFunctionImpl &SBTypeMemberFunction::ref() {
674   if (!m_opaque_sp)
675     m_opaque_sp = std::make_shared<TypeMemberFunctionImpl>();
676   return *m_opaque_sp.get();
677 }
678 
679 const TypeMemberFunctionImpl &SBTypeMemberFunction::ref() const {
680   return *m_opaque_sp.get();
681 }
682