ExprConstant.cpp revision d8bfe7f25a695ca947effbccdf9ecbe3e018e221
1b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner//===--- ExprConstant.cpp - Expression Constant Evaluator -----------------===// 2c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// 3c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// The LLVM Compiler Infrastructure 4c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// 5c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// This file is distributed under the University of Illinois Open Source 6c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// License. See LICENSE.TXT for details. 7c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// 8c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson//===----------------------------------------------------------------------===// 9c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// 10c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// This file implements the Expr constant evaluator. 11c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// 12c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson//===----------------------------------------------------------------------===// 13c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 14c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson#include "clang/AST/APValue.h" 15c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson#include "clang/AST/ASTContext.h" 160fe52e1bcaa69ba127f1bda036f057fec1f478deSeo Sanghyeon#include "clang/AST/StmtVisitor.h" 1754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner#include "clang/Basic/Diagnostic.h" 1806a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson#include "clang/Basic/TargetInfo.h" 19c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlsson#include "llvm/Support/Compiler.h" 20c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlssonusing namespace clang; 21f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerusing llvm::APSInt; 22d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanusing llvm::APFloat; 23c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 2487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// EvalInfo - This is a private struct used by the evaluator to capture 2587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// information about a subexpression as it is folded. It retains information 2687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// about the AST context, but also maintains information about the folded 2787eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// expression. 2887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// 2987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// If an expression could be evaluated, it is still possible it is not a C 3087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// "integer constant expression" or constant expression. If not, this struct 3187eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// captures information about how and why not. 3287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// 3387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// One bit of information passed *into* the request for constant folding 3487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// indicates whether the subexpression is "evaluated" or not according to C 3587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// rules. For example, the RHS of (0 && foo()) is not evaluated. We can 3687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// evaluate the expression regardless of what the RHS is, but C only allows 3787eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// certain things in certain situations. 3887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstruct EvalInfo { 3987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner ASTContext &Ctx; 4087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 4187eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner /// isEvaluated - True if the subexpression is required to be evaluated, false 4287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner /// if it is short-circuited (according to C rules). 4387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner bool isEvaluated; 4487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 4554176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// ICEDiag - If the expression is unfoldable, then ICEDiag contains the 4654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// error diagnostic indicating why it is not foldable and DiagLoc indicates a 4754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// caret position for the error. If it is foldable, but the expression is 4854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// not an integer constant expression, ICEDiag contains the extension 4954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// diagnostic to emit which describes why it isn't an integer constant 5054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// expression. If this expression *is* an integer-constant-expr, then 5154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// ICEDiag is zero. 5287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner /// 5354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// The caller can choose to emit this diagnostic or not, depending on whether 5454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// they require an i-c-e or a constant or not. DiagLoc indicates the caret 5554176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// position for the report. 5654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// 5754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// If ICEDiag is zero, then this expression is an i-c-e. 5887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner unsigned ICEDiag; 5987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner SourceLocation DiagLoc; 6087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 6187eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner EvalInfo(ASTContext &ctx) : Ctx(ctx), isEvaluated(true), ICEDiag(0) {} 6287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner}; 6387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 6487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 6587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstatic bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info); 6687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstatic bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info); 67d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanstatic bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info); 68f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 69f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 70f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Pointer Evaluation 71f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 72f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 73c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlssonnamespace { 742bad1687fe6f00e10767a691a33b070b151902b6Anders Carlssonclass VISIBILITY_HIDDEN PointerExprEvaluator 752bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson : public StmtVisitor<PointerExprEvaluator, APValue> { 7687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner EvalInfo &Info; 772bad1687fe6f00e10767a691a33b070b151902b6Anders Carlssonpublic: 782bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 7987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner PointerExprEvaluator(EvalInfo &info) : Info(info) {} 80f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 812bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson APValue VisitStmt(Stmt *S) { 822bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson // FIXME: Remove this when we support more expressions. 83650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson printf("Unhandled pointer statement\n"); 842bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson S->dump(); 852bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson return APValue(); 862bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson } 872bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 882bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 892bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 90650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue VisitBinaryOperator(const BinaryOperator *E); 91650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue VisitCastExpr(const CastExpr* E); 922bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson}; 93f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} // end anonymous namespace 942bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 9587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstatic bool EvaluatePointer(const Expr* E, APValue& Result, EvalInfo &Info) { 96f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (!E->getType()->isPointerType()) 97f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return false; 9887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner Result = PointerExprEvaluator(Info).Visit(const_cast<Expr*>(E)); 99f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return Result.isLValue(); 100f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} 101650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 102f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris LattnerAPValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 103650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (E->getOpcode() != BinaryOperator::Add && 104650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson E->getOpcode() != BinaryOperator::Sub) 105650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 106650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 107650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr *PExp = E->getLHS(); 108650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr *IExp = E->getRHS(); 109650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (IExp->getType()->isPointerType()) 110f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner std::swap(PExp, IExp); 111650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 112650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue ResultLValue; 11387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (!EvaluatePointer(PExp, ResultLValue, Info)) 114650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 115f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 116650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson llvm::APSInt AdditionalOffset(32); 11787eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (!EvaluateInteger(IExp, AdditionalOffset, Info)) 118650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 119650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 120650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson uint64_t Offset = ResultLValue.getLValueOffset(); 121650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (E->getOpcode() == BinaryOperator::Add) 122650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Offset += AdditionalOffset.getZExtValue(); 123650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson else 124650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Offset -= AdditionalOffset.getZExtValue(); 125650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 126650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(ResultLValue.getLValueBase(), Offset); 127650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson} 128650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 129650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 130b542afe02d317411d53b3541946f9f2a8f509a11Chris LattnerAPValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) { 131650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr* SubExpr = E->getSubExpr(); 132650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 133650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson // Check for pointer->pointer cast 134650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (SubExpr->getType()->isPointerType()) { 135650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue Result; 13687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (EvaluatePointer(SubExpr, Result, Info)) 137650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return Result; 138f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return APValue(); 139650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 140650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 141d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman if (SubExpr->getType()->isIntegralType()) { 142650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson llvm::APSInt Result(32); 14387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (EvaluateInteger(SubExpr, Result, Info)) { 14487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner Result.extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType())); 145650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(0, Result.getZExtValue()); 146650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 147650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 148650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 149650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson assert(0 && "Unhandled cast"); 150650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 151650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson} 152650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 153f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 154f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 155f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Integer Evaluation 156f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 157f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 158f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnernamespace { 159f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerclass VISIBILITY_HIDDEN IntExprEvaluator 160b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner : public StmtVisitor<IntExprEvaluator, bool> { 16187eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner EvalInfo &Info; 162b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner APSInt &Result; 163f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerpublic: 16487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner IntExprEvaluator(EvalInfo &info, APSInt &result) 16587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner : Info(info), Result(result) {} 166f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 1677a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner unsigned getIntTypeSizeInBits(QualType T) const { 16854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return (unsigned)Info.Ctx.getIntWidth(T); 16954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner } 17054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 17154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner bool Extension(SourceLocation L, diag::kind D) { 17254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Info.DiagLoc = L; 17354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Info.ICEDiag = D; 17454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return true; // still a constant. 17554176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner } 17654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 17754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner bool Error(SourceLocation L, diag::kind D) { 17854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner // If this is in an unevaluated portion of the subexpression, ignore the 17954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner // error. 18054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (!Info.isEvaluated) 18154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return true; 18254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 18354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Info.DiagLoc = L; 18454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Info.ICEDiag = D; 18554176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return false; 1867a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner } 1877a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner 188f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner //===--------------------------------------------------------------------===// 189f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner // Visitor Methods 190f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner //===--------------------------------------------------------------------===// 1917a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner 192b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitStmt(Stmt *S) { 19354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return Error(S->getLocStart(), diag::err_expr_not_constant); 194f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner } 195f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 196b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 197f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 1984c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitIntegerLiteral(const IntegerLiteral *E) { 1994c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result = E->getValue(); 2004c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 2014c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return true; 2024c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 2034c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitCharacterLiteral(const CharacterLiteral *E) { 2044c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 2054c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result = E->getValue(); 2064c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 2074c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return true; 2084c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 2094c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) { 2104c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 2114c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result = Info.Ctx.typesAreCompatible(E->getArgType1(), E->getArgType2()); 2124c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return true; 2134c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 2144c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitDeclRefExpr(const DeclRefExpr *E); 2154c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitCallExpr(const CallExpr *E); 216b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitBinaryOperator(const BinaryOperator *E); 217b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitUnaryOperator(const UnaryOperator *E); 218f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 219732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner bool VisitCastExpr(CastExpr* E) { 220732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner return HandleCast(E->getLocStart(), E->getSubExpr(), E->getType()); 221f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner } 222fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner bool VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) { 22354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return EvaluateSizeAlignOf(E->isSizeOf(), E->getArgumentType(), 22454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner E->getType()); 225fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner } 2264c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner 227fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattnerprivate: 228732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner bool HandleCast(SourceLocation CastLoc, Expr *SubExpr, QualType DestType); 229fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner bool EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy, QualType DstTy); 230f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner}; 231f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} // end anonymous namespace 232f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 23387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstatic bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) { 23487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E)); 235f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} 236f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 2374c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattnerbool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) { 2384c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // Enums are integer constant exprs. 2394c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner if (const EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(E->getDecl())) { 2404c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result = D->getInitVal(); 2414c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return true; 2424c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 2434c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner 2444c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // Otherwise, random variable references are not constants. 2454c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return Error(E->getLocStart(), diag::err_expr_not_constant); 2464c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner} 2474c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner 2484c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner 2494c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattnerbool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { 2504c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 2514c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // __builtin_type_compatible_p is a constant. 2524c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner if (E->isBuiltinClassifyType(Result)) 2534c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return true; 2544c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner 2554c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return Error(E->getLocStart(), diag::err_expr_not_constant); 2564c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner} 257f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 258b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattnerbool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 259a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // The LHS of a constant expr is always evaluated and needed. 260a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson llvm::APSInt RHS(32); 26154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (!Visit(E->getLHS())) 26254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return false; // error in subexpression. 26354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 26454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner bool OldEval = Info.isEvaluated; 26554176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 26654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner // The short-circuiting &&/|| operators don't necessarily evaluate their 26754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner // RHS. Make sure to pass isEvaluated down correctly. 26854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if ((E->getOpcode() == BinaryOperator::LAnd && Result == 0) || 26954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner (E->getOpcode() == BinaryOperator::LOr && Result != 0)) 27054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Info.isEvaluated = false; 271d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman 272d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman // FIXME: Handle pointer subtraction 273d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman 274d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman // FIXME Maybe we want to succeed even where we can't evaluate the 275d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman // right side of LAnd/LOr? 276d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman // For example, see http://llvm.org/bugs/show_bug.cgi?id=2525 27754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (!EvaluateInteger(E->getRHS(), RHS, Info)) 278b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 27954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Info.isEvaluated = OldEval; 280a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 281a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson switch (E->getOpcode()) { 28254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner default: return Error(E->getOperatorLoc(), diag::err_expr_not_constant); 28354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::Mul: Result *= RHS; return true; 28454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::Add: Result += RHS; return true; 28554176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::Sub: Result -= RHS; return true; 28654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::And: Result &= RHS; return true; 28754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::Xor: Result ^= RHS; return true; 28854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::Or: Result |= RHS; return true; 289a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Div: 29054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (RHS == 0) 29154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero); 292b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner Result /= RHS; 29354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return true; 294a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Rem: 29554176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (RHS == 0) 29654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero); 297a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result %= RHS; 29854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return true; 299a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Shl: 30054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner // FIXME: Warn about out of range shift amounts! 301b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner Result <<= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1); 302a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson break; 303a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Shr: 304b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1); 305a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson break; 306b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner 307ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::LT: 308ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result < RHS; 309ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 310ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 311ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::GT: 312ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result > RHS; 313ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 314ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 315ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::LE: 316ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result <= RHS; 317ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 318ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 319ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::GE: 320ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result >= RHS; 321ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 322ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 323ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::EQ: 324ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result == RHS; 325ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 326ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 327ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::NE: 328ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result != RHS; 329ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 330ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 33154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::LAnd: 33254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Result = Result != 0 && RHS != 0; 33354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 33454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner break; 33554176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::LOr: 33654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Result = Result != 0 || RHS != 0; 33754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 33854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner break; 33954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 34006a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson 341a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Comma: 34254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner // Result of the comma is just the result of the RHS. 34354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Result = RHS; 34454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 345a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // C99 6.6p3: "shall not contain assignment, ..., or comma operators, 346a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // *except* when they are contained within a subexpression that is not 347a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // evaluated". Note that Assignment can never happen due to constraints 348a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // on the LHS subexpr, so we don't need to check it here. 34954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (!Info.isEvaluated) 35054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return true; 35154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 35254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner // If the value is evaluated, we can accept it as an extension. 35354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return Extension(E->getOperatorLoc(), diag::ext_comma_in_constant_expr); 354a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson } 355a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 356a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 357b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return true; 358a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 359a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 360fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner/// EvaluateSizeAlignOf - Evaluate sizeof(SrcTy) or alignof(SrcTy) with a result 361fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner/// as a DstTy type. 362fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattnerbool IntExprEvaluator::EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy, 363fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner QualType DstTy) { 364fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // Return the result in the right width. 365fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(DstTy)); 366fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner Result.setIsUnsigned(DstTy->isUnsignedIntegerType()); 367fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 368fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // sizeof(void) and __alignof__(void) = 1 as a gcc extension. 369fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner if (SrcTy->isVoidType()) 370fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner Result = 1; 371fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 372fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2. 373fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner if (!SrcTy->isConstantSizeType()) { 374fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // FIXME: Should we attempt to evaluate this? 375fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner return false; 376fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner } 377fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 378fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // GCC extension: sizeof(function) = 1. 379fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner if (SrcTy->isFunctionType()) { 380fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // FIXME: AlignOf shouldn't be unconditionally 4! 381fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner Result = isSizeOf ? 1 : 4; 382fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner return true; 383fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner } 384fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 385fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // Get information about the size or align. 38687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner unsigned CharSize = Info.Ctx.Target.getCharWidth(); 387fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner if (isSizeOf) 388fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner Result = getIntTypeSizeInBits(SrcTy) / CharSize; 389fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner else 39087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner Result = Info.Ctx.getTypeAlign(SrcTy) / CharSize; 391fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner return true; 392fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner} 393fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 394b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattnerbool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { 3954c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // Special case unary operators that do not need their subexpression 3964c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // evaluated. offsetof/sizeof/alignof are all special. 39775a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner if (E->isOffsetOfOp()) { 3984c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 39987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner Result = E->evaluateOffsetOf(Info.Ctx); 40075a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 40175a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner return true; 40275a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner } 40375a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner 40475a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner if (E->isSizeOfAlignOfOp()) 405fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner return EvaluateSizeAlignOf(E->getOpcode() == UnaryOperator::SizeOf, 406fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner E->getSubExpr()->getType(), E->getType()); 40775a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner 40887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner // Get the operand value into 'Result'. 40987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (!Visit(E->getSubExpr())) 41075a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner return false; 411a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 41275a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner switch (E->getOpcode()) { 4134c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner default: 41475a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner // Address, indirect, pre/post inc/dec, etc are not valid constant exprs. 41575a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner // See C99 6.6p3. 4164c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return Error(E->getOperatorLoc(), diag::err_expr_not_constant); 41775a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner case UnaryOperator::LNot: { 41875a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner bool Val = Result == 0; 41975a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 42075a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner Result = Val; 42175a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner break; 42275a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner } 42375a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner case UnaryOperator::Extension: 4244c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // FIXME: Should extension allow i-c-e extension expressions in its scope? 4254c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // If so, we could clear the diagnostic ID. 42675a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner case UnaryOperator::Plus: 4274c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // The result is always just the subexpr. 42875a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner break; 42975a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner case UnaryOperator::Minus: 43075a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner Result = -Result; 43175a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner break; 43275a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner case UnaryOperator::Not: 43375a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner Result = ~Result; 43475a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner break; 43506a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson } 43606a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson 437a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 438b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return true; 439a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 440a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 441732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner/// HandleCast - This is used to evaluate implicit or explicit casts where the 442732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner/// result type is integer. 443732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattnerbool IntExprEvaluator::HandleCast(SourceLocation CastLoc, 444732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Expr *SubExpr, QualType DestType) { 4457a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner unsigned DestWidth = getIntTypeSizeInBits(DestType); 44606a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson 447a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Handle simple integer->integer casts. 448a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (SubExpr->getType()->isIntegerType()) { 449732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner if (!Visit(SubExpr)) 450b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 4512bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 452a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Figure out if this is a truncate, extend or noop cast. 453a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // If the input is signed, do a sign extend, noop, or truncate. 454a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (DestType->isBooleanType()) { 455a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Conversion to bool compares against zero. 456a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result = Result != 0; 457a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.zextOrTrunc(DestWidth); 4587a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner } else 459a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.extOrTrunc(DestWidth); 460732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Result.setIsUnsigned(DestType->isUnsignedIntegerType()); 461732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner return true; 462732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner } 463732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner 464732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner // FIXME: Clean this up! 465732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner if (SubExpr->getType()->isPointerType()) { 466a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson APValue LV; 46787eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (!EvaluatePointer(SubExpr, LV, Info)) 468b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 469a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (LV.getLValueBase()) 470b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 4712bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 472559e56b3a201316ae0b7e7389879a8054f6a3a82Anders Carlsson Result.extOrTrunc(DestWidth); 473559e56b3a201316ae0b7e7389879a8054f6a3a82Anders Carlsson Result = LV.getLValueOffset(); 474732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Result.setIsUnsigned(DestType->isUnsignedIntegerType()); 475732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner return true; 4762bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson } 4772bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 478732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner if (!SubExpr->getType()->isRealFloatingType()) 479732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner return Error(CastLoc, diag::err_expr_not_constant); 480732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner 481d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman APFloat F(0.0); 482d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (!EvaluateFloat(SubExpr, F, Info)) 483732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner return Error(CastLoc, diag::err_expr_not_constant); 484d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 485732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner // If the destination is boolean, compare against zero. 486732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner if (DestType->isBooleanType()) { 487d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result = !F.isZero(); 488732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Result.zextOrTrunc(DestWidth); 489732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Result.setIsUnsigned(DestType->isUnsignedIntegerType()); 490732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner return true; 491732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner } 492732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner 493732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner // Determine whether we are converting to unsigned or signed. 494732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner bool DestSigned = DestType->isSignedIntegerType(); 495732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner 496732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner // FIXME: Warning for overflow. 497732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner uint64_t Space[4]; 498d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman (void)F.convertToInteger(Space, DestWidth, DestSigned, 499d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman llvm::APFloat::rmTowardZero); 500732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Result = llvm::APInt(DestWidth, 4, Space); 501732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Result.setIsUnsigned(!DestSigned); 502b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return true; 503a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 5042bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 505f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 506d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman// Float Evaluation 507d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman//===----------------------------------------------------------------------===// 508d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 509d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmannamespace { 510d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanclass VISIBILITY_HIDDEN FloatExprEvaluator 511d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman : public StmtVisitor<FloatExprEvaluator, bool> { 512d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman EvalInfo &Info; 513d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman APFloat &Result; 514d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanpublic: 515d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman FloatExprEvaluator(EvalInfo &info, APFloat &result) 516d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman : Info(info), Result(result) {} 517d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 518d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitStmt(Stmt *S) { 519d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 520d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 521d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 522d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 523d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 524d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitBinaryOperator(const BinaryOperator *E); 525d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitFloatingLiteral(const FloatingLiteral *E); 526d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman}; 527d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} // end anonymous namespace 528d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 529d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanstatic bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) { 530d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E)); 531d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 532d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 533d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanbool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 534d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman // FIXME: Diagnostics? I really don't understand how the warnings 535d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman // and errors are supposed to work. 536d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman APFloat LHS(0.0), RHS(0.0); 537d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (!EvaluateFloat(E->getLHS(), Result, Info)) 538d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 539d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (!EvaluateFloat(E->getRHS(), RHS, Info)) 540d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 541d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 542d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman switch (E->getOpcode()) { 543d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman default: return false; 544d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman case BinaryOperator::Mul: 545d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.multiply(RHS, APFloat::rmNearestTiesToEven); 546d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 547d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman case BinaryOperator::Add: 548d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.add(RHS, APFloat::rmNearestTiesToEven); 549d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 550d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman case BinaryOperator::Sub: 551d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.subtract(RHS, APFloat::rmNearestTiesToEven); 552d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 553d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman case BinaryOperator::Div: 554d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.divide(RHS, APFloat::rmNearestTiesToEven); 555d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 556d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman case BinaryOperator::Rem: 557d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.mod(RHS, APFloat::rmNearestTiesToEven); 558d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 559d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 560d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 561d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 562d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanbool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) { 563d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result = E->getValue(); 564d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 565d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 566d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 567d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman//===----------------------------------------------------------------------===// 568f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Top level TryEvaluate. 569f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 570f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 571b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattnerbool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const { 57287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner EvalInfo Info(Ctx); 57306a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson if (getType()->isIntegerType()) { 574d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman llvm::APSInt sInt(32); 57587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (EvaluateInteger(this, sInt, Info)) { 57606a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson Result = APValue(sInt); 57706a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson return true; 57806a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson } 579d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } else if (getType()->isPointerType()) { 580d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (EvaluatePointer(this, Result, Info)) { 581d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 582d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 583d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } else if (getType()->isRealFloatingType()) { 584d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman llvm::APFloat f(0.0); 585d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (EvaluateFloat(this, f, Info)) { 586d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result = APValue(f); 587d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 588d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 589d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 590165a70fd0b75a4f23456531824e1b76a9f1c4f9cAnders Carlsson 591c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson return false; 592c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson} 593