From 848829840367b5513fd858b09f5bc57414cf7c2e Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rnk@google.com>
Date: Tue, 13 Sep 2016 00:01:23 +0000
Subject: [PATCH] [DebugInfo] Deduplicate debug info limiting logic

We should be doing the same checks when a type is completed as we do
when a complete type is used during emission. Previously, we duplicated
the logic, and it got out of sync. This could be observed with
dllimported classes.

Also reduce a test case for this slightly.

Implementing review feedback from David Blaikie on r281057.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@281278 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGDebugInfo.cpp                   | 31 ++++++-------------
 test/CodeGenCXX/debug-info-class-nolimit.cpp  |  5 +--
 .../debug-info-dllimport-base-class.cpp       | 12 +++++++
 3 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index c2878c38f6e..c0af91fd62d 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1644,27 +1644,6 @@ void CGDebugInfo::completeType(const RecordDecl *RD) {
     completeRequiredType(RD);
 }
 
-void CGDebugInfo::completeRequiredType(const RecordDecl *RD) {
-  if (DebugKind <= codegenoptions::DebugLineTablesOnly)
-    return;
-
-  // If this is a dynamic class and we're emitting limited debug info, wait
-  // until the vtable is emitted to complete the class debug info.
-  if (DebugKind <= codegenoptions::LimitedDebugInfo) {
-    if (const auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
-      if (CXXDecl->isDynamicClass())
-        return;
-  }
-
-  if (DebugTypeExtRefs && RD->isFromASTFile())
-    return;
-
-  QualType Ty = CGM.getContext().getRecordType(RD);
-  llvm::DIType *T = getTypeOrNull(Ty);
-  if (T && T->isForwardDecl())
-    completeClassData(RD);
-}
-
 void CGDebugInfo::completeClassData(const RecordDecl *RD) {
   if (DebugKind <= codegenoptions::DebugLineTablesOnly)
     return;
@@ -1763,6 +1742,16 @@ static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
   return false;
 }
 
+void CGDebugInfo::completeRequiredType(const RecordDecl *RD) {
+  if (shouldOmitDefinition(DebugKind, DebugTypeExtRefs, RD, CGM.getLangOpts()))
+    return;
+
+  QualType Ty = CGM.getContext().getRecordType(RD);
+  llvm::DIType *T = getTypeOrNull(Ty);
+  if (T && T->isForwardDecl())
+    completeClassData(RD);
+}
+
 llvm::DIType *CGDebugInfo::CreateType(const RecordType *Ty) {
   RecordDecl *RD = Ty->getDecl();
   llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(QualType(Ty, 0)));
diff --git a/test/CodeGenCXX/debug-info-class-nolimit.cpp b/test/CodeGenCXX/debug-info-class-nolimit.cpp
index 4b05fd6e87d..0b3b38dd17b 100644
--- a/test/CodeGenCXX/debug-info-class-nolimit.cpp
+++ b/test/CodeGenCXX/debug-info-class-nolimit.cpp
@@ -6,10 +6,7 @@
 // more general than that.
 
 struct UnicodeString;
-struct GetFwdDecl {
-  static UnicodeString format;
-};
-GetFwdDecl force_fwd_decl;
+UnicodeString *force_fwd_decl;
 struct UnicodeString {
 private:
   virtual ~UnicodeString();
diff --git a/test/CodeGenCXX/debug-info-dllimport-base-class.cpp b/test/CodeGenCXX/debug-info-dllimport-base-class.cpp
index dc15dd07f96..855ecaaa4c9 100644
--- a/test/CodeGenCXX/debug-info-dllimport-base-class.cpp
+++ b/test/CodeGenCXX/debug-info-dllimport-base-class.cpp
@@ -4,6 +4,10 @@
 // be imported from a DLL.  Otherwise, the debugger wouldn't be able to show the
 // members.
 
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ImportedAfterCompletion",
+// CHECK-NOT:              DIFlagFwdDecl
+// CHECK-SAME:             ){{$}}
+
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "OutOfLineCtor",
 // CHECK-SAME:             DIFlagFwdDecl
 // CHECK-SAME:             ){{$}}
@@ -16,6 +20,13 @@
 // CHECK-NOT:              DIFlagFwdDecl
 // CHECK-SAME:             ){{$}}
 
+
+struct ImportedAfterCompletion;
+ImportedAfterCompletion *force_fwd_decl;
+struct __declspec(dllimport) ImportedAfterCompletion {
+  virtual ~ImportedAfterCompletion();
+};
+
 struct OutOfLineCtor {
   OutOfLineCtor();
   virtual void Foo();
@@ -35,6 +46,7 @@ struct ImportedMethod {
 };
 
 int main() {
+  ImportedAfterCompletion c;
   OutOfLineCtor o;
   DerivedFromImported d;
   ImportedMethod m;
-- 
GitLab