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 uint32_t
453 SBType::GetTypeFlags ()
454 {
455     if (!IsValid())
456         return 0;
457     return m_opaque_sp->GetClangASTType(true).GetTypeInfo();
458 }
459 
460 const char*
461 SBType::GetName()
462 {
463     if (!IsValid())
464         return "";
465     return m_opaque_sp->GetName().GetCString();
466 }
467 
468 const char *
469 SBType::GetDisplayTypeName ()
470 {
471     if (!IsValid())
472         return "";
473     return m_opaque_sp->GetDisplayTypeName().GetCString();
474 }
475 
476 lldb::TypeClass
477 SBType::GetTypeClass ()
478 {
479     if (IsValid())
480         return m_opaque_sp->GetClangASTType(true).GetTypeClass();
481     return lldb::eTypeClassInvalid;
482 }
483 
484 uint32_t
485 SBType::GetNumberOfTemplateArguments ()
486 {
487     if (IsValid())
488         return m_opaque_sp->GetClangASTType(false).GetNumTemplateArguments();
489     return 0;
490 }
491 
492 lldb::SBType
493 SBType::GetTemplateArgumentType (uint32_t idx)
494 {
495     if (IsValid())
496     {
497         TemplateArgumentKind kind = eTemplateArgumentKindNull;
498         ClangASTType template_arg_type = m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
499         if (template_arg_type.IsValid())
500             return SBType(template_arg_type);
501     }
502     return SBType();
503 }
504 
505 
506 lldb::TemplateArgumentKind
507 SBType::GetTemplateArgumentKind (uint32_t idx)
508 {
509     TemplateArgumentKind kind = eTemplateArgumentKindNull;
510     if (IsValid())
511         m_opaque_sp->GetClangASTType(false).GetTemplateArgument (idx, kind);
512     return kind;
513 }
514 
515 
516 SBTypeList::SBTypeList() :
517     m_opaque_ap(new TypeListImpl())
518 {
519 }
520 
521 SBTypeList::SBTypeList(const SBTypeList& rhs) :
522     m_opaque_ap(new TypeListImpl())
523 {
524     for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
525         Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
526 }
527 
528 bool
529 SBTypeList::IsValid ()
530 {
531     return (m_opaque_ap.get() != NULL);
532 }
533 
534 SBTypeList&
535 SBTypeList::operator = (const SBTypeList& rhs)
536 {
537     if (this != &rhs)
538     {
539         m_opaque_ap.reset (new TypeListImpl());
540         for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++)
541             Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i));
542     }
543     return *this;
544 }
545 
546 void
547 SBTypeList::Append (SBType type)
548 {
549     if (type.IsValid())
550         m_opaque_ap->Append (type.m_opaque_sp);
551 }
552 
553 SBType
554 SBTypeList::GetTypeAtIndex(uint32_t index)
555 {
556     if (m_opaque_ap.get())
557         return SBType(m_opaque_ap->GetTypeAtIndex(index));
558     return SBType();
559 }
560 
561 uint32_t
562 SBTypeList::GetSize()
563 {
564     return m_opaque_ap->GetSize();
565 }
566 
567 SBTypeList::~SBTypeList()
568 {
569 }
570 
571 SBTypeMember::SBTypeMember() :
572     m_opaque_ap()
573 {
574 }
575 
576 SBTypeMember::~SBTypeMember()
577 {
578 }
579 
580 SBTypeMember::SBTypeMember (const SBTypeMember& rhs) :
581     m_opaque_ap()
582 {
583     if (this != &rhs)
584     {
585         if (rhs.IsValid())
586             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
587     }
588 }
589 
590 lldb::SBTypeMember&
591 SBTypeMember::operator = (const lldb::SBTypeMember& rhs)
592 {
593     if (this != &rhs)
594     {
595         if (rhs.IsValid())
596             m_opaque_ap.reset(new TypeMemberImpl(rhs.ref()));
597     }
598     return *this;
599 }
600 
601 bool
602 SBTypeMember::IsValid() const
603 {
604     return m_opaque_ap.get();
605 }
606 
607 const char *
608 SBTypeMember::GetName ()
609 {
610     if (m_opaque_ap.get())
611         return m_opaque_ap->GetName().GetCString();
612     return NULL;
613 }
614 
615 SBType
616 SBTypeMember::GetType ()
617 {
618     SBType sb_type;
619     if (m_opaque_ap.get())
620     {
621         sb_type.SetSP (m_opaque_ap->GetTypeImpl());
622     }
623     return sb_type;
624 
625 }
626 
627 uint64_t
628 SBTypeMember::GetOffsetInBytes()
629 {
630     if (m_opaque_ap.get())
631         return m_opaque_ap->GetBitOffset() / 8u;
632     return 0;
633 }
634 
635 uint64_t
636 SBTypeMember::GetOffsetInBits()
637 {
638     if (m_opaque_ap.get())
639         return m_opaque_ap->GetBitOffset();
640     return 0;
641 }
642 
643 bool
644 SBTypeMember::IsBitfield()
645 {
646     if (m_opaque_ap.get())
647         return m_opaque_ap->GetIsBitfield();
648     return false;
649 }
650 
651 uint32_t
652 SBTypeMember::GetBitfieldSizeInBits()
653 {
654     if (m_opaque_ap.get())
655         return m_opaque_ap->GetBitfieldBitSize();
656     return 0;
657 }
658 
659 
660 bool
661 SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level)
662 {
663     Stream &strm = description.ref();
664 
665     if (m_opaque_ap.get())
666     {
667         const uint32_t bit_offset = m_opaque_ap->GetBitOffset();
668         const uint32_t byte_offset = bit_offset / 8u;
669         const uint32_t byte_bit_offset = bit_offset % 8u;
670         const char *name = m_opaque_ap->GetName().GetCString();
671         if (byte_bit_offset)
672             strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset);
673         else
674             strm.Printf ("+%u: (", byte_offset);
675 
676         TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl());
677         if (type_impl_sp)
678             type_impl_sp->GetDescription(strm, description_level);
679 
680         strm.Printf (") %s", name);
681         if (m_opaque_ap->GetIsBitfield())
682         {
683             const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize();
684             strm.Printf (" : %u", bitfield_bit_size);
685         }
686     }
687     else
688     {
689         strm.PutCString ("No value");
690     }
691     return true;
692 }
693 
694 
695 void
696 SBTypeMember::reset(TypeMemberImpl *type_member_impl)
697 {
698     m_opaque_ap.reset(type_member_impl);
699 }
700 
701 TypeMemberImpl &
702 SBTypeMember::ref ()
703 {
704     if (m_opaque_ap.get() == NULL)
705         m_opaque_ap.reset (new TypeMemberImpl());
706     return *m_opaque_ap.get();
707 }
708 
709 const TypeMemberImpl &
710 SBTypeMember::ref () const
711 {
712     return *m_opaque_ap.get();
713 }
714 
715 SBTypeMemberFunction::SBTypeMemberFunction() :
716 m_opaque_sp()
717 {
718 }
719 
720 SBTypeMemberFunction::~SBTypeMemberFunction()
721 {
722 }
723 
724 SBTypeMemberFunction::SBTypeMemberFunction (const SBTypeMemberFunction& rhs) :
725     m_opaque_sp(rhs.m_opaque_sp)
726 {
727 }
728 
729 lldb::SBTypeMemberFunction&
730 SBTypeMemberFunction::operator = (const lldb::SBTypeMemberFunction& rhs)
731 {
732     if (this != &rhs)
733         m_opaque_sp = rhs.m_opaque_sp;
734     return *this;
735 }
736 
737 bool
738 SBTypeMemberFunction::IsValid() const
739 {
740     return m_opaque_sp.get();
741 }
742 
743 const char *
744 SBTypeMemberFunction::GetName ()
745 {
746     if (m_opaque_sp)
747         return m_opaque_sp->GetName().GetCString();
748     return NULL;
749 }
750 
751 SBType
752 SBTypeMemberFunction::GetType ()
753 {
754     SBType sb_type;
755     if (m_opaque_sp)
756     {
757         sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType())));
758     }
759     return sb_type;
760 }
761 
762 lldb::SBType
763 SBTypeMemberFunction::GetReturnType ()
764 {
765     SBType sb_type;
766     if (m_opaque_sp)
767     {
768         sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType())));
769     }
770     return sb_type;
771 }
772 
773 uint32_t
774 SBTypeMemberFunction::GetNumberOfArguments ()
775 {
776     if (m_opaque_sp)
777         return m_opaque_sp->GetNumArguments();
778     return 0;
779 }
780 
781 lldb::SBType
782 SBTypeMemberFunction::GetArgumentTypeAtIndex (uint32_t i)
783 {
784     SBType sb_type;
785     if (m_opaque_sp)
786     {
787         sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i))));
788     }
789     return sb_type;
790 }
791 
792 lldb::MemberFunctionKind
793 SBTypeMemberFunction::GetKind ()
794 {
795     if (m_opaque_sp)
796         return m_opaque_sp->GetKind();
797     return lldb::eMemberFunctionKindUnknown;
798 
799 }
800 
801 bool
802 SBTypeMemberFunction::GetDescription (lldb::SBStream &description,
803                                       lldb::DescriptionLevel description_level)
804 {
805     Stream &strm = description.ref();
806 
807     if (m_opaque_sp)
808         return m_opaque_sp->GetDescription(strm);
809 
810     return false;
811 }
812 
813 void
814 SBTypeMemberFunction::reset(TypeMemberFunctionImpl *type_member_impl)
815 {
816     m_opaque_sp.reset(type_member_impl);
817 }
818 
819 TypeMemberFunctionImpl &
820 SBTypeMemberFunction::ref ()
821 {
822     if (!m_opaque_sp)
823         m_opaque_sp.reset (new TypeMemberFunctionImpl());
824     return *m_opaque_sp.get();
825 }
826 
827 const TypeMemberFunctionImpl &
828 SBTypeMemberFunction::ref () const
829 {
830     return *m_opaque_sp.get();
831 }
832