Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -596,6 +596,10 @@ Group, Flags<[DriverOption]>; +def fuse_line_directives : Flag<["-"], "fuse-line-directives">, Group, + Flags<[CC1Option]>; +def fno_use_line_directives : Flag<["-"], "fno-use-line-directives">, 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 UseLineDirectives : 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; + UseLineDirectives = 0; ShowMacroComments = 0; ShowMacros = 0; RewriteIncludes = 0; Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -4067,6 +4067,11 @@ IsWindowsMSVC)) CmdArgs.push_back("-fms-extensions"); + // -fno-use-line-directives is default. + if (Args.hasFlag(options::OPT_fuse_line_directives, + options::OPT_fno_use_line_directives, false)) + CmdArgs.push_back("-fuse-line-directives"); + // -fms-compatibility=0 is default. if (Args.hasFlag(options::OPT_fms_compatibility, options::OPT_fno_ms_compatibility, Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1826,6 +1826,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.UseLineDirectives = Args.hasArg(OPT_fuse_line_directives); } static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) { Index: lib/Frontend/PrintPreprocessedOutput.cpp =================================================================== --- lib/Frontend/PrintPreprocessedOutput.cpp +++ lib/Frontend/PrintPreprocessedOutput.cpp @@ -94,14 +94,14 @@ bool Initialized; bool DisableLineMarkers; bool DumpDefines; - bool UseLineDirective; + bool UseLineDirectives; 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 UseLineDirectives) + : PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os), + DisableLineMarkers(lineMarkers), DumpDefines(defines), + UseLineDirectives(UseLineDirectives) { 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; } @@ -183,7 +180,7 @@ startNewLineIfNeeded(/*ShouldUpdateCurrentLine=*/false); // Emit #line directives or GNU line markers depending on what mode we're in. - if (UseLineDirective) { + if (UseLineDirectives) { OS << "#line" << ' ' << LineNo << ' ' << '"'; OS.write_escaped(CurFilename); OS << '"'; @@ -719,9 +716,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.UseLineDirectives); 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 @@ -43,14 +43,15 @@ StringRef MainEOL; ///< The line ending marker to use. const llvm::MemoryBuffer *PredefinesBuffer; ///< The preprocessor predefines. bool ShowLineMarkers; ///< Show #line markers. - bool UseLineDirective; ///< Use of line directives or line markers. + bool UseLineDirectives; ///< Use of line directives or line markers. typedef std::map FileChangeMap; FileChangeMap FileChanges; ///< Tracks which files were included where. /// Used transitively for building up the FileChanges mapping over the /// 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 UseLineDirectives); 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 UseLineDirectives) : 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()), + UseLineDirectives(UseLineDirectives) {} /// Write appropriate line information as either #line directives or GNU line /// markers depending on what mode we're in, including the \p Filename and @@ -106,7 +106,7 @@ StringRef Extra) { if (!ShowLineMarkers) return; - if (UseLineDirective) { + if (UseLineDirectives) { OS << "#line" << ' ' << Line << ' ' << '"'; OS.write_escaped(Filename); OS << '"'; @@ -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.UseLineDirectives); Rewrite->detectMainFileEOL(); PP.addPPCallbacks(std::unique_ptr(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-directives -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; } Index: test/Lexer/pragma-operators.cpp =================================================================== --- test/Lexer/pragma-operators.cpp +++ test/Lexer/pragma-operators.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fms-extensions -std=c++11 -E %s | FileCheck %s +// RUN: %clang_cc1 -fms-extensions -std=c++11 -E %s -fuse-line-directives | FileCheck %s // Test that we properly expand the C99 _Pragma and Microsoft __pragma // into #pragma directives, with newlines where needed. Index: test/Preprocessor/_Pragma-location.c =================================================================== --- test/Preprocessor/_Pragma-location.c +++ test/Preprocessor/_Pragma-location.c @@ -10,9 +10,9 @@ push_p _Pragma("pack(push)") __pragma(pack(push)) // CHECK: #pragma pack(push) -// CHECK-NEXT: #line 11 "{{.*}}_Pragma-location.c" +// CHECK-NEXT: # 11 "{{.*}}_Pragma-location.c" // CHECK-NEXT: #pragma pack(push) -// CHECK-NEXT: #line 11 "{{.*}}_Pragma-location.c" +// CHECK-NEXT: # 11 "{{.*}}_Pragma-location.c" // CHECK-NEXT: #pragma pack(push) @@ -31,17 +31,17 @@ // CHECK: void test () { // CHECK-NEXT: 1; -// CHECK-NEXT: #line 24 "{{.*}}_Pragma-location.c" +// CHECK-NEXT: # 24 "{{.*}}_Pragma-location.c" // CHECK-NEXT: #pragma clang diagnostic push // CHECK-NEXT: #pragma clang diagnostic ignored "-Wformat-extra-args" // CHECK-NEXT: #pragma clang diagnostic pop // CHECK: 2; -// CHECK-NEXT: #line 28 "{{.*}}_Pragma-location.c" +// CHECK-NEXT: # 28 "{{.*}}_Pragma-location.c" // CHECK-NEXT: #pragma clang diagnostic push -// CHECK-NEXT: #line 28 "{{.*}}_Pragma-location.c" +// CHECK-NEXT: # 28 "{{.*}}_Pragma-location.c" // CHECK-NEXT: #pragma clang diagnostic ignored "-Wformat-extra-args" // CHECK-NEXT: 3; -// CHECK-NEXT: #line 29 "{{.*}}_Pragma-location.c" +// CHECK-NEXT: # 29 "{{.*}}_Pragma-location.c" // CHECK-NEXT: #pragma clang diagnostic pop // CHECK-NEXT: }