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 SBType
215 SBType::GetBasicType(lldb::BasicType type)
216 {
217 
218     if (!IsValid())
219         return SBType();
220 
221     clang::CanQualType base_type_qual;
222 
223     switch (type)
224     {
225         case eBasicTypeChar:
226             base_type_qual = m_opaque_sp->GetASTContext()->CharTy;
227             break;
228         case eBasicTypeSignedChar:
229             base_type_qual = m_opaque_sp->GetASTContext()->SignedCharTy;
230             break;
231         case eBasicTypeShort:
232             base_type_qual = m_opaque_sp->GetASTContext()->ShortTy;
233             break;
234         case eBasicTypeUnsignedShort:
235             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedShortTy;
236             break;
237         case eBasicTypeInt:
238             base_type_qual = m_opaque_sp->GetASTContext()->IntTy;
239             break;
240         case eBasicTypeUnsignedInt:
241             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedIntTy;
242             break;
243         case eBasicTypeLong:
244             base_type_qual = m_opaque_sp->GetASTContext()->LongTy;
245             break;
246         case eBasicTypeUnsignedLong:
247             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongTy;
248             break;
249         case eBasicTypeBool:
250             base_type_qual = m_opaque_sp->GetASTContext()->BoolTy;
251             break;
252         case eBasicTypeFloat:
253             base_type_qual = m_opaque_sp->GetASTContext()->FloatTy;
254             break;
255         case eBasicTypeDouble:
256             base_type_qual = m_opaque_sp->GetASTContext()->DoubleTy;
257             break;
258         case eBasicTypeObjCID:
259             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinIdTy;
260             break;
261         case eBasicTypeVoid:
262             base_type_qual = m_opaque_sp->GetASTContext()->VoidTy;
263             break;
264         case eBasicTypeWChar:
265             base_type_qual = m_opaque_sp->GetASTContext()->WCharTy;
266             break;
267         case eBasicTypeChar16:
268             base_type_qual = m_opaque_sp->GetASTContext()->Char16Ty;
269             break;
270         case eBasicTypeChar32:
271             base_type_qual = m_opaque_sp->GetASTContext()->Char32Ty;
272             break;
273         case eBasicTypeLongLong:
274             base_type_qual = m_opaque_sp->GetASTContext()->LongLongTy;
275             break;
276         case eBasicTypeUnsignedLongLong:
277             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongLongTy;
278             break;
279         case eBasicTypeInt128:
280             base_type_qual = m_opaque_sp->GetASTContext()->Int128Ty;
281             break;
282         case eBasicTypeUnsignedInt128:
283             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedInt128Ty;
284             break;
285         case eBasicTypeLongDouble:
286             base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleTy;
287             break;
288         case eBasicTypeFloatComplex:
289             base_type_qual = m_opaque_sp->GetASTContext()->FloatComplexTy;
290             break;
291         case eBasicTypeDoubleComplex:
292             base_type_qual = m_opaque_sp->GetASTContext()->DoubleComplexTy;
293             break;
294         case eBasicTypeLongDoubleComplex:
295             base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleComplexTy;
296             break;
297         case eBasicTypeObjCClass:
298             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinClassTy;
299             break;
300         case eBasicTypeObjCSel:
301             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinSelTy;
302             break;
303         default:
304             return SBType();
305     }
306 
307     return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr()));
308 }
309 
310 uint32_t
311 SBType::GetNumberOfDirectBaseClasses ()
312 {
313     if (IsValid())
314         return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
315     return 0;
316 }
317 
318 uint32_t
319 SBType::GetNumberOfVirtualBaseClasses ()
320 {
321     if (IsValid())
322         return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
323     return 0;
324 }
325 
326 uint32_t
327 SBType::GetNumberOfFields ()
328 {
329     if (IsValid())
330         return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
331     return 0;
332 }
333 
334 SBTypeMember
335 SBType::GetDirectBaseClassAtIndex (uint32_t idx)
336 {
337     SBTypeMember sb_type_member;
338     if (IsValid())
339     {
340         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
341         uint32_t byte_offset = 0;
342         clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &byte_offset);
343         if (clang_type)
344         {
345             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
346             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset));
347         }
348     }
349     return sb_type_member;
350 
351 }
352 
353 SBTypeMember
354 SBType::GetVirtualBaseClassAtIndex (uint32_t idx)
355 {
356     SBTypeMember sb_type_member;
357     if (IsValid())
358     {
359         uint32_t byte_offset = 0;
360         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
361         clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &byte_offset);
362         if (clang_type)
363         {
364             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
365             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset));
366         }
367     }
368     return sb_type_member;
369 }
370 
371 SBTypeMember
372 SBType::GetFieldAtIndex (uint32_t idx)
373 {
374     SBTypeMember sb_type_member;
375     if (IsValid())
376     {
377         uint32_t byte_offset = 0;
378         clang::ASTContext* ast = m_opaque_sp->GetASTContext();
379         std::string name_sstr;
380         clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &byte_offset);
381         if (clang_type)
382         {
383             ConstString name;
384             if (!name_sstr.empty())
385                 name.SetCString(name_sstr.c_str());
386             TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type)));
387             sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset, name));
388         }
389     }
390     return sb_type_member;
391 }
392 
393 const char*
394 SBType::GetName()
395 {
396     if (!IsValid())
397         return "";
398 
399     return ClangASTType::GetConstTypeName(m_opaque_sp->GetOpaqueQualType()).GetCString();
400 }
401 
402 lldb::TypeClass
403 SBType::GetTypeClass ()
404 {
405     if (IsValid())
406         return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(),
407                                            m_opaque_sp->GetOpaqueQualType());
408     return lldb::eTypeClassInvalid;
409 }
410 
411 SBTypeList::SBTypeList() :
412     m_opaque_ap(new TypeListImpl())
413 {
414 }
415 
416 SBTypeList::SBTypeList(const SBTypeList& rhs) :
417     m_opaque_ap(new TypeListImpl())
418 {
419     for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
420         Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
421 }
422 
423 bool
424 SBTypeList::IsValid ()
425 {
426     return (m_opaque_ap.get() != NULL);
427 }
428 
429 SBTypeList&
430 SBTypeList::operator = (const SBTypeList& rhs)
431 {
432     if (this != &rhs)
433     {
434         m_opaque_ap.reset (new TypeListImpl());
435         for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
436             Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
437     }
438     return *this;
439 }
440 
441 void
442 SBTypeList::Append (SBType type)
443 {
444     if (type.IsValid())
445         m_opaque_ap->Append (type.m_opaque_sp);
446 }
447 
448 SBType
449 SBTypeList::GetTypeAtIndex(uint32_t index)
450 {
451     if (m_opaque_ap.get())
452         return SBType(m_opaque_ap->GetTypeAtIndex(index));
453     return SBType();
454 }
455 
456 uint32_t
457 SBTypeList::GetSize()
458 {
459     return m_opaque_ap->GetSize();
460 }
461 
462 SBTypeList::~SBTypeList()
463 {
464 }
465 
466 bool
467 SBType::IsPointerType (void *opaque_type)
468 {
469     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
470 
471     bool ret_value = ClangASTContext::IsPointerType (opaque_type);
472 
473     if (log)
474         log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false"));
475 
476     return ret_value;
477 }
478 
479 
480 SBTypeMember::SBTypeMember() :
481     m_opaque_ap()
482 {
483 }
484 
485 SBTypeMember::~SBTypeMember()
486 {
487 }
488 
489 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) :
490     m_opaque_ap()
491 {
492     if (this != &rhs)
493     {
494         if (rhs.IsValid())
495             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
496     }
497 }
498 
499 lldb::SBTypeMember&
500 SBTypeMember::operator = (const lldb::SBTypeMember& rhs)
501 {
502     if (this != &rhs)
503     {
504         if (rhs.IsValid())
505             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
506     }
507     return *this;
508 }
509 
510 bool
511 SBTypeMember::IsValid() const
512 {
513     return m_opaque_ap.get();
514 }
515 
516 const char *
517 SBTypeMember::GetName ()
518 {
519     if (m_opaque_ap.get())
520         return m_opaque_ap->GetName().GetCString();
521     return NULL;
522 }
523 
524 SBType
525 SBTypeMember::GetType ()
526 {
527     SBType sb_type;
528     if (m_opaque_ap.get())
529     {
530         sb_type.reset (m_opaque_ap->GetTypeImpl());
531     }
532     return sb_type;
533 
534 }
535 
536 uint64_t
537 SBTypeMember::GetOffsetByteSize()
538 {
539     if (m_opaque_ap.get())
540         return (m_opaque_ap->GetBitOffset() + 7) / 8u;
541     return 0;
542 }
543 
544 void
545 SBTypeMember::reset(TypeMemberImpl *type_member_impl)
546 {
547     m_opaque_ap.reset(type_member_impl);
548 }
549 
550 TypeMemberImpl &
551 SBTypeMember::ref ()
552 {
553     if (m_opaque_ap.get() == NULL)
554         m_opaque_ap.reset (new TypeMemberImpl());
555     return *m_opaque_ap.get();
556 }
557 
558 const TypeMemberImpl &
559 SBTypeMember::ref () const
560 {
561     return *m_opaque_ap.get();
562 }
563 
564