Home | History | Annotate | Download | only in API
      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 m_opaque_sp->GetClangASTType().GetByteSize();
    146 
    147 }
    148 
    149 bool
    150 SBType::IsPointerType()
    151 {
    152     if (!IsValid())
    153         return false;
    154     return m_opaque_sp->GetClangASTType().IsPointerType();
    155 }
    156 
    157 bool
    158 SBType::IsReferenceType()
    159 {
    160     if (!IsValid())
    161         return false;
    162     return m_opaque_sp->GetClangASTType().IsReferenceType();
    163 }
    164 
    165 SBType
    166 SBType::GetPointerType()
    167 {
    168     if (!IsValid())
    169         return SBType();
    170 
    171     return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointerType()));
    172 }
    173 
    174 SBType
    175 SBType::GetPointeeType()
    176 {
    177     if (!IsValid())
    178         return SBType();
    179     return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointeeType()));
    180 }
    181 
    182 SBType
    183 SBType::GetReferenceType()
    184 {
    185     if (!IsValid())
    186         return SBType();
    187     return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetLValueReferenceType()));
    188 }
    189 
    190 SBType
    191 SBType::GetDereferencedType()
    192 {
    193     if (!IsValid())
    194         return SBType();
    195     return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetNonReferenceType()));
    196 }
    197 
    198 bool
    199 SBType::IsFunctionType ()
    200 {
    201     if (!IsValid())
    202         return false;
    203     return m_opaque_sp->GetClangASTType().IsFunctionType();
    204 }
    205 
    206 bool
    207 SBType::IsPolymorphicClass ()
    208 {
    209     if (!IsValid())
    210         return false;
    211     return m_opaque_sp->GetClangASTType().IsPolymorphicClass();
    212 }
    213 
    214 
    215 
    216 lldb::SBType
    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
    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
    247 SBType::GetUnqualifiedType()
    248 {
    249     if (!IsValid())
    250         return SBType();
    251     return SBType(m_opaque_sp->GetClangASTType().GetFullyUnqualifiedType());
    252 }
    253 
    254 lldb::SBType
    255 SBType::GetCanonicalType()
    256 {
    257     if (IsValid())
    258         return SBType(m_opaque_sp->GetClangASTType().GetCanonicalType());
    259     return SBType();
    260 }
    261 
    262 
    263 lldb::BasicType
    264 SBType::GetBasicType()
    265 {
    266     if (IsValid())
    267         return m_opaque_sp->GetClangASTType().GetBasicTypeEnumeration ();
    268     return eBasicTypeInvalid;
    269 }
    270 
    271 SBType
    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
    280 SBType::GetNumberOfDirectBaseClasses ()
    281 {
    282     if (IsValid())
    283         return m_opaque_sp->GetClangASTType().GetNumDirectBaseClasses();
    284     return 0;
    285 }
    286 
    287 uint32_t
    288 SBType::GetNumberOfVirtualBaseClasses ()
    289 {
    290     if (IsValid())
    291         return m_opaque_sp->GetClangASTType().GetNumVirtualBaseClasses();
    292     return 0;
    293 }
    294 
    295 uint32_t
    296 SBType::GetNumberOfFields ()
    297 {
    298     if (IsValid())
    299         return m_opaque_sp->GetClangASTType().GetNumFields();
    300     return 0;
    301 }
    302 
    303 bool
    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
    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
    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
    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
    396 SBType::IsTypeComplete()
    397 {
    398     if (!IsValid())
    399         return false;
    400     return m_opaque_sp->GetClangASTType().IsCompleteType();
    401 }
    402 
    403 const char*
    404 SBType::GetName()
    405 {
    406     if (!IsValid())
    407         return "";
    408     return m_opaque_sp->GetClangASTType().GetConstTypeName().GetCString();
    409 }
    410 
    411 lldb::TypeClass
    412 SBType::GetTypeClass ()
    413 {
    414     if (IsValid())
    415         return m_opaque_sp->GetClangASTType().GetTypeClass();
    416     return lldb::eTypeClassInvalid;
    417 }
    418 
    419 uint32_t
    420 SBType::GetNumberOfTemplateArguments ()
    421 {
    422     if (IsValid())
    423         return m_opaque_sp->GetClangASTType().GetNumTemplateArguments();
    424     return 0;
    425 }
    426 
    427 lldb::SBType
    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
    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 
    451 SBTypeList::SBTypeList() :
    452     m_opaque_ap(new TypeListImpl())
    453 {
    454 }
    455 
    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
    464 SBTypeList::IsValid ()
    465 {
    466     return (m_opaque_ap.get() != NULL);
    467 }
    468 
    469 SBTypeList&
    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
    482 SBTypeList::Append (SBType type)
    483 {
    484     if (type.IsValid())
    485         m_opaque_ap->Append (type.m_opaque_sp);
    486 }
    487 
    488 SBType
    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
    497 SBTypeList::GetSize()
    498 {
    499     return m_opaque_ap->GetSize();
    500 }
    501 
    502 SBTypeList::~SBTypeList()
    503 {
    504 }
    505 
    506 SBTypeMember::SBTypeMember() :
    507     m_opaque_ap()
    508 {
    509 }
    510 
    511 SBTypeMember::~SBTypeMember()
    512 {
    513 }
    514 
    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&
    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
    537 SBTypeMember::IsValid() const
    538 {
    539     return m_opaque_ap.get();
    540 }
    541 
    542 const char *
    543 SBTypeMember::GetName ()
    544 {
    545     if (m_opaque_ap.get())
    546         return m_opaque_ap->GetName().GetCString();
    547     return NULL;
    548 }
    549 
    550 SBType
    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
    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
    571 SBTypeMember::GetOffsetInBits()
    572 {
    573     if (m_opaque_ap.get())
    574         return m_opaque_ap->GetBitOffset();
    575     return 0;
    576 }
    577 
    578 bool
    579 SBTypeMember::IsBitfield()
    580 {
    581     if (m_opaque_ap.get())
    582         return m_opaque_ap->GetIsBitfield();
    583     return false;
    584 }
    585 
    586 uint32_t
    587 SBTypeMember::GetBitfieldSizeInBits()
    588 {
    589     if (m_opaque_ap.get())
    590         return m_opaque_ap->GetBitfieldBitSize();
    591     return 0;
    592 }
    593 
    594 
    595 bool
    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
    631 SBTypeMember::reset(TypeMemberImpl *type_member_impl)
    632 {
    633     m_opaque_ap.reset(type_member_impl);
    634 }
    635 
    636 TypeMemberImpl &
    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 &
    645 SBTypeMember::ref () const
    646 {
    647     return *m_opaque_ap.get();
    648 }
    649