aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2008-11-30 19:50:32 +0000
committerAnders Carlsson <andersca@mac.com>2008-11-30 19:50:32 +0000
commite21555e666004b9aea0c8122358bc4cd3e61c4e7 (patch)
treee28b7c1688a76ca54fe612dd8616339b5bbb2bd3
parent0e8acbbba71ec6acd5dceb4fcbce63e463e1b755 (diff)
Add Sema::VerifyIntegerConstantExpression
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60305 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/Sema.h5
-rw-r--r--lib/Sema/SemaExpr.cpp33
2 files changed, 38 insertions, 0 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 044bfbd73b..7b69de5cc2 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1347,6 +1347,11 @@ public:
void InitBuiltinVaListType();
+ /// VerifyIntegerConstantExpression - verifies that an expression is an ICE,
+ /// and reports the appropriate diagnostics. Returns false on success.
+ /// Can optionally return the value of the expression.
+ bool VerifyIntegerConstantExpression(const Expr* E, llvm::APSInt *Result = 0);
+
//===--------------------------------------------------------------------===//
// Extra semantic analysis beyond the C type system
private:
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index fb964692b3..0c17c75fce 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3673,3 +3673,36 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
<< SrcExpr->getSourceRange();
return isInvalid;
}
+
+bool Sema::VerifyIntegerConstantExpression(const Expr* E, llvm::APSInt *Result)
+{
+ Expr::EvalResult EvalResult;
+
+ if (!E->Evaluate(EvalResult, Context) || !EvalResult.Val.isInt() ||
+ EvalResult.HasSideEffects) {
+ Diag(E->getExprLoc(), diag::err_expr_not_ice) << E->getSourceRange();
+
+ if (EvalResult.Diag) {
+ // We only show the note if it's not the usual "invalid subexpression"
+ // or if it's actually in a subexpression.
+ if (EvalResult.Diag != diag::note_invalid_subexpr_in_ice ||
+ E->IgnoreParens() != EvalResult.DiagExpr->IgnoreParens())
+ Diag(EvalResult.DiagLoc, EvalResult.Diag);
+ }
+
+ return true;
+ }
+
+ if (EvalResult.Diag) {
+ Diag(E->getExprLoc(), diag::ext_expr_not_ice) <<
+ E->getSourceRange();
+
+ // Print the reason it's not a constant.
+ if (Diags.getDiagnosticLevel(diag::ext_expr_not_ice) != Diagnostic::Ignored)
+ Diag(EvalResult.DiagLoc, EvalResult.Diag);
+ }
+
+ if (Result)
+ *Result = EvalResult.Val.getInt();
+ return false;
+}