[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cfe-commits
Subject:    [cfe-commits] [PATCH] -rewrite-includes
From:       Lubos Lunak <l.lunak () suse ! cz>
Date:       2012-03-15 1:12:57
Message-ID: 201203150212.57338.l.lunak () suse ! cz
[Download RAW message or body]

Hello,

 the attached patch is an attempt at option -rewrite-includes, which is 
similar to -rewrite-macros, but it expands only #include directives.

 The primary motivation is a better functionality of clang together with 
icecream, a distributed compile system (like distcc, only better, 
http://en.opensuse.org/Icecream). Remote compilation works by first 
preprocessing the file and sending the result for actual compilation. This 
difference doesn't matter with gcc, but clang disables some warnings for code 
expanded from macros, and also quotes source code, both of which no longer 
work well in the preprocessed case. So the idea is to add -rewrite-includes, 
which will only merge all included files into the resulting file, without any 
other modifications, and the result will be normally compiled again.

 The code is based on RewriteMacros.cpp and PrintPreprocessedOutput.cpp, it 
more or less works now and I consider it almost ready. The only remaining 
problem I have is commenting out the preprocessor directives - I'd like to 
keep them in the resulting file, similarly to what -rewrite-macros does. The 
problem is that neither /**/ nor // are safe for commenting it out in all 
possible cases, and since this should be used for transparent conversion 
during remote compile, I do not want to make assumptions about what the code 
looks like (e.g. my first trivial solution with /**/ failed 
on "#include /*MSVC <cstdlib> */ <stdlib.h>" ). Does somebody know how to 
achieve this? Otherwise I'll probably make it simply erase the directives.

-- 
 Lubos Lunak
 l.lunak@suse.cz

["rewrite-includes.patch" (text/x-diff)]

diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index d32ea0b..fc9e230 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -446,6 +446,8 @@ def rewrite_objc : Flag<"-rewrite-objc">,
   HelpText<"Rewrite ObjC into C (code rewriter example)">;
 def rewrite_macros : Flag<"-rewrite-macros">,
   HelpText<"Expand macros without full preprocessing">;
+def rewrite_includes : Flag<"-rewrite-includes">,
+  HelpText<"Expand includes without full preprocessing">;
 def migrate : Flag<"-migrate">,
   HelpText<"Migrate source code">;
 }
diff --git a/include/clang/Frontend/FrontendOptions.h \
b/include/clang/Frontend/FrontendOptions.h index 0ec2f6b..d9b24ba 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -43,6 +43,7 @@ namespace frontend {
     PrintPreamble,          ///< Print the "preamble" of the input file
     PrintPreprocessedInput, ///< -E mode.
     RewriteMacros,          ///< Expand macros but not #includes.
+    RewriteIncludes,        ///< Expand #includes but not macros.
     RewriteObjC,            ///< ObjC->C Rewriter.
     RewriteTest,            ///< Rewriter playground
     RunAnalysis,            ///< Run one or more source code analyses.
diff --git a/include/clang/Rewrite/FrontendActions.h \
b/include/clang/Rewrite/FrontendActions.h index 6e9ecac..ea876d9 100644
--- a/include/clang/Rewrite/FrontendActions.h
+++ b/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 a/include/clang/Rewrite/Rewriters.h b/include/clang/Rewrite/Rewriters.h
index 203b9bc..9704fe3 100644
--- a/include/clang/Rewrite/Rewriters.h
+++ b/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,9 @@ void RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS);
 /// DoRewriteTest - A simple test for the TokenRewriter class.
 void DoRewriteTest(Preprocessor &PP, raw_ostream *OS);
 
+/// RewriteIncludesInInput - Implement -rewrite-includes mode.
+void RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS, const \
PreprocessorOutputOptions &Opts); +
 }  // end namespace clang
 
 #endif
diff --git a/lib/Frontend/CompilerInvocation.cpp \
b/lib/Frontend/CompilerInvocation.cpp index 13a9897..e8dc20e 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -455,6 +455,7 @@ static const char *getActionName(frontend::ActionKind Kind) {
   case frontend::PrintPreamble:          return "-print-preamble";
   case frontend::PrintPreprocessedInput: return "-E";
   case frontend::RewriteMacros:          return "-rewrite-macros";
+  case frontend::RewriteIncludes:        return "-rewrite-includes";
   case frontend::RewriteObjC:            return "-rewrite-objc";
   case frontend::RewriteTest:            return "-rewrite-test";
   case frontend::RunAnalysis:            return "-analyze";
@@ -1451,6 +1452,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, \
ArgList &Args,  Opts.ProgramAction = frontend::PrintPreprocessedInput; break;
     case OPT_rewrite_macros:
       Opts.ProgramAction = frontend::RewriteMacros; break;
+    case OPT_rewrite_includes:
+      Opts.ProgramAction = frontend::RewriteIncludes; break;
     case OPT_rewrite_objc:
       Opts.ProgramAction = frontend::RewriteObjC; break;
     case OPT_rewrite_test:
diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp \
b/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 07d2b8d..49d0bb8 100644
--- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -73,6 +73,7 @@ static FrontendAction *CreateFrontendBaseAction(CompilerInstance \
&CI) {  case PrintPreamble:          return new PrintPreambleAction();
   case PrintPreprocessedInput: return new PrintPreprocessedAction();
   case RewriteMacros:          return new RewriteMacrosAction();
+  case RewriteIncludes:        return new RewriteIncludesAction();
   case RewriteObjC:            return new RewriteObjCAction();
   case RewriteTest:            return new RewriteTestAction();
   case RunAnalysis:            return new ento::AnalysisAction();
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index a49ab04..65d96d8 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -2020,7 +2020,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
@@ -2622,7 +2622,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 a/lib/Rewrite/CMakeLists.txt b/lib/Rewrite/CMakeLists.txt
index 2a05040..8070ba2 100644
--- a/lib/Rewrite/CMakeLists.txt
+++ b/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 a/lib/Rewrite/FrontendActions.cpp b/lib/Rewrite/FrontendActions.cpp
index 1753325..e462671 100644
--- a/lib/Rewrite/FrontendActions.cpp
+++ b/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 a/lib/Rewrite/RewriteIncludes.cpp b/lib/Rewrite/RewriteIncludes.cpp
new file mode 100644
index 0000000..b6041e6
--- /dev/null
+++ b/lib/Rewrite/RewriteIncludes.cpp
@@ -0,0 +1,288 @@
+//===--- 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;
+
+namespace {
+
+class RewriteIncludes : public PPCallbacks {
+  // Information about which #includes were actually performed,
+  // created by preprocessor callbacks.
+  struct FileChange {
+    SourceLocation from;
+    FileID id;
+    SrcMgr::CharacteristicKind type;
+    FileChangeReason reason;
+  };
+  Preprocessor &PP;
+  SourceManager &SM;
+  raw_ostream &OS;
+  bool DisableLineMarkers;
+  bool UseLineDirective;
+  std::list< FileChange > FileChanges;
+public:
+  RewriteIncludes(Preprocessor &pp, raw_ostream &os, bool lineMarkers)
+     : PP(pp), SM(PP.getSourceManager()),
+       OS(os), DisableLineMarkers(lineMarkers) {
+    // If we're in microsoft mode, use normal #line instead of line markers.
+    UseLineDirective = PP.getLangOpts().MicrosoftExt;
+  }
+  bool Process( FileID fileId, SrcMgr::CharacteristicKind type );
+private:
+  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);
+  void WriteLineInfo(const char* filename, int line,
+                     SrcMgr::CharacteristicKind type,
+                     const char *Extra = NULL, unsigned ExtraLen = 0);
+  void OutputContentsUpTo( unsigned writeEnd, unsigned& nextToWrite,
+                           const llvm::MemoryBuffer* FromFile );
+  PresumedLoc CommentOutDirective( Lexer& DirectivesLex,
+                            const Token& StartToken,
+                            unsigned& nextToWrite,
+                            const llvm::MemoryBuffer* FromFile );
+  const FileChange* FindFileChangeLocation( SourceLocation Loc,
+    FileChangeReason Reason ) const;
+  StringRef NextIdentifierName(Lexer& RawLex, Token& RawToken);
+};
+
+}  // end anonymous namespace
+
+void RewriteIncludes::WriteLineInfo(const char* filename, int line,
+                                    SrcMgr::CharacteristicKind type,
+                                    const char *Extra,
+                                    unsigned ExtraLen) {
+  // Emit #line directives or GNU line markers depending on what mode we're in.
+  if (UseLineDirective) {
+    OS << "#line" << ' ' << line << ' ' << '"' << filename;
+    OS << '"';
+  } else {
+    OS << '#' << ' ' << line << ' ' << '"' << filename << '"';
+    if (ExtraLen)
+      OS.write(Extra, ExtraLen);
+    if (type == SrcMgr::C_System)
+      OS.write(" 3", 2);
+    else if (type == SrcMgr::C_ExternCSystem)
+      OS.write(" 3 4", 4);
+  }
+  OS << '\n';
+}
+
+/// FileChanged - Whenever the preprocessor enters or exits a #include file
+/// it invokes this handler.
+void RewriteIncludes::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 (!FileChanges.empty()) { // there may be internal sort-of includes
+        FileChanges.back().id = id;
+        FileChanges.back().type = NewFileType;
+        FileChanges.back().reason = Reason;
+    }
+  } else if (Reason == SystemHeaderPragma) {
+    FileID id = FullSourceLoc(Loc,SM).getFileID();
+    FileChange change;
+    change.from = Loc;
+    change.id = id;
+    change.type = NewFileType;
+    change.reason = Reason;
+    FileChanges.push_back( change );
+  }
+}
+
+// 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 RewriteIncludes::InclusionDirective(SourceLocation HashLoc,
+                                         const Token&,
+                                         StringRef,
+                                         bool,
+                                         const FileEntry*,
+                                         SourceLocation,
+                                         StringRef,
+                                         StringRef) {
+  FileChange change;
+  change.from = HashLoc;
+  FileChanges.push_back( change );
+}
+
+const RewriteIncludes::FileChange*
+RewriteIncludes::FindFileChangeLocation( SourceLocation Loc,
+    FileChangeReason Reason ) const {
+  for( std::list< FileChange >::const_iterator it
+       = FileChanges.begin(), end = FileChanges.end();
+       it != end; ++it ) {
+    if( it->from == Loc && it->reason == Reason )
+      return &*it;
+  }
+  return NULL;
+}
+
+
+// Copies next yet written file contents up (and not including writeEnd).
+void RewriteIncludes::OutputContentsUpTo(unsigned writeEnd,
+                                         unsigned& nextToWrite,
+                                         const llvm::MemoryBuffer* FromFile ) {
+  if ( writeEnd > nextToWrite ) {
+    OS.write( FromFile->getBufferStart() + nextToWrite, writeEnd - nextToWrite );
+    nextToWrite = writeEnd;
+  }
+}
+
+PresumedLoc RewriteIncludes::CommentOutDirective( Lexer& DirectiveLex,
+                                                  const Token& StartToken,
+                                                  unsigned& nextToWrite,
+                                                  const llvm::MemoryBuffer* FromFile \
) { +  OutputContentsUpTo(SM.getFileOffset(StartToken.getLocation()), nextToWrite, \
FromFile); +  Token DirectiveToken;
+  do {
+    DirectiveLex.LexFromRawLexer(DirectiveToken);
+  } while (!DirectiveToken.is(tok::eod) && DirectiveToken.isNot(tok::eof));
+// TODO this is broken with C89
+  OS << "//";
+  OutputContentsUpTo(SM.getFileOffset(DirectiveToken.getLocation())
+    + DirectiveToken.getLength(), nextToWrite, FromFile);
+  // return location of EOD (for next line number, otherwise later it might not be \
exact +  // because of whitespace ignoring)
+  assert(SM.getPresumedLoc(DirectiveToken.getLocation()).isValid());
+  return SM.getPresumedLoc(DirectiveToken.getLocation());
+}
+
+StringRef RewriteIncludes::NextIdentifierName(Lexer& RawLex, 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();
+}
+
+bool RewriteIncludes::Process( FileID fileId,
+                                        SrcMgr::CharacteristicKind type )
+{
+  PresumedLoc start = SM.getPresumedLoc(SM.getLocForStartOfFile(fileId));
+  if( start.isInvalid())
+    return false;
+
+  // Use a raw lexer to analyze the input file, incrementally copying parts of
+  // it and including contents of included files recursively.
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer( fileId );
+  Lexer RawLex(fileId, FromFile, PP.getSourceManager(), PP.getLangOpts());
+  RawLex.SetCommentRetentionState(false);
+
+  WriteLineInfo( start.getFilename(), start.getLine(), type, " 1", 2 );
+  bool extraEndline = true; // from WriteLineInfo()
+
+  // position in file from which the contents have not yet been copied to the output
+  unsigned nextToWrite = 0;
+
+  Token RawToken;
+  RawLex.LexFromRawLexer(RawToken);
+
+  while (RawToken.isNot(tok::eof)) {
+    extraEndline = false;
+    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: {
+            if (const FileChange* change = FindFileChangeLocation(
+                HashToken.getLocation(), EnterFile)) {
+              // keep the directive in, commented out
+              PresumedLoc EODPos = CommentOutDirective(RawLex, HashToken,
+                nextToWrite, FromFile);
+              // now include and recursively process the file
+              if( Process( change->id, change->type )) {
+                // and set lineinfo back to this file, if the nested one was \
actually included +                WriteLineInfo( EODPos.getFilename(), \
EODPos.getLine() + 1, +                  type, " 2", 2);
+                extraEndline = true;
+              }
+            }
+            break;
+          }
+          case tok::pp_pragma: {
+            StringRef I = NextIdentifierName(RawLex, RawToken);
+            if (I == "clang" || I == "GCC" ) {
+              if (NextIdentifierName(RawLex, RawToken) == "system_header"
+                  && FindFileChangeLocation(RawToken.getLocation(), \
SystemHeaderPragma)) { +                type = SrcMgr::C_System; // update our own \
type +                // keep the directive in, commented out
+                PresumedLoc EODPos = CommentOutDirective(RawLex, HashToken,
+                  nextToWrite, FromFile);
+                WriteLineInfo( EODPos.getFilename(), EODPos.getLine() + 1,
+                  SrcMgr::C_System);
+                extraEndline = true;
+              }
+            }
+            break;
+          }
+          default:
+            break;
+        }
+      }
+      RawLex.setParsingPreprocessorDirective(false);
+      RawLex.SetCommentRetentionState(false);
+    }
+  RawLex.LexFromRawLexer(RawToken);
+  }
+  OutputContentsUpTo(SM.getFileOffset(SM.getLocForEndOfFile(fileId)),
+    nextToWrite, FromFile);
+  if (!extraEndline)
+    OS << '\n';
+  return true;
+}
+
+/// RewriteIncludesInInput - Implement -rewrite-includes mode.
+void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
+                                   const PreprocessorOutputOptions &Opts) {
+  SourceManager &SM = PP.getSourceManager();
+  RewriteIncludes* Rewrite = new RewriteIncludes(PP, *OS, !Opts.ShowLineMarkers);
+  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;
+  do {
+    PP.Lex(Tok);
+  } while (Tok.isNot(tok::eof));
+  Rewrite->Process( SM.getMainFileID(), SrcMgr::C_User );
+  OS->flush();
+}
diff --git a/test/Frontend/rewrite-includes.c b/test/Frontend/rewrite-includes.c
new file mode 100644
index 0000000..c5bed49
--- /dev/null
+++ b/test/Frontend/rewrite-includes.c
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -verify -rewrite-includes -DFIRST %s -o %t
+// RUN: cat %t | FileCheck -strict-whitespace %s
+// STARTCOMPARE
+#define A(a,b) a ## b
+A(1,2)
+#include "rewrite-includes1.h"
+#ifdef FIRST
+#include "rewrite-includes3.h"
+#else
+#include "rewrite-includes4.h"
+#endif
+#/**/include /**/ "rewrite-includes5.h" /**/ \
+ 
+#include "rewrite-includes6.h" // comment
+ 
+// ENDCOMPARE
+
+// CHECK: // STARTCOMPARE
+// CHECK-NEXT: #define A(a,b) a ## b
+// CHECK-NEXT: A(1,2)
+// CHECK-NEXT: //#include "rewrite-includes1.h"
+// CHECK-NEXT: # 1 "{{.*}}rewrite-includes1.h" 1
+// CHECK-NEXT: //#pragma clang system_header
+// CHECK-NEXT: # 1 "{{.*}}rewrite-includes1.h" 3
+// CHECK-NEXT: included_line1
+// CHECK-NEXT: //#include "rewrite-includes2.h"
+// CHECK-NEXT: # 1 "{{.*}}rewrite-includes2.h" 1 3
+// CHECK-NEXT: included_line2
+// CHECK-NEXT: # 3 "{{.*}}rewrite-includes1.h" 2 3
+// CHECK-NEXT: # 7 "{{.*}}rewrite-includes.c" 2
+// CHECK-NEXT: #ifdef FIRST
+// CHECK-NEXT: //#include "rewrite-includes3.h"
+// CHECK-NEXT: # 1 "{{.*}}rewrite-includes3.h" 1
+// CHECK-NEXT: included_line3
+// CHECK-NEXT: # 9 "{{.*}}rewrite-includes.c" 2
+// CHECK-NEXT: #else
+// CHECK-NEXT: #include "rewrite-includes4.h"
+// CHECK-NEXT: #endif
+// CHECK-NEXT: #/**/include /**/ "rewrite-includes5.h" /**/ {{\\}}
+// CHECK-NEXT: {{[ ]}}
+// CHECK-NEXT: # 1 "{{.*}}rewrite-includes5.h" 1
+// CHECK-NEXT: included_line5
+// CHECK-NEXT: # 14 "{{.*}}rewrite-includes.c" 2
+// CHECK-NEXT: //#include "rewrite-includes6.h" // comment
+// CHECK-NEXT: # 1 "{{.*}}rewrite-includes6.h" 1
+// CHECK-NEXT: included_line6
+// CHECK-NEXT: # 15 "{{.*}}rewrite-includes.c" 2
+// CHECK-NEXT: {{[ ]}}
+// CHECK-NEXT: // ENDCOMPARE
diff --git a/test/Frontend/rewrite-includes1.h b/test/Frontend/rewrite-includes1.h
new file mode 100644
index 0000000..1b6c80d
--- /dev/null
+++ b/test/Frontend/rewrite-includes1.h
@@ -0,0 +1,3 @@
+#pragma clang system_header
+included_line1
+#include "rewrite-includes2.h"
diff --git a/test/Frontend/rewrite-includes2.h b/test/Frontend/rewrite-includes2.h
new file mode 100644
index 0000000..1114e51
--- /dev/null
+++ b/test/Frontend/rewrite-includes2.h
@@ -0,0 +1 @@
+included_line2
diff --git a/test/Frontend/rewrite-includes3.h b/test/Frontend/rewrite-includes3.h
new file mode 100644
index 0000000..3757bc8
--- /dev/null
+++ b/test/Frontend/rewrite-includes3.h
@@ -0,0 +1 @@
+included_line3
diff --git a/test/Frontend/rewrite-includes4.h b/test/Frontend/rewrite-includes4.h
new file mode 100644
index 0000000..b4e25d2
--- /dev/null
+++ b/test/Frontend/rewrite-includes4.h
@@ -0,0 +1 @@
+included_line4
diff --git a/test/Frontend/rewrite-includes5.h b/test/Frontend/rewrite-includes5.h
new file mode 100644
index 0000000..934bf41
--- /dev/null
+++ b/test/Frontend/rewrite-includes5.h
@@ -0,0 +1 @@
+included_line5
diff --git a/test/Frontend/rewrite-includes6.h b/test/Frontend/rewrite-includes6.h
new file mode 100644
index 0000000..2e56dcb
--- /dev/null
+++ b/test/Frontend/rewrite-includes6.h
@@ -0,0 +1 @@
+included_line6



_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic