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