Centralize error reporting of improper uses of incomplete types in the
new DiagnoseIncompleteType. It provides additional information about
struct/class/union/enum types when possible, either by pointing to the
forward declaration of that type or by pointing to the definition (if
we're in the process of defining that type). 
Fixes <rdar://problem/6500531>.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62521 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index cff01c6..fe60496 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -705,10 +705,9 @@
     // C99 6.7.5.3p4: the parameters in a parameter type list in a
     // function declarator that is part of a function definition of
     // that function shall not have incomplete type.
-    if (Param->getType()->isIncompleteType() &&
-        !Param->isInvalidDecl()) {
-      Diag(Param->getLocation(), diag::err_typecheck_decl_incomplete_type)
-        << Param->getType();
+    if (!Param->isInvalidDecl() &&
+        DiagnoseIncompleteType(Param->getLocation(), Param->getType(),
+                               diag::err_typecheck_decl_incomplete_type)) {
       Param->setInvalidDecl();
       HasInvalidParm = true;
     }
@@ -2503,10 +2502,10 @@
     // no linkage (C99 6.2.2p6), the type for the object shall be complete...
     if (IDecl->isBlockVarDecl() && 
         IDecl->getStorageClass() != VarDecl::Extern) {
-      if (T->isIncompleteType() && !IDecl->isInvalidDecl()) {
-        Diag(IDecl->getLocation(), diag::err_typecheck_decl_incomplete_type)<<T;
+      if (!IDecl->isInvalidDecl() &&
+          DiagnoseIncompleteType(IDecl->getLocation(), T, 
+                                 diag::err_typecheck_decl_incomplete_type))
         IDecl->setInvalidDecl();
-      }
     }
     // File scope. C99 6.9.2p2: A declaration of an identifier for and 
     // object that has file scope without an initializer, and without a
@@ -2517,13 +2516,13 @@
       if (T->isIncompleteArrayType()) {
         // C99 6.9.2 (p2, p5): Implicit initialization causes an incomplete
         // array to be completed. Don't issue a diagnostic.
-      } else if (T->isIncompleteType() && !IDecl->isInvalidDecl()) {
+      } else if (!IDecl->isInvalidDecl() &&
+                 DiagnoseIncompleteType(IDecl->getLocation(), T,
+                                        diag::err_typecheck_decl_incomplete_type))
         // C99 6.9.2p3: If the declaration of an identifier for an object is
         // a tentative definition and has internal linkage (C99 6.2.2p3), the  
         // declared type shall not be an incomplete type.
-        Diag(IDecl->getLocation(), diag::err_typecheck_decl_incomplete_type)<<T;
         IDecl->setInvalidDecl();
-      }
     }
     if (IDecl->isFileVarDecl())
       CheckForFileScopedRedefinitions(S, IDecl);
@@ -3382,7 +3381,8 @@
     // C99 6.7.2.1p2 - A field may not be an incomplete type except...
     if (FDTy->isIncompleteType()) {
       if (!Record) {  // Incomplete ivar type is always an error.
-        Diag(FD->getLocation(), diag::err_field_incomplete) <<FD->getDeclName();
+        DiagnoseIncompleteType(FD->getLocation(), FD->getType(), 
+                               diag::err_field_incomplete);
         FD->setInvalidDecl();
         EnclosingDecl->setInvalidDecl();
         continue;
@@ -3390,7 +3390,8 @@
       if (i != NumFields-1 ||                   // ... that the last member ...
           !Record->isStruct() ||  // ... of a structure ...
           !FDTy->isArrayType()) {         //... may have incomplete array type.
-        Diag(FD->getLocation(), diag::err_field_incomplete) <<FD->getDeclName();
+        DiagnoseIncompleteType(FD->getLocation(), FD->getType(), 
+                               diag::err_field_incomplete);
         FD->setInvalidDecl();
         EnclosingDecl->setInvalidDecl();
         continue;