diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
new file mode 100644
index 0000000..2a6b2a7
--- /dev/null
+++ b/lib/Lex/PPExpressions.cpp
@@ -0,0 +1,745 @@
+//===--- PPExpressions.cpp - Preprocessor Expression Evaluation -----------===//
+//
+//                     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 Preprocessor::EvaluateDirectiveExpression method,
+// which parses and evaluates integer constant expressions for #if directives.
+//
+//===----------------------------------------------------------------------===//
+//
+// FIXME: implement testing for #assert's.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/LiteralSupport.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "llvm/ADT/APSInt.h"
+using namespace clang;
+
+/// PPValue - Represents the value of a subexpression of a preprocessor
+/// conditional and the source range covered by it.
+class PPValue {
+  SourceRange Range;
+public:
+  llvm::APSInt Val;
+
+  // Default ctor - Construct an 'invalid' PPValue.
+  PPValue(unsigned BitWidth) : Val(BitWidth) {}
+
+  unsigned getBitWidth() const { return Val.getBitWidth(); }
+  bool isUnsigned() const { return Val.isUnsigned(); }
+
+  const SourceRange &getRange() const { return Range; }
+
+  void setRange(SourceLocation L) { Range.setBegin(L); Range.setEnd(L); }
+  void setRange(SourceLocation B, SourceLocation E) {
+    Range.setBegin(B); Range.setEnd(E);
+  }
+  void setBegin(SourceLocation L) { Range.setBegin(L); }
+  void setEnd(SourceLocation L) { Range.setEnd(L); }
+};
+
+static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
+                                     Token &PeekTok, bool ValueLive,
+                                     Preprocessor &PP);
+
+/// DefinedTracker - This struct is used while parsing expressions to keep track
+/// of whether !defined(X) has been seen.
+///
+/// With this simple scheme, we handle the basic forms:
+///    !defined(X)   and !defined X
+/// but we also trivially handle (silly) stuff like:
+///    !!!defined(X) and +!defined(X) and !+!+!defined(X) and !(defined(X)).
+struct DefinedTracker {
+  /// Each time a Value is evaluated, it returns information about whether the
+  /// parsed value is of the form defined(X), !defined(X) or is something else.
+  enum TrackerState {
+    DefinedMacro,        // defined(X)
+    NotDefinedMacro,     // !defined(X)
+    Unknown              // Something else.
+  } State;
+  /// TheMacro - When the state is DefinedMacro or NotDefinedMacro, this
+  /// indicates the macro that was checked.
+  IdentifierInfo *TheMacro;
+};
+
+/// EvaluateDefined - Process a 'defined(sym)' expression.
+static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
+                            bool ValueLive, Preprocessor &PP) {
+  IdentifierInfo *II;
+  Result.setBegin(PeekTok.getLocation());
+
+  // Get the next token, don't expand it.
+  PP.LexUnexpandedToken(PeekTok);
+
+  // Two options, it can either be a pp-identifier or a (.
+  SourceLocation LParenLoc;
+  if (PeekTok.is(tok::l_paren)) {
+    // Found a paren, remember we saw it and skip it.
+    LParenLoc = PeekTok.getLocation();
+    PP.LexUnexpandedToken(PeekTok);
+  }
+
+  // If we don't have a pp-identifier now, this is an error.
+  if ((II = PeekTok.getIdentifierInfo()) == 0) {
+    PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier);
+    return true;
+  }
+
+  // Otherwise, we got an identifier, is it defined to something?
+  Result.Val = II->hasMacroDefinition();
+  Result.Val.setIsUnsigned(false);  // Result is signed intmax_t.
+
+  // If there is a macro, mark it used.
+  if (Result.Val != 0 && ValueLive) {
+    MacroInfo *Macro = PP.getMacroInfo(II);
+    Macro->setIsUsed(true);
+  }
+
+  // Consume identifier.
+  Result.setEnd(PeekTok.getLocation());
+  PP.LexNonComment(PeekTok);
+
+  // If we are in parens, ensure we have a trailing ).
+  if (LParenLoc.isValid()) {
+    if (PeekTok.isNot(tok::r_paren)) {
+      PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen) << "defined";
+      PP.Diag(LParenLoc, diag::note_matching) << "(";
+      return true;
+    }
+    // Consume the ).
+    Result.setEnd(PeekTok.getLocation());
+    PP.LexNonComment(PeekTok);
+  }
+
+  // Success, remember that we saw defined(X).
+  DT.State = DefinedTracker::DefinedMacro;
+  DT.TheMacro = II;
+  return false;
+}
+
+/// EvaluateValue - Evaluate the token PeekTok (and any others needed) and
+/// return the computed value in Result.  Return true if there was an error
+/// parsing.  This function also returns information about the form of the
+/// expression in DT.  See above for information on what DT means.
+///
+/// If ValueLive is false, then this value is being evaluated in a context where
+/// the result is not used.  As such, avoid diagnostics that relate to
+/// evaluation.
+static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
+                          bool ValueLive, Preprocessor &PP) {
+  DT.State = DefinedTracker::Unknown;
+
+  // If this token's spelling is a pp-identifier, check to see if it is
+  // 'defined' or if it is a macro.  Note that we check here because many
+  // keywords are pp-identifiers, so we can't check the kind.
+  if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
+    // Handle "defined X" and "defined(X)".
+    if (II->isStr("defined"))
+      return(EvaluateDefined(Result, PeekTok, DT, ValueLive, PP));
+    
+    // If this identifier isn't 'defined' or one of the special
+    // preprocessor keywords and it wasn't macro expanded, it turns
+    // into a simple 0, unless it is the C++ keyword "true", in which case it
+    // turns into "1".
+    if (ValueLive)
+      PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
+    Result.Val = II->getTokenID() == tok::kw_true;
+    Result.Val.setIsUnsigned(false);  // "0" is signed intmax_t 0.
+    Result.setRange(PeekTok.getLocation());
+    PP.LexNonComment(PeekTok);
+    return false;
+  }
+
+  switch (PeekTok.getKind()) {
+  default:  // Non-value token.
+    PP.Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
+    return true;
+  case tok::eom:
+  case tok::r_paren:
+    // If there is no expression, report and exit.
+    PP.Diag(PeekTok, diag::err_pp_expected_value_in_expr);
+    return true;
+  case tok::numeric_constant: {
+    llvm::SmallString<64> IntegerBuffer;
+    IntegerBuffer.resize(PeekTok.getLength());
+    const char *ThisTokBegin = &IntegerBuffer[0];
+    unsigned ActualLength = PP.getSpelling(PeekTok, ThisTokBegin);
+    NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
+                                 PeekTok.getLocation(), PP);
+    if (Literal.hadError)
+      return true; // a diagnostic was already reported.
+
+    if (Literal.isFloatingLiteral() || Literal.isImaginary) {
+      PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);
+      return true;
+    }
+    assert(Literal.isIntegerLiteral() && "Unknown ppnumber");
+
+    // long long is a C99 feature.
+    if (!PP.getLangOptions().C99 && !PP.getLangOptions().CPlusPlus0x
+        && Literal.isLongLong)
+      PP.Diag(PeekTok, diag::ext_longlong);
+
+    // Parse the integer literal into Result.
+    if (Literal.GetIntegerValue(Result.Val)) {
+      // Overflow parsing integer literal.
+      if (ValueLive) PP.Diag(PeekTok, diag::warn_integer_too_large);
+      Result.Val.setIsUnsigned(true);
+    } else {
+      // Set the signedness of the result to match whether there was a U suffix
+      // or not.
+      Result.Val.setIsUnsigned(Literal.isUnsigned);
+
+      // Detect overflow based on whether the value is signed.  If signed
+      // and if the value is too large, emit a warning "integer constant is so
+      // large that it is unsigned" e.g. on 12345678901234567890 where intmax_t
+      // is 64-bits.
+      if (!Literal.isUnsigned && Result.Val.isNegative()) {
+        // Don't warn for a hex literal: 0x8000..0 shouldn't warn.
+        if (ValueLive && Literal.getRadix() != 16)
+          PP.Diag(PeekTok, diag::warn_integer_too_large_for_signed);
+        Result.Val.setIsUnsigned(true);
+      }
+    }
+
+    // Consume the token.
+    Result.setRange(PeekTok.getLocation());
+    PP.LexNonComment(PeekTok);
+    return false;
+  }
+  case tok::char_constant: {   // 'x'
+    llvm::SmallString<32> CharBuffer;
+    CharBuffer.resize(PeekTok.getLength());
+    const char *ThisTokBegin = &CharBuffer[0];
+    unsigned ActualLength = PP.getSpelling(PeekTok, ThisTokBegin);
+    CharLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
+                              PeekTok.getLocation(), PP);
+    if (Literal.hadError())
+      return true;  // A diagnostic was already emitted.
+
+    // Character literals are always int or wchar_t, expand to intmax_t.
+    const TargetInfo &TI = PP.getTargetInfo();
+    unsigned NumBits;
+    if (Literal.isMultiChar())
+      NumBits = TI.getIntWidth();
+    else if (Literal.isWide())
+      NumBits = TI.getWCharWidth();
+    else
+      NumBits = TI.getCharWidth();
+
+    // Set the width.
+    llvm::APSInt Val(NumBits);
+    // Set the value.
+    Val = Literal.getValue();
+    // Set the signedness.
+    Val.setIsUnsigned(!PP.getLangOptions().CharIsSigned);
+
+    if (Result.Val.getBitWidth() > Val.getBitWidth()) {
+      Result.Val = Val.extend(Result.Val.getBitWidth());
+    } else {
+      assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
+             "intmax_t smaller than char/wchar_t?");
+      Result.Val = Val;
+    }
+
+    // Consume the token.
+    Result.setRange(PeekTok.getLocation());
+    PP.LexNonComment(PeekTok);
+    return false;
+  }
+  case tok::l_paren: {
+    SourceLocation Start = PeekTok.getLocation();
+    PP.LexNonComment(PeekTok);  // Eat the (.
+    // Parse the value and if there are any binary operators involved, parse
+    // them.
+    if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
+
+    // If this is a silly value like (X), which doesn't need parens, check for
+    // !(defined X).
+    if (PeekTok.is(tok::r_paren)) {
+      // Just use DT unmodified as our result.
+    } else {
+      // Otherwise, we have something like (x+y), and we consumed '(x'.
+      if (EvaluateDirectiveSubExpr(Result, 1, PeekTok, ValueLive, PP))
+        return true;
+
+      if (PeekTok.isNot(tok::r_paren)) {
+        PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_rparen)
+          << Result.getRange();
+        PP.Diag(Start, diag::note_matching) << "(";
+        return true;
+      }
+      DT.State = DefinedTracker::Unknown;
+    }
+    Result.setRange(Start, PeekTok.getLocation());
+    PP.LexNonComment(PeekTok);  // Eat the ).
+    return false;
+  }
+  case tok::plus: {
+    SourceLocation Start = PeekTok.getLocation();
+    // Unary plus doesn't modify the value.
+    PP.LexNonComment(PeekTok);
+    if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
+    Result.setBegin(Start);
+    return false;
+  }
+  case tok::minus: {
+    SourceLocation Loc = PeekTok.getLocation();
+    PP.LexNonComment(PeekTok);
+    if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
+    Result.setBegin(Loc);
+
+    // C99 6.5.3.3p3: The sign of the result matches the sign of the operand.
+    Result.Val = -Result.Val;
+
+    // -MININT is the only thing that overflows.  Unsigned never overflows.
+    bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
+
+    // If this operator is live and overflowed, report the issue.
+    if (Overflow && ValueLive)
+      PP.Diag(Loc, diag::warn_pp_expr_overflow) << Result.getRange();
+
+    DT.State = DefinedTracker::Unknown;
+    return false;
+  }
+
+  case tok::tilde: {
+    SourceLocation Start = PeekTok.getLocation();
+    PP.LexNonComment(PeekTok);
+    if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
+    Result.setBegin(Start);
+
+    // C99 6.5.3.3p4: The sign of the result matches the sign of the operand.
+    Result.Val = ~Result.Val;
+    DT.State = DefinedTracker::Unknown;
+    return false;
+  }
+
+  case tok::exclaim: {
+    SourceLocation Start = PeekTok.getLocation();
+    PP.LexNonComment(PeekTok);
+    if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
+    Result.setBegin(Start);
+    Result.Val = !Result.Val;
+    // C99 6.5.3.3p5: The sign of the result is 'int', aka it is signed.
+    Result.Val.setIsUnsigned(false);
+
+    if (DT.State == DefinedTracker::DefinedMacro)
+      DT.State = DefinedTracker::NotDefinedMacro;
+    else if (DT.State == DefinedTracker::NotDefinedMacro)
+      DT.State = DefinedTracker::DefinedMacro;
+    return false;
+  }
+
+  // FIXME: Handle #assert
+  }
+}
+
+
+
+/// getPrecedence - Return the precedence of the specified binary operator
+/// token.  This returns:
+///   ~0 - Invalid token.
+///   14 -> 3 - various operators.
+///    0 - 'eom' or ')'
+static unsigned getPrecedence(tok::TokenKind Kind) {
+  switch (Kind) {
+  default: return ~0U;
+  case tok::percent:
+  case tok::slash:
+  case tok::star:                 return 14;
+  case tok::plus:
+  case tok::minus:                return 13;
+  case tok::lessless:
+  case tok::greatergreater:       return 12;
+  case tok::lessequal:
+  case tok::less:
+  case tok::greaterequal:
+  case tok::greater:              return 11;
+  case tok::exclaimequal:
+  case tok::equalequal:           return 10;
+  case tok::amp:                  return 9;
+  case tok::caret:                return 8;
+  case tok::pipe:                 return 7;
+  case tok::ampamp:               return 6;
+  case tok::pipepipe:             return 5;
+  case tok::question:             return 4;
+  case tok::comma:                return 3;
+  case tok::colon:                return 2;
+  case tok::r_paren:              return 0;   // Lowest priority, end of expr.
+  case tok::eom:                  return 0;   // Lowest priority, end of macro.
+  }
+}
+
+
+/// EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is
+/// PeekTok, and whose precedence is PeekPrec.  This returns the result in LHS.
+///
+/// If ValueLive is false, then this value is being evaluated in a context where
+/// the result is not used.  As such, avoid diagnostics that relate to
+/// evaluation, such as division by zero warnings.
+static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
+                                     Token &PeekTok, bool ValueLive,
+                                     Preprocessor &PP) {
+  unsigned PeekPrec = getPrecedence(PeekTok.getKind());
+  // If this token isn't valid, report the error.
+  if (PeekPrec == ~0U) {
+    PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop)
+      << LHS.getRange();
+    return true;
+  }
+
+  while (1) {
+    // If this token has a lower precedence than we are allowed to parse, return
+    // it so that higher levels of the recursion can parse it.
+    if (PeekPrec < MinPrec)
+      return false;
+
+    tok::TokenKind Operator = PeekTok.getKind();
+
+    // If this is a short-circuiting operator, see if the RHS of the operator is
+    // dead.  Note that this cannot just clobber ValueLive.  Consider
+    // "0 && 1 ? 4 : 1 / 0", which is parsed as "(0 && 1) ? 4 : (1 / 0)".  In
+    // this example, the RHS of the && being dead does not make the rest of the
+    // expr dead.
+    bool RHSIsLive;
+    if (Operator == tok::ampamp && LHS.Val == 0)
+      RHSIsLive = false;   // RHS of "0 && x" is dead.
+    else if (Operator == tok::pipepipe && LHS.Val != 0)
+      RHSIsLive = false;   // RHS of "1 || x" is dead.
+    else if (Operator == tok::question && LHS.Val == 0)
+      RHSIsLive = false;   // RHS (x) of "0 ? x : y" is dead.
+    else
+      RHSIsLive = ValueLive;
+
+    // Consume the operator, remembering the operator's location for reporting.
+    SourceLocation OpLoc = PeekTok.getLocation();
+    PP.LexNonComment(PeekTok);
+
+    PPValue RHS(LHS.getBitWidth());
+    // Parse the RHS of the operator.
+    DefinedTracker DT;
+    if (EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP)) return true;
+
+    // Remember the precedence of this operator and get the precedence of the
+    // operator immediately to the right of the RHS.
+    unsigned ThisPrec = PeekPrec;
+    PeekPrec = getPrecedence(PeekTok.getKind());
+
+    // If this token isn't valid, report the error.
+    if (PeekPrec == ~0U) {
+      PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop)
+        << RHS.getRange();
+      return true;
+    }
+
+    // Decide whether to include the next binop in this subexpression.  For
+    // example, when parsing x+y*z and looking at '*', we want to recursively
+    // handle y*z as a single subexpression.  We do this because the precedence
+    // of * is higher than that of +.  The only strange case we have to handle
+    // here is for the ?: operator, where the precedence is actually lower than
+    // the LHS of the '?'.  The grammar rule is:
+    //
+    // conditional-expression ::=
+    //    logical-OR-expression ? expression : conditional-expression
+    // where 'expression' is actually comma-expression.
+    unsigned RHSPrec;
+    if (Operator == tok::question)
+      // The RHS of "?" should be maximally consumed as an expression.
+      RHSPrec = getPrecedence(tok::comma);
+    else  // All others should munch while higher precedence.
+      RHSPrec = ThisPrec+1;
+
+    if (PeekPrec >= RHSPrec) {
+      if (EvaluateDirectiveSubExpr(RHS, RHSPrec, PeekTok, RHSIsLive, PP))
+        return true;
+      PeekPrec = getPrecedence(PeekTok.getKind());
+    }
+    assert(PeekPrec <= ThisPrec && "Recursion didn't work!");
+
+    // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
+    // either operand is unsigned.
+    llvm::APSInt Res(LHS.getBitWidth());
+    switch (Operator) {
+    case tok::question:       // No UAC for x and y in "x ? y : z".
+    case tok::lessless:       // Shift amount doesn't UAC with shift value.
+    case tok::greatergreater: // Shift amount doesn't UAC with shift value.
+    case tok::comma:          // Comma operands are not subject to UACs.
+    case tok::pipepipe:       // Logical || does not do UACs.
+    case tok::ampamp:         // Logical && does not do UACs.
+      break;                  // No UAC
+    default:
+      Res.setIsUnsigned(LHS.isUnsigned()|RHS.isUnsigned());
+      // If this just promoted something from signed to unsigned, and if the
+      // value was negative, warn about it.
+      if (ValueLive && Res.isUnsigned()) {
+        if (!LHS.isUnsigned() && LHS.Val.isNegative())
+          PP.Diag(OpLoc, diag::warn_pp_convert_lhs_to_positive)
+            << LHS.Val.toString(10, true) + " to " +
+               LHS.Val.toString(10, false)
+            << LHS.getRange() << RHS.getRange();
+        if (!RHS.isUnsigned() && RHS.Val.isNegative())
+          PP.Diag(OpLoc, diag::warn_pp_convert_rhs_to_positive)
+            << RHS.Val.toString(10, true) + " to " +
+               RHS.Val.toString(10, false)
+            << LHS.getRange() << RHS.getRange();
+      }
+      LHS.Val.setIsUnsigned(Res.isUnsigned());
+      RHS.Val.setIsUnsigned(Res.isUnsigned());
+    }
+
+    // FIXME: All of these should detect and report overflow??
+    bool Overflow = false;
+    switch (Operator) {
+    default: assert(0 && "Unknown operator token!");
+    case tok::percent:
+      if (RHS.Val != 0)
+        Res = LHS.Val % RHS.Val;
+      else if (ValueLive) {
+        PP.Diag(OpLoc, diag::err_pp_remainder_by_zero)
+          << LHS.getRange() << RHS.getRange();
+        return true;
+      }
+      break;
+    case tok::slash:
+      if (RHS.Val != 0) {
+        Res = LHS.Val / RHS.Val;
+        if (LHS.Val.isSigned())   // MININT/-1  -->  overflow.
+          Overflow = LHS.Val.isMinSignedValue() && RHS.Val.isAllOnesValue();
+      } else if (ValueLive) {
+        PP.Diag(OpLoc, diag::err_pp_division_by_zero)
+          << LHS.getRange() << RHS.getRange();
+        return true;
+      }
+      break;
+
+    case tok::star:
+      Res = LHS.Val * RHS.Val;
+      if (Res.isSigned() && LHS.Val != 0 && RHS.Val != 0)
+        Overflow = Res/RHS.Val != LHS.Val || Res/LHS.Val != RHS.Val;
+      break;
+    case tok::lessless: {
+      // Determine whether overflow is about to happen.
+      unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
+      if (ShAmt >= LHS.Val.getBitWidth())
+        Overflow = true, ShAmt = LHS.Val.getBitWidth()-1;
+      else if (LHS.isUnsigned())
+        Overflow = false;
+      else if (LHS.Val.isNonNegative()) // Don't allow sign change.
+        Overflow = ShAmt >= LHS.Val.countLeadingZeros();
+      else
+        Overflow = ShAmt >= LHS.Val.countLeadingOnes();
+
+      Res = LHS.Val << ShAmt;
+      break;
+    }
+    case tok::greatergreater: {
+      // Determine whether overflow is about to happen.
+      unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
+      if (ShAmt >= LHS.getBitWidth())
+        Overflow = true, ShAmt = LHS.getBitWidth()-1;
+      Res = LHS.Val >> ShAmt;
+      break;
+    }
+    case tok::plus:
+      Res = LHS.Val + RHS.Val;
+      if (LHS.isUnsigned())
+        Overflow = false;
+      else if (LHS.Val.isNonNegative() == RHS.Val.isNonNegative() &&
+               Res.isNonNegative() != LHS.Val.isNonNegative())
+        Overflow = true;  // Overflow for signed addition.
+      break;
+    case tok::minus:
+      Res = LHS.Val - RHS.Val;
+      if (LHS.isUnsigned())
+        Overflow = false;
+      else if (LHS.Val.isNonNegative() != RHS.Val.isNonNegative() &&
+               Res.isNonNegative() != LHS.Val.isNonNegative())
+        Overflow = true;  // Overflow for signed subtraction.
+      break;
+    case tok::lessequal:
+      Res = LHS.Val <= RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
+      break;
+    case tok::less:
+      Res = LHS.Val < RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
+      break;
+    case tok::greaterequal:
+      Res = LHS.Val >= RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
+      break;
+    case tok::greater:
+      Res = LHS.Val > RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.8p6, result is always int (signed)
+      break;
+    case tok::exclaimequal:
+      Res = LHS.Val != RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.9p3, result is always int (signed)
+      break;
+    case tok::equalequal:
+      Res = LHS.Val == RHS.Val;
+      Res.setIsUnsigned(false);  // C99 6.5.9p3, result is always int (signed)
+      break;
+    case tok::amp:
+      Res = LHS.Val & RHS.Val;
+      break;
+    case tok::caret:
+      Res = LHS.Val ^ RHS.Val;
+      break;
+    case tok::pipe:
+      Res = LHS.Val | RHS.Val;
+      break;
+    case tok::ampamp:
+      Res = (LHS.Val != 0 && RHS.Val != 0);
+      Res.setIsUnsigned(false);  // C99 6.5.13p3, result is always int (signed)
+      break;
+    case tok::pipepipe:
+      Res = (LHS.Val != 0 || RHS.Val != 0);
+      Res.setIsUnsigned(false);  // C99 6.5.14p3, result is always int (signed)
+      break;
+    case tok::comma:
+      // Comma is invalid in pp expressions in c89/c++ mode, but is valid in C99
+      // if not being evaluated.
+      if (!PP.getLangOptions().C99 || ValueLive)
+        PP.Diag(OpLoc, diag::ext_pp_comma_expr)
+          << LHS.getRange() << RHS.getRange();
+      Res = RHS.Val; // LHS = LHS,RHS -> RHS.
+      break;
+    case tok::question: {
+      // Parse the : part of the expression.
+      if (PeekTok.isNot(tok::colon)) {
+        PP.Diag(PeekTok.getLocation(), diag::err_expected_colon)
+          << LHS.getRange(), RHS.getRange();
+        PP.Diag(OpLoc, diag::note_matching) << "?";
+        return true;
+      }
+      // Consume the :.
+      PP.LexNonComment(PeekTok);
+
+      // Evaluate the value after the :.
+      bool AfterColonLive = ValueLive && LHS.Val == 0;
+      PPValue AfterColonVal(LHS.getBitWidth());
+      DefinedTracker DT;
+      if (EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
+        return true;
+
+      // Parse anything after the : with the same precedence as ?.  We allow
+      // things of equal precedence because ?: is right associative.
+      if (EvaluateDirectiveSubExpr(AfterColonVal, ThisPrec,
+                                   PeekTok, AfterColonLive, PP))
+        return true;
+
+      // Now that we have the condition, the LHS and the RHS of the :, evaluate.
+      Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
+      RHS.setEnd(AfterColonVal.getRange().getEnd());
+
+      // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
+      // either operand is unsigned.
+      Res.setIsUnsigned(RHS.isUnsigned() | AfterColonVal.isUnsigned());
+
+      // Figure out the precedence of the token after the : part.
+      PeekPrec = getPrecedence(PeekTok.getKind());
+      break;
+    }
+    case tok::colon:
+      // Don't allow :'s to float around without being part of ?: exprs.
+      PP.Diag(OpLoc, diag::err_pp_colon_without_question)
+        << LHS.getRange() << RHS.getRange();
+      return true;
+    }
+
+    // If this operator is live and overflowed, report the issue.
+    if (Overflow && ValueLive)
+      PP.Diag(OpLoc, diag::warn_pp_expr_overflow)
+        << LHS.getRange() << RHS.getRange();
+
+    // Put the result back into 'LHS' for our next iteration.
+    LHS.Val = Res;
+    LHS.setEnd(RHS.getRange().getEnd());
+  }
+
+  return false;
+}
+
+/// EvaluateDirectiveExpression - Evaluate an integer constant expression that
+/// may occur after a #if or #elif directive.  If the expression is equivalent
+/// to "!defined(X)" return X in IfNDefMacro.
+bool Preprocessor::
+EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
+  // Save the current state of 'DisableMacroExpansion' and reset it to false. If
+  // 'DisableMacroExpansion' is true, then we must be in a macro argument list
+  // in which case a directive is undefined behavior.  We want macros to be able
+  // to recursively expand in order to get more gcc-list behavior, so we force
+  // DisableMacroExpansion to false and restore it when we're done parsing the
+  // expression.
+  bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
+  DisableMacroExpansion = false;
+  
+  // Peek ahead one token.
+  Token Tok;
+  Lex(Tok);
+
+  // C99 6.10.1p3 - All expressions are evaluated as intmax_t or uintmax_t.
+  unsigned BitWidth = getTargetInfo().getIntMaxTWidth();
+
+  PPValue ResVal(BitWidth);
+  DefinedTracker DT;
+  if (EvaluateValue(ResVal, Tok, DT, true, *this)) {
+    // Parse error, skip the rest of the macro line.
+    if (Tok.isNot(tok::eom))
+      DiscardUntilEndOfDirective();
+    
+    // Restore 'DisableMacroExpansion'.
+    DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
+    return false;
+  }
+
+  // If we are at the end of the expression after just parsing a value, there
+  // must be no (unparenthesized) binary operators involved, so we can exit
+  // directly.
+  if (Tok.is(tok::eom)) {
+    // If the expression we parsed was of the form !defined(macro), return the
+    // macro in IfNDefMacro.
+    if (DT.State == DefinedTracker::NotDefinedMacro)
+      IfNDefMacro = DT.TheMacro;
+
+    // Restore 'DisableMacroExpansion'.
+    DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
+    return ResVal.Val != 0;
+  }
+
+  // Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the
+  // operator and the stuff after it.
+  if (EvaluateDirectiveSubExpr(ResVal, getPrecedence(tok::question),
+                               Tok, true, *this)) {
+    // Parse error, skip the rest of the macro line.
+    if (Tok.isNot(tok::eom))
+      DiscardUntilEndOfDirective();
+    
+    // Restore 'DisableMacroExpansion'.
+    DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
+    return false;
+  }
+
+  // If we aren't at the tok::eom token, something bad happened, like an extra
+  // ')' token.
+  if (Tok.isNot(tok::eom)) {
+    Diag(Tok, diag::err_pp_expected_eol);
+    DiscardUntilEndOfDirective();
+  }
+
+  // Restore 'DisableMacroExpansion'.
+  DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
+  return ResVal.Val != 0;
+}
+
