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