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 | e54e8a11822b34f36594d159e4722b3b91391a50 (patch) | |
| tree | 8c79f8cc8fb484350a018dddd0149d92f45bcb3c /clang/lib/Sema | |
| parent | 13cae612b9d0f38f123627991f3ff911aa1dc323 (diff) | |
| download | bcm5719-llvm-e54e8a11822b34f36594d159e4722b3b91391a50.tar.gz bcm5719-llvm-e54e8a11822b34f36594d159e4722b3b91391a50.zip | |
Add Sema::VerifyIntegerConstantExpression
llvm-svn: 60305
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 33 |
2 files changed, 38 insertions, 0 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 044bfbd73be..7b69de5cc24 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index fb964692b35..0c17c75fceb 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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; +} |

