Hi clayborg, This is progress toward PR19676/PR20781 and should have both cases error rather than crashing the debugger (The former PR already had a similar work around, but I believe the original test case had the same issue as PR20781, so it never fully worked). Ideally, we need to figure out how to search other images in the process for a definition of this class at this point, instead of just pretending it's empty (which is what this patch does), but I don't know enough about LLDB to make that happen. Pointers appreciated.
REPOSITORY rL LLVM http://reviews.llvm.org/D10509 Files: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp source/Symbol/ClangASTType.cpp test/types/TestForwardTypes.py test/types/forward_inheritance.cpp test/types/forward_member.cpp EMAIL PREFERENCES http://reviews.llvm.org/settings/panel/emailpreferences/
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2176,7 +2176,23 @@ } } } - + + if (member_clang_type.GetCompleteType() == false) + { + GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 " DW_TAG_member '%s' refers to type '%s' that is a forward declaration, not a complete definition." + "\nThis can happen due to missing images or compiler bugs.", + MakeUserID(die->GetOffset()), + name, + member_clang_type.GetTypeName().GetCString()); + + // We have no choice other than to pretend that the base class + // is complete. If we don't do this, clang will crash later when computing + // the object layout. + member_clang_type.StartTagDeclarationDefinition (); + member_clang_type.CompleteTagDeclarationDefinition (); + } + + field_decl = class_clang_type.AddFieldToRecordType (name, member_clang_type, accessibility, Index: source/Symbol/ClangASTType.cpp =================================================================== --- source/Symbol/ClangASTType.cpp +++ source/Symbol/ClangASTType.cpp @@ -5848,6 +5848,13 @@ if (IsValid()) { clang::QualType qual_type (GetQualType()); + clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + cxx_record_decl->startDefinition(); + return true; + } + const clang::Type *t = qual_type.getTypePtr(); if (t) { Index: test/types/TestForwardTypes.py =================================================================== --- /dev/null +++ test/types/TestForwardTypes.py @@ -0,0 +1,44 @@ +""" +Test that forward declarations to types in other compilation units do not crash +the debugger. +""" + +import AbstractBase +import unittest2 +import lldb +import sys +from lldbtest import * + +class ForwardTypesTestCase(AbstractBase.GenericTester): + mydir = AbstractBase.GenericTester.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + AbstractBase.GenericTester.setUp(self) + # disable "There is a running process, kill it and restart?" prompt + self.runCmd("settings set auto-confirm true") + self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm")) + + @dwarf_test + def test_forward_member(self): + """Test that members with forwarded debug info don't crash the compiler""" + self.source = 'forward_member.cpp' + self.buildDwarf() + target = self.dbg.createTarget("a.out") + self.assertTrue(target, VALID_TARGET) + self.runCmd("p (bar_t*)0") + + @dwarf_test + def test_forward_inheritance(self): + """Test that bases with forwarded debug info don't crash the compiler""" + self.source = 'forward_inheritance.cpp' + self.buildDwarf() + target = self.dbg.createTarget("a.out") + self.assertTrue(target, VALID_TARGET) + self.runCmd("p (bar*)0") + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Index: test/types/forward_inheritance.cpp =================================================================== --- /dev/null +++ test/types/forward_inheritance.cpp @@ -0,0 +1,12 @@ +template<typename T> +class foo { + void func() { } +}; + +extern template class foo<int>; +typedef foo<int> fooint; + +class bar : public fooint { +}; + +bar f; Index: test/types/forward_member.cpp =================================================================== --- /dev/null +++ test/types/forward_member.cpp @@ -0,0 +1,13 @@ +template<typename T> +struct foo { + void func() { } +}; + +extern template struct foo<int>; +typedef foo<int> fooint; + +typedef struct bar { + fooint foo; +} bar_t; + +bar_t f;
_______________________________________________ lldb-commits mailing list lldb-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits