Index: packages/Python/lldbsuite/test/lang/objc/forward-decl/TestForwardDecl.py =================================================================== --- packages/Python/lldbsuite/test/lang/objc/forward-decl/TestForwardDecl.py +++ packages/Python/lldbsuite/test/lang/objc/forward-decl/TestForwardDecl.py @@ -23,9 +23,8 @@ 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 @@ # 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")) Index: source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -31,7 +31,7 @@ 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; Index: source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -146,6 +146,49 @@ } } +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);