ExprConstant.cpp revision a6afa768aa7bd3102a2807aa720917e4a1771e4e
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" 164efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman#include "clang/AST/RecordLayout.h" 170fe52e1bcaa69ba127f1bda036f057fec1f478deSeo Sanghyeon#include "clang/AST/StmtVisitor.h" 1854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner#include "clang/Basic/Diagnostic.h" 1906a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson#include "clang/Basic/TargetInfo.h" 20c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlsson#include "llvm/Support/Compiler.h" 21c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlssonusing namespace clang; 22f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerusing llvm::APSInt; 23d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanusing llvm::APFloat; 24c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 2587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// EvalInfo - This is a private struct used by the evaluator to capture 2687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// information about a subexpression as it is folded. It retains information 2787eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// about the AST context, but also maintains information about the folded 2887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// expression. 2987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// 3087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// If an expression could be evaluated, it is still possible it is not a C 3187eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// "integer constant expression" or constant expression. If not, this struct 3287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// captures information about how and why not. 3387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// 3487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// One bit of information passed *into* the request for constant folding 3587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// indicates whether the subexpression is "evaluated" or not according to C 3687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// rules. For example, the RHS of (0 && foo()) is not evaluated. We can 3787eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// evaluate the expression regardless of what the RHS is, but C only allows 3887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// certain things in certain situations. 3987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstruct EvalInfo { 4087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner ASTContext &Ctx; 4187eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 4287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner /// isEvaluated - True if the subexpression is required to be evaluated, false 4387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner /// if it is short-circuited (according to C rules). 4487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner bool isEvaluated; 4587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 4654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// ICEDiag - If the expression is unfoldable, then ICEDiag contains the 4754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// error diagnostic indicating why it is not foldable and DiagLoc indicates a 4854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// caret position for the error. If it is foldable, but the expression is 4954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// not an integer constant expression, ICEDiag contains the extension 5054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// diagnostic to emit which describes why it isn't an integer constant 5154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// expression. If this expression *is* an integer-constant-expr, then 5254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// ICEDiag is zero. 5387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner /// 5454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// The caller can choose to emit this diagnostic or not, depending on whether 5554176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// they require an i-c-e or a constant or not. DiagLoc indicates the caret 5654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// position for the report. 5754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// 5854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner /// If ICEDiag is zero, then this expression is an i-c-e. 5987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner unsigned ICEDiag; 6087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner SourceLocation DiagLoc; 6187eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 6287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner EvalInfo(ASTContext &ctx) : Ctx(ctx), isEvaluated(true), ICEDiag(0) {} 6387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner}; 6487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 6587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 664efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmanstatic bool EvaluateLValue(const Expr *E, APValue &Result, EvalInfo &Info); 6787eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstatic bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info); 6887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstatic bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info); 69d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanstatic bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info); 70f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 71f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 724efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman// Misc utilities 734efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 744efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 754efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmanstatic bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) { 764efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (E->getType()->isIntegralType()) { 774efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APSInt IntResult; 784efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!EvaluateInteger(E, IntResult, Info)) 794efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 804efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result = IntResult != 0; 814efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 824efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } else if (E->getType()->isRealFloatingType()) { 834efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APFloat FloatResult(0.0); 844efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!EvaluateFloat(E, FloatResult, Info)) 854efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 864efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result = !FloatResult.isZero(); 874efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 884efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } else if (E->getType()->isPointerType()) { 894efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue PointerResult; 904efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!EvaluatePointer(E, PointerResult, Info)) 914efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 924efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman // FIXME: Is this accurate for all kinds of bases? If not, what would 934efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman // the check look like? 944efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result = PointerResult.getLValueBase() || PointerResult.getLValueOffset(); 954efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 964efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 974efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 984efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 994efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 1004efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1014efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 1024efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman// LValue Evaluation 1034efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 1044efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmannamespace { 1054efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmanclass VISIBILITY_HIDDEN LValueExprEvaluator 1064efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman : public StmtVisitor<LValueExprEvaluator, APValue> { 1074efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman EvalInfo &Info; 1084efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmanpublic: 1094efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1104efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman LValueExprEvaluator(EvalInfo &info) : Info(info) {} 1114efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1124efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue VisitStmt(Stmt *S) { 1138a7b7c6d4c96ace3667204bed4a48bad91b7c0f0Daniel Dunbar#if 0 1144efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman // FIXME: Remove this when we support more expressions. 1154efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman printf("Unhandled pointer statement\n"); 1164efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman S->dump(); 1178a7b7c6d4c96ace3667204bed4a48bad91b7c0f0Daniel Dunbar#endif 1184efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return APValue(); 1194efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 1204efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1214efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 1224efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue VisitDeclRefExpr(DeclRefExpr *E) { return APValue(E, 0); } 1234efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E, 0); } 1244efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E); 1254efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue VisitMemberExpr(MemberExpr *E); 1264efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue VisitStringLiteral(StringLiteral *E) { return APValue(E, 0); } 1274efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman}; 1284efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} // end anonymous namespace 1294efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1304efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmanstatic bool EvaluateLValue(const Expr* E, APValue& Result, EvalInfo &Info) { 1314efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result = LValueExprEvaluator(Info).Visit(const_cast<Expr*>(E)); 1324efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return Result.isLValue(); 1334efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 1344efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1354efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli FriedmanAPValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 1364efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (E->isFileScope()) 1374efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return APValue(E, 0); 1384efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return APValue(); 1394efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 1404efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1414efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli FriedmanAPValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) { 1424efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue result; 1434efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman QualType Ty; 1444efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (E->isArrow()) { 1454efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!EvaluatePointer(E->getBase(), result, Info)) 1464efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return APValue(); 1474efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Ty = E->getBase()->getType()->getAsPointerType()->getPointeeType(); 1484efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } else { 1494efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman result = Visit(E->getBase()); 1504efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (result.isUninit()) 1514efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return APValue(); 1524efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Ty = E->getBase()->getType(); 1534efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 1544efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1554efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman RecordDecl *RD = Ty->getAsRecordType()->getDecl(); 1564efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD); 1574efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman FieldDecl *FD = E->getMemberDecl(); 1584efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1594efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman // FIXME: This is linear time. 1604efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman unsigned i = 0, e = 0; 1614efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman for (i = 0, e = RD->getNumMembers(); i != e; i++) { 1624efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (RD->getMember(i) == FD) 1634efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman break; 1644efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 1654efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1664efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman result.setLValue(result.getLValueBase(), 1674efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman result.getLValueOffset() + RL.getFieldOffset(i) / 8); 1684efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1694efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return result; 1704efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 1714efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1724efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1734efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 174f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Pointer Evaluation 175f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 176f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 177c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlssonnamespace { 1782bad1687fe6f00e10767a691a33b070b151902b6Anders Carlssonclass VISIBILITY_HIDDEN PointerExprEvaluator 1792bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson : public StmtVisitor<PointerExprEvaluator, APValue> { 18087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner EvalInfo &Info; 1812bad1687fe6f00e10767a691a33b070b151902b6Anders Carlssonpublic: 1822bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 18387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner PointerExprEvaluator(EvalInfo &info) : Info(info) {} 184f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 1852bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson APValue VisitStmt(Stmt *S) { 1862bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson return APValue(); 1872bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson } 1882bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 1892bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 1902bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 191650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue VisitBinaryOperator(const BinaryOperator *E); 192650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue VisitCastExpr(const CastExpr* E); 1934efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue VisitUnaryOperator(const UnaryOperator *E); 1944efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue VisitObjCStringLiteral(ObjCStringLiteral *E) 1954efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman { return APValue(E, 0); } 1964efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue VisitConditionalOperator(ConditionalOperator *E); 1972bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson}; 198f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} // end anonymous namespace 1992bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 20087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstatic bool EvaluatePointer(const Expr* E, APValue& Result, EvalInfo &Info) { 201f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (!E->getType()->isPointerType()) 202f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return false; 20387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner Result = PointerExprEvaluator(Info).Visit(const_cast<Expr*>(E)); 204f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return Result.isLValue(); 205f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} 206650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 207f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris LattnerAPValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 208650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (E->getOpcode() != BinaryOperator::Add && 209650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson E->getOpcode() != BinaryOperator::Sub) 210650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 211650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 212650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr *PExp = E->getLHS(); 213650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr *IExp = E->getRHS(); 214650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (IExp->getType()->isPointerType()) 215f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner std::swap(PExp, IExp); 216650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 217650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue ResultLValue; 21887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (!EvaluatePointer(PExp, ResultLValue, Info)) 219650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 220f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 221650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson llvm::APSInt AdditionalOffset(32); 22287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (!EvaluateInteger(IExp, AdditionalOffset, Info)) 223650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 224650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 2254efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman QualType PointeeType = PExp->getType()->getAsPointerType()->getPointeeType(); 2264efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman uint64_t SizeOfPointee = Info.Ctx.getTypeSize(PointeeType) / 8; 2274efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 228650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson uint64_t Offset = ResultLValue.getLValueOffset(); 2294efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 230650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (E->getOpcode() == BinaryOperator::Add) 2314efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Offset += AdditionalOffset.getLimitedValue() * SizeOfPointee; 232650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson else 2334efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Offset -= AdditionalOffset.getLimitedValue() * SizeOfPointee; 2344efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 235650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(ResultLValue.getLValueBase(), Offset); 236650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson} 2374efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2384efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli FriedmanAPValue PointerExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { 2394efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (E->getOpcode() == UnaryOperator::Extension) { 2404efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman // FIXME: Deal with warnings? 2414efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return Visit(E->getSubExpr()); 2424efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 2434efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2444efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (E->getOpcode() == UnaryOperator::AddrOf) { 2454efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue result; 2464efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (EvaluateLValue(E->getSubExpr(), result, Info)) 2474efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return result; 2484efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 2494efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2504efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return APValue(); 2514efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 252650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 253650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 254b542afe02d317411d53b3541946f9f2a8f509a11Chris LattnerAPValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) { 255650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr* SubExpr = E->getSubExpr(); 256650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 257650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson // Check for pointer->pointer cast 258650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (SubExpr->getType()->isPointerType()) { 259650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue Result; 26087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (EvaluatePointer(SubExpr, Result, Info)) 261650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return Result; 262f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return APValue(); 263650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 264650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 265d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman if (SubExpr->getType()->isIntegralType()) { 266650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson llvm::APSInt Result(32); 26787eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (EvaluateInteger(SubExpr, Result, Info)) { 26887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner Result.extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType())); 269650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(0, Result.getZExtValue()); 270650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 271650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 2724efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2734efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (SubExpr->getType()->isFunctionType() || 2744efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman SubExpr->getType()->isArrayType()) { 2754efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue Result; 2764efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (EvaluateLValue(SubExpr, Result, Info)) 2774efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return Result; 2784efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return APValue(); 2794efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 2804efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2814efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman //assert(0 && "Unhandled cast"); 282650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 283650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson} 284650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 2854efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli FriedmanAPValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) { 2864efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman bool BoolResult; 2874efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!HandleConversionToBool(E->getCond(), BoolResult, Info)) 2884efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return APValue(); 2894efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2904efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr(); 2914efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2924efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APValue Result; 2934efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (EvaluatePointer(EvalExpr, Result, Info)) 2944efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return Result; 2954efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return APValue(); 2964efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 297f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 298f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 299f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Integer Evaluation 300f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 301f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 302f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnernamespace { 303f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerclass VISIBILITY_HIDDEN IntExprEvaluator 304b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner : public StmtVisitor<IntExprEvaluator, bool> { 30587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner EvalInfo &Info; 306b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner APSInt &Result; 307f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerpublic: 30887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner IntExprEvaluator(EvalInfo &info, APSInt &result) 30987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner : Info(info), Result(result) {} 310f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 3117a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner unsigned getIntTypeSizeInBits(QualType T) const { 31254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return (unsigned)Info.Ctx.getIntWidth(T); 31354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner } 31454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 31554176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner bool Extension(SourceLocation L, diag::kind D) { 31654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Info.DiagLoc = L; 31754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Info.ICEDiag = D; 31854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return true; // still a constant. 31954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner } 32054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 32132fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner bool Error(SourceLocation L, diag::kind D, QualType ExprTy) { 32254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner // If this is in an unevaluated portion of the subexpression, ignore the 32354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner // error. 32432fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner if (!Info.isEvaluated) { 32532fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner // If error is ignored because the value isn't evaluated, get the real 32632fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner // type at least to prevent errors downstream. 32732fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(ExprTy)); 32832fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner Result.setIsUnsigned(ExprTy->isUnsignedIntegerType()); 32954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return true; 33032fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner } 33154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 33232fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner // Take the first error. 33332fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner if (Info.ICEDiag == 0) { 33432fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner Info.DiagLoc = L; 33532fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner Info.ICEDiag = D; 33632fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner } 33754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return false; 3387a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner } 3397a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner 340f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner //===--------------------------------------------------------------------===// 341f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner // Visitor Methods 342f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner //===--------------------------------------------------------------------===// 34332fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner 34432fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner bool VisitStmt(Stmt *) { 34532fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner assert(0 && "This should be called on integers, stmts are not integers"); 34632fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner return false; 34732fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner } 3487a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner 34932fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner bool VisitExpr(Expr *E) { 35032fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner return Error(E->getLocStart(), diag::err_expr_not_constant, E->getType()); 351f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner } 352f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 353b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 354f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 3554c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitIntegerLiteral(const IntegerLiteral *E) { 3564c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result = E->getValue(); 3574c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 3584c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return true; 3594c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 3604c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitCharacterLiteral(const CharacterLiteral *E) { 3614c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 3624c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result = E->getValue(); 3634c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 3644c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return true; 3654c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 3664c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) { 3674c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 368ac620decb68aad1a2cf6c0c191b56d78981d9aaaDaniel Dunbar // Per gcc docs "this built-in function ignores top level 369ac620decb68aad1a2cf6c0c191b56d78981d9aaaDaniel Dunbar // qualifiers". We need to use the canonical version to properly 370ac620decb68aad1a2cf6c0c191b56d78981d9aaaDaniel Dunbar // be able to strip CRV qualifiers from the type. 371ac620decb68aad1a2cf6c0c191b56d78981d9aaaDaniel Dunbar QualType T0 = Info.Ctx.getCanonicalType(E->getArgType1()); 372ac620decb68aad1a2cf6c0c191b56d78981d9aaaDaniel Dunbar QualType T1 = Info.Ctx.getCanonicalType(E->getArgType2()); 373ac620decb68aad1a2cf6c0c191b56d78981d9aaaDaniel Dunbar Result = Info.Ctx.typesAreCompatible(T0.getUnqualifiedType(), 374ac620decb68aad1a2cf6c0c191b56d78981d9aaaDaniel Dunbar T1.getUnqualifiedType()); 3754c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return true; 3764c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 3774c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitDeclRefExpr(const DeclRefExpr *E); 3784c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitCallExpr(const CallExpr *E); 379b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitBinaryOperator(const BinaryOperator *E); 380b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitUnaryOperator(const UnaryOperator *E); 381f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 382732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner bool VisitCastExpr(CastExpr* E) { 383732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner return HandleCast(E->getLocStart(), E->getSubExpr(), E->getType()); 384f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner } 3850518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E); 3860518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl 387fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattnerprivate: 388732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner bool HandleCast(SourceLocation CastLoc, Expr *SubExpr, QualType DestType); 389f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner}; 390f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} // end anonymous namespace 391f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 39287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstatic bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) { 39387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E)); 394f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} 395f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 3964c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattnerbool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) { 3974c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // Enums are integer constant exprs. 3984c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner if (const EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(E->getDecl())) { 3994c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result = D->getInitVal(); 4004c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner return true; 4014c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 4024c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner 4034c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // Otherwise, random variable references are not constants. 40432fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner return Error(E->getLocStart(), diag::err_expr_not_constant, E->getType()); 4054c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner} 4064c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner 407a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner/// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way 408a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner/// as GCC. 409a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattnerstatic int EvaluateBuiltinClassifyType(const CallExpr *E) { 410a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner // The following enum mimics the values returned by GCC. 411a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner enum gcc_type_class { 412a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner no_type_class = -1, 413a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner void_type_class, integer_type_class, char_type_class, 414a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner enumeral_type_class, boolean_type_class, 415a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner pointer_type_class, reference_type_class, offset_type_class, 416a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner real_type_class, complex_type_class, 417a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner function_type_class, method_type_class, 418a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner record_type_class, union_type_class, 419a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner array_type_class, string_type_class, 420a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner lang_type_class 421a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner }; 422a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner 423a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner // If no argument was supplied, default to "no_type_class". This isn't 424a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner // ideal, however it is what gcc does. 425a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner if (E->getNumArgs() == 0) 426a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return no_type_class; 427a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner 428a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner QualType ArgTy = E->getArg(0)->getType(); 429a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner if (ArgTy->isVoidType()) 430a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return void_type_class; 431a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isEnumeralType()) 432a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return enumeral_type_class; 433a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isBooleanType()) 434a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return boolean_type_class; 435a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isCharType()) 436a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return string_type_class; // gcc doesn't appear to use char_type_class 437a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isIntegerType()) 438a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return integer_type_class; 439a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isPointerType()) 440a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return pointer_type_class; 441a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isReferenceType()) 442a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return reference_type_class; 443a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isRealType()) 444a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return real_type_class; 445a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isComplexType()) 446a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return complex_type_class; 447a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isFunctionType()) 448a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return function_type_class; 449a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isStructureType()) 450a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return record_type_class; 451a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isUnionType()) 452a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return union_type_class; 453a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isArrayType()) 454a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return array_type_class; 455a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isUnionType()) 456a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return union_type_class; 457a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else // FIXME: offset_type_class, method_type_class, & lang_type_class? 458a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type"); 459a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return -1; 460a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner} 461a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner 4624c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattnerbool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { 4634c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 4644c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner 465019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner switch (E->isBuiltinCall()) { 466019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner default: 46732fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner return Error(E->getLocStart(), diag::err_expr_not_constant, E->getType()); 468019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_classify_type: 469a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner Result.setIsSigned(true); 470a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner Result = EvaluateBuiltinClassifyType(E); 471019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner return true; 472019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner 473019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_constant_p: { 474019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner // __builtin_constant_p always has one operand: it returns true if that 475019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner // operand can be folded, false otherwise. 476019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner APValue Res; 477019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner Result = E->getArg(0)->tryEvaluate(Res, Info.Ctx); 478019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner return true; 479019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner } 480019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner } 4814c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner} 482f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 483b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattnerbool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 484a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (E->getOpcode() == BinaryOperator::Comma) { 485a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // Evaluate the side that actually matters; this needs to be 486a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // handled specially because calling Visit() on the LHS can 487a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // have strange results when it doesn't have an integral type. 488a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman Visit(E->getRHS()); 489a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 490a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // Check for isEvaluated; the idea is that this might eventually 491a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // be useful for isICE and other similar uses that care about 492a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // whether a comma is evaluated. This isn't really used yet, though, 493a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // and I'm not sure it really works as intended. 494a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (!Info.isEvaluated) 495a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return true; 496c8cc9ccc7b87a7ed1749b074f6b670bcec49abc1Chris Lattner 497a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return Extension(E->getOperatorLoc(), diag::ext_comma_in_constant_expr); 498a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 499a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 500a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (E->isLogicalOp()) { 501a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // These need to be handled specially because the operands aren't 502a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // necessarily integral 503a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman bool bres; 504a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (!HandleConversionToBool(E->getLHS(), bres, Info)) { 505a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // We can't evaluate the LHS; however, sometimes the result 506a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // is determined by the RHS: X && 0 -> 0, X || 1 -> 1. 507a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (HandleConversionToBool(E->getRHS(), bres, Info) && 508a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman bres == (E->getOpcode() == BinaryOperator::LOr)) { 509a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 510a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 511a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman Result = bres; 512a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return true; 513a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 514a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 515a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // Really can't evaluate 516c8cc9ccc7b87a7ed1749b074f6b670bcec49abc1Chris Lattner return false; 517a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 518a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 519a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman bool bres2; 520a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (HandleConversionToBool(E->getRHS(), bres2, Info)) { 521c8cc9ccc7b87a7ed1749b074f6b670bcec49abc1Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 52232fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 523a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (E->getOpcode() == BinaryOperator::LOr) 524a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman Result = bres || bres2; 525a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman else 526a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman Result = bres && bres2; 527c8cc9ccc7b87a7ed1749b074f6b670bcec49abc1Chris Lattner return true; 528c8cc9ccc7b87a7ed1749b074f6b670bcec49abc1Chris Lattner } 529a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; 530c8cc9ccc7b87a7ed1749b074f6b670bcec49abc1Chris Lattner } 53154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 532a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (!E->getLHS()->getType()->isIntegralType() || 533a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman !E->getRHS()->getType()->isIntegralType()) { 534a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // We can't continue from here for non-integral types, and they 535a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // could potentially confuse the following operations. 536a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // FIXME: Deal with EQ and friends. 537a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; 538a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 539a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 540a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // The LHS of a constant expr is always evaluated and needed. 541a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman llvm::APSInt RHS(32); 542a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (!Visit(E->getLHS())) { 543a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; // error in subexpression. 544a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 545d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman 546d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman // FIXME: Handle pointer subtraction 547d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman 548d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman // FIXME Maybe we want to succeed even where we can't evaluate the 549d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman // right side of LAnd/LOr? 550d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman // For example, see http://llvm.org/bugs/show_bug.cgi?id=2525 55154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (!EvaluateInteger(E->getRHS(), RHS, Info)) 552b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 553a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 554a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson switch (E->getOpcode()) { 55532fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner default: 55632fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner return Error(E->getOperatorLoc(), diag::err_expr_not_constant,E->getType()); 55754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::Mul: Result *= RHS; return true; 55854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::Add: Result += RHS; return true; 55954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::Sub: Result -= RHS; return true; 56054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::And: Result &= RHS; return true; 56154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::Xor: Result ^= RHS; return true; 56254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::Or: Result |= RHS; return true; 563a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Div: 56454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (RHS == 0) 56532fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero, 56632fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner E->getType()); 567b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner Result /= RHS; 56832fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner break; 569a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Rem: 57054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (RHS == 0) 57132fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner return Error(E->getOperatorLoc(), diag::err_expr_divide_by_zero, 57232fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner E->getType()); 573a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result %= RHS; 57432fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner break; 575a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Shl: 57654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner // FIXME: Warn about out of range shift amounts! 577b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner Result <<= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1); 578a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson break; 579a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Shr: 580b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner Result >>= (unsigned)RHS.getLimitedValue(Result.getBitWidth()-1); 581a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson break; 582b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner 583ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::LT: 584ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result < RHS; 585ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 586ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 587ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::GT: 588ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result > RHS; 589ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 590ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 591ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::LE: 592ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result <= RHS; 593ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 594ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 595ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::GE: 596ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result >= RHS; 597ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 598ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 599ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::EQ: 600ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result == RHS; 601ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 602ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 603ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner case BinaryOperator::NE: 604ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result = Result != RHS; 605ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 606ac7cb603979a0e5a6a216ccbd20eee7647c96b54Chris Lattner break; 60754176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::LAnd: 60854176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Result = Result != 0 && RHS != 0; 60954176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 61054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner break; 61154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner case BinaryOperator::LOr: 61254176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Result = Result != 0 || RHS != 0; 61354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 61454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner break; 615b11e77836dd0867955c5abf32baf1c3e6c7f81e1Eli Friedman } 616a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 617a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 618b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return true; 619a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 620a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 6210518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the 6220518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl/// expression's type. 6230518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redlbool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { 6240518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl QualType DstTy = E->getType(); 625fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // Return the result in the right width. 626fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(DstTy)); 627fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner Result.setIsUnsigned(DstTy->isUnsignedIntegerType()); 628fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 6290518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl QualType SrcTy = E->getTypeOfArgument(); 6300518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl 631fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // sizeof(void) and __alignof__(void) = 1 as a gcc extension. 6324efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (SrcTy->isVoidType()) { 633fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner Result = 1; 6344efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 6354efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 636fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 637fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2. 6384efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman // FIXME: But alignof(vla) is! 639fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner if (!SrcTy->isConstantSizeType()) { 640fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // FIXME: Should we attempt to evaluate this? 641fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner return false; 642fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner } 6430518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl 6440518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl bool isSizeOf = E->isSizeOf(); 645fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 646fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // GCC extension: sizeof(function) = 1. 647fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner if (SrcTy->isFunctionType()) { 648fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // FIXME: AlignOf shouldn't be unconditionally 4! 649fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner Result = isSizeOf ? 1 : 4; 650fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner return true; 651fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner } 652fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 653fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // Get information about the size or align. 65487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner unsigned CharSize = Info.Ctx.Target.getCharWidth(); 655fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner if (isSizeOf) 6564efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result = Info.Ctx.getTypeSize(SrcTy) / CharSize; 657fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner else 65887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner Result = Info.Ctx.getTypeAlign(SrcTy) / CharSize; 659fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner return true; 660fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner} 661fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 662b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattnerbool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { 6634c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // Special case unary operators that do not need their subexpression 6644c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // evaluated. offsetof/sizeof/alignof are all special. 66575a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner if (E->isOffsetOfOp()) { 6664c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 66787eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner Result = E->evaluateOffsetOf(Info.Ctx); 66875a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 66975a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner return true; 67075a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner } 671a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 672a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (E->getOpcode() == UnaryOperator::LNot) { 673a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // LNot's operand isn't necessarily an integer, so we handle it specially. 674a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman bool bres; 675a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (!HandleConversionToBool(E->getSubExpr(), bres, Info)) 676a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; 677a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); 678a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 679a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman Result = !bres; 680a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return true; 681a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 682a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 68387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner // Get the operand value into 'Result'. 68487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (!Visit(E->getSubExpr())) 68575a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner return false; 686a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 68775a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner switch (E->getOpcode()) { 6884c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner default: 68975a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner // Address, indirect, pre/post inc/dec, etc are not valid constant exprs. 69075a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner // See C99 6.6p3. 69132fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner return Error(E->getOperatorLoc(), diag::err_expr_not_constant, 69232fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner E->getType()); 69375a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner case UnaryOperator::Extension: 6944c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // FIXME: Should extension allow i-c-e extension expressions in its scope? 6954c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // If so, we could clear the diagnostic ID. 69675a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner case UnaryOperator::Plus: 6974c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // The result is always just the subexpr. 69875a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner break; 69975a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner case UnaryOperator::Minus: 70075a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner Result = -Result; 70175a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner break; 70275a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner case UnaryOperator::Not: 70375a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner Result = ~Result; 70475a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner break; 70506a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson } 70606a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson 707a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 708b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return true; 709a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 710a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 711732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner/// HandleCast - This is used to evaluate implicit or explicit casts where the 712732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner/// result type is integer. 713732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattnerbool IntExprEvaluator::HandleCast(SourceLocation CastLoc, 714732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Expr *SubExpr, QualType DestType) { 7157a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner unsigned DestWidth = getIntTypeSizeInBits(DestType); 71606a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson 7174efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (DestType->isBooleanType()) { 7184efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman bool BoolResult; 7194efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!HandleConversionToBool(SubExpr, BoolResult, Info)) 7204efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 7214efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result.zextOrTrunc(DestWidth); 7224efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result.setIsUnsigned(DestType->isUnsignedIntegerType()); 7234efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result = BoolResult; 7244efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 7254efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 7264efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 727a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Handle simple integer->integer casts. 728a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (SubExpr->getType()->isIntegralType()) { 729732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner if (!Visit(SubExpr)) 730b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 7312bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 732a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Figure out if this is a truncate, extend or noop cast. 733a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // If the input is signed, do a sign extend, noop, or truncate. 7344efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result.extOrTrunc(DestWidth); 735732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Result.setIsUnsigned(DestType->isUnsignedIntegerType()); 736732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner return true; 737732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner } 738732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner 739732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner // FIXME: Clean this up! 740732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner if (SubExpr->getType()->isPointerType()) { 741a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson APValue LV; 74287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (!EvaluatePointer(SubExpr, LV, Info)) 743b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 7444efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 745a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (LV.getLValueBase()) 746b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 7474efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 748559e56b3a201316ae0b7e7389879a8054f6a3a82Anders Carlsson Result.extOrTrunc(DestWidth); 749559e56b3a201316ae0b7e7389879a8054f6a3a82Anders Carlsson Result = LV.getLValueOffset(); 750732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Result.setIsUnsigned(DestType->isUnsignedIntegerType()); 751732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner return true; 7522bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson } 7534efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 754732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner if (!SubExpr->getType()->isRealFloatingType()) 75532fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner return Error(CastLoc, diag::err_expr_not_constant, DestType); 756732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner 757d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman APFloat F(0.0); 758d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (!EvaluateFloat(SubExpr, F, Info)) 75932fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner return Error(CastLoc, diag::err_expr_not_constant, DestType); 760732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner 761732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner // Determine whether we are converting to unsigned or signed. 762732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner bool DestSigned = DestType->isSignedIntegerType(); 763732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner 764732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner // FIXME: Warning for overflow. 765ee5a700af3fe9ae1a639c271f093f40677dddc04Dale Johannesen uint64_t Space[4]; 766ee5a700af3fe9ae1a639c271f093f40677dddc04Dale Johannesen bool ignored; 767d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman (void)F.convertToInteger(Space, DestWidth, DestSigned, 768ee5a700af3fe9ae1a639c271f093f40677dddc04Dale Johannesen llvm::APFloat::rmTowardZero, &ignored); 769732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Result = llvm::APInt(DestWidth, 4, Space); 770732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner Result.setIsUnsigned(!DestSigned); 771b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return true; 772a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 7732bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 774f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 775d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman// Float Evaluation 776d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman//===----------------------------------------------------------------------===// 777d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 778d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmannamespace { 779d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanclass VISIBILITY_HIDDEN FloatExprEvaluator 780d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman : public StmtVisitor<FloatExprEvaluator, bool> { 781d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman EvalInfo &Info; 782d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman APFloat &Result; 783d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanpublic: 784d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman FloatExprEvaluator(EvalInfo &info, APFloat &result) 785d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman : Info(info), Result(result) {} 786d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 787d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitStmt(Stmt *S) { 788d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 789d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 790d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 791d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 792019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner bool VisitCallExpr(const CallExpr *E); 793d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 7945db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar bool VisitUnaryOperator(const UnaryOperator *E); 795d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitBinaryOperator(const BinaryOperator *E); 796d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitFloatingLiteral(const FloatingLiteral *E); 7974efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman bool VisitCastExpr(CastExpr *E); 7984efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman bool VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E); 799d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman}; 800d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} // end anonymous namespace 801d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 802d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanstatic bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) { 803d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E)); 804d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 805d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 806019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattnerbool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { 807019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner switch (E->isBuiltinCall()) { 80834a74ab81600a40c6324fd76adb724b803dfaf91Chris Lattner default: return false; 809019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_huge_val: 810019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_huge_valf: 811019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_huge_vall: 812019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_inf: 813019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_inff: 8147cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar case Builtin::BI__builtin_infl: { 8157cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar const llvm::fltSemantics &Sem = 8167cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar Info.Ctx.getFloatTypeSemantics(E->getType()); 81734a74ab81600a40c6324fd76adb724b803dfaf91Chris Lattner Result = llvm::APFloat::getInf(Sem); 81834a74ab81600a40c6324fd76adb724b803dfaf91Chris Lattner return true; 8197cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar } 8209e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner 8219e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner case Builtin::BI__builtin_nan: 8229e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner case Builtin::BI__builtin_nanf: 8239e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner case Builtin::BI__builtin_nanl: 8249e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner // If this is __builtin_nan("") turn this into a simple nan, otherwise we 8259e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner // can't constant fold it. 8269e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner if (const StringLiteral *S = 8279e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts())) { 8289e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner if (!S->isWide() && S->getByteLength() == 0) { // empty string. 8297cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar const llvm::fltSemantics &Sem = 8307cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar Info.Ctx.getFloatTypeSemantics(E->getType()); 8319e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner Result = llvm::APFloat::getNaN(Sem); 8329e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner return true; 8339e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner } 8349e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner } 8359e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner return false; 8365db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar 8375db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_fabs: 8385db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_fabsf: 8395db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_fabsl: 8405db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (!EvaluateFloat(E->getArg(0), Result, Info)) 8415db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return false; 8425db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar 8435db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (Result.isNegative()) 8445db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar Result.changeSign(); 8455db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 8465db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar 8475db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_copysign: 8485db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_copysignf: 8495db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_copysignl: { 8505db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar APFloat RHS(0.); 8515db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (!EvaluateFloat(E->getArg(0), Result, Info) || 8525db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar !EvaluateFloat(E->getArg(1), RHS, Info)) 8535db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return false; 8545db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar Result.copySign(RHS); 8555db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 8565db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar } 857019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner } 858019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner} 859019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner 8605db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbarbool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { 8615db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (!EvaluateFloat(E->getSubExpr(), Result, Info)) 8625db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return false; 8635db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar 8645db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar switch (E->getOpcode()) { 8655db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar default: return false; 8665db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case UnaryOperator::Plus: 8675db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 8685db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case UnaryOperator::Minus: 8695db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar Result.changeSign(); 8705db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 8715db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar } 8725db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar} 873019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner 874d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanbool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 875d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman // FIXME: Diagnostics? I really don't understand how the warnings 876d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman // and errors are supposed to work. 8775db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar APFloat RHS(0.0); 878d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (!EvaluateFloat(E->getLHS(), Result, Info)) 879d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 880d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (!EvaluateFloat(E->getRHS(), RHS, Info)) 881d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 882d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 883d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman switch (E->getOpcode()) { 884d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman default: return false; 885d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman case BinaryOperator::Mul: 886d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.multiply(RHS, APFloat::rmNearestTiesToEven); 887d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 888d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman case BinaryOperator::Add: 889d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.add(RHS, APFloat::rmNearestTiesToEven); 890d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 891d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman case BinaryOperator::Sub: 892d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.subtract(RHS, APFloat::rmNearestTiesToEven); 893d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 894d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman case BinaryOperator::Div: 895d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.divide(RHS, APFloat::rmNearestTiesToEven); 896d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 897d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman case BinaryOperator::Rem: 898d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.mod(RHS, APFloat::rmNearestTiesToEven); 899d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 900d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 901d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 902d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 903d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanbool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) { 904d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result = E->getValue(); 905d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 906d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 907d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 9084efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmanbool FloatExprEvaluator::VisitCastExpr(CastExpr *E) { 9094efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Expr* SubExpr = E->getSubExpr(); 9104efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman const llvm::fltSemantics& destSemantics = 9114efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Info.Ctx.getFloatTypeSemantics(E->getType()); 9124efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (SubExpr->getType()->isIntegralType()) { 9134efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APSInt IntResult; 9144efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!EvaluateInteger(E, IntResult, Info)) 9154efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 9164efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result = APFloat(destSemantics, 1); 9174efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result.convertFromAPInt(IntResult, IntResult.isSigned(), 9184efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APFloat::rmNearestTiesToEven); 9194efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 9204efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 9214efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (SubExpr->getType()->isRealFloatingType()) { 9224efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!Visit(SubExpr)) 9234efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 9244efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman bool ignored; 9254efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result.convert(destSemantics, APFloat::rmNearestTiesToEven, &ignored); 9264efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 9274efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 9284efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 9294efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 9304efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 9314efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 9324efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmanbool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) { 9334efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType())); 9344efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 9354efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 9364efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 937d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman//===----------------------------------------------------------------------===// 938f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Top level TryEvaluate. 939f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 940f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 941019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner/// tryEvaluate - Return true if this is a constant which we can fold using 942019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner/// any crazy technique (that has nothing to do with language standards) that 943019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner/// we want to. If this function returns true, it returns the folded constant 944019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner/// in Result. 945b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattnerbool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const { 94687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner EvalInfo Info(Ctx); 94706a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson if (getType()->isIntegerType()) { 948d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman llvm::APSInt sInt(32); 94987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (EvaluateInteger(this, sInt, Info)) { 95006a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson Result = APValue(sInt); 95106a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson return true; 95206a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson } 953d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } else if (getType()->isPointerType()) { 954d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (EvaluatePointer(this, Result, Info)) { 955d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 956d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 957d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } else if (getType()->isRealFloatingType()) { 958d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman llvm::APFloat f(0.0); 959d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (EvaluateFloat(this, f, Info)) { 960d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result = APValue(f); 961d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 962d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 963d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 964165a70fd0b75a4f23456531824e1b76a9f1c4f9cAnders Carlsson 965c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson return false; 966c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson} 96745b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner 96845b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner/// isEvaluatable - Call tryEvaluate to see if this expression can be constant 96945b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner/// folded, but discard the result. 97045b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattnerbool Expr::isEvaluatable(ASTContext &Ctx) const { 97145b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner APValue V; 97245b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner return tryEvaluate(V, Ctx); 97345b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner} 974