summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2012-02-02 05:48:16 +0000
committerGreg Clayton <gclayton@apple.com>2012-02-02 05:48:16 +0000
commit890ff5615a043ee4163efe523d2fb4e5945e2c48 (patch)
tree0a03a26a6178fdaa5723c53f3fb696ed6040b0dd
parent3a20bc36522ff1fbff82a34bc6bd63075c9179f9 (diff)
downloadbcm5719-llvm-890ff5615a043ee4163efe523d2fb4e5945e2c48.tar.gz
bcm5719-llvm-890ff5615a043ee4163efe523d2fb4e5945e2c48.zip
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
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp12
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h4
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp82
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h3
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 4cc6334c00b..f55bab69d23 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 9c2914f5840..cd55e5a89c6 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 5e963508231..7b9327f28bf 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; 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
// 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 72ac34656fa..8c98d74f697 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;
OpenPOWER on IntegriCloud