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