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