<rdar://problem/12585314>
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
This commit is contained in:
parent
9c6890a792
commit
2508b9b8d3
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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; i<num_attributes; ++i)
|
||||
{
|
||||
|
@ -1887,31 +1887,31 @@ SymbolFileDWARF::ParseChildMembers
|
|||
case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
|
||||
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
|
||||
case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
|
||||
// case DW_AT_data_member_location:
|
||||
// if (form_value.BlockData())
|
||||
// {
|
||||
// Value initialValue(0);
|
||||
// Value memberOffset(0);
|
||||
// const DataExtractor& debug_info_data = get_debug_info_data();
|
||||
// uint32_t block_length = form_value.Unsigned();
|
||||
// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
|
||||
// if (DWARFExpression::Evaluate (NULL,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// debug_info_data,
|
||||
// block_offset,
|
||||
// block_length,
|
||||
// eRegisterKindDWARF,
|
||||
// &initialValue,
|
||||
// memberOffset,
|
||||
// NULL))
|
||||
// {
|
||||
// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
case DW_AT_data_member_location:
|
||||
if (form_value.BlockData())
|
||||
{
|
||||
Value initialValue(0);
|
||||
Value memberOffset(0);
|
||||
const DataExtractor& debug_info_data = get_debug_info_data();
|
||||
uint32_t block_length = form_value.Unsigned();
|
||||
uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
|
||||
if (DWARFExpression::Evaluate (NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
debug_info_data,
|
||||
block_offset,
|
||||
block_length,
|
||||
eRegisterKindDWARF,
|
||||
&initialValue,
|
||||
memberOffset,
|
||||
NULL))
|
||||
{
|
||||
member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_AT_accessibility:
|
||||
accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
|
||||
|
@ -1940,6 +1940,17 @@ SymbolFileDWARF::ParseChildMembers
|
|||
accessibility,
|
||||
is_virtual,
|
||||
is_base_of_class));
|
||||
|
||||
if (is_virtual)
|
||||
{
|
||||
layout_info.vbase_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type),
|
||||
clang::CharUnits::fromQuantity(member_byte_offset)));
|
||||
}
|
||||
else
|
||||
{
|
||||
layout_info.base_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type),
|
||||
clang::CharUnits::fromQuantity(member_byte_offset)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2278,37 +2289,68 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
|
|||
|
||||
ast.CompleteTagDeclarationDefinition (clang_type);
|
||||
|
||||
if (!layout_info.field_offsets.empty())
|
||||
if (!layout_info.field_offsets.empty() ||
|
||||
!layout_info.base_offsets.empty() ||
|
||||
!layout_info.vbase_offsets.empty() )
|
||||
{
|
||||
if (type)
|
||||
layout_info.bit_size = type->GetByteSize() * 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<clang::RecordType>(qual_type.getTypePtr());
|
||||
if (record_type)
|
||||
{
|
||||
const clang::RecordDecl *record_decl = record_type->getDecl();
|
||||
|
||||
clang::CXXRecordDecl *record_decl = ClangASTType::GetAsCXXRecordDecl(clang_type);
|
||||
if (record_decl)
|
||||
{
|
||||
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 clang::FieldDecl *, uint64_t>::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 clang::CXXRecordDecl *, clang::CharUnits>::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 clang::CXXRecordDecl *, clang::CharUnits>::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;
|
||||
}
|
||||
|
|
|
@ -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 <const clang::FieldDecl *, uint64_t> field_offsets;
|
||||
// llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
|
||||
// llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
|
||||
llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
|
||||
llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
|
||||
};
|
||||
//------------------------------------------------------------------
|
||||
// PluginInterface protocol
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue