]> granicus.if.org Git - clang/commitdiff
Add Sema::VerifyIntegerConstantExpression
authorAnders Carlsson <andersca@mac.com>
Sun, 30 Nov 2008 19:50:32 +0000 (19:50 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 30 Nov 2008 19:50:32 +0000 (19:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60305 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaExpr.cpp

index 044bfbd73be1bb79964c71e5d6257ac8a390333d..7b69de5cc242179aba74457ca8227b601e146d32 100644 (file)
@@ -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:
index fb964692b3530d51fbc76e0093ac9785c0a79ed5..0c17c75fceb29d4417bd6630335602f301ed08a8 100644 (file)
@@ -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;
+}