forked from OSchip/llvm-project
Add -fuse-line-directive flag to control usage of #line with -E
Currently -fms-extensions controls this behavior, which doesn't make much sense. It means we can't identify what is and isn't a system header when compiling our own preprocessed output, because #line doesn't represent this information. If someone is feeding Clang's preprocessed output to another compiler, they can use this flag. Fixes PR20553. Reviewers: rsmith Differential Revision: http://reviews.llvm.org/D5217 llvm-svn: 230587
This commit is contained in:
parent
ebdfc00995
commit
1df0fea593
|
@ -596,6 +596,10 @@ def frewrite_map_file_EQ : Joined<["-"], "frewrite-map-file=">,
|
|||
Group<f_Group>,
|
||||
Flags<[DriverOption]>;
|
||||
|
||||
def fuse_line_directives : Flag<["-"], "fuse-line-directives">, Group<f_Group>,
|
||||
Flags<[CC1Option]>;
|
||||
def fno_use_line_directives : Flag<["-"], "fno-use-line-directives">, Group<f_Group>;
|
||||
|
||||
def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Assert that the compilation takes place in a freestanding environment">;
|
||||
def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group<f_Group>, Flags<[CC1Option]>,
|
||||
|
|
|
@ -19,6 +19,7 @@ public:
|
|||
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 @@ public:
|
|||
ShowCPP = 0;
|
||||
ShowComments = 0;
|
||||
ShowLineMarkers = 1;
|
||||
UseLineDirectives = 0;
|
||||
ShowMacroComments = 0;
|
||||
ShowMacros = 0;
|
||||
RewriteIncludes = 0;
|
||||
|
|
|
@ -4067,6 +4067,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
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,
|
||||
|
|
|
@ -1826,6 +1826,7 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
|
|||
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) {
|
||||
|
|
|
@ -94,14 +94,14 @@ private:
|
|||
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 += "<uninit>";
|
||||
EmittedTokensOnThisLine = false;
|
||||
|
@ -109,9 +109,6 @@ public:
|
|||
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 @@ void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
|
|||
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 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
|
|||
// 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",
|
||||
|
|
|
@ -43,14 +43,15 @@ class InclusionRewriter : public PPCallbacks {
|
|||
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<unsigned, FileChange> 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 @@ private:
|
|||
|
||||
/// 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 @@ void InclusionRewriter::WriteLineInfo(const char *Filename, int Line,
|
|||
StringRef Extra) {
|
||||
if (!ShowLineMarkers)
|
||||
return;
|
||||
if (UseLineDirective) {
|
||||
if (UseLineDirectives) {
|
||||
OS << "#line" << ' ' << Line << ' ' << '"';
|
||||
OS.write_escaped(Filename);
|
||||
OS << '"';
|
||||
|
@ -561,8 +561,8 @@ bool InclusionRewriter::Process(FileID FileId,
|
|||
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<PPCallbacks>(Rewrite));
|
||||
|
|
|
@ -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; }
|
|
@ -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. <rdar://problem/8412013>
|
||||
|
|
|
@ -10,9 +10,9 @@ push_p
|
|||
|
||||
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 @@ void test () {
|
|||
|
||||
// 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: }
|
||||
|
|
Loading…
Reference in New Issue