From 2508b9b8d3e291c3dd6414547c68ec2bdf35428f Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Thu, 1 Nov 2012 23:20:02 +0000 Subject: [PATCH] LLDB now provides base class offsets (virtual and non virtual) to Clang's record layout. We previously were told this wasn't necessary, but it is when pragma pack gets involved. llvm-svn: 167262 --- lldb/include/lldb/Symbol/ClangASTType.h | 3 + .../Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 116 ++++++++++++++------- .../Plugins/SymbolFile/DWARF/SymbolFileDWARF.h | 10 +- lldb/source/Symbol/ClangASTType.cpp | 7 ++ 4 files changed, 95 insertions(+), 41 deletions(-) diff --git a/lldb/include/lldb/Symbol/ClangASTType.h b/lldb/include/lldb/Symbol/ClangASTType.h index 623499a..a658107 100644 --- a/lldb/include/lldb/Symbol/ClangASTType.h +++ b/lldb/include/lldb/Symbol/ClangASTType.h @@ -320,6 +320,9 @@ public: static lldb::clang_type_t RemoveFastQualifiers (lldb::clang_type_t); + static clang::CXXRecordDecl * + GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type); + void Clear() { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 73f4166..5d5c308 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1873,7 +1873,7 @@ SymbolFileDWARF::ParseChildMembers AccessType accessibility = default_accessibility; bool is_virtual = false; bool is_base_of_class = true; - //off_t member_offset = 0; + off_t member_byte_offset = 0; uint32_t i; for (i=0; iGetByteSize() * 8; if (layout_info.bit_size == 0) layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, 0) * 8; - clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); - const clang::RecordType *record_type = clang::dyn_cast(qual_type.getTypePtr()); - if (record_type) + + clang::CXXRecordDecl *record_decl = ClangASTType::GetAsCXXRecordDecl(clang_type); + if (record_decl) { - const clang::RecordDecl *record_decl = record_type->getDecl(); - if (log) { GetObjectFile()->GetModule()->LogMessage (log.get(), - "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u], base_offsets[0], vbase_offsets[0])", + "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u], base_offsets[%u], vbase_offsets[%u])", clang_type, record_decl, layout_info.bit_size, layout_info.alignment, - (uint32_t)layout_info.field_offsets.size()); + (uint32_t)layout_info.field_offsets.size(), + (uint32_t)layout_info.base_offsets.size(), + (uint32_t)layout_info.vbase_offsets.size()); + uint32_t idx; + { llvm::DenseMap ::const_iterator pos, end = layout_info.field_offsets.end(); - for (pos = layout_info.field_offsets.begin(); pos != end; ++pos) + for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx) { GetObjectFile()->GetModule()->LogMessage (log.get(), - "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field = { bit_offset=%u, name='%s' }", + "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = { bit_offset=%u, name='%s' }", clang_type, + idx, (uint32_t)pos->second, pos->first->getNameAsString().c_str()); } + } + + { + llvm::DenseMap ::const_iterator base_pos, base_end = layout_info.base_offsets.end(); + for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end; ++base_pos, ++idx) + { + GetObjectFile()->GetModule()->LogMessage (log.get(), + "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] = { byte_offset=%u, name='%s' }", + clang_type, + idx, + (uint32_t)base_pos->second.getQuantity(), + base_pos->first->getNameAsString().c_str()); + } + } + { + llvm::DenseMap ::const_iterator vbase_pos, vbase_end = layout_info.vbase_offsets.end(); + for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end; ++vbase_pos, ++idx) + { + GetObjectFile()->GetModule()->LogMessage (log.get(), + "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) vbase[%u] = { byte_offset=%u, name='%s' }", + clang_type, + idx, + (uint32_t)vbase_pos->second.getQuantity(), + vbase_pos->first->getNameAsString().c_str()); + } + } } m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info)); } @@ -7259,6 +7301,8 @@ SymbolFileDWARF::LayoutRecordType (const clang::RecordDecl *record_decl, bit_size = pos->second.bit_size; alignment = pos->second.alignment; field_offsets.swap(pos->second.field_offsets); + base_offsets.swap (pos->second.base_offsets); + vbase_offsets.swap (pos->second.vbase_offsets); m_record_decl_to_layout_map.erase(pos); success = true; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 64f7fc4..5b8fbd9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -166,16 +166,16 @@ public: LayoutInfo () : bit_size(0), alignment(0), - field_offsets()//, - //base_offsets(), // We don't need to fill in the base classes, this can be done automatically - //vbase_offsets() // We don't need to fill in the virtual base classes, this can be done automatically + field_offsets(), + base_offsets(), + vbase_offsets() { } uint64_t bit_size; uint64_t alignment; llvm::DenseMap field_offsets; -// llvm::DenseMap base_offsets; -// llvm::DenseMap vbase_offsets; + llvm::DenseMap base_offsets; + llvm::DenseMap vbase_offsets; }; //------------------------------------------------------------------ // PluginInterface protocol diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index d01f5ea..3e9b466 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -1765,6 +1765,13 @@ ClangASTType::RemoveFastQualifiers (lldb::clang_type_t clang_type) return qual_type.getAsOpaquePtr(); } +clang::CXXRecordDecl * +ClangASTType::GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type) +{ + if (opaque_clang_qual_type) + return clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)->getAsCXXRecordDecl(); + return NULL; +} bool lldb_private::operator == (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs) -- 2.7.4