forked from OSchip/llvm-project
<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:🅱️:Foo;".
llvm-svn: 155488
This commit is contained in:
parent
7af41ccdc4
commit
a8022fa70d
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_
|
|
@ -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,6 +4555,7 @@ 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,
|
||||
const DWARFDebugInfoEntry *die,
|
||||
|
@ -4551,6 +4563,12 @@ SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
|
|||
{
|
||||
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;
|
||||
|
||||
|
@ -4704,6 +4722,158 @@ SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
|
|||
return type_sp;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
@ -410,6 +410,9 @@ protected:
|
|||
const DWARFDebugInfoEntry *die,
|
||||
const lldb_private::ConstString &type_name);
|
||||
|
||||
lldb::TypeSP FindDefinitionTypeForDWARFDeclContext (
|
||||
const DWARFDeclContext &die_decl_ctx);
|
||||
|
||||
lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE (
|
||||
const DWARFDebugInfoEntry *die,
|
||||
const lldb_private::ConstString &type_name,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue