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