From 890ff5615a043ee4163efe523d2fb4e5945e2c48 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Thu, 2 Feb 2012 05:48:16 +0000 Subject: [PATCH] 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 --- .../SymbolFile/DWARF/DWARFDebugInfoEntry.cpp | 12 +++ .../SymbolFile/DWARF/DWARFDebugInfoEntry.h | 4 + .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 82 ++++++++++++++++--- .../SymbolFile/DWARF/SymbolFileDWARF.h | 3 + 4 files changed, 89 insertions(+), 12 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 4cc6334c00b6..f55bab69d232 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -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 * DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h index 9c2914f58402..cd55e5a89c6c 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -355,6 +355,10 @@ public: 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, DWARFCompileUnit* cu) const; const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 5e963508231f..7b9327f28bfb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -4045,6 +4045,60 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry 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; iTag() != 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; iGetName(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 // 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) { - Type *resolved_type = ResolveType (type_cu, type_die, false); - if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) + // Make sure the decl contexts match all the way up + 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", - MakeUserID(die->GetOffset()), - MakeUserID(curr_cu->GetOffset()), - m_obj_file->GetFileSpec().GetFilename().AsCString(), - MakeUserID(type_die->GetOffset()), - MakeUserID(type_cu->GetOffset())); - - m_die_to_type[die] = resolved_type; - type_sp = resolved_type->shared_from_this(); - break; + Type *resolved_type = ResolveType (type_cu, type_die, false); + if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) + { + DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n", + MakeUserID(die->GetOffset()), + MakeUserID(curr_cu->GetOffset()), + m_obj_file->GetFileSpec().GetFilename().AsCString(), + MakeUserID(type_die->GetOffset()), + MakeUserID(type_cu->GetOffset())); + + m_die_to_type[die] = resolved_type; + type_sp = resolved_type; + break; + } } } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 72ac34656fa3..8c98d74f6974 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -503,6 +503,9 @@ protected: int tag_decl_kind, 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; clang::TranslationUnitDecl * m_clang_tu_decl;