Index: include/clang/Lex/PPConditionalDirectiveRecord.h
===================================================================
--- include/clang/Lex/PPConditionalDirectiveRecord.h	(revision 186327)
+++ include/clang/Lex/PPConditionalDirectiveRecord.h	(working copy)
@@ -86,9 +86,11 @@
   SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
 
 private:
-  virtual void If(SourceLocation Loc, SourceRange ConditionRange);
+  virtual void If(SourceLocation Loc, SourceRange ConditionRange,
+            SmallVectorImpl<Token> &ConditionTokens, bool ConditionResult);
   virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
-                    SourceLocation IfLoc);
+            SmallVectorImpl<Token> &ConditionTokens, bool ConditionResult,
+            SourceLocation IfLoc);
   virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
                      const MacroDirective *MD);
   virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
Index: include/clang/Lex/PPCallbacks.h
===================================================================
--- include/clang/Lex/PPCallbacks.h	(revision 186327)
+++ include/clang/Lex/PPCallbacks.h	(working copy)
@@ -243,18 +243,23 @@
   /// \brief Hook called whenever an \#if is seen.
   /// \param Loc the source location of the directive.
   /// \param ConditionRange The SourceRange of the expression being tested.
-  ///
-  // FIXME: better to pass in a list (or tree!) of Tokens.
-  virtual void If(SourceLocation Loc, SourceRange ConditionRange) {
+  /// \param ConditionTokens The tokens (after expansion) for the condition
+  ///   expression.
+  /// \param ConditionResult The evaluated value of the codition expression.
+  virtual void If(SourceLocation Loc, SourceRange ConditionRange,
+            SmallVectorImpl<Token> &ConditionTokens, bool ConditionResult) {
   }
 
   /// \brief Hook called whenever an \#elif is seen.
   /// \param Loc the source location of the directive.
   /// \param ConditionRange The SourceRange of the expression being tested.
+  /// \param ConditionTokens The tokens (after expansion) for the condition
+  ///   expression.
+  /// \param ConditionResult The evaluated value of the codition expression.
   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
-  // FIXME: better to pass in a list (or tree!) of Tokens.
   virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
-                    SourceLocation IfLoc) {
+                SmallVectorImpl<Token> &ConditionTokens, bool ConditionResult,
+                SourceLocation IfLoc) {
   }
 
   /// \brief Hook called whenever an \#ifdef is seen.
@@ -418,16 +423,18 @@
   }
 
   /// \brief Hook called whenever an \#if is seen.
-  virtual void If(SourceLocation Loc, SourceRange ConditionRange) {
-    First->If(Loc, ConditionRange);
-    Second->If(Loc, ConditionRange);
+  virtual void If(SourceLocation Loc, SourceRange ConditionRange,
+            SmallVectorImpl<Token> &ConditionTokens, bool ConditionResult) {
+    First->If(Loc, ConditionRange, ConditionTokens, ConditionResult);
+    Second->If(Loc, ConditionRange, ConditionTokens, ConditionResult);
   }
 
   /// \brief Hook called whenever an \#if is seen.
   virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
-                    SourceLocation IfLoc) {
-    First->Elif(Loc, ConditionRange, IfLoc);
-    Second->Elif(Loc, ConditionRange, IfLoc);
+              SmallVectorImpl<Token> &ConditionTokens, bool ConditionResult,
+              SourceLocation IfLoc) {
+    First->Elif(Loc, ConditionRange, ConditionTokens, ConditionResult, IfLoc);
+    Second->Elif(Loc, ConditionRange, ConditionTokens, ConditionResult, IfLoc);
   }
 
   /// \brief Hook called whenever an \#ifdef is seen.
Index: include/clang/Lex/Preprocessor.h
===================================================================
--- include/clang/Lex/Preprocessor.h	(revision 186327)
+++ include/clang/Lex/Preprocessor.h	(working copy)
@@ -296,6 +296,10 @@
   /// encountered (e.g. a file is \#included, etc).
   PPCallbacks *Callbacks;
 
+  /// \brief Token collection vector.
+  /// Used by the Callbacks mechanism.
+  OwningPtr<SmallVectorImpl<Token> > TokenCollectionBuffer;
+
   struct MacroExpandsInfo {
     Token Tok;
     MacroDirective *MD;
@@ -779,6 +783,45 @@
     while (Result.getKind() == tok::comment);
   }
 
+  /// LexNonCommentTracked - Lex a token (with optional token collection).
+  /// If it's a comment, keep lexing until we get
+  /// something not a comment.  This is useful in -E -C mode where comments
+  /// would foul up preprocessor directive handling.
+  void LexNonCommentTracked(Token &Result) {
+    do
+      Lex(Result);
+    while (Result.getKind() == tok::comment);
+    if (TokenCollectionBuffer)
+      TokenCollectionBuffer->push_back(Result);
+  }
+
+  /// LexUnexpandedTokenTracked - This is just like Lex, but this disables
+  /// macro expansion of identifier tokens, and optionally includes token
+  /// collection.
+  void LexUnexpandedTokenTracked(Token &Result) {
+    // Disable macro expansion.
+    bool OldVal = DisableMacroExpansion;
+    DisableMacroExpansion = true;
+    // Lex the token.
+    Lex(Result);
+
+    // Reenable it.
+    DisableMacroExpansion = OldVal;
+    if (TokenCollectionBuffer)
+      TokenCollectionBuffer->push_back(Result);
+  }
+
+  /// LexUnexpandedNonCommentTracked - Like LexNonComment, but this disables
+  /// macro expansion of identifier tokens, and optionally includes token
+  /// collection.
+  void LexUnexpandedNonCommentTracked(Token &Result) {
+    do
+      LexUnexpandedToken(Result);
+    while (Result.getKind() == tok::comment);
+    if (TokenCollectionBuffer)
+      TokenCollectionBuffer->push_back(Result);
+  }
+
   /// Disables macro expansion everywhere except for preprocessor directives.
   void SetMacroExpansionOnlyInDirectives() {
     DisableMacroExpansion = true;
Index: lib/Lex/PPDirectives.cpp
===================================================================
--- lib/Lex/PPDirectives.cpp	(revision 186327)
+++ lib/Lex/PPDirectives.cpp	(working copy)
@@ -430,6 +430,7 @@
           if (Callbacks)
             Callbacks->Elif(Tok.getLocation(),
                             SourceRange(ConditionalBegin, ConditionalEnd),
+                            *TokenCollectionBuffer, ShouldEnter,
                             CondInfo.IfLoc);
           break;
         }
@@ -2181,7 +2182,8 @@
 
   if (Callbacks)
     Callbacks->If(IfToken.getLocation(),
-                  SourceRange(ConditionalBegin, ConditionalEnd));
+                  SourceRange(ConditionalBegin, ConditionalEnd),
+                  *TokenCollectionBuffer, ConditionalTrue);
 
   // Should we include the stuff contained by this directive?
   if (ConditionalTrue) {
@@ -2277,7 +2279,8 @@
   
   if (Callbacks)
     Callbacks->Elif(ElifToken.getLocation(),
-                    SourceRange(ConditionalBegin, ConditionalEnd), CI.IfLoc);
+                    SourceRange(ConditionalBegin, ConditionalEnd),
+                    *TokenCollectionBuffer, true, CI.IfLoc);
 
   // Finally, skip the rest of the contents of this block.
   SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
Index: lib/Lex/PPConditionalDirectiveRecord.cpp
===================================================================
--- lib/Lex/PPConditionalDirectiveRecord.cpp	(revision 186327)
+++ lib/Lex/PPConditionalDirectiveRecord.cpp	(working copy)
@@ -76,7 +76,9 @@
 }
 
 void PPConditionalDirectiveRecord::If(SourceLocation Loc,
-                                      SourceRange ConditionRange) {
+                                      SourceRange ConditionRange,
+                                      SmallVectorImpl<Token> &ConditionTokens,
+                                      bool ConditionResult) {
   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
   CondDirectiveStack.push_back(Loc);
 }
@@ -96,8 +98,10 @@
 }
 
 void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
-                                        SourceRange ConditionRange,
-                                        SourceLocation IfLoc) {
+                                      SourceRange ConditionRange,
+                                      SmallVectorImpl<Token> &ConditionTokens,
+                                      bool ConditionResult,
+                                      SourceLocation IfLoc) {
   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
   CondDirectiveStack.back() = Loc;
 }
Index: lib/Lex/PPExpressions.cpp
===================================================================
--- lib/Lex/PPExpressions.cpp	(revision 186327)
+++ lib/Lex/PPExpressions.cpp	(working copy)
@@ -85,21 +85,21 @@
   Result.setBegin(PeekTok.getLocation());
 
   // Get the next token, don't expand it.
-  PP.LexUnexpandedNonComment(PeekTok);
+  PP.LexUnexpandedNonCommentTracked(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.LexUnexpandedNonComment(PeekTok);
+    PP.LexUnexpandedNonCommentTracked(PeekTok);
   }
 
   if (PeekTok.is(tok::code_completion)) {
     if (PP.getCodeCompletionHandler())
       PP.getCodeCompletionHandler()->CodeCompleteMacroName(false);
     PP.setCodeCompletionReached();
-    PP.LexUnexpandedNonComment(PeekTok);
+    PP.LexUnexpandedNonCommentTracked(PeekTok);
   }
   
   // If we don't have a pp-identifier now, this is an error.
@@ -132,7 +132,7 @@
   if (LParenLoc.isValid()) {
     // Consume identifier.
     Result.setEnd(PeekTok.getLocation());
-    PP.LexUnexpandedNonComment(PeekTok);
+    PP.LexUnexpandedNonCommentTracked(PeekTok);
 
     if (PeekTok.isNot(tok::r_paren)) {
       PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen) << "defined";
@@ -141,11 +141,11 @@
     }
     // Consume the ).
     Result.setEnd(PeekTok.getLocation());
-    PP.LexNonComment(PeekTok);
+    PP.LexNonCommentTracked(PeekTok);
   } else {
     // Consume identifier.
     Result.setEnd(PeekTok.getLocation());
-    PP.LexNonComment(PeekTok);
+    PP.LexNonCommentTracked(PeekTok);
   }
 
   // Success, remember that we saw defined(X).
@@ -170,7 +170,7 @@
     if (PP.getCodeCompletionHandler())
       PP.getCodeCompletionHandler()->CodeCompletePreprocessorExpression();
     PP.setCodeCompletionReached();
-    PP.LexNonComment(PeekTok);
+    PP.LexNonCommentTracked(PeekTok);
   }
       
   // If this token's spelling is a pp-identifier, check to see if it is
@@ -192,7 +192,7 @@
     Result.Val = II->getTokenID() == tok::kw_true;
     Result.Val.setIsUnsigned(false);  // "0" is signed intmax_t 0.
     Result.setRange(PeekTok.getLocation());
-    PP.LexNonComment(PeekTok);
+    PP.LexNonCommentTracked(PeekTok);
     return false;
   }
 
@@ -261,7 +261,7 @@
 
     // Consume the token.
     Result.setRange(PeekTok.getLocation());
-    PP.LexNonComment(PeekTok);
+    PP.LexNonCommentTracked(PeekTok);
     return false;
   }
   case tok::char_constant:          // 'x'
@@ -315,12 +315,12 @@
 
     // Consume the token.
     Result.setRange(PeekTok.getLocation());
-    PP.LexNonComment(PeekTok);
+    PP.LexNonCommentTracked(PeekTok);
     return false;
   }
   case tok::l_paren: {
     SourceLocation Start = PeekTok.getLocation();
-    PP.LexNonComment(PeekTok);  // Eat the (.
+    PP.LexNonCommentTracked(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;
@@ -343,20 +343,20 @@
       DT.State = DefinedTracker::Unknown;
     }
     Result.setRange(Start, PeekTok.getLocation());
-    PP.LexNonComment(PeekTok);  // Eat the ).
+    PP.LexNonCommentTracked(PeekTok);  // Eat the ).
     return false;
   }
   case tok::plus: {
     SourceLocation Start = PeekTok.getLocation();
     // Unary plus doesn't modify the value.
-    PP.LexNonComment(PeekTok);
+    PP.LexNonCommentTracked(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);
+    PP.LexNonCommentTracked(PeekTok);
     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
     Result.setBegin(Loc);
 
@@ -376,7 +376,7 @@
 
   case tok::tilde: {
     SourceLocation Start = PeekTok.getLocation();
-    PP.LexNonComment(PeekTok);
+    PP.LexNonCommentTracked(PeekTok);
     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
     Result.setBegin(Start);
 
@@ -388,7 +388,7 @@
 
   case tok::exclaim: {
     SourceLocation Start = PeekTok.getLocation();
-    PP.LexNonComment(PeekTok);
+    PP.LexNonCommentTracked(PeekTok);
     if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
     Result.setBegin(Start);
     Result.Val = !Result.Val;
@@ -485,7 +485,7 @@
 
     // Consume the operator, remembering the operator's location for reporting.
     SourceLocation OpLoc = PeekTok.getLocation();
-    PP.LexNonComment(PeekTok);
+    PP.LexNonCommentTracked(PeekTok);
 
     PPValue RHS(LHS.getBitWidth());
     // Parse the RHS of the operator.
@@ -681,7 +681,7 @@
         return true;
       }
       // Consume the :.
-      PP.LexNonComment(PeekTok);
+      PP.LexNonCommentTracked(PeekTok);
 
       // Evaluate the value after the :.
       bool AfterColonLive = ValueLive && LHS.Val == 0;
@@ -740,10 +740,16 @@
   // expression.
   bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
   DisableMacroExpansion = false;
+
+  if (Callbacks) {
+    if (!TokenCollectionBuffer)
+      TokenCollectionBuffer.reset(new SmallVector<Token, 8>());
+    TokenCollectionBuffer->clear();
+  }
   
   // Peek ahead one token.
   Token Tok;
-  LexNonComment(Tok);
+  LexNonCommentTracked(Tok);
   
   // C99 6.10.1p3 - All expressions are evaluated as intmax_t or uintmax_t.
   unsigned BitWidth = getTargetInfo().getIntMaxTWidth();
