Fixed an issue where we could end up creating multiple
C++ methods for a function depending on how the DWARF was created. Now we parse the class type from the definition, and all methods that use DW_AT_specification or DW_AT_abstract_origin attributes to point to the definition, now won't create duplicate entries. This is in response to how clang++ creates much different DWARF than gcc. llvm-svn: 137737
This commit is contained in:
parent
acb07b599c
commit
72da397a69
|
|
@ -3539,6 +3539,8 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
|
|||
bool is_static = false;
|
||||
bool is_virtual = false;
|
||||
bool is_explicit = false;
|
||||
dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
|
||||
dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
|
||||
|
||||
unsigned type_quals = 0;
|
||||
clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
|
||||
|
|
@ -3582,6 +3584,15 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
|
|||
}
|
||||
break;
|
||||
|
||||
case DW_AT_specification:
|
||||
specification_die_offset = form_value.Reference(dwarf_cu);
|
||||
break;
|
||||
|
||||
case DW_AT_abstract_origin:
|
||||
abstract_origin_die_offset = form_value.Reference(dwarf_cu);
|
||||
break;
|
||||
|
||||
|
||||
case DW_AT_allocated:
|
||||
case DW_AT_associated:
|
||||
case DW_AT_address_class:
|
||||
|
|
@ -3600,13 +3611,11 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
|
|||
case DW_AT_recursive:
|
||||
case DW_AT_return_addr:
|
||||
case DW_AT_segment:
|
||||
case DW_AT_specification:
|
||||
case DW_AT_start_scope:
|
||||
case DW_AT_static_link:
|
||||
case DW_AT_trampoline:
|
||||
case DW_AT_visibility:
|
||||
case DW_AT_vtable_elem_location:
|
||||
case DW_AT_abstract_origin:
|
||||
case DW_AT_description:
|
||||
case DW_AT_sibling:
|
||||
break;
|
||||
|
|
@ -3723,6 +3732,26 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
|
|||
// C++ method
|
||||
Type *class_type = ResolveType (dwarf_cu, m_decl_ctx_to_die[containing_decl_ctx]);
|
||||
if (class_type)
|
||||
{
|
||||
if (specification_die_offset != DW_INVALID_OFFSET)
|
||||
{
|
||||
// If we have a specification, then the function type should have been
|
||||
// made with the specification and not with this die.
|
||||
DWARFCompileUnitSP spec_cu_sp;
|
||||
const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
|
||||
if (m_die_to_decl_ctx[spec_die] == NULL)
|
||||
fprintf (stderr,"warning: 0x%8.8x: DW_AT_specification(0x%8.8x) has no decl\n", die->GetOffset(), specification_die_offset);
|
||||
type_handled = true;
|
||||
}
|
||||
else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
|
||||
{
|
||||
DWARFCompileUnitSP abs_cu_sp;
|
||||
const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
|
||||
if (m_die_to_decl_ctx[abs_die] == NULL)
|
||||
fprintf (stderr,"warning: 0x%8.8x: DW_AT_abstract_origin(0x%8.8x) has no decl\n", die->GetOffset(), abstract_origin_die_offset);
|
||||
type_handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
clang_type_t class_opaque_type = class_type->GetClangForwardType();
|
||||
if (ClangASTContext::IsCXXClassType (class_opaque_type))
|
||||
|
|
@ -3758,6 +3787,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!type_handled)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue