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 lldb_private::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 == (const lldb::SBType &rhs) const
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 != (const lldb::SBType &rhs) const
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 
86 const lldb::SBType &
87 SBType::operator = (const lldb::SBType &rhs)
88 {
89     if (*this != rhs)
90     {
91         m_opaque_sp = rhs.m_opaque_sp;
92     }
93     return *this;
94 }
95 
96 SBType::~SBType ()
97 {}
98 
99 lldb_private::TypeImpl &
100 SBType::ref ()
101 {
102     if (m_opaque_sp.get() == NULL)
103         m_opaque_sp.reset (new lldb_private::TypeImpl());
104         return *m_opaque_sp;
105 }
106 
107 const lldb_private::TypeImpl &
108 SBType::ref () const
109 {
110     // "const SBAddress &addr" should already have checked "addr.IsValid()"
111     // prior to calling this function. In case you didn't we will assert
112     // and die to let you know.
113     assert (m_opaque_sp.get());
114     return *m_opaque_sp;
115 }
116 
117 bool
118 SBType::IsValid() const
119 {
120     if (m_opaque_sp.get() == NULL)
121         return false;
122 
123     return m_opaque_sp->IsValid();
124 }
125 
126 size_t
127 SBType::GetByteSize() const
128 {
129     if (!IsValid())
130         return 0;
131 
132     return ClangASTType::GetTypeByteSize(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType());
133 
134 }
135 
136 bool
137 SBType::IsPointerType() const
138 {
139     if (!IsValid())
140         return false;
141 
142     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
143     const clang::Type* typePtr = qt.getTypePtrOrNull();
144 
145     if (typePtr)
146         return typePtr->isAnyPointerType();
147     return false;
148 }
149 
150 bool
151 SBType::IsReferenceType() const
152 {
153     if (!IsValid())
154         return false;
155 
156     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
157     const clang::Type* typePtr = qt.getTypePtrOrNull();
158 
159     if (typePtr)
160         return typePtr->isReferenceType();
161     return false;
162 }
163 
164 SBType
165 SBType::GetPointerType() const
166 {
167     if (!IsValid())
168         return SBType();
169 
170     return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
171                                ClangASTContext::CreatePointerType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType())));
172 }
173 
174 SBType
175 SBType::GetPointeeType() const
176 {
177     if (!IsValid())
178         return SBType();
179 
180     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
181     const clang::Type* typePtr = qt.getTypePtrOrNull();
182 
183     if (typePtr)
184         return SBType(ClangASTType(m_opaque_sp->GetASTContext(),typePtr->getPointeeType().getAsOpaquePtr()));
185     return SBType();
186 }
187 
188 SBType
189 SBType::GetReferenceType() const
190 {
191     if (!IsValid())
192         return SBType();
193 
194     return SBType(ClangASTType(m_opaque_sp->GetASTContext(),
195                                ClangASTContext::CreateLValueReferenceType(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType())));
196 }
197 
198 SBType
199 SBType::GetDereferencedType() const
200 {
201     if (!IsValid())
202         return SBType();
203 
204     QualType qt = QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType());
205 
206     return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getNonReferenceType().getAsOpaquePtr()));
207 }
208 
209 SBType
210 SBType::GetBasicType(lldb::BasicType type) const
211 {
212 
213     if (!IsValid())
214         return SBType();
215 
216     clang::CanQualType base_type_qual;
217 
218     switch (type)
219     {
220         case eBasicTypeChar:
221             base_type_qual = m_opaque_sp->GetASTContext()->CharTy;
222             break;
223         case eBasicTypeSignedChar:
224             base_type_qual = m_opaque_sp->GetASTContext()->SignedCharTy;
225             break;
226         case eBasicTypeShort:
227             base_type_qual = m_opaque_sp->GetASTContext()->ShortTy;
228             break;
229         case eBasicTypeUnsignedShort:
230             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedShortTy;
231             break;
232         case eBasicTypeInt:
233             base_type_qual = m_opaque_sp->GetASTContext()->IntTy;
234             break;
235         case eBasicTypeUnsignedInt:
236             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedIntTy;
237             break;
238         case eBasicTypeLong:
239             base_type_qual = m_opaque_sp->GetASTContext()->LongTy;
240             break;
241         case eBasicTypeUnsignedLong:
242             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongTy;
243             break;
244         case eBasicTypeBool:
245             base_type_qual = m_opaque_sp->GetASTContext()->BoolTy;
246             break;
247         case eBasicTypeFloat:
248             base_type_qual = m_opaque_sp->GetASTContext()->FloatTy;
249             break;
250         case eBasicTypeDouble:
251             base_type_qual = m_opaque_sp->GetASTContext()->DoubleTy;
252             break;
253         case eBasicTypeObjCID:
254             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinIdTy;
255             break;
256         case eBasicTypeVoid:
257             base_type_qual = m_opaque_sp->GetASTContext()->VoidTy;
258             break;
259         case eBasicTypeWChar:
260             base_type_qual = m_opaque_sp->GetASTContext()->WCharTy;
261             break;
262         case eBasicTypeChar16:
263             base_type_qual = m_opaque_sp->GetASTContext()->Char16Ty;
264             break;
265         case eBasicTypeChar32:
266             base_type_qual = m_opaque_sp->GetASTContext()->Char32Ty;
267             break;
268         case eBasicTypeLongLong:
269             base_type_qual = m_opaque_sp->GetASTContext()->LongLongTy;
270             break;
271         case eBasicTypeUnsignedLongLong:
272             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongLongTy;
273             break;
274         case eBasicTypeInt128:
275             base_type_qual = m_opaque_sp->GetASTContext()->Int128Ty;
276             break;
277         case eBasicTypeUnsignedInt128:
278             base_type_qual = m_opaque_sp->GetASTContext()->UnsignedInt128Ty;
279             break;
280         case eBasicTypeLongDouble:
281             base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleTy;
282             break;
283         case eBasicTypeFloatComplex:
284             base_type_qual = m_opaque_sp->GetASTContext()->FloatComplexTy;
285             break;
286         case eBasicTypeDoubleComplex:
287             base_type_qual = m_opaque_sp->GetASTContext()->DoubleComplexTy;
288             break;
289         case eBasicTypeLongDoubleComplex:
290             base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleComplexTy;
291             break;
292         case eBasicTypeObjCClass:
293             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinClassTy;
294             break;
295         case eBasicTypeObjCSel:
296             base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinSelTy;
297             break;
298         default:
299             return SBType();
300     }
301 
302     return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr()));
303 }
304 
305 const char*
306 SBType::GetName()
307 {
308     if (!IsValid())
309         return "";
310 
311     return ClangASTType::GetConstTypeName(m_opaque_sp->GetOpaqueQualType()).GetCString();
312 }
313 
314 SBTypeList::SBTypeList() :
315     m_opaque_ap(new TypeListImpl())
316 {
317 }
318 
319 SBTypeList::SBTypeList(const SBTypeList& rhs) :
320     m_opaque_ap(new TypeListImpl())
321 {
322     for (uint32_t i = 0, rhs_size = rhs.GetSize(); i < rhs_size; i++)
323         Append(rhs.GetTypeAtIndex(i));
324 }
325 
326 bool
327 SBTypeList::IsValid () const
328 {
329     return (m_opaque_ap.get() != NULL);
330 }
331 
332 SBTypeList&
333 SBTypeList::operator = (const SBTypeList& rhs)
334 {
335     if (this != &rhs && m_opaque_ap.get() != rhs.m_opaque_ap.get())
336     {
337         m_opaque_ap.reset(new TypeListImpl());
338         for (uint32_t i = 0, rhs_size = rhs.GetSize(); i < rhs_size; i++)
339             Append(rhs.GetTypeAtIndex(i));
340     }
341     return *this;
342 }
343 
344 void
345 SBTypeList::Append (const SBType& type)
346 {
347     if (type.IsValid())
348         m_opaque_ap->Append (type.m_opaque_sp);
349 }
350 
351 SBType
352 SBTypeList::GetTypeAtIndex(int index) const
353 {
354     return SBType(m_opaque_ap->GetTypeAtIndex(index));
355 }
356 
357 int
358 SBTypeList::GetSize() const
359 {
360     return m_opaque_ap->GetSize();
361 }
362 
363 SBTypeList::~SBTypeList()
364 {
365 }
366 
367 bool
368 SBType::IsPointerType (void *opaque_type)
369 {
370     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
371 
372     bool ret_value = ClangASTContext::IsPointerType (opaque_type);
373 
374     if (log)
375         log->Printf ("SBType::IsPointerType (opaque_type=%p) ==> '%s'", opaque_type, (ret_value ? "true" : "false"));
376 
377     return ret_value;
378 }
379