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/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index be87ee9..fb83cab 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1021,10 +1021,11 @@
else if (exprType->isVoidType())
Diag(OpLoc, diag::ext_sizeof_void_type)
<< (isSizeof ? "sizeof" : "__alignof") << ExprRange;
- else if (exprType->isIncompleteType())
- return Diag(OpLoc, isSizeof ? diag::err_sizeof_incomplete_type :
- diag::err_alignof_incomplete_type)
- << exprType << ExprRange;
+ else
+ return DiagnoseIncompleteType(OpLoc, exprType,
+ isSizeof ? diag::err_sizeof_incomplete_type :
+ diag::err_alignof_incomplete_type,
+ ExprRange);
return false;
}
@@ -1466,9 +1467,11 @@
// of the ObjC 'id' struct.
if (const RecordType *RTy = BaseType->getAsRecordType()) {
RecordDecl *RDecl = RTy->getDecl();
- if (RTy->isIncompleteType())
- return ExprError(Diag(OpLoc, diag::err_typecheck_incomplete_tag)
- << RDecl->getDeclName() << BaseExpr->getSourceRange());
+ if (DiagnoseIncompleteType(OpLoc, BaseType,
+ diag::err_typecheck_incomplete_tag,
+ BaseExpr->getSourceRange()))
+ return ExprError();
+
// The record definition is complete, now make sure the member is valid.
// FIXME: Qualified name lookup for C++ is a bit more complicated
// than this.
@@ -1906,11 +1909,10 @@
if (literalType->isVariableArrayType())
return Diag(LParenLoc, diag::err_variable_object_no_init)
<< SourceRange(LParenLoc, literalExpr->getSourceRange().getEnd());
- } else if (literalType->isIncompleteType()) {
- return Diag(LParenLoc, diag::err_typecheck_decl_incomplete_type)
- << literalType
- << SourceRange(LParenLoc, literalExpr->getSourceRange().getEnd());
- }
+ } else if (DiagnoseIncompleteType(LParenLoc, literalType,
+ diag::err_typecheck_decl_incomplete_type,
+ SourceRange(LParenLoc, literalExpr->getSourceRange().getEnd())))
+ return true;
if (CheckInitializerTypes(literalExpr, literalType, LParenLoc,
DeclarationName(), /*FIXME:DirectInit=*/false))
@@ -2643,10 +2645,16 @@
if (PTy->getPointeeType()->isVoidType()) {
Diag(Loc, diag::ext_gnu_void_ptr)
<< lex->getSourceRange() << rex->getSourceRange();
- } else {
- Diag(Loc, diag::err_typecheck_arithmetic_incomplete_type)
+ } else if (PTy->getPointeeType()->isFunctionType()) {
+ Diag(Loc, diag::err_typecheck_pointer_arith_function_type)
<< lex->getType() << lex->getSourceRange();
return QualType();
+ } else {
+ DiagnoseIncompleteType(Loc, PTy->getPointeeType(),
+ diag::err_typecheck_arithmetic_incomplete_type,
+ lex->getSourceRange(), SourceRange(),
+ lex->getType());
+ return QualType();
}
}
return PExp->getType();
@@ -3038,9 +3046,9 @@
break;
case Expr::MLV_IncompleteType:
case Expr::MLV_IncompleteVoidType:
- Diag = diag::err_typecheck_incomplete_type_not_modifiable_lvalue;
- NeedType = true;
- break;
+ return S.DiagnoseIncompleteType(Loc, E->getType(),
+ diag::err_typecheck_incomplete_type_not_modifiable_lvalue,
+ E->getSourceRange());
case Expr::MLV_DuplicateVectorComponents:
Diag = diag::err_typecheck_duplicate_vector_components_not_mlvalue;
break;
@@ -3155,10 +3163,16 @@
} else if (PT->getPointeeType()->isVoidType()) {
// Pointer to void is extension.
Diag(OpLoc, diag::ext_gnu_void_ptr) << Op->getSourceRange();
- } else {
- Diag(OpLoc, diag::err_typecheck_arithmetic_incomplete_type)
+ } else if (PT->getPointeeType()->isFunctionType()) {
+ Diag(OpLoc, diag::err_typecheck_pointer_arith_function_type)
<< ResType << Op->getSourceRange();
return QualType();
+ } else {
+ DiagnoseIncompleteType(OpLoc, PT->getPointeeType(),
+ diag::err_typecheck_arithmetic_incomplete_type,
+ Op->getSourceRange(), SourceRange(),
+ ResType);
+ return QualType();
}
} else if (ResType->isComplexType()) {
// C99 does not support ++/-- on complex types, we allow as an extension.