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;