c99bda78c4
OBS-URL: https://build.opensuse.org/request/show/116809 OBS-URL: https://build.opensuse.org/package/show/devel:tools:compiler/llvm?expand=0&rev=147
1211 lines
52 KiB
Diff
1211 lines
52 KiB
Diff
diff --git tools/clang/include/clang/Driver/CC1Options.td tools/clang/include/clang/Driver/CC1Options.td
|
|
index 83c988a..b278082 100644
|
|
--- tools/clang/include/clang/Driver/CC1Options.td
|
|
+++ tools/clang/include/clang/Driver/CC1Options.td
|
|
@@ -452,6 +452,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 tools/clang/include/clang/Frontend/FrontendOptions.h tools/clang/include/clang/Frontend/FrontendOptions.h
|
|
index 888388c..78d3adf 100644
|
|
--- tools/clang/include/clang/Frontend/FrontendOptions.h
|
|
+++ tools/clang/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 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..9704fe3 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,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 tools/clang/lib/Frontend/CompilerInvocation.cpp tools/clang/lib/Frontend/CompilerInvocation.cpp
|
|
index 4c5b063..4e46973 100644
|
|
--- tools/clang/lib/Frontend/CompilerInvocation.cpp
|
|
+++ tools/clang/lib/Frontend/CompilerInvocation.cpp
|
|
@@ -430,6 +430,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";
|
|
@@ -1370,6 +1371,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 tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
|
|
index 07d2b8d..49d0bb8 100644
|
|
--- tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
|
|
+++ tools/clang/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 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..54e09c5
|
|
--- /dev/null
|
|
+++ tools/clang/lib/Rewrite/RewriteIncludes.cpp
|
|
@@ -0,0 +1,542 @@
|
|
+//===--- 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, public CommentHandler {
|
|
+ /// 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;
|
|
+ /// From HandleComment() callback, two raw-encoded SourceLocation's,
|
|
+ /// will be sorted by the location.
|
|
+ typedef std::vector< std::pair<unsigned, unsigned> > CommentRangeVector;
|
|
+ CommentRangeVector CommentRanges;
|
|
+ bool KeepAllComments;
|
|
+ /// Keep comments in lines which are not only comments (such comments may be
|
|
+ /// visible in error/warning messages).
|
|
+ bool KeepCommentsInCodeLines;
|
|
+ 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);
|
|
+ virtual bool HandleComment(Preprocessor &PP, SourceRange Comment);
|
|
+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;
|
|
+ // In case of KeepCommentsInCodeLines, this is actually the position from
|
|
+ // which the content has not yet been written, as in that mode the last line
|
|
+ // is output only if it's known there is some non-whitespace content in it.
|
|
+ unsigned NextToWriteLine;
|
|
+ // the next CommentRange item that processed file contents contain (i.e.
|
|
+ // the current source location is >= NextToWrite's source location)
|
|
+ unsigned NextCommentRange;
|
|
+ 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);
|
|
+ void OutputContentStripComments(unsigned WriteEnd, bool RemoveAll);
|
|
+ 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)
|
|
+ , KeepAllComments(false)
|
|
+ , KeepCommentsInCodeLines(false) {
|
|
+ // If we're in microsoft mode, use normal #line instead of line markers.
|
|
+ UseLineDirective = PP.getLangOpts().MicrosoftExt;
|
|
+ // TODO: This is interpreting the -C and -CC options a bit differently than
|
|
+ // plain -E does, either document it or create new options.
|
|
+ if (Opts.ShowMacroComments)
|
|
+ KeepAllComments = true;
|
|
+ else if (Opts.ShowComments)
|
|
+ KeepCommentsInCodeLines = true;
|
|
+}
|
|
+
|
|
+/// 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;
|
|
+}
|
|
+
|
|
+bool IncludeRewriter::HandleComment(Preprocessor &, SourceRange Comment) {
|
|
+ CommentRanges.push_back( std::make_pair(Comment.getBegin().getRawEncoding(),
|
|
+ Comment.getEnd().getRawEncoding()));
|
|
+ return false;
|
|
+}
|
|
+
|
|
+static bool CompareCommentRanges( const std::pair<unsigned, unsigned>& left,
|
|
+ const std::pair<unsigned, unsigned>& right ) {
|
|
+ return left.first < right.first;
|
|
+}
|
|
+
|
|
+void IncludeRewriter::Process() {
|
|
+// Sort comment ranges for easy finding of the next one from a given location.
|
|
+ std::sort(CommentRanges.begin(), CommentRanges.end(), CompareCommentRanges);
|
|
+ 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)
|
|
+ , NextToWriteLine(0)
|
|
+ , NextCommentRange(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);
|
|
+
|
|
+ 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;
|
|
+}
|
|
+
|
|
+// Used by OutputContentUpTo() to output content depending on comment
|
|
+// removing options (either all comments are removed if RemoveAll),
|
|
+// or only comments on lines that have other non-whitespace).
|
|
+void IncludeRewriter::File::OutputContentStripComments(unsigned WriteEnd,
|
|
+ bool RemoveAll) {
|
|
+ unsigned LocalNextToWrite = NextToWrite;
|
|
+ // Only in !RemoveAll mode, true means there's something on the line
|
|
+ // besides whitespace and comments, so the comments should be kept.
|
|
+ bool LineKeepComment = false;
|
|
+ // Only in !RemoveAll mode, number of \n's in all comments
|
|
+ // from NextToWriteLine (in case they can be removed and just replaced
|
|
+ // with this number of \n's).
|
|
+ unsigned NewLinesInComments = 0;
|
|
+ for (;;) {
|
|
+ while (NextCommentRange < Rewriter->CommentRanges.size()
|
|
+ && Rewriter->CommentRanges[NextCommentRange].first
|
|
+ < LocalNextToWrite + StartLocation.getRawEncoding())
|
|
+ ++NextCommentRange;
|
|
+ // WriteEnd cannot be in the middle of a comment.
|
|
+ assert( !(NextCommentRange < Rewriter->CommentRanges.size()
|
|
+ && Rewriter->CommentRanges[NextCommentRange].first
|
|
+ <= StartLocation.getRawEncoding() + WriteEnd - 1
|
|
+ && Rewriter->CommentRanges[NextCommentRange].second
|
|
+ > StartLocation.getRawEncoding() + WriteEnd));
|
|
+ if (NextCommentRange >= Rewriter->CommentRanges.size()
|
|
+ || StartLocation.getRawEncoding() + WriteEnd - 1
|
|
+ < Rewriter->CommentRanges[NextCommentRange].first) {
|
|
+ // no further comment up to WriteEnd, write out all what we have
|
|
+ if (RemoveAll) {
|
|
+ OS.write(FromFile->getBufferStart() + LocalNextToWrite,
|
|
+ WriteEnd - LocalNextToWrite);
|
|
+ } else {
|
|
+ unsigned Pos = LocalNextToWrite;
|
|
+ unsigned ToWrite = WriteEnd - LocalNextToWrite;
|
|
+ for (unsigned int I = 0; I < ToWrite; ++I, ++Pos) {
|
|
+ char C = FromFile->getBufferStart()[Pos];
|
|
+ // TODO This is possibly wrong for EOL different from plain \n.
|
|
+ if (C == '\n') {
|
|
+ if (LineKeepComment)
|
|
+ OS.write(FromFile->getBufferStart() + NextToWriteLine,
|
|
+ Pos - NextToWriteLine + 1);
|
|
+ else {
|
|
+ for (unsigned I = 0; I < NewLinesInComments; ++I)
|
|
+ OS << EOL;
|
|
+ OS << EOL;
|
|
+ }
|
|
+ NextToWriteLine = Pos + 1;
|
|
+ LineKeepComment = false;
|
|
+ NewLinesInComments = 0;
|
|
+ }
|
|
+ if (!isspace(C))
|
|
+ LineKeepComment = true;
|
|
+ }
|
|
+ if (WriteEnd == SM.getFileIDSize(FileId)) {
|
|
+ // End of file, write out the rest if needed (there's no comment
|
|
+ // in it, so just write it out).
|
|
+ OS.write(FromFile->getBufferStart() + NextToWriteLine,
|
|
+ WriteEnd - NextToWriteLine);
|
|
+ NextToWriteLine = WriteEnd;
|
|
+ }
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+ const unsigned CommentStart = Rewriter->CommentRanges
|
|
+ [NextCommentRange].first - StartLocation.getRawEncoding();
|
|
+ const unsigned CommentEnd = Rewriter->CommentRanges
|
|
+ [NextCommentRange].second - StartLocation.getRawEncoding();//first after
|
|
+ // data up to the next comment
|
|
+ unsigned ToWrite = CommentStart - LocalNextToWrite;
|
|
+ if (RemoveAll) {
|
|
+ if (ToWrite > 0)
|
|
+ OS.write(FromFile->getBufferStart() + LocalNextToWrite, ToWrite);
|
|
+ // keep \n's and trailing \'s from the comment
|
|
+ unsigned Pos = CommentStart;
|
|
+ for (unsigned int I = 0; I < CommentEnd - CommentStart; ++I, ++Pos) {
|
|
+ char C = FromFile->getBufferStart()[Pos];
|
|
+ // TODO This is possibly wrong for EOL different from plain \n.
|
|
+ if (C == '\n')
|
|
+ OS << EOL;
|
|
+ else if (C == '\\' && I + 1 < CommentEnd - CommentStart
|
|
+ && FromFile->getBufferStart()[Pos + 1] == '\n') {
|
|
+ OS << '\\';
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ // Check if there's any \n, if yes, check if the line before it
|
|
+ // should be output (including comments) or whether it has only
|
|
+ // whitespace and comments, in which case output only \n for it.
|
|
+ unsigned Pos = LocalNextToWrite;
|
|
+ for (unsigned int I = 0; I < ToWrite; ++I, ++Pos) {
|
|
+ char C = FromFile->getBufferStart()[Pos];
|
|
+ // TODO This is possibly wrong for EOL different from plain \n.
|
|
+ if (C == '\n') {
|
|
+ if (LineKeepComment)
|
|
+ OS.write(FromFile->getBufferStart() + NextToWriteLine,
|
|
+ Pos - NextToWriteLine + 1);
|
|
+ else {
|
|
+ for (unsigned I = 0; I < NewLinesInComments; ++I)
|
|
+ OS << EOL;
|
|
+ OS << EOL;
|
|
+ }
|
|
+ NextToWriteLine = Pos + 1;
|
|
+ LineKeepComment = false;
|
|
+ NewLinesInComments = 0;
|
|
+ }
|
|
+ if (!isspace(C))
|
|
+ LineKeepComment = true;
|
|
+ }
|
|
+ // Process the comment - count the number of \n's in it, in case
|
|
+ // it can be removed.
|
|
+ // TODO Ideally, if there is a multiline comment, all lines inside
|
|
+ // the comment should be replaced with empty lines, to further reduce
|
|
+ // the size of the resulting output, even if the first and/or last
|
|
+ // line of the comment contain also other non-whitespace and should
|
|
+ // therefore be kept. Currently such a comment is kept as a whole.
|
|
+ // However in practice multiline comments, especially large ones
|
|
+ // (doxygen comments, file headers) usually can be removed as a whole,
|
|
+ // so this probably would not make a big difference.
|
|
+ for (unsigned int I = 0; I < CommentEnd - CommentStart; ++I, ++Pos) {
|
|
+ char C = FromFile->getBufferStart()[Pos];
|
|
+ if (C == '\n') {
|
|
+ ++NewLinesInComments;
|
|
+ } else if (C == '\\' && I + 1 < CommentEnd - CommentStart
|
|
+ && FromFile->getBufferStart()[Pos + 1] == '\n') {
|
|
+ // Do not remove lines in multiline comments that end with \,
|
|
+ // as that could be a body of a macro.
|
|
+ // TODO This is possibly wrong with EOL different from plain \n.
|
|
+ LineKeepComment = true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // and move after the comment
|
|
+ LocalNextToWrite = CommentEnd;
|
|
+ }
|
|
+}
|
|
+
|
|
+/// Copies next not yet written file content up (and not including) to writeEnd.
|
|
+void IncludeRewriter::File::OutputContentUpTo(unsigned WriteEnd,
|
|
+ bool EnsureNewline) {
|
|
+ if (WriteEnd > NextToWrite) {
|
|
+ if (Rewriter->KeepAllComments)
|
|
+ OS.write(FromFile->getBufferStart() + NextToWrite, WriteEnd - NextToWrite);
|
|
+ else if (Rewriter->KeepCommentsInCodeLines)
|
|
+ OutputContentStripComments(WriteEnd, false);
|
|
+ else // Remove all comments.
|
|
+ OutputContentStripComments(WriteEnd, true);
|
|
+ // 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 -rewrite-includes */" << EOL;
|
|
+ OutputContentUpTo(SM.getFileOffset(DirectiveToken.getLocation())
|
|
+ + DirectiveToken.getLength());
|
|
+ OS << "#endif /* expanded by -rewrite-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 -rewrite-includes mode.
|
|
+void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
|
|
+ const PreprocessorOutputOptions &Opts) {
|
|
+ IncludeRewriter* Rewrite = new IncludeRewriter(PP, *OS, Opts);
|
|
+ PP.addPPCallbacks(Rewrite);
|
|
+ PP.AddCommentHandler(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/make_patch tools/clang/make_patch
|
|
index d42af26..61a263d 100755
|
|
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..52be495
|
|
--- /dev/null
|
|
+++ tools/clang/test/Frontend/rewrite-includes.c
|
|
@@ -0,0 +1,46 @@
|
|
+// RUN: %clang_cc1 -verify -rewrite-includes -DFIRST -I %S/Inputs %s -CC -o - | FileCheck -check-prefix=CHECK-C2 -strict-whitespace %s.check
|
|
+// RUN: %clang_cc1 -verify -rewrite-includes -DFIRST -I %S/Inputs %s -C -o - | FileCheck -check-prefix=CHECK-C1 -strict-whitespace %s.check
|
|
+// RUN: %clang_cc1 -verify -rewrite-includes -DFIRST -I %S/Inputs %s -o - | FileCheck -check-prefix=CHECK-C0 -strict-whitespace %s.check
|
|
+
|
|
+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
|
|
+
|
|
+ // comment
|
|
+ /*
|
|
+ multiline
|
|
+ comment
|
|
+ */
|
|
+#define MACRO \
|
|
+ /*comment*/ \
|
|
+ /*multi \
|
|
+ line*/ \
|
|
+
|
|
+MACRO
|
|
+/*
|
|
+\
|
|
+comment
|
|
+*/
|
|
+foo /* multiline
|
|
+with code
|
|
+prepended */
|
|
+/* multiline
|
|
+with code
|
|
+appended */ bar
|
|
+#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
|
|
diff --git tools/clang/test/Frontend/rewrite-includes.c.check tools/clang/test/Frontend/rewrite-includes.c.check
|
|
new file mode 100644
|
|
index 0000000..7e920a5
|
|
--- /dev/null
|
|
+++ tools/clang/test/Frontend/rewrite-includes.c.check
|
|
@@ -0,0 +1,308 @@
|
|
+Modes that remove comments would also remove these check lines, so keep them in a separate file.
|
|
+
|
|
+Note that FileCheck does not seem to have a way to check for an empty line,
|
|
+so there is just a comment, the next non-empty line is not -NEXT but a plain check line
|
|
+and the line correctness is checked by same later # directive check.
|
|
+
|
|
+This one checks -CC, i.e. all comments are kept. It's the primary mode for the test.
|
|
+
|
|
+// CHECK-C2: {{^}}STARTCOMPARE{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#define A(a,b) a ## b{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}A(1,2){{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#include "rewrite-includes1.h"{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes1.h" 1{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#pragma clang system_header{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 2 "{{.*}}/Inputs/rewrite-includes1.h" 3{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}included_line1{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#include "rewrite-includes2.h"{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes2.h" 1 3{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}included_line2{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 4 "{{.*}}/Inputs/rewrite-includes1.h" 2 3{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 9 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#ifdef FIRST{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#define HEADER "rewrite-includes3.h"{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#include HEADER{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes3.h" 1{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}included_line3{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 12 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#else{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#include "rewrite-includes4.h"{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 14 "{{.*}}rewrite-includes.c"{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#/**/include /**/ "rewrite-includes5.h" /**/ {{\\}}{{$}}
|
|
+// CHECK-C2-NEXT: {{^}} {{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes5.h" 1{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}included_line5{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 17 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#include "rewrite-includes6.h" // comment{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes6.h" 1{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#pragma once{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 2 "{{.*}}/Inputs/rewrite-includes6.h"{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}included_line6{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 18 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C2-NEXT: {{^}} {{$}}
|
|
+// CHECK-C2-NEXT: {{^}} // comment{{$}}
|
|
+// CHECK-C2-NEXT: {{^}} /*{{$}}
|
|
+// CHECK-C2-NEXT: {{^}} multiline{{$}}
|
|
+// CHECK-C2-NEXT: {{^}} comment{{$}}
|
|
+// CHECK-C2-NEXT: {{^}} */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#define MACRO \{{$}}
|
|
+// CHECK-C2-NEXT: {{^}} /*comment*/ \{{$}}
|
|
+// CHECK-C2-NEXT: {{^}} /*multi \{{$}}
|
|
+// CHECK-C2-NEXT: {{^}} line*/ \{{$}}
|
|
+// CHECK-C2-NEXT: {{^}} {{$}}
|
|
+// CHECK-C2-NEXT: {{^}}MACRO{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}/*{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}\{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}comment{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}*/{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}foo /* multiline{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}with code{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}prepended */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}/* multiline{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}with code{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}appended */ bar{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#include "rewrite-includes6.h" /* comment{{$}}
|
|
+// CHECK-C2-NEXT: {{^}} continues */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 42 "{{.*}}rewrite-includes.c"{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes7.h" 1{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#ifndef REWRITE_INCLUDES7_H{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#define REWRITE_INCLUDES7_H{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}included_line7{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 43 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 44 "{{.*}}rewrite-includes.c"{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#include "rewrite-includes8.h" // no trailing \n in file{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes8.h" 1{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}included_line8{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 45 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#include "rewrite-includes9.h" // empty file{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes9.h" 1{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}# 46 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C2-NEXT: {{^}}ENDCOMPARE{{$}}
|
|
+
|
|
+This one checks -C, i.e. only comments on lines with other non-whitespace are kept.
|
|
+Note that lines containing only whitespace are not preserved exactly and are converted to empty lines.
|
|
+
|
|
+// CHECK-C1: {{^}}STARTCOMPARE{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#define A(a,b) a ## b{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}A(1,2){{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#include "rewrite-includes1.h"{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes1.h" 1{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#pragma clang system_header{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 2 "{{.*}}/Inputs/rewrite-includes1.h" 3{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}included_line1{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#include "rewrite-includes2.h"{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes2.h" 1 3{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}included_line2{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 4 "{{.*}}/Inputs/rewrite-includes1.h" 2 3{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 9 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#ifdef FIRST{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#define HEADER "rewrite-includes3.h"{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#include HEADER{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes3.h" 1{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}included_line3{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 12 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#else{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#include "rewrite-includes4.h"{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 14 "{{.*}}rewrite-includes.c"{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#/**/include /**/ "rewrite-includes5.h" /**/ {{\\}}{{$}}
|
|
+// here's an empty line
|
|
+// CHECK-C1: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes5.h" 1{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}included_line5{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 17 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#include "rewrite-includes6.h" // comment{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes6.h" 1{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#pragma once{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 2 "{{.*}}/Inputs/rewrite-includes6.h"{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}included_line6{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 18 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// here are 6 empty lines
|
|
+// CHECK-C1: {{^}}#define MACRO \{{$}}
|
|
+// CHECK-C1-NEXT: {{^}} /*comment*/ \{{$}}
|
|
+// CHECK-C1-NEXT: {{^}} /*multi \{{$}}
|
|
+// CHECK-C1-NEXT: {{^}} line*/ \{{$}}
|
|
+// here's an empty line
|
|
+// CHECK-C1: {{^}}MACRO{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}/*{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}\{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}comment{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}*/{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}foo /* multiline{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}with code{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}prepended */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}/* multiline{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}with code{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}appended */ bar{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#include "rewrite-includes6.h" /* comment{{$}}
|
|
+// CHECK-C1-NEXT: {{^}} continues */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 42 "{{.*}}rewrite-includes.c"{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes7.h" 1{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#ifndef REWRITE_INCLUDES7_H{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#define REWRITE_INCLUDES7_H{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}included_line7{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 43 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 44 "{{.*}}rewrite-includes.c"{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#include "rewrite-includes8.h" // no trailing \n in file{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes8.h" 1{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}included_line8{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 45 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#include "rewrite-includes9.h" // empty file{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes9.h" 1{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}# 46 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C1-NEXT: {{^}}ENDCOMPARE{{$}}
|
|
+
|
|
+This one checks without -C or -CC, i.e. comments removed.
|
|
+
|
|
+// CHECK-C0: {{^}}STARTCOMPARE{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#define A(a,b) a ## b{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}A(1,2){{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#include "rewrite-includes1.h"{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes1.h" 1{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#pragma clang system_header{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 2 "{{.*}}/Inputs/rewrite-includes1.h" 3{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}included_line1{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#include "rewrite-includes2.h"{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes2.h" 1 3{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}included_line2{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 4 "{{.*}}/Inputs/rewrite-includes1.h" 2 3{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 9 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#ifdef FIRST{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#define HEADER "rewrite-includes3.h"{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#include HEADER{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes3.h" 1{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}included_line3{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 12 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#else{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#include "rewrite-includes4.h"{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 14 "{{.*}}rewrite-includes.c"{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#include "rewrite-includes5.h" {{\\}}{{$}}
|
|
+// CHECK-C0-NEXT: {{^}} {{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes5.h" 1{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}included_line5{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 17 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#include "rewrite-includes6.h" {{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes6.h" 1{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#pragma once{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 2 "{{.*}}/Inputs/rewrite-includes6.h"{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}included_line6{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 18 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C0-NEXT: {{^}} {{$}}
|
|
+// here are 5 empty lines
|
|
+// CHECK-C0: {{^}}#define MACRO \{{$}}
|
|
+// CHECK-C0-NEXT: {{^}} \{{$}}
|
|
+// CHECK-C0-NEXT: {{^}} \{{$}}
|
|
+// CHECK-C0-NEXT: {{^}} \{{$}}
|
|
+// here's an empty line
|
|
+// CHECK-C0: {{^}}MACRO{{$}}
|
|
+// here's an empty line
|
|
+// CHECK-C0: {{^}}\{{$}}
|
|
+// here are 2 empty lines
|
|
+// CHECK-C0: {{^}}foo {{$}}
|
|
+// here are 4 empty lines
|
|
+// CHECK-C0: {{^}} bar{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#include "rewrite-includes6.h" {{$}}
|
|
+// here's an empty line
|
|
+// CHECK-C0: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 42 "{{.*}}rewrite-includes.c"{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes7.h" 1{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#ifndef REWRITE_INCLUDES7_H{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#define REWRITE_INCLUDES7_H{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}included_line7{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 43 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 44 "{{.*}}rewrite-includes.c"{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#include "rewrite-includes8.h" {{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes8.h" 1{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}included_line8{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 45 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#if 0 /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#include "rewrite-includes9.h" {{$}}
|
|
+// CHECK-C0-NEXT: {{^}}#endif /* expanded by -rewrite-includes */{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 1 "{{.*}}/Inputs/rewrite-includes9.h" 1{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}# 46 "{{.*}}rewrite-includes.c" 2{{$}}
|
|
+// CHECK-C0-NEXT: {{^}}ENDCOMPARE{{$}}
|