Updated to use getAsTagDecl.

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
@@ -5851,15 +5851,11 @@
         const clang::Type *t = qual_type.getTypePtr();
         if (t)
         {
-            const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(t);
-            if (tag_type)
+            clang::TagDecl *tag_decl = t->getAsTagDecl();
+            if (tag_decl)
             {
-                clang::TagDecl *tag_decl = tag_type->getDecl();
-                if (tag_decl)
-                {
-                    tag_decl->startDefinition();
-                    return true;
-                }
+                tag_decl->startDefinition();
+                return true;
             }
             
             const clang::ObjCObjectType *object_type = llvm::dyn_cast<clang::ObjCObjectType>(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

Reply via email to