<div class="gmail_quote">On Wed, Jun 6, 2012 at 11:52 AM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: dblaikie<br>
Date: Wed Jun  6 13:52:13 2012<br>
New Revision: 158093<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=158093&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=158093&view=rev</a><br>
Log:<br>
Add a -rewrite-includes option, which is similar to -rewrite-macros, but only expands #include directives.<br></blockquote><div><br></div><div>Woot, thanks for taking this over and driving it David.</div><div><br></div><div>
Want to mail a proposal to switch the crash-recovery stuff to produce its test cases using this instead of fully preprocessing the source? =D</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
Patch contributed by Lubos Lunak (<a href="mailto:l.lunax@suse.cz">l.lunax@suse.cz</a>).<br>
Review by Matt Beaumont-Gay (<a href="mailto:matthewbg@google.com">matthewbg@google.com</a>).<br>
<br>
Added:<br>
    cfe/trunk/lib/Rewrite/InclusionRewriter.cpp<br>
    cfe/trunk/test/Frontend/Inputs/rewrite-includes1.h<br>
    cfe/trunk/test/Frontend/Inputs/rewrite-includes2.h<br>
    cfe/trunk/test/Frontend/Inputs/rewrite-includes3.h<br>
    cfe/trunk/test/Frontend/Inputs/rewrite-includes4.h<br>
    cfe/trunk/test/Frontend/Inputs/rewrite-includes5.h<br>
    cfe/trunk/test/Frontend/Inputs/rewrite-includes6.h<br>
    cfe/trunk/test/Frontend/Inputs/rewrite-includes7.h<br>
    cfe/trunk/test/Frontend/rewrite-includes.c<br>
Modified:<br>
    cfe/trunk/include/clang/Driver/CC1Options.td<br>
    cfe/trunk/include/clang/Frontend/FrontendOptions.h<br>
    cfe/trunk/include/clang/Lex/Preprocessor.h<br>
    cfe/trunk/include/clang/Rewrite/FrontendActions.h<br>
    cfe/trunk/include/clang/Rewrite/Rewriters.h<br>
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
    cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp<br>
    cfe/trunk/lib/Lex/Lexer.cpp<br>
    cfe/trunk/lib/Lex/PPDirectives.cpp<br>
    cfe/trunk/lib/Lex/Preprocessor.cpp<br>
    cfe/trunk/lib/Rewrite/CMakeLists.txt<br>
    cfe/trunk/lib/Rewrite/FrontendActions.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Driver/CC1Options.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)<br>
+++ cfe/trunk/include/clang/Driver/CC1Options.td Wed Jun  6 13:52:13 2012<br>
@@ -332,6 +332,8 @@<br>
   HelpText<"Rewriter playground">;<br>
 def rewrite_macros : Flag<"-rewrite-macros">,<br>
   HelpText<"Expand macros without full preprocessing">;<br>
+def rewrite_includes : Flag<"-rewrite-includes">,<br>
+  HelpText<"Expand includes without full preprocessing">;<br>
 def migrate : Flag<"-migrate">,<br>
   HelpText<"Migrate source code">;<br>
 }<br>
<br>
Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original)<br>
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Wed Jun  6 13:52:13 2012<br>
@@ -43,6 +43,7 @@<br>
     PrintPreamble,          ///< Print the "preamble" of the input file<br>
     PrintPreprocessedInput, ///< -E mode.<br>
     RewriteMacros,          ///< Expand macros but not #includes.<br>
+    RewriteIncludes,        ///< Expand #includes but not macros.<br>
     RewriteObjC,            ///< ObjC->C Rewriter.<br>
     RewriteTest,            ///< Rewriter playground<br>
     RunAnalysis,            ///< Run one or more source code analyses.<br>
<br>
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)<br>
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Wed Jun  6 13:52:13 2012<br>
@@ -121,6 +121,13 @@<br>
   /// DisableMacroExpansion - True if macro expansion is disabled.<br>
   bool DisableMacroExpansion : 1;<br>
<br>
+  /// MacroExpansionInDirectivesOverride - Temporarily disables<br>
+  /// DisableMacroExpansion (i.e. enables expansion) when parsing preprocessor<br>
+  /// directives.<br>
+  bool MacroExpansionInDirectivesOverride : 1;<br>
+<br>
+  class ResetMacroExpansionHelper;<br>
+<br>
   /// \brief Whether we have already loaded macros from the external source.<br>
   mutable bool ReadMacrosFromExternalSource : 1;<br>
<br>
@@ -643,6 +650,12 @@<br>
     while (Result.getKind() == tok::comment);<br>
   }<br>
<br>
+  /// Disables macro expansion everywhere except for preprocessor directives.<br>
+  void SetMacroExpansionOnlyInDirectives() {<br>
+    DisableMacroExpansion = true;<br>
+    MacroExpansionInDirectivesOverride = true;<br>
+  }<br>
+<br>
   /// LookAhead - This peeks ahead N tokens and returns that token without<br>
   /// consuming any tokens.  LookAhead(0) returns the next token that would be<br>
   /// returned by Lex(), LookAhead(1) returns the token after it, etc.  This<br>
<br>
Modified: cfe/trunk/include/clang/Rewrite/FrontendActions.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/FrontendActions.h?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/FrontendActions.h?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Rewrite/FrontendActions.h (original)<br>
+++ cfe/trunk/include/clang/Rewrite/FrontendActions.h Wed Jun  6 13:52:13 2012<br>
@@ -73,6 +73,11 @@<br>
   void ExecuteAction();<br>
 };<br>
<br>
+class RewriteIncludesAction : public PreprocessorFrontendAction {<br>
+protected:<br>
+  void ExecuteAction();<br>
+};<br>
+<br>
 }  // end namespace clang<br>
<br>
 #endif<br>
<br>
Modified: cfe/trunk/include/clang/Rewrite/Rewriters.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/Rewriters.h?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/Rewriters.h?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Rewrite/Rewriters.h (original)<br>
+++ cfe/trunk/include/clang/Rewrite/Rewriters.h Wed Jun  6 13:52:13 2012<br>
@@ -18,6 +18,7 @@<br>
<br>
 namespace clang {<br>
 class Preprocessor;<br>
+class PreprocessorOutputOptions;<br>
<br>
 /// RewriteMacrosInInput - Implement -rewrite-macros mode.<br>
 void RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS);<br>
@@ -25,6 +26,10 @@<br>
 /// DoRewriteTest - A simple test for the TokenRewriter class.<br>
 void DoRewriteTest(Preprocessor &PP, raw_ostream *OS);<br>
<br>
+/// RewriteIncludesInInput - Implement -rewrite-includes mode.<br>
+void RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,<br>
+                            const PreprocessorOutputOptions &Opts);<br>
+<br>
 }  // end namespace clang<br>
<br>
 #endif<br>
<br>
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Jun  6 13:52:13 2012<br>
@@ -445,6 +445,7 @@<br>
   case frontend::PrintPreamble:          return "-print-preamble";<br>
   case frontend::PrintPreprocessedInput: return "-E";<br>
   case frontend::RewriteMacros:          return "-rewrite-macros";<br>
+  case frontend::RewriteIncludes:        return "-rewrite-includes";<br>
   case frontend::RewriteObjC:            return "-rewrite-objc";<br>
   case frontend::RewriteTest:            return "-rewrite-test";<br>
   case frontend::RunAnalysis:            return "-analyze";<br>
@@ -1435,6 +1436,8 @@<br>
       Opts.ProgramAction = frontend::PrintPreprocessedInput; break;<br>
     case OPT_rewrite_macros:<br>
       Opts.ProgramAction = frontend::RewriteMacros; break;<br>
+    case OPT_rewrite_includes:<br>
+      Opts.ProgramAction = frontend::RewriteIncludes; break;<br>
     case OPT_rewrite_objc:<br>
       Opts.ProgramAction = frontend::RewriteObjC; break;<br>
     case OPT_rewrite_test:<br>
<br>
Modified: cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp (original)<br>
+++ cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp Wed Jun  6 13:52:13 2012<br>
@@ -73,6 +73,7 @@<br>
   case PrintPreamble:          return new PrintPreambleAction();<br>
   case PrintPreprocessedInput: return new PrintPreprocessedAction();<br>
   case RewriteMacros:          return new RewriteMacrosAction();<br>
+  case RewriteIncludes:        return new RewriteIncludesAction();<br>
   case RewriteObjC:            return new RewriteObjCAction();<br>
   case RewriteTest:            return new RewriteTestAction();<br>
   case RunAnalysis:            return new ento::AnalysisAction();<br>
<br>
Modified: cfe/trunk/lib/Lex/Lexer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Lex/Lexer.cpp (original)<br>
+++ cfe/trunk/lib/Lex/Lexer.cpp Wed Jun  6 13:52:13 2012<br>
@@ -2022,7 +2022,7 @@<br>
   // directly.<br>
   FormTokenWithChars(Result, CurPtr, tok::comment);<br>
<br>
-  if (!ParsingPreprocessorDirective)<br>
+  if (!ParsingPreprocessorDirective || LexingRawMode)<br>
     return true;<br>
<br>
   // If this BCPL-style comment is in a macro definition, transmogrify it into<br>
@@ -2626,7 +2626,8 @@<br>
       ParsingPreprocessorDirective = false;<br>
<br>
       // Restore comment saving mode, in case it was disabled for directive.<br>
-      SetCommentRetentionState(PP->getCommentRetentionState());<br>
+      if (!LexingRawMode)<br>
+        SetCommentRetentionState(PP->getCommentRetentionState());<br>
<br>
       // Since we consumed a newline, we are back at the start of a line.<br>
       IsAtStartOfLine = true;<br>
<br>
Modified: cfe/trunk/lib/Lex/PPDirectives.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)<br>
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Wed Jun  6 13:52:13 2012<br>
@@ -553,6 +553,21 @@<br>
 // Preprocessor Directive Handling.<br>
 //===----------------------------------------------------------------------===//<br>
<br>
+class Preprocessor::ResetMacroExpansionHelper {<br>
+public:<br>
+  ResetMacroExpansionHelper(Preprocessor *pp)<br>
+    : PP(pp), save(pp->DisableMacroExpansion) {<br>
+    if (pp->MacroExpansionInDirectivesOverride)<br>
+      pp->DisableMacroExpansion = false;<br>
+  }<br>
+  ~ResetMacroExpansionHelper() {<br>
+    PP->DisableMacroExpansion = save;<br>
+  }<br>
+private:<br>
+  Preprocessor *PP;<br>
+  bool save;<br>
+};<br>
+<br>
 /// HandleDirective - This callback is invoked when the lexer sees a # token<br>
 /// at the start of a line.  This consumes the directive, modifies the<br>
 /// lexer/preprocessor state, and advances the lexer(s) so that the next token<br>
@@ -604,6 +619,10 @@<br>
     Diag(Result, diag::ext_embedded_directive);<br>
   }<br>
<br>
+  // Temporarily enable macro expansion if set so<br>
+  // and reset to previous state when returning from this function.<br>
+  ResetMacroExpansionHelper helper(this);<br>
+<br>
 TryAgain:<br>
   switch (Result.getKind()) {<br>
   case tok::eod:<br>
<br>
Modified: cfe/trunk/lib/Lex/Preprocessor.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)<br>
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Wed Jun  6 13:52:13 2012<br>
@@ -86,6 +86,7 @@<br>
<br>
   // Macro expansion is enabled.<br>
   DisableMacroExpansion = false;<br>
+  MacroExpansionInDirectivesOverride = false;<br>
   InMacroArgs = false;<br>
   InMacroArgPreExpansion = false;<br>
   NumCachedTokenLexers = 0;<br>
<br>
Modified: cfe/trunk/lib/Rewrite/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/CMakeLists.txt?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/CMakeLists.txt?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Rewrite/CMakeLists.txt (original)<br>
+++ cfe/trunk/lib/Rewrite/CMakeLists.txt Wed Jun  6 13:52:13 2012<br>
@@ -6,6 +6,7 @@<br>
   FrontendActions.cpp<br>
   HTMLPrint.cpp<br>
   HTMLRewrite.cpp<br>
+  InclusionRewriter.cpp<br>
   RewriteMacros.cpp<br>
   RewriteModernObjC.cpp<br>
   RewriteObjC.cpp<br>
<br>
Modified: cfe/trunk/lib/Rewrite/FrontendActions.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/FrontendActions.cpp?rev=158093&r1=158092&r2=158093&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/FrontendActions.cpp?rev=158093&r1=158092&r2=158093&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Rewrite/FrontendActions.cpp (original)<br>
+++ cfe/trunk/lib/Rewrite/FrontendActions.cpp Wed Jun  6 13:52:13 2012<br>
@@ -181,3 +181,12 @@<br>
<br>
   DoRewriteTest(CI.getPreprocessor(), OS);<br>
 }<br>
+<br>
+void RewriteIncludesAction::ExecuteAction() {<br>
+  CompilerInstance &CI = getCompilerInstance();<br>
+  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());<br>
+  if (!OS) return;<br>
+<br>
+  RewriteIncludesInInput(CI.getPreprocessor(), OS,<br>
+                         CI.getPreprocessorOutputOpts());<br>
+}<br>
<br>
Added: cfe/trunk/lib/Rewrite/InclusionRewriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/InclusionRewriter.cpp?rev=158093&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/InclusionRewriter.cpp?rev=158093&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Rewrite/InclusionRewriter.cpp (added)<br>
+++ cfe/trunk/lib/Rewrite/InclusionRewriter.cpp Wed Jun  6 13:52:13 2012<br>
@@ -0,0 +1,370 @@<br>
+//===--- InclusionRewriter.cpp - Rewrite includes into their expansions ---===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This code rewrites include invocations into their expansions.  This gives you<br>
+// a file with all included files merged into it.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "clang/Rewrite/Rewriters.h"<br>
+#include "clang/Lex/Preprocessor.h"<br>
+#include "clang/Basic/SourceManager.h"<br>
+#include "clang/Frontend/PreprocessorOutputOptions.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+<br>
+using namespace clang;<br>
+using namespace llvm;<br>
+<br>
+namespace {<br>
+<br>
+class InclusionRewriter : public PPCallbacks {<br>
+  /// Information about which #includes were actually performed,<br>
+  /// created by preprocessor callbacks.<br>
+  struct FileChange {<br>
+    SourceLocation From;<br>
+    FileID Id;<br>
+    SrcMgr::CharacteristicKind FileType;<br>
+    FileChange(SourceLocation From) : From(From) {<br>
+    }<br>
+  };<br>
+  Preprocessor &PP; //< Used to find inclusion directives.<br>
+  SourceManager &SM; //< Used to read and manage source files.<br>
+  raw_ostream &OS; //< The destination stream for rewritten contents.<br>
+  bool ShowLineMarkers; //< Show #line markers.<br>
+  bool UseLineDirective; //< Use of line directives or line markers.<br>
+  typedef std::map<unsigned, FileChange> FileChangeMap;<br>
+  FileChangeMap FileChanges; /// Tracks which files were included where.<br>
+  /// Used transitively for building up the FileChanges mapping over the<br>
+  /// various \c PPCallbacks callbacks.<br>
+  FileChangeMap::iterator LastInsertedFileChange;<br>
+public:<br>
+  InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers);<br>
+  bool Process(FileID FileId, SrcMgr::CharacteristicKind FileType);<br>
+private:<br>
+  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,<br>
+                           SrcMgr::CharacteristicKind FileType,<br>
+                           FileID PrevFID);<br>
+  virtual void FileSkipped(const FileEntry &ParentFile,<br>
+                           const Token &FilenameTok,<br>
+                           SrcMgr::CharacteristicKind FileType);<br>
+  virtual void InclusionDirective(SourceLocation HashLoc,<br>
+                                  const Token &IncludeTok,<br>
+                                  StringRef FileName,<br>
+                                  bool IsAngled,<br>
+                                  const FileEntry *File,<br>
+                                  SourceLocation EndLoc,<br>
+                                  StringRef SearchPath,<br>
+                                  StringRef RelativePath);<br>
+  void WriteLineInfo(const char *Filename, int Line,<br>
+                     SrcMgr::CharacteristicKind FileType,<br>
+                     StringRef EOL, StringRef Extra = StringRef());<br>
+  void OutputContentUpTo(const MemoryBuffer &FromFile,<br>
+                         unsigned &WriteFrom, unsigned WriteTo,<br>
+                         StringRef EOL, int &lines,<br>
+                         bool EnsureNewline = false);<br>
+  void CommentOutDirective(Lexer &DirectivesLex, const Token &StartToken,<br>
+                           const MemoryBuffer &FromFile, StringRef EOL,<br>
+                           unsigned &NextToWrite, int &Lines);<br>
+  const FileChange *FindFileChangeLocation(SourceLocation Loc) const;<br>
+  StringRef NextIdentifierName(Lexer &RawLex, Token &RawToken);<br>
+};<br>
+<br>
+}  // end anonymous namespace<br>
+<br>
+/// Initializes an InclusionRewriter with a \p PP source and \p OS destination.<br>
+InclusionRewriter::InclusionRewriter(Preprocessor &PP, raw_ostream &OS,<br>
+                                     bool ShowLineMarkers)<br>
+    : PP(PP), SM(PP.getSourceManager()), OS(OS),<br>
+    ShowLineMarkers(ShowLineMarkers),<br>
+    LastInsertedFileChange(FileChanges.end()) {<br>
+  // If we're in microsoft mode, use normal #line instead of line markers.<br>
+  UseLineDirective = PP.getLangOpts().MicrosoftExt;<br>
+}<br>
+<br>
+/// Write appropriate line information as either #line directives or GNU line<br>
+/// markers depending on what mode we're in, including the \p Filename and<br>
+/// \p Line we are located at, using the specified \p EOL line separator, and<br>
+/// any \p Extra context specifiers in GNU line directives.<br>
+void InclusionRewriter::WriteLineInfo(const char *Filename, int Line,<br>
+                                      SrcMgr::CharacteristicKind FileType,<br>
+                                      StringRef EOL, StringRef Extra) {<br>
+  if (!ShowLineMarkers)<br>
+    return;<br>
+  if (UseLineDirective) {<br>
+    OS << "#line" << ' ' << Line << ' ' << '"' << Filename << '"';<br>
+  } else {<br>
+    // Use GNU linemarkers as described here:<br>
+    // <a href="http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html" target="_blank">http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html</a><br>
+    OS << '#' << ' ' << Line << ' ' << '"' << Filename << '"';<br>
+    if (!Extra.empty())<br>
+      OS << Extra;<br>
+    if (FileType == SrcMgr::C_System)<br>
+      // "`3' This indicates that the following text comes from a system header<br>
+      // file, so certain warnings should be suppressed."<br>
+      OS << " 3";<br>
+    else if (FileType == SrcMgr::C_ExternCSystem)<br>
+      // as above for `3', plus "`4' This indicates that the following text<br>
+      // should be treated as being wrapped in an implicit extern "C" block."<br>
+      OS << " 3 4";<br>
+  }<br>
+  OS << EOL;<br>
+}<br>
+<br>
+/// FileChanged - Whenever the preprocessor enters or exits a #include file<br>
+/// it invokes this handler.<br>
+void InclusionRewriter::FileChanged(SourceLocation Loc,<br>
+                                    FileChangeReason Reason,<br>
+                                    SrcMgr::CharacteristicKind NewFileType,<br>
+                                    FileID) {<br>
+  if (Reason != EnterFile)<br>
+    return;<br>
+  if (LastInsertedFileChange == FileChanges.end())<br>
+    // we didn't reach this file (eg: the main file) via an inclusion directive<br>
+    return;<br>
+  LastInsertedFileChange->second.Id = FullSourceLoc(Loc, SM).getFileID();<br>
+  LastInsertedFileChange->second.FileType = NewFileType;<br>
+  LastInsertedFileChange = FileChanges.end();<br>
+}<br>
+<br>
+/// Called whenever an inclusion is skipped due to canonical header protection<br>
+/// macros.<br>
+void InclusionRewriter::FileSkipped(const FileEntry &/*ParentFile*/,<br>
+                                    const Token &/*FilenameTok*/,<br>
+                                    SrcMgr::CharacteristicKind /*FileType*/) {<br>
+  assert(LastInsertedFileChange != FileChanges.end() && "A file, that wasn't "<br>
+    "found via an inclusion directive, was skipped");<br>
+  FileChanges.erase(LastInsertedFileChange);<br>
+  LastInsertedFileChange = FileChanges.end();<br>
+}<br>
+<br>
+/// This should be called whenever the preprocessor encounters include<br>
+/// directives. It does not say whether the file has been included, but it<br>
+/// provides more information about the directive (hash location instead<br>
+/// of location inside the included file). It is assumed that the matching<br>
+/// FileChanged() or FileSkipped() is called after this.<br>
+void InclusionRewriter::InclusionDirective(SourceLocation HashLoc,<br>
+                                           const Token &/*IncludeTok*/,<br>
+                                           StringRef /*FileName*/,<br>
+                                           bool /*IsAngled*/,<br>
+                                           const FileEntry * /*File*/,<br>
+                                           SourceLocation /*EndLoc*/,<br>
+                                           StringRef /*SearchPath*/,<br>
+                                           StringRef /*RelativePath*/) {<br>
+  assert(LastInsertedFileChange == FileChanges.end() && "Another inclusion "<br>
+    "directive was found before the previous one was processed");<br>
+  std::pair<FileChangeMap::iterator, bool> p = FileChanges.insert(<br>
+    std::make_pair(HashLoc.getRawEncoding(), FileChange(HashLoc)));<br>
+  assert(p.second && "Unexpected revisitation of the same include directive");<br>
+  LastInsertedFileChange = p.first;<br>
+}<br>
+<br>
+/// Simple lookup for a SourceLocation (specifically one denoting the hash in<br>
+/// an inclusion directive) in the map of inclusion information, FileChanges.<br>
+const InclusionRewriter::FileChange *<br>
+InclusionRewriter::FindFileChangeLocation(SourceLocation Loc) const {<br>
+  FileChangeMap::const_iterator I = FileChanges.find(Loc.getRawEncoding());<br>
+  if (I != FileChanges.end())<br>
+    return &I->second;<br>
+  return NULL;<br>
+}<br>
+<br>
+/// Count the raw \\n characters in the \p Len characters from \p Pos.<br>
+inline unsigned CountNewLines(const char *Pos, int Len) {<br>
+  const char *End = Pos + Len;<br>
+  unsigned Lines = 0;<br>
+  --Pos;<br>
+  while ((Pos = static_cast<const char*>(memchr(Pos + 1, '\n', End - Pos - 1))))<br>
+    ++Lines;<br>
+  return Lines;<br>
+}<br>
+<br>
+/// Detect the likely line ending style of \p FromFile by examining the first<br>
+/// newline found within it.<br>
+static StringRef DetectEOL(const MemoryBuffer &FromFile) {<br>
+  // detect what line endings the file uses, so that added content does not mix<br>
+  // the style<br>
+  const char *Pos = strchr(FromFile.getBufferStart(), '\n');<br>
+  if (Pos == NULL)<br>
+    return "\n";<br>
+  if (Pos + 1 < FromFile.getBufferEnd() && Pos[1] == '\r')<br>
+    return "\n\r";<br>
+  if (Pos - 1 >= FromFile.getBufferStart() && Pos[-1] == '\r')<br>
+    return "\r\n";<br>
+  return "\n";<br>
+}<br>
+<br>
+/// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at<br>
+/// \p WriteTo - 1.<br>
+void InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile,<br>
+                                          unsigned &WriteFrom, unsigned WriteTo,<br>
+                                          StringRef EOL, int &Line,<br>
+                                          bool EnsureNewline) {<br>
+  if (WriteTo <= WriteFrom)<br>
+    return;<br>
+  OS.write(FromFile.getBufferStart() + WriteFrom, WriteTo - WriteFrom);<br>
+  // count lines manually, it's faster than getPresumedLoc()<br>
+  Line += CountNewLines(FromFile.getBufferStart() + WriteFrom,<br>
+                        WriteTo - WriteFrom);<br>
+  if (EnsureNewline) {<br>
+    char LastChar = FromFile.getBufferStart()[WriteTo - 1];<br>
+    if (LastChar != '\n' && LastChar != '\r')<br>
+      OS << EOL;<br>
+  }<br>
+  WriteFrom = WriteTo;<br>
+}<br>
+<br>
+/// Print characters from \p FromFile starting at \p NextToWrite up until the<br>
+/// inclusion directive at \p StartToken, then print out the inclusion<br>
+/// inclusion directive disabled by a #if directive, updating \p NextToWrite<br>
+/// and \p Line to track the number of source lines visited and the progress<br>
+/// through the \p FromFile buffer.<br>
+void InclusionRewriter::CommentOutDirective(Lexer &DirectiveLex,<br>
+                                            const Token &StartToken,<br>
+                                            const MemoryBuffer &FromFile,<br>
+                                            StringRef EOL,<br>
+                                            unsigned &NextToWrite, int &Line) {<br>
+  OutputContentUpTo(FromFile, NextToWrite,<br>
+    SM.getFileOffset(StartToken.getLocation()), EOL, Line);<br>
+  Token DirectiveToken;<br>
+  do {<br>
+    DirectiveLex.LexFromRawLexer(DirectiveToken);<br>
+  } while (!DirectiveToken.is(tok::eod) && DirectiveToken.isNot(tok::eof));<br>
+  OS << "#if 0 /* expanded by -rewrite-includes */" << EOL;<br>
+  OutputContentUpTo(FromFile, NextToWrite,<br>
+    SM.getFileOffset(DirectiveToken.getLocation()) + DirectiveToken.getLength(),<br>
+    EOL, Line);<br>
+  OS << "#endif /* expanded by -rewrite-includes */" << EOL;<br>
+}<br>
+<br>
+/// Find the next identifier in the pragma directive specified by \p RawToken.<br>
+StringRef InclusionRewriter::NextIdentifierName(Lexer &RawLex,<br>
+                                                Token &RawToken) {<br>
+  RawLex.LexFromRawLexer(RawToken);<br>
+  if (RawToken.is(tok::raw_identifier))<br>
+    PP.LookUpIdentifierInfo(RawToken);<br>
+  if (RawToken.is(tok::identifier))<br>
+    return RawToken.getIdentifierInfo()->getName();<br>
+  return StringRef();<br>
+}<br>
+<br>
+/// Use a raw lexer to analyze \p FileId, inccrementally copying parts of it<br>
+/// and including content of included files recursively.<br>
+bool InclusionRewriter::Process(FileID FileId,<br>
+                                SrcMgr::CharacteristicKind FileType)<br>
+{<br>
+  bool Invalid;<br>
+  const MemoryBuffer &FromFile = *SM.getBuffer(FileId, &Invalid);<br>
+  assert(!Invalid && "Invalid FileID while trying to rewrite includes");<br>
+  const char *FileName = FromFile.getBufferIdentifier();<br>
+  Lexer RawLex(FileId, &FromFile, PP.getSourceManager(), PP.getLangOpts());<br>
+  RawLex.SetCommentRetentionState(false);<br>
+<br>
+  StringRef EOL = DetectEOL(FromFile);<br>
+<br>
+  // Per the GNU docs: "1" indicates the start of a new file.<br>
+  WriteLineInfo(FileName, 1, FileType, EOL, " 1");<br>
+<br>
+  if (SM.getFileIDSize(FileId) == 0)<br>
+    return true;<br>
+<br>
+  // The next byte to be copied from the source file<br>
+  unsigned NextToWrite = 0;<br>
+  int Line = 1; // The current input file line number.<br>
+<br>
+  Token RawToken;<br>
+  RawLex.LexFromRawLexer(RawToken);<br>
+<br>
+  // TODO: Consider adding a switch that strips possibly unimportant content,<br>
+  // such as comments, to reduce the size of repro files.<br>
+  while (RawToken.isNot(tok::eof)) {<br>
+    if (RawToken.is(tok::hash) && RawToken.isAtStartOfLine()) {<br>
+      RawLex.setParsingPreprocessorDirective(true);<br>
+      Token HashToken = RawToken;<br>
+      RawLex.LexFromRawLexer(RawToken);<br>
+      if (RawToken.is(tok::raw_identifier))<br>
+        PP.LookUpIdentifierInfo(RawToken);<br>
+      if (RawToken.is(tok::identifier)) {<br>
+        switch (RawToken.getIdentifierInfo()->getPPKeywordID()) {<br>
+          case tok::pp_include:<br>
+          case tok::pp_include_next:<br>
+          case tok::pp_import: {<br>
+            CommentOutDirective(RawLex, HashToken, FromFile, EOL, NextToWrite,<br>
+              Line);<br>
+            if (const FileChange *Change = FindFileChangeLocation(<br>
+                HashToken.getLocation())) {<br>
+              // now include and recursively process the file<br>
+              if (Process(Change->Id, Change->FileType))<br>
+                // and set lineinfo back to this file, if the nested one was<br>
+                // actually included<br>
+                // `2' indicates returning to a file (after having included<br>
+                // another file.<br>
+                WriteLineInfo(FileName, Line, FileType, EOL, " 2");<br>
+            } else<br>
+              // fix up lineinfo (since commented out directive changed line<br>
+              // numbers) for inclusions that were skipped due to header guards<br>
+              WriteLineInfo(FileName, Line, FileType, EOL);<br>
+            break;<br>
+          }<br>
+          case tok::pp_pragma: {<br>
+            StringRef Identifier = NextIdentifierName(RawLex, RawToken);<br>
+            if (Identifier == "clang" || Identifier == "GCC") {<br>
+              if (NextIdentifierName(RawLex, RawToken) == "system_header") {<br>
+                // keep the directive in, commented out<br>
+                CommentOutDirective(RawLex, HashToken, FromFile, EOL,<br>
+                  NextToWrite, Line);<br>
+                // update our own type<br>
+                FileType = SM.getFileCharacteristic(RawToken.getLocation());<br>
+                WriteLineInfo(FileName, Line, FileType, EOL);<br>
+              }<br>
+            } else if (Identifier == "once") {<br>
+              // keep the directive in, commented out<br>
+              CommentOutDirective(RawLex, HashToken, FromFile, EOL,<br>
+                NextToWrite, Line);<br>
+              WriteLineInfo(FileName, Line, FileType, EOL);<br>
+            }<br>
+            break;<br>
+          }<br>
+          default:<br>
+            break;<br>
+        }<br>
+      }<br>
+      RawLex.setParsingPreprocessorDirective(false);<br>
+    }<br>
+    RawLex.LexFromRawLexer(RawToken);<br>
+  }<br>
+  OutputContentUpTo(FromFile, NextToWrite,<br>
+    SM.getFileOffset(SM.getLocForEndOfFile(FileId)) + 1, EOL, Line,<br>
+    /*EnsureNewline*/true);<br>
+  return true;<br>
+}<br>
+<br>
+/// InclusionRewriterInInput - Implement -rewrite-includes mode.<br>
+void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,<br>
+                                   const PreprocessorOutputOptions &Opts) {<br>
+  SourceManager &SM = PP.getSourceManager();<br>
+  InclusionRewriter *Rewrite = new InclusionRewriter(PP, *OS,<br>
+                                                     Opts.ShowLineMarkers);<br>
+  PP.addPPCallbacks(Rewrite);<br>
+<br>
+  // First let the preprocessor process the entire file and call callbacks.<br>
+  // Callbacks will record which #include's were actually performed.<br>
+  PP.EnterMainSourceFile();<br>
+  Token Tok;<br>
+  // Only preprocessor directives matter here, so disable macro expansion<br>
+  // everywhere else as an optimization.<br>
+  // TODO: It would be even faster if the preprocessor could be switched<br>
+  // to a mode where it would parse only preprocessor directives and comments,<br>
+  // nothing else matters for parsing or processing.<br>
+  PP.SetMacroExpansionOnlyInDirectives();<br>
+  do {<br>
+    PP.Lex(Tok);<br>
+  } while (Tok.isNot(tok::eof));<br>
+  Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User);<br>
+  OS->flush();<br>
+}<br>
<br>
Added: cfe/trunk/test/Frontend/Inputs/rewrite-includes1.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes1.h?rev=158093&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes1.h?rev=158093&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Frontend/Inputs/rewrite-includes1.h (added)<br>
+++ cfe/trunk/test/Frontend/Inputs/rewrite-includes1.h Wed Jun  6 13:52:13 2012<br>
@@ -0,0 +1,3 @@<br>
+#pragma clang system_header<br>
+included_line1<br>
+#include "rewrite-includes2.h"<br>
<br>
Added: cfe/trunk/test/Frontend/Inputs/rewrite-includes2.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes2.h?rev=158093&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes2.h?rev=158093&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Frontend/Inputs/rewrite-includes2.h (added)<br>
+++ cfe/trunk/test/Frontend/Inputs/rewrite-includes2.h Wed Jun  6 13:52:13 2012<br>
@@ -0,0 +1 @@<br>
+included_line2<br>
<br>
Added: cfe/trunk/test/Frontend/Inputs/rewrite-includes3.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes3.h?rev=158093&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes3.h?rev=158093&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Frontend/Inputs/rewrite-includes3.h (added)<br>
+++ cfe/trunk/test/Frontend/Inputs/rewrite-includes3.h Wed Jun  6 13:52:13 2012<br>
@@ -0,0 +1 @@<br>
+included_line3<br>
<br>
Added: cfe/trunk/test/Frontend/Inputs/rewrite-includes4.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes4.h?rev=158093&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes4.h?rev=158093&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Frontend/Inputs/rewrite-includes4.h (added)<br>
+++ cfe/trunk/test/Frontend/Inputs/rewrite-includes4.h Wed Jun  6 13:52:13 2012<br>
@@ -0,0 +1 @@<br>
+included_line4<br>
<br>
Added: cfe/trunk/test/Frontend/Inputs/rewrite-includes5.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes5.h?rev=158093&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes5.h?rev=158093&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Frontend/Inputs/rewrite-includes5.h (added)<br>
+++ cfe/trunk/test/Frontend/Inputs/rewrite-includes5.h Wed Jun  6 13:52:13 2012<br>
@@ -0,0 +1 @@<br>
+included_line5<br>
<br>
Added: cfe/trunk/test/Frontend/Inputs/rewrite-includes6.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes6.h?rev=158093&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes6.h?rev=158093&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Frontend/Inputs/rewrite-includes6.h (added)<br>
+++ cfe/trunk/test/Frontend/Inputs/rewrite-includes6.h Wed Jun  6 13:52:13 2012<br>
@@ -0,0 +1,2 @@<br>
+#pragma once<br>
+included_line6<br>
<br>
Added: cfe/trunk/test/Frontend/Inputs/rewrite-includes7.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes7.h?rev=158093&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/Inputs/rewrite-includes7.h?rev=158093&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Frontend/Inputs/rewrite-includes7.h (added)<br>
+++ cfe/trunk/test/Frontend/Inputs/rewrite-includes7.h Wed Jun  6 13:52:13 2012<br>
@@ -0,0 +1,4 @@<br>
+#ifndef REWRITE_INCLUDES_7<br>
+#define REWRITE_INCLUDES_7<br>
+included_line7<br>
+#endif<br>
<br>
Added: cfe/trunk/test/Frontend/rewrite-includes.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/rewrite-includes.c?rev=158093&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/rewrite-includes.c?rev=158093&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Frontend/rewrite-includes.c (added)<br>
+++ cfe/trunk/test/Frontend/rewrite-includes.c Wed Jun  6 13:52:13 2012<br>
@@ -0,0 +1,145 @@<br>
+// RUN: %clang_cc1 -verify -rewrite-includes -DFIRST -I %S/Inputs %s -o - | FileCheck -strict-whitespace %s<br>
+// RUN: %clang_cc1 -verify -rewrite-includes -P -DFIRST -I %S/Inputs %s -o - | FileCheck -check-prefix=CHECKNL -strict-whitespace %s<br>
+// STARTCOMPARE<br>
+#define A(a,b) a ## b<br>
+A(1,2)<br>
+#include "rewrite-includes1.h"<br>
+#ifdef FIRST<br>
+#define HEADER "rewrite-includes3.h"<br>
+#include HEADER<br>
+#else<br>
+#include "rewrite-includes4.h"<br>
+#endif<br>
+#/**/include /**/ "rewrite-includes5.h" /**/ \<br>
+<br>
+#include "rewrite-includes6.h" // comment<br>
+<br>
+#include "rewrite-includes6.h" /* comment<br>
+                                  continues */<br>
+#include "rewrite-includes7.h"<br>
+#include "rewrite-includes7.h"<br>
+// ENDCOMPARE<br>
+// CHECK: {{^}}// STARTCOMPARE{{$}}<br>
+// CHECK-NEXT: {{^}}#define A(a,b) a ## b{{$}}<br>
+// CHECK-NEXT: {{^}}A(1,2){{$}}<br>
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}#include "rewrite-includes1.h"{{$}}<br>
+// CHECK-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes1.h" 1{{$}}<br>
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}#pragma clang system_header{{$}}<br>
+// CHECK-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}# 2 "{{.*}}/Inputs/rewrite-includes1.h" 3{{$}}<br>
+// CHECK-NEXT: {{^}}included_line1{{$}}<br>
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}#include "rewrite-includes2.h"{{$}}<br>
+// CHECK-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes2.h" 1 3{{$}}<br>
+// CHECK-NEXT: {{^}}included_line2{{$}}<br>
+// CHECK-NEXT: {{^}}# 4 "{{.*}}/Inputs/rewrite-includes1.h" 2 3{{$}}<br>
+// CHECK-NEXT: {{^}}# 7 "{{.*}}rewrite-includes.c" 2{{$}}<br>
+// CHECK-NEXT: {{^}}#ifdef FIRST{{$}}<br>
+// CHECK-NEXT: {{^}}#define HEADER "rewrite-includes3.h"{{$}}<br>
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}#include HEADER{{$}}<br>
+// CHECK-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes3.h" 1{{$}}<br>
+// CHECK-NEXT: {{^}}included_line3{{$}}<br>
+// CHECK-NEXT: {{^}}# 10 "{{.*}}rewrite-includes.c" 2{{$}}<br>
+// CHECK-NEXT: {{^}}#else{{$}}<br>
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}#include "rewrite-includes4.h"{{$}}<br>
+// CHECK-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}# 12 "{{.*}}rewrite-includes.c"{{$}}<br>
+// CHECK-NEXT: {{^}}#endif{{$}}<br>
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}#/**/include /**/ "rewrite-includes5.h" /**/ {{\\}}{{$}}<br>
+// CHECK-NEXT: {{^}} {{$}}<br>
+// CHECK-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes5.h" 1{{$}}<br>
+// CHECK-NEXT: {{^}}included_line5{{$}}<br>
+// CHECK-NEXT: {{^}}# 15 "{{.*}}rewrite-includes.c" 2{{$}}<br>
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}#include "rewrite-includes6.h" // comment{{$}}<br>
+// CHECK-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes6.h" 1{{$}}<br>
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}#pragma once{{$}}<br>
+// CHECK-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}# 2 "{{.*}}/Inputs/rewrite-includes6.h"{{$}}<br>
+// CHECK-NEXT: {{^}}included_line6{{$}}<br>
+// CHECK-NEXT: {{^}}# 16 "{{.*}}rewrite-includes.c" 2{{$}}<br>
+// CHECK-NEXT: {{^}} {{$}}<br>
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}#include "rewrite-includes6.h" /* comment{{$}}<br>
+// CHECK-NEXT: {{^}}                                  continues */{{$}}<br>
+// CHECK-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}# 19 "{{.*}}rewrite-includes.c"{{$}}<br>
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}<br>
+// CHECK-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes7.h" 1{{$}}<br>
+// CHECK-NEXT: {{^}}#ifndef REWRITE_INCLUDES_7{{$}}<br>
+// CHECK-NEXT: {{^}}#define REWRITE_INCLUDES_7{{$}}<br>
+// CHECK-NEXT: {{^}}included_line7{{$}}<br>
+// CHECK-NEXT: {{^}}#endif{{$}}<br>
+// CHECK-NEXT: {{^}}# 20 "{{.*}}rewrite-includes.c" 2{{$}}<br>
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}<br>
+// CHECK-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECK-NEXT: {{^}}# 21 "{{.*}}rewrite-includes.c"{{$}}<br>
+// CHECK-NEXT: {{^}}// ENDCOMPARE{{$}}<br>
+<br>
+// CHECKNL: {{^}}// STARTCOMPARE{{$}}<br>
+// CHECKNL-NEXT: {{^}}#define A(a,b) a ## b{{$}}<br>
+// CHECKNL-NEXT: {{^}}A(1,2){{$}}<br>
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#include "rewrite-includes1.h"{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#pragma clang system_header{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}included_line1{{$}}<br>
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#include "rewrite-includes2.h"{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}included_line2{{$}}<br>
+// CHECKNL-NEXT: {{^}}#ifdef FIRST{{$}}<br>
+// CHECKNL-NEXT: {{^}}#define HEADER "rewrite-includes3.h"{{$}}<br>
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#include HEADER{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}included_line3{{$}}<br>
+// CHECKNL-NEXT: {{^}}#else{{$}}<br>
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#include "rewrite-includes4.h"{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif{{$}}<br>
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#/**/include /**/ "rewrite-includes5.h" /**/ {{\\}}{{$}}<br>
+// CHECKNL-NEXT: {{^}} {{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}included_line5{{$}}<br>
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#include "rewrite-includes6.h" // comment{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#pragma once{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}included_line6{{$}}<br>
+// CHECKNL-NEXT: {{^}} {{$}}<br>
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#include "rewrite-includes6.h" /* comment{{$}}<br>
+// CHECKNL-NEXT: {{^}}                                  continues */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#ifndef REWRITE_INCLUDES_7{{$}}<br>
+// CHECKNL-NEXT: {{^}}#define REWRITE_INCLUDES_7{{$}}<br>
+// CHECKNL-NEXT: {{^}}included_line7{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif{{$}}<br>
+// CHECKNL-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}<br>
+// CHECKNL-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}<br>
+// CHECKNL-NEXT: {{^}}// ENDCOMPARE{{$}}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br>