From: Richard Smith Date: Sat, 29 Oct 2011 00:50:52 +0000 (+0000) Subject: Rename Expr::Evaluate to Expr::EvaluateAsRValue to make it clear that it will X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=51f4708c00110940ca3f337961915f2ca1668375;p=clang 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 b484a42b04..ca884b955a 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -462,12 +462,13 @@ public: 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 @@ public: 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 6e2e15c6cb..bba7d5e579 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2912,7 +2912,7 @@ bool ComplexExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { } //===----------------------------------------------------------------------===// -// Top level Expr::Evaluate method. +// Top level Expr::EvaluateAsRValue method. //===----------------------------------------------------------------------===// static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) { @@ -2951,12 +2951,12 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) { } -/// 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 @@ bool Expr::Evaluate(EvalResult &Result, const ASTContext &Ctx) const { 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 @@ bool Expr::EvaluateAsAnyLValue(EvalResult &Result, 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 @@ bool Expr::HasSideEffects(const ASTContext &Ctx) const { 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 @@ APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx) const { // 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 NoDiag() { return ICEDiag(); } 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 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { } 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 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { 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 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { = dyn_cast(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 83c7384db0..4095fe925e 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -431,7 +431,7 @@ private: 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 ec0ca42422..bdf49a1e79 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -176,7 +176,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 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 b7107d5883..920eb5578e 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1112,7 +1112,8 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) { if (const VarDecl *V = dyn_cast(*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 31e0f2c3b0..0622c10165 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -957,7 +957,7 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E, 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 25b4a0a0e7..50c5057f3e 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -208,7 +208,7 @@ public: // 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::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { } 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::VisitUnaryLNot(const UnaryOperator *E) { 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 @@ ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr( // 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 3da4bd1f98..0346936146 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -513,7 +513,7 @@ ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APInt &ResultInt) { // 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 715abb9c0a..8cae0408f0 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -2994,7 +2994,7 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { // 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 @@ bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, 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 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T, // 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 fb00c918ab..6bd0d25f75 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3445,7 +3445,7 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, 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 1e890eef1e..21d0309377 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9121,7 +9121,7 @@ bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result){ 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 77cfe6c2de..a24e708b1e 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2526,7 +2526,7 @@ bool InitializationSequence::endsWithNarrowing(ASTContext &Ctx, 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 6dcfbbab84..8c99e8a4de 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -666,7 +666,8 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, 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 802b36db07..09d47e8e17 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1180,7 +1180,7 @@ static bool isArraySizeVLA(Expr *ArraySize, llvm::APSInt &SizeVal, Sema &S) { // 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 1769ba35b3..bf97b8bbad 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -489,7 +489,7 @@ VisitOffsetOfExpr(const OffsetOfExpr *OOE, 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 @@ VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, } Expr::EvalResult Result; - Ex->Evaluate(Result, getContext()); + Ex->EvaluateAsRValue(Result, getContext()); CharUnits amt = CharUnits::fromQuantity(Result.Val.getInt().getZExtValue()); const ProgramState *state = Pred->getState();