//===--- ExprConstant.cpp - Expression Constant Evaluator -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Expr constant evaluator.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/Support/Compiler.h"
using namespace clang;
using llvm::APSInt;
using llvm::APFloat;

/// EvalInfo - This is a private struct used by the evaluator to capture
/// information about a subexpression as it is folded.  It retains information
/// about the AST context, but also maintains information about the folded
/// expression.
///
/// If an expression could be evaluated, it is still possible it is not a C
/// "integer constant expression" or constant expression.  If not, this struct
/// captures information about how and why not.
///
/// One bit of information passed *into* the request for constant folding
/// indicates whether the subexpression is "evaluated" or not according to C
/// rules.  For example, the RHS of (0 && foo()) is not evaluated.  We can
/// evaluate the expression regardless of what the RHS is, but C only allows
/// certain things in certain situations.
struct EvalInfo {
  ASTContext &Ctx;
  
  /// EvalResult - Contains information about the evaluation.
  Expr::EvalResult &EvalResult;

  EvalInfo(ASTContext &ctx, Expr::EvalResult& evalresult) : Ctx(ctx), 
           EvalResult(evalresult) {}
};


static bool EvaluateLValue(const Expr *E, APValue &Result, EvalInfo &Info);
static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
static bool EvaluateInteger(const Expr *E, APSInt  &Result, EvalInfo &Info);
static bool EvaluateIntegerOrLValue(const Expr *E, APValue  &Result, EvalInfo &Info);
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info);

//===----------------------------------------------------------------------===//
// Misc utilities
//===----------------------------------------------------------------------===//

static bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) {
  if (E->getType()->isIntegralType()) {
    APSInt IntResult;
    if (!EvaluateInteger(E, IntResult, Info))
      return false;
    Result = IntResult != 0;
    return true;
  } else if (E->getType()->isRealFloatingType()) {
    APFloat FloatResult(0.0);
    if (!EvaluateFloat(E, FloatResult, Info))
      return false;
    Result = !FloatResult.isZero();
    return true;
  } else if (E->getType()->hasPointerRepresentation()) {
    APValue PointerResult;
    if (!EvaluatePointer(E, PointerResult, Info))
      return false;
    // FIXME: Is this accurate for all kinds of bases?  If not, what would
    // the check look like?
    Result = PointerResult.getLValueBase() || PointerResult.getLValueOffset();
    return true;
  } else if (E->getType()->isAnyComplexType()) {
    APValue ComplexResult;
    if (!EvaluateComplex(E, ComplexResult, Info))
      return false;
    if (ComplexResult.isComplexFloat()) {
      Result = !ComplexResult.getComplexFloatReal().isZero() ||
               !ComplexResult.getComplexFloatImag().isZero();
    } else {
      Result = ComplexResult.getComplexIntReal().getBoolValue() ||
               ComplexResult.getComplexIntImag().getBoolValue();
    }
    return true;
  }

  return false;
}

static APSInt HandleFloatToIntCast(QualType DestType, QualType SrcType, 
                                   APFloat &Value, ASTContext &Ctx) {
  unsigned DestWidth = Ctx.getIntWidth(DestType);
  // Determine whether we are converting to unsigned or signed.
  bool DestSigned = DestType->isSignedIntegerType();
  
  // FIXME: Warning for overflow.
  uint64_t Space[4];
  bool ignored;
  (void)Value.convertToInteger(Space, DestWidth, DestSigned,
                               llvm::APFloat::rmTowardZero, &ignored);
  return APSInt(llvm::APInt(DestWidth, 4, Space), !DestSigned);
}

static APFloat HandleFloatToFloatCast(QualType DestType, QualType SrcType, 
                                      APFloat &Value, ASTContext &Ctx) {
  bool ignored;
  APFloat Result = Value;
  Result.convert(Ctx.getFloatTypeSemantics(DestType), 
                 APFloat::rmNearestTiesToEven, &ignored);
  return Result;
}

static APSInt HandleIntToIntCast(QualType DestType, QualType SrcType, 
                                 APSInt &Value, ASTContext &Ctx) {
  unsigned DestWidth = Ctx.getIntWidth(DestType);
  APSInt Result = Value;
  // Figure out if this is a truncate, extend or noop cast.
  // If the input is signed, do a sign extend, noop, or truncate.
  Result.extOrTrunc(DestWidth);
  Result.setIsUnsigned(DestType->isUnsignedIntegerType());
  return Result;
}

static APFloat HandleIntToFloatCast(QualType DestType, QualType SrcType, 
                                    APSInt &Value, ASTContext &Ctx) {

  APFloat Result(Ctx.getFloatTypeSemantics(DestType), 1);
  Result.convertFromAPInt(Value, Value.isSigned(),
                          APFloat::rmNearestTiesToEven);
  return Result;
}

//===----------------------------------------------------------------------===//
// LValue Evaluation
//===----------------------------------------------------------------------===//
namespace {
class VISIBILITY_HIDDEN LValueExprEvaluator
  : public StmtVisitor<LValueExprEvaluator, APValue> {
  EvalInfo &Info;
public:
    
  LValueExprEvaluator(EvalInfo &info) : Info(info) {}

  APValue VisitStmt(Stmt *S) {
    return APValue();
  }

  APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
  APValue VisitDeclRefExpr(DeclRefExpr *E);
  APValue VisitBlockExpr(BlockExpr *E);
  APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E, 0); }
  APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
  APValue VisitMemberExpr(MemberExpr *E);
  APValue VisitStringLiteral(StringLiteral *E) { return APValue(E, 0); }
  APValue VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return APValue(E, 0); }
  APValue VisitArraySubscriptExpr(ArraySubscriptExpr *E);
  APValue VisitUnaryDeref(UnaryOperator *E);
  APValue VisitUnaryExtension(const UnaryOperator *E)
    { return Visit(E->getSubExpr()); }
  APValue VisitChooseExpr(const ChooseExpr *E)
    { return Visit(E->getChosenSubExpr(Info.Ctx)); }
  // FIXME: Missing: __real__, __imag__
};
} // end anonymous namespace

static bool EvaluateLValue(const Expr* E, APValue& Result, EvalInfo &Info) {
  Result = LValueExprEvaluator(Info).Visit(const_cast<Expr*>(E));
  return Result.isLValue();
}

APValue LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E)
{ 
  if (!E->hasGlobalStorage())
    return APValue();
  
  return APValue(E, 0); 
}

APValue LValueExprEvaluator::VisitBlockExpr(BlockExpr *E)
{ 
  if (E->hasBlockDeclRefExprs())
    return APValue();
    
  return APValue(E, 0);
}

APValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
  if (E->isFileScope())
    return APValue(E, 0);
  return APValue();
}

APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) {
  APValue result;
  QualType Ty;
  if (E->isArrow()) {
    if (!EvaluatePointer(E->getBase(), result, Info))
      return APValue();
    Ty = E->getBase()->getType()->getAsPointerType()->getPointeeType();
  } else {
    result = Visit(E->getBase());
    if (result.isUninit())
      return APValue();
    Ty = E->getBase()->getType();
  }

  RecordDecl *RD = Ty->getAsRecordType()->getDecl();
  const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);

  FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
  if (!FD) // FIXME: deal with other kinds of member expressions
    return APValue();
    
  // FIXME: This is linear time.
  unsigned i = 0;
  for (RecordDecl::field_iterator Field = RD->field_begin(Info.Ctx),
                               FieldEnd = RD->field_end(Info.Ctx);
       Field != FieldEnd; (void)++Field, ++i) {
    if (*Field == FD)
      break;
  }

  result.setLValue(result.getLValueBase(),
                   result.getLValueOffset() + RL.getFieldOffset(i) / 8);

  return result;
}

APValue LValueExprEvaluator::VisitArraySubscriptExpr(ArraySubscriptExpr *E)
{
  APValue Result;
  
  if (!EvaluatePointer(E->getBase(), Result, Info))
    return APValue();
  
  APSInt Index;
  if (!EvaluateInteger(E->getIdx(), Index, Info))
    return APValue();

  uint64_t ElementSize = Info.Ctx.getTypeSize(E->getType()) / 8;

  uint64_t Offset = Index.getSExtValue() * ElementSize;
  Result.setLValue(Result.getLValueBase(), 
                   Result.getLValueOffset() + Offset);
  return Result;
}

APValue LValueExprEvaluator::VisitUnaryDeref(UnaryOperator *E)
{
  APValue Result;
  if (!EvaluatePointer(E->getSubExpr(), Result, Info))
    return APValue();
  return Result;
}

//===----------------------------------------------------------------------===//
// Pointer Evaluation
//===----------------------------------------------------------------------===//

namespace {
class VISIBILITY_HIDDEN PointerExprEvaluator
  : public StmtVisitor<PointerExprEvaluator, APValue> {
  EvalInfo &Info;
public:
    
  PointerExprEvaluator(EvalInfo &info) : Info(info) {}

  APValue VisitStmt(Stmt *S) {
    return APValue();
  }

  APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }

  APValue VisitBinaryOperator(const BinaryOperator *E);
  APValue VisitCastExpr(const CastExpr* E);
  APValue VisitUnaryExtension(const UnaryOperator *E)
      { return Visit(E->getSubExpr()); }
  APValue VisitUnaryAddrOf(const UnaryOperator *E);
  APValue VisitObjCStringLiteral(ObjCStringLiteral *E)
      { return APValue(E, 0); }
  APValue VisitAddrLabelExpr(AddrLabelExpr *E)
      { return APValue(E, 0); }
  APValue VisitCallExpr(CallExpr *E);
  APValue VisitBlockExpr(BlockExpr *E) {
    if (!E->hasBlockDeclRefExprs())
      return APValue(E, 0);
    return APValue();
  }
  APValue VisitImplicitValueInitExpr(ImplicitValueInitExpr *E)
      { return APValue((Expr*)0, 0); }
  APValue VisitConditionalOperator(ConditionalOperator *E);
  APValue VisitChooseExpr(ChooseExpr *E)
    { return Visit(E->getChosenSubExpr(Info.Ctx)); }
  // FIXME: Missing: @protocol, @selector
};
} // end anonymous namespace

static bool EvaluatePointer(const Expr* E, APValue& Result, EvalInfo &Info) {
  if (!E->getType()->hasPointerRepresentation())
    return false;
  Result = PointerExprEvaluator(Info).Visit(const_cast<Expr*>(E));
  return Result.isLValue();
}

APValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
  if (E->getOpcode() != BinaryOperator::Add &&
      E->getOpcode() != BinaryOperator::Sub)
    return APValue();
  
  const Expr *PExp = E->getLHS();
  const Expr *IExp = E->getRHS();
  if (IExp->getType()->isPointerType())
    std::swap(PExp, IExp);
  
  APValue ResultLValue;
  if (!EvaluatePointer(PExp, ResultLValue, Info))
    return APValue();
  
  llvm::APSInt AdditionalOffset(32);
  if (!EvaluateInteger(IExp, AdditionalOffset, Info))
    return APValue();

  QualType PointeeType = PExp->getType()->getAsPointerType()->getPointeeType();
  uint64_t SizeOfPointee;
  
  // Explicitly handle GNU void* and function pointer arithmetic extensions.
  if (PointeeType->isVoidType() || PointeeType->isFunctionType())
    SizeOfPointee = 1;
  else
    SizeOfPointee = Info.Ctx.getTypeSize(PointeeType) / 8;

  uint64_t Offset = ResultLValue.getLValueOffset();

  if (E->getOpcode() == BinaryOperator::Add)
    Offset += AdditionalOffset.getLimitedValue() * SizeOfPointee;
  else
    Offset -= AdditionalOffset.getLimitedValue() * SizeOfPointee;

  return APValue(ResultLValue.getLValueBase(), Offset);
}

APValue PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
  APValue result;
  if (EvaluateLValue(E->getSubExpr(), result, Info))
    return result;
  return APValue();
}
  

APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
  const Expr* SubExpr = E->getSubExpr();

   // Check for pointer->pointer cast
  if (SubExpr->getType()->isPointerType()) {
    APValue Result;
    if (EvaluatePointer(SubExpr, Result, Info))
      return Result;
    return APValue();
  }
  
  if (SubExpr->getType()->isIntegralType()) {
    APValue Result;
    if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
      return APValue();

    if (Result.isInt()) {
      Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
      return APValue(0, Result.getInt().getZExtValue());
    }
    
    // Cast is of an lvalue, no need to change value.
    return Result;
  }

  if (SubExpr->getType()->isFunctionType() ||
      SubExpr->getType()->isBlockPointerType() ||
      SubExpr->getType()->isArrayType()) {
    APValue Result;
    if (EvaluateLValue(SubExpr, Result, Info))
      return Result;
    return APValue();
  }

  return APValue();
}  

APValue PointerExprEvaluator::VisitCallExpr(CallExpr *E) {
  if (E->isBuiltinCall(Info.Ctx) == 
        Builtin::BI__builtin___CFStringMakeConstantString)
    return APValue(E, 0);
  return APValue();
}

APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) {
  bool BoolResult;
  if (!HandleConversionToBool(E->getCond(), BoolResult, Info))
    return APValue();

  Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();

  APValue Result;
  if (EvaluatePointer(EvalExpr, Result, Info))
    return Result;
  return APValue();
}

//===----------------------------------------------------------------------===//
// Vector Evaluation
//===----------------------------------------------------------------------===//

namespace {
  class VISIBILITY_HIDDEN VectorExprEvaluator
  : public StmtVisitor<VectorExprEvaluator, APValue> {
    EvalInfo &Info;
    APValue GetZeroVector(QualType VecType);
  public:
    
    VectorExprEvaluator(EvalInfo &info) : Info(info) {}
    
    APValue VisitStmt(Stmt *S) {
      return APValue();
    }
    
    APValue VisitParenExpr(ParenExpr *E)
        { return Visit(E->getSubExpr()); }
    APValue VisitUnaryExtension(const UnaryOperator *E)
      { return Visit(E->getSubExpr()); }
    APValue VisitUnaryPlus(const UnaryOperator *E)
      { return Visit(E->getSubExpr()); }
    APValue VisitUnaryReal(const UnaryOperator *E)
      { return Visit(E->getSubExpr()); }
    APValue VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E)
      { return GetZeroVector(E->getType()); }
    APValue VisitCastExpr(const CastExpr* E);
    APValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
    APValue VisitInitListExpr(const InitListExpr *E);
    APValue VisitConditionalOperator(const ConditionalOperator *E);
    APValue VisitChooseExpr(const ChooseExpr *E)
      { return Visit(E->getChosenSubExpr(Info.Ctx)); }
    APValue VisitUnaryImag(const UnaryOperator *E);
    // FIXME: Missing: unary -, unary ~, binary add/sub/mul/div,
    //                 binary comparisons, binary and/or/xor,
    //                 shufflevector, ExtVectorElementExpr
    //        (Note that these require implementing conversions
    //         between vector types.)
  };
} // end anonymous namespace

static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) {
  if (!E->getType()->isVectorType())
    return false;
  Result = VectorExprEvaluator(Info).Visit(const_cast<Expr*>(E));
  return !Result.isUninit();
}

APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
  const Expr* SE = E->getSubExpr();

  // Check for vector->vector bitcast.
  if (SE->getType()->isVectorType())
    return this->Visit(const_cast<Expr*>(SE));

  return APValue();
}

APValue 
VectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
  return this->Visit(const_cast<Expr*>(E->getInitializer()));
}

APValue 
VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
  const VectorType *VT = E->getType()->getAsVectorType();
  unsigned NumInits = E->getNumInits();
  unsigned NumElements = VT->getNumElements();
  
  QualType EltTy = VT->getElementType();
  llvm::SmallVector<APValue, 4> Elements;

  for (unsigned i = 0; i < NumElements; i++) {
    if (EltTy->isIntegerType()) {
      llvm::APSInt sInt(32);
      if (i < NumInits) {
        if (!EvaluateInteger(E->getInit(i), sInt, Info))
          return APValue();
      } else {
        sInt = Info.Ctx.MakeIntValue(0, EltTy);
      }
      Elements.push_back(APValue(sInt));
    } else {
      llvm::APFloat f(0.0);
      if (i < NumInits) {
        if (!EvaluateFloat(E->getInit(i), f, Info))
          return APValue();
      } else {
        f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
      }
      Elements.push_back(APValue(f));
    }
  }
  return APValue(&Elements[0], Elements.size());
}

APValue 
VectorExprEvaluator::GetZeroVector(QualType T) {
  const VectorType *VT = T->getAsVectorType();
  QualType EltTy = VT->getElementType();
  APValue ZeroElement;
  if (EltTy->isIntegerType())
    ZeroElement = APValue(Info.Ctx.MakeIntValue(0, EltTy));
  else
    ZeroElement =
        APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));

  llvm::SmallVector<APValue, 4> Elements(VT->getNumElements(), ZeroElement);
  return APValue(&Elements[0], Elements.size());
}

APValue VectorExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
  bool BoolResult;
  if (!HandleConversionToBool(E->getCond(), BoolResult, Info))
    return APValue();

  Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr();

  APValue Result;
  if (EvaluateVector(EvalExpr, Result, Info))
    return Result;
  return APValue();
}

APValue VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
  if (!E->getSubExpr()->isEvaluatable(Info.Ctx))
    Info.EvalResult.HasSideEffects = true;
  return GetZeroVector(E->getType());
}

//===----------------------------------------------------------------------===//
// Integer Evaluation
//===----------------------------------------------------------------------===//

namespace {
class VISIBILITY_HIDDEN IntExprEvaluator
  : public StmtVisitor<IntExprEvaluator, bool> {
  EvalInfo &Info;
  APValue &Result;
public:
  IntExprEvaluator(EvalInfo &info, APValue &result)
    : Info(info), Result(result) {}

  bool Success(const llvm::APSInt &SI, const Expr *E) {
    assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
    assert(SI.isSigned() == E->getType()->isSignedIntegerType() &&
           "Invalid evaluation result.");
    assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
           "Invalid evaluation result.");
    Result = APValue(SI);
    return true;
  }

  bool Success(const llvm::APInt &I, const Expr *E) {
    assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
    assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
           "Invalid evaluation result.");
    Result = APValue(APSInt(I));
    Result.getInt().setIsUnsigned(E->getType()->isUnsignedIntegerType());
    return true;
  }

  bool Success(uint64_t Value, const Expr *E) {
    assert(E->getType()->isIntegralType() && "Invalid evaluation result.");
    Result = APValue(Info.Ctx.MakeIntValue(Value, E->getType()));
    return true;
  }

  bool Error(SourceLocation L, diag::kind D, const Expr *E) {
    // Take the first error.
    if (Info.EvalResult.Diag == 0) {
      Info.EvalResult.DiagLoc = L;
      Info.EvalResult.Diag = D;
      Info.EvalResult.DiagExpr = E;
    }
    return false;
  }
    
  //===--------------------------------------------------------------------===//
  //                            Visitor Methods
  //===--------------------------------------------------------------------===//
  
  bool VisitStmt(Stmt *) {
    assert(0 && "This should be called on integers, stmts are not integers");
    return false;
  }
    
  bool VisitExpr(Expr *E) {
    return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
  }
  
  bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }

  bool VisitIntegerLiteral(const IntegerLiteral *E) {
    return Success(E->getValue(), E);
  }
  bool VisitCharacterLiteral(const CharacterLiteral *E) {
    return Success(E->getValue(), E);
  }
  bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
    // Per gcc docs "this built-in function ignores top level
    // qualifiers".  We need to use the canonical version to properly
    // be able to strip CRV qualifiers from the type.
    QualType T0 = Info.Ctx.getCanonicalType(E->getArgType1());
    QualType T1 = Info.Ctx.getCanonicalType(E->getArgType2());
    return Success(Info.Ctx.typesAreCompatible(T0.getUnqualifiedType(), 
                                               T1.getUnqualifiedType()),
                   E);
  }
  bool VisitDeclRefExpr(const DeclRefExpr *E);
  bool VisitCallExpr(const CallExpr *E);
  bool VisitBinaryOperator(const BinaryOperator *E);
  bool VisitUnaryOperator(const UnaryOperator *E);
  bool VisitConditionalOperator(const ConditionalOperator *E);

  bool VisitCastExpr(CastExpr* E);
  bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);

  bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
    return Success(E->getValue(), E);
  }
  
  bool VisitGNUNullExpr(const GNUNullExpr *E) {
    return Success(0, E);
  }
    
  bool VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
    return Success(0, E);
  }

  bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
    return Success(0, E);
  }

  bool VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
    return Success(E->EvaluateTrait(), E);
  }

  bool VisitChooseExpr(const ChooseExpr *E) {
    return Visit(E->getChosenSubExpr(Info.Ctx));
  }

  bool VisitUnaryReal(const UnaryOperator *E);
  bool VisitUnaryImag(const UnaryOperator *E);

private:
  unsigned GetAlignOfExpr(const Expr *E);
  unsigned GetAlignOfType(QualType T);
  // FIXME: Missing: array subscript of vector, member of vector
};
} // end anonymous namespace

static bool EvaluateIntegerOrLValue(const Expr* E, APValue &Result, EvalInfo &Info) {
  if (!E->getType()->isIntegralType())
    return false;
  
  return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
}

static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
  APValue Val;
  if (!EvaluateIntegerOrLValue(E, Val, Info) || !Val.isInt())
    return false;
  Result = Val.getInt();
  return true;
}

bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
  // Enums are integer constant exprs.
  if (const EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(E->getDecl())) {
    // FIXME: This is an ugly hack around the fact that enums don't set their
    // signedness consistently; see PR3173.
    APSInt SI = D->getInitVal();
    SI.setIsUnsigned(!E->getType()->isSignedIntegerType());
    // FIXME: This is an ugly hack around the fact that enums don't
    // set their width (!?!) consistently; see PR3173.
    SI.extOrTrunc(Info.Ctx.getIntWidth(E->getType()));
    return Success(SI, E);
  }

  // In C++, const, non-volatile integers initialized with ICEs are ICEs.
  // In C, they can also be folded, although they are not ICEs.
  if (E->getType().getCVRQualifiers() == QualType::Const) {
    if (const VarDecl *D = dyn_cast<VarDecl>(E->getDecl())) {
      if (const Expr *Init = D->getInit())
        return Visit(const_cast<Expr*>(Init));
    }
  }

  // Otherwise, random variable references are not constants.
  return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
}

/// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way
/// as GCC.
static int EvaluateBuiltinClassifyType(const CallExpr *E) {
  // The following enum mimics the values returned by GCC.
  // FIXME: Does GCC differ between lvalue and rvalue references here?
  enum gcc_type_class {
    no_type_class = -1,
    void_type_class, integer_type_class, char_type_class,
    enumeral_type_class, boolean_type_class,
    pointer_type_class, reference_type_class, offset_type_class,
    real_type_class, complex_type_class,
    function_type_class, method_type_class,
    record_type_class, union_type_class,
    array_type_class, string_type_class,
    lang_type_class
  };
  
  // If no argument was supplied, default to "no_type_class". This isn't 
  // ideal, however it is what gcc does.
  if (E->getNumArgs() == 0)
    return no_type_class;
  
  QualType ArgTy = E->getArg(0)->getType();
  if (ArgTy->isVoidType())
    return void_type_class;
  else if (ArgTy->isEnumeralType())
    return enumeral_type_class;
  else if (ArgTy->isBooleanType())
    return boolean_type_class;
  else if (ArgTy->isCharType())
    return string_type_class; // gcc doesn't appear to use char_type_class
  else if (ArgTy->isIntegerType())
    return integer_type_class;
  else if (ArgTy->isPointerType())
    return pointer_type_class;
  else if (ArgTy->isReferenceType())
    return reference_type_class;
  else if (ArgTy->isRealType())
    return real_type_class;
  else if (ArgTy->isComplexType())
    return complex_type_class;
  else if (ArgTy->isFunctionType())
    return function_type_class;
  else if (ArgTy->isStructureType())
    return record_type_class;
  else if (ArgTy->isUnionType())
    return union_type_class;
  else if (ArgTy->isArrayType())
    return array_type_class;
  else if (ArgTy->isUnionType())
    return union_type_class;
  else  // FIXME: offset_type_class, method_type_class, & lang_type_class?
    assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type");
  return -1;
}

bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
  switch (E->isBuiltinCall(Info.Ctx)) {
  default:
    return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
  case Builtin::BI__builtin_classify_type:
    return Success(EvaluateBuiltinClassifyType(E), E);
    
  case Builtin::BI__builtin_constant_p:
    // __builtin_constant_p always has one operand: it returns true if that
    // operand can be folded, false otherwise.
    return Success(E->getArg(0)->isEvaluatable(Info.Ctx), E);
  }
}

bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
  if (E->getOpcode() == BinaryOperator::Comma) {
    if (!Visit(E->getRHS()))
      return false;

    // If we can't evaluate the LHS, it might have side effects;
    // conservatively mark it.
    if (!E->getLHS()->isEvaluatable(Info.Ctx))
      Info.EvalResult.HasSideEffects = true;

    return true;
  }

  if (E->isLogicalOp()) {
    // These need to be handled specially because the operands aren't
    // necessarily integral
    bool lhsResult, rhsResult;
    
    if (HandleConversionToBool(E->getLHS(), lhsResult, Info)) {
      // We were able to evaluate the LHS, see if we can get away with not
      // evaluating the RHS: 0 && X -> 0, 1 || X -> 1
      if (lhsResult == (E->getOpcode() == BinaryOperator::LOr))
        return Success(lhsResult, E);

      if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) {
        if (E->getOpcode() == BinaryOperator::LOr)
          return Success(lhsResult || rhsResult, E);
        else
          return Success(lhsResult && rhsResult, E);
      }
    } else {
      if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) {
        // We can't evaluate the LHS; however, sometimes the result
        // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
        if (rhsResult == (E->getOpcode() == BinaryOperator::LOr) || 
            !rhsResult == (E->getOpcode() == BinaryOperator::LAnd)) {
          // Since we weren't able to evaluate the left hand side, it
          // must have had side effects.
          Info.EvalResult.HasSideEffects = true;

          return Success(rhsResult, E);
        }
      }
    }

    return false;
  }

  QualType LHSTy = E->getLHS()->getType();
  QualType RHSTy = E->getRHS()->getType();

  if (LHSTy->isAnyComplexType()) {
    assert(RHSTy->isAnyComplexType() && "Invalid comparison");
    APValue LHS, RHS;

    if (!EvaluateComplex(E->getLHS(), LHS, Info))
      return false;

    if (!EvaluateComplex(E->getRHS(), RHS, Info))
      return false;

    if (LHS.isComplexFloat()) {
      APFloat::cmpResult CR_r = 
        LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
      APFloat::cmpResult CR_i = 
        LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());

      if (E->getOpcode() == BinaryOperator::EQ)
        return Success((CR_r == APFloat::cmpEqual &&
                        CR_i == APFloat::cmpEqual), E);
      else {
        assert(E->getOpcode() == BinaryOperator::NE &&
               "Invalid complex comparison.");
        return Success(((CR_r == APFloat::cmpGreaterThan || 
                         CR_r == APFloat::cmpLessThan) &&
                        (CR_i == APFloat::cmpGreaterThan || 
                         CR_i == APFloat::cmpLessThan)), E);
      }
    } else {
      if (E->getOpcode() == BinaryOperator::EQ)
        return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
                        LHS.getComplexIntImag() == RHS.getComplexIntImag()), E);
      else {
        assert(E->getOpcode() == BinaryOperator::NE &&
               "Invalid compex comparison.");
        return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
                        LHS.getComplexIntImag() != RHS.getComplexIntImag()), E);
      }
    }
  }
  
  if (LHSTy->isRealFloatingType() &&
      RHSTy->isRealFloatingType()) {
    APFloat RHS(0.0), LHS(0.0);
    
    if (!EvaluateFloat(E->getRHS(), RHS, Info))
      return false;
    
    if (!EvaluateFloat(E->getLHS(), LHS, Info))
      return false;
    
    APFloat::cmpResult CR = LHS.compare(RHS);

    switch (E->getOpcode()) {
    default:
      assert(0 && "Invalid binary operator!");
    case BinaryOperator::LT:
      return Success(CR == APFloat::cmpLessThan, E);
    case BinaryOperator::GT:
      return Success(CR == APFloat::cmpGreaterThan, E);
    case BinaryOperator::LE:
      return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E);
    case BinaryOperator::GE:
      return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual, 
                     E);
    case BinaryOperator::EQ:
      return Success(CR == APFloat::cmpEqual, E);
    case BinaryOperator::NE:
      return Success(CR == APFloat::cmpGreaterThan 
                     || CR == APFloat::cmpLessThan, E);
    }
  }
  
  if (LHSTy->isPointerType() && RHSTy->isPointerType()) {
    if (E->getOpcode() == BinaryOperator::Sub || E->isEqualityOp()) {
      APValue LHSValue;
      if (!EvaluatePointer(E->getLHS(), LHSValue, Info))
        return false;

      APValue RHSValue;
      if (!EvaluatePointer(E->getRHS(), RHSValue, Info))
        return false;

      // Reject any bases; this is conservative, but good enough for
      // common uses
      if (LHSValue.getLValueBase() || RHSValue.getLValueBase())
        return false;

      if (E->getOpcode() == BinaryOperator::Sub) {
        const QualType Type = E->getLHS()->getType();
        const QualType ElementType = Type->getAsPointerType()->getPointeeType();

        uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset();
        D /= Info.Ctx.getTypeSize(ElementType) / 8;

        return Success(D, E);
      }
      bool Result;
      if (E->getOpcode() == BinaryOperator::EQ) {
        Result = LHSValue.getLValueOffset() == RHSValue.getLValueOffset();
      } else {
        Result = LHSValue.getLValueOffset() != RHSValue.getLValueOffset();
      }
      return Success(Result, E);
    }
  }
  if (!LHSTy->isIntegralType() ||
      !RHSTy->isIntegralType()) {
    // We can't continue from here for non-integral types, and they
    // could potentially confuse the following operations.
    return false;
  }

  // The LHS of a constant expr is always evaluated and needed.
  if (!Visit(E->getLHS()))
    return false; // error in subexpression.

  APValue RHSVal;
  if (!EvaluateIntegerOrLValue(E->getRHS(), RHSVal, Info))
    return false;

  // Handle cases like (unsigned long)&a + 4.
  if (E->isAdditiveOp() && Result.isLValue() && RHSVal.isInt()) {
    uint64_t offset = Result.getLValueOffset();
    if (E->getOpcode() == BinaryOperator::Add)
      offset += RHSVal.getInt().getZExtValue();
    else
      offset -= RHSVal.getInt().getZExtValue();
    Result = APValue(Result.getLValueBase(), offset);
    return true;
  }

  // Handle cases like 4 + (unsigned long)&a
  if (E->getOpcode() == BinaryOperator::Add &&
        RHSVal.isLValue() && Result.isInt()) {
    uint64_t offset = RHSVal.getLValueOffset();
    offset += Result.getInt().getZExtValue();
    Result = APValue(RHSVal.getLValueBase(), offset);
    return true;
  }

  // All the following cases expect both operands to be an integer
  if (!Result.isInt() || !RHSVal.isInt())
    return false;

  APSInt& RHS = RHSVal.getInt();

  switch (E->getOpcode()) {
  default:
    return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E);
  case BinaryOperator::Mul: return Success(Result.getInt() * RHS, E);
  case BinaryOperator::Add: return Success(Result.getInt() + RHS, E);
  case BinaryOperator::Sub: return Success(Result.getInt() - RHS, E);
  case BinaryOperator::And: return Success(Result.getInt() & RHS, E);
  case BinaryOperator::Xor: return Success(Result.getInt() ^ RHS, E);
  case BinaryOperator::Or:  return Success(Result.getInt() | RHS, E);
  case BinaryOperator::Div:
    if (RHS == 0)
      return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
    return Success(Result.getInt() / RHS, E);
  case BinaryOperator::Rem:
    if (RHS == 0)
      return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E);
    return Success(Result.getInt() % RHS, E);
  case BinaryOperator::Shl: {
    // FIXME: Warn about out of range shift amounts!
    unsigned SA = 
      (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1);
    return Success(Result.getInt() << SA, E);
  }
  case BinaryOperator::Shr: {
    unsigned SA = 
      (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1);
    return Success(Result.getInt() >> SA, E);
  }
      
  case BinaryOperator::LT: return Success(Result.getInt() < RHS, E);
  case BinaryOperator::GT: return Success(Result.getInt() > RHS, E);
  case BinaryOperator::LE: return Success(Result.getInt() <= RHS, E);
  case BinaryOperator::GE: return Success(Result.getInt() >= RHS, E);
  case BinaryOperator::EQ: return Success(Result.getInt() == RHS, E);
  case BinaryOperator::NE: return Success(Result.getInt() != RHS, E);
  }
}

bool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
  bool Cond;
  if (!HandleConversionToBool(E->getCond(), Cond, Info))
    return false;

  return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
}

unsigned IntExprEvaluator::GetAlignOfType(QualType T) {
  // Get information about the alignment.
  unsigned CharSize = Info.Ctx.Target.getCharWidth();

  // FIXME: Why do we ask for the preferred alignment?
  return Info.Ctx.getPreferredTypeAlign(T.getTypePtr()) / CharSize;
}

unsigned IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
  E = E->IgnoreParens();

  // alignof decl is always accepted, even if it doesn't make sense: we default
  // to 1 in those cases. 
  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
    return Info.Ctx.getDeclAlignInBytes(DRE->getDecl());

  if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
    return Info.Ctx.getDeclAlignInBytes(ME->getMemberDecl());

  return GetAlignOfType(E->getType());
}


/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the
/// expression's type.
bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
  QualType DstTy = E->getType();

  // Handle alignof separately.
  if (!E->isSizeOf()) {
    if (E->isArgumentType())
      return Success(GetAlignOfType(E->getArgumentType()), E);
    else
      return Success(GetAlignOfExpr(E->getArgumentExpr()), E);
  }

  QualType SrcTy = E->getTypeOfArgument();

  // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
  // extension.
  if (SrcTy->isVoidType() || SrcTy->isFunctionType())
    return Success(1, E);

  // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
  if (!SrcTy->isConstantSizeType())
    return false;

  // Get information about the size.
  unsigned BitWidth = Info.Ctx.getTypeSize(SrcTy);
  return Success(BitWidth / Info.Ctx.Target.getCharWidth(), E);
}

bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
  // Special case unary operators that do not need their subexpression
  // evaluated.  offsetof/sizeof/alignof are all special.
  if (E->isOffsetOfOp()) {
    // The AST for offsetof is defined in such a way that we can just
    // directly Evaluate it as an l-value.
    APValue LV;
    if (!EvaluateLValue(E->getSubExpr(), LV, Info))
      return false;
    if (LV.getLValueBase())
      return false;
    return Success(LV.getLValueOffset(), E);
  }

  if (E->getOpcode() == UnaryOperator::LNot) {
    // LNot's operand isn't necessarily an integer, so we handle it specially.
    bool bres;
    if (!HandleConversionToBool(E->getSubExpr(), bres, Info))
      return false;
    return Success(!bres, E);
  }

  // Only handle integral operations...
  if (!E->getSubExpr()->getType()->isIntegralType())
    return false;

  // Get the operand value into 'Result'.
  if (!Visit(E->getSubExpr()))
    return false;

  switch (E->getOpcode()) {
  default:
    // Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
    // See C99 6.6p3.
    return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E);
  case UnaryOperator::Extension:
    // FIXME: Should extension allow i-c-e extension expressions in its scope?
    // If so, we could clear the diagnostic ID.
    return true;
  case UnaryOperator::Plus:
    // The result is always just the subexpr. 
    return true;
  case UnaryOperator::Minus:
    if (!Result.isInt()) return false;
    return Success(-Result.getInt(), E);
  case UnaryOperator::Not:
    if (!Result.isInt()) return false;
    return Success(~Result.getInt(), E);
  }
}
  
/// HandleCast - This is used to evaluate implicit or explicit casts where the
/// result type is integer.
bool IntExprEvaluator::VisitCastExpr(CastExpr *E) {
  Expr *SubExpr = E->getSubExpr();
  QualType DestType = E->getType();
  QualType SrcType = SubExpr->getType();

  if (DestType->isBooleanType()) {
    bool BoolResult;
    if (!HandleConversionToBool(SubExpr, BoolResult, Info))
      return false;
    return Success(BoolResult, E);
  }

  // Handle simple integer->integer casts.
  if (SrcType->isIntegralType()) {
    if (!Visit(SubExpr))
      return false;

    if (!Result.isInt()) {
      // Only allow casts of lvalues if they are lossless.
      return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
    }

    return Success(HandleIntToIntCast(DestType, SrcType,
                                      Result.getInt(), Info.Ctx), E);
  }
  
  // FIXME: Clean this up!
  if (SrcType->isPointerType()) {
    APValue LV;
    if (!EvaluatePointer(SubExpr, LV, Info))
      return false;

    if (LV.getLValueBase()) {
      // Only allow based lvalue casts if they are lossless.
      if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
        return false;

      Result = LV;
      return true;
    }

    APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset(), SrcType);
    return Success(HandleIntToIntCast(DestType, SrcType, AsInt, Info.Ctx), E);
  }

  if (SrcType->isArrayType() || SrcType->isFunctionType()) {
    // This handles double-conversion cases, where there's both
    // an l-value promotion and an implicit conversion to int.
    APValue LV;
    if (!EvaluateLValue(SubExpr, LV, Info))
      return false;

    if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(Info.Ctx.VoidPtrTy))
      return false;

    Result = LV;
    return true;
  }

  if (SrcType->isAnyComplexType()) {
    APValue C;
    if (!EvaluateComplex(SubExpr, C, Info))
      return false;
    if (C.isComplexFloat())
      return Success(HandleFloatToIntCast(DestType, SrcType,
                                          C.getComplexFloatReal(), Info.Ctx),
                     E);
    else
      return Success(HandleIntToIntCast(DestType, SrcType,
                                        C.getComplexIntReal(), Info.Ctx), E);
  }
  // FIXME: Handle vectors

  if (!SrcType->isRealFloatingType())
    return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);

  APFloat F(0.0);
  if (!EvaluateFloat(SubExpr, F, Info))
    return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
  
  return Success(HandleFloatToIntCast(DestType, SrcType, F, Info.Ctx), E);
}

bool IntExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
  if (E->getSubExpr()->getType()->isAnyComplexType()) {
    APValue LV;
    if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt())
      return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
    return Success(LV.getComplexIntReal(), E);
  }

  return Visit(E->getSubExpr());
}

bool IntExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
  if (E->getSubExpr()->getType()->isComplexIntegerType()) {
    APValue LV;
    if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt())
      return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
    return Success(LV.getComplexIntImag(), E);
  }

  if (!E->getSubExpr()->isEvaluatable(Info.Ctx))
    Info.EvalResult.HasSideEffects = true;
  return Success(0, E);
}

//===----------------------------------------------------------------------===//
// Float Evaluation
//===----------------------------------------------------------------------===//

namespace {
class VISIBILITY_HIDDEN FloatExprEvaluator
  : public StmtVisitor<FloatExprEvaluator, bool> {
  EvalInfo &Info;
  APFloat &Result;
public:
  FloatExprEvaluator(EvalInfo &info, APFloat &result)
    : Info(info), Result(result) {}

  bool VisitStmt(Stmt *S) {
    return false;
  }

  bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
  bool VisitCallExpr(const CallExpr *E);

  bool VisitUnaryOperator(const UnaryOperator *E);
  bool VisitBinaryOperator(const BinaryOperator *E);
  bool VisitFloatingLiteral(const FloatingLiteral *E);
  bool VisitCastExpr(CastExpr *E);
  bool VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);

  bool VisitChooseExpr(const ChooseExpr *E)
    { return Visit(E->getChosenSubExpr(Info.Ctx)); }
  bool VisitUnaryExtension(const UnaryOperator *E)
    { return Visit(E->getSubExpr()); }

  // FIXME: Missing: __real__/__imag__, array subscript of vector,
  //                 member of vector, ImplicitValueInitExpr,
  //                 conditional ?:, comma
};
} // end anonymous namespace

static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) {
  return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
}

bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
  switch (E->isBuiltinCall(Info.Ctx)) {
  default: return false;
  case Builtin::BI__builtin_huge_val:
  case Builtin::BI__builtin_huge_valf:
  case Builtin::BI__builtin_huge_vall:
  case Builtin::BI__builtin_inf:
  case Builtin::BI__builtin_inff:
  case Builtin::BI__builtin_infl: {
    const llvm::fltSemantics &Sem =
      Info.Ctx.getFloatTypeSemantics(E->getType());
    Result = llvm::APFloat::getInf(Sem);
    return true;
  }
      
  case Builtin::BI__builtin_nan:
  case Builtin::BI__builtin_nanf:
  case Builtin::BI__builtin_nanl:
    // If this is __builtin_nan("") turn this into a simple nan, otherwise we
    // can't constant fold it.
    if (const StringLiteral *S = 
        dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts())) {
      if (!S->isWide() && S->getByteLength() == 0) { // empty string.
        const llvm::fltSemantics &Sem =
          Info.Ctx.getFloatTypeSemantics(E->getType());
        Result = llvm::APFloat::getNaN(Sem);
        return true;
      }
    }
    return false;

  case Builtin::BI__builtin_fabs:
  case Builtin::BI__builtin_fabsf:
  case Builtin::BI__builtin_fabsl:
    if (!EvaluateFloat(E->getArg(0), Result, Info))
      return false;
    
    if (Result.isNegative())
      Result.changeSign();
    return true;

  case Builtin::BI__builtin_copysign: 
  case Builtin::BI__builtin_copysignf: 
  case Builtin::BI__builtin_copysignl: {
    APFloat RHS(0.);
    if (!EvaluateFloat(E->getArg(0), Result, Info) ||
        !EvaluateFloat(E->getArg(1), RHS, Info))
      return false;
    Result.copySign(RHS);
    return true;
  }
  }
}

bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
  if (E->getOpcode() == UnaryOperator::Deref)
    return false;

  if (!EvaluateFloat(E->getSubExpr(), Result, Info))
    return false;

  switch (E->getOpcode()) {
  default: return false;
  case UnaryOperator::Plus: 
    return true;
  case UnaryOperator::Minus:
    Result.changeSign();
    return true;
  }
}

bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
  // FIXME: Diagnostics?  I really don't understand how the warnings
  // and errors are supposed to work.
  APFloat RHS(0.0);
  if (!EvaluateFloat(E->getLHS(), Result, Info))
    return false;
  if (!EvaluateFloat(E->getRHS(), RHS, Info))
    return false;

  switch (E->getOpcode()) {
  default: return false;
  case BinaryOperator::Mul:
    Result.multiply(RHS, APFloat::rmNearestTiesToEven);
    return true;
  case BinaryOperator::Add:
    Result.add(RHS, APFloat::rmNearestTiesToEven);
    return true;
  case BinaryOperator::Sub:
    Result.subtract(RHS, APFloat::rmNearestTiesToEven);
    return true;
  case BinaryOperator::Div:
    Result.divide(RHS, APFloat::rmNearestTiesToEven);
    return true;
  }
}

bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) {
  Result = E->getValue();
  return true;
}

bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) {
  Expr* SubExpr = E->getSubExpr();
  
  if (SubExpr->getType()->isIntegralType()) {
    APSInt IntResult;
    if (!EvaluateInteger(SubExpr, IntResult, Info))
      return false;
    Result = HandleIntToFloatCast(E->getType(), SubExpr->getType(), 
                                  IntResult, Info.Ctx);
    return true;
  }
  if (SubExpr->getType()->isRealFloatingType()) {
    if (!Visit(SubExpr))
      return false;
    Result = HandleFloatToFloatCast(E->getType(), SubExpr->getType(),
                                    Result, Info.Ctx);
    return true;
  }
  // FIXME: Handle complex types

  return false;
}

bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
  Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType()));
  return true;
}

//===----------------------------------------------------------------------===//
// Complex Evaluation (for float and integer)
//===----------------------------------------------------------------------===//

namespace {
class VISIBILITY_HIDDEN ComplexExprEvaluator
  : public StmtVisitor<ComplexExprEvaluator, APValue> {
  EvalInfo &Info;
  
public:
  ComplexExprEvaluator(EvalInfo &info) : Info(info) {}
  
  //===--------------------------------------------------------------------===//
  //                            Visitor Methods
  //===--------------------------------------------------------------------===//

  APValue VisitStmt(Stmt *S) {
    return APValue();
  }
    
  APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }

  APValue VisitImaginaryLiteral(ImaginaryLiteral *E) {
    Expr* SubExpr = E->getSubExpr();

    if (SubExpr->getType()->isRealFloatingType()) {
      APFloat Result(0.0);

      if (!EvaluateFloat(SubExpr, Result, Info))
        return APValue();
    
      return APValue(APFloat(Result.getSemantics(), APFloat::fcZero, false), 
                     Result);
    } else {
      assert(SubExpr->getType()->isIntegerType() && 
             "Unexpected imaginary literal.");

      llvm::APSInt Result;
      if (!EvaluateInteger(SubExpr, Result, Info))
        return APValue();
      
      llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
      Zero = 0;
      return APValue(Zero, Result);
    }
  }

  APValue VisitCastExpr(CastExpr *E) {
    Expr* SubExpr = E->getSubExpr();
    QualType EltType = E->getType()->getAsComplexType()->getElementType();
    QualType SubType = SubExpr->getType();

    if (SubType->isRealFloatingType()) {
      APFloat Result(0.0);

      if (!EvaluateFloat(SubExpr, Result, Info))
        return APValue();

      if (EltType->isRealFloatingType()) {
        Result = HandleFloatToFloatCast(EltType, SubType, Result, Info.Ctx);
        return APValue(Result, 
                       APFloat(Result.getSemantics(), APFloat::fcZero, false));
      } else {
        llvm::APSInt IResult;
        IResult = HandleFloatToIntCast(EltType, SubType, Result, Info.Ctx);
        llvm::APSInt Zero(IResult.getBitWidth(), !IResult.isSigned());
        Zero = 0;
        return APValue(IResult, Zero);
      }
    } else if (SubType->isIntegerType()) {
      APSInt Result;

      if (!EvaluateInteger(SubExpr, Result, Info))
        return APValue();

      if (EltType->isRealFloatingType()) {
        APFloat FResult =
            HandleIntToFloatCast(EltType, SubType, Result, Info.Ctx);
        return APValue(FResult, 
                       APFloat(FResult.getSemantics(), APFloat::fcZero, false));
      } else {
        Result = HandleIntToIntCast(EltType, SubType, Result, Info.Ctx);
        llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
        Zero = 0;
        return APValue(Result, Zero);
      }
    } else if (const ComplexType *CT = SubType->getAsComplexType()) {
      APValue Src;

      if (!EvaluateComplex(SubExpr, Src, Info))
        return APValue();

      QualType SrcType = CT->getElementType();

      if (Src.isComplexFloat()) {
        if (EltType->isRealFloatingType()) {
          return APValue(HandleFloatToFloatCast(EltType, SrcType, 
                                                Src.getComplexFloatReal(),
                                                Info.Ctx),
                         HandleFloatToFloatCast(EltType, SrcType, 
                                                Src.getComplexFloatImag(),
                                                Info.Ctx));
        } else {
          return APValue(HandleFloatToIntCast(EltType, SrcType,
                                              Src.getComplexFloatReal(),
                                              Info.Ctx),
                         HandleFloatToIntCast(EltType, SrcType, 
                                              Src.getComplexFloatImag(),
                                              Info.Ctx)); 
        }
      } else {
        assert(Src.isComplexInt() && "Invalid evaluate result.");
        if (EltType->isRealFloatingType()) {
          return APValue(HandleIntToFloatCast(EltType, SrcType, 
                                              Src.getComplexIntReal(),
                                              Info.Ctx),
                         HandleIntToFloatCast(EltType, SrcType, 
                                              Src.getComplexIntImag(),
                                              Info.Ctx));
        } else {
          return APValue(HandleIntToIntCast(EltType, SrcType,
                                            Src.getComplexIntReal(),
                                            Info.Ctx),
                         HandleIntToIntCast(EltType, SrcType, 
                                            Src.getComplexIntImag(),
                                            Info.Ctx)); 
        }
      }
    }

    // FIXME: Handle more casts.
    return APValue();
  }
  
  APValue VisitBinaryOperator(const BinaryOperator *E);
  APValue VisitChooseExpr(const ChooseExpr *E)
    { return Visit(E->getChosenSubExpr(Info.Ctx)); }
  APValue VisitUnaryExtension(const UnaryOperator *E)
    { return Visit(E->getSubExpr()); }
  // FIXME Missing: unary +/-/~, binary div, ImplicitValueInitExpr,
  //                conditional ?:, comma
};
} // end anonymous namespace

static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info)
{
  Result = ComplexExprEvaluator(Info).Visit(const_cast<Expr*>(E));
  assert((!Result.isComplexFloat() ||
          (&Result.getComplexFloatReal().getSemantics() == 
           &Result.getComplexFloatImag().getSemantics())) && 
         "Invalid complex evaluation.");
  return Result.isComplexFloat() || Result.isComplexInt();
}

APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E)
{
  APValue Result, RHS;
  
  if (!EvaluateComplex(E->getLHS(), Result, Info))
    return APValue();
  
  if (!EvaluateComplex(E->getRHS(), RHS, Info))
    return APValue();

  assert(Result.isComplexFloat() == RHS.isComplexFloat() &&
         "Invalid operands to binary operator.");
  switch (E->getOpcode()) {
  default: return APValue();
  case BinaryOperator::Add:
    if (Result.isComplexFloat()) {
      Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
                                       APFloat::rmNearestTiesToEven);
      Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
                                       APFloat::rmNearestTiesToEven);
    } else {
      Result.getComplexIntReal() += RHS.getComplexIntReal();
      Result.getComplexIntImag() += RHS.getComplexIntImag();
    }
    break;
  case BinaryOperator::Sub:
    if (Result.isComplexFloat()) {
      Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
                                            APFloat::rmNearestTiesToEven);
      Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
                                            APFloat::rmNearestTiesToEven);
    } else {
      Result.getComplexIntReal() -= RHS.getComplexIntReal();
      Result.getComplexIntImag() -= RHS.getComplexIntImag();
    }
    break;
  case BinaryOperator::Mul:
    if (Result.isComplexFloat()) {
      APValue LHS = Result;
      APFloat &LHS_r = LHS.getComplexFloatReal();
      APFloat &LHS_i = LHS.getComplexFloatImag();
      APFloat &RHS_r = RHS.getComplexFloatReal();
      APFloat &RHS_i = RHS.getComplexFloatImag();
      
      APFloat Tmp = LHS_r;
      Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
      Result.getComplexFloatReal() = Tmp;
      Tmp = LHS_i;
      Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
      Result.getComplexFloatReal().subtract(Tmp, APFloat::rmNearestTiesToEven);

      Tmp = LHS_r;
      Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
      Result.getComplexFloatImag() = Tmp;
      Tmp = LHS_i;
      Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
      Result.getComplexFloatImag().add(Tmp, APFloat::rmNearestTiesToEven);
    } else {
      APValue LHS = Result;
      Result.getComplexIntReal() = 
        (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
         LHS.getComplexIntImag() * RHS.getComplexIntImag());
      Result.getComplexIntImag() = 
        (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
         LHS.getComplexIntImag() * RHS.getComplexIntReal());
    }
    break;
  }

  return Result;
}

//===----------------------------------------------------------------------===//
// Top level Expr::Evaluate method.
//===----------------------------------------------------------------------===//

/// Evaluate - Return true if this is a constant which we can fold using
/// any crazy technique (that has nothing to do with language standards) that
/// we want to.  If this function returns true, it returns the folded constant
/// in Result.
bool Expr::Evaluate(EvalResult &Result, ASTContext &Ctx) const {
  EvalInfo Info(Ctx, Result);

  if (getType()->isVectorType()) {
    if (!EvaluateVector(this, Result.Val, Info))
      return false;
  } else if (getType()->isIntegerType()) {
    if (!IntExprEvaluator(Info, Result.Val).Visit(const_cast<Expr*>(this)))
      return false;
  } else if (getType()->hasPointerRepresentation()) {
    if (!EvaluatePointer(this, Result.Val, Info))
      return false;
  } else if (getType()->isRealFloatingType()) {
    llvm::APFloat f(0.0);
    if (!EvaluateFloat(this, f, Info))
      return false;
    
    Result.Val = APValue(f);
  } else if (getType()->isAnyComplexType()) {
    if (!EvaluateComplex(this, Result.Val, Info))
      return false;
  } else
    return false;

  return true;
}

bool Expr::EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const {
  EvalInfo Info(Ctx, Result);

  return EvaluateLValue(this, Result.Val, Info) && !Result.HasSideEffects;
}

/// isEvaluatable - Call Evaluate to see if this expression can be constant
/// folded, but discard the result.
bool Expr::isEvaluatable(ASTContext &Ctx) const {
  EvalResult Result;
  return Evaluate(Result, Ctx) && !Result.HasSideEffects;
}

APSInt Expr::EvaluateAsInt(ASTContext &Ctx) const {
  EvalResult EvalResult;
  bool Result = Evaluate(EvalResult, Ctx);
  Result = Result;
  assert(Result && "Could not evaluate expression");
  assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer");

  return EvalResult.Val.getInt();
}
