diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/API/SBFrame.cpp | 4 | ||||
-rw-r--r-- | lldb/source/API/SBType.cpp | 245 | ||||
-rw-r--r-- | lldb/source/API/SBValue.cpp | 84 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangASTContext.cpp | 381 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangASTType.cpp | 73 |
5 files changed, 690 insertions, 97 deletions
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index 4174638b8e7..3f27b6fc123 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -538,8 +538,8 @@ SBFrame::get() const return m_opaque_sp.get(); } -const lldb::StackFrameSP & -SBFrame::get_sp() const +lldb::StackFrameSP & +SBFrame::get_sp() { return m_opaque_sp; } diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp index 582eceec1e3..8deb01c50af 100644 --- a/lldb/source/API/SBType.cpp +++ b/lldb/source/API/SBType.cpp @@ -31,7 +31,7 @@ SBType::SBType() : { } -SBType::SBType (const lldb_private::ClangASTType &type) : +SBType::SBType (const ClangASTType &type) : m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(), type.GetOpaqueQualType()))) { @@ -63,7 +63,7 @@ SBType::SBType (const SBType &rhs) : //{} // bool -SBType::operator == (const lldb::SBType &rhs) const +SBType::operator == (SBType &rhs) { if (IsValid() == false) return !rhs.IsValid(); @@ -73,7 +73,7 @@ SBType::operator == (const lldb::SBType &rhs) const } bool -SBType::operator != (const lldb::SBType &rhs) const +SBType::operator != (SBType &rhs) { if (IsValid() == false) return rhs.IsValid(); @@ -82,11 +82,16 @@ SBType::operator != (const lldb::SBType &rhs) const (rhs.m_opaque_sp->GetOpaqueQualType() != m_opaque_sp->GetOpaqueQualType()); } +void +SBType::reset(const lldb::TypeImplSP &type_impl_sp) +{ + m_opaque_sp = type_impl_sp; +} -const lldb::SBType & -SBType::operator = (const lldb::SBType &rhs) +SBType & +SBType::operator = (const SBType &rhs) { - if (*this != rhs) + if (this != &rhs) { m_opaque_sp = rhs.m_opaque_sp; } @@ -96,15 +101,15 @@ SBType::operator = (const lldb::SBType &rhs) SBType::~SBType () {} -lldb_private::TypeImpl & +TypeImpl & SBType::ref () { if (m_opaque_sp.get() == NULL) - m_opaque_sp.reset (new lldb_private::TypeImpl()); + m_opaque_sp.reset (new TypeImpl()); return *m_opaque_sp; } -const lldb_private::TypeImpl & +const TypeImpl & SBType::ref () const { // "const SBAddress &addr" should already have checked "addr.IsValid()" @@ -124,7 +129,7 @@ SBType::IsValid() const } size_t -SBType::GetByteSize() const +SBType::GetByteSize() { if (!IsValid()) return 0; @@ -134,7 +139,7 @@ SBType::GetByteSize() const } bool -SBType::IsPointerType() const +SBType::IsPointerType() { if (!IsValid()) return false; @@ -148,7 +153,7 @@ SBType::IsPointerType() const } bool -SBType::IsReferenceType() const +SBType::IsReferenceType() { if (!IsValid()) return false; @@ -162,7 +167,7 @@ SBType::IsReferenceType() const } SBType -SBType::GetPointerType() const +SBType::GetPointerType() { if (!IsValid()) return SBType(); @@ -172,7 +177,7 @@ SBType::GetPointerType() const } SBType -SBType::GetPointeeType() const +SBType::GetPointeeType() { if (!IsValid()) return SBType(); @@ -186,7 +191,7 @@ SBType::GetPointeeType() const } SBType -SBType::GetReferenceType() const +SBType::GetReferenceType() { if (!IsValid()) return SBType(); @@ -196,7 +201,7 @@ SBType::GetReferenceType() const } SBType -SBType::GetDereferencedType() const +SBType::GetDereferencedType() { if (!IsValid()) return SBType(); @@ -207,7 +212,7 @@ SBType::GetDereferencedType() const } SBType -SBType::GetBasicType(lldb::BasicType type) const +SBType::GetBasicType(lldb::BasicType type) { if (!IsValid()) @@ -302,6 +307,89 @@ SBType::GetBasicType(lldb::BasicType type) const return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr())); } +uint32_t +SBType::GetNumberOfDirectBaseClasses () +{ + if (IsValid()) + return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); + return 0; +} + +uint32_t +SBType::GetNumberOfVirtualBaseClasses () +{ + if (IsValid()) + return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); + return 0; +} + +uint32_t +SBType::GetNumberOfFields () +{ + if (IsValid()) + return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); + return 0; +} + +SBTypeMember +SBType::GetDirectBaseClassAtIndex (uint32_t idx) +{ + SBTypeMember sb_type_member; + if (IsValid()) + { + clang::ASTContext* ast = m_opaque_sp->GetASTContext(); + uint32_t byte_offset = 0; + clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &byte_offset); + if (clang_type) + { + TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); + sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset)); + } + } + return sb_type_member; + +} + +SBTypeMember +SBType::GetVirtualBaseClassAtIndex (uint32_t idx) +{ + SBTypeMember sb_type_member; + if (IsValid()) + { + uint32_t byte_offset = 0; + clang::ASTContext* ast = m_opaque_sp->GetASTContext(); + clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &byte_offset); + if (clang_type) + { + TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); + sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset)); + } + } + return sb_type_member; +} + +SBTypeMember +SBType::GetFieldAtIndex (uint32_t idx) +{ + SBTypeMember sb_type_member; + if (IsValid()) + { + uint32_t byte_offset = 0; + clang::ASTContext* ast = m_opaque_sp->GetASTContext(); + std::string name_sstr; + clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &byte_offset); + if (clang_type) + { + ConstString name; + if (!name_sstr.empty()) + name.SetCString(name_sstr.c_str()); + TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); + sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset, name)); + } + } + return sb_type_member; +} + const char* SBType::GetName() { @@ -311,6 +399,15 @@ SBType::GetName() return ClangASTType::GetConstTypeName(m_opaque_sp->GetOpaqueQualType()).GetCString(); } +lldb::TypeClass +SBType::GetTypeClass () +{ + if (IsValid()) + return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(), + m_opaque_sp->GetOpaqueQualType()); + return lldb::eTypeClassInvalid; +} + SBTypeList::SBTypeList() : m_opaque_ap(new TypeListImpl()) { @@ -319,12 +416,12 @@ SBTypeList::SBTypeList() : SBTypeList::SBTypeList(const SBTypeList& rhs) : m_opaque_ap(new TypeListImpl()) { - for (uint32_t i = 0, rhs_size = rhs.GetSize(); i < rhs_size; i++) - Append(rhs.GetTypeAtIndex(i)); + for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); } bool -SBTypeList::IsValid () const +SBTypeList::IsValid () { return (m_opaque_ap.get() != NULL); } @@ -332,30 +429,32 @@ SBTypeList::IsValid () const SBTypeList& SBTypeList::operator = (const SBTypeList& rhs) { - if (this != &rhs && m_opaque_ap.get() != rhs.m_opaque_ap.get()) + if (this != &rhs) { - m_opaque_ap.reset(new TypeListImpl()); - for (uint32_t i = 0, rhs_size = rhs.GetSize(); i < rhs_size; i++) - Append(rhs.GetTypeAtIndex(i)); + m_opaque_ap.reset (new TypeListImpl()); + for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); } return *this; } void -SBTypeList::Append (const SBType& type) +SBTypeList::Append (SBType type) { if (type.IsValid()) m_opaque_ap->Append (type.m_opaque_sp); } SBType -SBTypeList::GetTypeAtIndex(int index) const +SBTypeList::GetTypeAtIndex(uint32_t index) { - return SBType(m_opaque_ap->GetTypeAtIndex(index)); + if (m_opaque_ap.get()) + return SBType(m_opaque_ap->GetTypeAtIndex(index)); + return SBType(); } -int -SBTypeList::GetSize() const +uint32_t +SBTypeList::GetSize() { return m_opaque_ap->GetSize(); } @@ -367,7 +466,7 @@ SBTypeList::~SBTypeList() bool SBType::IsPointerType (void *opaque_type) { - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); bool ret_value = ClangASTContext::IsPointerType (opaque_type); @@ -376,3 +475,89 @@ SBType::IsPointerType (void *opaque_type) return ret_value; } + + +SBTypeMember::SBTypeMember() : + m_opaque_ap() +{ +} + +SBTypeMember::~SBTypeMember() +{ +} + +SBTypeMember::SBTypeMember (const SBTypeMember& rhs) : + m_opaque_ap() +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); + } +} + +lldb::SBTypeMember& +SBTypeMember::operator = (const lldb::SBTypeMember& rhs) +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); + } + return *this; +} + +bool +SBTypeMember::IsValid() const +{ + return m_opaque_ap.get(); +} + +const char * +SBTypeMember::GetName () +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetName().GetCString(); + return NULL; +} + +SBType +SBTypeMember::GetType () +{ + SBType sb_type; + if (m_opaque_ap.get()) + { + sb_type.reset (m_opaque_ap->GetTypeImpl()); + } + return sb_type; + +} + +uint64_t +SBTypeMember::GetOffsetByteSize() +{ + if (m_opaque_ap.get()) + return (m_opaque_ap->GetBitOffset() + 7) / 8u; + return 0; +} + +void +SBTypeMember::reset(TypeMemberImpl *type_member_impl) +{ + m_opaque_ap.reset(type_member_impl); +} + +TypeMemberImpl & +SBTypeMember::ref () +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset (new TypeMemberImpl()); + return *m_opaque_ap.get(); +} + +const TypeMemberImpl & +SBTypeMember::ref () const +{ + return *m_opaque_ap.get(); +} + diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index ea7ebf8c13e..d0e2e678793 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -52,7 +52,7 @@ SBValue::SBValue(const SBValue &rhs) : { } -const SBValue & +SBValue & SBValue::operator = (const SBValue &rhs) { if (this != &rhs) @@ -65,7 +65,7 @@ SBValue::~SBValue() } bool -SBValue::IsValid () const +SBValue::IsValid () { // If this function ever changes to anything that does more than just // check if the opaque shared pointer is non NULL, then we need to update @@ -146,12 +146,6 @@ SBValue::GetByteSize () } bool -SBValue::IsInScope (const SBFrame &sb_frame) -{ - return IsInScope(); -} - -bool SBValue::IsInScope () { bool result = false; @@ -173,12 +167,6 @@ SBValue::IsInScope () } const char * -SBValue::GetValue (const SBFrame &sb_frame) -{ - return GetValue(); -} - -const char * SBValue::GetValue () { const char *cstr = NULL; @@ -228,12 +216,6 @@ SBValue::GetValueType () } const char * -SBValue::GetObjectDescription (const SBFrame &sb_frame) -{ - return GetObjectDescription (); -} - -const char * SBValue::GetObjectDescription () { const char *cstr = NULL; @@ -256,12 +238,6 @@ SBValue::GetObjectDescription () return cstr; } -bool -SBValue::GetValueDidChange (const SBFrame &sb_frame) -{ - return GetValueDidChange (); -} - SBType SBValue::GetType() { @@ -305,12 +281,6 @@ SBValue::GetValueDidChange () } const char * -SBValue::GetSummary (const SBFrame &sb_frame) -{ - return GetSummary (); -} - -const char * SBValue::GetSummary () { const char *cstr = NULL; @@ -334,12 +304,6 @@ SBValue::GetSummary () } const char * -SBValue::GetLocation (const SBFrame &sb_frame) -{ - return GetLocation (); -} - -const char * SBValue::GetLocation () { const char *cstr = NULL; @@ -363,12 +327,6 @@ SBValue::GetLocation () } bool -SBValue::SetValueFromCString (const SBFrame &sb_frame, const char *value_str) -{ - return SetValueFromCString (value_str); -} - -bool SBValue::SetValueFromCString (const char *value_str) { bool success = false; @@ -384,7 +342,7 @@ SBValue::SetValueFromCString (const char *value_str) } lldb::SBValue -SBValue::CreateChildAtOffset (const char *name, uint32_t offset, const SBType& type) +SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type) { lldb::SBValue result; if (m_opaque_sp) @@ -407,7 +365,7 @@ SBValue::CreateChildAtOffset (const char *name, uint32_t offset, const SBType& t } lldb::SBValue -SBValue::Cast(const SBType& type) +SBValue::Cast (SBType type) { return CreateChildAtOffset(m_opaque_sp->GetName().GetCString(), 0, type); } @@ -419,10 +377,10 @@ SBValue::CreateValueFromExpression (const char *name, const char* expression) if (m_opaque_sp) { ValueObjectSP result_valobj_sp; - m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression(expression, - m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame(), - true, true, eNoDynamicValues, - result_valobj_sp); + m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression (expression, + m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame(), + true, true, eNoDynamicValues, + result_valobj_sp); result_valobj_sp->SetName(ConstString(name)); result = SBValue(result_valobj_sp); } @@ -438,7 +396,7 @@ SBValue::CreateValueFromExpression (const char *name, const char* expression) } lldb::SBValue -SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, const SBType& type) +SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType type) { lldb::SBValue result; if (m_opaque_sp) @@ -448,13 +406,13 @@ SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, const SB lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); - ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope(), - real_type.m_opaque_sp->GetASTContext(), - real_type.m_opaque_sp->GetOpaqueQualType(), - ConstString(name), - buffer, - lldb::endian::InlHostByteOrder(), - GetTarget().GetProcess().GetAddressByteSize())); + ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope(), + real_type.m_opaque_sp->GetASTContext(), + real_type.m_opaque_sp->GetOpaqueQualType(), + ConstString(name), + buffer, + lldb::endian::InlHostByteOrder(), + GetTarget().GetProcess().GetAddressByteSize())); ValueObjectSP result_valobj_sp; @@ -480,9 +438,7 @@ SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, const SB } lldb::SBValue -SBValue::CreateValueFromData (const char* name, - const SBData& data, - const SBType& type) +SBValue::CreateValueFromData (const char* name, SBData data, SBType type) { SBValue result; @@ -869,7 +825,7 @@ SBValue::GetThread() { if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()) { - result = SBThread(lldb::ThreadSP(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateThread())); + result = SBThread(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateThread()->GetSP()); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -891,7 +847,7 @@ SBValue::GetFrame() { if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()) { - result = SBFrame(lldb::StackFrameSP(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame())); + result.SetFrame (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame()->GetSP()); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -980,7 +936,7 @@ SBValue::GetDescription (SBStream &description) } lldb::Format -SBValue::GetFormat () const +SBValue::GetFormat () { if (m_opaque_sp) return m_opaque_sp->GetFormat(); diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 382133a78d8..1c0ec1baf09 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -2397,6 +2397,386 @@ ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type return num_children; } +uint32_t +ClangASTContext::GetNumDirectBaseClasses (clang::ASTContext *ast, clang_type_t clang_type) +{ + if (clang_type == NULL) + return 0; + + uint32_t count = 0; + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + count = cxx_record_decl->getNumBases(); + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteQualType (ast, qual_type)) + { + const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType(); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl && class_interface_decl->getSuperClass()) + count = 1; + } + } + break; + + + case clang::Type::Typedef: + count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); + break; + + case clang::Type::Elaborated: + count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); + break; + + default: + break; + } + return count; +} + +uint32_t +ClangASTContext::GetNumVirtualBaseClasses (clang::ASTContext *ast, + clang_type_t clang_type) +{ + if (clang_type == NULL) + return 0; + + uint32_t count = 0; + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + count = cxx_record_decl->getNumVBases(); + } + break; + + case clang::Type::Typedef: + count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); + break; + + case clang::Type::Elaborated: + count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); + break; + + default: + break; + } + return count; +} + +uint32_t +ClangASTContext::GetNumFields (clang::ASTContext *ast, clang_type_t clang_type) +{ + if (clang_type == NULL) + return 0; + + uint32_t count = 0; + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr()); + if (record_type) + { + RecordDecl *record_decl = record_type->getDecl(); + if (record_decl) + { + uint32_t field_idx = 0; + RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) + ++field_idx; + count = field_idx; + } + } + } + break; + + case clang::Type::Typedef: + count = ClangASTContext::GetNumFields (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); + break; + + case clang::Type::Elaborated: + count = ClangASTContext::GetNumFields (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); + break; + + default: + break; + } + return count; +} + +clang_type_t +ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast, + clang_type_t clang_type, + uint32_t idx, + uint32_t *byte_offset_ptr) +{ + if (clang_type == NULL) + return 0; + + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + uint32_t curr_idx = 0; + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; + ++base_class, ++curr_idx) + { + if (curr_idx == idx) + { + if (byte_offset_ptr) + { + const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl); + const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); +// if (base_class->isVirtual()) +// *byte_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; +// else + *byte_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; + } + return base_class->getType().getAsOpaquePtr(); + } + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (idx == 0 && GetCompleteQualType (ast, qual_type)) + { + const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType(); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + if (superclass_interface_decl) + { + if (byte_offset_ptr) + *byte_offset_ptr = 0; + return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(); + } + } + } + } + break; + + + case clang::Type::Typedef: + return ClangASTContext::GetDirectBaseClassAtIndex (ast, + cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), + idx, + byte_offset_ptr); + + case clang::Type::Elaborated: + return ClangASTContext::GetDirectBaseClassAtIndex (ast, + cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), + idx, + byte_offset_ptr); + + default: + break; + } + return NULL; +} + +clang_type_t +ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast, + clang_type_t clang_type, + uint32_t idx, + uint32_t *byte_offset_ptr) +{ + if (clang_type == NULL) + return 0; + + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + uint32_t curr_idx = 0; + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end(); + base_class != base_class_end; + ++base_class, ++curr_idx) + { + if (curr_idx == idx) + { + if (byte_offset_ptr) + { + const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl); + const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); + *byte_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; + + } + return base_class->getType().getAsOpaquePtr(); + } + } + } + } + break; + + case clang::Type::Typedef: + return ClangASTContext::GetVirtualBaseClassAtIndex (ast, + cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), + idx, + byte_offset_ptr); + + case clang::Type::Elaborated: + return ClangASTContext::GetVirtualBaseClassAtIndex (ast, + cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), + idx, + byte_offset_ptr); + + default: + break; + } + return NULL; +} + +clang_type_t +ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast, + clang_type_t clang_type, + uint32_t idx, + std::string& name, + uint32_t *byte_offset_ptr) +{ + if (clang_type == NULL) + return 0; + + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); + const RecordDecl *record_decl = record_type->getDecl(); + uint32_t field_idx = 0; + RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx) + { + if (idx == field_idx) + { + // Print the member type if requested + // Print the member name and equal sign + name.assign(field->getNameAsString()); + + // Figure out the type byte size (field_type_info.first) and + // alignment (field_type_info.second) from the AST context. + if (byte_offset_ptr) + { + const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl); + *byte_offset_ptr = (record_layout.getFieldOffset (field_idx) + 7) / 8; + } + + return field->getType().getAsOpaquePtr(); + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteQualType (ast, qual_type)) + { + const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + if (idx < (class_interface_decl->ivar_size())) + { + ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); + uint32_t ivar_idx = 0; + + for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx) + { + if (ivar_idx == idx) + { + const ObjCIvarDecl* ivar_decl = *ivar_pos; + + QualType ivar_qual_type(ivar_decl->getType()); + + name.assign(ivar_decl->getNameAsString()); + + if (byte_offset_ptr) + { + const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl); + *byte_offset_ptr = (interface_layout.getFieldOffset (ivar_idx) + 7)/8; + } + + return ivar_qual_type.getAsOpaquePtr(); + } + } + } + } + } + } + break; + + + case clang::Type::Typedef: + return ClangASTContext::GetFieldAtIndex (ast, + cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), + idx, + name, + byte_offset_ptr); + + case clang::Type::Elaborated: + return ClangASTContext::GetFieldAtIndex (ast, + cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), + idx, + name, + byte_offset_ptr); + + default: + break; + } + return NULL; +} + + // If a pointer to a pointee type (the clang_type arg) says that it has no // children, then we either need to trust it, or override it and return a // different result. For example, an "int *" has one child that is an integer, @@ -2616,7 +2996,6 @@ ClangASTContext::GetChildClangTypeAtIndex bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; // Base classes should be a multiple of 8 bits in size - assert (bit_offset % 8 == 0); child_byte_offset = bit_offset/8; child_name = ClangASTType::GetTypeNameForQualType(base_class->getType()); diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index 931bd5e7273..f383323d583 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -215,6 +215,79 @@ ClangASTType::GetMinimumLanguage () m_type); } +lldb::TypeClass +ClangASTType::GetTypeClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type) +{ + if (clang_type == NULL) + return lldb::eTypeClassInvalid; + + clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); + + switch (qual_type->getTypeClass()) + { + case clang::Type::UnaryTransform: break; + case clang::Type::FunctionNoProto: return lldb::eTypeClassFunction; + case clang::Type::FunctionProto: return lldb::eTypeClassFunction; + case clang::Type::IncompleteArray: return lldb::eTypeClassArray; + case clang::Type::VariableArray: return lldb::eTypeClassArray; + case clang::Type::ConstantArray: return lldb::eTypeClassArray; + case clang::Type::DependentSizedArray: return lldb::eTypeClassArray; + case clang::Type::DependentSizedExtVector: return lldb::eTypeClassVector; + case clang::Type::ExtVector: return lldb::eTypeClassVector; + case clang::Type::Vector: return lldb::eTypeClassVector; + case clang::Type::Builtin: return lldb::eTypeClassBuiltin; + case clang::Type::ObjCObjectPointer: return lldb::eTypeClassObjCObjectPointer; + case clang::Type::BlockPointer: return lldb::eTypeClassBlockPointer; + case clang::Type::Pointer: return lldb::eTypeClassPointer; + case clang::Type::LValueReference: return lldb::eTypeClassReference; + case clang::Type::RValueReference: return lldb::eTypeClassReference; + case clang::Type::MemberPointer: return lldb::eTypeClassMemberPointer; + case clang::Type::Complex: + if (qual_type->isComplexType()) + return lldb::eTypeClassComplexFloat; + else + return lldb::eTypeClassComplexInteger; + case clang::Type::ObjCObject: return lldb::eTypeClassObjCObject; + case clang::Type::ObjCInterface: return lldb::eTypeClassObjCInterface; + case clang::Type::Record: + if (ClangASTContext::GetCompleteType (ast_context, clang_type)) + { + const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + if (record_decl->isUnion()) + return lldb::eTypeClassUnion; + else if (record_decl->isStruct()) + return lldb::eTypeClassStruct; + else + return lldb::eTypeClassClass; + } + break; + case clang::Type::Enum: return lldb::eTypeClassEnumeration; + case clang::Type::Typedef: return lldb::eTypeClassTypedef; + case clang::Type::UnresolvedUsing: break; + case clang::Type::Paren: break; + case clang::Type::Elaborated: break; + case clang::Type::Attributed: break; + case clang::Type::TemplateTypeParm: break; + case clang::Type::SubstTemplateTypeParm: break; + case clang::Type::SubstTemplateTypeParmPack:break; + case clang::Type::Auto: break; + case clang::Type::InjectedClassName: break; + case clang::Type::DependentName: break; + case clang::Type::DependentTemplateSpecialization: break; + case clang::Type::PackExpansion: break; + + case clang::Type::TypeOfExpr: break; + case clang::Type::TypeOf: break; + case clang::Type::Decltype: break; + case clang::Type::TemplateSpecialization: break; + } + // We don't know hot to display this type... + return lldb::eTypeClassOther; + +} + + lldb::LanguageType ClangASTType::GetMinimumLanguage (clang::ASTContext *ctx, lldb::clang_type_t clang_type) |