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