[SymbolFile] Implement GetCompleteObjCClass for .debug_names

When running the test suite with .debug_names a bunch of tests were
failing because GetCompleteObjCClass was not yet implemented for
DebugNamesDWARFIndex. This patch adds the required logic.

We use the .debug_names to find the Objective-C class and then rely on
DW_AT_APPLE_objc_complete_type to find the complete type. If we can't
find it or the attribute is not supported, we return a list of potential
complete types.

Differential revision: https://reviews.llvm.org/D48596

llvm-svn: 335776
This commit is contained in:
Jonas Devlieghere 2018-06-27 19:58:39 +00:00
parent bc0748e812
commit 8e93917e8d
3 changed files with 60 additions and 4 deletions

View File

@ -23,9 +23,8 @@ class ForwardDeclTestCase(TestBase):
self.line = line_number(self.source, '// Set breakpoint 0 here.')
self.shlib_names = ["Container"]
@skipUnlessDarwin
def test_expr(self):
self.build()
def do_test(self, dictionary=None):
self.build(dictionary=dictionary)
# Create a target by the debugger.
target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
@ -57,3 +56,17 @@ class ForwardDeclTestCase(TestBase):
# This should display correctly.
self.expect("expression [j getMember]", VARIABLES_DISPLAYED_CORRECTLY,
substrs=["= 0x"])
@skipUnlessDarwin
def test_expr(self):
self.do_test()
@no_debug_info_test
@skipUnlessDarwin
@skipIf(compiler=no_match("clang"))
@skipIf(compiler_version=["<", "7.0"])
def test_debug_names(self):
"""Test that we are able to find complete types when using DWARF v5
accelerator tables"""
self.do_test(
dict(CFLAGS_EXTRAS="-dwarf-version=5 -mllvm -accel-tables=Dwarf"))

View File

@ -146,6 +146,49 @@ void DebugNamesDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
}
}
void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name,
bool must_be_implementation,
DIEArray &offsets) {
m_fallback.GetCompleteObjCClass(class_name, must_be_implementation, offsets);
// Keep a list of incomplete types as fallback for when we don't find the
// complete type.
DIEArray incomplete_types;
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(class_name.GetStringRef())) {
if (entry.tag() != DW_TAG_structure_type &&
entry.tag() != DW_TAG_class_type)
continue;
DIERef ref = ToDIERef(entry);
if (!ref)
continue;
DWARFUnit *cu = m_debug_info.GetCompileUnit(ref.cu_offset);
if (!cu || !cu->Supports_DW_AT_APPLE_objc_complete_type()) {
incomplete_types.push_back(ref);
continue;
}
// FIXME: We should return DWARFDIEs so we don't have to resolve it twice.
DWARFDIE die = m_debug_info.GetDIE(ref);
if (!die)
continue;
if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) {
// If we find the complete version we're done.
offsets.push_back(ref);
return;
} else {
incomplete_types.push_back(ref);
}
}
offsets.insert(offsets.end(), incomplete_types.begin(),
incomplete_types.end());
}
void DebugNamesDWARFIndex::GetTypes(ConstString name, DIEArray &offsets) {
m_fallback.GetTypes(name, offsets);

View File

@ -31,7 +31,7 @@ public:
void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;
void GetObjCMethods(ConstString class_name, DIEArray &offsets) override {}
void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
DIEArray &offsets) override {}
DIEArray &offsets) override;
void GetTypes(ConstString name, DIEArray &offsets) override;
void GetTypes(const DWARFDeclContext &context, DIEArray &offsets) override;
void GetNamespaces(ConstString name, DIEArray &offsets) override;