Skip to content

Commit 2508b9b

Browse files
author
Greg Clayton
committed
<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
1 parent 9c6890a commit 2508b9b

File tree

4 files changed

+95
-41
lines changed

4 files changed

+95
-41
lines changed

lldb/include/lldb/Symbol/ClangASTType.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,9 @@ class ClangASTType
320320
static lldb::clang_type_t
321321
RemoveFastQualifiers (lldb::clang_type_t);
322322

323+
static clang::CXXRecordDecl *
324+
GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type);
325+
323326
void
324327
Clear()
325328
{

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 80 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,7 +1873,7 @@ SymbolFileDWARF::ParseChildMembers
18731873
AccessType accessibility = default_accessibility;
18741874
bool is_virtual = false;
18751875
bool is_base_of_class = true;
1876-
//off_t member_offset = 0;
1876+
off_t member_byte_offset = 0;
18771877
uint32_t i;
18781878
for (i=0; i<num_attributes; ++i)
18791879
{
@@ -1887,31 +1887,31 @@ SymbolFileDWARF::ParseChildMembers
18871887
case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
18881888
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
18891889
case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1890-
// case DW_AT_data_member_location:
1891-
// if (form_value.BlockData())
1892-
// {
1893-
// Value initialValue(0);
1894-
// Value memberOffset(0);
1895-
// const DataExtractor& debug_info_data = get_debug_info_data();
1896-
// uint32_t block_length = form_value.Unsigned();
1897-
// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1898-
// if (DWARFExpression::Evaluate (NULL,
1899-
// NULL,
1900-
// NULL,
1901-
// NULL,
1902-
// NULL,
1903-
// debug_info_data,
1904-
// block_offset,
1905-
// block_length,
1906-
// eRegisterKindDWARF,
1907-
// &initialValue,
1908-
// memberOffset,
1909-
// NULL))
1910-
// {
1911-
// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1912-
// }
1913-
// }
1914-
// break;
1890+
case DW_AT_data_member_location:
1891+
if (form_value.BlockData())
1892+
{
1893+
Value initialValue(0);
1894+
Value memberOffset(0);
1895+
const DataExtractor& debug_info_data = get_debug_info_data();
1896+
uint32_t block_length = form_value.Unsigned();
1897+
uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1898+
if (DWARFExpression::Evaluate (NULL,
1899+
NULL,
1900+
NULL,
1901+
NULL,
1902+
NULL,
1903+
debug_info_data,
1904+
block_offset,
1905+
block_length,
1906+
eRegisterKindDWARF,
1907+
&initialValue,
1908+
memberOffset,
1909+
NULL))
1910+
{
1911+
member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1912+
}
1913+
}
1914+
break;
19151915

19161916
case DW_AT_accessibility:
19171917
accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
@@ -1940,6 +1940,17 @@ SymbolFileDWARF::ParseChildMembers
19401940
accessibility,
19411941
is_virtual,
19421942
is_base_of_class));
1943+
1944+
if (is_virtual)
1945+
{
1946+
layout_info.vbase_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type),
1947+
clang::CharUnits::fromQuantity(member_byte_offset)));
1948+
}
1949+
else
1950+
{
1951+
layout_info.base_offsets.insert(std::make_pair(ClangASTType::GetAsCXXRecordDecl(class_clang_type),
1952+
clang::CharUnits::fromQuantity(member_byte_offset)));
1953+
}
19431954
}
19441955
}
19451956
}
@@ -2278,37 +2289,68 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type
22782289

22792290
ast.CompleteTagDeclarationDefinition (clang_type);
22802291

2281-
if (!layout_info.field_offsets.empty())
2292+
if (!layout_info.field_offsets.empty() ||
2293+
!layout_info.base_offsets.empty() ||
2294+
!layout_info.vbase_offsets.empty() )
22822295
{
22832296
if (type)
22842297
layout_info.bit_size = type->GetByteSize() * 8;
22852298
if (layout_info.bit_size == 0)
22862299
layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, 0) * 8;
2287-
clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
2288-
const clang::RecordType *record_type = clang::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
2289-
if (record_type)
2300+
2301+
clang::CXXRecordDecl *record_decl = ClangASTType::GetAsCXXRecordDecl(clang_type);
2302+
if (record_decl)
22902303
{
2291-
const clang::RecordDecl *record_decl = record_type->getDecl();
2292-
22932304
if (log)
22942305
{
22952306
GetObjectFile()->GetModule()->LogMessage (log.get(),
2296-
"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])",
2307+
"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])",
22972308
clang_type,
22982309
record_decl,
22992310
layout_info.bit_size,
23002311
layout_info.alignment,
2301-
(uint32_t)layout_info.field_offsets.size());
2312+
(uint32_t)layout_info.field_offsets.size(),
2313+
(uint32_t)layout_info.base_offsets.size(),
2314+
(uint32_t)layout_info.vbase_offsets.size());
23022315

2316+
uint32_t idx;
2317+
{
23032318
llvm::DenseMap <const clang::FieldDecl *, uint64_t>::const_iterator pos, end = layout_info.field_offsets.end();
2304-
for (pos = layout_info.field_offsets.begin(); pos != end; ++pos)
2319+
for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx)
23052320
{
23062321
GetObjectFile()->GetModule()->LogMessage (log.get(),
2307-
"SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field = { bit_offset=%u, name='%s' }",
2322+
"SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = { bit_offset=%u, name='%s' }",
23082323
clang_type,
2324+
idx,
23092325
(uint32_t)pos->second,
23102326
pos->first->getNameAsString().c_str());
23112327
}
2328+
}
2329+
2330+
{
2331+
llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos, base_end = layout_info.base_offsets.end();
2332+
for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end; ++base_pos, ++idx)
2333+
{
2334+
GetObjectFile()->GetModule()->LogMessage (log.get(),
2335+
"SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] = { byte_offset=%u, name='%s' }",
2336+
clang_type,
2337+
idx,
2338+
(uint32_t)base_pos->second.getQuantity(),
2339+
base_pos->first->getNameAsString().c_str());
2340+
}
2341+
}
2342+
{
2343+
llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos, vbase_end = layout_info.vbase_offsets.end();
2344+
for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end; ++vbase_pos, ++idx)
2345+
{
2346+
GetObjectFile()->GetModule()->LogMessage (log.get(),
2347+
"SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) vbase[%u] = { byte_offset=%u, name='%s' }",
2348+
clang_type,
2349+
idx,
2350+
(uint32_t)vbase_pos->second.getQuantity(),
2351+
vbase_pos->first->getNameAsString().c_str());
2352+
}
2353+
}
23122354
}
23132355
m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
23142356
}
@@ -7259,6 +7301,8 @@ SymbolFileDWARF::LayoutRecordType (const clang::RecordDecl *record_decl,
72597301
bit_size = pos->second.bit_size;
72607302
alignment = pos->second.alignment;
72617303
field_offsets.swap(pos->second.field_offsets);
7304+
base_offsets.swap (pos->second.base_offsets);
7305+
vbase_offsets.swap (pos->second.vbase_offsets);
72627306
m_record_decl_to_layout_map.erase(pos);
72637307
success = true;
72647308
}

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,16 +166,16 @@ class SymbolFileDWARF : public lldb_private::SymbolFile, public lldb_private::Us
166166
LayoutInfo () :
167167
bit_size(0),
168168
alignment(0),
169-
field_offsets()//,
170-
//base_offsets(), // We don't need to fill in the base classes, this can be done automatically
171-
//vbase_offsets() // We don't need to fill in the virtual base classes, this can be done automatically
169+
field_offsets(),
170+
base_offsets(),
171+
vbase_offsets()
172172
{
173173
}
174174
uint64_t bit_size;
175175
uint64_t alignment;
176176
llvm::DenseMap <const clang::FieldDecl *, uint64_t> field_offsets;
177-
// llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
178-
// llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
177+
llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
178+
llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
179179
};
180180
//------------------------------------------------------------------
181181
// PluginInterface protocol

lldb/source/Symbol/ClangASTType.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,13 @@ ClangASTType::RemoveFastQualifiers (lldb::clang_type_t clang_type)
17651765
return qual_type.getAsOpaquePtr();
17661766
}
17671767

1768+
clang::CXXRecordDecl *
1769+
ClangASTType::GetAsCXXRecordDecl (lldb::clang_type_t opaque_clang_qual_type)
1770+
{
1771+
if (opaque_clang_qual_type)
1772+
return clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)->getAsCXXRecordDecl();
1773+
return NULL;
1774+
}
17681775

17691776
bool
17701777
lldb_private::operator == (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)

0 commit comments

Comments
 (0)