Introduce the -fdiagnostics-format=xxx option to control how Clang

prints the file, line, and column of a diagnostic. We currently
support Clang's normal format, MSVC, and Vi formats.

Note that we no longer change the diagnostic format based on
-fms-extensions.

Patch by Andrew Fish!

llvm-svn: 131794
This commit is contained in:
Douglas Gregor 2011-05-21 17:07:29 +00:00
parent 61b6e49ee1
commit 643c922e66
8 changed files with 124 additions and 11 deletions

View File

@ -272,6 +272,29 @@ when this is enabled, Clang will print something like:
//
</pre>
</dd>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<dt id="opt_fdiagnostics-format"><b>-fdiagnostics-format=clang/msvc/vi</b>:
Changes diagnostic output format to better match IDEs and command line tools.</dt>
<dd>This option controls the output format of the filename, line number, and column printed in diagnostic messages. The options, and their affect on formatting a simple conversion diagnostic, follow:
<dl>
<dt><b>clang</b> (default)</dt>
<dd>
<pre>t.c:3:11: warning: conversion specifies type 'char *' but the argument has type 'int'</pre>
</dd>
<dt><b>msvc</b></dt>
<dd>
<pre>t.c(3,11) : warning: conversion specifies type 'char *' but the argument has type 'int'</pre>
</dd>
<dt><b>vi</b></dt>
<dd>
<pre>t.c +3:11: warning: conversion specifies type 'char *' but the argument has type 'int'</pre>
</dd>
</dl>
</dd>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<dt id="opt_fdiagnostics-show-option"><b>-f[no-]diagnostics-show-option</b>:
Enable <tt>[-Woption]</tt> information in diagnostic line.</dt>

View File

@ -216,6 +216,8 @@ def diagnostic_log_file : Separate<"-diagnostic-log-file">,
HelpText<"Filename (or -) to log diagnostics to">;
def fno_show_column : Flag<"-fno-show-column">,
HelpText<"Do not include column number on diagnostics">;
def fshow_column : Flag<"-fshow-column">,
HelpText<"Include column number on diagnostics">;
def fno_show_source_location : Flag<"-fno-show-source-location">,
HelpText<"Do not include source location information with diagnostics">;
def fshow_overloads_EQ : Joined<"-fshow-overloads=">,
@ -245,6 +247,8 @@ def fdiagnostics_show_name : Flag<"-fdiagnostics-show-name">,
HelpText<"Print diagnostic name">;
def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">,
HelpText<"Print option name with mappable diagnostics">;
def fdiagnostics_format : Separate<"-fdiagnostics-format">,
HelpText<"Change diagnostic formatting to match IDE and command line tools">;
def fdiagnostics_show_category : Separate<"-fdiagnostics-show-category">,
HelpText<"Print diagnostic category">;
def fdiagnostics_show_note_include_stack :

View File

@ -278,6 +278,7 @@ def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">, Grou
def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>;
def fdiagnostics_show_name : Flag<"-fdiagnostics-show-name">, Group<f_Group>;
def fdiagnostics_show_note_include_stack : Flag<"-fdiagnostics-show-note-include-stack">, Group<f_Group>;
def fdiagnostics_format_EQ : Joined<"-fdiagnostics-format=">, Group<f_clang_Group>;
def fdiagnostics_show_category_EQ : Joined<"-fdiagnostics-show-category=">, Group<f_clang_Group>;
def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, Group<f_Group>;
def fdwarf2_cfi_asm : Flag<"-fdwarf2-cfi-asm">, Group<f_Group>;
@ -418,6 +419,7 @@ def fshort_enums : Flag<"-fshort-enums">, Group<f_Group>;
def freorder_blocks : Flag<"-freorder-blocks">, Group<clang_ignored_f_Group>;
def fshort_wchar : Flag<"-fshort-wchar">, Group<f_Group>;
def fshow_overloads_EQ : Joined<"-fshow-overloads=">, Group<f_Group>;
def fshow_column : Flag<"-fshow-column">, Group<f_Group>;
def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>;
def fspell_checking : Flag<"-fspell-checking">, Group<f_Group>;
def fsigned_bitfields : Flag<"-fsigned-bitfields">, Group<f_Group>;

View File

@ -37,6 +37,10 @@ public:
unsigned ShowNoteIncludeStack : 1; /// Show include stacks for notes.
unsigned ShowCategories : 2; /// Show categories: 0 -> none, 1 -> Number,
/// 2 -> Full Name.
unsigned Format : 2; /// Format for diagnostics:
enum TextDiagnosticFormat { Clang, Msvc, Vi };
unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences.
unsigned ShowOverloads : 1; /// Overload candidates to show. Values from
/// Diagnostic::OverloadsShown
@ -86,6 +90,7 @@ public:
ShowNames = 0;
ShowOptionNames = 0;
ShowCategories = 0;
Format = Clang;
ShowSourceRanges = 0;
ShowParseableFixits = 0;
VerifyDiagnostics = 0;

View File

@ -1543,7 +1543,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.getLastArg(options::OPT_fapple_kext))
CmdArgs.push_back("-fapple-kext");
Args.AddLastArg(CmdArgs, options::OPT_fno_show_column);
Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
@ -1869,6 +1868,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue(Args));
}
if (const Arg *A =
Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
CmdArgs.push_back("-fdiagnostics-format");
CmdArgs.push_back(A->getValue(Args));
}
if (Arg *A = Args.getLastArg(
options::OPT_fdiagnostics_show_note_include_stack,
options::OPT_fno_diagnostics_show_note_include_stack)) {
@ -1890,6 +1895,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_show_source_location))
CmdArgs.push_back("-fno-show-source-location");
if (!Args.hasFlag(options::OPT_fshow_column,
options::OPT_fno_show_column,
true))
CmdArgs.push_back("-fno-show-column");
if (!Args.hasFlag(options::OPT_fspell_checking,
options::OPT_fno_spell_checking))
CmdArgs.push_back("-fno-spell-checking");

View File

@ -277,6 +277,14 @@ static void DiagnosticOptsToArgs(const DiagnosticOptions &Opts,
Res.push_back("-fdiagnostics-show-category=id");
else if (Opts.ShowCategories == 2)
Res.push_back("-fdiagnostics-show-category=name");
switch (Opts.Format) {
case DiagnosticOptions::Clang:
Res.push_back("-fdiagnostics-format=clang"); break;
case DiagnosticOptions::Msvc:
Res.push_back("-fdiagnostics-format=msvc"); break;
case DiagnosticOptions::Vi:
Res.push_back("-fdiagnostics-format=vi"); break;
}
if (Opts.ErrorLimit) {
Res.push_back("-ferror-limit");
Res.push_back(llvm::utostr(Opts.ErrorLimit));
@ -1011,7 +1019,9 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors);
Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics);
Opts.ShowColors = Args.hasArg(OPT_fcolor_diagnostics);
Opts.ShowColumn = !Args.hasArg(OPT_fno_show_column);
Opts.ShowColumn = Args.hasFlag(OPT_fshow_column,
OPT_fno_show_column,
/*Default=*/true);
Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info);
Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location);
Opts.ShowNames = Args.hasArg(OPT_fdiagnostics_show_name);
@ -1048,6 +1058,19 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
<< Args.getLastArg(OPT_fdiagnostics_show_category)->getAsString(Args)
<< ShowCategory;
llvm::StringRef Format =
Args.getLastArgValue(OPT_fdiagnostics_format, "clang");
if (Format == "clang")
Opts.Format = DiagnosticOptions::Clang;
else if (Format == "msvc")
Opts.Format = DiagnosticOptions::Msvc;
else if (Format == "vi")
Opts.Format = DiagnosticOptions::Vi;
else
Diags.Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_fdiagnostics_format)->getAsString(Args)
<< Format;
Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits);
Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);

View File

@ -819,16 +819,28 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
if (DiagOpts->ShowColors)
OS.changeColor(savedColor, true);
// Emit a Visual Studio compatible line number syntax.
if (LangOpts && LangOpts->Microsoft) {
OS << PLoc.getFilename() << '(' << LineNo << ')';
OS << " : ";
} else {
OS << PLoc.getFilename() << ':' << LineNo << ':';
if (DiagOpts->ShowColumn)
if (unsigned ColNo = PLoc.getColumn())
OS << ColNo << ':';
OS << PLoc.getFilename();
switch (DiagOpts->Format) {
case DiagnosticOptions::Clang: OS << ':' << LineNo; break;
case DiagnosticOptions::Msvc: OS << '(' << LineNo; break;
case DiagnosticOptions::Vi: OS << " +" << LineNo; break;
}
if (DiagOpts->ShowColumn)
if (unsigned ColNo = PLoc.getColumn()) {
if (DiagOpts->Format == DiagnosticOptions::Msvc) {
OS << ',';
ColNo--;
} else
OS << ':';
OS << ColNo;
}
switch (DiagOpts->Format) {
case DiagnosticOptions::Clang:
case DiagnosticOptions::Vi: OS << ':'; break;
case DiagnosticOptions::Msvc: OS << ") : "; break;
}
if (DiagOpts->ShowSourceRanges && Info.getNumRanges()) {
FileID CaretFileID =
SM.getFileID(SM.getInstantiationLoc(Info.getLocation()));

View File

@ -0,0 +1,34 @@
// RUN: %clang -fsyntax-only %s 2>&1 | FileCheck %s -check-prefix=DEFAULT
// RUN: %clang -fsyntax-only -fdiagnostics-format=clang %s 2>&1 | FileCheck %s -check-prefix=DEFAULT
// RUN: %clang -fsyntax-only -fdiagnostics-format=clang -ccc-host-triple x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=DEFAULT
//
// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc %s 2>&1 | FileCheck %s -check-prefix=MSVC
// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -ccc-host-triple x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC
// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -ccc-host-triple x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC
//
// RUN: %clang -fsyntax-only -fdiagnostics-format=vi %s 2>&1 | FileCheck %s -check-prefix=VI
//
// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fno-show-column %s 2>&1 | FileCheck %s -check-prefix=MSVC_ORIG
//
// RUN: %clang -fsyntax-only -fno-show-column %s 2>&1 | FileCheck %s -check-prefix=NO_COLUMN
//
#ifdef foo
#endif bad // extension!
// DEFAULT: {{.*}}:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
// MSVC: {{.*}}(28,7) : warning: extra tokens at end of #endif directive [-Wextra-tokens]
// VI: {{.*}} +28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
// MSVC_ORIG: {{.*}}(28) : warning: extra tokens at end of #endif directive [-Wextra-tokens]
// NO_COLUMN: {{.*}}:28: warning: extra tokens at end of #endif directive [-Wextra-tokens]
int x;