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 uint32_t
256 SBType::GetNumberOfMemberFunctions ()
257 {
258     if (IsValid())
259     {
260         return m_opaque_sp->GetClangASTType(true).GetNumMemberFunctions();
261     }
262     return 0;
263 }
264 
265 lldb::SBTypeMemberFunction
266 SBType::GetMemberFunctionAtIndex (uint32_t idx)
267 {
268     SBTypeMemberFunction sb_func_type;
269     if (IsValid())
270         sb_func_type.reset(new TypeMemberFunctionImpl(m_opaque_sp->GetClangASTType(true).GetMemberFunctionAtIndex(idx)));
271     return sb_func_type;
272 }
273 
274 lldb::SBType
275 SBType::GetUnqualifiedType()
276 {
277     if (!IsValid())
278         return SBType();
279     return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetUnqualifiedType())));
280 }
281 
282 lldb::SBType
283 SBType::GetCanonicalType()
284 {
285     if (IsValid())
286         return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetCanonicalType())));
287     return SBType();
288 }
289 
290 
291 lldb::BasicType
292 SBType::GetBasicType()
293 {
294     if (IsValid())
295         return m_opaque_sp->GetClangASTType(false).GetBasicTypeEnumeration ();
296     return eBasicTypeInvalid;
297 }
298 
299 SBType
300 SBType::GetBasicType(lldb::BasicType basic_type)
301 {
302     if (IsValid())
303         return SBType (ClangASTContext::GetBasicType (m_opaque_sp->GetClangASTContext(false), basic_type));
304     return SBType();
305 }
306 
307 uint32_t
308 SBType::GetNumberOfDirectBaseClasses ()
309 {
310     if (IsValid())
311         return m_opaque_sp->GetClangASTType(true).GetNumDirectBaseClasses();
312     return 0;
313 }
314 
315 uint32_t
316 SBType::GetNumberOfVirtualBaseClasses ()
317 {
318     if (IsValid())
319         return m_opaque_sp->GetClangASTType(true).GetNumVirtualBaseClasses();
320     return 0;
321 }
322 
323 uint32_t
324 SBType::GetNumberOfFields ()
325 {
326     if (IsValid())
327         return m_opaque_sp->GetClangASTType(true).GetNumFields();
328     return 0;
329 }
330 
331 bool
332 SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level)
333 {
334     Stream &strm = description.ref();
335 
336     if (m_opaque_sp)
337     {
338         m_opaque_sp->GetDescription (strm, description_level);
339     }
340     else
341         strm.PutCString ("No value");
342 
343     return true;
344 }
345 
346 
347 
348 SBTypeMember
349 SBType::GetDirectBaseClassAtIndex (uint32_t idx)
350 {
351     SBTypeMember sb_type_member;
352     if (IsValid())
353     {
354         ClangASTType this_type (m_opaque_sp->GetClangASTType (true));
355         if (this_type.IsValid())
356         {
357             uint32_t bit_offset = 0;
358             ClangASTType base_class_type (this_type.GetDirectBaseClassAtIndex(idx, &bit_offset));
359             if (base_class_type.IsValid())
360             {
361                 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
362             }
363         }
364     }
365     return sb_type_member;
366 
367 }
368 
369 SBTypeMember
370 SBType::GetVirtualBaseClassAtIndex (uint32_t idx)
371 {
372     SBTypeMember sb_type_member;
373     if (IsValid())
374     {
375         ClangASTType this_type (m_opaque_sp->GetClangASTType (true));
376         if (this_type.IsValid())
377         {
378             uint32_t bit_offset = 0;
379             ClangASTType base_class_type (this_type.GetVirtualBaseClassAtIndex(idx, &bit_offset));
380             if (base_class_type.IsValid())
381             {
382                 sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset));
383             }
384         }
385     }
386     return sb_type_member;
387 }
388 
389 SBTypeEnumMemberList
390 SBType::GetEnumMembers ()
391 {
392     SBTypeEnumMemberList sb_enum_member_list;
393     if (IsValid())
394     {
395         const clang::EnumDecl *enum_decl = m_opaque_sp->GetClangASTType(true).GetFullyUnqualifiedType().GetAsEnumDecl();
396         if (enum_decl)
397         {
398             clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
399             for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
400             {
401                 SBTypeEnumMember enum_member;
402                 enum_member.reset(new TypeEnumMemberImpl(*enum_pos, ClangASTType(m_opaque_sp->GetClangASTContext(true), enum_decl->getIntegerType())));
403                 sb_enum_member_list.Append(enum_member);
404             }
405         }
406     }
407     return sb_enum_member_list;
408 }
409 
410 SBTypeMember
411 SBType::GetFieldAtIndex (uint32_t idx)
412 {
413     SBTypeMember sb_type_member;
414     if (IsValid())
415     {
416         ClangASTType this_type (m_opaque_sp->GetClangASTType (false));
417         if (this_type.IsValid())
418         {
419             uint64_t bit_offset = 0;
420             uint32_t bitfield_bit_size = 0;
421             bool is_bitfield = false;
422             std::string name_sstr;
423             ClangASTType field_type (this_type.GetFieldAtIndex (idx,
424                                                                 name_sstr,
425                                                                 &bit_offset,
426                                                                 &bitfield_bit_size,
427                                                                 &is_bitfield));
428             if (field_type.IsValid())
429             {
430                 ConstString name;
431                 if (!name_sstr.empty())
432                     name.SetCString(name_sstr.c_str());
433                 sb_type_member.reset (new TypeMemberImpl (TypeImplSP (new TypeImpl(field_type)),
434                                                           bit_offset,
435                                                           name,
436                                                           bitfield_bit_size,
437                                                           is_bitfield));
438             }
439         }
440     }
441     return sb_type_member;
442 }
443 
444 bool
445 SBType::IsTypeComplete()
446 {
447     if (!IsValid())
448         return false;
449     return m_opaque_sp->GetClangASTType(false).IsCompleteType();
450 }
451 
452 const char*
453 SBType::GetName()
454 {
455     if (!IsValid())
456         return "";
457     return m_opaque_sp->GetName().GetCString();
458 }
459 
460 const char *
461 SBType::GetDisplayTypeName ()
462 {
463     if (!IsValid())
464         return "";
465     return m_opaque_sp->GetDisplayTypeName().GetCString();
466 }
467 
468 lldb::TypeClass
469 SBType::GetTypeClass ()
470 {
471     if (IsValid())
472         return m_opaque_sp->GetClangASTType(false).GetTypeClass();
473     return lldb::eTypeClassInvalid;
474 }
475 
476 uint32_t
477 SBType::GetNumberOfTemplateArguments ()
478 {
479     if (IsValid())
480         return m_opaque_sp->GetClangASTType(false).GetNumTemplateArguments();
481     return 0;
482 }
483 
484 lldb::SBType
485 SBType::GetTemplateArgumentType (uint32_t idx)
486 {
487     if (IsValid())
488     {
489         TemplateArgumentKind kind = eTemplateArgumentKindNull;
490         ClangASTType template_arg_type = m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
491         if (template_arg_type.IsValid())
492             return SBType(template_arg_type);
493     }
494     return SBType();
495 }
496 
497 
498 lldb::TemplateArgumentKind
499 SBType::GetTemplateArgumentKind (uint32_t idx)
500 {
501     TemplateArgumentKind kind = eTemplateArgumentKindNull;
502     if (IsValid())
503         m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
504     return kind;
505 }
506 
507 
508 SBTypeList::SBTypeList() :
509     m_opaque_ap(new TypeListImpl())
510 {
511 }
512 
513 SBTypeList::SBTypeList(const SBTypeList& rhs) :
514     m_opaque_ap(new TypeListImpl())
515 {
516     for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
517         Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
518 }
519 
520 bool
521 SBTypeList::IsValid ()
522 {
523     return (m_opaque_ap.get() != NULL);
524 }
525 
526 SBTypeList&
527 SBTypeList::operator = (const SBTypeList& rhs)
528 {
529     if (this != &rhs)
530     {
531         m_opaque_ap.reset (new TypeListImpl());
532         for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
533             Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
534     }
535     return *this;
536 }
537 
538 void
539 SBTypeList::Append (SBType type)
540 {
541     if (type.IsValid())
542         m_opaque_ap->Append (type.m_opaque_sp);
543 }
544 
545 SBType
546 SBTypeList::GetTypeAtIndex(uint32_t index)
547 {
548     if (m_opaque_ap.get())
549         return SBType(m_opaque_ap->GetTypeAtIndex(index));
550     return SBType();
551 }
552 
553 uint32_t
554 SBTypeList::GetSize()
555 {
556     return m_opaque_ap->GetSize();
557 }
558 
559 SBTypeList::~SBTypeList()
560 {
561 }
562 
563 SBTypeMember::SBTypeMember() :
564     m_opaque_ap()
565 {
566 }
567 
568 SBTypeMember::~SBTypeMember()
569 {
570 }
571 
572 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) :
573     m_opaque_ap()
574 {
575     if (this != &rhs)
576     {
577         if (rhs.IsValid())
578             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
579     }
580 }
581 
582 lldb::SBTypeMember&
583 SBTypeMember::operator = (const lldb::SBTypeMember& rhs)
584 {
585     if (this != &rhs)
586     {
587         if (rhs.IsValid())
588             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
589     }
590     return *this;
591 }
592 
593 bool
594 SBTypeMember::IsValid() const
595 {
596     return m_opaque_ap.get();
597 }
598 
599 const char *
600 SBTypeMember::GetName ()
601 {
602     if (m_opaque_ap.get())
603         return m_opaque_ap->GetName().GetCString();
604     return NULL;
605 }
606 
607 SBType
608 SBTypeMember::GetType ()
609 {
610     SBType sb_type;
611     if (m_opaque_ap.get())
612     {
613         sb_type.SetSP (m_opaque_ap->GetTypeImpl());
614     }
615     return sb_type;
616 
617 }
618 
619 uint64_t
620 SBTypeMember::GetOffsetInBytes()
621 {
622     if (m_opaque_ap.get())
623         return m_opaque_ap->GetBitOffset() / 8u;
624     return 0;
625 }
626 
627 uint64_t
628 SBTypeMember::GetOffsetInBits()
629 {
630     if (m_opaque_ap.get())
631         return m_opaque_ap->GetBitOffset();
632     return 0;
633 }
634 
635 bool
636 SBTypeMember::IsBitfield()
637 {
638     if (m_opaque_ap.get())
639         return m_opaque_ap->GetIsBitfield();
640     return false;
641 }
642 
643 uint32_t
644 SBTypeMember::GetBitfieldSizeInBits()
645 {
646     if (m_opaque_ap.get())
647         return m_opaque_ap->GetBitfieldBitSize();
648     return 0;
649 }
650 
651 
652 bool
653 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level)
654 {
655     Stream &strm = description.ref();
656 
657     if (m_opaque_ap.get())
658     {
659         const uint32_t bit_offset = m_opaque_ap->GetBitOffset();
660         const uint32_t byte_offset = bit_offset / 8u;
661         const uint32_t byte_bit_offset = bit_offset % 8u;
662         const char *name = m_opaque_ap->GetName().GetCString();
663         if (byte_bit_offset)
664             strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset);
665         else
666             strm.Printf ("+%u: (", byte_offset);
667 
668         TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl());
669         if (type_impl_sp)
670             type_impl_sp->GetDescription(strm, description_level);
671 
672         strm.Printf (") %s", name);
673         if (m_opaque_ap->GetIsBitfield())
674         {
675             const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize();
676             strm.Printf (" : %u", bitfield_bit_size);
677         }
678     }
679     else
680     {
681         strm.PutCString ("No value");
682     }
683     return true;
684 }
685 
686 
687 void
688 SBTypeMember::reset(TypeMemberImpl *type_member_impl)
689 {
690     m_opaque_ap.reset(type_member_impl);
691 }
692 
693 TypeMemberImpl &
694 SBTypeMember::ref ()
695 {
696     if (m_opaque_ap.get() == NULL)
697         m_opaque_ap.reset (new TypeMemberImpl());
698     return *m_opaque_ap.get();
699 }
700 
701 const TypeMemberImpl &
702 SBTypeMember::ref () const
703 {
704     return *m_opaque_ap.get();
705 }
706 
707 SBTypeMemberFunction::SBTypeMemberFunction() :
708 m_opaque_sp()
709 {
710 }
711 
712 SBTypeMemberFunction::~SBTypeMemberFunction()
713 {
714 }
715 
716 SBTypeMemberFunction::SBTypeMemberFunction (const SBTypeMemberFunction& rhs) :
717     m_opaque_sp(rhs.m_opaque_sp)
718 {
719 }
720 
721 lldb::SBTypeMemberFunction&
722 SBTypeMemberFunction::operator = (const lldb::SBTypeMemberFunction& rhs)
723 {
724     if (this != &rhs)
725         m_opaque_sp = rhs.m_opaque_sp;
726     return *this;
727 }
728 
729 bool
730 SBTypeMemberFunction::IsValid() const
731 {
732     return m_opaque_sp.get();
733 }
734 
735 const char *
736 SBTypeMemberFunction::GetName ()
737 {
738     if (m_opaque_sp)
739         return m_opaque_sp->GetName().GetCString();
740     return NULL;
741 }
742 
743 SBType
744 SBTypeMemberFunction::GetType ()
745 {
746     SBType sb_type;
747     if (m_opaque_sp)
748     {
749         sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType())));
750     }
751     return sb_type;
752 }
753 
754 lldb::SBType
755 SBTypeMemberFunction::GetReturnType ()
756 {
757     SBType sb_type;
758     if (m_opaque_sp)
759     {
760         sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType())));
761     }
762     return sb_type;
763 }
764 
765 uint32_t
766 SBTypeMemberFunction::GetNumberOfArguments ()
767 {
768     if (m_opaque_sp)
769         return m_opaque_sp->GetNumArguments();
770     return 0;
771 }
772 
773 lldb::SBType
774 SBTypeMemberFunction::GetArgumentTypeAtIndex (uint32_t i)
775 {
776     SBType sb_type;
777     if (m_opaque_sp)
778     {
779         sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i))));
780     }
781     return sb_type;
782 }
783 
784 lldb::MemberFunctionKind
785 SBTypeMemberFunction::GetKind ()
786 {
787     if (m_opaque_sp)
788         return m_opaque_sp->GetKind();
789     return lldb::eMemberFunctionKindUnknown;
790 
791 }
792 
793 bool
794 SBTypeMemberFunction::GetDescription (lldb::SBStream &description,
795                                       lldb::DescriptionLevel description_level)
796 {
797     Stream &strm = description.ref();
798 
799     if (m_opaque_sp)
800         return m_opaque_sp->GetDescription(strm);
801 
802     return false;
803 }
804 
805 void
806 SBTypeMemberFunction::reset(TypeMemberFunctionImpl *type_member_impl)
807 {
808     m_opaque_sp.reset(type_member_impl);
809 }
810 
811 TypeMemberFunctionImpl &
812 SBTypeMemberFunction::ref ()
813 {
814     if (!m_opaque_sp)
815         m_opaque_sp.reset (new TypeMemberFunctionImpl());
816     return *m_opaque_sp.get();
817 }
818 
819 const TypeMemberFunctionImpl &
820 SBTypeMemberFunction::ref () const
821 {
822     return *m_opaque_sp.get();
823 }
824