Skip to content

Commit a8022fa

Browse files
author
Greg Clayton
committed
<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
1 parent 7af41cc commit a8022fa

File tree

11 files changed

+444
-13
lines changed

11 files changed

+444
-13
lines changed

lldb/lldb.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,8 @@
386386
26A527C414E24F5F00F3A14A /* ThreadMachCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 26A527C014E24F5F00F3A14A /* ThreadMachCore.h */; };
387387
26A69C5F137A17A500262477 /* RegisterValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C6886E137880C400407EDF /* RegisterValue.cpp */; };
388388
26A7A035135E6E4200FB369E /* NamedOptionValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A7A034135E6E4200FB369E /* NamedOptionValue.cpp */; };
389+
26B1EFAE154638AF00E2DAC7 /* DWARFDeclContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26B1EFAC154638AF00E2DAC7 /* DWARFDeclContext.cpp */; };
390+
26B1EFAF154638AF00E2DAC7 /* DWARFDeclContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 26B1EFAD154638AF00E2DAC7 /* DWARFDeclContext.h */; };
389391
26B1FCB813381071002886E2 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C39010F3FA26009D5894 /* CoreFoundation.framework */; };
390392
26B1FCBC13381071002886E2 /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C37410F3F61B009D5894 /* libobjc.dylib */; };
391393
26B1FCC21338115F002886E2 /* Host.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EE810F1B88F00F91463 /* Host.mm */; };
@@ -923,6 +925,8 @@
923925
26A7A034135E6E4200FB369E /* NamedOptionValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NamedOptionValue.cpp; path = source/Interpreter/NamedOptionValue.cpp; sourceTree = "<group>"; };
924926
26A7A036135E6E5300FB369E /* NamedOptionValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NamedOptionValue.h; path = include/lldb/Interpreter/NamedOptionValue.h; sourceTree = "<group>"; };
925927
26B167A41123BF5500DC7B4F /* ThreadSafeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSafeValue.h; path = include/lldb/Core/ThreadSafeValue.h; sourceTree = "<group>"; };
928+
26B1EFAC154638AF00E2DAC7 /* DWARFDeclContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DWARFDeclContext.cpp; sourceTree = "<group>"; };
929+
26B1EFAD154638AF00E2DAC7 /* DWARFDeclContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWARFDeclContext.h; sourceTree = "<group>"; };
926930
26B42C4C1187ABA50079C8C8 /* LLDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLDB.h; path = include/lldb/API/LLDB.h; sourceTree = "<group>"; };
927931
26B4E26E112F35F700AB3F64 /* TimeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TimeValue.h; path = include/lldb/Host/TimeValue.h; sourceTree = "<group>"; };
928932
26B7564C14F89356008D9CB3 /* PlatformiOSSimulator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformiOSSimulator.cpp; sourceTree = "<group>"; };
@@ -1832,6 +1836,8 @@
18321836
260C89CC10F57C5600BB2B04 /* DWARFDebugPubnamesSet.h */,
18331837
260C89CD10F57C5600BB2B04 /* DWARFDebugRanges.cpp */,
18341838
260C89CE10F57C5600BB2B04 /* DWARFDebugRanges.h */,
1839+
26B1EFAC154638AF00E2DAC7 /* DWARFDeclContext.cpp */,
1840+
26B1EFAD154638AF00E2DAC7 /* DWARFDeclContext.h */,
18351841
260C89CF10F57C5600BB2B04 /* DWARFDefines.cpp */,
18361842
260C89D010F57C5600BB2B04 /* DWARFDefines.h */,
18371843
260C89D110F57C5600BB2B04 /* DWARFDIECollection.cpp */,
@@ -3195,6 +3201,7 @@
31953201
2694E99E14FC0BB30076DE67 /* PlatformFreeBSD.h in Headers */,
31963202
2694E9A514FC0BBD0076DE67 /* PlatformLinux.h in Headers */,
31973203
2663E379152BD1890091EC22 /* ReadWriteLock.h in Headers */,
3204+
26B1EFAF154638AF00E2DAC7 /* DWARFDeclContext.h in Headers */,
31983205
);
31993206
runOnlyForDeploymentPostprocessing = 0;
32003207
};
@@ -3907,6 +3914,7 @@
39073914
26FFC19D14FC072100087D58 /* DynamicLoaderPOSIXDYLD.cpp in Sources */,
39083915
2694E99D14FC0BB30076DE67 /* PlatformFreeBSD.cpp in Sources */,
39093916
2694E9A414FC0BBD0076DE67 /* PlatformLinux.cpp in Sources */,
3917+
26B1EFAE154638AF00E2DAC7 /* DWARFDeclContext.cpp in Sources */,
39103918
);
39113919
runOnlyForDeploymentPostprocessing = 0;
39123920
};

lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,23 @@ DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx)
184184
return cu;
185185
}
186186

187+
bool
188+
DWARFDebugInfo::ContainsCompileUnit (const DWARFCompileUnit *cu) const
189+
{
190+
// Not a verify efficient function, but it is handy for use in assertions
191+
// to make sure that a compile unit comes from a debug information file.
192+
CompileUnitColl::const_iterator end_pos = m_compile_units.end();
193+
CompileUnitColl::const_iterator pos;
194+
195+
for (pos = m_compile_units.begin(); pos != end_pos; ++pos)
196+
{
197+
if (pos->get() == cu)
198+
return true;
199+
}
200+
return false;
201+
}
202+
203+
187204
static bool CompileUnitOffsetLessThan (const DWARFCompileUnitSP& a, const DWARFCompileUnitSP& b)
188205
{
189206
return a->GetOffset() < b->GetOffset();

lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class DWARFDebugInfo
4646

4747
void AddCompileUnit(DWARFCompileUnitSP& cu);
4848
uint32_t GetNumCompileUnits();
49+
bool ContainsCompileUnit (const DWARFCompileUnit *cu) const;
4950
DWARFCompileUnit* GetCompileUnitAtIndex(uint32_t idx);
5051
DWARFCompileUnitSP GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr = NULL);
5152
DWARFCompileUnitSP GetCompileUnitContainingDIE(dw_offset_t die_offset);

lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "DWARFDebugAbbrev.h"
2424
#include "DWARFDebugAranges.h"
2525
#include "DWARFDebugInfo.h"
26+
#include "DWARFDeclContext.h"
2627
#include "DWARFDIECollection.h"
2728
#include "DWARFFormValue.h"
2829
#include "DWARFLocationDescription.h"
@@ -1739,6 +1740,36 @@ DWARFDebugInfoEntry::GetDeclContextDIEs (SymbolFileDWARF* dwarf2Data,
17391740
}
17401741
}
17411742

1743+
void
1744+
DWARFDebugInfoEntry::GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
1745+
DWARFCompileUnit* cu,
1746+
DWARFDeclContext &dwarf_decl_ctx) const
1747+
{
1748+
const dw_tag_t tag = Tag();
1749+
if (tag != DW_TAG_compile_unit)
1750+
{
1751+
dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
1752+
const DWARFDebugInfoEntry *parent_decl_ctx_die = GetParentDeclContextDIE (dwarf2Data, cu);
1753+
if (parent_decl_ctx_die && parent_decl_ctx_die != this)
1754+
{
1755+
if (parent_decl_ctx_die->Tag() != DW_TAG_compile_unit)
1756+
parent_decl_ctx_die->GetDWARFDeclContext (dwarf2Data, cu, dwarf_decl_ctx);
1757+
}
1758+
}
1759+
}
1760+
1761+
1762+
bool
1763+
DWARFDebugInfoEntry::MatchesDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
1764+
DWARFCompileUnit* cu,
1765+
const DWARFDeclContext &dwarf_decl_ctx) const
1766+
{
1767+
1768+
DWARFDeclContext this_dwarf_decl_ctx;
1769+
GetDWARFDeclContext (dwarf2Data, cu, this_dwarf_decl_ctx);
1770+
return this_dwarf_decl_ctx == dwarf_decl_ctx;
1771+
}
1772+
17421773
const DWARFDebugInfoEntry *
17431774
DWARFDebugInfoEntry::GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
17441775
DWARFCompileUnit* cu) const

lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ typedef std::multimap<uint32_t, const DWARFDebugInfoEntry*> UInt32ToDIEMMap;
4141
typedef UInt32ToDIEMMap::iterator UInt32ToDIEMMapIter;
4242
typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter;
4343

44+
class DWARFDeclContext;
45+
4446
#define DIE_SIBLING_IDX_BITSIZE 31
4547
#define DIE_ABBR_IDX_BITSIZE 15
4648

@@ -359,6 +361,15 @@ class DWARFDebugInfoEntry
359361
DWARFCompileUnit* cu,
360362
DWARFDIECollection &decl_context_dies) const;
361363

364+
void GetDWARFDeclContext (SymbolFileDWARF* dwarf2Data,
365+
DWARFCompileUnit* cu,
366+
DWARFDeclContext &dwarf_decl_ctx) const;
367+
368+
369+
bool MatchesDWARFDeclContext(SymbolFileDWARF* dwarf2Data,
370+
DWARFCompileUnit* cu,
371+
const DWARFDeclContext &dwarf_decl_ctx) const;
372+
362373
const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
363374
DWARFCompileUnit* cu) const;
364375
const DWARFDebugInfoEntry* GetParentDeclContextDIE (SymbolFileDWARF* dwarf2Data,
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//===-- DWARFDeclContext.cpp ------------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "DWARFDeclContext.h"
11+
12+
const char *
13+
DWARFDeclContext::GetQualifiedName () const
14+
{
15+
if (m_qualified_name.empty())
16+
{
17+
// The declaration context array for a class named "foo" in namespace
18+
// "a::b::c" will be something like:
19+
// [0] DW_TAG_class_type "foo"
20+
// [1] DW_TAG_namespace "c"
21+
// [2] DW_TAG_namespace "b"
22+
// [3] DW_TAG_namespace "a"
23+
if (!m_entries.empty())
24+
{
25+
if (m_entries.size() == 1)
26+
{
27+
if (m_entries[0].name)
28+
{
29+
m_qualified_name.append("::");
30+
m_qualified_name.append(m_entries[0].name);
31+
}
32+
}
33+
else
34+
{
35+
collection::const_reverse_iterator pos;
36+
collection::const_reverse_iterator begin = m_entries.rbegin();
37+
collection::const_reverse_iterator end = m_entries.rend();
38+
for (pos = begin; pos != end; ++pos)
39+
{
40+
if (pos != begin)
41+
m_qualified_name.append("::");
42+
m_qualified_name.append(pos->name);
43+
}
44+
}
45+
}
46+
}
47+
if (m_qualified_name.empty())
48+
return NULL;
49+
return m_qualified_name.c_str();
50+
}
51+
52+
53+
bool
54+
DWARFDeclContext::operator==(const DWARFDeclContext& rhs) const
55+
{
56+
if (m_entries.size() != rhs.m_entries.size())
57+
return false;
58+
59+
collection::const_iterator pos;
60+
collection::const_iterator begin = m_entries.begin();
61+
collection::const_iterator end = m_entries.end();
62+
63+
collection::const_iterator rhs_pos;
64+
collection::const_iterator rhs_begin = rhs.m_entries.begin();
65+
// The two entry arrays have the same size
66+
67+
// First compare the tags before we do expensize name compares
68+
for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos)
69+
{
70+
if (pos->tag != rhs_pos->tag)
71+
return false;
72+
}
73+
// The tags all match, now compare the names
74+
for (pos = begin, rhs_pos = rhs_begin; pos != end; ++pos, ++rhs_pos)
75+
{
76+
if (!pos->NameMatches (*rhs_pos))
77+
return false;
78+
}
79+
// All tags and names match
80+
return true;
81+
}
82+
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//===-- DWARFDeclContext.h --------------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef SymbolFileDWARF_DWARFDeclContext_h_
11+
#define SymbolFileDWARF_DWARFDeclContext_h_
12+
13+
// C Includes
14+
// C++ Includes
15+
#include <string>
16+
#include <vector>
17+
// Other libraries and framework includes
18+
#include "lldb/Core/ConstString.h"
19+
// Project includes
20+
#include "DWARFDefines.h"
21+
22+
//----------------------------------------------------------------------
23+
// DWARFDeclContext
24+
//
25+
// A class that represents a declaration context all the way down to a
26+
// DIE. This is useful when trying to find a DIE in one DWARF to a DIE
27+
// in another DWARF file.
28+
//----------------------------------------------------------------------
29+
30+
class DWARFDeclContext
31+
{
32+
public:
33+
struct Entry
34+
{
35+
Entry () :
36+
tag(0),
37+
name(NULL)
38+
{
39+
}
40+
Entry (dw_tag_t t, const char *n) :
41+
tag(t),
42+
name(n)
43+
{
44+
}
45+
46+
bool
47+
NameMatches (const Entry& rhs) const
48+
{
49+
if (name && rhs.name)
50+
return strcmp(name, rhs.name) == 0;
51+
return name == NULL && rhs.name == NULL;
52+
}
53+
54+
// Test operator
55+
operator bool() const
56+
{
57+
return tag != 0;
58+
}
59+
60+
dw_tag_t tag;
61+
const char *name;
62+
};
63+
64+
DWARFDeclContext () :
65+
m_entries()
66+
{
67+
}
68+
69+
void
70+
AppendDeclContext (dw_tag_t tag, const char *name)
71+
{
72+
m_entries.push_back(Entry(tag, name));
73+
}
74+
75+
bool
76+
operator ==(const DWARFDeclContext& rhs) const;
77+
78+
uint32_t
79+
GetSize() const
80+
{
81+
return m_entries.size();
82+
}
83+
84+
Entry &
85+
operator[] (uint32_t idx)
86+
{
87+
// "idx" must be valid
88+
return m_entries[idx];
89+
}
90+
91+
const Entry &
92+
operator[] (uint32_t idx) const
93+
{
94+
// "idx" must be valid
95+
return m_entries[idx];
96+
}
97+
98+
const char *
99+
GetQualifiedName () const;
100+
101+
protected:
102+
typedef std::vector<Entry> collection;
103+
collection m_entries;
104+
mutable std::string m_qualified_name;
105+
};
106+
107+
#endif // SymbolFileDWARF_DWARFDeclContext_h_

0 commit comments

Comments
 (0)