Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -569,6 +569,10 @@ Flags<[CC1Option]>; def fno_rewrite_includes : Flag<["-"], "fno-rewrite-includes">, Group; +def fuse_line_directive : Flag<["-"], "fuse-line-directive">, Group, + Flags<[CC1Option]>; +def fno_use_line_directive : Flag<["-"], "fno-use-line-directive">, Group; + def ffreestanding : Flag<["-"], "ffreestanding">, Group, Flags<[CC1Option]>, HelpText<"Assert that the compilation takes place in a freestanding environment">; def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group, Flags<[CC1Option]>, Index: include/clang/Frontend/PreprocessorOutputOptions.h =================================================================== --- include/clang/Frontend/PreprocessorOutputOptions.h +++ include/clang/Frontend/PreprocessorOutputOptions.h @@ -19,6 +19,7 @@ unsigned ShowCPP : 1; ///< Print normal preprocessed output. unsigned ShowComments : 1; ///< Show comments. unsigned ShowLineMarkers : 1; ///< Show \#line markers. + unsigned UseLineDirective : 1; ///< Use \#line instead of GCC-style \# N. unsigned ShowMacroComments : 1; ///< Show comments, even in macros. unsigned ShowMacros : 1; ///< Print macro definitions. unsigned RewriteIncludes : 1; ///< Preprocess include directives only. @@ -28,6 +29,7 @@ ShowCPP = 0; ShowComments = 0; ShowLineMarkers = 1; + UseLineDirective = 0; ShowMacroComments = 0; ShowMacros = 0; RewriteIncludes = 0; Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1766,6 +1766,7 @@ Opts.ShowMacroComments = Args.hasArg(OPT_CC); Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD); Opts.RewriteIncludes = Args.hasArg(OPT_frewrite_includes); + Opts.UseLineDirective = Args.hasArg(OPT_fuse_line_directive); } static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) { Index: lib/Frontend/PrintPreprocessedOutput.cpp =================================================================== --- lib/Frontend/PrintPreprocessedOutput.cpp +++ lib/Frontend/PrintPreprocessedOutput.cpp @@ -97,11 +97,11 @@ bool UseLineDirective; bool IsFirstFileEntered; public: - PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream &os, - bool lineMarkers, bool defines) - : PP(pp), SM(PP.getSourceManager()), - ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers), - DumpDefines(defines) { + PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream &os, bool lineMarkers, + bool defines, bool UseLineDirective) + : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os), + DisableLineMarkers(lineMarkers), DumpDefines(defines), + UseLineDirective(UseLineDirective) { CurLine = 0; CurFilename += ""; EmittedTokensOnThisLine = false; @@ -109,9 +109,6 @@ FileType = SrcMgr::C_User; Initialized = false; IsFirstFileEntered = false; - - // If we're in microsoft mode, use normal #line instead of line markers. - UseLineDirective = PP.getLangOpts().MicrosoftExt; } void setEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; } @@ -716,9 +713,8 @@ // to -C or -CC. PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments); - PrintPPOutputPPCallbacks *Callbacks = - new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers, - Opts.ShowMacros); + PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks( + PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros, Opts.UseLineDirective); PP.AddPragmaHandler(new UnknownPragmaHandler("#pragma", Callbacks)); PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",Callbacks)); PP.AddPragmaHandler("clang", Index: lib/Frontend/Rewrite/InclusionRewriter.cpp =================================================================== --- lib/Frontend/Rewrite/InclusionRewriter.cpp +++ lib/Frontend/Rewrite/InclusionRewriter.cpp @@ -50,7 +50,8 @@ /// various \c PPCallbacks callbacks. FileChangeMap::iterator LastInsertedFileChange; public: - InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers); + InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers, + bool UseLineDirective); bool Process(FileID FileId, SrcMgr::CharacteristicKind FileType); void setPredefinesBuffer(const llvm::MemoryBuffer *Buf) { PredefinesBuffer = Buf; @@ -89,13 +90,12 @@ /// Initializes an InclusionRewriter with a \p PP source and \p OS destination. InclusionRewriter::InclusionRewriter(Preprocessor &PP, raw_ostream &OS, - bool ShowLineMarkers) + bool ShowLineMarkers, + bool UseLineDirective) : PP(PP), SM(PP.getSourceManager()), OS(OS), MainEOL("\n"), PredefinesBuffer(nullptr), ShowLineMarkers(ShowLineMarkers), - LastInsertedFileChange(FileChanges.end()) { - // If we're in microsoft mode, use normal #line instead of line markers. - UseLineDirective = PP.getLangOpts().MicrosoftExt; -} + LastInsertedFileChange(FileChanges.end()), + UseLineDirective(UseLineDirective) {} /// Write appropriate line information as either #line directives or GNU line /// markers depending on what mode we're in, including the \p Filename and @@ -561,8 +561,8 @@ void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts) { SourceManager &SM = PP.getSourceManager(); - InclusionRewriter *Rewrite = new InclusionRewriter(PP, *OS, - Opts.ShowLineMarkers); + InclusionRewriter *Rewrite = new InclusionRewriter( + PP, *OS, Opts.ShowLineMarkers, Opts.UseLineDirective); Rewrite->detectMainFileEOL(); PP.addPPCallbacks(Rewrite); Index: test/Frontend/rewrite-includes-line-markers.c =================================================================== --- /dev/null +++ test/Frontend/rewrite-includes-line-markers.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -E -frewrite-includes -I %S/Inputs %s | FileCheck %s --check-prefix=GNU +// RUN: %clang_cc1 -E -frewrite-includes -fuse-line-directive -I %S/Inputs %s | FileCheck %s --check-prefix=LINE +#include "test.h" +int f() { return x; } + +// GNU: {{^}}# 1 "{{.*}}rewrite-includes-line-markers.c" +// GNU: {{^}}#include "test.h" +// GNU: {{^}}# 1 "{{.*}}test.h" +// GNU: {{^}}#include "test2.h" +// GNU: {{^}}# 1 "{{.*}}test2.h" +// GNU: {{^}}int x; +// GNU: {{^}}# 4 "{{.*}}rewrite-includes-line-markers.c" 2 +// GNU: {{^}}int f() { return x; } + +// LINE: {{^}}#line 1 "{{.*}}rewrite-includes-line-markers.c" +// LINE: {{^}}#include "test.h" +// LINE: {{^}}#line 1 "{{.*}}test.h" +// LINE: {{^}}#include "test2.h" +// LINE: {{^}}#line 1 "{{.*}}test2.h" +// LINE: {{^}}int x; +// LINE: {{^}}#line 4 "{{.*}}rewrite-includes-line-markers.c" +// LINE: {{^}}int f() { return x; }