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