Rename Expr::Evaluate to Expr::EvaluateAsRValue to make it clear that it will
implicitly perform an lvalue-to-rvalue conversion if used on an lvalue
expression. Also improve the documentation of Expr::Evaluate* to indicate which
of them will accept expressions with side-effects.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143263 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index b484a42..ca884b9 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -462,12 +462,13 @@
     bool isGlobalLValue() const;
   };
 
-  /// Evaluate - Return true if this is a constant which we can fold using
-  /// any crazy technique (that has nothing to do with language standards) that
-  /// we want to.  If this function returns true, it returns the folded constant
-  /// in Result. If this expression is a glvalue, an lvalue-to-rvalue conversion
-  /// will be applied.
-  bool Evaluate(EvalResult &Result, const ASTContext &Ctx) const;
+  /// EvaluateAsRValue - Return true if this is a constant which we can fold to
+  /// an rvalue using any crazy technique (that has nothing to do with language
+  /// standards) that we want to, even if the expression has side-effects. If
+  /// this function returns true, it returns the folded constant in Result. If
+  /// the expression is a glvalue, an lvalue-to-rvalue conversion will be
+  /// applied.
+  bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const;
 
   /// EvaluateAsBooleanCondition - Return true if this is a constant
   /// which we we can fold and convert to a boolean condition using
@@ -476,28 +477,31 @@
   bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const;
 
   /// EvaluateAsInt - Return true if this is a constant which we can fold and
-  /// convert to an integer using any crazy technique that we want to.
+  /// convert to an integer without side-effects, using any crazy technique that
+  /// we want to.
   bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx) const;
 
-  /// isEvaluatable - Call Evaluate to see if this expression can be constant
-  /// folded, but discard the result.
+  /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
+  /// constant folded without side-effects, but discard the result.
   bool isEvaluatable(const ASTContext &Ctx) const;
 
   /// HasSideEffects - This routine returns true for all those expressions
-  /// which must be evaluated each time and must not be optimized away 
+  /// which must be evaluated each time and must not be optimized away
   /// or evaluated at compile time. Example is a function call, volatile
   /// variable read.
   bool HasSideEffects(const ASTContext &Ctx) const;
-  
-  /// EvaluateKnownConstInt - Call Evaluate and return the folded integer. This
-  /// must be called on an expression that constant folds to an integer.
+
+  /// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
+  /// integer. This must be called on an expression that constant folds to an
+  /// integer.
   llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const;
 
-  /// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue
-  /// with link time known address.
+  /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an
+  /// lvalue with link time known address, with no side-effects.
   bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const;
 
-  /// EvaluateAsLValue - Evaluate an expression to see if it's a lvalue.
+  /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an
+  /// lvalue, even if the expression has side-effects.
   bool EvaluateAsAnyLValue(EvalResult &Result, const ASTContext &Ctx) const;
 
   /// \brief Enumeration used to describe the kind of Null pointer constant
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 6e2e15c..bba7d5e 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -2912,7 +2912,7 @@
 }
 
 //===----------------------------------------------------------------------===//
-// Top level Expr::Evaluate method.
+// Top level Expr::EvaluateAsRValue method.
 //===----------------------------------------------------------------------===//
 
 static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) {
@@ -2951,12 +2951,12 @@
 }
 
 
-/// Evaluate - Return true if this is a constant which we can fold using
+/// EvaluateAsRValue - Return true if this is a constant which we can fold using
 /// any crazy technique (that has nothing to do with language standards) that
 /// we want to.  If this function returns true, it returns the folded constant
 /// in Result. If this expression is a glvalue, an lvalue-to-rvalue conversion
 /// will be applied to the result.
-bool Expr::Evaluate(EvalResult &Result, const ASTContext &Ctx) const {
+bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const {
   EvalInfo Info(Ctx, Result);
 
   if (!::Evaluate(Result.Val, Info, this))
@@ -2968,20 +2968,21 @@
     return HandleLValueToRValueConversion(Info, getType(), LV, Result.Val);
   }
 
-  // FIXME: We don't allow expressions to fold to pointers or references to
-  // locals. Code which calls Evaluate() isn't ready for that yet.
+  // FIXME: We don't allow expressions to fold to pointers to locals. Code which
+  // calls EvaluateAsRValue() isn't ready for that yet.
   return !Result.Val.isLValue() || IsGlobalLValue(Result.Val.getLValueBase());
 }
 
 bool Expr::EvaluateAsBooleanCondition(bool &Result,
                                       const ASTContext &Ctx) const {
   EvalResult Scratch;
-  return Evaluate(Scratch, Ctx) && HandleConversionToBool(Scratch.Val, Result);
+  return EvaluateAsRValue(Scratch, Ctx) &&
+         HandleConversionToBool(Scratch.Val, Result);
 }
 
 bool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx) const {
   EvalResult ExprResult;
-  if (!Evaluate(ExprResult, Ctx) || ExprResult.HasSideEffects ||
+  if (!EvaluateAsRValue(ExprResult, Ctx) || ExprResult.HasSideEffects ||
       !ExprResult.Val.isInt()) {
     return false;
   }
@@ -3013,11 +3014,11 @@
   return false;
 }
 
-/// isEvaluatable - Call Evaluate to see if this expression can be constant
-/// folded, but discard the result.
+/// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
+/// constant folded, but discard the result.
 bool Expr::isEvaluatable(const ASTContext &Ctx) const {
   EvalResult Result;
-  return Evaluate(Result, Ctx) && !Result.HasSideEffects;
+  return EvaluateAsRValue(Result, Ctx) && !Result.HasSideEffects;
 }
 
 bool Expr::HasSideEffects(const ASTContext &Ctx) const {
@@ -3026,7 +3027,7 @@
 
 APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx) const {
   EvalResult EvalResult;
-  bool Result = Evaluate(EvalResult, Ctx);
+  bool Result = EvaluateAsRValue(EvalResult, Ctx);
   (void)Result;
   assert(Result && "Could not evaluate expression");
   assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer");
@@ -3058,7 +3059,7 @@
 // value, it calls into Evalute.
 //
 // Meanings of Val:
-// 0: This expression is an ICE if it can be evaluated by Evaluate.
+// 0: This expression is an ICE.
 // 1: This expression is not an ICE, but if it isn't evaluated, it's
 //    a legal subexpression for an ICE. This return value is used to handle
 //    the comma operator in C99 mode.
@@ -3081,7 +3082,7 @@
 
 static ICEDiag CheckEvalInICE(const Expr* E, ASTContext &Ctx) {
   Expr::EvalResult EVResult;
-  if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects ||
+  if (!E->EvaluateAsRValue(EVResult, Ctx) || EVResult.HasSideEffects ||
       !EVResult.Val.isInt()) {
     return ICEDiag(2, E->getLocStart());
   }
@@ -3272,7 +3273,7 @@
   }
   case Expr::OffsetOfExprClass: {
       // Note that per C99, offsetof must be an ICE. And AFAIK, using
-      // Evaluate matches the proposed gcc behavior for cases like
+      // EvaluateAsRValue matches the proposed gcc behavior for cases like
       // "offsetof(struct s{int x[4];}, x[1.0])".  This doesn't affect
       // compliance: we should warn earlier for offsetof expressions with
       // array subscripts that aren't ICEs, and if the array subscripts
@@ -3328,7 +3329,7 @@
       ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx);
       if (Exp->getOpcode() == BO_Div ||
           Exp->getOpcode() == BO_Rem) {
-        // Evaluate gives an error for undefined Div/Rem, so make sure
+        // EvaluateAsRValue gives an error for undefined Div/Rem, so make sure
         // we don't evaluate one.
         if (LHSResult.Val == 0 && RHSResult.Val == 0) {
           llvm::APSInt REval = Exp->getRHS()->EvaluateKnownConstInt(Ctx);
@@ -3433,7 +3434,7 @@
         = dyn_cast<CallExpr>(Exp->getCond()->IgnoreParenCasts()))
       if (CallCE->isBuiltinCall(Ctx) == Builtin::BI__builtin_constant_p) {
         Expr::EvalResult EVResult;
-        if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects ||
+        if (!E->EvaluateAsRValue(EVResult, Ctx) || EVResult.HasSideEffects ||
             !EVResult.Val.isInt()) {
           return ICEDiag(2, E->getLocStart());
         }
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 83c7384..4095fe9 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -431,7 +431,7 @@
       return false;
     return !S->isTypeDependent() && 
            !S->isValueDependent() &&
-           S->Evaluate(outResult, *Context);
+           S->EvaluateAsRValue(outResult, *Context);
   }
 
   /// tryEvaluateBool - Try and evaluate the Stmt and return 0 or 1
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index ec0ca42..bdf49a1 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -176,7 +176,7 @@
                                         unsigned BuiltinID, const CallExpr *E) {
   // See if we can constant fold this builtin.  If so, don't emit it at all.
   Expr::EvalResult Result;
-  if (E->Evaluate(Result, CGM.getContext()) &&
+  if (E->EvaluateAsRValue(Result, CGM.getContext()) &&
       !Result.hasSideEffects()) {
     if (Result.Val.isInt())
       return RValue::get(llvm::ConstantInt::get(getLLVMContext(),
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index b7107d5..920eb55 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1112,7 +1112,8 @@
     if (const VarDecl *V = dyn_cast<VarDecl>(*I)) {
       if (const Expr *Init = V->getInit()) {
         Expr::EvalResult Result;
-        if (Init->Evaluate(Result, CGM.getContext()) && Result.Val.isInt()) {
+        if (Init->EvaluateAsRValue(Result, CGM.getContext()) &&
+            Result.Val.isInt()) {
           llvm::ConstantInt *CI 
             = llvm::ConstantInt::get(CGM.getLLVMContext(), Result.Val.getInt());
           
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 31e0f2c..0622c10 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -957,7 +957,7 @@
   if (DestType->isReferenceType())
     Success = E->EvaluateAsLValue(Result, Context);
   else
-    Success = E->Evaluate(Result, Context);
+    Success = E->EvaluateAsRValue(Result, Context);
 
   if (Success && !Result.HasSideEffects) {
     switch (Result.Val.getKind()) {
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 25b4a0a..50c5057 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -208,7 +208,7 @@
   // l-values.
   Value *VisitDeclRefExpr(DeclRefExpr *E) {
     Expr::EvalResult Result;
-    if (!E->Evaluate(Result, CGF.getContext()))
+    if (!E->EvaluateAsRValue(Result, CGF.getContext()))
       return EmitLoadOfLValue(E);
 
     assert(!Result.HasSideEffects && "Constant declref with side-effect?!");
@@ -801,7 +801,7 @@
 }
 Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
   Expr::EvalResult Result;
-  if (E->Evaluate(Result, CGF.getContext()) && Result.Val.isInt()) {
+  if (E->EvaluateAsRValue(Result, CGF.getContext()) && Result.Val.isInt()) {
     if (E->isArrow())
       CGF.EmitScalarExpr(E->getBase());
     else
@@ -1474,7 +1474,7 @@
 Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
   // Try folding the offsetof to a constant.
   Expr::EvalResult EvalResult;
-  if (E->Evaluate(EvalResult, CGF.getContext()))
+  if (E->EvaluateAsRValue(EvalResult, CGF.getContext()))
     return Builder.getInt(EvalResult.Val.getInt());
 
   // Loop over the components of the offsetof to compute the value.
@@ -1597,7 +1597,7 @@
   // If this isn't sizeof(vla), the result must be constant; use the constant
   // folding logic so we don't have to duplicate it here.
   Expr::EvalResult Result;
-  E->Evaluate(Result, CGF.getContext());
+  E->EvaluateAsRValue(Result, CGF.getContext());
   return Builder.getInt(Result.Val.getInt());
 }
 
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 3da4bd1..0346936 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -513,7 +513,7 @@
   // FIXME: Rename and handle conversion of other evaluatable things
   // to bool.
   Expr::EvalResult Result;
-  if (!Cond->Evaluate(Result, getContext()) || !Result.Val.isInt() ||
+  if (!Cond->EvaluateAsRValue(Result, getContext()) || !Result.Val.isInt() ||
       Result.HasSideEffects)
     return false;  // Not foldable, not integer or not fully evaluatable.
   
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 715abb9..8cae040 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -2994,7 +2994,7 @@
 
   // Try a full evaluation first.
   Expr::EvalResult result;
-  if (E->Evaluate(result, C))
+  if (E->EvaluateAsRValue(result, C))
     return GetValueRange(C, result.Val, E->getType(), MaxWidth);
 
   // I think we only want to look through implicit casts here; if the
@@ -3405,7 +3405,7 @@
   Expr *OriginalInit = Init->IgnoreParenImpCasts();
 
   Expr::EvalResult InitValue;
-  if (!OriginalInit->Evaluate(InitValue, S.Context) ||
+  if (!OriginalInit->EvaluateAsRValue(InitValue, S.Context) ||
       !InitValue.Val.isInt())
     return false;
 
@@ -3576,7 +3576,7 @@
         // Don't warn about float constants that are precisely
         // representable in the target type.
         Expr::EvalResult result;
-        if (E->Evaluate(result, S.Context)) {
+        if (E->EvaluateAsRValue(result, S.Context)) {
           // Value might be a float, a float vector, or a float complex.
           if (IsSameFloatAfterCast(result.Val,
                    S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)),
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index fb00c91..6bd0d25 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3445,7 +3445,7 @@
 
   Expr::EvalResult EvalResult;
   if (!VLATy->getSizeExpr() ||
-      !VLATy->getSizeExpr()->Evaluate(EvalResult, Context) ||
+      !VLATy->getSizeExpr()->EvaluateAsRValue(EvalResult, Context) ||
       !EvalResult.Val.isInt())
     return QualType();
 
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 1e890ee..21d0309 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -9121,7 +9121,7 @@
 
   Expr::EvalResult EvalResult;
 
-  if (!E->Evaluate(EvalResult, Context) || !EvalResult.Val.isInt() ||
+  if (!E->EvaluateAsRValue(EvalResult, Context) || !EvalResult.Val.isInt() ||
       EvalResult.HasSideEffects) {
     Diag(E->getExprLoc(), diag::err_expr_not_ice) << E->getSourceRange();
 
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 77cfe6c..a24e708 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2526,7 +2526,7 @@
       Expr::EvalResult InitializerValue;
       // FIXME: Check whether Initializer is a constant expression according
       // to C++0x [expr.const], rather than just whether it can be folded.
-      if (Initializer->Evaluate(InitializerValue, Ctx) &&
+      if (Initializer->EvaluateAsRValue(InitializerValue, Ctx) &&
           !InitializerValue.HasSideEffects && InitializerValue.Val.isFloat()) {
         // Constant! (Except for FIXME above.)
         llvm::APFloat FloatVal = InitializerValue.Val.getFloat();
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 6dcfbba..8c99e8a 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -666,7 +666,8 @@
     bool ShouldCheckConstantCond = false;
     if (!HasDependentValue && !TheDefaultStmt) {
       Expr::EvalResult Result;
-      HasConstantCond = CondExprBeforePromotion->Evaluate(Result, Context);
+      HasConstantCond
+        = CondExprBeforePromotion->EvaluateAsRValue(Result, Context);
       if (HasConstantCond) {
         assert(Result.Val.isInt() && "switch condition evaluated to non-int");
         ConstantCondValue = Result.Val.getInt();
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 802b36d..09d47e8 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1180,7 +1180,7 @@
   // If we're in a GNU mode (like gnu99, but not c99) accept any evaluatable
   // value as an extension.
   Expr::EvalResult Result;
-  if (S.LangOpts.GNUMode && ArraySize->Evaluate(Result, S.Context)) {
+  if (S.LangOpts.GNUMode && ArraySize->EvaluateAsRValue(Result, S.Context)) {
     if (!Result.hasSideEffects() && Result.Val.isInt()) {
       SizeVal = Result.Val.getInt();
       S.Diag(ArraySize->getLocStart(), diag::ext_vla_folded_to_constant);
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 1769ba3..bf97b8b 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -489,7 +489,7 @@
                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {
   StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
   Expr::EvalResult Res;
-  if (OOE->Evaluate(Res, getContext()) && Res.Val.isInt()) {
+  if (OOE->EvaluateAsRValue(Res, getContext()) && Res.Val.isInt()) {
     const APSInt &IV = Res.Val.getInt();
     assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
     assert(OOE->getType()->isIntegerType());
@@ -526,7 +526,7 @@
   }
   
   Expr::EvalResult Result;
-  Ex->Evaluate(Result, getContext());
+  Ex->EvaluateAsRValue(Result, getContext());
   CharUnits amt = CharUnits::fromQuantity(Result.Val.getInt().getZExtValue());
   
   const ProgramState *state = Pred->getState();