diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index a99a52f..01a4784 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -1,1177 +1,1177 @@
-//===--- MacroExpansion.cpp - Top level Macro Expansion -------------------===//
-//
-//                     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 top level handling of macro expasion for the
-// preprocessor.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Lex/Preprocessor.h"
-#include "MacroArgs.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/LexDiagnostic.h"
-#include "clang/Lex/CodeCompletionHandler.h"
-#include "clang/Lex/ExternalPreprocessorSource.h"
-#include "clang/Lex/LiteralSupport.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Config/llvm-config.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <cstdio>
-#include <ctime>
-using namespace clang;
-
-MacroInfo *Preprocessor::getInfoForMacro(IdentifierInfo *II) const {
-  assert(II->hasMacroDefinition() && "Identifier is not a macro!");
-
-  macro_iterator Pos = Macros.find(II);
-  if (Pos == Macros.end()) {
-    // Load this macro from the external source.
-    getExternalSource()->LoadMacroDefinition(II);
-    Pos = Macros.find(II);
-  }
-  assert(Pos != Macros.end() && "Identifier macro info is missing!");
-  assert(Pos->second->getUndefLoc().isInvalid() && "Macro is undefined!");
-  return Pos->second;
-}
-
-/// setMacroInfo - Specify a macro for this identifier.
-///
-void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI,
-                                bool LoadedFromAST) {
-  assert(MI && "MacroInfo should be non-zero!");
-  MI->setPreviousDefinition(Macros[II]);
-  Macros[II] = MI;
-  II->setHasMacroDefinition(true);
-  if (II->isFromAST() && !LoadedFromAST)
-    II->setChangedSinceDeserialization();
-}
-
-/// \brief Undefine a macro for this identifier.
-void Preprocessor::clearMacroInfo(IdentifierInfo *II) {
-  assert(II->hasMacroDefinition() && "Macro is not defined!");
-  assert(Macros[II]->getUndefLoc().isValid() && "Macro is still defined!");
-  II->setHasMacroDefinition(false);
-  if (II->isFromAST())
-    II->setChangedSinceDeserialization();
-}
-
-/// RegisterBuiltinMacro - Register the specified identifier in the identifier
-/// table and mark it as a builtin macro to be expanded.
-static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){
-  // Get the identifier.
-  IdentifierInfo *Id = PP.getIdentifierInfo(Name);
-
-  // Mark it as being a macro that is builtin.
-  MacroInfo *MI = PP.AllocateMacroInfo(SourceLocation());
-  MI->setIsBuiltinMacro();
-  PP.setMacroInfo(Id, MI);
-  return Id;
-}
-
-
-/// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
-/// identifier table.
-void Preprocessor::RegisterBuiltinMacros() {
-  Ident__LINE__ = RegisterBuiltinMacro(*this, "__LINE__");
-  Ident__FILE__ = RegisterBuiltinMacro(*this, "__FILE__");
-  Ident__DATE__ = RegisterBuiltinMacro(*this, "__DATE__");
-  Ident__TIME__ = RegisterBuiltinMacro(*this, "__TIME__");
-  Ident__COUNTER__ = RegisterBuiltinMacro(*this, "__COUNTER__");
-  Ident_Pragma  = RegisterBuiltinMacro(*this, "_Pragma");
-
-  // GCC Extensions.
-  Ident__BASE_FILE__     = RegisterBuiltinMacro(*this, "__BASE_FILE__");
-  Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(*this, "__INCLUDE_LEVEL__");
-  Ident__TIMESTAMP__     = RegisterBuiltinMacro(*this, "__TIMESTAMP__");
-
-  // Clang Extensions.
-  Ident__has_feature      = RegisterBuiltinMacro(*this, "__has_feature");
-  Ident__has_extension    = RegisterBuiltinMacro(*this, "__has_extension");
-  Ident__has_builtin      = RegisterBuiltinMacro(*this, "__has_builtin");
-  Ident__has_attribute    = RegisterBuiltinMacro(*this, "__has_attribute");
-  Ident__has_include      = RegisterBuiltinMacro(*this, "__has_include");
-  Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next");
-  Ident__has_warning      = RegisterBuiltinMacro(*this, "__has_warning");
-
-  // Microsoft Extensions.
-  if (LangOpts.MicrosoftExt) 
-    Ident__pragma = RegisterBuiltinMacro(*this, "__pragma");
-  else
-    Ident__pragma = 0;
-}
-
-/// isTrivialSingleTokenExpansion - Return true if MI, which has a single token
-/// in its expansion, currently expands to that token literally.
-static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
-                                          const IdentifierInfo *MacroIdent,
-                                          Preprocessor &PP) {
-  IdentifierInfo *II = MI->getReplacementToken(0).getIdentifierInfo();
-
-  // If the token isn't an identifier, it's always literally expanded.
-  if (II == 0) return true;
-
-  // If the information about this identifier is out of date, update it from
-  // the external source.
-  if (II->isOutOfDate())
-    PP.getExternalSource()->updateOutOfDateIdentifier(*II);
-
-  // If the identifier is a macro, and if that macro is enabled, it may be
-  // expanded so it's not a trivial expansion.
-  if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled() &&
-      // Fast expanding "#define X X" is ok, because X would be disabled.
-      II != MacroIdent)
-    return false;
-
-  // If this is an object-like macro invocation, it is safe to trivially expand
-  // it.
-  if (MI->isObjectLike()) return true;
-
-  // If this is a function-like macro invocation, it's safe to trivially expand
-  // as long as the identifier is not a macro argument.
-  for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
-       I != E; ++I)
-    if (*I == II)
-      return false;   // Identifier is a macro argument.
-
-  return true;
-}
-
-
-/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
-/// lexed is a '('.  If so, consume the token and return true, if not, this
-/// method should have no observable side-effect on the lexed tokens.
-bool Preprocessor::isNextPPTokenLParen() {
-  // Do some quick tests for rejection cases.
-  unsigned Val;
-  if (CurLexer)
-    Val = CurLexer->isNextPPTokenLParen();
-  else if (CurPTHLexer)
-    Val = CurPTHLexer->isNextPPTokenLParen();
-  else
-    Val = CurTokenLexer->isNextTokenLParen();
-
-  if (Val == 2) {
-    // We have run off the end.  If it's a source file we don't
-    // examine enclosing ones (C99 5.1.1.2p4).  Otherwise walk up the
-    // macro stack.
-    if (CurPPLexer)
-      return false;
-    for (unsigned i = IncludeMacroStack.size(); i != 0; --i) {
-      IncludeStackInfo &Entry = IncludeMacroStack[i-1];
-      if (Entry.TheLexer)
-        Val = Entry.TheLexer->isNextPPTokenLParen();
-      else if (Entry.ThePTHLexer)
-        Val = Entry.ThePTHLexer->isNextPPTokenLParen();
-      else
-        Val = Entry.TheTokenLexer->isNextTokenLParen();
-
-      if (Val != 2)
-        break;
-
-      // Ran off the end of a source file?
-      if (Entry.ThePPLexer)
-        return false;
-    }
-  }
-
-  // Okay, if we know that the token is a '(', lex it and return.  Otherwise we
-  // have found something that isn't a '(' or we found the end of the
-  // translation unit.  In either case, return false.
-  return Val == 1;
-}
-
-/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be
-/// expanded as a macro, handle it and return the next token as 'Identifier'.
-bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
-                                                 MacroInfo *MI) {
-  // If this is a macro expansion in the "#if !defined(x)" line for the file,
-  // then the macro could expand to different things in other contexts, we need
-  // to disable the optimization in this case.
-  if (CurPPLexer) CurPPLexer->MIOpt.ExpandedMacro();
-
-  // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
-  if (MI->isBuiltinMacro()) {
-    if (Callbacks) Callbacks->MacroExpands(Identifier, MI,
-                                           Identifier.getLocation());
-    ExpandBuiltinMacro(Identifier);
-    return false;
-  }
-
-  /// Args - If this is a function-like macro expansion, this contains,
-  /// for each macro argument, the list of tokens that were provided to the
-  /// invocation.
-  MacroArgs *Args = 0;
-
-  // Remember where the end of the expansion occurred.  For an object-like
-  // macro, this is the identifier.  For a function-like macro, this is the ')'.
-  SourceLocation ExpansionEnd = Identifier.getLocation();
-
-  // If this is a function-like macro, read the arguments.
-  if (MI->isFunctionLike()) {
-    // C99 6.10.3p10: If the preprocessing token immediately after the macro
-    // name isn't a '(', this macro should not be expanded.
-    if (!isNextPPTokenLParen())
-      return true;
-
-    // Remember that we are now parsing the arguments to a macro invocation.
-    // Preprocessor directives used inside macro arguments are not portable, and
-    // this enables the warning.
-    InMacroArgs = true;
-    Args = ReadFunctionLikeMacroArgs(Identifier, MI, ExpansionEnd);
-
-    // Finished parsing args.
-    InMacroArgs = false;
-
-    // If there was an error parsing the arguments, bail out.
-    if (Args == 0) return false;
-
-    ++NumFnMacroExpanded;
-  } else {
-    ++NumMacroExpanded;
-  }
-
-  // Notice that this macro has been used.
-  markMacroAsUsed(MI);
-
-  // Remember where the token is expanded.
-  SourceLocation ExpandLoc = Identifier.getLocation();
-  SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);
-
-  if (Callbacks) {
-    if (InMacroArgs) {
-      // We can have macro expansion inside a conditional directive while
-      // reading the function macro arguments. To ensure, in that case, that
-      // MacroExpands callbacks still happen in source order, queue this
-      // callback to have it happen after the function macro callback.
-      DelayedMacroExpandsCallbacks.push_back(
-                              MacroExpandsInfo(Identifier, MI, ExpansionRange));
-    } else {
-      Callbacks->MacroExpands(Identifier, MI, ExpansionRange);
-      if (!DelayedMacroExpandsCallbacks.empty()) {
-        for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
-          MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
-          Callbacks->MacroExpands(Info.Tok, Info.MI, Info.Range);
-        }
-        DelayedMacroExpandsCallbacks.clear();
-      }
-    }
-  }
-  
-  // If we started lexing a macro, enter the macro expansion body.
-
-  // If this macro expands to no tokens, don't bother to push it onto the
-  // expansion stack, only to take it right back off.
-  if (MI->getNumTokens() == 0) {
-    // No need for arg info.
-    if (Args) Args->destroy(*this);
-
-    // Ignore this macro use, just return the next token in the current
-    // buffer.
-    bool HadLeadingSpace = Identifier.hasLeadingSpace();
-    bool IsAtStartOfLine = Identifier.isAtStartOfLine();
-
-    Lex(Identifier);
-
-    // If the identifier isn't on some OTHER line, inherit the leading
-    // whitespace/first-on-a-line property of this token.  This handles
-    // stuff like "! XX," -> "! ," and "   XX," -> "    ,", when XX is
-    // empty.
-    if (!Identifier.isAtStartOfLine()) {
-      if (IsAtStartOfLine) Identifier.setFlag(Token::StartOfLine);
-      if (HadLeadingSpace) Identifier.setFlag(Token::LeadingSpace);
-    }
-    Identifier.setFlag(Token::LeadingEmptyMacro);
-    ++NumFastMacroExpanded;
-    return false;
-
-  } else if (MI->getNumTokens() == 1 &&
-             isTrivialSingleTokenExpansion(MI, Identifier.getIdentifierInfo(),
-                                           *this)) {
-    // Otherwise, if this macro expands into a single trivially-expanded
-    // token: expand it now.  This handles common cases like
-    // "#define VAL 42".
-
-    // No need for arg info.
-    if (Args) Args->destroy(*this);
-
-    // Propagate the isAtStartOfLine/hasLeadingSpace markers of the macro
-    // identifier to the expanded token.
-    bool isAtStartOfLine = Identifier.isAtStartOfLine();
-    bool hasLeadingSpace = Identifier.hasLeadingSpace();
-
-    // Replace the result token.
-    Identifier = MI->getReplacementToken(0);
-
-    // Restore the StartOfLine/LeadingSpace markers.
-    Identifier.setFlagValue(Token::StartOfLine , isAtStartOfLine);
-    Identifier.setFlagValue(Token::LeadingSpace, hasLeadingSpace);
-
-    // Update the tokens location to include both its expansion and physical
-    // locations.
-    SourceLocation Loc =
-      SourceMgr.createExpansionLoc(Identifier.getLocation(), ExpandLoc,
-                                   ExpansionEnd,Identifier.getLength());
-    Identifier.setLocation(Loc);
-
-    // If this is a disabled macro or #define X X, we must mark the result as
-    // unexpandable.
-    if (IdentifierInfo *NewII = Identifier.getIdentifierInfo()) {
-      if (MacroInfo *NewMI = getMacroInfo(NewII))
-        if (!NewMI->isEnabled() || NewMI == MI) {
-          Identifier.setFlag(Token::DisableExpand);
-          Diag(Identifier, diag::pp_disabled_macro_expansion);
-        }
-    }
-
-    // Since this is not an identifier token, it can't be macro expanded, so
-    // we're done.
-    ++NumFastMacroExpanded;
-    return false;
-  }
-
-  // Start expanding the macro.
-  EnterMacro(Identifier, ExpansionEnd, MI, Args);
-
-  // Now that the macro is at the top of the include stack, ask the
-  // preprocessor to read the next token from it.
-  Lex(Identifier);
-  return false;
-}
-
-/// ReadFunctionLikeMacroArgs - After reading "MACRO" and knowing that the next
-/// token is the '(' of the macro, this method is invoked to read all of the
-/// actual arguments specified for the macro invocation.  This returns null on
-/// error.
-MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
-                                                   MacroInfo *MI,
-                                                   SourceLocation &MacroEnd) {
-  // The number of fixed arguments to parse.
-  unsigned NumFixedArgsLeft = MI->getNumArgs();
-  bool isVariadic = MI->isVariadic();
-
-  // Outer loop, while there are more arguments, keep reading them.
-  Token Tok;
-
-  // Read arguments as unexpanded tokens.  This avoids issues, e.g., where
-  // an argument value in a macro could expand to ',' or '(' or ')'.
-  LexUnexpandedToken(Tok);
-  assert(Tok.is(tok::l_paren) && "Error computing l-paren-ness?");
-
-  // ArgTokens - Build up a list of tokens that make up each argument.  Each
-  // argument is separated by an EOF token.  Use a SmallVector so we can avoid
-  // heap allocations in the common case.
-  SmallVector<Token, 64> ArgTokens;
-
-  unsigned NumActuals = 0;
-  while (Tok.isNot(tok::r_paren)) {
-    assert((Tok.is(tok::l_paren) || Tok.is(tok::comma)) &&
-           "only expect argument separators here");
-
-    unsigned ArgTokenStart = ArgTokens.size();
-    SourceLocation ArgStartLoc = Tok.getLocation();
-
-    // C99 6.10.3p11: Keep track of the number of l_parens we have seen.  Note
-    // that we already consumed the first one.
-    unsigned NumParens = 0;
-
-    while (1) {
-      // Read arguments as unexpanded tokens.  This avoids issues, e.g., where
-      // an argument value in a macro could expand to ',' or '(' or ')'.
-      LexUnexpandedToken(Tok);
-
-      if (Tok.is(tok::eof) || Tok.is(tok::eod)) { // "#if f(<eof>" & "#if f(\n"
-        Diag(MacroName, diag::err_unterm_macro_invoc);
-        // Do not lose the EOF/EOD.  Return it to the client.
-        MacroName = Tok;
-        return 0;
-      } else if (Tok.is(tok::r_paren)) {
-        // If we found the ) token, the macro arg list is done.
-        if (NumParens-- == 0) {
-          MacroEnd = Tok.getLocation();
-          break;
-        }
-      } else if (Tok.is(tok::l_paren)) {
-        ++NumParens;
-      // In Microsoft-compatibility mode, commas from nested macro expan-
-      // sions should not be considered as argument separators. We test
-      // for this with the IgnoredComma token flag.
-      } else if (Tok.is(tok::comma)
-          && !(Tok.getFlags() & Token::IgnoredComma) && NumParens == 0) {
-        // Comma ends this argument if there are more fixed arguments expected.
-        // However, if this is a variadic macro, and this is part of the
-        // variadic part, then the comma is just an argument token.
-        if (!isVariadic) break;
-        if (NumFixedArgsLeft > 1)
-          break;
-      } else if (Tok.is(tok::comment) && !KeepMacroComments) {
-        // If this is a comment token in the argument list and we're just in
-        // -C mode (not -CC mode), discard the comment.
-        continue;
-      } else if (Tok.getIdentifierInfo() != 0) {
-        // Reading macro arguments can cause macros that we are currently
-        // expanding from to be popped off the expansion stack.  Doing so causes
-        // them to be reenabled for expansion.  Here we record whether any
-        // identifiers we lex as macro arguments correspond to disabled macros.
-        // If so, we mark the token as noexpand.  This is a subtle aspect of
-        // C99 6.10.3.4p2.
-        if (MacroInfo *MI = getMacroInfo(Tok.getIdentifierInfo()))
-          if (!MI->isEnabled())
-            Tok.setFlag(Token::DisableExpand);
-      } else if (Tok.is(tok::code_completion)) {
-        if (CodeComplete)
-          CodeComplete->CodeCompleteMacroArgument(MacroName.getIdentifierInfo(),
-                                                  MI, NumActuals);
-        // Don't mark that we reached the code-completion point because the
-        // parser is going to handle the token and there will be another
-        // code-completion callback.
-      }
-
-      ArgTokens.push_back(Tok);
-    }
-
-    // If this was an empty argument list foo(), don't add this as an empty
-    // argument.
-    if (ArgTokens.empty() && Tok.getKind() == tok::r_paren)
-      break;
-
-    // If this is not a variadic macro, and too many args were specified, emit
-    // an error.
-    if (!isVariadic && NumFixedArgsLeft == 0) {
-      if (ArgTokens.size() != ArgTokenStart)
-        ArgStartLoc = ArgTokens[ArgTokenStart].getLocation();
-
-      // Emit the diagnostic at the macro name in case there is a missing ).
-      // Emitting it at the , could be far away from the macro name.
-      Diag(ArgStartLoc, diag::err_too_many_args_in_macro_invoc);
-      return 0;
-    }
-
-    // Empty arguments are standard in C99 and C++0x, and are supported as an extension in
-    // other modes.
-    if (ArgTokens.size() == ArgTokenStart && !LangOpts.C99)
-      Diag(Tok, LangOpts.CPlusPlus0x ?
-           diag::warn_cxx98_compat_empty_fnmacro_arg :
-           diag::ext_empty_fnmacro_arg);
-
-    // Add a marker EOF token to the end of the token list for this argument.
-    Token EOFTok;
-    EOFTok.startToken();
-    EOFTok.setKind(tok::eof);
-    EOFTok.setLocation(Tok.getLocation());
-    EOFTok.setLength(0);
-    ArgTokens.push_back(EOFTok);
-    ++NumActuals;
-    assert(NumFixedArgsLeft != 0 && "Too many arguments parsed");
-    --NumFixedArgsLeft;
-  }
-
-  // Okay, we either found the r_paren.  Check to see if we parsed too few
-  // arguments.
-  unsigned MinArgsExpected = MI->getNumArgs();
-
-  // See MacroArgs instance var for description of this.
-  bool isVarargsElided = false;
-
-  if (NumActuals < MinArgsExpected) {
-    // There are several cases where too few arguments is ok, handle them now.
-    if (NumActuals == 0 && MinArgsExpected == 1) {
-      // #define A(X)  or  #define A(...)   ---> A()
-
-      // If there is exactly one argument, and that argument is missing,
-      // then we have an empty "()" argument empty list.  This is fine, even if
-      // the macro expects one argument (the argument is just empty).
-      isVarargsElided = MI->isVariadic();
-    } else if (MI->isVariadic() &&
-               (NumActuals+1 == MinArgsExpected ||  // A(x, ...) -> A(X)
-                (NumActuals == 0 && MinArgsExpected == 2))) {// A(x,...) -> A()
-      // Varargs where the named vararg parameter is missing: OK as extension.
-      //   #define A(x, ...)
-      //   A("blah")
-      Diag(Tok, diag::ext_missing_varargs_arg);
-      Diag(MI->getDefinitionLoc(), diag::note_macro_here)
-        << MacroName.getIdentifierInfo();
-
-      // Remember this occurred, allowing us to elide the comma when used for
-      // cases like:
-      //   #define A(x, foo...) blah(a, ## foo)
-      //   #define B(x, ...) blah(a, ## __VA_ARGS__)
-      //   #define C(...) blah(a, ## __VA_ARGS__)
-      //  A(x) B(x) C()
-      isVarargsElided = true;
-    } else {
-      // Otherwise, emit the error.
-      Diag(Tok, diag::err_too_few_args_in_macro_invoc);
-      return 0;
-    }
-
-    // Add a marker EOF token to the end of the token list for this argument.
-    SourceLocation EndLoc = Tok.getLocation();
-    Tok.startToken();
-    Tok.setKind(tok::eof);
-    Tok.setLocation(EndLoc);
-    Tok.setLength(0);
-    ArgTokens.push_back(Tok);
-
-    // If we expect two arguments, add both as empty.
-    if (NumActuals == 0 && MinArgsExpected == 2)
-      ArgTokens.push_back(Tok);
-
-  } else if (NumActuals > MinArgsExpected && !MI->isVariadic()) {
-    // Emit the diagnostic at the macro name in case there is a missing ).
-    // Emitting it at the , could be far away from the macro name.
-    Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
-    return 0;
-  }
-
-  return MacroArgs::create(MI, ArgTokens, isVarargsElided, *this);
-}
-
-/// \brief Keeps macro expanded tokens for TokenLexers.
-//
-/// Works like a stack; a TokenLexer adds the macro expanded tokens that is
-/// going to lex in the cache and when it finishes the tokens are removed
-/// from the end of the cache.
-Token *Preprocessor::cacheMacroExpandedTokens(TokenLexer *tokLexer,
-                                              ArrayRef<Token> tokens) {
-  assert(tokLexer);
-  if (tokens.empty())
-    return 0;
-
-  size_t newIndex = MacroExpandedTokens.size();
-  bool cacheNeedsToGrow = tokens.size() >
-                      MacroExpandedTokens.capacity()-MacroExpandedTokens.size(); 
-  MacroExpandedTokens.append(tokens.begin(), tokens.end());
-
-  if (cacheNeedsToGrow) {
-    // Go through all the TokenLexers whose 'Tokens' pointer points in the
-    // buffer and update the pointers to the (potential) new buffer array.
-    for (unsigned i = 0, e = MacroExpandingLexersStack.size(); i != e; ++i) {
-      TokenLexer *prevLexer;
-      size_t tokIndex;
-      llvm::tie(prevLexer, tokIndex) = MacroExpandingLexersStack[i];
-      prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
-    }
-  }
-
-  MacroExpandingLexersStack.push_back(std::make_pair(tokLexer, newIndex));
-  return MacroExpandedTokens.data() + newIndex;
-}
-
-void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() {
-  assert(!MacroExpandingLexersStack.empty());
-  size_t tokIndex = MacroExpandingLexersStack.back().second;
-  assert(tokIndex < MacroExpandedTokens.size());
-  // Pop the cached macro expanded tokens from the end.
-  MacroExpandedTokens.resize(tokIndex);
-  MacroExpandingLexersStack.pop_back();
-}
-
-/// ComputeDATE_TIME - Compute the current time, enter it into the specified
-/// scratch buffer, then return DATELoc/TIMELoc locations with the position of
-/// the identifier tokens inserted.
-static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
-                             Preprocessor &PP) {
-  time_t TT = time(0);
-  struct tm *TM = localtime(&TT);
-
-  static const char * const Months[] = {
-    "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
-  };
-
-  char TmpBuffer[32];
-#ifdef LLVM_ON_WIN32
-  sprintf(TmpBuffer, "\"%s %2d %4d\"", Months[TM->tm_mon], TM->tm_mday,
-          TM->tm_year+1900);
-#else
-  snprintf(TmpBuffer, sizeof(TmpBuffer), "\"%s %2d %4d\"", Months[TM->tm_mon], TM->tm_mday,
-          TM->tm_year+1900);
-#endif
-
-  Token TmpTok;
-  TmpTok.startToken();
-  PP.CreateString(TmpBuffer, strlen(TmpBuffer), TmpTok);
-  DATELoc = TmpTok.getLocation();
-
-#ifdef LLVM_ON_WIN32
-  sprintf(TmpBuffer, "\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min, TM->tm_sec);
-#else
-  snprintf(TmpBuffer, sizeof(TmpBuffer), "\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min, TM->tm_sec);
-#endif
-  PP.CreateString(TmpBuffer, strlen(TmpBuffer), TmpTok);
-  TIMELoc = TmpTok.getLocation();
-}
-
-
-/// HasFeature - Return true if we recognize and implement the feature
-/// specified by the identifier as a standard language feature.
-static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
-  const LangOptions &LangOpts = PP.getLangOpts();
-  StringRef Feature = II->getName();
-
-  // Normalize the feature name, __foo__ becomes foo.
-  if (Feature.startswith("__") && Feature.endswith("__") && Feature.size() >= 4)
-    Feature = Feature.substr(2, Feature.size() - 4);
-
-  return llvm::StringSwitch<bool>(Feature)
-           .Case("address_sanitizer", LangOpts.AddressSanitizer)
-           .Case("attribute_analyzer_noreturn", true)
-           .Case("attribute_availability", true)
-           .Case("attribute_availability_with_message", true)
-           .Case("attribute_cf_returns_not_retained", true)
-           .Case("attribute_cf_returns_retained", true)
-           .Case("attribute_deprecated_with_message", true)
-           .Case("attribute_ext_vector_type", true)
-           .Case("attribute_ns_returns_not_retained", true)
-           .Case("attribute_ns_returns_retained", true)
-           .Case("attribute_ns_consumes_self", true)
-           .Case("attribute_ns_consumed", true)
-           .Case("attribute_cf_consumed", true)
-           .Case("attribute_objc_ivar_unused", true)
-           .Case("attribute_objc_method_family", true)
-           .Case("attribute_overloadable", true)
-           .Case("attribute_unavailable_with_message", true)
-           .Case("attribute_unused_on_fields", true)
-           .Case("blocks", LangOpts.Blocks)
-           .Case("cxx_exceptions", LangOpts.Exceptions)
-           .Case("cxx_rtti", LangOpts.RTTI)
-           .Case("enumerator_attributes", true)
-           // Objective-C features
-           .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
-           .Case("objc_arc", LangOpts.ObjCAutoRefCount)
-           .Case("objc_arc_weak", LangOpts.ObjCARCWeak)
-           .Case("objc_default_synthesize_properties", LangOpts.ObjC2)
-           .Case("objc_fixed_enum", LangOpts.ObjC2)
-           .Case("objc_instancetype", LangOpts.ObjC2)
-           .Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules)
-           .Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile())
-           .Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport())
-           .Case("ownership_holds", true)
-           .Case("ownership_returns", true)
-           .Case("ownership_takes", true)
-           .Case("objc_bool", true)
-           .Case("objc_subscripting", LangOpts.ObjCRuntime.isNonFragile())
-           .Case("objc_array_literals", LangOpts.ObjC2)
-           .Case("objc_dictionary_literals", LangOpts.ObjC2)
-           .Case("objc_boxed_expressions", LangOpts.ObjC2)
-           .Case("arc_cf_code_audited", true)
-           // C11 features
-           .Case("c_alignas", LangOpts.C11)
-           .Case("c_atomic", LangOpts.C11)
-           .Case("c_generic_selections", LangOpts.C11)
-           .Case("c_static_assert", LangOpts.C11)
-           // C++11 features
-           .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus0x)
-           .Case("cxx_alias_templates", LangOpts.CPlusPlus0x)
-           .Case("cxx_alignas", LangOpts.CPlusPlus0x)
-           .Case("cxx_atomic", LangOpts.CPlusPlus0x)
-           .Case("cxx_attributes", LangOpts.CPlusPlus0x)
-           .Case("cxx_auto_type", LangOpts.CPlusPlus0x)
-           .Case("cxx_constexpr", LangOpts.CPlusPlus0x)
-           .Case("cxx_decltype", LangOpts.CPlusPlus0x)
-           .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus0x)
-           .Case("cxx_default_function_template_args", LangOpts.CPlusPlus0x)
-           .Case("cxx_defaulted_functions", LangOpts.CPlusPlus0x)
-           .Case("cxx_delegating_constructors", LangOpts.CPlusPlus0x)
-           .Case("cxx_deleted_functions", LangOpts.CPlusPlus0x)
-           .Case("cxx_explicit_conversions", LangOpts.CPlusPlus0x)
-           .Case("cxx_generalized_initializers", LangOpts.CPlusPlus0x)
-           .Case("cxx_implicit_moves", LangOpts.CPlusPlus0x)
-         //.Case("cxx_inheriting_constructors", false)
-           .Case("cxx_inline_namespaces", LangOpts.CPlusPlus0x)
-           .Case("cxx_lambdas", LangOpts.CPlusPlus0x)
-           .Case("cxx_local_type_template_args", LangOpts.CPlusPlus0x)
-           .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus0x)
-           .Case("cxx_noexcept", LangOpts.CPlusPlus0x)
-           .Case("cxx_nullptr", LangOpts.CPlusPlus0x)
-           .Case("cxx_override_control", LangOpts.CPlusPlus0x)
-           .Case("cxx_range_for", LangOpts.CPlusPlus0x)
-           .Case("cxx_raw_string_literals", LangOpts.CPlusPlus0x)
-           .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus0x)
-           .Case("cxx_rvalue_references", LangOpts.CPlusPlus0x)
-           .Case("cxx_strong_enums", LangOpts.CPlusPlus0x)
-           .Case("cxx_static_assert", LangOpts.CPlusPlus0x)
-           .Case("cxx_trailing_return", LangOpts.CPlusPlus0x)
-           .Case("cxx_unicode_literals", LangOpts.CPlusPlus0x)
-           .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus0x)
-           .Case("cxx_user_literals", LangOpts.CPlusPlus0x)
-           .Case("cxx_variadic_templates", LangOpts.CPlusPlus0x)
-           // Type traits
-           .Case("has_nothrow_assign", LangOpts.CPlusPlus)
-           .Case("has_nothrow_copy", LangOpts.CPlusPlus)
-           .Case("has_nothrow_constructor", LangOpts.CPlusPlus)
-           .Case("has_trivial_assign", LangOpts.CPlusPlus)
-           .Case("has_trivial_copy", LangOpts.CPlusPlus)
-           .Case("has_trivial_constructor", LangOpts.CPlusPlus)
-           .Case("has_trivial_destructor", LangOpts.CPlusPlus)
-           .Case("has_virtual_destructor", LangOpts.CPlusPlus)
-           .Case("is_abstract", LangOpts.CPlusPlus)
-           .Case("is_base_of", LangOpts.CPlusPlus)
-           .Case("is_class", LangOpts.CPlusPlus)
-           .Case("is_convertible_to", LangOpts.CPlusPlus)
-            // __is_empty is available only if the horrible
-            // "struct __is_empty" parsing hack hasn't been needed in this
-            // translation unit. If it has, __is_empty reverts to a normal
-            // identifier and __has_feature(is_empty) evaluates false.
-           .Case("is_empty", LangOpts.CPlusPlus)
-           .Case("is_enum", LangOpts.CPlusPlus)
-           .Case("is_final", LangOpts.CPlusPlus)
-           .Case("is_literal", LangOpts.CPlusPlus)
-           .Case("is_standard_layout", LangOpts.CPlusPlus)
-           .Case("is_pod", LangOpts.CPlusPlus)
-           .Case("is_polymorphic", LangOpts.CPlusPlus)
-           .Case("is_trivial", LangOpts.CPlusPlus)
-           .Case("is_trivially_assignable", LangOpts.CPlusPlus)
-           .Case("is_trivially_constructible", LangOpts.CPlusPlus)
-           .Case("is_trivially_copyable", LangOpts.CPlusPlus)
-           .Case("is_union", LangOpts.CPlusPlus)
-           .Case("modules", LangOpts.Modules)
-           .Case("tls", PP.getTargetInfo().isTLSSupported())
-           .Case("underlying_type", LangOpts.CPlusPlus)
-           .Default(false);
-}
-
-/// HasExtension - Return true if we recognize and implement the feature
-/// specified by the identifier, either as an extension or a standard language
-/// feature.
-static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) {
-  if (HasFeature(PP, II))
-    return true;
-
-  // If the use of an extension results in an error diagnostic, extensions are
-  // effectively unavailable, so just return false here.
-  if (PP.getDiagnostics().getExtensionHandlingBehavior() ==
-      DiagnosticsEngine::Ext_Error)
-    return false;
-
-  const LangOptions &LangOpts = PP.getLangOpts();
-  StringRef Extension = II->getName();
-
-  // Normalize the extension name, __foo__ becomes foo.
-  if (Extension.startswith("__") && Extension.endswith("__") &&
-      Extension.size() >= 4)
-    Extension = Extension.substr(2, Extension.size() - 4);
-
-  // Because we inherit the feature list from HasFeature, this string switch
-  // must be less restrictive than HasFeature's.
-  return llvm::StringSwitch<bool>(Extension)
-           // C11 features supported by other languages as extensions.
-           .Case("c_alignas", true)
-           .Case("c_atomic", true)
-           .Case("c_generic_selections", true)
-           .Case("c_static_assert", true)
-           // C++0x features supported by other languages as extensions.
-           .Case("cxx_atomic", LangOpts.CPlusPlus)
-           .Case("cxx_deleted_functions", LangOpts.CPlusPlus)
-           .Case("cxx_explicit_conversions", LangOpts.CPlusPlus)
-           .Case("cxx_inline_namespaces", LangOpts.CPlusPlus)
-           .Case("cxx_local_type_template_args", LangOpts.CPlusPlus)
-           .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus)
-           .Case("cxx_override_control", LangOpts.CPlusPlus)
-           .Case("cxx_range_for", LangOpts.CPlusPlus)
-           .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus)
-           .Case("cxx_rvalue_references", LangOpts.CPlusPlus)
-           .Default(false);
-}
-
-/// HasAttribute -  Return true if we recognize and implement the attribute
-/// specified by the given identifier.
-static bool HasAttribute(const IdentifierInfo *II) {
-  StringRef Name = II->getName();
-  // Normalize the attribute name, __foo__ becomes foo.
-  if (Name.startswith("__") && Name.endswith("__") && Name.size() >= 4)
-    Name = Name.substr(2, Name.size() - 4);
-
-  // FIXME: Do we need to handle namespaces here?
-  return llvm::StringSwitch<bool>(Name)
-#include "clang/Lex/AttrSpellings.inc"
-        .Default(false);
-}
-
-/// EvaluateHasIncludeCommon - Process a '__has_include("path")'
-/// or '__has_include_next("path")' expression.
-/// Returns true if successful.
-static bool EvaluateHasIncludeCommon(Token &Tok,
-                                     IdentifierInfo *II, Preprocessor &PP,
-                                     const DirectoryLookup *LookupFrom) {
-  SourceLocation LParenLoc;
-
-  // Get '('.
-  PP.LexNonComment(Tok);
-
-  // Ensure we have a '('.
-  if (Tok.isNot(tok::l_paren)) {
-    PP.Diag(Tok.getLocation(), diag::err_pp_missing_lparen) << II->getName();
-    return false;
-  }
-
-  // Save '(' location for possible missing ')' message.
-  LParenLoc = Tok.getLocation();
-
-  // Get the file name.
-  PP.getCurrentLexer()->LexIncludeFilename(Tok);
-
-  // Reserve a buffer to get the spelling.
-  SmallString<128> FilenameBuffer;
-  StringRef Filename;
-  SourceLocation EndLoc;
-  
-  switch (Tok.getKind()) {
-  case tok::eod:
-    // If the token kind is EOD, the error has already been diagnosed.
-    return false;
-
-  case tok::angle_string_literal:
-  case tok::string_literal: {
-    bool Invalid = false;
-    Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid);
-    if (Invalid)
-      return false;
-    break;
-  }
-
-  case tok::less:
-    // This could be a <foo/bar.h> file coming from a macro expansion.  In this
-    // case, glue the tokens together into FilenameBuffer and interpret those.
-    FilenameBuffer.push_back('<');
-    if (PP.ConcatenateIncludeName(FilenameBuffer, EndLoc))
-      return false;   // Found <eod> but no ">"?  Diagnostic already emitted.
-    Filename = FilenameBuffer.str();
-    break;
-  default:
-    PP.Diag(Tok.getLocation(), diag::err_pp_expects_filename);
-    return false;
-  }
-
-  // Get ')'.
-  PP.LexNonComment(Tok);
-
-  // Ensure we have a trailing ).
-  if (Tok.isNot(tok::r_paren)) {
-    PP.Diag(Tok.getLocation(), diag::err_pp_missing_rparen) << II->getName();
-    PP.Diag(LParenLoc, diag::note_matching) << "(";
-    return false;
-  }
-
-  bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename);
-  // If GetIncludeFilenameSpelling set the start ptr to null, there was an
-  // error.
-  if (Filename.empty())
-    return false;
-
-  // Search include directories.
-  const DirectoryLookup *CurDir;
-  const FileEntry *File =
-      PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL, NULL, NULL);
-
-  // Get the result value.  A result of true means the file exists.
-  return File != 0;
-}
-
-/// EvaluateHasInclude - Process a '__has_include("path")' expression.
-/// Returns true if successful.
-static bool EvaluateHasInclude(Token &Tok, IdentifierInfo *II,
-                               Preprocessor &PP) {
-  return EvaluateHasIncludeCommon(Tok, II, PP, NULL);
-}
-
-/// EvaluateHasIncludeNext - Process '__has_include_next("path")' expression.
-/// Returns true if successful.
-static bool EvaluateHasIncludeNext(Token &Tok,
-                                   IdentifierInfo *II, Preprocessor &PP) {
-  // __has_include_next is like __has_include, except that we start
-  // searching after the current found directory.  If we can't do this,
-  // issue a diagnostic.
-  const DirectoryLookup *Lookup = PP.GetCurDirLookup();
-  if (PP.isInPrimaryFile()) {
-    Lookup = 0;
-    PP.Diag(Tok, diag::pp_include_next_in_primary);
-  } else if (Lookup == 0) {
-    PP.Diag(Tok, diag::pp_include_next_absolute_path);
-  } else {
-    // Start looking up in the next directory.
-    ++Lookup;
-  }
-
-  return EvaluateHasIncludeCommon(Tok, II, PP, Lookup);
-}
-
-/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
-/// as a builtin macro, handle it and return the next token as 'Tok'.
-void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
-  // Figure out which token this is.
-  IdentifierInfo *II = Tok.getIdentifierInfo();
-  assert(II && "Can't be a macro without id info!");
-
-  // If this is an _Pragma or Microsoft __pragma directive, expand it,
-  // invoke the pragma handler, then lex the token after it.
-  if (II == Ident_Pragma)
-    return Handle_Pragma(Tok);
-  else if (II == Ident__pragma) // in non-MS mode this is null
-    return HandleMicrosoft__pragma(Tok);
-
-  ++NumBuiltinMacroExpanded;
-
-  SmallString<128> TmpBuffer;
-  llvm::raw_svector_ostream OS(TmpBuffer);
-
-  // Set up the return result.
-  Tok.setIdentifierInfo(0);
-  Tok.clearFlag(Token::NeedsCleaning);
-
-  if (II == Ident__LINE__) {
-    // C99 6.10.8: "__LINE__: The presumed line number (within the current
-    // source file) of the current source line (an integer constant)".  This can
-    // be affected by #line.
-    SourceLocation Loc = Tok.getLocation();
-
-    // Advance to the location of the first _, this might not be the first byte
-    // of the token if it starts with an escaped newline.
-    Loc = AdvanceToTokenCharacter(Loc, 0);
-
-    // One wrinkle here is that GCC expands __LINE__ to location of the *end* of
-    // a macro expansion.  This doesn't matter for object-like macros, but
-    // can matter for a function-like macro that expands to contain __LINE__.
-    // Skip down through expansion points until we find a file loc for the
-    // end of the expansion history.
-    Loc = SourceMgr.getExpansionRange(Loc).second;
-    PresumedLoc PLoc = SourceMgr.getPresumedLoc(Loc);
-
-    // __LINE__ expands to a simple numeric value.
-    OS << (PLoc.isValid()? PLoc.getLine() : 1);
-    Tok.setKind(tok::numeric_constant);
-  } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) {
-    // C99 6.10.8: "__FILE__: The presumed name of the current source file (a
-    // character string literal)". This can be affected by #line.
-    PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
-
-    // __BASE_FILE__ is a GNU extension that returns the top of the presumed
-    // #include stack instead of the current file.
-    if (II == Ident__BASE_FILE__ && PLoc.isValid()) {
-      SourceLocation NextLoc = PLoc.getIncludeLoc();
-      while (NextLoc.isValid()) {
-        PLoc = SourceMgr.getPresumedLoc(NextLoc);
-        if (PLoc.isInvalid())
-          break;
-        
-        NextLoc = PLoc.getIncludeLoc();
-      }
-    }
-
-    // Escape this filename.  Turn '\' -> '\\' '"' -> '\"'
-    SmallString<128> FN;
-    if (PLoc.isValid()) {
-      FN += PLoc.getFilename();
-      Lexer::Stringify(FN);
-      OS << '"' << FN.str() << '"';
-    }
-    Tok.setKind(tok::string_literal);
-  } else if (II == Ident__DATE__) {
-    if (!DATELoc.isValid())
-      ComputeDATE_TIME(DATELoc, TIMELoc, *this);
-    Tok.setKind(tok::string_literal);
-    Tok.setLength(strlen("\"Mmm dd yyyy\""));
-    Tok.setLocation(SourceMgr.createExpansionLoc(DATELoc, Tok.getLocation(),
-                                                 Tok.getLocation(),
-                                                 Tok.getLength()));
-    return;
-  } else if (II == Ident__TIME__) {
-    if (!TIMELoc.isValid())
-      ComputeDATE_TIME(DATELoc, TIMELoc, *this);
-    Tok.setKind(tok::string_literal);
-    Tok.setLength(strlen("\"hh:mm:ss\""));
-    Tok.setLocation(SourceMgr.createExpansionLoc(TIMELoc, Tok.getLocation(),
-                                                 Tok.getLocation(),
-                                                 Tok.getLength()));
-    return;
-  } else if (II == Ident__INCLUDE_LEVEL__) {
-    // Compute the presumed include depth of this token.  This can be affected
-    // by GNU line markers.
-    unsigned Depth = 0;
-
-    PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
-    if (PLoc.isValid()) {
-      PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
-      for (; PLoc.isValid(); ++Depth)
-        PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
-    }
-
-    // __INCLUDE_LEVEL__ expands to a simple numeric value.
-    OS << Depth;
-    Tok.setKind(tok::numeric_constant);
-  } else if (II == Ident__TIMESTAMP__) {
-    // MSVC, ICC, GCC, VisualAge C++ extension.  The generated string should be
-    // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
-
-    // Get the file that we are lexing out of.  If we're currently lexing from
-    // a macro, dig into the include stack.
-    const FileEntry *CurFile = 0;
-    PreprocessorLexer *TheLexer = getCurrentFileLexer();
-
-    if (TheLexer)
-      CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID());
-
-    const char *Result;
-    if (CurFile) {
-      time_t TT = CurFile->getModificationTime();
-      struct tm *TM = localtime(&TT);
-      Result = asctime(TM);
-    } else {
-      Result = "??? ??? ?? ??:??:?? ????\n";
-    }
-    // Surround the string with " and strip the trailing newline.
-    OS << '"' << StringRef(Result, strlen(Result)-1) << '"';
-    Tok.setKind(tok::string_literal);
-  } else if (II == Ident__COUNTER__) {
-    // __COUNTER__ expands to a simple numeric value.
-    OS << CounterValue++;
-    Tok.setKind(tok::numeric_constant);
-  } else if (II == Ident__has_feature   ||
-             II == Ident__has_extension ||
-             II == Ident__has_builtin   ||
-             II == Ident__has_attribute) {
-    // The argument to these builtins should be a parenthesized identifier.
-    SourceLocation StartLoc = Tok.getLocation();
-
-    bool IsValid = false;
-    IdentifierInfo *FeatureII = 0;
-
-    // Read the '('.
-    Lex(Tok);
-    if (Tok.is(tok::l_paren)) {
-      // Read the identifier
-      Lex(Tok);
-      if (Tok.is(tok::identifier) || Tok.is(tok::kw_const)) {
-        FeatureII = Tok.getIdentifierInfo();
-
-        // Read the ')'.
-        Lex(Tok);
-        if (Tok.is(tok::r_paren))
-          IsValid = true;
-      }
-    }
-
-    bool Value = false;
-    if (!IsValid)
-      Diag(StartLoc, diag::err_feature_check_malformed);
-    else if (II == Ident__has_builtin) {
-      // Check for a builtin is trivial.
-      Value = FeatureII->getBuiltinID() != 0;
-    } else if (II == Ident__has_attribute)
-      Value = HasAttribute(FeatureII);
-    else if (II == Ident__has_extension)
-      Value = HasExtension(*this, FeatureII);
-    else {
-      assert(II == Ident__has_feature && "Must be feature check");
-      Value = HasFeature(*this, FeatureII);
-    }
-
-    OS << (int)Value;
-    if (IsValid)
-      Tok.setKind(tok::numeric_constant);
-  } else if (II == Ident__has_include ||
-             II == Ident__has_include_next) {
-    // The argument to these two builtins should be a parenthesized
-    // file name string literal using angle brackets (<>) or
-    // double-quotes ("").
-    bool Value;
-    if (II == Ident__has_include)
-      Value = EvaluateHasInclude(Tok, II, *this);
-    else
-      Value = EvaluateHasIncludeNext(Tok, II, *this);
-    OS << (int)Value;
-    Tok.setKind(tok::numeric_constant);
-  } else if (II == Ident__has_warning) {
-    // The argument should be a parenthesized string literal.
-    // The argument to these builtins should be a parenthesized identifier.
-    SourceLocation StartLoc = Tok.getLocation();    
-    bool IsValid = false;
-    bool Value = false;
-    // Read the '('.
-    Lex(Tok);
-    do {
-      if (Tok.is(tok::l_paren)) {      
-        // Read the string.
-        Lex(Tok);
-      
-        // We need at least one string literal.
-        if (!Tok.is(tok::string_literal)) {
-          StartLoc = Tok.getLocation();
-          IsValid = false;
-          // Eat tokens until ')'.
-          do Lex(Tok); while (!(Tok.is(tok::r_paren) || Tok.is(tok::eod)));
-          break;
-        }
-        
-        // String concatenation allows multiple strings, which can even come
-        // from macro expansion.
-        SmallVector<Token, 4> StrToks;
-        while (Tok.is(tok::string_literal)) {
-          // Complain about, and drop, any ud-suffix.
-          if (Tok.hasUDSuffix())
-            Diag(Tok, diag::err_invalid_string_udl);
-          StrToks.push_back(Tok);
-          LexUnexpandedToken(Tok);
-        }
-        
-        // Is the end a ')'?
-        if (!(IsValid = Tok.is(tok::r_paren)))
-          break;
-        
-        // Concatenate and parse the strings.
-        StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this);
-        assert(Literal.isAscii() && "Didn't allow wide strings in");
-        if (Literal.hadError)
-          break;
-        if (Literal.Pascal) {
-          Diag(Tok, diag::warn_pragma_diagnostic_invalid);
-          break;
-        }
-        
-        StringRef WarningName(Literal.GetString());
-        
-        if (WarningName.size() < 3 || WarningName[0] != '-' ||
-            WarningName[1] != 'W') {
-          Diag(StrToks[0].getLocation(), diag::warn_has_warning_invalid_option);
-          break;
-        }
-        
-        // Finally, check if the warning flags maps to a diagnostic group.
-        // We construct a SmallVector here to talk to getDiagnosticIDs().
-        // Although we don't use the result, this isn't a hot path, and not
-        // worth special casing.
-        llvm::SmallVector<diag::kind, 10> Diags;
-        Value = !getDiagnostics().getDiagnosticIDs()->
-          getDiagnosticsInGroup(WarningName.substr(2), Diags);
-      }
-    } while (false);
-    
-    if (!IsValid)
-      Diag(StartLoc, diag::err_warning_check_malformed);
-
-    OS << (int)Value;
-    Tok.setKind(tok::numeric_constant);
-  } else {
-    llvm_unreachable("Unknown identifier!");
-  }
-  CreateString(OS.str().data(), OS.str().size(), Tok,
-               Tok.getLocation(), Tok.getLocation());
-}
-
-void Preprocessor::markMacroAsUsed(MacroInfo *MI) {
-  // If the 'used' status changed, and the macro requires 'unused' warning,
-  // remove its SourceLocation from the warn-for-unused-macro locations.
-  if (MI->isWarnIfUnused() && !MI->isUsed())
-    WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
-  MI->setIsUsed(true);
-}
+//===--- MacroExpansion.cpp - Top level Macro Expansion -------------------===//
+//
+//                     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 top level handling of macro expasion for the
+// preprocessor.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/Preprocessor.h"
+#include "MacroArgs.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/CodeCompletionHandler.h"
+#include "clang/Lex/ExternalPreprocessorSource.h"
+#include "clang/Lex/LiteralSupport.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstdio>
+#include <ctime>
+using namespace clang;
+
+MacroInfo *Preprocessor::getInfoForMacro(IdentifierInfo *II) const {
+  assert(II->hasMacroDefinition() && "Identifier is not a macro!");
+
+  macro_iterator Pos = Macros.find(II);
+  if (Pos == Macros.end()) {
+    // Load this macro from the external source.
+    getExternalSource()->LoadMacroDefinition(II);
+    Pos = Macros.find(II);
+  }
+  assert(Pos != Macros.end() && "Identifier macro info is missing!");
+  assert(Pos->second->getUndefLoc().isInvalid() && "Macro is undefined!");
+  return Pos->second;
+}
+
+/// setMacroInfo - Specify a macro for this identifier.
+///
+void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI,
+                                bool LoadedFromAST) {
+  assert(MI && "MacroInfo should be non-zero!");
+  MI->setPreviousDefinition(Macros[II]);
+  Macros[II] = MI;
+  II->setHasMacroDefinition(true);
+  if (II->isFromAST() && !LoadedFromAST)
+    II->setChangedSinceDeserialization();
+}
+
+/// \brief Undefine a macro for this identifier.
+void Preprocessor::clearMacroInfo(IdentifierInfo *II) {
+  assert(II->hasMacroDefinition() && "Macro is not defined!");
+  assert(Macros[II]->getUndefLoc().isValid() && "Macro is still defined!");
+  II->setHasMacroDefinition(false);
+  if (II->isFromAST())
+    II->setChangedSinceDeserialization();
+}
+
+/// RegisterBuiltinMacro - Register the specified identifier in the identifier
+/// table and mark it as a builtin macro to be expanded.
+static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){
+  // Get the identifier.
+  IdentifierInfo *Id = PP.getIdentifierInfo(Name);
+
+  // Mark it as being a macro that is builtin.
+  MacroInfo *MI = PP.AllocateMacroInfo(SourceLocation());
+  MI->setIsBuiltinMacro();
+  PP.setMacroInfo(Id, MI);
+  return Id;
+}
+
+
+/// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
+/// identifier table.
+void Preprocessor::RegisterBuiltinMacros() {
+  Ident__LINE__ = RegisterBuiltinMacro(*this, "__LINE__");
+  Ident__FILE__ = RegisterBuiltinMacro(*this, "__FILE__");
+  Ident__DATE__ = RegisterBuiltinMacro(*this, "__DATE__");
+  Ident__TIME__ = RegisterBuiltinMacro(*this, "__TIME__");
+  Ident__COUNTER__ = RegisterBuiltinMacro(*this, "__COUNTER__");
+  Ident_Pragma  = RegisterBuiltinMacro(*this, "_Pragma");
+
+  // GCC Extensions.
+  Ident__BASE_FILE__     = RegisterBuiltinMacro(*this, "__BASE_FILE__");
+  Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(*this, "__INCLUDE_LEVEL__");
+  Ident__TIMESTAMP__     = RegisterBuiltinMacro(*this, "__TIMESTAMP__");
+
+  // Clang Extensions.
+  Ident__has_feature      = RegisterBuiltinMacro(*this, "__has_feature");
+  Ident__has_extension    = RegisterBuiltinMacro(*this, "__has_extension");
+  Ident__has_builtin      = RegisterBuiltinMacro(*this, "__has_builtin");
+  Ident__has_attribute    = RegisterBuiltinMacro(*this, "__has_attribute");
+  Ident__has_include      = RegisterBuiltinMacro(*this, "__has_include");
+  Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next");
+  Ident__has_warning      = RegisterBuiltinMacro(*this, "__has_warning");
+
+  // Microsoft Extensions.
+  if (LangOpts.MicrosoftExt) 
+    Ident__pragma = RegisterBuiltinMacro(*this, "__pragma");
+  else
+    Ident__pragma = 0;
+}
+
+/// isTrivialSingleTokenExpansion - Return true if MI, which has a single token
+/// in its expansion, currently expands to that token literally.
+static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
+                                          const IdentifierInfo *MacroIdent,
+                                          Preprocessor &PP) {
+  IdentifierInfo *II = MI->getReplacementToken(0).getIdentifierInfo();
+
+  // If the token isn't an identifier, it's always literally expanded.
+  if (II == 0) return true;
+
+  // If the information about this identifier is out of date, update it from
+  // the external source.
+  if (II->isOutOfDate())
+    PP.getExternalSource()->updateOutOfDateIdentifier(*II);
+
+  // If the identifier is a macro, and if that macro is enabled, it may be
+  // expanded so it's not a trivial expansion.
+  if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled() &&
+      // Fast expanding "#define X X" is ok, because X would be disabled.
+      II != MacroIdent)
+    return false;
+
+  // If this is an object-like macro invocation, it is safe to trivially expand
+  // it.
+  if (MI->isObjectLike()) return true;
+
+  // If this is a function-like macro invocation, it's safe to trivially expand
+  // as long as the identifier is not a macro argument.
+  for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
+       I != E; ++I)
+    if (*I == II)
+      return false;   // Identifier is a macro argument.
+
+  return true;
+}
+
+
+/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
+/// lexed is a '('.  If so, consume the token and return true, if not, this
+/// method should have no observable side-effect on the lexed tokens.
+bool Preprocessor::isNextPPTokenLParen() {
+  // Do some quick tests for rejection cases.
+  unsigned Val;
+  if (CurLexer)
+    Val = CurLexer->isNextPPTokenLParen();
+  else if (CurPTHLexer)
+    Val = CurPTHLexer->isNextPPTokenLParen();
+  else
+    Val = CurTokenLexer->isNextTokenLParen();
+
+  if (Val == 2) {
+    // We have run off the end.  If it's a source file we don't
+    // examine enclosing ones (C99 5.1.1.2p4).  Otherwise walk up the
+    // macro stack.
+    if (CurPPLexer)
+      return false;
+    for (unsigned i = IncludeMacroStack.size(); i != 0; --i) {
+      IncludeStackInfo &Entry = IncludeMacroStack[i-1];
+      if (Entry.TheLexer)
+        Val = Entry.TheLexer->isNextPPTokenLParen();
+      else if (Entry.ThePTHLexer)
+        Val = Entry.ThePTHLexer->isNextPPTokenLParen();
+      else
+        Val = Entry.TheTokenLexer->isNextTokenLParen();
+
+      if (Val != 2)
+        break;
+
+      // Ran off the end of a source file?
+      if (Entry.ThePPLexer)
+        return false;
+    }
+  }
+
+  // Okay, if we know that the token is a '(', lex it and return.  Otherwise we
+  // have found something that isn't a '(' or we found the end of the
+  // translation unit.  In either case, return false.
+  return Val == 1;
+}
+
+/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be
+/// expanded as a macro, handle it and return the next token as 'Identifier'.
+bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
+                                                 MacroInfo *MI) {
+  // If this is a macro expansion in the "#if !defined(x)" line for the file,
+  // then the macro could expand to different things in other contexts, we need
+  // to disable the optimization in this case.
+  if (CurPPLexer) CurPPLexer->MIOpt.ExpandedMacro();
+
+  // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
+  if (MI->isBuiltinMacro()) {
+    if (Callbacks) Callbacks->MacroExpands(Identifier, MI,
+                                           Identifier.getLocation());
+    ExpandBuiltinMacro(Identifier);
+    return false;
+  }
+
+  /// Args - If this is a function-like macro expansion, this contains,
+  /// for each macro argument, the list of tokens that were provided to the
+  /// invocation.
+  MacroArgs *Args = 0;
+
+  // Remember where the end of the expansion occurred.  For an object-like
+  // macro, this is the identifier.  For a function-like macro, this is the ')'.
+  SourceLocation ExpansionEnd = Identifier.getLocation();
+
+  // If this is a function-like macro, read the arguments.
+  if (MI->isFunctionLike()) {
+    // C99 6.10.3p10: If the preprocessing token immediately after the macro
+    // name isn't a '(', this macro should not be expanded.
+    if (!isNextPPTokenLParen())
+      return true;
+
+    // Remember that we are now parsing the arguments to a macro invocation.
+    // Preprocessor directives used inside macro arguments are not portable, and
+    // this enables the warning.
+    InMacroArgs = true;
+    Args = ReadFunctionLikeMacroArgs(Identifier, MI, ExpansionEnd);
+
+    // Finished parsing args.
+    InMacroArgs = false;
+
+    // If there was an error parsing the arguments, bail out.
+    if (Args == 0) return false;
+
+    ++NumFnMacroExpanded;
+  } else {
+    ++NumMacroExpanded;
+  }
+
+  // Notice that this macro has been used.
+  markMacroAsUsed(MI);
+
+  // Remember where the token is expanded.
+  SourceLocation ExpandLoc = Identifier.getLocation();
+  SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);
+
+  if (Callbacks) {
+    if (InMacroArgs) {
+      // We can have macro expansion inside a conditional directive while
+      // reading the function macro arguments. To ensure, in that case, that
+      // MacroExpands callbacks still happen in source order, queue this
+      // callback to have it happen after the function macro callback.
+      DelayedMacroExpandsCallbacks.push_back(
+                              MacroExpandsInfo(Identifier, MI, ExpansionRange));
+    } else {
+      Callbacks->MacroExpands(Identifier, MI, ExpansionRange);
+      if (!DelayedMacroExpandsCallbacks.empty()) {
+        for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
+          MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
+          Callbacks->MacroExpands(Info.Tok, Info.MI, Info.Range);
+        }
+        DelayedMacroExpandsCallbacks.clear();
+      }
+    }
+  }
+  
+  // If we started lexing a macro, enter the macro expansion body.
+
+  // If this macro expands to no tokens, don't bother to push it onto the
+  // expansion stack, only to take it right back off.
+  if (MI->getNumTokens() == 0) {
+    // No need for arg info.
+    if (Args) Args->destroy(*this);
+
+    // Ignore this macro use, just return the next token in the current
+    // buffer.
+    bool HadLeadingSpace = Identifier.hasLeadingSpace();
+    bool IsAtStartOfLine = Identifier.isAtStartOfLine();
+
+    Lex(Identifier);
+
+    // If the identifier isn't on some OTHER line, inherit the leading
+    // whitespace/first-on-a-line property of this token.  This handles
+    // stuff like "! XX," -> "! ," and "   XX," -> "    ,", when XX is
+    // empty.
+    if (!Identifier.isAtStartOfLine()) {
+      if (IsAtStartOfLine) Identifier.setFlag(Token::StartOfLine);
+      if (HadLeadingSpace) Identifier.setFlag(Token::LeadingSpace);
+    }
+    Identifier.setFlag(Token::LeadingEmptyMacro);
+    ++NumFastMacroExpanded;
+    return false;
+
+  } else if (MI->getNumTokens() == 1 &&
+             isTrivialSingleTokenExpansion(MI, Identifier.getIdentifierInfo(),
+                                           *this)) {
+    // Otherwise, if this macro expands into a single trivially-expanded
+    // token: expand it now.  This handles common cases like
+    // "#define VAL 42".
+
+    // No need for arg info.
+    if (Args) Args->destroy(*this);
+
+    // Propagate the isAtStartOfLine/hasLeadingSpace markers of the macro
+    // identifier to the expanded token.
+    bool isAtStartOfLine = Identifier.isAtStartOfLine();
+    bool hasLeadingSpace = Identifier.hasLeadingSpace();
+
+    // Replace the result token.
+    Identifier = MI->getReplacementToken(0);
+
+    // Restore the StartOfLine/LeadingSpace markers.
+    Identifier.setFlagValue(Token::StartOfLine , isAtStartOfLine);
+    Identifier.setFlagValue(Token::LeadingSpace, hasLeadingSpace);
+
+    // Update the tokens location to include both its expansion and physical
+    // locations.
+    SourceLocation Loc =
+      SourceMgr.createExpansionLoc(Identifier.getLocation(), ExpandLoc,
+                                   ExpansionEnd,Identifier.getLength());
+    Identifier.setLocation(Loc);
+
+    // If this is a disabled macro or #define X X, we must mark the result as
+    // unexpandable.
+    if (IdentifierInfo *NewII = Identifier.getIdentifierInfo()) {
+      if (MacroInfo *NewMI = getMacroInfo(NewII))
+        if (!NewMI->isEnabled() || NewMI == MI) {
+          Identifier.setFlag(Token::DisableExpand);
+          Diag(Identifier, diag::pp_disabled_macro_expansion);
+        }
+    }
+
+    // Since this is not an identifier token, it can't be macro expanded, so
+    // we're done.
+    ++NumFastMacroExpanded;
+    return false;
+  }
+
+  // Start expanding the macro.
+  EnterMacro(Identifier, ExpansionEnd, MI, Args);
+
+  // Now that the macro is at the top of the include stack, ask the
+  // preprocessor to read the next token from it.
+  Lex(Identifier);
+  return false;
+}
+
+/// ReadFunctionLikeMacroArgs - After reading "MACRO" and knowing that the next
+/// token is the '(' of the macro, this method is invoked to read all of the
+/// actual arguments specified for the macro invocation.  This returns null on
+/// error.
+MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
+                                                   MacroInfo *MI,
+                                                   SourceLocation &MacroEnd) {
+  // The number of fixed arguments to parse.
+  unsigned NumFixedArgsLeft = MI->getNumArgs();
+  bool isVariadic = MI->isVariadic();
+
+  // Outer loop, while there are more arguments, keep reading them.
+  Token Tok;
+
+  // Read arguments as unexpanded tokens.  This avoids issues, e.g., where
+  // an argument value in a macro could expand to ',' or '(' or ')'.
+  LexUnexpandedToken(Tok);
+  assert(Tok.is(tok::l_paren) && "Error computing l-paren-ness?");
+
+  // ArgTokens - Build up a list of tokens that make up each argument.  Each
+  // argument is separated by an EOF token.  Use a SmallVector so we can avoid
+  // heap allocations in the common case.
+  SmallVector<Token, 64> ArgTokens;
+
+  unsigned NumActuals = 0;
+  while (Tok.isNot(tok::r_paren)) {
+    assert((Tok.is(tok::l_paren) || Tok.is(tok::comma)) &&
+           "only expect argument separators here");
+
+    unsigned ArgTokenStart = ArgTokens.size();
+    SourceLocation ArgStartLoc = Tok.getLocation();
+
+    // C99 6.10.3p11: Keep track of the number of l_parens we have seen.  Note
+    // that we already consumed the first one.
+    unsigned NumParens = 0;
+
+    while (1) {
+      // Read arguments as unexpanded tokens.  This avoids issues, e.g., where
+      // an argument value in a macro could expand to ',' or '(' or ')'.
+      LexUnexpandedToken(Tok);
+
+      if (Tok.is(tok::eof) || Tok.is(tok::eod)) { // "#if f(<eof>" & "#if f(\n"
+        Diag(MacroName, diag::err_unterm_macro_invoc);
+        // Do not lose the EOF/EOD.  Return it to the client.
+        MacroName = Tok;
+        return 0;
+      } else if (Tok.is(tok::r_paren)) {
+        // If we found the ) token, the macro arg list is done.
+        if (NumParens-- == 0) {
+          MacroEnd = Tok.getLocation();
+          break;
+        }
+      } else if (Tok.is(tok::l_paren)) {
+        ++NumParens;
+      // In Microsoft-compatibility mode, commas from nested macro expan-
+      // sions should not be considered as argument separators. We test
+      // for this with the IgnoredComma token flag.
+      } else if (Tok.is(tok::comma)
+          && !(Tok.getFlags() & Token::IgnoredComma) && NumParens == 0) {
+        // Comma ends this argument if there are more fixed arguments expected.
+        // However, if this is a variadic macro, and this is part of the
+        // variadic part, then the comma is just an argument token.
+        if (!isVariadic) break;
+        if (NumFixedArgsLeft > 1)
+          break;
+      } else if (Tok.is(tok::comment) && !KeepMacroComments) {
+        // If this is a comment token in the argument list and we're just in
+        // -C mode (not -CC mode), discard the comment.
+        continue;
+      } else if (Tok.getIdentifierInfo() != 0) {
+        // Reading macro arguments can cause macros that we are currently
+        // expanding from to be popped off the expansion stack.  Doing so causes
+        // them to be reenabled for expansion.  Here we record whether any
+        // identifiers we lex as macro arguments correspond to disabled macros.
+        // If so, we mark the token as noexpand.  This is a subtle aspect of
+        // C99 6.10.3.4p2.
+        if (MacroInfo *MI = getMacroInfo(Tok.getIdentifierInfo()))
+          if (!MI->isEnabled())
+            Tok.setFlag(Token::DisableExpand);
+      } else if (Tok.is(tok::code_completion)) {
+        if (CodeComplete)
+          CodeComplete->CodeCompleteMacroArgument(MacroName.getIdentifierInfo(),
+                                                  MI, NumActuals);
+        // Don't mark that we reached the code-completion point because the
+        // parser is going to handle the token and there will be another
+        // code-completion callback.
+      }
+
+      ArgTokens.push_back(Tok);
+    }
+
+    // If this was an empty argument list foo(), don't add this as an empty
+    // argument.
+    if (ArgTokens.empty() && Tok.getKind() == tok::r_paren)
+      break;
+
+    // If this is not a variadic macro, and too many args were specified, emit
+    // an error.
+    if (!isVariadic && NumFixedArgsLeft == 0) {
+      if (ArgTokens.size() != ArgTokenStart)
+        ArgStartLoc = ArgTokens[ArgTokenStart].getLocation();
+
+      // Emit the diagnostic at the macro name in case there is a missing ).
+      // Emitting it at the , could be far away from the macro name.
+      Diag(ArgStartLoc, diag::err_too_many_args_in_macro_invoc);
+      return 0;
+    }
+
+    // Empty arguments are standard in C99 and C++0x, and are supported as an extension in
+    // other modes.
+    if (ArgTokens.size() == ArgTokenStart && !LangOpts.C99)
+      Diag(Tok, LangOpts.CPlusPlus0x ?
+           diag::warn_cxx98_compat_empty_fnmacro_arg :
+           diag::ext_empty_fnmacro_arg);
+
+    // Add a marker EOF token to the end of the token list for this argument.
+    Token EOFTok;
+    EOFTok.startToken();
+    EOFTok.setKind(tok::eof);
+    EOFTok.setLocation(Tok.getLocation());
+    EOFTok.setLength(0);
+    ArgTokens.push_back(EOFTok);
+    ++NumActuals;
+    assert(NumFixedArgsLeft != 0 && "Too many arguments parsed");
+    --NumFixedArgsLeft;
+  }
+
+  // Okay, we either found the r_paren.  Check to see if we parsed too few
+  // arguments.
+  unsigned MinArgsExpected = MI->getNumArgs();
+
+  // See MacroArgs instance var for description of this.
+  bool isVarargsElided = false;
+
+  if (NumActuals < MinArgsExpected) {
+    // There are several cases where too few arguments is ok, handle them now.
+    if (NumActuals == 0 && MinArgsExpected == 1) {
+      // #define A(X)  or  #define A(...)   ---> A()
+
+      // If there is exactly one argument, and that argument is missing,
+      // then we have an empty "()" argument empty list.  This is fine, even if
+      // the macro expects one argument (the argument is just empty).
+      isVarargsElided = MI->isVariadic();
+    } else if (MI->isVariadic() &&
+               (NumActuals+1 == MinArgsExpected ||  // A(x, ...) -> A(X)
+                (NumActuals == 0 && MinArgsExpected == 2))) {// A(x,...) -> A()
+      // Varargs where the named vararg parameter is missing: OK as extension.
+      //   #define A(x, ...)
+      //   A("blah")
+      Diag(Tok, diag::ext_missing_varargs_arg);
+      Diag(MI->getDefinitionLoc(), diag::note_macro_here)
+        << MacroName.getIdentifierInfo();
+
+      // Remember this occurred, allowing us to elide the comma when used for
+      // cases like:
+      //   #define A(x, foo...) blah(a, ## foo)
+      //   #define B(x, ...) blah(a, ## __VA_ARGS__)
+      //   #define C(...) blah(a, ## __VA_ARGS__)
+      //  A(x) B(x) C()
+      isVarargsElided = true;
+    } else {
+      // Otherwise, emit the error.
+      Diag(Tok, diag::err_too_few_args_in_macro_invoc);
+      return 0;
+    }
+
+    // Add a marker EOF token to the end of the token list for this argument.
+    SourceLocation EndLoc = Tok.getLocation();
+    Tok.startToken();
+    Tok.setKind(tok::eof);
+    Tok.setLocation(EndLoc);
+    Tok.setLength(0);
+    ArgTokens.push_back(Tok);
+
+    // If we expect two arguments, add both as empty.
+    if (NumActuals == 0 && MinArgsExpected == 2)
+      ArgTokens.push_back(Tok);
+
+  } else if (NumActuals > MinArgsExpected && !MI->isVariadic()) {
+    // Emit the diagnostic at the macro name in case there is a missing ).
+    // Emitting it at the , could be far away from the macro name.
+    Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
+    return 0;
+  }
+
+  return MacroArgs::create(MI, ArgTokens, isVarargsElided, *this);
+}
+
+/// \brief Keeps macro expanded tokens for TokenLexers.
+//
+/// Works like a stack; a TokenLexer adds the macro expanded tokens that is
+/// going to lex in the cache and when it finishes the tokens are removed
+/// from the end of the cache.
+Token *Preprocessor::cacheMacroExpandedTokens(TokenLexer *tokLexer,
+                                              ArrayRef<Token> tokens) {
+  assert(tokLexer);
+  if (tokens.empty())
+    return 0;
+
+  size_t newIndex = MacroExpandedTokens.size();
+  bool cacheNeedsToGrow = tokens.size() >
+                      MacroExpandedTokens.capacity()-MacroExpandedTokens.size(); 
+  MacroExpandedTokens.append(tokens.begin(), tokens.end());
+
+  if (cacheNeedsToGrow) {
+    // Go through all the TokenLexers whose 'Tokens' pointer points in the
+    // buffer and update the pointers to the (potential) new buffer array.
+    for (unsigned i = 0, e = MacroExpandingLexersStack.size(); i != e; ++i) {
+      TokenLexer *prevLexer;
+      size_t tokIndex;
+      llvm::tie(prevLexer, tokIndex) = MacroExpandingLexersStack[i];
+      prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
+    }
+  }
+
+  MacroExpandingLexersStack.push_back(std::make_pair(tokLexer, newIndex));
+  return MacroExpandedTokens.data() + newIndex;
+}
+
+void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() {
+  assert(!MacroExpandingLexersStack.empty());
+  size_t tokIndex = MacroExpandingLexersStack.back().second;
+  assert(tokIndex < MacroExpandedTokens.size());
+  // Pop the cached macro expanded tokens from the end.
+  MacroExpandedTokens.resize(tokIndex);
+  MacroExpandingLexersStack.pop_back();
+}
+
+/// ComputeDATE_TIME - Compute the current time, enter it into the specified
+/// scratch buffer, then return DATELoc/TIMELoc locations with the position of
+/// the identifier tokens inserted.
+static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
+                             Preprocessor &PP) {
+  time_t TT = time(0);
+  struct tm *TM = localtime(&TT);
+
+  static const char * const Months[] = {
+    "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
+  };
+
+  char TmpBuffer[32];
+#ifdef LLVM_ON_WIN32
+  sprintf(TmpBuffer, "\"%s %2d %4d\"", Months[TM->tm_mon], TM->tm_mday,
+          TM->tm_year+1900);
+#else
+  snprintf(TmpBuffer, sizeof(TmpBuffer), "\"%s %2d %4d\"", Months[TM->tm_mon], TM->tm_mday,
+          TM->tm_year+1900);
+#endif
+
+  Token TmpTok;
+  TmpTok.startToken();
+  PP.CreateString(TmpBuffer, strlen(TmpBuffer), TmpTok);
+  DATELoc = TmpTok.getLocation();
+
+#ifdef LLVM_ON_WIN32
+  sprintf(TmpBuffer, "\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min, TM->tm_sec);
+#else
+  snprintf(TmpBuffer, sizeof(TmpBuffer), "\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min, TM->tm_sec);
+#endif
+  PP.CreateString(TmpBuffer, strlen(TmpBuffer), TmpTok);
+  TIMELoc = TmpTok.getLocation();
+}
+
+
+/// HasFeature - Return true if we recognize and implement the feature
+/// specified by the identifier as a standard language feature.
+static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
+  const LangOptions &LangOpts = PP.getLangOpts();
+  StringRef Feature = II->getName();
+
+  // Normalize the feature name, __foo__ becomes foo.
+  if (Feature.startswith("__") && Feature.endswith("__") && Feature.size() >= 4)
+    Feature = Feature.substr(2, Feature.size() - 4);
+
+  return llvm::StringSwitch<bool>(Feature)
+           .Case("address_sanitizer", LangOpts.AddressSanitizer)
+           .Case("attribute_analyzer_noreturn", true)
+           .Case("attribute_availability", true)
+           .Case("attribute_availability_with_message", true)
+           .Case("attribute_cf_returns_not_retained", true)
+           .Case("attribute_cf_returns_retained", true)
+           .Case("attribute_deprecated_with_message", true)
+           .Case("attribute_ext_vector_type", true)
+           .Case("attribute_ns_returns_not_retained", true)
+           .Case("attribute_ns_returns_retained", true)
+           .Case("attribute_ns_consumes_self", true)
+           .Case("attribute_ns_consumed", true)
+           .Case("attribute_cf_consumed", true)
+           .Case("attribute_objc_ivar_unused", true)
+           .Case("attribute_objc_method_family", true)
+           .Case("attribute_overloadable", true)
+           .Case("attribute_unavailable_with_message", true)
+           .Case("attribute_unused_on_fields", true)
+           .Case("blocks", LangOpts.Blocks)
+           .Case("cxx_exceptions", LangOpts.Exceptions)
+           .Case("cxx_rtti", LangOpts.RTTI)
+           .Case("enumerator_attributes", true)
+           // Objective-C features
+           .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
+           .Case("objc_arc", LangOpts.ObjCAutoRefCount)
+           .Case("objc_arc_weak", LangOpts.ObjCARCWeak)
+           .Case("objc_default_synthesize_properties", LangOpts.ObjC2)
+           .Case("objc_fixed_enum", LangOpts.ObjC2)
+           .Case("objc_instancetype", LangOpts.ObjC2)
+           .Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules)
+           .Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile())
+           .Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport())
+           .Case("ownership_holds", true)
+           .Case("ownership_returns", true)
+           .Case("ownership_takes", true)
+           .Case("objc_bool", true)
+           .Case("objc_subscripting", LangOpts.ObjCRuntime.isNonFragile())
+           .Case("objc_array_literals", LangOpts.ObjC2)
+           .Case("objc_dictionary_literals", LangOpts.ObjC2)
+           .Case("objc_boxed_expressions", LangOpts.ObjC2)
+           .Case("arc_cf_code_audited", true)
+           // C11 features
+           .Case("c_alignas", LangOpts.C11)
+           .Case("c_atomic", LangOpts.C11)
+           .Case("c_generic_selections", LangOpts.C11)
+           .Case("c_static_assert", LangOpts.C11)
+           // C++11 features
+           .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus0x)
+           .Case("cxx_alias_templates", LangOpts.CPlusPlus0x)
+           .Case("cxx_alignas", LangOpts.CPlusPlus0x)
+           .Case("cxx_atomic", LangOpts.CPlusPlus0x)
+           .Case("cxx_attributes", LangOpts.CPlusPlus0x)
+           .Case("cxx_auto_type", LangOpts.CPlusPlus0x)
+           .Case("cxx_constexpr", LangOpts.CPlusPlus0x)
+           .Case("cxx_decltype", LangOpts.CPlusPlus0x)
+           .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus0x)
+           .Case("cxx_default_function_template_args", LangOpts.CPlusPlus0x)
+           .Case("cxx_defaulted_functions", LangOpts.CPlusPlus0x)
+           .Case("cxx_delegating_constructors", LangOpts.CPlusPlus0x)
+           .Case("cxx_deleted_functions", LangOpts.CPlusPlus0x)
+           .Case("cxx_explicit_conversions", LangOpts.CPlusPlus0x)
+           .Case("cxx_generalized_initializers", LangOpts.CPlusPlus0x)
+           .Case("cxx_implicit_moves", LangOpts.CPlusPlus0x)
+         //.Case("cxx_inheriting_constructors", false)
+           .Case("cxx_inline_namespaces", LangOpts.CPlusPlus0x)
+           .Case("cxx_lambdas", LangOpts.CPlusPlus0x)
+           .Case("cxx_local_type_template_args", LangOpts.CPlusPlus0x)
+           .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus0x)
+           .Case("cxx_noexcept", LangOpts.CPlusPlus0x)
+           .Case("cxx_nullptr", LangOpts.CPlusPlus0x)
+           .Case("cxx_override_control", LangOpts.CPlusPlus0x)
+           .Case("cxx_range_for", LangOpts.CPlusPlus0x)
+           .Case("cxx_raw_string_literals", LangOpts.CPlusPlus0x)
+           .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus0x)
+           .Case("cxx_rvalue_references", LangOpts.CPlusPlus0x)
+           .Case("cxx_strong_enums", LangOpts.CPlusPlus0x)
+           .Case("cxx_static_assert", LangOpts.CPlusPlus0x)
+           .Case("cxx_trailing_return", LangOpts.CPlusPlus0x)
+           .Case("cxx_unicode_literals", LangOpts.CPlusPlus0x)
+           .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus0x)
+           .Case("cxx_user_literals", LangOpts.CPlusPlus0x)
+           .Case("cxx_variadic_templates", LangOpts.CPlusPlus0x)
+           // Type traits
+           .Case("has_nothrow_assign", LangOpts.CPlusPlus)
+           .Case("has_nothrow_copy", LangOpts.CPlusPlus)
+           .Case("has_nothrow_constructor", LangOpts.CPlusPlus)
+           .Case("has_trivial_assign", LangOpts.CPlusPlus)
+           .Case("has_trivial_copy", LangOpts.CPlusPlus)
+           .Case("has_trivial_constructor", LangOpts.CPlusPlus)
+           .Case("has_trivial_destructor", LangOpts.CPlusPlus)
+           .Case("has_virtual_destructor", LangOpts.CPlusPlus)
+           .Case("is_abstract", LangOpts.CPlusPlus)
+           .Case("is_base_of", LangOpts.CPlusPlus)
+           .Case("is_class", LangOpts.CPlusPlus)
+           .Case("is_convertible_to", LangOpts.CPlusPlus)
+            // __is_empty is available only if the horrible
+            // "struct __is_empty" parsing hack hasn't been needed in this
+            // translation unit. If it has, __is_empty reverts to a normal
+            // identifier and __has_feature(is_empty) evaluates false.
+           .Case("is_empty", LangOpts.CPlusPlus)
+           .Case("is_enum", LangOpts.CPlusPlus)
+           .Case("is_final", LangOpts.CPlusPlus)
+           .Case("is_literal", LangOpts.CPlusPlus)
+           .Case("is_standard_layout", LangOpts.CPlusPlus)
+           .Case("is_pod", LangOpts.CPlusPlus)
+           .Case("is_polymorphic", LangOpts.CPlusPlus)
+           .Case("is_trivial", LangOpts.CPlusPlus)
+           .Case("is_trivially_assignable", LangOpts.CPlusPlus)
+           .Case("is_trivially_constructible", LangOpts.CPlusPlus)
+           .Case("is_trivially_copyable", LangOpts.CPlusPlus)
+           .Case("is_union", LangOpts.CPlusPlus)
+           .Case("modules", LangOpts.Modules)
+           .Case("tls", PP.getTargetInfo().isTLSSupported())
+           .Case("underlying_type", LangOpts.CPlusPlus)
+           .Default(false);
+}
+
+/// HasExtension - Return true if we recognize and implement the feature
+/// specified by the identifier, either as an extension or a standard language
+/// feature.
+static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) {
+  if (HasFeature(PP, II))
+    return true;
+
+  // If the use of an extension results in an error diagnostic, extensions are
+  // effectively unavailable, so just return false here.
+  if (PP.getDiagnostics().getExtensionHandlingBehavior() ==
+      DiagnosticsEngine::Ext_Error)
+    return false;
+
+  const LangOptions &LangOpts = PP.getLangOpts();
+  StringRef Extension = II->getName();
+
+  // Normalize the extension name, __foo__ becomes foo.
+  if (Extension.startswith("__") && Extension.endswith("__") &&
+      Extension.size() >= 4)
+    Extension = Extension.substr(2, Extension.size() - 4);
+
+  // Because we inherit the feature list from HasFeature, this string switch
+  // must be less restrictive than HasFeature's.
+  return llvm::StringSwitch<bool>(Extension)
+           // C11 features supported by other languages as extensions.
+           .Case("c_alignas", true)
+           .Case("c_atomic", true)
+           .Case("c_generic_selections", true)
+           .Case("c_static_assert", true)
+           // C++0x features supported by other languages as extensions.
+           .Case("cxx_atomic", LangOpts.CPlusPlus)
+           .Case("cxx_deleted_functions", LangOpts.CPlusPlus)
+           .Case("cxx_explicit_conversions", LangOpts.CPlusPlus)
+           .Case("cxx_inline_namespaces", LangOpts.CPlusPlus)
+           .Case("cxx_local_type_template_args", LangOpts.CPlusPlus)
+           .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus)
+           .Case("cxx_override_control", LangOpts.CPlusPlus)
+           .Case("cxx_range_for", LangOpts.CPlusPlus)
+           .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus)
+           .Case("cxx_rvalue_references", LangOpts.CPlusPlus)
+           .Default(false);
+}
+
+/// HasAttribute -  Return true if we recognize and implement the attribute
+/// specified by the given identifier.
+static bool HasAttribute(const IdentifierInfo *II) {
+  StringRef Name = II->getName();
+  // Normalize the attribute name, __foo__ becomes foo.
+  if (Name.startswith("__") && Name.endswith("__") && Name.size() >= 4)
+    Name = Name.substr(2, Name.size() - 4);
+
+  // FIXME: Do we need to handle namespaces here?
+  return llvm::StringSwitch<bool>(Name)
+#include "clang/Lex/AttrSpellings.inc"
+        .Default(false);
+}
+
+/// EvaluateHasIncludeCommon - Process a '__has_include("path")'
+/// or '__has_include_next("path")' expression.
+/// Returns true if successful.
+static bool EvaluateHasIncludeCommon(Token &Tok,
+                                     IdentifierInfo *II, Preprocessor &PP,
+                                     const DirectoryLookup *LookupFrom) {
+  SourceLocation LParenLoc;
+
+  // Get '('.
+  PP.LexNonComment(Tok);
+
+  // Ensure we have a '('.
+  if (Tok.isNot(tok::l_paren)) {
+    PP.Diag(Tok.getLocation(), diag::err_pp_missing_lparen) << II->getName();
+    return false;
+  }
+
+  // Save '(' location for possible missing ')' message.
+  LParenLoc = Tok.getLocation();
+
+  // Get the file name.
+  PP.getCurrentLexer()->LexIncludeFilename(Tok);
+
+  // Reserve a buffer to get the spelling.
+  SmallString<128> FilenameBuffer;
+  StringRef Filename;
+  SourceLocation EndLoc;
+  
+  switch (Tok.getKind()) {
+  case tok::eod:
+    // If the token kind is EOD, the error has already been diagnosed.
+    return false;
+
+  case tok::angle_string_literal:
+  case tok::string_literal: {
+    bool Invalid = false;
+    Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid);
+    if (Invalid)
+      return false;
+    break;
+  }
+
+  case tok::less:
+    // This could be a <foo/bar.h> file coming from a macro expansion.  In this
+    // case, glue the tokens together into FilenameBuffer and interpret those.
+    FilenameBuffer.push_back('<');
+    if (PP.ConcatenateIncludeName(FilenameBuffer, EndLoc))
+      return false;   // Found <eod> but no ">"?  Diagnostic already emitted.
+    Filename = FilenameBuffer.str();
+    break;
+  default:
+    PP.Diag(Tok.getLocation(), diag::err_pp_expects_filename);
+    return false;
+  }
+
+  // Get ')'.
+  PP.LexNonComment(Tok);
+
+  // Ensure we have a trailing ).
+  if (Tok.isNot(tok::r_paren)) {
+    PP.Diag(Tok.getLocation(), diag::err_pp_missing_rparen) << II->getName();
+    PP.Diag(LParenLoc, diag::note_matching) << "(";
+    return false;
+  }
+
+  bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename);
+  // If GetIncludeFilenameSpelling set the start ptr to null, there was an
+  // error.
+  if (Filename.empty())
+    return false;
+
+  // Search include directories.
+  const DirectoryLookup *CurDir;
+  const FileEntry *File =
+      PP.LookupFile(Filename, isAngled, LookupFrom, CurDir, NULL, NULL, NULL);
+
+  // Get the result value.  A result of true means the file exists.
+  return File != 0;
+}
+
+/// EvaluateHasInclude - Process a '__has_include("path")' expression.
+/// Returns true if successful.
+static bool EvaluateHasInclude(Token &Tok, IdentifierInfo *II,
+                               Preprocessor &PP) {
+  return EvaluateHasIncludeCommon(Tok, II, PP, NULL);
+}
+
+/// EvaluateHasIncludeNext - Process '__has_include_next("path")' expression.
+/// Returns true if successful.
+static bool EvaluateHasIncludeNext(Token &Tok,
+                                   IdentifierInfo *II, Preprocessor &PP) {
+  // __has_include_next is like __has_include, except that we start
+  // searching after the current found directory.  If we can't do this,
+  // issue a diagnostic.
+  const DirectoryLookup *Lookup = PP.GetCurDirLookup();
+  if (PP.isInPrimaryFile()) {
+    Lookup = 0;
+    PP.Diag(Tok, diag::pp_include_next_in_primary);
+  } else if (Lookup == 0) {
+    PP.Diag(Tok, diag::pp_include_next_absolute_path);
+  } else {
+    // Start looking up in the next directory.
+    ++Lookup;
+  }
+
+  return EvaluateHasIncludeCommon(Tok, II, PP, Lookup);
+}
+
+/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
+/// as a builtin macro, handle it and return the next token as 'Tok'.
+void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
+  // Figure out which token this is.
+  IdentifierInfo *II = Tok.getIdentifierInfo();
+  assert(II && "Can't be a macro without id info!");
+
+  // If this is an _Pragma or Microsoft __pragma directive, expand it,
+  // invoke the pragma handler, then lex the token after it.
+  if (II == Ident_Pragma)
+    return Handle_Pragma(Tok);
+  else if (II == Ident__pragma) // in non-MS mode this is null
+    return HandleMicrosoft__pragma(Tok);
+
+  ++NumBuiltinMacroExpanded;
+
+  SmallString<128> TmpBuffer;
+  llvm::raw_svector_ostream OS(TmpBuffer);
+
+  // Set up the return result.
+  Tok.setIdentifierInfo(0);
+  Tok.clearFlag(Token::NeedsCleaning);
+
+  if (II == Ident__LINE__) {
+    // C99 6.10.8: "__LINE__: The presumed line number (within the current
+    // source file) of the current source line (an integer constant)".  This can
+    // be affected by #line.
+    SourceLocation Loc = Tok.getLocation();
+
+    // Advance to the location of the first _, this might not be the first byte
+    // of the token if it starts with an escaped newline.
+    Loc = AdvanceToTokenCharacter(Loc, 0);
+
+    // One wrinkle here is that GCC expands __LINE__ to location of the *end* of
+    // a macro expansion.  This doesn't matter for object-like macros, but
+    // can matter for a function-like macro that expands to contain __LINE__.
+    // Skip down through expansion points until we find a file loc for the
+    // end of the expansion history.
+    Loc = SourceMgr.getExpansionRange(Loc).second;
+    PresumedLoc PLoc = SourceMgr.getPresumedLoc(Loc);
+
+    // __LINE__ expands to a simple numeric value.
+    OS << (PLoc.isValid()? PLoc.getLine() : 1);
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) {
+    // C99 6.10.8: "__FILE__: The presumed name of the current source file (a
+    // character string literal)". This can be affected by #line.
+    PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
+
+    // __BASE_FILE__ is a GNU extension that returns the top of the presumed
+    // #include stack instead of the current file.
+    if (II == Ident__BASE_FILE__ && PLoc.isValid()) {
+      SourceLocation NextLoc = PLoc.getIncludeLoc();
+      while (NextLoc.isValid()) {
+        PLoc = SourceMgr.getPresumedLoc(NextLoc);
+        if (PLoc.isInvalid())
+          break;
+        
+        NextLoc = PLoc.getIncludeLoc();
+      }
+    }
+
+    // Escape this filename.  Turn '\' -> '\\' '"' -> '\"'
+    SmallString<128> FN;
+    if (PLoc.isValid()) {
+      FN += PLoc.getFilename();
+      Lexer::Stringify(FN);
+      OS << '"' << FN.str() << '"';
+    }
+    Tok.setKind(tok::string_literal);
+  } else if (II == Ident__DATE__) {
+    if (!DATELoc.isValid())
+      ComputeDATE_TIME(DATELoc, TIMELoc, *this);
+    Tok.setKind(tok::string_literal);
+    Tok.setLength(strlen("\"Mmm dd yyyy\""));
+    Tok.setLocation(SourceMgr.createExpansionLoc(DATELoc, Tok.getLocation(),
+                                                 Tok.getLocation(),
+                                                 Tok.getLength()));
+    return;
+  } else if (II == Ident__TIME__) {
+    if (!TIMELoc.isValid())
+      ComputeDATE_TIME(DATELoc, TIMELoc, *this);
+    Tok.setKind(tok::string_literal);
+    Tok.setLength(strlen("\"hh:mm:ss\""));
+    Tok.setLocation(SourceMgr.createExpansionLoc(TIMELoc, Tok.getLocation(),
+                                                 Tok.getLocation(),
+                                                 Tok.getLength()));
+    return;
+  } else if (II == Ident__INCLUDE_LEVEL__) {
+    // Compute the presumed include depth of this token.  This can be affected
+    // by GNU line markers.
+    unsigned Depth = 0;
+
+    PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());
+    if (PLoc.isValid()) {
+      PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
+      for (; PLoc.isValid(); ++Depth)
+        PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());
+    }
+
+    // __INCLUDE_LEVEL__ expands to a simple numeric value.
+    OS << Depth;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__TIMESTAMP__) {
+    // MSVC, ICC, GCC, VisualAge C++ extension.  The generated string should be
+    // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
+
+    // Get the file that we are lexing out of.  If we're currently lexing from
+    // a macro, dig into the include stack.
+    const FileEntry *CurFile = 0;
+    PreprocessorLexer *TheLexer = getCurrentFileLexer();
+
+    if (TheLexer)
+      CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID());
+
+    const char *Result;
+    if (CurFile) {
+      time_t TT = CurFile->getModificationTime();
+      struct tm *TM = localtime(&TT);
+      Result = asctime(TM);
+    } else {
+      Result = "??? ??? ?? ??:??:?? ????\n";
+    }
+    // Surround the string with " and strip the trailing newline.
+    OS << '"' << StringRef(Result, strlen(Result)-1) << '"';
+    Tok.setKind(tok::string_literal);
+  } else if (II == Ident__COUNTER__) {
+    // __COUNTER__ expands to a simple numeric value.
+    OS << CounterValue++;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__has_feature   ||
+             II == Ident__has_extension ||
+             II == Ident__has_builtin   ||
+             II == Ident__has_attribute) {
+    // The argument to these builtins should be a parenthesized identifier.
+    SourceLocation StartLoc = Tok.getLocation();
+
+    bool IsValid = false;
+    IdentifierInfo *FeatureII = 0;
+
+    // Read the '('.
+    Lex(Tok);
+    if (Tok.is(tok::l_paren)) {
+      // Read the identifier
+      Lex(Tok);
+      if (Tok.is(tok::identifier) || Tok.is(tok::kw_const)) {
+        FeatureII = Tok.getIdentifierInfo();
+
+        // Read the ')'.
+        Lex(Tok);
+        if (Tok.is(tok::r_paren))
+          IsValid = true;
+      }
+    }
+
+    bool Value = false;
+    if (!IsValid)
+      Diag(StartLoc, diag::err_feature_check_malformed);
+    else if (II == Ident__has_builtin) {
+      // Check for a builtin is trivial.
+      Value = FeatureII->getBuiltinID() != 0;
+    } else if (II == Ident__has_attribute)
+      Value = HasAttribute(FeatureII);
+    else if (II == Ident__has_extension)
+      Value = HasExtension(*this, FeatureII);
+    else {
+      assert(II == Ident__has_feature && "Must be feature check");
+      Value = HasFeature(*this, FeatureII);
+    }
+
+    OS << (int)Value;
+    if (IsValid)
+      Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__has_include ||
+             II == Ident__has_include_next) {
+    // The argument to these two builtins should be a parenthesized
+    // file name string literal using angle brackets (<>) or
+    // double-quotes ("").
+    bool Value;
+    if (II == Ident__has_include)
+      Value = EvaluateHasInclude(Tok, II, *this);
+    else
+      Value = EvaluateHasIncludeNext(Tok, II, *this);
+    OS << (int)Value;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__has_warning) {
+    // The argument should be a parenthesized string literal.
+    // The argument to these builtins should be a parenthesized identifier.
+    SourceLocation StartLoc = Tok.getLocation();    
+    bool IsValid = false;
+    bool Value = false;
+    // Read the '('.
+    Lex(Tok);
+    do {
+      if (Tok.is(tok::l_paren)) {      
+        // Read the string.
+        Lex(Tok);
+      
+        // We need at least one string literal.
+        if (!Tok.is(tok::string_literal)) {
+          StartLoc = Tok.getLocation();
+          IsValid = false;
+          // Eat tokens until ')'.
+          do Lex(Tok); while (!(Tok.is(tok::r_paren) || Tok.is(tok::eod)));
+          break;
+        }
+        
+        // String concatenation allows multiple strings, which can even come
+        // from macro expansion.
+        SmallVector<Token, 4> StrToks;
+        while (Tok.is(tok::string_literal)) {
+          // Complain about, and drop, any ud-suffix.
+          if (Tok.hasUDSuffix())
+            Diag(Tok, diag::err_invalid_string_udl);
+          StrToks.push_back(Tok);
+          LexUnexpandedToken(Tok);
+        }
+        
+        // Is the end a ')'?
+        if (!(IsValid = Tok.is(tok::r_paren)))
+          break;
+        
+        // Concatenate and parse the strings.
+        StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this);
+        assert(Literal.isAscii() && "Didn't allow wide strings in");
+        if (Literal.hadError)
+          break;
+        if (Literal.Pascal) {
+          Diag(Tok, diag::warn_pragma_diagnostic_invalid);
+          break;
+        }
+        
+        StringRef WarningName(Literal.GetString());
+        
+        if (WarningName.size() < 3 || WarningName[0] != '-' ||
+            WarningName[1] != 'W') {
+          Diag(StrToks[0].getLocation(), diag::warn_has_warning_invalid_option);
+          break;
+        }
+        
+        // Finally, check if the warning flags maps to a diagnostic group.
+        // We construct a SmallVector here to talk to getDiagnosticIDs().
+        // Although we don't use the result, this isn't a hot path, and not
+        // worth special casing.
+        llvm::SmallVector<diag::kind, 10> Diags;
+        Value = !getDiagnostics().getDiagnosticIDs()->
+          getDiagnosticsInGroup(WarningName.substr(2), Diags);
+      }
+    } while (false);
+    
+    if (!IsValid)
+      Diag(StartLoc, diag::err_warning_check_malformed);
+
+    OS << (int)Value;
+    Tok.setKind(tok::numeric_constant);
+  } else {
+    llvm_unreachable("Unknown identifier!");
+  }
+  CreateString(OS.str().data(), OS.str().size(), Tok,
+               Tok.getLocation(), Tok.getLocation());
+}
+
+void Preprocessor::markMacroAsUsed(MacroInfo *MI) {
+  // If the 'used' status changed, and the macro requires 'unused' warning,
+  // remove its SourceLocation from the warn-for-unused-macro locations.
+  if (MI->isWarnIfUnused() && !MI->isUsed())
+    WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
+  MI->setIsUsed(true);
+}
diff --git a/test/Preprocessor/microsoft-ext.c b/test/Preprocessor/microsoft-ext.c
index a95ddca..5046655 100644
--- a/test/Preprocessor/microsoft-ext.c
+++ b/test/Preprocessor/microsoft-ext.c
@@ -4,4 +4,3 @@
 # define P(x, y) {x, y}
 # define M(x, y) M2(x, P(x, y))
 M(a, b) // CHECK: a + {a, b}
-
