diff options
author | Greg Clayton <gclayton@apple.com> | 2012-04-24 21:22:41 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2012-04-24 21:22:41 +0000 |
commit | a8022fa70de20171d95d54d6921d7a32d7108a77 (patch) | |
tree | afd27119820040a5e5912a60e2b3f22abd5aa76f | |
parent | 7af41ccdc478f8bf27694f3d17fa60df4d534fc9 (diff) | |
download | bcm5719-llvm-a8022fa70de20171d95d54d6921d7a32d7108a77.tar.gz bcm5719-llvm-a8022fa70de20171d95d54d6921d7a32d7108a77.zip |
<rdar://problem/11291668>
Fixed an issue that would happen when using debug map with DWARF in the .o files where we wouldn't ever track down the actual definition for a type when things were in namespaces. We now serialize the decl context information into an intermediate format which allows us to track down the correct definition for a type regardless of which DWARF symbol file it comes from. We do this by creating a "DWARFDeclContext" object that contains the DW_TAG + name for each item in a decl context which we can then use to veto potential accelerator table matches. For example, the accelerator tables store the basename of the type, so if you have "std::vector<int>", we would end up with an accelerator table entry for the type that contained "vector<int>", which we would then search for using a DWARFDeclContext object that contained:
[0] DW_TAG_class_type "vector<int>"
[1] DW_TAG_namespace "std"
This is currently used to track down forward declarations for things like "class a::b::Foo;".
llvm-svn: 155488
11 files changed, 444 insertions, 13 deletions
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 23faccda26b..e6229bb7fb6 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -386,6 +386,8 @@ 26A527C414E24F5F00F3A14A /* ThreadMachCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 26A527C014E24F5F00F3A14A /* ThreadMachCore.h */; }; 26A69C5F137A17A500262477 /* RegisterValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C6886E137880C400407EDF /* RegisterValue.cpp */; }; 26A7A035135E6E4200FB369E /* NamedOptionValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A7A034135E6E4200FB369E /* NamedOptionValue.cpp */; }; + 26B1EFAE154638AF00E2DAC7 /* DWARFDeclContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26B1EFAC154638AF00E2DAC7 /* DWARFDeclContext.cpp */; }; + 26B1EFAF154638AF00E2DAC7 /* DWARFDeclContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 26B1EFAD154638AF00E2DAC7 /* DWARFDeclContext.h */; }; 26B1FCB813381071002886E2 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C39010F3FA26009D5894 /* CoreFoundation.framework */; }; 26B1FCBC13381071002886E2 /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C37410F3F61B009D5894 /* libobjc.dylib */; }; 26B1FCC21338115F002886E2 /* Host.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EE810F1B88F00F91463 /* Host.mm */; }; @@ -923,6 +925,8 @@ 26A7A034135E6E4200FB369E /* NamedOptionValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NamedOptionValue.cpp; path = source/Interpreter/NamedOptionValue.cpp; sourceTree = "<group>"; }; 26A7A036135E6E5300FB369E /* NamedOptionValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NamedOptionValue.h; path = include/lldb/Interpreter/NamedOptionValue.h; sourceTree = "<group>"; }; 26B167A41123BF5500DC7B4F /* ThreadSafeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSafeValue.h; path = include/lldb/Core/ThreadSafeValue.h; sourceTree = "<group>"; }; + 26B1EFAC154638AF00E2DAC7 /* DWARFDeclContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DWARFDeclContext.cpp; sourceTree = "<group>"; }; + 26B1EFAD154638AF00E2DAC7 /* DWARFDeclContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWARFDeclContext.h; sourceTree = "<group>"; }; 26B42C4C1187ABA50079C8C8 /* LLDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLDB.h; path = include/lldb/API/LLDB.h; sourceTree = "<group>"; }; 26B4E26E112F35F700AB3F64 /* TimeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TimeValue.h; path = include/lldb/Host/TimeValue.h; sourceTree = "<group>"; }; 26B7564C14F89356008D9CB3 /* PlatformiOSSimulator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformiOSSimulator.cpp; sourceTree = "<group>"; }; @@ -1832,6 +1836,8 @@ 260C89CC10F57C5600BB2B04 /* DWARFDebugPubnamesSet.h */, 260C89CD10F57C5600BB2B04 /* DWARFDebugRanges.cpp */, 260C89CE10F57C5600BB2B04 /* DWARFDebugRanges.h */, + 26B1EFAC154638AF00E2DAC7 /* DWARFDeclContext.cpp */, + 26B1EFAD154638AF00E2DAC7 /* DWARFDeclContext.h */, 260C89CF10F57C5600BB2B04 /* DWARFDefines.cpp */, 260C89D010F57C5600BB2B04 /* DWARFDefines.h */, 260C89D110F57C5600BB2B04 /* DWARFDIECollection.cpp */, @@ -3195,6 +3201,7 @@ 2694E99E14FC0BB30076DE67 /* PlatformFreeBSD.h in Headers */, 2694E9A514FC0BBD0076DE67 /* PlatformLinux.h in Headers */, 2663E379152BD1890091EC22 /* ReadWriteLock.h in Headers */, + 26B1EFAF154638AF00E2DAC7 /* DWARFDeclContext.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3907,6 +3914,7 @@ 26FFC19D14FC072100087D58 /* DynamicLoaderPOSIXDYLD.cpp in Sources */, 2694E99D14FC0BB30076DE67 /* PlatformFreeBSD.cpp in Sources */, 2694E9A414FC0BBD0076DE67 /* PlatformLinux.cpp in Sources */, + 26B1EFAE154638AF00E2DAC7 /* DWARFDeclContext.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index dbfc0a1039b..68b95162afe 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -184,6 +184,23 @@ DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx) return cu; } +bool +DWARFDebugInfo::ContainsCompileUnit (const DWARFCompileUnit *cu) const +{ + // Not a verify efficient function, but it is handy for use in assertions + // to make sure that a compile unit comes from a debug information file. + CompileUnitColl::const_iterator end_pos = m_compile_units.end(); + CompileUnitColl::const_iterator pos; + + for (pos = m_compile_units.begin(); pos != end_pos; ++pos) + { + if (pos->get() == cu) + return true; + } + return false; +} + + static bool CompileUnitOffsetLessThan (const DWARFCompileUnitSP& a, const DWARFCompileUnitSP& b) { return a->GetOffset() < b->GetOffset(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h index caa55857765..b9010cdefaa 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -46,6 +46,7 @@ public: void AddCompileUnit(DWARFCompileUnitSP& cu); uint32_t GetNumCompileUnits(); + bool ContainsCompileUnit (const DWARFCompileUnit *cu) const; DWARFCompileUnit* GetCompileUnitAtIndex(uint32_t idx); DWARFCompileUnitSP GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr = NULL); DWARFCompileUnitSP GetCompileUnitContainingDIE(dw_offset_t die_offset); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index f55bab69d23..1fc5e573c6f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -23,6 +23,7 @@ #include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" +#include "DWARFDeclContext.h" #include "DWARFDIECollection.h" #include "DWARFFormValue.h" #include "DWARFLocationDescription.h" @@ -1739,6 +1740,36 @@ DWARFDebugInfoEntry::GetDeclContextDIEs (SymbolFileDWARF* dwarf2Data, } } +void +DWARFDebugInfoEntry::GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data, + DWARFCompileUnit* cu, + DWARFDeclContext &dwarf_decl_ctx) const +{ + const dw_tag_t tag = Tag(); + if (tag != DW_TAG_compile_unit) + { + dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu)); + const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu); + if (parent_decl_ctx_die && parent_decl_ctx_die != this) + { + if (parent_decl_ctx_die->Tag() != DW_TAG_compile_unit) + parent_decl_ctx_die->GetDWARFDeclContext (dwarf2Data, cu, dwarf_decl_ctx); + } + } +} + + +bool +DWARFDebugInfoEntry::MatchesDWARFDeclContext (SymbolFileDWARF* dwarf2Data, + DWARFCompileUnit* cu, + const DWARFDeclContext &dwarf_decl_ctx) const +{ + + DWARFDeclContext this_dwarf_decl_ctx; + GetDWARFDeclContext (dwarf2Data, cu, this_dwarf_decl_ctx); + return this_dwarf_decl_ctx == dwarf_decl_ctx; +} + const DWARFDebugInfoEntry * DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, DWARFCompileUnit* cu) const diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h index cd55e5a89c6..0a97bbd1ec7 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -41,6 +41,8 @@ typedef std::multimap<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMMap; typedef UInt32ToDIEMMap::iterator UInt32ToDIEMMapIter; typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter; +class DWARFDeclContext; + #define DIE_SIBLING_IDX_BITSIZE 31 #define DIE_ABBR_IDX_BITSIZE 15 @@ -359,6 +361,15 @@ public: DWARFCompileUnit* cu, DWARFDIECollection &decl_context_dies) const; + void GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data, + DWARFCompileUnit* cu, + DWARFDeclContext &dwarf_decl_ctx) const; + + + bool MatchesDWARFDeclContext(SymbolFileDWARF* dwarf2Data, + DWARFCompileUnit* cu, + const DWARFDeclContext &dwarf_decl_ctx) const; + const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, DWARFCompileUnit* cu) const; const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp new file mode 100644 index 00000000000..2c1c59be1d2 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp @@ -0,0 +1,82 @@ +//===-- DWARFDeclContext.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFDeclContext.h" + +const char * +DWARFDeclContext::GetQualifiedName () const +{ + if (m_qualified_name.empty()) + { + // The declaration context array for a class named "foo" in namespace + // "a::b::c" will be something like: + // [0] DW_TAG_class_type "foo" + // [1] DW_TAG_namespace "c" + // [2] DW_TAG_namespace "b" + // [3] DW_TAG_namespace "a" + if (!m_entries.empty()) + { + if (m_entries.size() == 1) + { + if (m_entries[0].name) + { + m_qualified_name.append("::"); + m_qualified_name.append(m_entries[0].name); + } + } + else + { + collection::const_reverse_iterator pos; + collection::const_reverse_iterator begin = m_entries.rbegin(); + collection::const_reverse_iterator end = m_entries.rend(); + for (pos = begin; pos != end; ++pos) + { + if (pos != begin) + m_qualified_name.append("::"); + m_qualified_name.append(pos->name); + } + } + } + } + if (m_qualified_name.empty()) + return NULL; + return m_qualified_name.c_str(); +} + + +bool +DWARFDeclContext::operator==(const DWARFDeclContext& rhs) const +{ + if (m_entries.size() != rhs.m_entries.size()) + return false; + + collection::const_iterator pos; + collection::const_iterator begin = m_entries.begin(); + collection::const_iterator end = m_entries.end(); + + collection::const_iterator rhs_pos; + collection::const_iterator rhs_begin = rhs.m_entries.begin(); + // The two entry arrays have the same size + + // First compare the tags before we do expensize name compares + for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) + { + if (pos->tag != rhs_pos->tag) + return false; + } + // The tags all match, now compare the names + for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos) + { + if (!pos->NameMatches (*rhs_pos)) + return false; + } + // All tags and names match + return true; +} + diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h new file mode 100644 index 00000000000..85c97f1c68f --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h @@ -0,0 +1,107 @@ +//===-- DWARFDeclContext.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef SymbolFileDWARF_DWARFDeclContext_h_ +#define SymbolFileDWARF_DWARFDeclContext_h_ + +// C Includes +// C++ Includes +#include <string> +#include <vector> +// Other libraries and framework includes +#include "lldb/Core/ConstString.h" +// Project includes +#include "DWARFDefines.h" + +//---------------------------------------------------------------------- +// DWARFDeclContext +// +// A class that represents a declaration context all the way down to a +// DIE. This is useful when trying to find a DIE in one DWARF to a DIE +// in another DWARF file. +//---------------------------------------------------------------------- + +class DWARFDeclContext +{ +public: + struct Entry + { + Entry () : + tag(0), + name(NULL) + { + } + Entry (dw_tag_t t, const char *n) : + tag(t), + name(n) + { + } + + bool + NameMatches (const Entry& rhs) const + { + if (name && rhs.name) + return strcmp(name, rhs.name) == 0; + return name == NULL && rhs.name == NULL; + } + + // Test operator + operator bool() const + { + return tag != 0; + } + + dw_tag_t tag; + const char *name; + }; + + DWARFDeclContext () : + m_entries() + { + } + + void + AppendDeclContext (dw_tag_t tag, const char *name) + { + m_entries.push_back(Entry(tag, name)); + } + + bool + operator ==(const DWARFDeclContext& rhs) const; + + uint32_t + GetSize() const + { + return m_entries.size(); + } + + Entry & + operator[] (uint32_t idx) + { + // "idx" must be valid + return m_entries[idx]; + } + + const Entry & + operator[] (uint32_t idx) const + { + // "idx" must be valid + return m_entries[idx]; + } + + const char * + GetQualifiedName () const; + +protected: + typedef std::vector<Entry> collection; + collection m_entries; + mutable std::string m_qualified_name; +}; + +#endif // SymbolFileDWARF_DWARFDeclContext_h_ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 7660569766b..1ad818a91f9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -57,6 +57,7 @@ #include "DWARFDebugLine.h" #include "DWARFDebugPubnames.h" #include "DWARFDebugRanges.h" +#include "DWARFDeclContext.h" #include "DWARFDIECollection.h" #include "DWARFFormValue.h" #include "DWARFLocationList.h" @@ -4447,6 +4448,7 @@ SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry return type_sp; } + //---------------------------------------------------------------------- // This function helps to ensure that the declaration contexts match for // two different DIEs. Often times debug information will refer to a @@ -4463,7 +4465,16 @@ bool SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugInfoEntry *die1, DWARFCompileUnit* cu2, const DWARFDebugInfoEntry *die2) { - assert (die1 != die2); + if (die1 == die2) + return true; + +#if defined (LLDB_CONFIGURATION_DEBUG) + // You can't and shouldn't call this function with a compile unit from + // two different SymbolFileDWARF instances. + assert (DebugInfo()->ContainsCompileUnit (cu1)); + assert (DebugInfo()->ContainsCompileUnit (cu2)); +#endif + DWARFDIECollection decl_ctx_1; DWARFDIECollection decl_ctx_2; //The declaration DIE stack is a stack of the declaration context @@ -4544,13 +4555,20 @@ SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugIn // 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. +// "cu" and "die" must be from this SymbolFileDWARF TypeSP -SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu, +SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu, const DWARFDebugInfoEntry *die, const ConstString &type_name) { TypeSP type_sp; +#if defined (LLDB_CONFIGURATION_DEBUG) + // You can't and shouldn't call this function with a compile unit from + // another SymbolFileDWARF instance. + assert (DebugInfo()->ContainsCompileUnit (cu)); +#endif + if (cu == NULL || die == NULL || !type_name) return type_sp; @@ -4705,6 +4723,158 @@ SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu, } TypeSP +SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx) +{ + TypeSP type_sp; + + const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize(); + if (dwarf_decl_ctx_count > 0) + { + const ConstString type_name(dwarf_decl_ctx[0].name); + const dw_tag_t tag = dwarf_decl_ctx[0].tag; + + if (type_name) + { + LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS)); + if (log) + { + GetObjectFile()->GetModule()->LogMessage (log.get(), + "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')", + DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), + dwarf_decl_ctx.GetQualifiedName()); + } + + DIEArray die_offsets; + + if (m_using_apple_tables) + { + if (m_apple_types_ap.get()) + { + if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1) + { + m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets); + } + else + { + m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets); + } + } + } + else + { + if (!m_indexed) + Index (); + + m_type_index.Find (type_name, die_offsets); + } + + const size_t num_matches = die_offsets.size(); + + + DWARFCompileUnit* type_cu = NULL; + const DWARFDebugInfoEntry* type_die = NULL; + if (num_matches) + { + DWARFDebugInfo* debug_info = DebugInfo(); + for (size_t i=0; i<num_matches; ++i) + { + const dw_offset_t die_offset = die_offsets[i]; + type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu); + + if (type_die) + { + bool try_resolving_type = false; + + // Don't try and resolve the DIE we are looking for with the DIE itself! + const dw_tag_t type_tag = type_die->Tag(); + // Make sure the tags match + if (type_tag == tag) + { + // The tags match, lets try resolving this type + try_resolving_type = true; + } + else + { + // The tags don't match, but we need to watch our for a + // forward declaration for a struct and ("struct foo") + // ends up being a class ("class foo { ... };") or + // vice versa. + switch (type_tag) + { + case DW_TAG_class_type: + // We had a "class foo", see if we ended up with a "struct foo { ... };" + try_resolving_type = (tag == DW_TAG_structure_type); + break; + case DW_TAG_structure_type: + // We had a "struct foo", see if we ended up with a "class foo { ... };" + try_resolving_type = (tag == DW_TAG_class_type); + break; + default: + // Tags don't match, don't event try to resolve + // using this type whose name matches.... + break; + } + } + + if (try_resolving_type) + { + DWARFDeclContext type_dwarf_decl_ctx; + type_die->GetDWARFDeclContext (this, type_cu, type_dwarf_decl_ctx); + + if (log) + { + GetObjectFile()->GetModule()->LogMessage (log.get(), + "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)", + DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), + dwarf_decl_ctx.GetQualifiedName(), + type_die->GetOffset(), + type_dwarf_decl_ctx.GetQualifiedName()); + } + + // Make sure the decl contexts match all the way up + if (dwarf_decl_ctx == type_dwarf_decl_ctx) + { + Type *resolved_type = ResolveType (type_cu, type_die, false); + if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) + { + type_sp = resolved_type->shared_from_this(); + break; + } + } + } + else + { + if (log) + { + std::string qualified_name; + type_die->GetQualifiedName(this, type_cu, qualified_name); + GetObjectFile()->GetModule()->LogMessage (log.get(), + "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)", + DW_TAG_value_to_name(dwarf_decl_ctx[0].tag), + dwarf_decl_ctx.GetQualifiedName(), + type_die->GetOffset(), + qualified_name.c_str()); + } + } + } + else + { + if (m_using_apple_tables) + { + GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", + die_offset, type_name.GetCString()); + } + } + + } + } + } + } + return type_sp; +} + + +TypeSP SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr) { TypeSP type_sp; @@ -5136,14 +5306,18 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, type_name_cstr); } - type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); + DWARFDeclContext die_decl_ctx; + die->GetDWARFDeclContext(this, dwarf_cu, die_decl_ctx); + + //type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); + type_sp = FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); if (!type_sp && m_debug_map_symfile) { // We weren't able to find a full declaration in // this DWARF, see if we have a declaration anywhere // else... - type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); + type_sp = m_debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); } if (type_sp) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index b0a66cce039..ad1e9359f14 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -40,13 +40,12 @@ #include "NameToDIE.h" #include "UniqueDWARFASTType.h" - //---------------------------------------------------------------------- // Forward Declarations for this DWARF plugin //---------------------------------------------------------------------- class DWARFAbbreviationDeclaration; class DWARFAbbreviationDeclarationSet; -class DWARFCompileUnit; +class DWARFileUnit; class DWARFDebugAbbrev; class DWARFDebugAranges; class DWARFDebugInfo; @@ -54,6 +53,7 @@ class DWARFDebugInfoEntry; class DWARFDebugLine; class DWARFDebugPubnames; class DWARFDebugRanges; +class DWARFDeclContext; class DWARFDIECollection; class DWARFFormValue; class SymbolFileDWARFDebugMap; @@ -409,6 +409,9 @@ protected: DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, const lldb_private::ConstString &type_name); + + lldb::TypeSP FindDefinitionTypeForDWARFDeclContext ( + const DWARFDeclContext &die_decl_ctx); lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE ( const DWARFDebugInfoEntry *die, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index c2bba5d157e..7e69d453cfb 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -957,15 +957,13 @@ SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool inc } TypeSP -SymbolFileDWARFDebugMap::FindDefinitionTypeForDIE (DWARFCompileUnit* cu, - const DWARFDebugInfoEntry *die, - const ConstString &type_name) +SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx) { TypeSP type_sp; SymbolFileDWARF *oso_dwarf; for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) { - type_sp = oso_dwarf->FindDefinitionTypeForDIE (cu, die, type_name); + type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); if (type_sp) break; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 4ac0f4c9772..d7b69e0b23e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -23,6 +23,7 @@ class SymbolFileDWARF; class DWARFCompileUnit; class DWARFDebugInfoEntry; +class DWARFDeclContext; class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile { @@ -227,9 +228,7 @@ protected: SetCompileUnit (SymbolFileDWARF *oso_dwarf, const lldb::CompUnitSP &cu_sp); lldb::TypeSP - FindDefinitionTypeForDIE (DWARFCompileUnit* cu, - const DWARFDebugInfoEntry *die, - const lldb_private::ConstString &type_name); + FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx); bool Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso); |