Alternative fix for r184473.

This just seems a bit tidier/more principled. Based on a patch provided
by Adrian - with the only minor tweak that it needed to use
"getTypeOrNull" rather than "getCompletedTypeOrNull" since we don't
store declarations in the CompletedTypes cache.

No intended functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184509 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index f8c814c..e1b6342 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1886,22 +1886,6 @@
   return llvm::DIType();
 }
 
-/// ContainsFwdDecl - True if Ty is either a forward declaration or a
-/// derived type of a forward declaration.
-static bool ContainsFwdDecl(llvm::DIType Ty) {
-  // Composite types such as structs inherit from DIDerivedType, so
-  // check this first and do an early exit.
-  if (Ty.isForwardDecl())
-    return true;
-
-  if (Ty.isDerivedType()) {
-    llvm::DIDerivedType DTy(Ty);
-    return ContainsFwdDecl(DTy.getTypeDerivedFrom());
-  }
-
-  return false;
-}
-
 /// getCompletedTypeOrNull - Get the type from the cache or return null if it
 /// doesn't exist.
 llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {
@@ -1920,21 +1904,24 @@
   }
 
   // Verify that any cached debug info still exists.
-  if (V != 0) {
-    llvm::DIType CachedType(cast<llvm::MDNode>(V));
-
-    // Unless we are limiting debug info, attempt to resolve any
-    // forward declarations.
-    if (DebugKind > CodeGenOptions::LimitedDebugInfo &&
-        ContainsFwdDecl(CachedType))
-      return llvm::DIType();
-
-    return CachedType;
-  }
+  if (V != 0)
+    return llvm::DIType(cast<llvm::MDNode>(V));
 
   return llvm::DIType();
 }
 
+void CGDebugInfo::completeFwdDecl(const RecordDecl &RD) {
+  // In limited debug info we only want to do this if the complete type was
+  // required.
+  if (DebugKind <= CodeGenOptions::LimitedDebugInfo)
+    return;
+
+  llvm::DIType T = getTypeOrNull(CGM.getContext().getRecordType(&RD));
+
+  if (T.Verify() && T.isForwardDecl())
+    getOrCreateType(QTy, getOrCreateFile(RD.getLocation());
+}
+
 /// getCachedInterfaceTypeOrNull - Get the type from the interface
 /// cache, unless it needs to regenerated. Otherwise return null.
 llvm::Value *CGDebugInfo::getCachedInterfaceTypeOrNull(QualType Ty) {
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index fc62600..72a9d71 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -289,6 +289,8 @@
   llvm::DIType getOrCreateInterfaceType(QualType Ty,
                                         SourceLocation Loc);
 
+  void completeFwdDecls(const RecordDecl *TD);
+
 private:
   /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
   void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 4240216..6ebb418 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -260,6 +260,11 @@
   // yet, we'll just do it lazily.
   if (RecordDeclTypes.count(Context.getTagDeclType(RD).getTypePtr()))
     ConvertRecordDeclType(RD);
+
+  // If necessary, provide the full definition of a type only used with a
+  // declaration so far.
+  if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
+    DI->completeFwdDecls(RD);
 }
 
 static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext,