diff options
author | Anders Carlsson <andersca@mac.com> | 2008-11-30 19:50:32 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-11-30 19:50:32 +0000 |
commit | e21555e666004b9aea0c8122358bc4cd3e61c4e7 (patch) | |
tree | e28b7c1688a76ca54fe612dd8616339b5bbb2bd3 | |
parent | 0e8acbbba71ec6acd5dceb4fcbce63e463e1b755 (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.h | 5 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 33 |
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; +} |