On 2010-08-19 00:58, Douglas Gregor wrote:
>  [...]

Hi Doug,

Thanks for the quick and useful feedback! Attached is a revised patch
that addresses the issues you mentioned.

Eelis
>From d288bfb7f00612c9b1ff6a02c1e004264a69d2cc Mon Sep 17 00:00:00 2001
From: Eelis van der Weegen <[email protected]>
Date: Thu, 19 Aug 2010 02:01:09 +0200
Subject: [PATCH] Add -fdiagnostics-parseable-fixits.

---
 docs/UsersManual.html                      |   12 ++++++++
 docs/tools/clang.pod                       |    1 +
 include/clang/Driver/CC1Options.td         |    2 +
 include/clang/Driver/Options.td            |    1 +
 include/clang/Frontend/DiagnosticOptions.h |    2 +
 lib/Driver/Tools.cpp                       |    1 +
 lib/Frontend/CompilerInvocation.cpp        |    3 ++
 lib/Frontend/TextDiagnosticPrinter.cpp     |   42 ++++++++++++++++++++++++++++
 8 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/docs/UsersManual.html b/docs/UsersManual.html
index 2402bf8..ce3cc96 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>This is saying that characters 25 up to but not including 29 on line 7 in t.cpp should be replaced with the string "Gamma". Both the range and the replacement string may be empty (representing strict insertions and strict erasures, respectively).</p>
+</dd>
 
 </dl>
 
diff --git a/docs/tools/clang.pod b/docs/tools/clang.pod
index 94f6b76..bcf84b7 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 abe8148..74d9fba 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 034a234..45bea9c 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 516dc67..c80bc03 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 8fe2271..dd9e713 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 68b384f..056edfe 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 bc1b504..c971ca3 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
-- 
1.7.1

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to