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 "lldb/API/SBDefines.h"
11 #include "lldb/API/SBType.h"
12 #include "lldb/API/SBStream.h"
13 #include "lldb/Core/ConstString.h"
14 #include "lldb/Core/Log.h"
15 #include "lldb/Core/Stream.h"
16 #include "lldb/Symbol/ClangASTContext.h"
17 #include "lldb/Symbol/ClangASTType.h"
18 #include "lldb/Symbol/Type.h"
19 
20 using namespace lldb;
21 using namespace lldb_private;
22 using namespace clang;
23 
24 SBType::SBType() :
25     m_opaque_sp()
26 {
27 }
28 
29 SBType::SBType (const ClangASTType &type) :
30     m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(),
31                                           type.GetOpaqueQualType())))
32 {
33 }
34 
35 SBType::SBType (const lldb::TypeSP &type_sp) :
36     m_opaque_sp(new TypeImpl(type_sp))
37 {
38 }
39 
40 SBType::SBType (const lldb::TypeImplSP &type_impl_sp) :
41     m_opaque_sp(type_impl_sp)
42 {
43 }
44 
45 
46 SBType::SBType (const SBType &rhs) :
47     m_opaque_sp()
48 {
49     if (this != &rhs)
50     {
51         m_opaque_sp = rhs.m_opaque_sp;
52     }
53 }
54 
55 
56 //SBType::SBType (TypeImpl* impl) :
57 //    m_opaque_ap(impl)
58 //{}
59 //
60 bool
61 SBType::operator == (SBType &rhs)
62 {
63     if (IsValid() == false)
64         return !rhs.IsValid();
65 
66     if (rhs.IsValid() == false)
67         return false;
68 
69     return *m_opaque_sp.get() == *rhs.m_opaque_sp.get();
70 }
71 
72 bool
73 SBType::operator != (SBType &rhs)
74 {
75     if (IsValid() == false)
76         return rhs.IsValid();
77 
78     if (rhs.IsValid() == false)
79         return true;
80 
81     return *m_opaque_sp.get() != *rhs.m_opaque_sp.get();
82 }
83 
84 lldb::TypeImplSP
85 SBType::GetSP ()
86 {
87     return m_opaque_sp;
88 }
89 
90 
91 void
92 SBType::SetSP (const lldb::TypeImplSP &type_impl_sp)
93 {
94     m_opaque_sp = type_impl_sp;
95 }
96 
97 SBType &
98 SBType::operator = (const SBType &rhs)
99 {
100     if (this != &rhs)
101     {
102         m_opaque_sp = rhs.m_opaque_sp;
103     }
104     return *this;
105 }
106 
107 SBType::~SBType ()
108 {}
109 
110 TypeImpl &
111 SBType::ref ()
112 {
113     if (m_opaque_sp.get() == NULL)
114         m_opaque_sp.reset (new TypeImpl());
115         return *m_opaque_sp;
116 }
117 
118 const TypeImpl &
119 SBType::ref () const
120 {
121     // "const SBAddress &addr" should already have checked "addr.IsValid()"
122     // prior to calling this function. In case you didn't we will assert
123     // and die to let you know.
124     assert (m_opaque_sp.get());
125     return *m_opaque_sp;
126 }
127 
128 bool
129 SBType::IsValid() const
130 {
131     if (m_opaque_sp.get() == NULL)
132         return false;
133 
134     return m_opaque_sp->IsValid();
135 }
136 
137 uint64_t
138 SBType::GetByteSize()
139 {
140     if (!IsValid())
141         return 0;
142 
143     return m_opaque_sp->GetClangASTType(false).GetByteSize();
144 
145 }
146 
147 bool
148 SBType::IsPointerType()
149 {
150     if (!IsValid())
151         return false;
152     return m_opaque_sp->GetClangASTType(true).IsPointerType();
153 }
154 
155 bool
156 SBType::IsReferenceType()
157 {
158     if (!IsValid())
159         return false;
160     return m_opaque_sp->GetClangASTType(true).IsReferenceType();
161 }
162 
163 SBType
164 SBType::GetPointerType()
165 {
166     if (!IsValid())
167         return SBType();
168 
169     return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointerType())));
170 }
171 
172 SBType
173 SBType::GetPointeeType()
174 {
175     if (!IsValid())
176         return SBType();
177     return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointeeType())));
178 }
179 
180 SBType
181 SBType::GetReferenceType()
182 {
183     if (!IsValid())
184         return SBType();
185     return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetReferenceType())));
186 }
187 
188 SBType
189 SBType::GetTypedefedType()
190 {
191     if (!IsValid())
192         return SBType();
193     return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetTypedefedType())));
194 }
195 
196 SBType
197 SBType::GetDereferencedType()
198 {
199     if (!IsValid())
200         return SBType();
201     return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetDereferencedType())));
202 }
203 
204 bool
205 SBType::IsFunctionType ()
206 {
207     if (!IsValid())
208         return false;
209     return m_opaque_sp->GetClangASTType(true).IsFunctionType();
210 }
211 
212 bool
213 SBType::IsPolymorphicClass ()
214 {
215     if (!IsValid())
216         return false;
217     return m_opaque_sp->GetClangASTType(true).IsPolymorphicClass();
218 }
219 
220 
221 
222 lldb::SBType
223 SBType::GetFunctionReturnType ()
224 {
225     if (IsValid())
226     {
227         ClangASTType return_clang_type (m_opaque_sp->GetClangASTType(true).GetFunctionReturnType());
228         if (return_clang_type.IsValid())
229             return SBType(return_clang_type);
230     }
231     return lldb::SBType();
232 }
233 
234 lldb::SBTypeList
235 SBType::GetFunctionArgumentTypes ()
236 {
237     SBTypeList sb_type_list;
238     if (IsValid())
239     {
240         ClangASTType func_type(m_opaque_sp->GetClangASTType(true));
241         size_t count = func_type.GetNumberOfFunctionArguments();
242         for (size_t i = 0;
243              i < count;
244              i++)
245         {
246             sb_type_list.Append(SBType(func_type.GetFunctionArgumentAtIndex(i)));
247         }
248     }
249     return sb_type_list;
250 }
251 
252 lldb::SBType
253 SBType::GetUnqualifiedType()
254 {
255     if (!IsValid())
256         return SBType();
257     return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetUnqualifiedType())));
258 }
259 
260 lldb::SBType
261 SBType::GetCanonicalType()
262 {
263     if (IsValid())
264         return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetCanonicalType())));
265     return SBType();
266 }
267 
268 
269 lldb::BasicType
270 SBType::GetBasicType()
271 {
272     if (IsValid())
273         return m_opaque_sp->GetClangASTType(false).GetBasicTypeEnumeration ();
274     return eBasicTypeInvalid;
275 }
276 
277 SBType
278 SBType::GetBasicType(lldb::BasicType basic_type)
279 {
280     if (IsValid())
281         return SBType (ClangASTContext::GetBasicType (m_opaque_sp->GetClangASTContext(false), basic_type));
282     return SBType();
283 }
284 
285 uint32_t
286 SBType::GetNumberOfDirectBaseClasses ()
287 {
288     if (IsValid())
289         return m_opaque_sp->GetClangASTType(true).GetNumDirectBaseClasses();
290     return 0;
291 }
292 
293 uint32_t
294 SBType::GetNumberOfVirtualBaseClasses ()
295 {
296     if (IsValid())
297         return m_opaque_sp->GetClangASTType(true).GetNumVirtualBaseClasses();
298     return 0;
299 }
300 
301 uint32_t
302 SBType::GetNumberOfFields ()
303 {
304     if (IsValid())
305         return m_opaque_sp->GetClangASTType(false).GetNumFields();
306     return 0;
307 }
308 
309 bool
310 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level)
311 {
312     Stream &strm = description.ref();
313 
314     if (m_opaque_sp)
315     {
316         m_opaque_sp->GetDescription (strm, description_level);
317     }
318     else
319         strm.PutCString ("No value");
320 
321     return true;
322 }
323 
324 
325 
326 SBTypeMember
327 SBType::GetDirectBaseClassAtIndex (uint32_t idx)
328 {
329     SBTypeMember sb_type_member;
330     if (IsValid())
331     {
332         ClangASTType this_type (m_opaque_sp->GetClangASTType (true));
333         if (this_type.IsValid())
334         {
335             uint32_t bit_offset = 0;
336             ClangASTType base_class_type (this_type.GetDirectBaseClassAtIndex(idx, &bit_offset));
337             if (base_class_type.IsValid())
338             {
339                 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
340             }
341         }
342     }
343     return sb_type_member;
344 
345 }
346 
347 SBTypeMember
348 SBType::GetVirtualBaseClassAtIndex (uint32_t idx)
349 {
350     SBTypeMember sb_type_member;
351     if (IsValid())
352     {
353         ClangASTType this_type (m_opaque_sp->GetClangASTType (true));
354         if (this_type.IsValid())
355         {
356             uint32_t bit_offset = 0;
357             ClangASTType base_class_type (this_type.GetVirtualBaseClassAtIndex(idx, &bit_offset));
358             if (base_class_type.IsValid())
359             {
360                 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
361             }
362         }
363     }
364     return sb_type_member;
365 }
366 
367 SBTypeMember
368 SBType::GetFieldAtIndex (uint32_t idx)
369 {
370     SBTypeMember sb_type_member;
371     if (IsValid())
372     {
373         ClangASTType this_type (m_opaque_sp->GetClangASTType (false));
374         if (this_type.IsValid())
375         {
376             uint64_t bit_offset = 0;
377             uint32_t bitfield_bit_size = 0;
378             bool is_bitfield = false;
379             std::string name_sstr;
380             ClangASTType field_type (this_type.GetFieldAtIndex (idx,
381                                                                 name_sstr,
382                                                                 &bit_offset,
383                                                                 &bitfield_bit_size,
384                                                                 &is_bitfield));
385             if (field_type.IsValid())
386             {
387                 ConstString name;
388                 if (!name_sstr.empty())
389                     name.SetCString(name_sstr.c_str());
390                 sb_type_member.reset (new TypeMemberImpl (TypeImplSP (new TypeImpl(field_type)),
391                                                           bit_offset,
392                                                           name,
393                                                           bitfield_bit_size,
394                                                           is_bitfield));
395             }
396         }
397     }
398     return sb_type_member;
399 }
400 
401 bool
402 SBType::IsTypeComplete()
403 {
404     if (!IsValid())
405         return false;
406     return m_opaque_sp->GetClangASTType(false).IsCompleteType();
407 }
408 
409 const char*
410 SBType::GetName()
411 {
412     if (!IsValid())
413         return "";
414     return m_opaque_sp->GetName().GetCString();
415 }
416 
417 const char *
418 SBType::GetDisplayTypeName ()
419 {
420     if (!IsValid())
421         return "";
422     return m_opaque_sp->GetDisplayTypeName().GetCString();
423 }
424 
425 lldb::TypeClass
426 SBType::GetTypeClass ()
427 {
428     if (IsValid())
429         return m_opaque_sp->GetClangASTType(false).GetTypeClass();
430     return lldb::eTypeClassInvalid;
431 }
432 
433 uint32_t
434 SBType::GetNumberOfTemplateArguments ()
435 {
436     if (IsValid())
437         return m_opaque_sp->GetClangASTType(false).GetNumTemplateArguments();
438     return 0;
439 }
440 
441 lldb::SBType
442 SBType::GetTemplateArgumentType (uint32_t idx)
443 {
444     if (IsValid())
445     {
446         TemplateArgumentKind kind = eTemplateArgumentKindNull;
447         ClangASTType template_arg_type = m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
448         if (template_arg_type.IsValid())
449             return SBType(template_arg_type);
450     }
451     return SBType();
452 }
453 
454 
455 lldb::TemplateArgumentKind
456 SBType::GetTemplateArgumentKind (uint32_t idx)
457 {
458     TemplateArgumentKind kind = eTemplateArgumentKindNull;
459     if (IsValid())
460         m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
461     return kind;
462 }
463 
464 
465 SBTypeList::SBTypeList() :
466     m_opaque_ap(new TypeListImpl())
467 {
468 }
469 
470 SBTypeList::SBTypeList(const SBTypeList& rhs) :
471     m_opaque_ap(new TypeListImpl())
472 {
473     for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
474         Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
475 }
476 
477 bool
478 SBTypeList::IsValid ()
479 {
480     return (m_opaque_ap.get() != NULL);
481 }
482 
483 SBTypeList&
484 SBTypeList::operator = (const SBTypeList& rhs)
485 {
486     if (this != &rhs)
487     {
488         m_opaque_ap.reset (new TypeListImpl());
489         for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
490             Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
491     }
492     return *this;
493 }
494 
495 void
496 SBTypeList::Append (SBType type)
497 {
498     if (type.IsValid())
499         m_opaque_ap->Append (type.m_opaque_sp);
500 }
501 
502 SBType
503 SBTypeList::GetTypeAtIndex(uint32_t index)
504 {
505     if (m_opaque_ap.get())
506         return SBType(m_opaque_ap->GetTypeAtIndex(index));
507     return SBType();
508 }
509 
510 uint32_t
511 SBTypeList::GetSize()
512 {
513     return m_opaque_ap->GetSize();
514 }
515 
516 SBTypeList::~SBTypeList()
517 {
518 }
519 
520 SBTypeMember::SBTypeMember() :
521     m_opaque_ap()
522 {
523 }
524 
525 SBTypeMember::~SBTypeMember()
526 {
527 }
528 
529 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) :
530     m_opaque_ap()
531 {
532     if (this != &rhs)
533     {
534         if (rhs.IsValid())
535             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
536     }
537 }
538 
539 lldb::SBTypeMember&
540 SBTypeMember::operator = (const lldb::SBTypeMember& rhs)
541 {
542     if (this != &rhs)
543     {
544         if (rhs.IsValid())
545             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
546     }
547     return *this;
548 }
549 
550 bool
551 SBTypeMember::IsValid() const
552 {
553     return m_opaque_ap.get();
554 }
555 
556 const char *
557 SBTypeMember::GetName ()
558 {
559     if (m_opaque_ap.get())
560         return m_opaque_ap->GetName().GetCString();
561     return NULL;
562 }
563 
564 SBType
565 SBTypeMember::GetType ()
566 {
567     SBType sb_type;
568     if (m_opaque_ap.get())
569     {
570         sb_type.SetSP (m_opaque_ap->GetTypeImpl());
571     }
572     return sb_type;
573 
574 }
575 
576 uint64_t
577 SBTypeMember::GetOffsetInBytes()
578 {
579     if (m_opaque_ap.get())
580         return m_opaque_ap->GetBitOffset() / 8u;
581     return 0;
582 }
583 
584 uint64_t
585 SBTypeMember::GetOffsetInBits()
586 {
587     if (m_opaque_ap.get())
588         return m_opaque_ap->GetBitOffset();
589     return 0;
590 }
591 
592 bool
593 SBTypeMember::IsBitfield()
594 {
595     if (m_opaque_ap.get())
596         return m_opaque_ap->GetIsBitfield();
597     return false;
598 }
599 
600 uint32_t
601 SBTypeMember::GetBitfieldSizeInBits()
602 {
603     if (m_opaque_ap.get())
604         return m_opaque_ap->GetBitfieldBitSize();
605     return 0;
606 }
607 
608 
609 bool
610 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level)
611 {
612     Stream &strm = description.ref();
613 
614     if (m_opaque_ap.get())
615     {
616         const uint32_t bit_offset = m_opaque_ap->GetBitOffset();
617         const uint32_t byte_offset = bit_offset / 8u;
618         const uint32_t byte_bit_offset = bit_offset % 8u;
619         const char *name = m_opaque_ap->GetName().GetCString();
620         if (byte_bit_offset)
621             strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset);
622         else
623             strm.Printf ("+%u: (", byte_offset);
624 
625         TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl());
626         if (type_impl_sp)
627             type_impl_sp->GetDescription(strm, description_level);
628 
629         strm.Printf (") %s", name);
630         if (m_opaque_ap->GetIsBitfield())
631         {
632             const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize();
633             strm.Printf (" : %u", bitfield_bit_size);
634         }
635     }
636     else
637     {
638         strm.PutCString ("No value");
639     }
640     return true;
641 }
642 
643 
644 void
645 SBTypeMember::reset(TypeMemberImpl *type_member_impl)
646 {
647     m_opaque_ap.reset(type_member_impl);
648 }
649 
650 TypeMemberImpl &
651 SBTypeMember::ref ()
652 {
653     if (m_opaque_ap.get() == NULL)
654         m_opaque_ap.reset (new TypeMemberImpl());
655     return *m_opaque_ap.get();
656 }
657 
658 const TypeMemberImpl &
659 SBTypeMember::ref () const
660 {
661     return *m_opaque_ap.get();
662 }
663