diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-08-19 20:24:43 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-08-19 20:24:43 +0000 |
commit | 4786c15f4977c7cee98fde3ebdee213dba23848b (patch) | |
tree | 52faf7befb7a831cd58682ea60713d7414081550 | |
parent | c1cf1586f7bbdf8a955a3be79309834ebc25c3af (diff) |
Add machine-parseable Fix-It output as part of diagnostics, under the
flag -fdiagnostics-parseable-fixits, from Eelis van der Weegen!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111557 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/UsersManual.html | 12 | ||||
-rw-r--r-- | docs/tools/clang.pod | 1 | ||||
-rw-r--r-- | include/clang/Driver/CC1Options.td | 2 | ||||
-rw-r--r-- | include/clang/Driver/Options.td | 1 | ||||
-rw-r--r-- | include/clang/Frontend/DiagnosticOptions.h | 2 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 1 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 3 | ||||
-rw-r--r-- | lib/Frontend/TextDiagnosticPrinter.cpp | 42 |
8 files changed, 64 insertions, 0 deletions
diff --git a/docs/UsersManual.html b/docs/UsersManual.html index 2402bf8dd7..1fcd59e26e 100644 --- a/docs/UsersManual.html +++ b/docs/UsersManual.html @@ -358,6 +358,18 @@ exprs.c:47:15:{47:8-47:14}{47:17-47:24}: error: invalid operands to binary expre <p>The {}'s are generated by -fdiagnostics-print-source-range-info.</p> </dd> +<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<dt id="opt_fdiagnostics-parseable-fixits"> +<b>-fdiagnostics-parseable-fixits</b>: +Print Fix-Its in a machine parseable form.</dt> +<dd><p>This option makes Clang print available Fix-Its in a machine parseable format at the end of diagnostics. The following example illustrates the format:</p> + +<pre> + fix-it: "t.cpp":{7:25-7:29}: "Gamma" +</pre> + +<p>The range printed is a half-open range, so in this example the characters at column 25 up to but not including column 29 on line 7 in t.cpp should be replaced with the string "Gamma". Either the range or the replacement string may be empty (representing strict insertions and strict erasures, respectively). Both the file name and the insertion string escape '\', tabs (as "\n"), newlines (as "\n"), double quotes(as "\n") and non-printable characters (as octal "\xxx").</p> +</dd> </dl> diff --git a/docs/tools/clang.pod b/docs/tools/clang.pod index 94f6b767a8..bcf84b7049 100644 --- a/docs/tools/clang.pod +++ b/docs/tools/clang.pod @@ -395,6 +395,7 @@ Show commands to run and use verbose output. B<-fshow-source-location> B<-fcaret-diagnostics> B<-fdiagnostics-fixit-info> +B<-fdiagnostics-parseable-fixits> B<-fdiagnostics-print-source-range-info> B<-fprint-source-range-info> B<-fdiagnostics-show-option> diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index abe81482dd..74d9fbaccf 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -215,6 +215,8 @@ def W : Joined<"-W">; def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, HelpText<"Print source range spans in numeric form">; +def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">, + HelpText<"Print fix-its in machine parseable form">; def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, HelpText<"Print diagnostic name with mappable diagnostics">; def fdiagnostics_show_category : Separate<"-fdiagnostics-show-category">, diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 034a234d6b..45bea9c186 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -261,6 +261,7 @@ def fdebug_pass_structure : Flag<"-fdebug-pass-structure">, Group<f_Group>; def fdiagnostics_binary : Flag<"-fdiagnostics-binary">, Group<f_Group>, Flags<[HelpHidden]>; def fdiagnostics_fixit_info : Flag<"-fdiagnostics-fixit-info">, Group<f_Group>; def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, Group<f_Group>; +def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">, Group<f_Group>; def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>; def fdiagnostics_show_category_EQ : Joined<"-fdiagnostics-show-category=">, Group<f_Group>; def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, Group<f_Group>; diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h index 516dc67b42..c80bc03721 100644 --- a/include/clang/Frontend/DiagnosticOptions.h +++ b/include/clang/Frontend/DiagnosticOptions.h @@ -30,6 +30,7 @@ public: unsigned ShowCarets : 1; /// Show carets in diagnostics. unsigned ShowFixits : 1; /// Show fixit information. unsigned ShowSourceRanges : 1; /// Show source ranges in numeric form. + unsigned ShowParseableFixits : 1; /// Show machine parseable fix-its. unsigned ShowOptionNames : 1; /// Show the diagnostic name for mappable /// diagnostics. unsigned ShowCategories : 2; /// Show categories: 0 -> none, 1 -> Number, @@ -83,6 +84,7 @@ public: ShowOptionNames = 0; ShowCategories = 0; ShowSourceRanges = 0; + ShowParseableFixits = 0; VerifyDiagnostics = 0; BinaryOutput = 0; ErrorLimit = 0; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 8fe2271f50..dd9e713c92 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1207,6 +1207,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, 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); Args.AddLastArg(CmdArgs, options::OPT_ftime_report); Args.AddLastArg(CmdArgs, options::OPT_ftrapv); Args.AddLastArg(CmdArgs, options::OPT_fwrapv); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 47bfefacd2..f8a56a0bad 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -244,6 +244,8 @@ static void DiagnosticOptsToArgs(const DiagnosticOptions &Opts, Res.push_back("-fno-diagnostics-fixit-info"); if (Opts.ShowSourceRanges) Res.push_back("-fdiagnostics-print-source-range-info"); + if (Opts.ShowParseableFixits) + Res.push_back("-fdiagnostics-parseable-fixits"); if (Opts.ShowColors) Res.push_back("-fcolor-diagnostics"); if (Opts.VerifyDiagnostics) @@ -933,6 +935,7 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, << ShowCategory; Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info); + Opts.ShowParseableFixits = Args.hasArg(OPT_fdiagnostics_parseable_fixits); Opts.VerifyDiagnostics = Args.hasArg(OPT_verify); Opts.BinaryOutput = Args.hasArg(OPT_fdiagnostics_binary); Opts.ErrorLimit = Args.getLastArgIntValue(OPT_ferror_limit, 0, Diags); diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp index bc1b50475b..c971ca3b9d 100644 --- a/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/lib/Frontend/TextDiagnosticPrinter.cpp @@ -537,6 +537,48 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc, if (DiagOpts->ShowColors) OS.resetColor(); } + + if (DiagOpts->ShowParseableFixits) { + + // We follow FixItRewriter's example in not (yet) handling + // fix-its in macros. + bool BadApples = false; + for (const FixItHint *Hint = Hints; Hint != Hints + NumHints; ++Hint) { + if (Hint->RemoveRange.isInvalid() || + Hint->RemoveRange.getBegin().isMacroID() || + Hint->RemoveRange.getEnd().isMacroID()) { + BadApples = true; + break; + } + } + + if (!BadApples) { + for (const FixItHint *Hint = Hints; Hint != Hints + NumHints; ++Hint) { + + SourceLocation B = Hint->RemoveRange.getBegin(); + SourceLocation E = Hint->RemoveRange.getEnd(); + + std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B); + std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E); + + // Adjust for token ranges. + if (Hint->RemoveRange.isTokenRange()) + EInfo.second += Lexer::MeasureTokenLength(E, SM, *LangOpts); + + // We specifically do not do word-wrapping or tab-expansion here, + // because this is supposed to be easy to parse. + OS << " fix-it: \""; + OS.write_escaped(SM.getPresumedLoc(B).getFilename()); + OS << "\":{" << SM.getLineNumber(BInfo.first, BInfo.second) + << ':' << SM.getColumnNumber(BInfo.first, BInfo.second) + << '-' << SM.getLineNumber(EInfo.first, EInfo.second) + << ':' << SM.getColumnNumber(EInfo.first, EInfo.second) + << "}: \""; + OS.write_escaped(Hint->CodeToInsert); + OS << "\"\n"; + } + } + } } /// \brief Skip over whitespace in the string, starting at the given |