]> granicus.if.org Git - clang/commitdiff
Add machine-parseable Fix-It output as part of diagnostics, under the
authorDouglas Gregor <dgregor@apple.com>
Thu, 19 Aug 2010 20:24:43 +0000 (20:24 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 19 Aug 2010 20:24:43 +0000 (20:24 +0000)
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

docs/UsersManual.html
docs/tools/clang.pod
include/clang/Driver/CC1Options.td
include/clang/Driver/Options.td
include/clang/Frontend/DiagnosticOptions.h
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp
lib/Frontend/TextDiagnosticPrinter.cpp

index 2402bf8dd70a9f064d91a19724f38b0afcf64425..1fcd59e26e31b63ee3d0af8956401bc47d3d158e 100644 (file)
@@ -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>
 
index 94f6b767a88caa10664342a79c364b090a5c3920..bcf84b7049f41f2cbbbd44c3b768caa02aa16624 100644 (file)
@@ -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>
index abe81482dd5ec132a8114f8f5e8da045fcfad7a9..74d9fbaccf39d87b9f2d7521ee6ab6536112835b 100644 (file)
@@ -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">,
index 034a234d6b00b82bb4b806fe9aa05933b37bda5e..45bea9c186a208096956caf12a88a21db27be515 100644 (file)
@@ -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>;
index 516dc67b425d443f8bf5a30c0960e69ab744195f..c80bc037212b68ccb8da635273e0c39c12b0df56 100644 (file)
@@ -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;
index 8fe2271f508601802db8de598d93c24114554428..dd9e713c92096632475e0bd70d4319ca61806644 100644 (file)
@@ -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);
index 47bfefacd2e128fb61bb0718da5ed5b38e2141dd..f8a56a0badc0bc014e8f7e8e0946d8dc39b1a15b 100644 (file)
@@ -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);
index bc1b50475bce0f796e793a3778a62931a52960e2..c971ca3b9ddc4fb9af5874c9d311a7043fa3a020 100644 (file)
@@ -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