Module Debugging: Fix a crash when emitting debug info for nested tag types
whose DeclContext is not yet complete by deferring their emission.
rdar://problem/24918680
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@262851 91177308-0d34-0410-b5e6-96231b3b80d8
(cherry picked from commit 45b0585fa2e7c9c467a938ce8838c9b3ceb01ca8)
diff --git a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
index d4a3483..656b082 100644
--- a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
+++ b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -201,6 +201,15 @@
if (D->getName().empty())
return;
+ // Defer tag decls until their declcontext is complete.
+ auto *DeclCtx = D->getDeclContext();
+ while (DeclCtx) {
+ if (auto *D = dyn_cast<TagDecl>(DeclCtx))
+ if (!D->isCompleteDefinition())
+ return;
+ DeclCtx = DeclCtx->getParent();
+ }
+
DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx);
DTV.TraverseDecl(D);
Builder->UpdateCompletedType(D);
diff --git a/test/Modules/Inputs/DebugCXX.h b/test/Modules/Inputs/DebugCXX.h
index 39dda95..2e17a2e 100644
--- a/test/Modules/Inputs/DebugCXX.h
+++ b/test/Modules/Inputs/DebugCXX.h
@@ -72,3 +72,14 @@
struct InAnonymousNamespace { int i; };
}
}
+
+class Base;
+class A {
+ virtual Base *getParent() const;
+};
+class Base {};
+class Derived : Base {
+ class B : A {
+ Derived *getParent() const override;
+ };
+};
diff --git a/test/Modules/ModuleDebugInfo.cpp b/test/Modules/ModuleDebugInfo.cpp
index 7344397..993e72a 100644
--- a/test/Modules/ModuleDebugInfo.cpp
+++ b/test/Modules/ModuleDebugInfo.cpp
@@ -68,6 +68,13 @@
// CHECK-SAME-NOT: name:
// CHECK-SAME: identifier: "_ZTS13TypedefStruct")
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "Derived",
+// CHECK-SAME: identifier: "_ZTS7Derived")
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B", scope: !"_ZTS7Derived",
+// CHECK-SAME: elements: ![[B_MBRS:.*]], vtableHolder: !"_ZTS1A"
+// CHECK: ![[B_MBRS]] = !{{{.*}}, ![[GET_PARENT:.*]]}
+// CHECK: ![[GET_PARENT]] = !DISubprogram(name: "getParent"
+
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "FloatInstatiation"
// no mangled name here yet.