forked from OSchip/llvm-project
Move Sema::RequireCompleteType() and Sema::RequireCompleteExprType()
off PartialDiagnostic. PartialDiagnostic is rather heavyweight for something that is in the critical path and is rarely used. So, switch over to an abstract-class-based callback mechanism that delays most of the work until a diagnostic is actually produced. Good for ~11k code size reduction in the compiler and 1% speedup in -fsyntax-only on the code in <rdar://problem/11004361>. llvm-svn: 156176
This commit is contained in:
parent
5ff430ce06
commit
7bfb2d026e
|
@ -944,16 +944,140 @@ public:
|
|||
/// in an Objective-C message declaration. Return the appropriate type.
|
||||
ParsedType ActOnObjCInstanceType(SourceLocation Loc);
|
||||
|
||||
/// \brief Abstract class used to diagnose incomplete types.
|
||||
struct IncompleteTypeDiagnoser {
|
||||
bool Suppressed;
|
||||
|
||||
IncompleteTypeDiagnoser(bool Suppressed = false) : Suppressed(Suppressed) { }
|
||||
|
||||
virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) = 0;
|
||||
virtual ~IncompleteTypeDiagnoser() {}
|
||||
};
|
||||
|
||||
static int getPrintable(int I) { return I; }
|
||||
static bool getPrintable(bool B) { return B; }
|
||||
static const char * getPrintable(const char *S) { return S; }
|
||||
static StringRef getPrintable(StringRef S) { return S; }
|
||||
static const std::string &getPrintable(const std::string &S) { return S; }
|
||||
static const IdentifierInfo *getPrintable(const IdentifierInfo *II) {
|
||||
return II;
|
||||
}
|
||||
static DeclarationName getPrintable(DeclarationName N) { return N; }
|
||||
static QualType getPrintable(QualType T) { return T; }
|
||||
static SourceRange getPrintable(SourceRange R) { return R; }
|
||||
static SourceRange getPrintable(SourceLocation L) { return L; }
|
||||
static SourceRange getPrintable(Expr *E) { return E->getSourceRange(); }
|
||||
static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();}
|
||||
|
||||
template<typename T1>
|
||||
class BoundIncompleteTypeDiagnoser1 : public IncompleteTypeDiagnoser {
|
||||
unsigned DiagID;
|
||||
const T1 &Arg1;
|
||||
|
||||
public:
|
||||
BoundIncompleteTypeDiagnoser1(unsigned DiagID, const T1 &Arg1)
|
||||
: IncompleteTypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1) { }
|
||||
virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
|
||||
if (Suppressed) return;
|
||||
S.Diag(Loc, DiagID) << getPrintable(Arg1) << T;
|
||||
}
|
||||
|
||||
virtual ~BoundIncompleteTypeDiagnoser1() { }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2>
|
||||
class BoundIncompleteTypeDiagnoser2 : public IncompleteTypeDiagnoser {
|
||||
unsigned DiagID;
|
||||
const T1 &Arg1;
|
||||
const T2 &Arg2;
|
||||
|
||||
public:
|
||||
BoundIncompleteTypeDiagnoser2(unsigned DiagID, const T1 &Arg1,
|
||||
const T2 &Arg2)
|
||||
: IncompleteTypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1),
|
||||
Arg2(Arg2) { }
|
||||
|
||||
virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
|
||||
if (Suppressed) return;
|
||||
S.Diag(Loc, DiagID) << getPrintable(Arg1) << getPrintable(Arg2) << T;
|
||||
}
|
||||
|
||||
virtual ~BoundIncompleteTypeDiagnoser2() { }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, typename T3>
|
||||
class BoundIncompleteTypeDiagnoser3 : public IncompleteTypeDiagnoser {
|
||||
unsigned DiagID;
|
||||
const T1 &Arg1;
|
||||
const T2 &Arg2;
|
||||
const T3 &Arg3;
|
||||
|
||||
public:
|
||||
BoundIncompleteTypeDiagnoser3(unsigned DiagID, const T1 &Arg1,
|
||||
const T2 &Arg2, const T3 &Arg3)
|
||||
: IncompleteTypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1),
|
||||
Arg2(Arg2), Arg3(Arg3) { }
|
||||
|
||||
virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
|
||||
if (Suppressed) return;
|
||||
S.Diag(Loc, DiagID)
|
||||
<< getPrintable(Arg1) << getPrintable(Arg2) << getPrintable(Arg3) << T;
|
||||
}
|
||||
|
||||
virtual ~BoundIncompleteTypeDiagnoser3() { }
|
||||
};
|
||||
|
||||
bool RequireCompleteType(SourceLocation Loc, QualType T,
|
||||
const PartialDiagnostic &PD,
|
||||
std::pair<SourceLocation, PartialDiagnostic> Note);
|
||||
bool RequireCompleteType(SourceLocation Loc, QualType T,
|
||||
const PartialDiagnostic &PD);
|
||||
IncompleteTypeDiagnoser &Diagnoser);
|
||||
bool RequireCompleteType(SourceLocation Loc, QualType T,
|
||||
unsigned DiagID);
|
||||
bool RequireCompleteExprType(Expr *E, const PartialDiagnostic &PD,
|
||||
std::pair<SourceLocation,
|
||||
PartialDiagnostic> Note);
|
||||
|
||||
template<typename T1>
|
||||
bool RequireCompleteType(SourceLocation Loc, QualType T,
|
||||
unsigned DiagID, const T1 &Arg1) {
|
||||
BoundIncompleteTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1);
|
||||
return RequireCompleteType(Loc, T, Diagnoser);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
bool RequireCompleteType(SourceLocation Loc, QualType T,
|
||||
unsigned DiagID, const T1 &Arg1, const T2 &Arg2) {
|
||||
BoundIncompleteTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2);
|
||||
return RequireCompleteType(Loc, T, Diagnoser);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3>
|
||||
bool RequireCompleteType(SourceLocation Loc, QualType T,
|
||||
unsigned DiagID, const T1 &Arg1, const T2 &Arg2,
|
||||
const T3 &Arg3) {
|
||||
BoundIncompleteTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2,
|
||||
Arg3);
|
||||
return RequireCompleteType(Loc, T, Diagnoser);
|
||||
}
|
||||
|
||||
bool RequireCompleteExprType(Expr *E, IncompleteTypeDiagnoser &Diagnoser);
|
||||
bool RequireCompleteExprType(Expr *E, unsigned DiagID);
|
||||
|
||||
template<typename T1>
|
||||
bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1) {
|
||||
BoundIncompleteTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1);
|
||||
return RequireCompleteExprType(E, Diagnoser);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1,
|
||||
const T2 &Arg2) {
|
||||
BoundIncompleteTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2);
|
||||
return RequireCompleteExprType(E, Diagnoser);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3>
|
||||
bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1,
|
||||
const T2 &Arg2, const T3 &Arg3) {
|
||||
BoundIncompleteTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2,
|
||||
Arg3);
|
||||
return RequireCompleteExprType(E, Diagnoser);
|
||||
}
|
||||
|
||||
bool RequireLiteralType(SourceLocation Loc, QualType T,
|
||||
const PartialDiagnostic &PD);
|
||||
|
|
|
@ -227,9 +227,8 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,
|
|||
if (loc.isInvalid()) loc = SS.getRange().getBegin();
|
||||
|
||||
// The type must be complete.
|
||||
if (RequireCompleteType(loc, type,
|
||||
PDiag(diag::err_incomplete_nested_name_spec)
|
||||
<< SS.getRange())) {
|
||||
if (RequireCompleteType(loc, type, diag::err_incomplete_nested_name_spec,
|
||||
SS.getRange())) {
|
||||
SS.SetInvalid(SS.getRange());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -561,8 +561,8 @@ void CastOperation::CheckDynamicCast() {
|
|||
assert(DestPointer && "Reference to void is not possible");
|
||||
} else if (DestRecord) {
|
||||
if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee,
|
||||
Self.PDiag(diag::err_bad_dynamic_cast_incomplete)
|
||||
<< DestRange))
|
||||
diag::err_bad_dynamic_cast_incomplete,
|
||||
DestRange))
|
||||
return;
|
||||
} else {
|
||||
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
|
||||
|
@ -597,8 +597,8 @@ void CastOperation::CheckDynamicCast() {
|
|||
const RecordType *SrcRecord = SrcPointee->getAs<RecordType>();
|
||||
if (SrcRecord) {
|
||||
if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
|
||||
Self.PDiag(diag::err_bad_dynamic_cast_incomplete)
|
||||
<< SrcExpr.get()->getSourceRange()))
|
||||
diag::err_bad_dynamic_cast_incomplete,
|
||||
SrcExpr.get()))
|
||||
return;
|
||||
} else {
|
||||
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
|
||||
|
@ -1075,8 +1075,8 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
|
|||
QualType OrigDestType, unsigned &msg,
|
||||
CastKind &Kind, CXXCastPath &BasePath) {
|
||||
// We can only work with complete types. But don't complain if it doesn't work
|
||||
if (Self.RequireCompleteType(OpRange.getBegin(), SrcType, Self.PDiag(0)) ||
|
||||
Self.RequireCompleteType(OpRange.getBegin(), DestType, Self.PDiag(0)))
|
||||
if (Self.RequireCompleteType(OpRange.getBegin(), SrcType, 0) ||
|
||||
Self.RequireCompleteType(OpRange.getBegin(), DestType, 0))
|
||||
return TC_NotApplicable;
|
||||
|
||||
// Downcast can only happen in class hierarchies, so we need classes.
|
||||
|
|
|
@ -4488,7 +4488,7 @@ bool Sema::CheckParmsForFunctionDef(ParmVarDecl **P, ParmVarDecl **PEnd,
|
|||
// This is also C++ [dcl.fct]p6.
|
||||
if (!Param->isInvalidDecl() &&
|
||||
RequireCompleteType(Param->getLocation(), Param->getType(),
|
||||
diag::err_typecheck_decl_incomplete_type)) {
|
||||
diag::err_typecheck_decl_incomplete_type)) {
|
||||
Param->setInvalidDecl();
|
||||
HasInvalidParm = true;
|
||||
}
|
||||
|
|
|
@ -1055,8 +1055,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
|
|||
// The class-name in a base-specifier shall not be an incompletely
|
||||
// defined class.
|
||||
if (RequireCompleteType(BaseLoc, BaseType,
|
||||
PDiag(diag::err_incomplete_base_class)
|
||||
<< SpecifierRange)) {
|
||||
diag::err_incomplete_base_class, SpecifierRange)) {
|
||||
Class->setInvalidDecl();
|
||||
return 0;
|
||||
}
|
||||
|
@ -10650,8 +10649,8 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
|
|||
if (const RecordType *RT = NewClassTy->getAs<RecordType>()) {
|
||||
if (!RT->isBeingDefined() &&
|
||||
RequireCompleteType(New->getLocation(), NewClassTy,
|
||||
PDiag(diag::err_covariant_return_incomplete)
|
||||
<< New->getDeclName()))
|
||||
diag::err_covariant_return_incomplete,
|
||||
New->getDeclName()))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -474,11 +474,11 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
Diag(SuperLoc, diag::err_undef_superclass)
|
||||
<< SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
|
||||
else if (RequireCompleteType(SuperLoc,
|
||||
Context.getObjCInterfaceType(SuperClassDecl),
|
||||
PDiag(diag::err_forward_superclass)
|
||||
<< SuperClassDecl->getDeclName()
|
||||
<< ClassName
|
||||
<< SourceRange(AtInterfaceLoc, ClassLoc))) {
|
||||
Context.getObjCInterfaceType(SuperClassDecl),
|
||||
diag::err_forward_superclass,
|
||||
SuperClassDecl->getDeclName(),
|
||||
ClassName,
|
||||
SourceRange(AtInterfaceLoc, ClassLoc))) {
|
||||
SuperClassDecl = 0;
|
||||
}
|
||||
}
|
||||
|
@ -759,8 +759,8 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
|
|||
|
||||
if (!IDecl
|
||||
|| RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
|
||||
PDiag(diag::err_category_forward_interface)
|
||||
<< (CategoryName == 0))) {
|
||||
diag::err_category_forward_interface,
|
||||
CategoryName == 0)) {
|
||||
// Create an invalid ObjCCategoryDecl to serve as context for
|
||||
// the enclosing method declarations. We mark the decl invalid
|
||||
// to make it clear that this isn't a valid AST.
|
||||
|
|
|
@ -51,7 +51,8 @@ bool Sema::CheckSpecifiedExceptionType(QualType T, const SourceRange &Range) {
|
|||
// C++ 15.4p2: A type denoted in an exception-specification shall not denote
|
||||
// an incomplete type.
|
||||
if (RequireCompleteType(Range.getBegin(), T,
|
||||
PDiag(diag::err_incomplete_in_exception_spec) << /*direct*/0 << Range))
|
||||
diag::err_incomplete_in_exception_spec,
|
||||
/*direct*/0, Range))
|
||||
return true;
|
||||
|
||||
// C++ 15.4p2: A type denoted in an exception-specification shall not denote
|
||||
|
@ -71,8 +72,9 @@ bool Sema::CheckSpecifiedExceptionType(QualType T, const SourceRange &Range) {
|
|||
if (T->isRecordType() && T->getAs<RecordType>()->isBeingDefined())
|
||||
return false;
|
||||
|
||||
if (!T->isVoidType() && RequireCompleteType(Range.getBegin(), T,
|
||||
PDiag(diag::err_incomplete_in_exception_spec) << kind << Range))
|
||||
if (!T->isVoidType() &&
|
||||
RequireCompleteType(Range.getBegin(), T,
|
||||
diag::err_incomplete_in_exception_spec, kind, Range))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -2838,9 +2838,8 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
|
|||
return false;
|
||||
|
||||
if (RequireCompleteExprType(E,
|
||||
PDiag(diag::err_sizeof_alignof_incomplete_type)
|
||||
<< ExprKind << E->getSourceRange(),
|
||||
std::make_pair(SourceLocation(), PDiag(0))))
|
||||
diag::err_sizeof_alignof_incomplete_type,
|
||||
ExprKind, E->getSourceRange()))
|
||||
return true;
|
||||
|
||||
// Completeing the expression's type may have changed it.
|
||||
|
@ -2907,8 +2906,8 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType,
|
|||
return false;
|
||||
|
||||
if (RequireCompleteType(OpLoc, ExprType,
|
||||
PDiag(diag::err_sizeof_alignof_incomplete_type)
|
||||
<< ExprKind << ExprRange))
|
||||
diag::err_sizeof_alignof_incomplete_type,
|
||||
ExprKind, ExprRange))
|
||||
return true;
|
||||
|
||||
if (CheckObjCTraitOperandConstraints(*this, ExprType, OpLoc, ExprRange,
|
||||
|
@ -3246,8 +3245,7 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
|
|||
if (!ResultType.hasQualifiers()) VK = VK_RValue;
|
||||
} else if (!ResultType->isDependentType() &&
|
||||
RequireCompleteType(LLoc, ResultType,
|
||||
PDiag(diag::err_subscript_incomplete_type)
|
||||
<< BaseExpr->getSourceRange()))
|
||||
diag::err_subscript_incomplete_type, BaseExpr))
|
||||
return ExprError();
|
||||
|
||||
// Diagnose bad cases where we step over interface counts.
|
||||
|
@ -3465,8 +3463,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
|
|||
|
||||
if (RequireCompleteType(Arg->getLocStart(),
|
||||
ProtoArgType,
|
||||
PDiag(diag::err_call_incomplete_argument)
|
||||
<< Arg->getSourceRange()))
|
||||
diag::err_call_incomplete_argument, Arg))
|
||||
return true;
|
||||
|
||||
// Pass the argument
|
||||
|
@ -3909,8 +3906,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
|
|||
|
||||
if (RequireCompleteType(Arg->getLocStart(),
|
||||
Arg->getType(),
|
||||
PDiag(diag::err_call_incomplete_argument)
|
||||
<< Arg->getSourceRange()))
|
||||
diag::err_call_incomplete_argument, Arg))
|
||||
return ExprError();
|
||||
|
||||
TheCall->setArg(i, Arg);
|
||||
|
@ -3963,18 +3959,17 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
|
|||
|
||||
if (literalType->isArrayType()) {
|
||||
if (RequireCompleteType(LParenLoc, Context.getBaseElementType(literalType),
|
||||
PDiag(diag::err_illegal_decl_array_incomplete_type)
|
||||
<< SourceRange(LParenLoc,
|
||||
LiteralExpr->getSourceRange().getEnd())))
|
||||
diag::err_illegal_decl_array_incomplete_type,
|
||||
SourceRange(LParenLoc,
|
||||
LiteralExpr->getSourceRange().getEnd())))
|
||||
return ExprError();
|
||||
if (literalType->isVariableArrayType())
|
||||
return ExprError(Diag(LParenLoc, diag::err_variable_object_no_init)
|
||||
<< SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd()));
|
||||
} else if (!literalType->isDependentType() &&
|
||||
RequireCompleteType(LParenLoc, literalType,
|
||||
PDiag(diag::err_typecheck_decl_incomplete_type)
|
||||
<< SourceRange(LParenLoc,
|
||||
LiteralExpr->getSourceRange().getEnd())))
|
||||
diag::err_typecheck_decl_incomplete_type,
|
||||
SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd())))
|
||||
return ExprError();
|
||||
|
||||
InitializedEntity Entity
|
||||
|
@ -6059,8 +6054,8 @@ static bool checkArithmeticIncompletePointerType(Sema &S, SourceLocation Loc,
|
|||
QualType PointeeTy = Operand->getType()->getPointeeType();
|
||||
if (S.RequireCompleteType(
|
||||
Loc, PointeeTy,
|
||||
S.PDiag(diag::err_typecheck_arithmetic_incomplete_type)
|
||||
<< PointeeTy << Operand->getSourceRange()))
|
||||
diag::err_typecheck_arithmetic_incomplete_type,
|
||||
PointeeTy, Operand->getSourceRange()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -7288,8 +7283,7 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
|
|||
case Expr::MLV_IncompleteType:
|
||||
case Expr::MLV_IncompleteVoidType:
|
||||
return S.RequireCompleteType(Loc, E->getType(),
|
||||
S.PDiag(diag::err_typecheck_incomplete_type_not_modifiable_lvalue)
|
||||
<< E->getSourceRange());
|
||||
diag::err_typecheck_incomplete_type_not_modifiable_lvalue, E);
|
||||
case Expr::MLV_DuplicateVectorComponents:
|
||||
Diag = diag::err_typecheck_duplicate_vector_components_not_mlvalue;
|
||||
break;
|
||||
|
@ -8686,8 +8680,7 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
|
|||
// with an incomplete type would be ill-formed.
|
||||
if (!Dependent
|
||||
&& RequireCompleteType(BuiltinLoc, ArgTy,
|
||||
PDiag(diag::err_offsetof_incomplete_type)
|
||||
<< TypeRange))
|
||||
diag::err_offsetof_incomplete_type, TypeRange))
|
||||
return ExprError();
|
||||
|
||||
// offsetof with non-identifier designators (e.g. "offsetof(x, a.b[c])") are a
|
||||
|
@ -9207,8 +9200,8 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
|
|||
|
||||
if (!TInfo->getType()->isDependentType()) {
|
||||
if (RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), TInfo->getType(),
|
||||
PDiag(diag::err_second_parameter_to_va_arg_incomplete)
|
||||
<< TInfo->getTypeLoc().getSourceRange()))
|
||||
diag::err_second_parameter_to_va_arg_incomplete,
|
||||
TInfo->getTypeLoc()))
|
||||
return ExprError();
|
||||
|
||||
if (RequireNonAbstractType(TInfo->getTypeLoc().getBeginLoc(),
|
||||
|
@ -10670,18 +10663,30 @@ bool Sema::CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
|
|||
return false;
|
||||
}
|
||||
|
||||
PartialDiagnostic Note =
|
||||
FD ? PDiag(diag::note_function_with_incomplete_return_type_declared_here)
|
||||
<< FD->getDeclName() : PDiag();
|
||||
SourceLocation NoteLoc = FD ? FD->getLocation() : SourceLocation();
|
||||
|
||||
if (RequireCompleteType(Loc, ReturnType,
|
||||
FD ?
|
||||
PDiag(diag::err_call_function_incomplete_return)
|
||||
<< CE->getSourceRange() << FD->getDeclName() :
|
||||
PDiag(diag::err_call_incomplete_return)
|
||||
<< CE->getSourceRange(),
|
||||
std::make_pair(NoteLoc, Note)))
|
||||
class CallReturnIncompleteDiagnoser : public IncompleteTypeDiagnoser {
|
||||
FunctionDecl *FD;
|
||||
CallExpr *CE;
|
||||
|
||||
public:
|
||||
CallReturnIncompleteDiagnoser(FunctionDecl *FD, CallExpr *CE)
|
||||
: FD(FD), CE(CE) { }
|
||||
|
||||
virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
|
||||
if (!FD) {
|
||||
S.Diag(Loc, diag::err_call_incomplete_return)
|
||||
<< T << CE->getSourceRange();
|
||||
return;
|
||||
}
|
||||
|
||||
S.Diag(Loc, diag::err_call_function_incomplete_return)
|
||||
<< CE->getSourceRange() << FD->getDeclName() << T;
|
||||
S.Diag(FD->getLocation(),
|
||||
diag::note_function_with_incomplete_return_type_declared_here)
|
||||
<< FD->getDeclName();
|
||||
}
|
||||
} Diagnoser(FD, CE);
|
||||
|
||||
if (RequireCompleteType(Loc, ReturnType, Diagnoser))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -584,9 +584,9 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E,
|
|||
}
|
||||
if (!isPointer || !Ty->isVoidType()) {
|
||||
if (RequireCompleteType(ThrowLoc, Ty,
|
||||
PDiag(isPointer ? diag::err_throw_incomplete_ptr
|
||||
: diag::err_throw_incomplete)
|
||||
<< E->getSourceRange()))
|
||||
isPointer? diag::err_throw_incomplete_ptr
|
||||
: diag::err_throw_incomplete,
|
||||
E->getSourceRange()))
|
||||
return ExprError();
|
||||
|
||||
if (RequireNonAbstractType(ThrowLoc, E->getType(),
|
||||
|
@ -839,8 +839,7 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
|
|||
|
||||
if (!Ty->isVoidType() &&
|
||||
RequireCompleteType(TyBeginLoc, ElemTy,
|
||||
PDiag(diag::err_invalid_incomplete_type_use)
|
||||
<< FullRange))
|
||||
diag::err_invalid_incomplete_type_use, FullRange))
|
||||
return ExprError();
|
||||
|
||||
if (RequireNonAbstractType(TyBeginLoc, Ty,
|
||||
|
@ -1401,9 +1400,7 @@ bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
|
|||
return Diag(Loc, diag::err_bad_new_type)
|
||||
<< AllocType << 1 << R;
|
||||
else if (!AllocType->isDependentType() &&
|
||||
RequireCompleteType(Loc, AllocType,
|
||||
PDiag(diag::err_new_incomplete_type)
|
||||
<< R))
|
||||
RequireCompleteType(Loc, AllocType, diag::err_new_incomplete_type,R))
|
||||
return true;
|
||||
else if (RequireNonAbstractType(Loc, AllocType,
|
||||
diag::err_allocation_of_abstract_type))
|
||||
|
@ -2014,7 +2011,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
|
|||
|
||||
if (const RecordType *Record = Type->getAs<RecordType>()) {
|
||||
if (RequireCompleteType(StartLoc, Type,
|
||||
PDiag(diag::err_delete_incomplete_class_type)))
|
||||
diag::err_delete_incomplete_class_type))
|
||||
return ExprError();
|
||||
|
||||
SmallVector<CXXConversionDecl*, 4> ObjectPtrConversions;
|
||||
|
@ -2084,8 +2081,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
|
|||
<< Type << Ex.get()->getSourceRange());
|
||||
} else if (!Pointee->isDependentType()) {
|
||||
if (!RequireCompleteType(StartLoc, Pointee,
|
||||
PDiag(diag::warn_delete_incomplete)
|
||||
<< Ex.get()->getSourceRange())) {
|
||||
diag::warn_delete_incomplete, Ex.get())) {
|
||||
if (const RecordType *RT = PointeeElem->getAs<RecordType>())
|
||||
PointeeRD = cast<CXXRecordDecl>(RT->getDecl());
|
||||
}
|
||||
|
@ -3767,8 +3763,8 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
|
|||
|
||||
if (!Context.hasSameUnqualifiedType(Class, LHSType)) {
|
||||
// If we want to check the hierarchy, we need a complete type.
|
||||
if (RequireCompleteType(Loc, LHSType, PDiag(diag::err_bad_memptr_lhs)
|
||||
<< OpSpelling << (int)isIndirect)) {
|
||||
if (RequireCompleteType(Loc, LHSType, diag::err_bad_memptr_lhs,
|
||||
OpSpelling, (int)isIndirect)) {
|
||||
return QualType();
|
||||
}
|
||||
CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
|
||||
|
@ -4833,8 +4829,7 @@ Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc,
|
|||
// the member function body.
|
||||
if (!BaseType->isDependentType() &&
|
||||
!isThisOutsideMemberFunctionBody(BaseType) &&
|
||||
RequireCompleteType(OpLoc, BaseType,
|
||||
PDiag(diag::err_incomplete_member_access)))
|
||||
RequireCompleteType(OpLoc, BaseType, diag::err_incomplete_member_access))
|
||||
return ExprError();
|
||||
|
||||
// C++ [basic.lookup.classref]p2:
|
||||
|
|
|
@ -548,8 +548,8 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
|
|||
RecordDecl *RDecl = RTy->getDecl();
|
||||
if (!SemaRef.isThisOutsideMemberFunctionBody(QualType(RTy, 0)) &&
|
||||
SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0),
|
||||
SemaRef.PDiag(diag::err_typecheck_incomplete_tag)
|
||||
<< BaseRange))
|
||||
diag::err_typecheck_incomplete_tag,
|
||||
BaseRange))
|
||||
return true;
|
||||
|
||||
if (HasTemplateArgs) {
|
||||
|
@ -1150,9 +1150,8 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (RequireCompleteType(OpLoc, BaseType,
|
||||
PDiag(diag::err_typecheck_incomplete_tag)
|
||||
<< BaseExpr.get()->getSourceRange()))
|
||||
if (RequireCompleteType(OpLoc, BaseType, diag::err_typecheck_incomplete_tag,
|
||||
BaseExpr.get()))
|
||||
return ExprError();
|
||||
|
||||
ObjCInterfaceDecl *ClassDeclared = 0;
|
||||
|
|
|
@ -910,8 +910,8 @@ ExprResult Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
|
|||
if (!EncodedType->getAsArrayTypeUnsafe() && //// Incomplete array is handled.
|
||||
!EncodedType->isVoidType()) // void is handled too.
|
||||
if (RequireCompleteType(AtLoc, EncodedType,
|
||||
PDiag(diag::err_incomplete_type_objc_at_encode)
|
||||
<< EncodedTypeInfo->getTypeLoc().getSourceRange()))
|
||||
diag::err_incomplete_type_objc_at_encode,
|
||||
EncodedTypeInfo->getTypeLoc()))
|
||||
return ExprError();
|
||||
|
||||
std::string Str;
|
||||
|
@ -1176,8 +1176,7 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
|
|||
|
||||
if (RequireCompleteType(argExpr->getSourceRange().getBegin(),
|
||||
param->getType(),
|
||||
PDiag(diag::err_call_incomplete_argument)
|
||||
<< argExpr->getSourceRange()))
|
||||
diag::err_call_incomplete_argument, argExpr))
|
||||
return true;
|
||||
|
||||
InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
|
||||
|
@ -1395,8 +1394,8 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
|
|||
SourceRange BaseRange = Super? SourceRange(SuperLoc)
|
||||
: BaseExpr->getSourceRange();
|
||||
if (RequireCompleteType(MemberLoc, OPT->getPointeeType(),
|
||||
PDiag(diag::err_property_not_found_forward_class)
|
||||
<< MemberName << BaseRange))
|
||||
diag::err_property_not_found_forward_class,
|
||||
MemberName, BaseRange))
|
||||
return ExprError();
|
||||
|
||||
// Search for a declared property first.
|
||||
|
@ -1524,8 +1523,8 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
|
|||
if (const ObjCObjectPointerType * OBJPT =
|
||||
T->getAsObjCInterfacePointerType()) {
|
||||
if (RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),
|
||||
PDiag(diag::err_property_not_as_forward_class)
|
||||
<< MemberName << BaseExpr->getSourceRange()))
|
||||
diag::err_property_not_as_forward_class,
|
||||
MemberName, BaseExpr))
|
||||
return ExprError();
|
||||
}
|
||||
Diag(MemberLoc,
|
||||
|
@ -1958,11 +1957,11 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
|
|||
SourceRange TypeRange
|
||||
= SuperLoc.isValid()? SourceRange(SuperLoc)
|
||||
: ReceiverTypeInfo->getTypeLoc().getSourceRange();
|
||||
if (RequireCompleteType(Loc, Context.getObjCInterfaceType(Class),
|
||||
if (RequireCompleteType(Loc, Context.getObjCInterfaceType(Class),
|
||||
(getLangOpts().ObjCAutoRefCount
|
||||
? PDiag(diag::err_arc_receiver_forward_class)
|
||||
: PDiag(diag::warn_receiver_forward_class))
|
||||
<< TypeRange)) {
|
||||
? diag::err_arc_receiver_forward_class
|
||||
: diag::warn_receiver_forward_class),
|
||||
TypeRange)) {
|
||||
// A forward class used in messaging is treated as a 'Class'
|
||||
Method = LookupFactoryMethodInGlobalPool(Sel,
|
||||
SourceRange(LBracLoc, RBracLoc));
|
||||
|
@ -2221,12 +2220,10 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
|
|||
const ObjCInterfaceDecl *forwardClass = 0;
|
||||
if (RequireCompleteType(Loc, OCIType->getPointeeType(),
|
||||
getLangOpts().ObjCAutoRefCount
|
||||
? PDiag(diag::err_arc_receiver_forward_instance)
|
||||
<< (Receiver ? Receiver->getSourceRange()
|
||||
: SourceRange(SuperLoc))
|
||||
: PDiag(diag::warn_receiver_forward_instance)
|
||||
<< (Receiver ? Receiver->getSourceRange()
|
||||
: SourceRange(SuperLoc)))) {
|
||||
? diag::err_arc_receiver_forward_instance
|
||||
: diag::warn_receiver_forward_instance,
|
||||
Receiver? Receiver->getSourceRange()
|
||||
: SourceRange(SuperLoc))) {
|
||||
if (getLangOpts().ObjCAutoRefCount)
|
||||
return ExprError();
|
||||
|
||||
|
|
|
@ -3108,7 +3108,7 @@ static void TryListInitialization(Sema &S,
|
|||
return;
|
||||
}
|
||||
if (DestType->isRecordType()) {
|
||||
if (S.RequireCompleteType(InitList->getLocStart(), DestType, S.PDiag())) {
|
||||
if (S.RequireCompleteType(InitList->getLocStart(), DestType, 0)) {
|
||||
Sequence.setIncompleteTypeFailure(DestType);
|
||||
return;
|
||||
}
|
||||
|
@ -4452,7 +4452,7 @@ static ExprResult CopyObject(Sema &S,
|
|||
SourceLocation Loc = getInitializationLoc(Entity, CurInit.get());
|
||||
|
||||
// Make sure that the type we are copying is complete.
|
||||
if (S.RequireCompleteType(Loc, T, S.PDiag(diag::err_temp_copy_incomplete)))
|
||||
if (S.RequireCompleteType(Loc, T, diag::err_temp_copy_incomplete))
|
||||
return move(CurInit);
|
||||
|
||||
// Perform overload resolution using the class's copy/move constructors.
|
||||
|
@ -4516,7 +4516,7 @@ static ExprResult CopyObject(Sema &S,
|
|||
for (unsigned I = 1, N = Constructor->getNumParams(); I != N; ++I) {
|
||||
ParmVarDecl *Parm = Constructor->getParamDecl(I);
|
||||
if (S.RequireCompleteType(Loc, Parm->getType(),
|
||||
S.PDiag(diag::err_call_incomplete_argument)))
|
||||
diag::err_call_incomplete_argument))
|
||||
break;
|
||||
|
||||
// Build the default argument expression; we don't actually care
|
||||
|
|
|
@ -670,8 +670,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
|
|||
QualType PropertyIvarType = PropType.getNonReferenceType();
|
||||
|
||||
if (RequireCompleteType(PropertyDiagLoc, PropertyIvarType,
|
||||
PDiag(diag::err_incomplete_synthesized_property)
|
||||
<< property->getDeclName())) {
|
||||
diag::err_incomplete_synthesized_property,
|
||||
property->getDeclName())) {
|
||||
Diag(property->getLocation(), diag::note_property_declare);
|
||||
CompleteTypeErr = true;
|
||||
}
|
||||
|
|
|
@ -1657,7 +1657,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
|
|||
|
||||
// We have already pre-calculated the promotion type, so this is trivial.
|
||||
if (ToType->isIntegerType() &&
|
||||
!RequireCompleteType(From->getLocStart(), FromType, PDiag()))
|
||||
!RequireCompleteType(From->getLocStart(), FromType, 0))
|
||||
return Context.hasSameUnqualifiedType(ToType,
|
||||
FromEnumType->getDecl()->getPromotionType());
|
||||
}
|
||||
|
@ -1987,7 +1987,7 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
|
|||
if (getLangOpts().CPlusPlus &&
|
||||
FromPointeeType->isRecordType() && ToPointeeType->isRecordType() &&
|
||||
!Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType) &&
|
||||
!RequireCompleteType(From->getLocStart(), FromPointeeType, PDiag()) &&
|
||||
!RequireCompleteType(From->getLocStart(), FromPointeeType, 0) &&
|
||||
IsDerivedFrom(FromPointeeType, ToPointeeType)) {
|
||||
ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
|
||||
ToPointeeType,
|
||||
|
@ -2616,7 +2616,7 @@ bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType,
|
|||
QualType ToClass(ToTypePtr->getClass(), 0);
|
||||
|
||||
if (!Context.hasSameUnqualifiedType(FromClass, ToClass) &&
|
||||
!RequireCompleteType(From->getLocStart(), ToClass, PDiag()) &&
|
||||
!RequireCompleteType(From->getLocStart(), ToClass, 0) &&
|
||||
IsDerivedFrom(ToClass, FromClass)) {
|
||||
ConvertedType = Context.getMemberPointerType(FromTypePtr->getPointeeType(),
|
||||
ToClass.getTypePtr());
|
||||
|
@ -2923,7 +2923,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
|||
S.IsDerivedFrom(From->getType(), ToType)))
|
||||
ConstructorsOnly = true;
|
||||
|
||||
S.RequireCompleteType(From->getLocStart(), ToType, S.PDiag());
|
||||
S.RequireCompleteType(From->getLocStart(), ToType, 0);
|
||||
// RequireCompleteType may have returned true due to some invalid decl
|
||||
// during template instantiation, but ToType may be complete enough now
|
||||
// to try to recover.
|
||||
|
@ -3001,8 +3001,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
|||
|
||||
// Enumerate conversion functions, if we're allowed to.
|
||||
if (ConstructorsOnly || isa<InitListExpr>(From)) {
|
||||
} else if (S.RequireCompleteType(From->getLocStart(), From->getType(),
|
||||
S.PDiag(0) << From->getSourceRange())) {
|
||||
} else if (S.RequireCompleteType(From->getLocStart(), From->getType(), 0)) {
|
||||
// No conversion functions from incomplete types.
|
||||
} else if (const RecordType *FromRecordType
|
||||
= From->getType()->getAs<RecordType>()) {
|
||||
|
@ -3848,7 +3847,7 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
|
|||
ObjCLifetimeConversion = false;
|
||||
if (UnqualT1 == UnqualT2) {
|
||||
// Nothing to do.
|
||||
} else if (!RequireCompleteType(Loc, OrigT2, PDiag()) &&
|
||||
} else if (!RequireCompleteType(Loc, OrigT2, 0) &&
|
||||
IsDerivedFrom(UnqualT2, UnqualT1))
|
||||
DerivedToBase = true;
|
||||
else if (UnqualT1->isObjCObjectOrInterfaceType() &&
|
||||
|
@ -4313,7 +4312,7 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
|
|||
|
||||
// We need a complete type for what follows. Incomplete types can never be
|
||||
// initialized from init lists.
|
||||
if (S.RequireCompleteType(From->getLocStart(), ToType, S.PDiag()))
|
||||
if (S.RequireCompleteType(From->getLocStart(), ToType, 0))
|
||||
return Result;
|
||||
|
||||
// C++11 [over.ics.list]p2:
|
||||
|
@ -5062,7 +5061,18 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
|
|||
}
|
||||
|
||||
// We must have a complete class type.
|
||||
if (RequireCompleteType(Loc, T, IncompleteDiag))
|
||||
struct IncompleteTypeDiagnoserPartialDiag : IncompleteTypeDiagnoser {
|
||||
const PartialDiagnostic &PD;
|
||||
|
||||
IncompleteTypeDiagnoserPartialDiag(const PartialDiagnostic &PD)
|
||||
: IncompleteTypeDiagnoser(PD.getDiagID() == 0), PD(PD) {}
|
||||
|
||||
virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
|
||||
S.Diag(Loc, PD) << T;
|
||||
}
|
||||
} IncompleteDiagnoser(IncompleteDiag);
|
||||
|
||||
if (RequireCompleteType(Loc, T, IncompleteDiagnoser))
|
||||
return Owned(From);
|
||||
|
||||
// Look for a conversion to an integral or enumeration type.
|
||||
|
@ -5906,7 +5916,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
|
|||
// empty.
|
||||
if (const RecordType *T1Rec = T1->getAs<RecordType>()) {
|
||||
// Complete the type if it can be completed. Otherwise, we're done.
|
||||
if (RequireCompleteType(OpLoc, T1, PDiag()))
|
||||
if (RequireCompleteType(OpLoc, T1, 0))
|
||||
return;
|
||||
|
||||
LookupResult Operators(*this, OpName, OpLoc, LookupOrdinaryName);
|
||||
|
@ -10610,8 +10620,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
|
|||
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
|
||||
|
||||
if (RequireCompleteType(LParenLoc, Object.get()->getType(),
|
||||
PDiag(diag::err_incomplete_object_call)
|
||||
<< Object.get()->getSourceRange()))
|
||||
diag::err_incomplete_object_call, Object.get()))
|
||||
return true;
|
||||
|
||||
LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName);
|
||||
|
@ -10899,8 +10908,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
|
|||
const RecordType *BaseRecord = Base->getType()->getAs<RecordType>();
|
||||
|
||||
if (RequireCompleteType(Loc, Base->getType(),
|
||||
PDiag(diag::err_typecheck_incomplete_tag)
|
||||
<< Base->getSourceRange()))
|
||||
diag::err_typecheck_incomplete_tag, Base))
|
||||
return ExprError();
|
||||
|
||||
LookupResult R(*this, OpName, OpLoc, LookupOrdinaryName);
|
||||
|
|
|
@ -889,8 +889,7 @@ Sema::ObjCSubscriptKind
|
|||
|
||||
// We must have a complete class type.
|
||||
if (RequireCompleteType(FromE->getExprLoc(), T,
|
||||
PDiag(diag::err_objc_index_incomplete_class_type)
|
||||
<< FromE->getSourceRange()))
|
||||
diag::err_objc_index_incomplete_class_type, FromE))
|
||||
return OS_Error;
|
||||
|
||||
// Look for a conversion to an integral, enumeration type, or
|
||||
|
|
|
@ -1350,9 +1350,9 @@ Sema::ActOnObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) {
|
|||
if (iface &&
|
||||
RequireCompleteType(forLoc, QualType(objectType, 0),
|
||||
getLangOpts().ObjCAutoRefCount
|
||||
? PDiag(diag::err_arc_collection_forward)
|
||||
<< collection->getSourceRange()
|
||||
: PDiag(0))) {
|
||||
? diag::err_arc_collection_forward
|
||||
: 0,
|
||||
collection)) {
|
||||
// Otherwise, if we have any useful type information, check that
|
||||
// the type declares the appropriate method.
|
||||
} else if (iface || !objectType->qual_empty()) {
|
||||
|
@ -1659,7 +1659,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
|
|||
QualType RangeType = Range->getType();
|
||||
|
||||
if (RequireCompleteType(RangeLoc, RangeType,
|
||||
PDiag(diag::err_for_range_incomplete_type)))
|
||||
diag::err_for_range_incomplete_type))
|
||||
return StmtError();
|
||||
|
||||
// Build auto __begin = begin-expr, __end = end-expr.
|
||||
|
|
|
@ -2825,9 +2825,7 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S,
|
|||
QualType PointeeType = ParamRefType->getPointeeType();
|
||||
|
||||
// If the argument has incomplete array type, try to complete it's type.
|
||||
if (ArgType->isIncompleteArrayType() &&
|
||||
!S.RequireCompleteExprType(Arg, S.PDiag(),
|
||||
std::make_pair(SourceLocation(), S.PDiag())))
|
||||
if (ArgType->isIncompleteArrayType() && !S.RequireCompleteExprType(Arg, 0))
|
||||
ArgType = Arg->getType();
|
||||
|
||||
// [C++0x] If P is an rvalue reference to a cv-unqualified
|
||||
|
|
|
@ -4043,14 +4043,12 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
|||
/// case of a reference type, the referred-to type).
|
||||
///
|
||||
/// \param E The expression whose type is required to be complete.
|
||||
/// \param PD The partial diagnostic that will be printed out if the type cannot
|
||||
/// be completed.
|
||||
/// \param Diagnoser The object that will emit a diagnostic if the type is
|
||||
/// incomplete.
|
||||
///
|
||||
/// \returns \c true if the type of \p E is incomplete and diagnosed, \c false
|
||||
/// otherwise.
|
||||
bool Sema::RequireCompleteExprType(Expr *E, const PartialDiagnostic &PD,
|
||||
std::pair<SourceLocation,
|
||||
PartialDiagnostic> Note) {
|
||||
bool Sema::RequireCompleteExprType(Expr *E, IncompleteTypeDiagnoser &Diagnoser){
|
||||
QualType T = E->getType();
|
||||
|
||||
// Fast path the case where the type is already complete.
|
||||
|
@ -4107,7 +4105,26 @@ bool Sema::RequireCompleteExprType(Expr *E, const PartialDiagnostic &PD,
|
|||
if (const ReferenceType *Ref = T->getAs<ReferenceType>())
|
||||
T = Ref->getPointeeType();
|
||||
|
||||
return RequireCompleteType(E->getExprLoc(), T, PD, Note);
|
||||
return RequireCompleteType(E->getExprLoc(), T, Diagnoser);
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct IncompleteTypeDiagnoserDiag : Sema::IncompleteTypeDiagnoser {
|
||||
unsigned DiagID;
|
||||
|
||||
IncompleteTypeDiagnoserDiag(unsigned DiagID)
|
||||
: Sema::IncompleteTypeDiagnoser(DiagID == 0), DiagID(DiagID) {}
|
||||
|
||||
virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
|
||||
if (Suppressed) return;
|
||||
S.Diag(Loc, DiagID) << T;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
bool Sema::RequireCompleteExprType(Expr *E, unsigned DiagID) {
|
||||
IncompleteTypeDiagnoserDiag Diagnoser(DiagID);
|
||||
return RequireCompleteExprType(E, Diagnoser);
|
||||
}
|
||||
|
||||
/// @brief Ensure that the type T is a complete type.
|
||||
|
@ -4131,11 +4148,7 @@ bool Sema::RequireCompleteExprType(Expr *E, const PartialDiagnostic &PD,
|
|||
/// @returns @c true if @p T is incomplete and a diagnostic was emitted,
|
||||
/// @c false otherwise.
|
||||
bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
|
||||
const PartialDiagnostic &PD,
|
||||
std::pair<SourceLocation,
|
||||
PartialDiagnostic> Note) {
|
||||
unsigned diag = PD.getDiagID();
|
||||
|
||||
IncompleteTypeDiagnoser &Diagnoser) {
|
||||
// FIXME: Add this assertion to make sure we always get instantiation points.
|
||||
// assert(!Loc.isInvalid() && "Invalid location in RequireCompleteType");
|
||||
// FIXME: Add this assertion to help us flush out problems with
|
||||
|
@ -4148,7 +4161,7 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
|
|||
NamedDecl *Def = 0;
|
||||
if (!T->isIncompleteType(&Def)) {
|
||||
// If we know about the definition but it is not visible, complain.
|
||||
if (diag != 0 && Def && !LookupResult::isVisible(Def)) {
|
||||
if (!Diagnoser.Suppressed && Def && !LookupResult::isVisible(Def)) {
|
||||
// Suppress this error outside of a SFINAE context if we've already
|
||||
// emitted the error once for this type. There's no usefulness in
|
||||
// repeating the diagnostic.
|
||||
|
@ -4204,7 +4217,7 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
|
|||
if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared)
|
||||
return InstantiateClassTemplateSpecialization(Loc, ClassTemplateSpec,
|
||||
TSK_ImplicitInstantiation,
|
||||
/*Complain=*/diag != 0);
|
||||
/*Complain=*/!Diagnoser.Suppressed);
|
||||
} else if (CXXRecordDecl *Rec
|
||||
= dyn_cast<CXXRecordDecl>(Record->getDecl())) {
|
||||
CXXRecordDecl *Pattern = Rec->getInstantiatedFromMemberClass();
|
||||
|
@ -4216,20 +4229,16 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
|
|||
return InstantiateClass(Loc, Rec, Pattern,
|
||||
getTemplateInstantiationArgs(Rec),
|
||||
TSK_ImplicitInstantiation,
|
||||
/*Complain=*/diag != 0);
|
||||
/*Complain=*/!Diagnoser.Suppressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (diag == 0)
|
||||
if (Diagnoser.Suppressed)
|
||||
return true;
|
||||
|
||||
|
||||
// We have an incomplete type. Produce a diagnostic.
|
||||
Diag(Loc, PD) << T;
|
||||
|
||||
// If we have a note, produce it.
|
||||
if (!Note.first.isInvalid())
|
||||
Diag(Note.first, Note.second);
|
||||
Diagnoser.diagnose(*this, Loc, T);
|
||||
|
||||
// If the type was a forward declaration of a class/struct/union
|
||||
// type, produce a note.
|
||||
|
@ -4247,15 +4256,9 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
|
|||
}
|
||||
|
||||
bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
|
||||
const PartialDiagnostic &PD) {
|
||||
return RequireCompleteType(Loc, T, PD,
|
||||
std::make_pair(SourceLocation(), PDiag(0)));
|
||||
}
|
||||
|
||||
bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
|
||||
unsigned DiagID) {
|
||||
return RequireCompleteType(Loc, T, PDiag(DiagID),
|
||||
std::make_pair(SourceLocation(), PDiag(0)));
|
||||
unsigned DiagID) {
|
||||
IncompleteTypeDiagnoserDiag Diagnoser(DiagID);
|
||||
return RequireCompleteType(Loc, T, Diagnoser);
|
||||
}
|
||||
|
||||
/// @brief Ensure that the type T is a literal type.
|
||||
|
@ -4305,8 +4308,7 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T,
|
|||
// class type must have a trivial destructor (which can't be checked until
|
||||
// the class definition is complete).
|
||||
if (!RD->isCompleteDefinition()) {
|
||||
RequireCompleteType(Loc, ElemType,
|
||||
PDiag(diag::note_non_literal_incomplete) << T);
|
||||
RequireCompleteType(Loc, ElemType, diag::note_non_literal_incomplete, T);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4487,8 +4489,7 @@ QualType Sema::BuildAtomicType(QualType T, SourceLocation Loc) {
|
|||
if (!T->isDependentType()) {
|
||||
// FIXME: It isn't entirely clear whether incomplete atomic types
|
||||
// are allowed or not; for simplicity, ban them for the moment.
|
||||
if (RequireCompleteType(Loc, T,
|
||||
PDiag(diag::err_atomic_specifier_bad_type) << 0))
|
||||
if (RequireCompleteType(Loc, T, diag::err_atomic_specifier_bad_type, 0))
|
||||
return QualType();
|
||||
|
||||
int DisallowedKind = -1;
|
||||
|
|
Loading…
Reference in New Issue