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