Move Sema::VerifyIntegerConstantExpression() and
Sema::ConvertToIntegralOrEnumerationType() from PartialDiagnostics to
abstract "diagnoser" classes. Not much of a win here, but we're
-several PartialDiagnostics.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156217 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index ba1e699..af3fabb 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -2709,10 +2709,10 @@
SourceLocation AttrLoc = AttrRange.getBegin();
// FIXME: Cache the number on the Attr object?
llvm::APSInt Alignment(32);
- ExprResult ICE =
- VerifyIntegerConstantExpression(E, &Alignment,
- PDiag(diag::err_attribute_argument_not_int) << "aligned",
- /*AllowFold*/ false);
+ ExprResult ICE
+ = VerifyIntegerConstantExpression(E, &Alignment,
+ diag::err_aligned_attribute_argument_not_int,
+ /*AllowFold*/ false);
if (ICE.isInvalid())
return;
if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index e049121..3c74f73 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -9906,7 +9906,7 @@
llvm::APSInt Cond;
if (VerifyIntegerConstantExpression(Converted.get(), &Cond,
- PDiag(diag::err_static_assert_expression_is_not_constant),
+ diag::err_static_assert_expression_is_not_constant,
/*AllowFold=*/false).isInvalid())
return 0;
@@ -11302,7 +11302,7 @@
if (!NoexceptExpr->isValueDependent())
NoexceptExpr = VerifyIntegerConstantExpression(NoexceptExpr, 0,
- PDiag(diag::err_noexcept_needs_constant_expression),
+ diag::err_noexcept_needs_constant_expression,
/*AllowFold*/ false).take();
EPI.NoexceptExpr = NoexceptExpr;
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 36ba46b..3ab0723 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -8868,8 +8868,9 @@
} else {
// The conditional expression is required to be a constant expression.
llvm::APSInt condEval(32);
- ExprResult CondICE = VerifyIntegerConstantExpression(CondExpr, &condEval,
- PDiag(diag::err_typecheck_choose_expr_requires_constant), false);
+ ExprResult CondICE
+ = VerifyIntegerConstantExpression(CondExpr, &condEval,
+ diag::err_typecheck_choose_expr_requires_constant, false);
if (CondICE.isInvalid())
return ExprError();
CondExpr = CondICE.take();
@@ -9452,15 +9453,44 @@
ExprResult Sema::VerifyIntegerConstantExpression(Expr *E,
llvm::APSInt *Result) {
- return VerifyIntegerConstantExpression(E, Result,
- PDiag(diag::err_expr_not_ice) << LangOpts.CPlusPlus);
+ class SimpleICEDiagnoser : public VerifyICEDiagnoser {
+ public:
+ virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) {
+ S.Diag(Loc, diag::err_expr_not_ice) << S.LangOpts.CPlusPlus << SR;
+ }
+ } Diagnoser;
+
+ return VerifyIntegerConstantExpression(E, Result, Diagnoser);
+}
+
+ExprResult Sema::VerifyIntegerConstantExpression(Expr *E,
+ llvm::APSInt *Result,
+ unsigned DiagID,
+ bool AllowFold) {
+ class IDDiagnoser : public VerifyICEDiagnoser {
+ unsigned DiagID;
+
+ public:
+ IDDiagnoser(unsigned DiagID)
+ : VerifyICEDiagnoser(DiagID == 0), DiagID(DiagID) { }
+
+ virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) {
+ S.Diag(Loc, DiagID) << SR;
+ }
+ } Diagnoser(DiagID);
+
+ return VerifyIntegerConstantExpression(E, Result, Diagnoser, AllowFold);
+}
+
+void Sema::VerifyICEDiagnoser::diagnoseFold(Sema &S, SourceLocation Loc,
+ SourceRange SR) {
+ S.Diag(Loc, diag::ext_expr_not_ice) << SR << S.LangOpts.CPlusPlus;
}
ExprResult
Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
- const PartialDiagnostic &NotIceDiag,
- bool AllowFold,
- const PartialDiagnostic &FoldDiag) {
+ VerifyICEDiagnoser &Diagnoser,
+ bool AllowFold) {
SourceLocation DiagLoc = E->getLocStart();
if (getLangOpts().CPlusPlus0x) {
@@ -9470,23 +9500,111 @@
// have a single non-explicit conversion function to an integral or
// unscoped enumeration type
ExprResult Converted;
- if (NotIceDiag.getDiagID()) {
- Converted = ConvertToIntegralOrEnumerationType(
- DiagLoc, E,
- PDiag(diag::err_ice_not_integral),
- PDiag(diag::err_ice_incomplete_type),
- PDiag(diag::err_ice_explicit_conversion),
- PDiag(diag::note_ice_conversion_here),
- PDiag(diag::err_ice_ambiguous_conversion),
- PDiag(diag::note_ice_conversion_here),
- PDiag(0),
- /*AllowScopedEnumerations*/ false);
+ if (!Diagnoser.Suppress) {
+ class CXX11ConvertDiagnoser : public ICEConvertDiagnoser {
+ public:
+ CXX11ConvertDiagnoser() : ICEConvertDiagnoser(false, true) { }
+
+ virtual DiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
+ QualType T) {
+ return S.Diag(Loc, diag::err_ice_not_integral) << T;
+ }
+
+ virtual DiagnosticBuilder diagnoseIncomplete(Sema &S,
+ SourceLocation Loc,
+ QualType T) {
+ return S.Diag(Loc, diag::err_ice_incomplete_type) << T;
+ }
+
+ virtual DiagnosticBuilder diagnoseExplicitConv(Sema &S,
+ SourceLocation Loc,
+ QualType T,
+ QualType ConvTy) {
+ return S.Diag(Loc, diag::err_ice_explicit_conversion) << T << ConvTy;
+ }
+
+ virtual DiagnosticBuilder noteExplicitConv(Sema &S,
+ CXXConversionDecl *Conv,
+ QualType ConvTy) {
+ return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here)
+ << ConvTy->isEnumeralType() << ConvTy;
+ }
+
+ virtual DiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
+ QualType T) {
+ return S.Diag(Loc, diag::err_ice_ambiguous_conversion) << T;
+ }
+
+ virtual DiagnosticBuilder noteAmbiguous(Sema &S,
+ CXXConversionDecl *Conv,
+ QualType ConvTy) {
+ return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here)
+ << ConvTy->isEnumeralType() << ConvTy;
+ }
+
+ virtual DiagnosticBuilder diagnoseConversion(Sema &S,
+ SourceLocation Loc,
+ QualType T,
+ QualType ConvTy) {
+ return DiagnosticBuilder::getEmpty();
+ }
+ } ConvertDiagnoser;
+
+ Converted = ConvertToIntegralOrEnumerationType(DiagLoc, E,
+ ConvertDiagnoser,
+ /*AllowScopedEnumerations*/ false);
} else {
// The caller wants to silently enquire whether this is an ICE. Don't
// produce any diagnostics if it isn't.
- Converted = ConvertToIntegralOrEnumerationType(
- DiagLoc, E, PDiag(), PDiag(), PDiag(), PDiag(),
- PDiag(), PDiag(), PDiag(), false);
+ class SilentICEConvertDiagnoser : public ICEConvertDiagnoser {
+ public:
+ SilentICEConvertDiagnoser() : ICEConvertDiagnoser(true, true) { }
+
+ virtual DiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
+ QualType T) {
+ return DiagnosticBuilder::getEmpty();
+ }
+
+ virtual DiagnosticBuilder diagnoseIncomplete(Sema &S,
+ SourceLocation Loc,
+ QualType T) {
+ return DiagnosticBuilder::getEmpty();
+ }
+
+ virtual DiagnosticBuilder diagnoseExplicitConv(Sema &S,
+ SourceLocation Loc,
+ QualType T,
+ QualType ConvTy) {
+ return DiagnosticBuilder::getEmpty();
+ }
+
+ virtual DiagnosticBuilder noteExplicitConv(Sema &S,
+ CXXConversionDecl *Conv,
+ QualType ConvTy) {
+ return DiagnosticBuilder::getEmpty();
+ }
+
+ virtual DiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
+ QualType T) {
+ return DiagnosticBuilder::getEmpty();
+ }
+
+ virtual DiagnosticBuilder noteAmbiguous(Sema &S,
+ CXXConversionDecl *Conv,
+ QualType ConvTy) {
+ return DiagnosticBuilder::getEmpty();
+ }
+
+ virtual DiagnosticBuilder diagnoseConversion(Sema &S,
+ SourceLocation Loc,
+ QualType T,
+ QualType ConvTy) {
+ return DiagnosticBuilder::getEmpty();
+ }
+ } ConvertDiagnoser;
+
+ Converted = ConvertToIntegralOrEnumerationType(DiagLoc, E,
+ ConvertDiagnoser, false);
}
if (Converted.isInvalid())
return Converted;
@@ -9495,8 +9613,8 @@
return ExprError();
} else if (!E->getType()->isIntegralOrUnscopedEnumerationType()) {
// An ICE must be of integral or unscoped enumeration type.
- if (NotIceDiag.getDiagID())
- Diag(DiagLoc, NotIceDiag) << E->getSourceRange();
+ if (!Diagnoser.Suppress)
+ Diagnoser.diagnoseNotICE(*this, DiagLoc, E->getSourceRange());
return ExprError();
}
@@ -9536,8 +9654,8 @@
}
if (!Folded || !AllowFold) {
- if (NotIceDiag.getDiagID()) {
- Diag(DiagLoc, NotIceDiag) << E->getSourceRange();
+ if (!Diagnoser.Suppress) {
+ Diagnoser.diagnoseNotICE(*this, DiagLoc, E->getSourceRange());
for (unsigned I = 0, N = Notes.size(); I != N; ++I)
Diag(Notes[I].first, Notes[I].second);
}
@@ -9545,11 +9663,7 @@
return ExprError();
}
- if (FoldDiag.getDiagID())
- Diag(DiagLoc, FoldDiag) << E->getSourceRange();
- else
- Diag(DiagLoc, diag::ext_expr_not_ice)
- << E->getSourceRange() << LangOpts.CPlusPlus;
+ Diagnoser.diagnoseFold(*this, DiagLoc, E->getSourceRange());
for (unsigned I = 0, N = Notes.size(); I != N; ++I)
Diag(Notes[I].first, Notes[I].second);
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 0e5d630..7d987af 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -982,8 +982,10 @@
DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr;
if (Expr *NumElts = (Expr *)Array.NumElts) {
if (!NumElts->isTypeDependent() && !NumElts->isValueDependent()) {
- Array.NumElts = VerifyIntegerConstantExpression(NumElts, 0,
- PDiag(diag::err_new_array_nonconst)).take();
+ Array.NumElts
+ = VerifyIntegerConstantExpression(NumElts, 0,
+ diag::err_new_array_nonconst)
+ .take();
if (!Array.NumElts)
return ExprError();
}
@@ -1148,19 +1150,64 @@
// enumeration type, or a class type for which a single non-explicit
// conversion function to integral or unscoped enumeration type exists.
if (ArraySize && !ArraySize->isTypeDependent()) {
- ExprResult ConvertedSize = ConvertToIntegralOrEnumerationType(
- StartLoc, ArraySize,
- PDiag(diag::err_array_size_not_integral) << getLangOpts().CPlusPlus0x,
- PDiag(diag::err_array_size_incomplete_type)
- << ArraySize->getSourceRange(),
- PDiag(diag::err_array_size_explicit_conversion),
- PDiag(diag::note_array_size_conversion),
- PDiag(diag::err_array_size_ambiguous_conversion),
- PDiag(diag::note_array_size_conversion),
- PDiag(getLangOpts().CPlusPlus0x ?
- diag::warn_cxx98_compat_array_size_conversion :
- diag::ext_array_size_conversion),
- /*AllowScopedEnumerations*/ false);
+ class SizeConvertDiagnoser : public ICEConvertDiagnoser {
+ Expr *ArraySize;
+
+ public:
+ SizeConvertDiagnoser(Expr *ArraySize)
+ : ICEConvertDiagnoser(false, false), ArraySize(ArraySize) { }
+
+ virtual DiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
+ QualType T) {
+ return S.Diag(Loc, diag::err_array_size_not_integral)
+ << S.getLangOpts().CPlusPlus0x << T;
+ }
+
+ virtual DiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
+ QualType T) {
+ return S.Diag(Loc, diag::err_array_size_incomplete_type)
+ << T << ArraySize->getSourceRange();
+ }
+
+ virtual DiagnosticBuilder diagnoseExplicitConv(Sema &S,
+ SourceLocation Loc,
+ QualType T,
+ QualType ConvTy) {
+ return S.Diag(Loc, diag::err_array_size_explicit_conversion) << T << ConvTy;
+ }
+
+ virtual DiagnosticBuilder noteExplicitConv(Sema &S,
+ CXXConversionDecl *Conv,
+ QualType ConvTy) {
+ return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
+ << ConvTy->isEnumeralType() << ConvTy;
+ }
+
+ virtual DiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
+ QualType T) {
+ return S.Diag(Loc, diag::err_array_size_ambiguous_conversion) << T;
+ }
+
+ virtual DiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
+ QualType ConvTy) {
+ return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
+ << ConvTy->isEnumeralType() << ConvTy;
+ }
+
+ virtual DiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc,
+ QualType T,
+ QualType ConvTy) {
+ return S.Diag(Loc,
+ S.getLangOpts().CPlusPlus0x
+ ? diag::warn_cxx98_compat_array_size_conversion
+ : diag::ext_array_size_conversion)
+ << T << ConvTy->isEnumeralType() << ConvTy;
+ }
+ } SizeDiagnoser(ArraySize);
+
+ ExprResult ConvertedSize
+ = ConvertToIntegralOrEnumerationType(StartLoc, ArraySize, SizeDiagnoser,
+ /*AllowScopedEnumerations*/ false);
if (ConvertedSize.isInvalid())
return ExprError();
@@ -3610,7 +3657,7 @@
llvm::APSInt Value;
uint64_t Dim;
if (Self.VerifyIntegerConstantExpression(DimExpr, &Value,
- Self.PDiag(diag::err_dimension_expr_not_constant_integer),
+ diag::err_dimension_expr_not_constant_integer,
false).isInvalid())
return 0;
if (Value.isSigned() && Value.isNegative()) {
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index fb8ab47..007ea0f 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -5025,13 +5025,7 @@
/// successful.
ExprResult
Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
- const PartialDiagnostic &NotIntDiag,
- const PartialDiagnostic &IncompleteDiag,
- const PartialDiagnostic &ExplicitConvDiag,
- const PartialDiagnostic &ExplicitConvNote,
- const PartialDiagnostic &AmbigDiag,
- const PartialDiagnostic &AmbigNote,
- const PartialDiagnostic &ConvDiag,
+ ICEConvertDiagnoser &Diagnoser,
bool AllowScopedEnumerations) {
// We can't perform any more checking for type-dependent expressions.
if (From->isTypeDependent())
@@ -5055,22 +5049,23 @@
// expression of integral or enumeration type.
const RecordType *RecordTy = T->getAs<RecordType>();
if (!RecordTy || !getLangOpts().CPlusPlus) {
- if (NotIntDiag.getDiagID())
- Diag(Loc, NotIntDiag) << T << From->getSourceRange();
+ if (!Diagnoser.Suppress)
+ Diagnoser.diagnoseNotInt(*this, Loc, T) << From->getSourceRange();
return Owned(From);
}
// We must have a complete class type.
struct TypeDiagnoserPartialDiag : TypeDiagnoser {
- const PartialDiagnostic &PD;
+ ICEConvertDiagnoser &Diagnoser;
+ Expr *From;
- TypeDiagnoserPartialDiag(const PartialDiagnostic &PD)
- : TypeDiagnoser(PD.getDiagID() == 0), PD(PD) {}
+ TypeDiagnoserPartialDiag(ICEConvertDiagnoser &Diagnoser, Expr *From)
+ : TypeDiagnoser(Diagnoser.Suppress), Diagnoser(Diagnoser), From(From) {}
virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
- S.Diag(Loc, PD) << T;
+ Diagnoser.diagnoseIncomplete(S, Loc, T) << From->getSourceRange();
}
- } IncompleteDiagnoser(IncompleteDiag);
+ } IncompleteDiagnoser(Diagnoser, From);
if (RequireCompleteType(Loc, T, IncompleteDiagnoser))
return Owned(From);
@@ -5102,7 +5097,7 @@
switch (ViableConversions.size()) {
case 0:
- if (ExplicitConversions.size() == 1 && ExplicitConvDiag.getDiagID()) {
+ if (ExplicitConversions.size() == 1 && !Diagnoser.Suppress) {
DeclAccessPair Found = ExplicitConversions[0];
CXXConversionDecl *Conversion
= cast<CXXConversionDecl>(Found->getUnderlyingDecl());
@@ -5114,14 +5109,12 @@
std::string TypeStr;
ConvTy.getAsStringInternal(TypeStr, getPrintingPolicy());
- Diag(Loc, ExplicitConvDiag)
- << T << ConvTy
+ Diagnoser.diagnoseExplicitConv(*this, Loc, T, ConvTy)
<< FixItHint::CreateInsertion(From->getLocStart(),
"static_cast<" + TypeStr + ">(")
<< FixItHint::CreateInsertion(PP.getLocForEndOfToken(From->getLocEnd()),
")");
- Diag(Conversion->getLocation(), ExplicitConvNote)
- << ConvTy->isEnumeralType() << ConvTy;
+ Diagnoser.noteExplicitConv(*this, Conversion, ConvTy);
// If we aren't in a SFINAE context, build a call to the
// explicit conversion function.
@@ -5152,12 +5145,12 @@
= cast<CXXConversionDecl>(Found->getUnderlyingDecl());
QualType ConvTy
= Conversion->getConversionType().getNonReferenceType();
- if (ConvDiag.getDiagID()) {
+ if (!Diagnoser.SuppressConversion) {
if (isSFINAEContext())
return ExprError();
- Diag(Loc, ConvDiag)
- << T << ConvTy->isEnumeralType() << ConvTy << From->getSourceRange();
+ Diagnoser.diagnoseConversion(*this, Loc, T, ConvTy)
+ << From->getSourceRange();
}
ExprResult Result = BuildCXXMemberCallExpr(From, Found, Conversion,
@@ -5173,24 +5166,24 @@
}
default:
- if (!AmbigDiag.getDiagID())
- return Owned(From);
+ if (Diagnoser.Suppress)
+ return ExprError();
- Diag(Loc, AmbigDiag)
- << T << From->getSourceRange();
+ Diagnoser.diagnoseAmbiguous(*this, Loc, T) << From->getSourceRange();
for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
CXXConversionDecl *Conv
= cast<CXXConversionDecl>(ViableConversions[I]->getUnderlyingDecl());
QualType ConvTy = Conv->getConversionType().getNonReferenceType();
- Diag(Conv->getLocation(), AmbigNote)
- << ConvTy->isEnumeralType() << ConvTy;
+ Diagnoser.noteAmbiguous(*this, Conv, ConvTy);
}
return Owned(From);
}
if (!isIntegralOrEnumerationType(From->getType(), AllowScopedEnumerations) &&
- NotIntDiag.getDiagID())
- Diag(Loc, NotIntDiag) << From->getType() << From->getSourceRange();
+ !Diagnoser.Suppress) {
+ Diagnoser.diagnoseNotInt(*this, Loc, From->getType())
+ << From->getSourceRange();
+ }
return DefaultLvalueConversion(From);
}
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 407323d..77cc642 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -521,16 +521,56 @@
if (!Cond)
return StmtError();
+ class SwitchConvertDiagnoser : public ICEConvertDiagnoser {
+ Expr *Cond;
+
+ public:
+ SwitchConvertDiagnoser(Expr *Cond)
+ : ICEConvertDiagnoser(false, true), Cond(Cond) { }
+
+ virtual DiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
+ QualType T) {
+ return S.Diag(Loc, diag::err_typecheck_statement_requires_integer) << T;
+ }
+
+ virtual DiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
+ QualType T) {
+ return S.Diag(Loc, diag::err_switch_incomplete_class_type)
+ << T << Cond->getSourceRange();
+ }
+
+ virtual DiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
+ QualType T,
+ QualType ConvTy) {
+ return S.Diag(Loc, diag::err_switch_explicit_conversion) << T << ConvTy;
+ }
+
+ virtual DiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
+ QualType ConvTy) {
+ return S.Diag(Conv->getLocation(), diag::note_switch_conversion)
+ << ConvTy->isEnumeralType() << ConvTy;
+ }
+
+ virtual DiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
+ QualType T) {
+ return S.Diag(Loc, diag::err_switch_multiple_conversions) << T;
+ }
+
+ virtual DiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
+ QualType ConvTy) {
+ return S.Diag(Conv->getLocation(), diag::note_switch_conversion)
+ << ConvTy->isEnumeralType() << ConvTy;
+ }
+
+ virtual DiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc,
+ QualType T,
+ QualType ConvTy) {
+ return DiagnosticBuilder::getEmpty();
+ }
+ } SwitchDiagnoser(Cond);
+
CondResult
- = ConvertToIntegralOrEnumerationType(SwitchLoc, Cond,
- PDiag(diag::err_typecheck_statement_requires_integer),
- PDiag(diag::err_switch_incomplete_class_type)
- << Cond->getSourceRange(),
- PDiag(diag::err_switch_explicit_conversion),
- PDiag(diag::note_switch_conversion),
- PDiag(diag::err_switch_multiple_conversions),
- PDiag(diag::note_switch_conversion),
- PDiag(0),
+ = ConvertToIntegralOrEnumerationType(SwitchLoc, Cond, SwitchDiagnoser,
/*AllowScopedEnumerations*/ true);
if (CondResult.isInvalid()) return StmtError();
Cond = CondResult.take();
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 35d3cfa..bde80fd 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -4113,8 +4113,20 @@
Diag(Param->getLocation(), diag::note_template_param_here);
return ExprError();
} else if (!Arg->isValueDependent()) {
- Arg = VerifyIntegerConstantExpression(Arg, &Value,
- PDiag(diag::err_template_arg_not_ice) << ArgType, false).take();
+ class TmplArgICEDiagnoser : public VerifyICEDiagnoser {
+ QualType T;
+
+ public:
+ TmplArgICEDiagnoser(QualType T) : T(T) { }
+
+ virtual void diagnoseNotICE(Sema &S, SourceLocation Loc,
+ SourceRange SR) {
+ S.Diag(Loc, diag::err_template_arg_not_ice) << T << SR;
+ }
+ } Diagnoser(ArgType);
+
+ Arg = VerifyIntegerConstantExpression(Arg, &Value, Diagnoser,
+ false).take();
if (!Arg)
return ExprError();
}
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 2da2fbc..51dffac 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2354,9 +2354,10 @@
NoexceptExpr = E.take();
if (!NoexceptExpr->isTypeDependent() &&
!NoexceptExpr->isValueDependent())
- NoexceptExpr = SemaRef.VerifyIntegerConstantExpression(NoexceptExpr,
- 0, SemaRef.PDiag(diag::err_noexcept_needs_constant_expression),
- /*AllowFold*/ false).take();
+ NoexceptExpr
+ = SemaRef.VerifyIntegerConstantExpression(NoexceptExpr,
+ 0, diag::err_noexcept_needs_constant_expression,
+ /*AllowFold*/ false).take();
}
}
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 09e4ec8..527dce4 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1205,9 +1205,20 @@
static bool isArraySizeVLA(Sema &S, Expr *ArraySize, llvm::APSInt &SizeVal) {
// If the size is an ICE, it certainly isn't a VLA. If we're in a GNU mode
// (like gnu99, but not c99) accept any evaluatable value as an extension.
- return S.VerifyIntegerConstantExpression(
- ArraySize, &SizeVal, S.PDiag(), S.LangOpts.GNUMode,
- S.PDiag(diag::ext_vla_folded_to_constant)).isInvalid();
+ class VLADiagnoser : public Sema::VerifyICEDiagnoser {
+ public:
+ VLADiagnoser() : Sema::VerifyICEDiagnoser(true) {}
+
+ virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) {
+ }
+
+ virtual void diagnoseFold(Sema &S, SourceLocation Loc, SourceRange SR) {
+ S.Diag(Loc, diag::ext_vla_folded_to_constant) << SR;
+ }
+ } Diagnoser;
+
+ return S.VerifyIntegerConstantExpression(ArraySize, &SizeVal, Diagnoser,
+ S.LangOpts.GNUMode).isInvalid();
}