forked from OSchip/llvm-project
Fixed an issue where we might accept the wrong type when completing
a type when we have a forward declaration. We always have found a type by basename, but now we also compare the decl context of the die we are trying to complete with the matches we find from the accelerator tables to ensure we get the right one. llvm-svn: 149593
This commit is contained in:
parent
3a20bc3652
commit
890ff5615a
|
@ -1726,6 +1726,18 @@ DWARFDebugInfoEntry::BuildFunctionAddressRangeTable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DWARFDebugInfoEntry::GetDeclContextDIEs (SymbolFileDWARF* dwarf2Data,
|
||||||
|
DWARFCompileUnit* cu,
|
||||||
|
DWARFDIECollection &decl_context_dies) const
|
||||||
|
{
|
||||||
|
const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
|
||||||
|
if (parent_decl_ctx_die && parent_decl_ctx_die != this)
|
||||||
|
{
|
||||||
|
decl_context_dies.Append(parent_decl_ctx_die);
|
||||||
|
parent_decl_ctx_die->GetDeclContextDIEs (dwarf2Data, cu, decl_context_dies);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const DWARFDebugInfoEntry *
|
const DWARFDebugInfoEntry *
|
||||||
DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
|
DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
|
||||||
|
|
|
@ -355,6 +355,10 @@ public:
|
||||||
const DWARFDebugInfoEntry* GetFirstChild() const { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; }
|
const DWARFDebugInfoEntry* GetFirstChild() const { return (HasChildren() && !m_empty_children) ? this + 1 : NULL; }
|
||||||
|
|
||||||
|
|
||||||
|
void GetDeclContextDIEs (SymbolFileDWARF* dwarf2Data,
|
||||||
|
DWARFCompileUnit* cu,
|
||||||
|
DWARFDIECollection &decl_context_dies) const;
|
||||||
|
|
||||||
const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
|
const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
|
||||||
DWARFCompileUnit* cu) const;
|
DWARFCompileUnit* cu) const;
|
||||||
const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
|
const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
|
||||||
|
|
|
@ -4045,6 +4045,60 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry
|
||||||
return type_sp;
|
return type_sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugInfoEntry *die1,
|
||||||
|
DWARFCompileUnit* cu2, const DWARFDebugInfoEntry *die2)
|
||||||
|
{
|
||||||
|
assert (die1 != die2);
|
||||||
|
DWARFDIECollection decl_ctx_1;
|
||||||
|
DWARFDIECollection decl_ctx_2;
|
||||||
|
die1->GetDeclContextDIEs (this, cu1, decl_ctx_1);
|
||||||
|
die1->GetDeclContextDIEs (this, cu2, decl_ctx_2);
|
||||||
|
const size_t count1 = decl_ctx_1.Size();
|
||||||
|
const size_t count2 = decl_ctx_2.Size();
|
||||||
|
if (count1 != count2)
|
||||||
|
return false;
|
||||||
|
const DWARFDebugInfoEntry *decl_ctx_die1;
|
||||||
|
const DWARFDebugInfoEntry *decl_ctx_die2;
|
||||||
|
size_t i;
|
||||||
|
for (i=0; i<count1; i++)
|
||||||
|
{
|
||||||
|
decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
|
||||||
|
decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
|
||||||
|
if (decl_ctx_die1->Tag() != decl_ctx_die2->Tag())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Make sure the top item in the decl context die array is always a compile unit
|
||||||
|
#if defined LLDB_CONFIGURATION_DEBUG
|
||||||
|
assert (decl_ctx_1.GetDIEPtrAtIndex (count1 - 1)->Tag() == DW_TAG_compile_unit);
|
||||||
|
#endif
|
||||||
|
// Always skip the compile unit when comparing by only iterating up to
|
||||||
|
// "count1 - 1"
|
||||||
|
for (i=0; i<count1 - 1; i++)
|
||||||
|
{
|
||||||
|
decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
|
||||||
|
decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
|
||||||
|
const char *name1 = decl_ctx_die1->GetName(this, cu1);
|
||||||
|
const char *name2 = decl_ctx_die1->GetName(this, cu2);
|
||||||
|
// If the string was from a DW_FORM_strp, then the pointer will often
|
||||||
|
// be the same!
|
||||||
|
if (name1 != name2)
|
||||||
|
{
|
||||||
|
if (name1 && name2)
|
||||||
|
{
|
||||||
|
// If the strings don't compare, we are done...
|
||||||
|
if (strcmp(name1, name2) != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// One name was NULL while the other wasn't
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// This function can be used when a DIE is found that is a forward declaration
|
// This function can be used when a DIE is found that is a forward declaration
|
||||||
// DIE and we want to try and find a type that has the complete definition.
|
// DIE and we want to try and find a type that has the complete definition.
|
||||||
|
@ -4136,19 +4190,23 @@ SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
|
||||||
|
|
||||||
if (try_resolving_type)
|
if (try_resolving_type)
|
||||||
{
|
{
|
||||||
Type *resolved_type = ResolveType (type_cu, type_die, false);
|
// Make sure the decl contexts match all the way up
|
||||||
if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
|
if (DIEDeclContextsMatch(cu, die, type_cu, type_die))
|
||||||
{
|
{
|
||||||
DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
|
Type *resolved_type = ResolveType (type_cu, type_die, false);
|
||||||
MakeUserID(die->GetOffset()),
|
if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
|
||||||
MakeUserID(curr_cu->GetOffset()),
|
{
|
||||||
m_obj_file->GetFileSpec().GetFilename().AsCString(),
|
DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
|
||||||
MakeUserID(type_die->GetOffset()),
|
MakeUserID(die->GetOffset()),
|
||||||
MakeUserID(type_cu->GetOffset()));
|
MakeUserID(curr_cu->GetOffset()),
|
||||||
|
m_obj_file->GetFileSpec().GetFilename().AsCString(),
|
||||||
m_die_to_type[die] = resolved_type;
|
MakeUserID(type_die->GetOffset()),
|
||||||
type_sp = resolved_type->shared_from_this();
|
MakeUserID(type_cu->GetOffset()));
|
||||||
break;
|
|
||||||
|
m_die_to_type[die] = resolved_type;
|
||||||
|
type_sp = resolved_type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -503,6 +503,9 @@ protected:
|
||||||
int tag_decl_kind,
|
int tag_decl_kind,
|
||||||
const lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
|
const lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
|
||||||
|
|
||||||
|
bool
|
||||||
|
DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugInfoEntry *die1,
|
||||||
|
DWARFCompileUnit* cu2, const DWARFDebugInfoEntry *die2);
|
||||||
|
|
||||||
SymbolFileDWARFDebugMap * m_debug_map_symfile;
|
SymbolFileDWARFDebugMap * m_debug_map_symfile;
|
||||||
clang::TranslationUnitDecl * m_clang_tu_decl;
|
clang::TranslationUnitDecl * m_clang_tu_decl;
|
||||||
|
|
Loading…
Reference in New Issue