Added a fix that should help incorrect type uniquing. There was an issue

for templatized types that could cause parts of a std::vector (and I am sure
other STL types) to be incorrectly uniqued to each other wreaking havoc on 
variable display for types within the same executable module.

llvm-svn: 127662
This commit is contained in:
Greg Clayton 2011-03-15 04:38:20 +00:00
parent 3ad0572d2e
commit 3690964ca1
3 changed files with 88 additions and 13 deletions

View File

@ -2986,6 +2986,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
ConstString type_name_const_str;
Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
size_t byte_size = 0;
bool byte_size_valid = false;
Declaration decl;
Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
@ -3028,7 +3029,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
type_name_cstr = form_value.AsCString(&get_debug_str_data());
type_name_const_str.SetCString(type_name_cstr);
break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
case DW_AT_encoding: encoding = form_value.Unsigned(); break;
case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
default:
@ -3150,6 +3151,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
case DW_AT_byte_size:
byte_size = form_value.Unsigned();
byte_size_valid = true;
break;
case DW_AT_accessibility:
@ -3182,8 +3184,11 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
if (decl.IsValid())
{
if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
this,
dwarf_cu,
die,
decl,
byte_size_valid ? byte_size : -1,
unique_ast_entry))
{
// We have already parsed this type or from another
@ -3280,6 +3285,8 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
// end up creating many copies of the same type over
// and over in the ASTContext for our module
unique_ast_entry.m_type_sp = type_sp;
unique_ast_entry.m_symfile = this;
unique_ast_entry.m_cu = dwarf_cu;
unique_ast_entry.m_die = die;
unique_ast_entry.m_declaration = decl;
GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
@ -3333,7 +3340,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
type_name_const_str.SetCString(type_name_cstr);
break;
case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
case DW_AT_allocated:
@ -3691,7 +3698,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
break;
case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;

View File

@ -20,20 +20,64 @@
bool
UniqueDWARFASTTypeList::Find
(
SymbolFileDWARF *symfile,
const DWARFCompileUnit *cu,
const DWARFDebugInfoEntry *die,
const lldb_private::Declaration &decl,
const int32_t byte_size,
UniqueDWARFASTType &entry
) const
{
collection::const_iterator pos, end = m_collection.end();
for (pos = m_collection.begin(); pos != end; ++pos)
{
// Make sure the tags match
if (pos->m_die->Tag() == die->Tag())
{
if (pos->m_declaration == decl)
// Validate byte sizes of both types only if both are valid.
if (pos->m_byte_size < 0 || byte_size < 0 || pos->m_byte_size == byte_size)
{
entry = *pos;
return true;
// Make sure the file and line match
if (pos->m_declaration == decl)
{
// The type has the same name, and was defined on the same
// file and line. Now verify all of the parent DIEs match.
const DWARFDebugInfoEntry *parent_arg_die = die->GetParent();
const DWARFDebugInfoEntry *parend_pos_die = pos->m_die->GetParent();
bool match = true;
bool done = false;
while (!done && match && parent_arg_die && parend_pos_die)
{
if (parent_arg_die->Tag() == parend_pos_die->Tag())
{
const dw_tag_t tag = parent_arg_die->Tag();
switch (tag)
{
case DW_TAG_class_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_namespace:
{
const char *parent_arg_die_name = parent_arg_die->GetName(symfile, cu);
const char *parent_pos_die_name = parend_pos_die->GetName(pos->m_symfile, pos->m_cu);
if (strcmp (parent_arg_die_name, parent_pos_die_name))
match = false;
}
break;
case DW_TAG_compile_unit:
done = true;
break;
}
}
}
if (match)
{
entry = *pos;
return true;
}
}
}
}
}

View File

@ -32,24 +32,36 @@ public:
//------------------------------------------------------------------
UniqueDWARFASTType () :
m_type_sp (),
m_symfile (NULL),
m_cu (NULL),
m_die (NULL),
m_declaration ()
m_declaration (),
m_byte_size (-1) // Set to negative value to make sure we have a valid value
{
}
UniqueDWARFASTType (lldb::TypeSP &type_sp,
SymbolFileDWARF *symfile,
DWARFCompileUnit *cu,
DWARFDebugInfoEntry *die,
const lldb_private::Declaration &decl) :
const lldb_private::Declaration &decl,
int32_t byte_size) :
m_type_sp (type_sp),
m_symfile (symfile),
m_cu (cu),
m_die (die),
m_declaration (decl)
m_declaration (decl),
m_byte_size (byte_size)
{
}
UniqueDWARFASTType (const UniqueDWARFASTType &rhs) :
m_type_sp (rhs.m_type_sp),
m_symfile (rhs.m_symfile),
m_cu (rhs.m_cu),
m_die (rhs.m_die),
m_declaration (rhs.m_declaration)
m_declaration (rhs.m_declaration),
m_byte_size (rhs.m_byte_size)
{
}
@ -63,15 +75,21 @@ public:
if (this != &rhs)
{
m_type_sp = rhs.m_type_sp;
m_symfile = rhs.m_symfile;
m_cu = rhs.m_cu;
m_die = rhs.m_die;
m_declaration = rhs.m_declaration;
m_byte_size = rhs.m_byte_size;
}
return *this;
}
lldb::TypeSP m_type_sp;
SymbolFileDWARF *m_symfile;
const DWARFCompileUnit *m_cu;
const DWARFDebugInfoEntry *m_die;
lldb_private::Declaration m_declaration;
lldb_private::Declaration m_declaration;
int32_t m_byte_size;
};
class UniqueDWARFASTTypeList
@ -99,8 +117,11 @@ public:
}
bool
Find (const DWARFDebugInfoEntry *die,
Find (SymbolFileDWARF *symfile,
const DWARFCompileUnit *cu,
const DWARFDebugInfoEntry *die,
const lldb_private::Declaration &decl,
const int32_t byte_size,
UniqueDWARFASTType &entry) const;
protected:
@ -129,15 +150,18 @@ public:
bool
Find (const lldb_private::ConstString &name,
SymbolFileDWARF *symfile,
const DWARFCompileUnit *cu,
const DWARFDebugInfoEntry *die,
const lldb_private::Declaration &decl,
const int32_t byte_size,
UniqueDWARFASTType &entry) const
{
const char *unique_name_cstr = name.GetCString();
collection::const_iterator pos = m_collection.find (unique_name_cstr);
if (pos != m_collection.end())
{
return pos->second.Find (die, decl, entry);
return pos->second.Find (symfile, cu, die, decl, byte_size, entry);
}
return false;
}