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 void
87 SBType::reset(const lldb::TypeImplSP &type_impl_sp)
88 {
89     m_opaque_sp = type_impl_sp;
90 }
91 
92 SBType &
93 SBType::operator = (const SBType &rhs)
94 {
95     if (this != &rhs)
96     {
97         m_opaque_sp = rhs.m_opaque_sp;
98     }
99     return *this;
100 }
101 
102 SBType::~SBType ()
103 {}
104 
105 TypeImpl &
106 SBType::ref ()
107 {
108     if (m_opaque_sp.get() == NULL)
109         m_opaque_sp.reset (new TypeImpl());
110         return *m_opaque_sp;
111 }
112 
113 const TypeImpl &
114 SBType::ref () const
115 {
116     // "const SBAddress &addr" should already have checked "addr.IsValid()"
117     // prior to calling this function. In case you didn't we will assert
118     // and die to let you know.
119     assert (m_opaque_sp.get());
120     return *m_opaque_sp;
121 }
122 
123 bool
124 SBType::IsValid() const
125 {
126     if (m_opaque_sp.get() == NULL)
127         return false;
128 
129     return m_opaque_sp->IsValid();
130 }
131 
132 size_t
133 SBType::GetByteSize()
134 {
135     if (!IsValid())
136         return 0;
137 
138     return ClangASTType::GetTypeByteSize(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
139 
140 }
141 
142 bool
143 SBType::IsPointerType()
144 {
145     if (!IsValid())
146         return false;
147 
148     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
149     const clang::Type* typePtr = qt.getTypePtrOrNull();
150 
151     if (typePtr)
152         return typePtr->isAnyPointerType();
153     return false;
154 }
155 
156 bool
157 SBType::IsReferenceType()
158 {
159     if (!IsValid())
160         return false;
161 
162     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
163     const clang::Type* typePtr = qt.getTypePtrOrNull();
164 
165     if (typePtr)
166         return typePtr->isReferenceType();
167     return false;
168 }
169 
170 SBType
171 SBType::GetPointerType()
172 {
173     if (!IsValid())
174         return SBType();
175 
176     return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
177                                ClangASTContext::CreatePointerType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType())));
178 }
179 
180 SBType
181 SBType::GetPointeeType()
182 {
183     if (!IsValid())
184         return SBType();
185 
186     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
187     const clang::Type* typePtr = qt.getTypePtrOrNull();
188 
189     if (typePtr)
190         return SBType(ClangASTType(m_opaque_sp->GetASTContext(),typePtr->getPointeeType().getAsOpaquePtr()));
191     return SBType();
192 }
193 
194 SBType
195 SBType::GetReferenceType()
196 {
197     if (!IsValid())
198         return SBType();
199 
200     return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
201                                ClangASTContext::CreateLValueReferenceType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType())));
202 }
203 
204 SBType
205 SBType::GetDereferencedType()
206 {
207     if (!IsValid())
208         return SBType();
209 
210     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
211 
212     return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getNonReferenceType().getAsOpaquePtr()));
213 }
214 
215 lldb::SBType
216 SBType::GetUnqualifiedType()
217 {
218     if (!IsValid())
219         return SBType();
220 
221     QualType qt (QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()));
222     return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getUnqualifiedType().getAsOpaquePtr()));
223 }
224 
225 
226 SBType
227 SBType::GetBasicType(lldb::BasicType type)
228 {
229 
230     if (!IsValid())
231         return SBType();
232 
233     clang::CanQualType base_type_qual;
234 
235     switch (type)
236     {
237         case eBasicTypeChar:
238             base_type_qual = m_opaque_sp->GetASTContext()->CharTy;
239             break;
240         case eBasicTypeSignedChar:
241             base_type_qual = m_opaque_sp->GetASTContext()->SignedCharTy;
242             break;
243         case eBasicTypeShort:
244             base_type_qual = m_opaque_sp->GetASTContext()->ShortTy;
245             break;
246         case eBasicTypeUnsignedShort:
247             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedShortTy;
248             break;
249         case eBasicTypeInt:
250             base_type_qual = m_opaque_sp->GetASTContext()->IntTy;
251             break;
252         case eBasicTypeUnsignedInt:
253             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedIntTy;
254             break;
255         case eBasicTypeLong:
256             base_type_qual = m_opaque_sp->GetASTContext()->LongTy;
257             break;
258         case eBasicTypeUnsignedLong:
259             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongTy;
260             break;
261         case eBasicTypeBool:
262             base_type_qual = m_opaque_sp->GetASTContext()->BoolTy;
263             break;
264         case eBasicTypeFloat:
265             base_type_qual = m_opaque_sp->GetASTContext()->FloatTy;
266             break;
267         case eBasicTypeDouble:
268             base_type_qual = m_opaque_sp->GetASTContext()->DoubleTy;
269             break;
270         case eBasicTypeObjCID:
271             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinIdTy;
272             break;
273         case eBasicTypeVoid:
274             base_type_qual = m_opaque_sp->GetASTContext()->VoidTy;
275             break;
276         case eBasicTypeWChar:
277             base_type_qual = m_opaque_sp->GetASTContext()->WCharTy;
278             break;
279         case eBasicTypeChar16:
280             base_type_qual = m_opaque_sp->GetASTContext()->Char16Ty;
281             break;
282         case eBasicTypeChar32:
283             base_type_qual = m_opaque_sp->GetASTContext()->Char32Ty;
284             break;
285         case eBasicTypeLongLong:
286             base_type_qual = m_opaque_sp->GetASTContext()->LongLongTy;
287             break;
288         case eBasicTypeUnsignedLongLong:
289             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongLongTy;
290             break;
291         case eBasicTypeInt128:
292             base_type_qual = m_opaque_sp->GetASTContext()->Int128Ty;
293             break;
294         case eBasicTypeUnsignedInt128:
295             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedInt128Ty;
296             break;
297         case eBasicTypeLongDouble:
298             base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleTy;
299             break;
300         case eBasicTypeFloatComplex:
301             base_type_qual = m_opaque_sp->GetASTContext()->FloatComplexTy;
302             break;
303         case eBasicTypeDoubleComplex:
304             base_type_qual = m_opaque_sp->GetASTContext()->DoubleComplexTy;
305             break;
306         case eBasicTypeLongDoubleComplex:
307             base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleComplexTy;
308             break;
309         case eBasicTypeObjCClass:
310             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinClassTy;
311             break;
312         case eBasicTypeObjCSel:
313             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinSelTy;
314             break;
315         default:
316             return SBType();
317     }
318 
319     return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr()));
320 }
321 
322 uint32_t
323 SBType::GetNumberOfDirectBaseClasses ()
324 {
325     if (IsValid())
326         return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
327     return 0;
328 }
329 
330 uint32_t
331 SBType::GetNumberOfVirtualBaseClasses ()
332 {
333     if (IsValid())
334         return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
335     return 0;
336 }
337 
338 uint32_t
339 SBType::GetNumberOfFields ()
340 {
341     if (IsValid())
342         return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
343     return 0;
344 }
345 
346 bool
347 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level)
348 {
349     Stream &strm = description.ref();
350 
351     if (m_opaque_sp)
352     {
353         m_opaque_sp->GetDescription (strm, description_level);
354     }
355     else
356         strm.PutCString ("No value");
357 
358     return true;
359 }
360 
361 
362 
363 SBTypeMember
364 SBType::GetDirectBaseClassAtIndex (uint32_t idx)
365 {
366     SBTypeMember sb_type_member;
367     if (IsValid())
368     {
369         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
370         uint32_t bit_offset = 0;
371         clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset);
372         if (clang_type)
373         {
374             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
375             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset));
376         }
377     }
378     return sb_type_member;
379 
380 }
381 
382 SBTypeMember
383 SBType::GetVirtualBaseClassAtIndex (uint32_t idx)
384 {
385     SBTypeMember sb_type_member;
386     if (IsValid())
387     {
388         uint32_t bit_offset = 0;
389         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
390         clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &bit_offset);
391         if (clang_type)
392         {
393             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
394             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset));
395         }
396     }
397     return sb_type_member;
398 }
399 
400 SBTypeMember
401 SBType::GetFieldAtIndex (uint32_t idx)
402 {
403     SBTypeMember sb_type_member;
404     if (IsValid())
405     {
406         uint32_t bit_offset = 0;
407         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
408         std::string name_sstr;
409         clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &bit_offset);
410         if (clang_type)
411         {
412             ConstString name;
413             if (!name_sstr.empty())
414                 name.SetCString(name_sstr.c_str());
415             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
416             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, bit_offset, name));
417         }
418     }
419     return sb_type_member;
420 }
421 
422 const char*
423 SBType::GetName()
424 {
425     if (!IsValid())
426         return "";
427 
428     return ClangASTType::GetConstTypeName(m_opaque_sp->GetOpaqueQualType()).GetCString();
429 }
430 
431 lldb::TypeClass
432 SBType::GetTypeClass ()
433 {
434     if (IsValid())
435         return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(),
436                                            m_opaque_sp->GetOpaqueQualType());
437     return lldb::eTypeClassInvalid;
438 }
439 
440 SBTypeList::SBTypeList() :
441     m_opaque_ap(new TypeListImpl())
442 {
443 }
444 
445 SBTypeList::SBTypeList(const SBTypeList& rhs) :
446     m_opaque_ap(new TypeListImpl())
447 {
448     for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
449         Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
450 }
451 
452 bool
453 SBTypeList::IsValid ()
454 {
455     return (m_opaque_ap.get() != NULL);
456 }
457 
458 SBTypeList&
459 SBTypeList::operator = (const SBTypeList& rhs)
460 {
461     if (this != &rhs)
462     {
463         m_opaque_ap.reset (new TypeListImpl());
464         for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
465             Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
466     }
467     return *this;
468 }
469 
470 void
471 SBTypeList::Append (SBType type)
472 {
473     if (type.IsValid())
474         m_opaque_ap->Append (type.m_opaque_sp);
475 }
476 
477 SBType
478 SBTypeList::GetTypeAtIndex(uint32_t index)
479 {
480     if (m_opaque_ap.get())
481         return SBType(m_opaque_ap->GetTypeAtIndex(index));
482     return SBType();
483 }
484 
485 uint32_t
486 SBTypeList::GetSize()
487 {
488     return m_opaque_ap->GetSize();
489 }
490 
491 SBTypeList::~SBTypeList()
492 {
493 }
494 
495 bool
496 SBType::IsPointerType (void *opaque_type)
497 {
498     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
499 
500     bool ret_value = ClangASTContext::IsPointerType (opaque_type);
501 
502     if (log)
503         log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false"));
504 
505     return ret_value;
506 }
507 
508 
509 SBTypeMember::SBTypeMember() :
510     m_opaque_ap()
511 {
512 }
513 
514 SBTypeMember::~SBTypeMember()
515 {
516 }
517 
518 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) :
519     m_opaque_ap()
520 {
521     if (this != &rhs)
522     {
523         if (rhs.IsValid())
524             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
525     }
526 }
527 
528 lldb::SBTypeMember&
529 SBTypeMember::operator = (const lldb::SBTypeMember& rhs)
530 {
531     if (this != &rhs)
532     {
533         if (rhs.IsValid())
534             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
535     }
536     return *this;
537 }
538 
539 bool
540 SBTypeMember::IsValid() const
541 {
542     return m_opaque_ap.get();
543 }
544 
545 const char *
546 SBTypeMember::GetName ()
547 {
548     if (m_opaque_ap.get())
549         return m_opaque_ap->GetName().GetCString();
550     return NULL;
551 }
552 
553 SBType
554 SBTypeMember::GetType ()
555 {
556     SBType sb_type;
557     if (m_opaque_ap.get())
558     {
559         sb_type.reset (m_opaque_ap->GetTypeImpl());
560     }
561     return sb_type;
562 
563 }
564 
565 uint64_t
566 SBTypeMember::GetOffsetInBytes()
567 {
568     if (m_opaque_ap.get())
569         return (m_opaque_ap->GetBitOffset() + 7) / 8u;
570     return 0;
571 }
572 
573 uint64_t
574 SBTypeMember::GetOffsetInBits()
575 {
576     if (m_opaque_ap.get())
577         return m_opaque_ap->GetBitOffset();
578     return 0;
579 }
580 
581 bool
582 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level)
583 {
584     Stream &strm = description.ref();
585 
586     if (m_opaque_ap.get())
587     {
588         const uint32_t byte_offset = (m_opaque_ap->GetBitOffset() + 7) / 8u;
589         const char *name = m_opaque_ap->GetName().GetCString();
590         strm.Printf ("+%u: (", byte_offset);
591 
592         TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl());
593         if (type_impl_sp)
594             type_impl_sp->GetDescription(strm, description_level);
595 
596         strm.Printf (") %s", name);
597     }
598     else
599     {
600         strm.PutCString ("No value");
601     }
602     return true;
603 }
604 
605 
606 void
607 SBTypeMember::reset(TypeMemberImpl *type_member_impl)
608 {
609     m_opaque_ap.reset(type_member_impl);
610 }
611 
612 TypeMemberImpl &
613 SBTypeMember::ref ()
614 {
615     if (m_opaque_ap.get() == NULL)
616         m_opaque_ap.reset (new TypeMemberImpl());
617     return *m_opaque_ap.get();
618 }
619 
620 const TypeMemberImpl &
621 SBTypeMember::ref () const
622 {
623     return *m_opaque_ap.get();
624 }
625 
626