File rewrite-includes.patch of Package llvm

diff --git tools/clang/include/clang/Driver/CC1Options.td tools/clang/include/clang/Driver/CC1Options.td
index 83c988a..b7deed0 100644
--- tools/clang/include/clang/Driver/CC1Options.td
+++ tools/clang/include/clang/Driver/CC1Options.td
@@ -814,6 +814,8 @@ def dM : Flag<"-dM">,
   HelpText<"Print macro definitions in -E mode instead of normal output">;
 def dD : Flag<"-dD">,
   HelpText<"Print macro definitions in -E mode in addition to normal output">;
+def frewrite_includes : Flag<"-frewrite-includes">,
+  HelpText<"Expand includes without full preprocessing">;
 
 //===----------------------------------------------------------------------===//
 // OpenCL Options
diff --git tools/clang/include/clang/Driver/Options.td tools/clang/include/clang/Driver/Options.td
index b796771..f58d824 100644
--- tools/clang/include/clang/Driver/Options.td
+++ tools/clang/include/clang/Driver/Options.td
@@ -362,6 +362,9 @@ def fno_trapping_math : Flag<"-fno-trapping-math">, Group<f_Group>;
 def ffor_scope : Flag<"-ffor-scope">, Group<f_Group>;
 def fno_for_scope : Flag<"-fno-for-scope">, Group<f_Group>;
 
+def frewrite_includes : Flag<"-frewrite-includes">, Group<f_Group>;
+def fno_rewrite_includes : Flag<"-fno-rewrite-includes">, Group<f_Group>;
+
 def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>;
 def fgnu_keywords : Flag<"-fgnu-keywords">, Group<f_Group>;
 def fgnu89_inline : Flag<"-fgnu89-inline">, Group<f_Group>;
diff --git tools/clang/include/clang/Frontend/FrontendOptions.h tools/clang/include/clang/Frontend/FrontendOptions.h
index 888388c..48cd317 100644
--- tools/clang/include/clang/Frontend/FrontendOptions.h
+++ tools/clang/include/clang/Frontend/FrontendOptions.h
@@ -42,7 +42,7 @@ namespace frontend {
     PrintDeclContext,       ///< Print DeclContext and their Decls.
     PrintPreamble,          ///< Print the "preamble" of the input file
     PrintPreprocessedInput, ///< -E mode.
-    RewriteMacros,          ///< Expand macros but not #includes.
+    RewriteMacros,          ///< Expand macros but not \#includes.
     RewriteObjC,            ///< ObjC->C Rewriter.
     RewriteTest,            ///< Rewriter playground
     RunAnalysis,            ///< Run one or more source code analyses.
diff --git tools/clang/include/clang/Frontend/PreprocessorOutputOptions.h tools/clang/include/clang/Frontend/PreprocessorOutputOptions.h
index 1eda0d4..31724cd 100644
--- tools/clang/include/clang/Frontend/PreprocessorOutputOptions.h
+++ tools/clang/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -21,6 +21,7 @@ public:
   unsigned ShowLineMarkers : 1;    ///< Show #line markers.
   unsigned ShowMacroComments : 1;  ///< Show comments, even in macros.
   unsigned ShowMacros : 1;         ///< Print macro definitions.
+  unsigned RewriteIncludes : 1;    ///< Preprocess include directives only.
 
 public:
   PreprocessorOutputOptions() {
@@ -29,6 +30,7 @@ public:
     ShowLineMarkers = 1;
     ShowMacroComments = 0;
     ShowMacros = 0;
+    RewriteIncludes = 0;
   }
 };
 
diff --git tools/clang/include/clang/Lex/Preprocessor.h tools/clang/include/clang/Lex/Preprocessor.h
index 055008f..638b4aa 100644
--- tools/clang/include/clang/Lex/Preprocessor.h
+++ tools/clang/include/clang/Lex/Preprocessor.h
@@ -121,6 +121,13 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
   /// DisableMacroExpansion - True if macro expansion is disabled.
   bool DisableMacroExpansion : 1;
 
+  /// MacroExpansionInDirectivesOverride - Temporarily disables
+  /// DisableMacroExpansion (i.e. enables expansion) when parsing preprocessor
+  /// directives.
+  bool MacroExpansionInDirectivesOverride : 1;
+
+  class ResetMacroExpansionHelper;
+
   /// \brief Whether we have already loaded macros from the external source.
   mutable bool ReadMacrosFromExternalSource : 1;
 
@@ -634,6 +641,12 @@ public:
     while (Result.getKind() == tok::comment);
   }
 
+  /// Disables macro expansion everywhere except for preprocessor directives.
+  void SetMacroExpansionOnlyInDirectives() {
+    DisableMacroExpansion = true;
+    MacroExpansionInDirectivesOverride = true;
+  }
+
   /// LookAhead - This peeks ahead N tokens and returns that token without
   /// consuming any tokens.  LookAhead(0) returns the next token that would be
   /// returned by Lex(), LookAhead(1) returns the token after it, etc.  This
diff --git tools/clang/include/clang/Rewrite/FrontendActions.h tools/clang/include/clang/Rewrite/FrontendActions.h
index 6e9ecac..ea876d9 100644
--- tools/clang/include/clang/Rewrite/FrontendActions.h
+++ tools/clang/include/clang/Rewrite/FrontendActions.h
@@ -73,6 +73,11 @@ protected:
   void ExecuteAction();
 };
 
+class RewriteIncludesAction : public PreprocessorFrontendAction {
+protected:
+  void ExecuteAction();
+};
+
 }  // end namespace clang
 
 #endif
diff --git tools/clang/include/clang/Rewrite/Rewriters.h tools/clang/include/clang/Rewrite/Rewriters.h
index 203b9bc..f5ade5a 100644
--- tools/clang/include/clang/Rewrite/Rewriters.h
+++ tools/clang/include/clang/Rewrite/Rewriters.h
@@ -18,6 +18,7 @@
 
 namespace clang {
 class Preprocessor;
+class PreprocessorOutputOptions;
 
 /// RewriteMacrosInInput - Implement -rewrite-macros mode.
 void RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS);
@@ -25,6 +26,10 @@ void RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS);
 /// DoRewriteTest - A simple test for the TokenRewriter class.
 void DoRewriteTest(Preprocessor &PP, raw_ostream *OS);
 
+/// RewriteIncludesInInput - Implement -frewrite-includes mode.
+void RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
+                            const PreprocessorOutputOptions &Opts);
+
 }  // end namespace clang
 
 #endif
diff --git tools/clang/lib/Driver/Tools.cpp tools/clang/lib/Driver/Tools.cpp
index 47b5294..c0504e7 100644
--- tools/clang/lib/Driver/Tools.cpp
+++ tools/clang/lib/Driver/Tools.cpp
@@ -2106,6 +2106,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   if (Args.getLastArg(options::OPT_fapple_kext))
     CmdArgs.push_back("-fapple-kext");
 
+  if (Args.hasFlag(options::OPT_frewrite_includes,
+                   options::OPT_fno_rewrite_includes, false))
+    CmdArgs.push_back("-frewrite-includes");
+
   Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
diff --git tools/clang/lib/Frontend/CompilerInvocation.cpp tools/clang/lib/Frontend/CompilerInvocation.cpp
index 4c5b063..28935ce 100644
--- tools/clang/lib/Frontend/CompilerInvocation.cpp
+++ tools/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2058,6 +2058,7 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
   Opts.ShowLineMarkers = !Args.hasArg(OPT_P);
   Opts.ShowMacroComments = Args.hasArg(OPT_CC);
   Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
+  Opts.RewriteIncludes = Args.hasArg(OPT_frewrite_includes);
 }
 
 static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
diff --git tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 07d2b8d..0824978 100644
--- tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -71,7 +71,12 @@ static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
 
   case PrintDeclContext:       return new DeclContextPrintAction();
   case PrintPreamble:          return new PrintPreambleAction();
-  case PrintPreprocessedInput: return new PrintPreprocessedAction();
+  case PrintPreprocessedInput: {
+    if (CI.getPreprocessorOutputOpts().RewriteIncludes)
+      return new RewriteIncludesAction();
+    return new PrintPreprocessedAction();
+  }
+
   case RewriteMacros:          return new RewriteMacrosAction();
   case RewriteObjC:            return new RewriteObjCAction();
   case RewriteTest:            return new RewriteTestAction();
diff --git tools/clang/lib/Lex/Lexer.cpp tools/clang/lib/Lex/Lexer.cpp
index 535a852..aa424b4 100644
--- tools/clang/lib/Lex/Lexer.cpp
+++ tools/clang/lib/Lex/Lexer.cpp
@@ -2022,7 +2022,7 @@ bool Lexer::SaveBCPLComment(Token &Result, const char *CurPtr) {
   // directly.
   FormTokenWithChars(Result, CurPtr, tok::comment);
 
-  if (!ParsingPreprocessorDirective)
+  if (!ParsingPreprocessorDirective || LexingRawMode)
     return true;
 
   // If this BCPL-style comment is in a macro definition, transmogrify it into
@@ -2625,7 +2625,8 @@ LexNextToken:
       ParsingPreprocessorDirective = false;
 
       // Restore comment saving mode, in case it was disabled for directive.
-      SetCommentRetentionState(PP->getCommentRetentionState());
+      if (!LexingRawMode)
+        SetCommentRetentionState(PP->getCommentRetentionState());
 
       // Since we consumed a newline, we are back at the start of a line.
       IsAtStartOfLine = true;
diff --git tools/clang/lib/Lex/PPDirectives.cpp tools/clang/lib/Lex/PPDirectives.cpp
index 625a204..29a8614 100644
--- tools/clang/lib/Lex/PPDirectives.cpp
+++ tools/clang/lib/Lex/PPDirectives.cpp
@@ -553,6 +553,22 @@ const FileEntry *Preprocessor::LookupFile(
 // Preprocessor Directive Handling.
 //===----------------------------------------------------------------------===//
 
+class Preprocessor::ResetMacroExpansionHelper
+{
+public:
+  ResetMacroExpansionHelper(Preprocessor*pp)
+    : PP(pp), save(pp->DisableMacroExpansion) {
+    if (pp->MacroExpansionInDirectivesOverride)
+      pp->DisableMacroExpansion = false;
+  }
+  ~ResetMacroExpansionHelper() {
+    PP->DisableMacroExpansion = save;
+  }
+private:
+  Preprocessor* PP;
+  bool save;
+};
+
 /// HandleDirective - This callback is invoked when the lexer sees a # token
 /// at the start of a line.  This consumes the directive, modifies the
 /// lexer/preprocessor state, and advances the lexer(s) so that the next token
@@ -604,6 +620,10 @@ void Preprocessor::HandleDirective(Token &Result) {
     Diag(Result, diag::ext_embedded_directive);
   }
 
+  // temporarily enable macro expansion if set so
+  // and reset to previous state when returning from this function
+  ResetMacroExpansionHelper helper(this);
+
 TryAgain:
   switch (Result.getKind()) {
   case tok::eod:
diff --git tools/clang/lib/Lex/Preprocessor.cpp tools/clang/lib/Lex/Preprocessor.cpp
index 06e5685..f5d7a51 100644
--- tools/clang/lib/Lex/Preprocessor.cpp
+++ tools/clang/lib/Lex/Preprocessor.cpp
@@ -134,6 +134,7 @@ void Preprocessor::Initialize(const TargetInfo &Target) {
   
   // Macro expansion is enabled.
   DisableMacroExpansion = false;
+  MacroExpansionInDirectivesOverride = false;
   InMacroArgs = false;
   InMacroArgPreExpansion = false;
   NumCachedTokenLexers = 0;
diff --git tools/clang/lib/Rewrite/CMakeLists.txt tools/clang/lib/Rewrite/CMakeLists.txt
index 2a05040..8070ba2 100644
--- tools/clang/lib/Rewrite/CMakeLists.txt
+++ tools/clang/lib/Rewrite/CMakeLists.txt
@@ -6,6 +6,7 @@ add_clang_library(clangRewrite
   FrontendActions.cpp
   HTMLPrint.cpp
   HTMLRewrite.cpp
+  RewriteIncludes.cpp
   RewriteMacros.cpp
   RewriteModernObjC.cpp
   RewriteObjC.cpp
diff --git tools/clang/lib/Rewrite/FrontendActions.cpp tools/clang/lib/Rewrite/FrontendActions.cpp
index 1753325..e462671 100644
--- tools/clang/lib/Rewrite/FrontendActions.cpp
+++ tools/clang/lib/Rewrite/FrontendActions.cpp
@@ -181,3 +181,11 @@ void RewriteTestAction::ExecuteAction() {
 
   DoRewriteTest(CI.getPreprocessor(), OS);
 }
+
+void RewriteIncludesAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
+  if (!OS) return;
+
+  RewriteIncludesInInput(CI.getPreprocessor(), OS, CI.getPreprocessorOutputOpts());
+}
diff --git tools/clang/lib/Rewrite/RewriteIncludes.cpp tools/clang/lib/Rewrite/RewriteIncludes.cpp
new file mode 100644
index 0000000..b7de20c
--- /dev/null
+++ tools/clang/lib/Rewrite/RewriteIncludes.cpp
@@ -0,0 +1,362 @@
+//===--- RewriteIncludes.cpp - Rewrite includes into their expansions -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This code rewrites include invocations into their expansions.  This gives you
+// a file with all included files merged into it.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Rewriters.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/PreprocessorOutputOptions.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace llvm;
+
+namespace {
+
+/// Class representing the whole rewriting process and global data for it.
+class IncludeRewriter : public PPCallbacks {
+  /// Information about which #includes were actually performed,
+  /// created by preprocessor callbacks.
+  struct FileChange {
+    SourceLocation From;
+    FileID Id;
+    SrcMgr::CharacteristicKind Type;
+  };
+  Preprocessor &PP;
+  SourceManager &SM;
+  raw_ostream &OS;
+  bool DisableLineMarkers;
+  bool UseLineDirective;
+  typedef std::map<unsigned, FileChange> FileChangeMap;
+  FileChangeMap FileChanges;
+  unsigned LastInsertedFileChange;
+  class File;
+public:
+  IncludeRewriter(Preprocessor &PP, raw_ostream &OS,
+                  const PreprocessorOutputOptions &Opts);
+  void Process();
+  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                           SrcMgr::CharacteristicKind FileType,
+                           FileID PrevFID);
+  virtual void InclusionDirective(SourceLocation HashLoc,
+                                  const Token &IncludeTok,
+                                  StringRef FileName,
+                                  bool IsAngled,
+                                  const FileEntry *File,
+                                  SourceLocation EndLoc,
+                                  StringRef SearchPath,
+                                  StringRef RelativePath);
+private:
+  const FileChange* FindFileChangeLocation(SourceLocation Loc) const;
+};
+
+/// Class representing the process of rewriting one source file.
+class IncludeRewriter::File {
+  IncludeRewriter* Rewriter;
+  Preprocessor &PP;
+  SourceManager &SM;
+  raw_ostream &OS;
+  FileID FileId;
+  SrcMgr::CharacteristicKind Type;
+  const MemoryBuffer *FromFile;
+  const char* FileName;
+  SourceLocation StartLocation;
+  bool Invalid;
+  const char* EOL;
+  OwningPtr<Lexer> RawLex;
+  // file position from which the content has not yet been copied to the output
+  unsigned NextToWrite;
+  int Line; // current input file line number
+public:
+  File(IncludeRewriter* Rewriter, FileID FileId,
+       SrcMgr::CharacteristicKind Type);
+  bool Process();
+private:
+  void WriteLineInfo(StringRef Extra = StringRef());
+  void OutputContentUpTo(unsigned WriteEnd, bool EnsureNewline = false);
+  void CommentOutDirective(const Token& StartToken);
+  StringRef NextIdentifierName(Token& RawToken);
+  void DetectEOL();
+  unsigned CountNewLines(const char* Pos, int Len);
+};
+
+}  // end anonymous namespace
+
+IncludeRewriter::IncludeRewriter(Preprocessor &pp, raw_ostream &os,
+                                 const PreprocessorOutputOptions &Opts)
+  : PP(pp), SM(PP.getSourceManager()), OS(os),
+  DisableLineMarkers(!Opts.ShowLineMarkers), LastInsertedFileChange(0) {
+  // If we're in microsoft mode, use normal #line instead of line markers.
+  UseLineDirective = PP.getLangOpts().MicrosoftExt;
+}
+
+/// FileChanged - Whenever the preprocessor enters or exits a #include file
+/// it invokes this handler.
+void IncludeRewriter::FileChanged(SourceLocation Loc,
+                                  FileChangeReason Reason,
+                                  SrcMgr::CharacteristicKind NewFileType,
+                                  FileID) {
+  if (Reason == EnterFile) {
+    // InclusionDirective() has already been called, add more info
+    FileID Id = FullSourceLoc(Loc,SM).getFileID();
+    if (LastInsertedFileChange != 0) { // there may be e.g. "<built-in>" first
+        FileChange& Ref = FileChanges[LastInsertedFileChange];
+        Ref.Id = Id;
+        Ref.Type = NewFileType;
+    }
+  }
+}
+
+/// This should be called whenever the preprocessor encounters include
+/// directives. It does not say whether the file has been included, but it
+/// provides more information about the directive (hash location istead
+/// of location inside the included file. It is assumed that the matching
+/// FileChanged() is called after this (if at all).
+void IncludeRewriter::InclusionDirective(SourceLocation HashLoc,
+                                         const Token &/*IncludeTok*/,
+                                         StringRef /*FileName*/,
+                                         bool /*IsAngled*/,
+                                         const FileEntry* /*File*/,
+                                         SourceLocation /*EndLoc*/,
+                                         StringRef /*SearchPath*/,
+                                         StringRef /*RelativePath*/) {
+  FileChange Change;
+  Change.From = HashLoc;
+  LastInsertedFileChange = HashLoc.getRawEncoding();
+  FileChanges[LastInsertedFileChange] = Change;
+}
+
+const IncludeRewriter::FileChange*
+IncludeRewriter::FindFileChangeLocation(SourceLocation Loc) const {
+  FileChangeMap ::const_iterator Find = FileChanges.find(Loc.getRawEncoding());
+  if(Find != FileChanges.end())
+    return &Find->second;
+  return NULL;
+}
+
+void IncludeRewriter::Process() {
+  File MainFile(this, SM.getMainFileID(), SrcMgr::C_User);
+  MainFile.Process();
+}
+
+
+IncludeRewriter::File::File(IncludeRewriter* Rewriter,
+                            FileID FileId,
+                            SrcMgr::CharacteristicKind Type)
+  : Rewriter(Rewriter)
+  , PP(Rewriter->PP)
+  , SM(Rewriter->SM)
+  , OS(Rewriter->OS)
+  , FileId(FileId)
+  , Type(Type)
+  , Invalid(true)
+  , NextToWrite(0)
+  , Line(1) {
+
+  StartLocation = SM.getLocForStartOfFile(FileId);
+  FileName = SM.getBufferName(StartLocation, &Invalid);
+  if (Invalid)
+    return;
+
+  // Use a raw lexer to analyze the input file, incrementally copying parts of
+  // it and including content of included files recursively.
+  FromFile = SM.getBuffer(FileId);
+  RawLex.reset( new Lexer(FileId, FromFile, PP.getSourceManager(), PP.getLangOpts()));
+  RawLex->SetCommentRetentionState(false);
+  DetectEOL();
+
+  WriteLineInfo(" 1");
+}
+
+bool IncludeRewriter::File::Process()
+{
+  if (Invalid)
+    return false;
+  if (SM.getFileIDSize(FileId) == 0)
+    return true;
+
+  Token RawToken;
+  RawLex->LexFromRawLexer(RawToken);
+
+  // TODO: It might be beneficial to have a switch that removes content of lines
+  // that are irrevelant for compile, i.e. comments. Comments are usually
+  // a significant part of the resulting file and cleaning up such lines would
+  // significantly reduce the size of the resulting file without having any
+  // effect on any following usage (with the exception of human inspection).
+  while (RawToken.isNot(tok::eof)) {
+    if (RawToken.is(tok::hash) && RawToken.isAtStartOfLine()) {
+      RawLex->setParsingPreprocessorDirective(true);
+      Token HashToken = RawToken;
+      RawLex->LexFromRawLexer(RawToken);
+      if (RawToken.is(tok::raw_identifier))
+        PP.LookUpIdentifierInfo(RawToken);
+      if (RawToken.is(tok::identifier)) {
+        switch (RawToken.getIdentifierInfo()->getPPKeywordID()) {
+          case tok::pp_include:
+          case tok::pp_include_next:
+          case tok::pp_import: {
+            // keep the directive in, commented out
+            // (clang sometimes optimizes and does not repeatedly include some
+            // files even though it should, so all includes need to be
+            // commented, otherwise valid directives would be left in)
+            CommentOutDirective(HashToken);
+            // fix up lineinfo, commenting out has added lines
+            bool NeedFixup = true;
+            if (const FileChange* Change = Rewriter->FindFileChangeLocation(
+                HashToken.getLocation())) {
+              // now include and recursively process the file
+              File IncludedFile(Rewriter, Change->Id, Change->Type);
+              if (IncludedFile.Process()) {
+                // and set lineinfo back to this file, if the nested one was
+                // actually included
+                WriteLineInfo(" 2");
+                NeedFixup = false;
+              }
+            }
+            if(NeedFixup)
+              WriteLineInfo();
+            break;
+          }
+          case tok::pp_pragma: {
+            StringRef Identifier = NextIdentifierName(RawToken);
+            if (Identifier == "clang" || Identifier == "GCC") {
+              if (NextIdentifierName(RawToken) == "system_header") {
+                // keep the directive in, commented out
+                CommentOutDirective(HashToken);
+                // update our own type
+                Type = SM.getFileCharacteristic(RawToken.getLocation());
+                WriteLineInfo();
+              }
+            } else if (Identifier == "once") {
+              // keep the directive in, commented out
+              CommentOutDirective(HashToken);
+              WriteLineInfo();
+            }
+            break;
+          }
+          default:
+            break;
+        }
+      }
+      RawLex->setParsingPreprocessorDirective(false);
+      RawLex->SetCommentRetentionState(false);
+    }
+  RawLex->LexFromRawLexer(RawToken);
+  }
+  OutputContentUpTo(SM.getFileIDSize(FileId), true);
+  return true;
+}
+
+void IncludeRewriter::File::DetectEOL() {
+  // detect what line endings the file uses, so that added content does not mix
+  // the style
+  const char* Pos = strchr(FromFile->getBufferStart(), '\n');
+  if (Pos == NULL)
+    EOL = "\n";
+  else if (Pos+1 < FromFile->getBufferEnd() && *(Pos+1) == '\r')
+    EOL = "\n\r";
+  else if (Pos-1 >= FromFile->getBufferStart() && *(Pos+1) == '\r')
+    EOL = "\r\n";
+  else 
+    EOL = "\n";
+}
+
+void IncludeRewriter::File::WriteLineInfo(StringRef Extra) {
+  if (Rewriter->DisableLineMarkers) {
+    OS << EOL; // Still need to at least separate lines.
+    return;
+  }
+  // Emit #line directives or GNU line markers depending on what mode we're in.
+  if (Rewriter->UseLineDirective) {
+    OS << "#line" << ' ' << Line << ' ' << '"' << FileName << '"';
+  } else {
+    OS << '#' << ' ' << Line << ' ' << '"' << FileName << '"';
+    if (!Extra.empty())
+      OS << Extra;
+    if (Type == SrcMgr::C_System)
+      OS << " 3";
+    else if (Type == SrcMgr::C_ExternCSystem)
+      OS << " 3 4";
+  }
+  OS << EOL;
+}
+
+inline unsigned IncludeRewriter::File::CountNewLines(const char* Pos, int Len) {
+  const char* End = Pos + Len;
+  unsigned Lines = 0;
+  --Pos;
+  while ((Pos = static_cast<const char*>(memchr(Pos + 1, '\n', End - Pos - 1))))
+    ++Lines;
+  return Lines;
+}
+
+/// Copies next not yet written file content up (and not including) to writeEnd.
+void IncludeRewriter::File::OutputContentUpTo(unsigned WriteEnd,
+                                              bool EnsureNewline) {
+  if (WriteEnd > NextToWrite) {
+    OS.write(FromFile->getBufferStart() + NextToWrite, WriteEnd - NextToWrite);
+    // count lines manually, it's faster than getPresumedLoc()
+    Line += CountNewLines(FromFile->getBufferStart() + NextToWrite,
+      WriteEnd - NextToWrite);
+    if (EnsureNewline) {
+      char LastChar = FromFile->getBufferStart()[WriteEnd - 1];
+      if (LastChar != '\n' && LastChar != '\r')
+        OS << EOL;
+    }
+    NextToWrite = WriteEnd;
+  }
+}
+
+void IncludeRewriter::File::CommentOutDirective(const Token& StartToken) {
+  OutputContentUpTo(SM.getFileOffset(StartToken.getLocation()));
+  Token DirectiveToken;
+  do {
+    RawLex->LexFromRawLexer(DirectiveToken);
+  } while (!DirectiveToken.is(tok::eod) && DirectiveToken.isNot(tok::eof));
+  OS << "#if 0 /* expanded by -frewrite-includes */" << EOL;
+  OutputContentUpTo(SM.getFileOffset(DirectiveToken.getLocation())
+    + DirectiveToken.getLength());
+  OS << "#endif /* expanded by -frewrite-includes */" << EOL;
+}
+
+StringRef IncludeRewriter::File::NextIdentifierName(Token& RawToken) {
+  RawLex->LexFromRawLexer(RawToken);
+  if (RawToken.is(tok::raw_identifier))
+    PP.LookUpIdentifierInfo(RawToken);
+  if (RawToken.is(tok::identifier))
+    return RawToken.getIdentifierInfo()->getName();
+  return StringRef();
+}
+
+/// RewriteIncludesInInput - Implement -frewrite-includes mode.
+void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
+                                   const PreprocessorOutputOptions &Opts) {
+  IncludeRewriter* Rewrite = new IncludeRewriter(PP, *OS, Opts);
+  PP.addPPCallbacks(Rewrite);
+
+  // First let the preprocessor process the entire file and call callbacks.
+  // Callbacks will record which #include's were actually performed.
+  PP.EnterMainSourceFile();
+  Token Tok;
+  // Only preprocessor directives matter here, so disable macro expansion
+  // everywhere else as an optimization.
+  // TODO: It would be even faster if the preprocessor could be switched
+  // to a mode where it would parse only preprocessor directives and comments,
+  // nothing else matters for parsing or processing.
+  PP.SetMacroExpansionOnlyInDirectives();
+  do {
+    PP.Lex(Tok);
+  } while (Tok.isNot(tok::eof));
+  Rewrite->Process();
+  OS->flush();
+}
diff --git tools/clang/test/Frontend/Inputs/rewrite-includes1.h tools/clang/test/Frontend/Inputs/rewrite-includes1.h
new file mode 100644
index 0000000..1b6c80d
--- /dev/null
+++ tools/clang/test/Frontend/Inputs/rewrite-includes1.h
@@ -0,0 +1,3 @@
+#pragma clang system_header
+included_line1
+#include "rewrite-includes2.h"
diff --git tools/clang/test/Frontend/Inputs/rewrite-includes2.h tools/clang/test/Frontend/Inputs/rewrite-includes2.h
new file mode 100644
index 0000000..1114e51
--- /dev/null
+++ tools/clang/test/Frontend/Inputs/rewrite-includes2.h
@@ -0,0 +1 @@
+included_line2
diff --git tools/clang/test/Frontend/Inputs/rewrite-includes3.h tools/clang/test/Frontend/Inputs/rewrite-includes3.h
new file mode 100644
index 0000000..3757bc8
--- /dev/null
+++ tools/clang/test/Frontend/Inputs/rewrite-includes3.h
@@ -0,0 +1 @@
+included_line3
diff --git tools/clang/test/Frontend/Inputs/rewrite-includes4.h tools/clang/test/Frontend/Inputs/rewrite-includes4.h
new file mode 100644
index 0000000..b4e25d2
--- /dev/null
+++ tools/clang/test/Frontend/Inputs/rewrite-includes4.h
@@ -0,0 +1 @@
+included_line4
diff --git tools/clang/test/Frontend/Inputs/rewrite-includes5.h tools/clang/test/Frontend/Inputs/rewrite-includes5.h
new file mode 100644
index 0000000..934bf41
--- /dev/null
+++ tools/clang/test/Frontend/Inputs/rewrite-includes5.h
@@ -0,0 +1 @@
+included_line5
diff --git tools/clang/test/Frontend/Inputs/rewrite-includes6.h tools/clang/test/Frontend/Inputs/rewrite-includes6.h
new file mode 100644
index 0000000..c18e501
--- /dev/null
+++ tools/clang/test/Frontend/Inputs/rewrite-includes6.h
@@ -0,0 +1,2 @@
+#pragma once
+included_line6
diff --git tools/clang/test/Frontend/Inputs/rewrite-includes7.h tools/clang/test/Frontend/Inputs/rewrite-includes7.h
new file mode 100644
index 0000000..85428fd
--- /dev/null
+++ tools/clang/test/Frontend/Inputs/rewrite-includes7.h
@@ -0,0 +1,4 @@
+#ifndef REWRITE_INCLUDES7_H
+#define REWRITE_INCLUDES7_H
+included_line7
+#endif
diff --git tools/clang/test/Frontend/Inputs/rewrite-includes8.h tools/clang/test/Frontend/Inputs/rewrite-includes8.h
new file mode 100644
index 0000000..7ab5fd9
--- /dev/null
+++ tools/clang/test/Frontend/Inputs/rewrite-includes8.h
@@ -0,0 +1 @@
+included_line8
\ No newline at end of file
diff --git tools/clang/test/Frontend/Inputs/rewrite-includes9.h tools/clang/test/Frontend/Inputs/rewrite-includes9.h
new file mode 100644
index 0000000..e69de29
diff --git tools/clang/test/Frontend/rewrite-includes.c tools/clang/test/Frontend/rewrite-includes.c
new file mode 100644
index 0000000..67a8802
--- /dev/null
+++ tools/clang/test/Frontend/rewrite-includes.c
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -verify -E -frewrite-includes -DFIRST -I %S/Inputs %s -o - | FileCheck -strict-whitespace %s
+
+// STARTCOMPARE
+#define A(a,b) a ## b
+A(1,2)
+#include "rewrite-includes1.h"
+#ifdef FIRST
+#define HEADER "rewrite-includes3.h"
+#include HEADER
+#else
+#include "rewrite-includes4.h"
+#endif
+#/**/include /**/ "rewrite-includes5.h" /**/ \
+ 
+#include "rewrite-includes6.h" // comment
+ 
+#include "rewrite-includes6.h" /* comment
+                                  continues */
+#include "rewrite-includes7.h"
+#include "rewrite-includes7.h"
+#include "rewrite-includes8.h" // no trailing \n in file
+#include "rewrite-includes9.h" // empty file
+// ENDCOMPARE
+
+// CHECK: {{^}}// STARTCOMPARE{{$}}
+// CHECK-NEXT: {{^}}#define A(a,b) a ## b{{$}}
+// CHECK-NEXT: {{^}}A(1,2){{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#include "rewrite-includes1.h"{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes1.h" 1{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#pragma clang system_header{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 2 "{{.*}}/Inputs/rewrite-includes1.h" 3{{$}}
+// CHECK-NEXT: {{^}}included_line1{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#include "rewrite-includes2.h"{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes2.h" 1 3{{$}}
+// CHECK-NEXT: {{^}}included_line2{{$}}
+// CHECK-NEXT: {{^}}# 4 "{{.*}}/Inputs/rewrite-includes1.h" 2 3{{$}}
+// CHECK-NEXT: {{^}}# 7 "{{.*}}rewrite-includes.c" 2{{$}}
+// CHECK-NEXT: {{^}}#ifdef FIRST{{$}}
+// CHECK-NEXT: {{^}}#define HEADER "rewrite-includes3.h"{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#include HEADER{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes3.h" 1{{$}}
+// CHECK-NEXT: {{^}}included_line3{{$}}
+// CHECK-NEXT: {{^}}# 10 "{{.*}}rewrite-includes.c" 2{{$}}
+// CHECK-NEXT: {{^}}#else{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#include "rewrite-includes4.h"{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 12 "{{.*}}rewrite-includes.c"{{$}}
+// CHECK-NEXT: {{^}}#endif{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#/**/include /**/ "rewrite-includes5.h" /**/ {{\\}}{{$}}
+// CHECK-NEXT: {{^}} {{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes5.h" 1{{$}}
+// CHECK-NEXT: {{^}}included_line5{{$}}
+// CHECK-NEXT: {{^}}# 15 "{{.*}}rewrite-includes.c" 2{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#include "rewrite-includes6.h" // comment{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes6.h" 1{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#pragma once{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 2 "{{.*}}/Inputs/rewrite-includes6.h"{{$}}
+// CHECK-NEXT: {{^}}included_line6{{$}}
+// CHECK-NEXT: {{^}}# 16 "{{.*}}rewrite-includes.c" 2{{$}}
+// CHECK-NEXT: {{^}} {{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#include "rewrite-includes6.h" /* comment{{$}}
+// CHECK-NEXT: {{^}}                                  continues */{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 19 "{{.*}}rewrite-includes.c"{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes7.h" 1{{$}}
+// CHECK-NEXT: {{^}}#ifndef REWRITE_INCLUDES7_H{{$}}
+// CHECK-NEXT: {{^}}#define REWRITE_INCLUDES7_H{{$}}
+// CHECK-NEXT: {{^}}included_line7{{$}}
+// CHECK-NEXT: {{^}}#endif{{$}}
+// CHECK-NEXT: {{^}}# 20 "{{.*}}rewrite-includes.c" 2{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 21 "{{.*}}rewrite-includes.c"{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#include "rewrite-includes8.h" // no trailing \n in file{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes8.h" 1{{$}}
+// CHECK-NEXT: {{^}}included_line8{{$}}
+// CHECK-NEXT: {{^}}# 22 "{{.*}}rewrite-includes.c" 2{{$}}
+// CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}#include "rewrite-includes9.h" // empty file{{$}}
+// CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes9.h" 1{{$}}
+// CHECK-NEXT: {{^}}# 23 "{{.*}}rewrite-includes.c" 2{{$}}
+// CHECK-NEXT: {{^}}// ENDCOMPARE{{$}}
openSUSE Build Service is sponsored by