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 
233 SBType
234 SBType::GetBasicType(lldb::BasicType type)
235 {
236 
237     if (!IsValid())
238         return SBType();
239 
240     clang::CanQualType base_type_qual;
241 
242     switch (type)
243     {
244         case eBasicTypeChar:
245             base_type_qual = m_opaque_sp->GetASTContext()->CharTy;
246             break;
247         case eBasicTypeSignedChar:
248             base_type_qual = m_opaque_sp->GetASTContext()->SignedCharTy;
249             break;
250         case eBasicTypeShort:
251             base_type_qual = m_opaque_sp->GetASTContext()->ShortTy;
252             break;
253         case eBasicTypeUnsignedShort:
254             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedShortTy;
255             break;
256         case eBasicTypeInt:
257             base_type_qual = m_opaque_sp->GetASTContext()->IntTy;
258             break;
259         case eBasicTypeUnsignedInt:
260             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedIntTy;
261             break;
262         case eBasicTypeLong:
263             base_type_qual = m_opaque_sp->GetASTContext()->LongTy;
264             break;
265         case eBasicTypeUnsignedLong:
266             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongTy;
267             break;
268         case eBasicTypeBool:
269             base_type_qual = m_opaque_sp->GetASTContext()->BoolTy;
270             break;
271         case eBasicTypeFloat:
272             base_type_qual = m_opaque_sp->GetASTContext()->FloatTy;
273             break;
274         case eBasicTypeDouble:
275             base_type_qual = m_opaque_sp->GetASTContext()->DoubleTy;
276             break;
277         case eBasicTypeObjCID:
278             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinIdTy;
279             break;
280         case eBasicTypeVoid:
281             base_type_qual = m_opaque_sp->GetASTContext()->VoidTy;
282             break;
283         case eBasicTypeWChar:
284             base_type_qual = m_opaque_sp->GetASTContext()->WCharTy;
285             break;
286         case eBasicTypeChar16:
287             base_type_qual = m_opaque_sp->GetASTContext()->Char16Ty;
288             break;
289         case eBasicTypeChar32:
290             base_type_qual = m_opaque_sp->GetASTContext()->Char32Ty;
291             break;
292         case eBasicTypeLongLong:
293             base_type_qual = m_opaque_sp->GetASTContext()->LongLongTy;
294             break;
295         case eBasicTypeUnsignedLongLong:
296             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongLongTy;
297             break;
298         case eBasicTypeInt128:
299             base_type_qual = m_opaque_sp->GetASTContext()->Int128Ty;
300             break;
301         case eBasicTypeUnsignedInt128:
302             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedInt128Ty;
303             break;
304         case eBasicTypeLongDouble:
305             base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleTy;
306             break;
307         case eBasicTypeFloatComplex:
308             base_type_qual = m_opaque_sp->GetASTContext()->FloatComplexTy;
309             break;
310         case eBasicTypeDoubleComplex:
311             base_type_qual = m_opaque_sp->GetASTContext()->DoubleComplexTy;
312             break;
313         case eBasicTypeLongDoubleComplex:
314             base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleComplexTy;
315             break;
316         case eBasicTypeObjCClass:
317             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinClassTy;
318             break;
319         case eBasicTypeObjCSel:
320             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinSelTy;
321             break;
322         default:
323             return SBType();
324     }
325 
326     return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr()));
327 }
328 
329 uint32_t
330 SBType::GetNumberOfDirectBaseClasses ()
331 {
332     if (IsValid())
333         return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
334     return 0;
335 }
336 
337 uint32_t
338 SBType::GetNumberOfVirtualBaseClasses ()
339 {
340     if (IsValid())
341         return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
342     return 0;
343 }
344 
345 uint32_t
346 SBType::GetNumberOfFields ()
347 {
348     if (IsValid())
349         return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
350     return 0;
351 }
352 
353 bool
354 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level)
355 {
356     Stream &strm = description.ref();
357 
358     if (m_opaque_sp)
359     {
360         m_opaque_sp->GetDescription (strm, description_level);
361     }
362     else
363         strm.PutCString ("No value");
364 
365     return true;
366 }
367 
368 
369 
370 SBTypeMember
371 SBType::GetDirectBaseClassAtIndex (uint32_t idx)
372 {
373     SBTypeMember sb_type_member;
374     if (IsValid())
375     {
376         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
377         uint32_t bit_offset = 0;
378         clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset);
379         if (clang_type)
380         {
381             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
382             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset));
383         }
384     }
385     return sb_type_member;
386 
387 }
388 
389 SBTypeMember
390 SBType::GetVirtualBaseClassAtIndex (uint32_t idx)
391 {
392     SBTypeMember sb_type_member;
393     if (IsValid())
394     {
395         uint32_t bit_offset = 0;
396         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
397         clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset);
398         if (clang_type)
399         {
400             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
401             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset));
402         }
403     }
404     return sb_type_member;
405 }
406 
407 SBTypeMember
408 SBType::GetFieldAtIndex (uint32_t idx)
409 {
410     SBTypeMember sb_type_member;
411     if (IsValid())
412     {
413         uint64_t bit_offset = 0;
414         uint32_t bitfield_bit_size = 0;
415         bool is_bitfield = false;
416         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
417         std::string name_sstr;
418         clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &bit_offset, &bitfield_bit_size, &is_bitfield);
419         if (clang_type)
420         {
421             ConstString name;
422             if (!name_sstr.empty())
423                 name.SetCString(name_sstr.c_str());
424             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
425             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset, name, bitfield_bit_size, is_bitfield));
426         }
427     }
428     return sb_type_member;
429 }
430 
431 bool
432 SBType::IsTypeComplete()
433 {
434     if (!IsValid())
435         return false;
436 
437     return ClangASTContext::IsCompleteType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
438 }
439 
440 const char*
441 SBType::GetName()
442 {
443     if (!IsValid())
444         return "";
445 
446     return ClangASTType::GetConstTypeName(m_opaque_sp->GetASTContext(),
447                                           m_opaque_sp->GetOpaqueQualType()).GetCString();
448 }
449 
450 lldb::TypeClass
451 SBType::GetTypeClass ()
452 {
453     if (IsValid())
454         return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(),
455                                            m_opaque_sp->GetOpaqueQualType());
456     return lldb::eTypeClassInvalid;
457 }
458 
459 uint32_t
460 SBType::GetNumberOfTemplateArguments ()
461 {
462     if (IsValid())
463     {
464         return ClangASTContext::GetNumTemplateArguments (m_opaque_sp->GetASTContext(),
465                                                          m_opaque_sp->GetOpaqueQualType());
466     }
467     return 0;
468 }
469 
470 lldb::SBType
471 SBType::GetTemplateArgumentType (uint32_t idx)
472 {
473     if (IsValid())
474     {
475         TemplateArgumentKind kind = eTemplateArgumentKindNull;
476         return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
477                                    ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(),
478                                                                         m_opaque_sp->GetOpaqueQualType(),
479                                                                         idx,
480                                                                         kind)));
481     }
482     return SBType();
483 }
484 
485 
486 lldb::TemplateArgumentKind
487 SBType::GetTemplateArgumentKind (uint32_t idx)
488 {
489     TemplateArgumentKind kind = eTemplateArgumentKindNull;
490     if (IsValid())
491     {
492         ClangASTContext::GetTemplateArgument(m_opaque_sp->GetASTContext(),
493                                              m_opaque_sp->GetOpaqueQualType(),
494                                              idx,
495                                              kind);
496     }
497     return kind;
498 }
499 
500 
501 
502 
503 SBTypeList::SBTypeList() :
504     m_opaque_ap(new TypeListImpl())
505 {
506 }
507 
508 SBTypeList::SBTypeList(const SBTypeList& rhs) :
509     m_opaque_ap(new TypeListImpl())
510 {
511     for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
512         Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
513 }
514 
515 bool
516 SBTypeList::IsValid ()
517 {
518     return (m_opaque_ap.get() != NULL);
519 }
520 
521 SBTypeList&
522 SBTypeList::operator = (const SBTypeList& rhs)
523 {
524     if (this != &rhs)
525     {
526         m_opaque_ap.reset (new TypeListImpl());
527         for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
528             Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
529     }
530     return *this;
531 }
532 
533 void
534 SBTypeList::Append (SBType type)
535 {
536     if (type.IsValid())
537         m_opaque_ap->Append (type.m_opaque_sp);
538 }
539 
540 SBType
541 SBTypeList::GetTypeAtIndex(uint32_t index)
542 {
543     if (m_opaque_ap.get())
544         return SBType(m_opaque_ap->GetTypeAtIndex(index));
545     return SBType();
546 }
547 
548 uint32_t
549 SBTypeList::GetSize()
550 {
551     return m_opaque_ap->GetSize();
552 }
553 
554 SBTypeList::~SBTypeList()
555 {
556 }
557 
558 bool
559 SBType::IsPointerType (void *opaque_type)
560 {
561     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
562 
563     bool ret_value = ClangASTContext::IsPointerType (opaque_type);
564 
565     if (log)
566         log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false"));
567 
568     return ret_value;
569 }
570 
571 
572 SBTypeMember::SBTypeMember() :
573     m_opaque_ap()
574 {
575 }
576 
577 SBTypeMember::~SBTypeMember()
578 {
579 }
580 
581 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) :
582     m_opaque_ap()
583 {
584     if (this != &rhs)
585     {
586         if (rhs.IsValid())
587             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
588     }
589 }
590 
591 lldb::SBTypeMember&
592 SBTypeMember::operator = (const lldb::SBTypeMember& rhs)
593 {
594     if (this != &rhs)
595     {
596         if (rhs.IsValid())
597             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
598     }
599     return *this;
600 }
601 
602 bool
603 SBTypeMember::IsValid() const
604 {
605     return m_opaque_ap.get();
606 }
607 
608 const char *
609 SBTypeMember::GetName ()
610 {
611     if (m_opaque_ap.get())
612         return m_opaque_ap->GetName().GetCString();
613     return NULL;
614 }
615 
616 SBType
617 SBTypeMember::GetType ()
618 {
619     SBType sb_type;
620     if (m_opaque_ap.get())
621     {
622         sb_type.SetSP (m_opaque_ap->GetTypeImpl());
623     }
624     return sb_type;
625 
626 }
627 
628 uint64_t
629 SBTypeMember::GetOffsetInBytes()
630 {
631     if (m_opaque_ap.get())
632         return m_opaque_ap->GetBitOffset() / 8u;
633     return 0;
634 }
635 
636 uint64_t
637 SBTypeMember::GetOffsetInBits()
638 {
639     if (m_opaque_ap.get())
640         return m_opaque_ap->GetBitOffset();
641     return 0;
642 }
643 
644 bool
645 SBTypeMember::IsBitfield()
646 {
647     if (m_opaque_ap.get())
648         return m_opaque_ap->GetIsBitfield();
649     return false;
650 }
651 
652 uint32_t
653 SBTypeMember::GetBitfieldSizeInBits()
654 {
655     if (m_opaque_ap.get())
656         return m_opaque_ap->GetBitfieldBitSize();
657     return 0;
658 }
659 
660 
661 bool
662 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level)
663 {
664     Stream &strm = description.ref();
665 
666     if (m_opaque_ap.get())
667     {
668         const uint32_t bit_offset = m_opaque_ap->GetBitOffset();
669         const uint32_t byte_offset = bit_offset / 8u;
670         const uint32_t byte_bit_offset = bit_offset % 8u;
671         const char *name = m_opaque_ap->GetName().GetCString();
672         if (byte_bit_offset)
673             strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset);
674         else
675             strm.Printf ("+%u: (", byte_offset);
676 
677         TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl());
678         if (type_impl_sp)
679             type_impl_sp->GetDescription(strm, description_level);
680 
681         strm.Printf (") %s", name);
682         if (m_opaque_ap->GetIsBitfield())
683         {
684             const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize();
685             strm.Printf (" : %u", bitfield_bit_size);
686         }
687     }
688     else
689     {
690         strm.PutCString ("No value");
691     }
692     return true;
693 }
694 
695 
696 void
697 SBTypeMember::reset(TypeMemberImpl *type_member_impl)
698 {
699     m_opaque_ap.reset(type_member_impl);
700 }
701 
702 TypeMemberImpl &
703 SBTypeMember::ref ()
704 {
705     if (m_opaque_ap.get() == NULL)
706         m_opaque_ap.reset (new TypeMemberImpl());
707     return *m_opaque_ap.get();
708 }
709 
710 const TypeMemberImpl &
711 SBTypeMember::ref () const
712 {
713     return *m_opaque_ap.get();
714 }
715