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 <string.h>
11 
12 #include "clang/AST/ASTContext.h"
13 #include "clang/AST/TemplateBase.h"
14 #include "clang/AST/Type.h"
15 
16 #include "lldb/API/SBDefines.h"
17 #include "lldb/API/SBType.h"
18 #include "lldb/API/SBStream.h"
19 #include "lldb/Core/ConstString.h"
20 #include "lldb/Core/Log.h"
21 #include "lldb/Core/Stream.h"
22 #include "lldb/Symbol/ClangASTContext.h"
23 #include "lldb/Symbol/ClangASTType.h"
24 #include "lldb/Symbol/Type.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 using namespace clang;
29 
30 SBType::SBType() :
31     m_opaque_sp()
32 {
33 }
34 
35 SBType::SBType (const ClangASTType &type) :
36     m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(),
37                                           type.GetOpaqueQualType())))
38 {
39 }
40 
41 SBType::SBType (const lldb::TypeSP &type_sp) :
42     m_opaque_sp(new TypeImpl(type_sp))
43 {
44 }
45 
46 SBType::SBType (const lldb::TypeImplSP &type_impl_sp) :
47     m_opaque_sp(type_impl_sp)
48 {
49 }
50 
51 
52 SBType::SBType (const SBType &rhs) :
53     m_opaque_sp()
54 {
55     if (this != &rhs)
56     {
57         m_opaque_sp = rhs.m_opaque_sp;
58     }
59 }
60 
61 
62 //SBType::SBType (TypeImpl* impl) :
63 //    m_opaque_ap(impl)
64 //{}
65 //
66 bool
67 SBType::operator == (SBType &rhs)
68 {
69     if (IsValid() == false)
70         return !rhs.IsValid();
71 
72     return  (rhs.m_opaque_sp->GetASTContext() == m_opaque_sp->GetASTContext()) &&
73             (rhs.m_opaque_sp->GetOpaqueQualType() == m_opaque_sp->GetOpaqueQualType());
74 }
75 
76 bool
77 SBType::operator != (SBType &rhs)
78 {
79     if (IsValid() == false)
80         return rhs.IsValid();
81 
82     return  (rhs.m_opaque_sp->GetASTContext() != m_opaque_sp->GetASTContext()) ||
83             (rhs.m_opaque_sp->GetOpaqueQualType() != m_opaque_sp->GetOpaqueQualType());
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 size_t
140 SBType::GetByteSize()
141 {
142     if (!IsValid())
143         return 0;
144 
145     return ClangASTType::GetTypeByteSize(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
146 
147 }
148 
149 bool
150 SBType::IsPointerType()
151 {
152     if (!IsValid())
153         return false;
154 
155     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
156     const clang::Type* typePtr = qt.getTypePtrOrNull();
157 
158     if (typePtr)
159         return typePtr->isAnyPointerType();
160     return false;
161 }
162 
163 bool
164 SBType::IsReferenceType()
165 {
166     if (!IsValid())
167         return false;
168 
169     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
170     const clang::Type* typePtr = qt.getTypePtrOrNull();
171 
172     if (typePtr)
173         return typePtr->isReferenceType();
174     return false;
175 }
176 
177 SBType
178 SBType::GetPointerType()
179 {
180     if (!IsValid())
181         return SBType();
182 
183     return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
184                                ClangASTContext::CreatePointerType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType())));
185 }
186 
187 SBType
188 SBType::GetPointeeType()
189 {
190     if (!IsValid())
191         return SBType();
192 
193     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
194     const clang::Type* typePtr = qt.getTypePtrOrNull();
195 
196     if (typePtr)
197         return SBType(ClangASTType(m_opaque_sp->GetASTContext(),typePtr->getPointeeType().getAsOpaquePtr()));
198     return SBType();
199 }
200 
201 SBType
202 SBType::GetReferenceType()
203 {
204     if (!IsValid())
205         return SBType();
206 
207     return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
208                                ClangASTContext::CreateLValueReferenceType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType())));
209 }
210 
211 SBType
212 SBType::GetDereferencedType()
213 {
214     if (!IsValid())
215         return SBType();
216 
217     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
218 
219     return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getNonReferenceType().getAsOpaquePtr()));
220 }
221 
222 lldb::SBType
223 SBType::GetUnqualifiedType()
224 {
225     if (!IsValid())
226         return SBType();
227 
228     QualType qt (QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()));
229     return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getUnqualifiedType().getAsOpaquePtr()));
230 }
231 
232 lldb::BasicType
233 SBType::GetBasicType()
234 {
235     if (IsValid())
236         return ClangASTContext::GetLLDBBasicTypeEnumeration (m_opaque_sp->GetOpaqueQualType());
237     return eBasicTypeInvalid;
238 }
239 
240 SBType
241 SBType::GetBasicType(lldb::BasicType type)
242 {
243     if (!IsValid())
244         return SBType();
245 
246     clang::QualType base_type_qual;
247 
248     switch (type)
249     {
250         case eBasicTypeVoid:
251             base_type_qual = m_opaque_sp->GetASTContext()->VoidTy;
252             break;
253         case eBasicTypeChar:
254             base_type_qual = m_opaque_sp->GetASTContext()->CharTy;
255             break;
256         case eBasicTypeSignedChar:
257             base_type_qual = m_opaque_sp->GetASTContext()->SignedCharTy;
258             break;
259         case eBasicTypeUnsignedChar:
260             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedCharTy;
261             break;
262         case eBasicTypeWChar:
263             base_type_qual = m_opaque_sp->GetASTContext()->getWCharType();
264             break;
265         case eBasicTypeSignedWChar:
266             base_type_qual = m_opaque_sp->GetASTContext()->getSignedWCharType();
267             break;
268         case eBasicTypeUnsignedWChar:
269             base_type_qual = m_opaque_sp->GetASTContext()->getUnsignedWCharType();
270             break;
271         case eBasicTypeChar16:
272             base_type_qual = m_opaque_sp->GetASTContext()->Char16Ty;
273             break;
274         case eBasicTypeChar32:
275             base_type_qual = m_opaque_sp->GetASTContext()->Char32Ty;
276             break;
277         case eBasicTypeShort:
278             base_type_qual = m_opaque_sp->GetASTContext()->ShortTy;
279             break;
280         case eBasicTypeUnsignedShort:
281             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedShortTy;
282             break;
283         case eBasicTypeInt:
284             base_type_qual = m_opaque_sp->GetASTContext()->IntTy;
285             break;
286         case eBasicTypeUnsignedInt:
287             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedIntTy;
288             break;
289         case eBasicTypeLong:
290             base_type_qual = m_opaque_sp->GetASTContext()->LongTy;
291             break;
292         case eBasicTypeUnsignedLong:
293             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongTy;
294             break;
295         case eBasicTypeLongLong:
296             base_type_qual = m_opaque_sp->GetASTContext()->LongLongTy;
297             break;
298         case eBasicTypeUnsignedLongLong:
299             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongLongTy;
300             break;
301         case eBasicTypeInt128:
302             base_type_qual = m_opaque_sp->GetASTContext()->Int128Ty;
303             break;
304         case eBasicTypeUnsignedInt128:
305             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedInt128Ty;
306             break;
307         case eBasicTypeBool:
308             base_type_qual = m_opaque_sp->GetASTContext()->BoolTy;
309             break;
310         case eBasicTypeHalf:
311             base_type_qual = m_opaque_sp->GetASTContext()->HalfTy;
312             break;
313         case eBasicTypeFloat:
314             base_type_qual = m_opaque_sp->GetASTContext()->FloatTy;
315             break;
316         case eBasicTypeDouble:
317             base_type_qual = m_opaque_sp->GetASTContext()->DoubleTy;
318             break;
319         case eBasicTypeLongDouble:
320             base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleTy;
321             break;
322         case eBasicTypeFloatComplex:
323             base_type_qual = m_opaque_sp->GetASTContext()->FloatComplexTy;
324             break;
325         case eBasicTypeDoubleComplex:
326             base_type_qual = m_opaque_sp->GetASTContext()->DoubleComplexTy;
327             break;
328         case eBasicTypeLongDoubleComplex:
329             base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleComplexTy;
330             break;
331         case eBasicTypeObjCID:
332             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinIdTy;
333             break;
334         case eBasicTypeObjCClass:
335             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinClassTy;
336             break;
337         case eBasicTypeObjCSel:
338             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinSelTy;
339             break;
340         case eBasicTypeNullPtr:
341             base_type_qual = m_opaque_sp->GetASTContext()->NullPtrTy;
342             break;
343         default:
344             return SBType();
345     }
346 
347     return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr()));
348 }
349 
350 uint32_t
351 SBType::GetNumberOfDirectBaseClasses ()
352 {
353     if (IsValid())
354         return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
355     return 0;
356 }
357 
358 uint32_t
359 SBType::GetNumberOfVirtualBaseClasses ()
360 {
361     if (IsValid())
362         return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
363     return 0;
364 }
365 
366 uint32_t
367 SBType::GetNumberOfFields ()
368 {
369     if (IsValid())
370         return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
371     return 0;
372 }
373 
374 bool
375 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level)
376 {
377     Stream &strm = description.ref();
378 
379     if (m_opaque_sp)
380     {
381         m_opaque_sp->GetDescription (strm, description_level);
382     }
383     else
384         strm.PutCString ("No value");
385 
386     return true;
387 }
388 
389 
390 
391 SBTypeMember
392 SBType::GetDirectBaseClassAtIndex (uint32_t idx)
393 {
394     SBTypeMember sb_type_member;
395     if (IsValid())
396     {
397         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
398         uint32_t bit_offset = 0;
399         clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset);
400         if (clang_type)
401         {
402             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
403             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset));
404         }
405     }
406     return sb_type_member;
407 
408 }
409 
410 SBTypeMember
411 SBType::GetVirtualBaseClassAtIndex (uint32_t idx)
412 {
413     SBTypeMember sb_type_member;
414     if (IsValid())
415     {
416         uint32_t bit_offset = 0;
417         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
418         clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset);
419         if (clang_type)
420         {
421             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
422             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset));
423         }
424     }
425     return sb_type_member;
426 }
427 
428 SBTypeMember
429 SBType::GetFieldAtIndex (uint32_t idx)
430 {
431     SBTypeMember sb_type_member;
432     if (IsValid())
433     {
434         uint64_t bit_offset = 0;
435         uint32_t bitfield_bit_size = 0;
436         bool is_bitfield = false;
437         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
438         std::string name_sstr;
439         clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &bit_offset, &bitfield_bit_size, &is_bitfield);
440         if (clang_type)
441         {
442             ConstString name;
443             if (!name_sstr.empty())
444                 name.SetCString(name_sstr.c_str());
445             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
446             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset, name, bitfield_bit_size, is_bitfield));
447         }
448     }
449     return sb_type_member;
450 }
451 
452 bool
453 SBType::IsTypeComplete()
454 {
455     if (!IsValid())
456         return false;
457 
458     return ClangASTContext::IsCompleteType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
459 }
460 
461 const char*
462 SBType::GetName()
463 {
464     if (!IsValid())
465         return "";
466 
467     return ClangASTType::GetConstTypeName(m_opaque_sp->GetASTContext(),
468                                           m_opaque_sp->GetOpaqueQualType()).GetCString();
469 }
470 
471 lldb::TypeClass
472 SBType::GetTypeClass ()
473 {
474     if (IsValid())
475         return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(),
476                                            m_opaque_sp->GetOpaqueQualType());
477     return lldb::eTypeClassInvalid;
478 }
479 
480 uint32_t
481 SBType::GetNumberOfTemplateArguments ()
482 {
483     if (IsValid())
484     {
485         return ClangASTContext::GetNumTemplateArguments (m_opaque_sp->GetASTContext(),
486                                                          m_opaque_sp->GetOpaqueQualType());
487     }
488     return 0;
489 }
490 
491 lldb::SBType
492 SBType::GetTemplateArgumentType (uint32_t idx)
493 {
494     if (IsValid())
495     {
496         TemplateArgumentKind kind = eTemplateArgumentKindNull;
497         return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
498                                    ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(),
499                                                                         m_opaque_sp->GetOpaqueQualType(),
500                                                                         idx,
501                                                                         kind)));
502     }
503     return SBType();
504 }
505 
506 
507 lldb::TemplateArgumentKind
508 SBType::GetTemplateArgumentKind (uint32_t idx)
509 {
510     TemplateArgumentKind kind = eTemplateArgumentKindNull;
511     if (IsValid())
512     {
513         ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(),
514                                              m_opaque_sp->GetOpaqueQualType(),
515                                              idx,
516                                              kind);
517     }
518     return kind;
519 }
520 
521 
522 
523 
524 SBTypeList::SBTypeList() :
525     m_opaque_ap(new TypeListImpl())
526 {
527 }
528 
529 SBTypeList::SBTypeList(const SBTypeList& rhs) :
530     m_opaque_ap(new TypeListImpl())
531 {
532     for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
533         Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
534 }
535 
536 bool
537 SBTypeList::IsValid ()
538 {
539     return (m_opaque_ap.get() != NULL);
540 }
541 
542 SBTypeList&
543 SBTypeList::operator = (const SBTypeList& rhs)
544 {
545     if (this != &rhs)
546     {
547         m_opaque_ap.reset (new TypeListImpl());
548         for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
549             Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
550     }
551     return *this;
552 }
553 
554 void
555 SBTypeList::Append (SBType type)
556 {
557     if (type.IsValid())
558         m_opaque_ap->Append (type.m_opaque_sp);
559 }
560 
561 SBType
562 SBTypeList::GetTypeAtIndex(uint32_t index)
563 {
564     if (m_opaque_ap.get())
565         return SBType(m_opaque_ap->GetTypeAtIndex(index));
566     return SBType();
567 }
568 
569 uint32_t
570 SBTypeList::GetSize()
571 {
572     return m_opaque_ap->GetSize();
573 }
574 
575 SBTypeList::~SBTypeList()
576 {
577 }
578 
579 bool
580 SBType::IsPointerType (void *opaque_type)
581 {
582     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
583 
584     bool ret_value = ClangASTContext::IsPointerType (opaque_type);
585 
586     if (log)
587         log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false"));
588 
589     return ret_value;
590 }
591 
592 
593 SBTypeMember::SBTypeMember() :
594     m_opaque_ap()
595 {
596 }
597 
598 SBTypeMember::~SBTypeMember()
599 {
600 }
601 
602 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) :
603     m_opaque_ap()
604 {
605     if (this != &rhs)
606     {
607         if (rhs.IsValid())
608             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
609     }
610 }
611 
612 lldb::SBTypeMember&
613 SBTypeMember::operator = (const lldb::SBTypeMember& rhs)
614 {
615     if (this != &rhs)
616     {
617         if (rhs.IsValid())
618             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
619     }
620     return *this;
621 }
622 
623 bool
624 SBTypeMember::IsValid() const
625 {
626     return m_opaque_ap.get();
627 }
628 
629 const char *
630 SBTypeMember::GetName ()
631 {
632     if (m_opaque_ap.get())
633         return m_opaque_ap->GetName().GetCString();
634     return NULL;
635 }
636 
637 SBType
638 SBTypeMember::GetType ()
639 {
640     SBType sb_type;
641     if (m_opaque_ap.get())
642     {
643         sb_type.SetSP (m_opaque_ap->GetTypeImpl());
644     }
645     return sb_type;
646 
647 }
648 
649 uint64_t
650 SBTypeMember::GetOffsetInBytes()
651 {
652     if (m_opaque_ap.get())
653         return m_opaque_ap->GetBitOffset() / 8u;
654     return 0;
655 }
656 
657 uint64_t
658 SBTypeMember::GetOffsetInBits()
659 {
660     if (m_opaque_ap.get())
661         return m_opaque_ap->GetBitOffset();
662     return 0;
663 }
664 
665 bool
666 SBTypeMember::IsBitfield()
667 {
668     if (m_opaque_ap.get())
669         return m_opaque_ap->GetIsBitfield();
670     return false;
671 }
672 
673 uint32_t
674 SBTypeMember::GetBitfieldSizeInBits()
675 {
676     if (m_opaque_ap.get())
677         return m_opaque_ap->GetBitfieldBitSize();
678     return 0;
679 }
680 
681 
682 bool
683 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level)
684 {
685     Stream &strm = description.ref();
686 
687     if (m_opaque_ap.get())
688     {
689         const uint32_t bit_offset = m_opaque_ap->GetBitOffset();
690         const uint32_t byte_offset = bit_offset / 8u;
691         const uint32_t byte_bit_offset = bit_offset % 8u;
692         const char *name = m_opaque_ap->GetName().GetCString();
693         if (byte_bit_offset)
694             strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset);
695         else
696             strm.Printf ("+%u: (", byte_offset);
697 
698         TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl());
699         if (type_impl_sp)
700             type_impl_sp->GetDescription(strm, description_level);
701 
702         strm.Printf (") %s", name);
703         if (m_opaque_ap->GetIsBitfield())
704         {
705             const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize();
706             strm.Printf (" : %u", bitfield_bit_size);
707         }
708     }
709     else
710     {
711         strm.PutCString ("No value");
712     }
713     return true;
714 }
715 
716 
717 void
718 SBTypeMember::reset(TypeMemberImpl *type_member_impl)
719 {
720     m_opaque_ap.reset(type_member_impl);
721 }
722 
723 TypeMemberImpl &
724 SBTypeMember::ref ()
725 {
726     if (m_opaque_ap.get() == NULL)
727         m_opaque_ap.reset (new TypeMemberImpl());
728     return *m_opaque_ap.get();
729 }
730 
731 const TypeMemberImpl &
732 SBTypeMember::ref () const
733 {
734     return *m_opaque_ap.get();
735 }
736