summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-02 19:41:17 +0000
committerdmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-02 19:41:17 +0000
commit40a431fa1b60546aa99d26090ecdda5e56e108f5 (patch)
tree1c48b3da48c0d917939aeb557e3ff941f07bf978
parent0b80c4b2d7a168c3da186901ff8f4b9b53eaab4a (diff)
downloadgcc-40a431fa1b60546aa99d26090ecdda5e56e108f5.tar.gz
Add -fdiagnostics-generate-patch
gcc/ChangeLog: * common.opt (fdiagnostics-generate-patch): New option. * diagnostic.c: Include "edit-context.h". (diagnostic_initialize): Initialize context->edit_context_ptr. (diagnostic_finish): Delete context->edit_context_ptr. (diagnostic_report_diagnostic): Add fix-it hints from the diagnostic to context->edit_context_ptr, if any. * diagnostic.h (class edit_context): Add forward decl. (struct diagnostic_context): Add field "edit_context_ptr". * doc/invoke.texi (Diagnostic Message Formatting Options): Add -fdiagnostics-generate-patch. (-fdiagnostics-generate-patch): New item. * toplev.c: Include "edit-context.h". (process_options): Set global_dc->edit_context_ptr to a new edit_context if the options need one. (toplev::main): Handle -fdiagnostics-generate-patch by using global_dc->edit_context_ptr. gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c: New test case. * gcc.dg/plugin/plugin.exp (plugin_test_list): Add diagnostic-test-show-locus-generate-patch.c to the sources for diagnostic_plugin_test_show_locus.c. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@239965 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/diagnostic.c11
-rw-r--r--gcc/diagnostic.h6
-rw-r--r--gcc/doc/invoke.texi23
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c77
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp3
-rw-r--r--gcc/toplev.c14
9 files changed, 163 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b4710f9274f..2e076c7a976 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,22 @@
+2016-09-02 David Malcolm <dmalcolm@redhat.com>
+
+ * common.opt (fdiagnostics-generate-patch): New option.
+ * diagnostic.c: Include "edit-context.h".
+ (diagnostic_initialize): Initialize context->edit_context_ptr.
+ (diagnostic_finish): Delete context->edit_context_ptr.
+ (diagnostic_report_diagnostic): Add fix-it hints from the
+ diagnostic to context->edit_context_ptr, if any.
+ * diagnostic.h (class edit_context): Add forward decl.
+ (struct diagnostic_context): Add field "edit_context_ptr".
+ * doc/invoke.texi (Diagnostic Message Formatting Options): Add
+ -fdiagnostics-generate-patch.
+ (-fdiagnostics-generate-patch): New item.
+ * toplev.c: Include "edit-context.h".
+ (process_options): Set global_dc->edit_context_ptr to a new
+ edit_context if the options need one.
+ (toplev::main): Handle -fdiagnostics-generate-patch by using
+ global_dc->edit_context_ptr.
+
2016-09-02 Jakub Jelinek <jakub@redhat.com>
PR c/65467
diff --git a/gcc/common.opt b/gcc/common.opt
index fd1ac87ddab..fa1c0365e3c 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1196,6 +1196,10 @@ fdiagnostics-parseable-fixits
Common Var(flag_diagnostics_parseable_fixits)
Print fixit hints in machine-readable form.
+fdiagnostics-generate-patch
+Common Var(flag_diagnostics_generate_patch)
+Print fix-it hints to stderr in unified diff format.
+
fdiagnostics-show-option
Common Var(flag_diagnostics_show_option) Init(1)
Amend appropriate diagnostic messages with the command line option that controls them.
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 47b4c79ebcc..46cdb629e8d 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "backtrace.h"
#include "diagnostic.h"
#include "diagnostic-color.h"
+#include "edit-context.h"
#include "selftest.h"
#ifdef HAVE_TERMIOS_H
@@ -174,6 +175,7 @@ diagnostic_initialize (diagnostic_context *context, int n_opts)
context->colorize_source_p = false;
context->show_ruler_p = false;
context->parseable_fixits_p = false;
+ context->edit_context_ptr = NULL;
}
/* Maybe initialize the color support. We require clients to do this
@@ -235,6 +237,12 @@ diagnostic_finish (diagnostic_context *context)
context->printer->~pretty_printer ();
XDELETE (context->printer);
context->printer = NULL;
+
+ if (context->edit_context_ptr)
+ {
+ delete context->edit_context_ptr;
+ context->edit_context_ptr = NULL;
+ }
}
/* Initialize DIAGNOSTIC, where the message MSG has already been
@@ -943,6 +951,9 @@ diagnostic_report_diagnostic (diagnostic_context *context,
diagnostic->message.format_spec = saved_format_spec;
diagnostic->x_data = NULL;
+ if (context->edit_context_ptr)
+ context->edit_context_ptr->add_fixits (diagnostic->richloc);
+
context->lock--;
return true;
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 0727644d96b..ead4d2a9544 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -62,6 +62,8 @@ typedef void (*diagnostic_start_span_fn) (diagnostic_context *,
typedef diagnostic_starter_fn diagnostic_finalizer_fn;
+class edit_context;
+
/* This data structure bundles altogether any information relevant to
the context of a diagnostic message. */
struct diagnostic_context
@@ -209,6 +211,10 @@ struct diagnostic_context
/* If true, print fixits in machine-parseable form after the
rest of the diagnostic. */
bool parseable_fixits_p;
+
+ /* If non-NULL, an edit_context to which fix-it hints should be
+ applied, for generating patches. */
+ edit_context *edit_context_ptr;
};
static inline void
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 986ab436018..73aab7cddc8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -248,7 +248,7 @@ Objective-C and Objective-C++ Dialects}.
-fdiagnostics-show-location=@r{[}once@r{|}every-line@r{]} @gol
-fdiagnostics-color=@r{[}auto@r{|}never@r{|}always@r{]} @gol
-fno-diagnostics-show-option -fno-diagnostics-show-caret @gol
--fdiagnostics-parseable-fixits}
+-fdiagnostics-parseable-fixits -fdiagnostics-generate-patch}
@item Warning Options
@xref{Warning Options,,Options to Request or Suppress Warnings}.
@@ -3460,6 +3460,27 @@ An empty replacement string indicates that the given range is to be removed.
An empty range (e.g. ``45:3-45:3'') indicates that the string is to
be inserted at the given position.
+@item -fdiagnostics-generate-patch
+@opindex fdiagnostics-generate-patch
+Print fix-it hints to stderr in unified diff format, after any diagnostics
+are printed. For example:
+
+@smallexample
+--- test.c
++++ test.c
+@@ -42,5 +42,5 @@
+
+ void show_cb(GtkDialog *dlg)
+ @{
+- gtk_widget_showall(dlg);
++ gtk_widget_show_all(dlg);
+ @}
+
+@end smallexample
+
+The diff may or may not be colorized, following the same rules
+as for diagnostics (see @option{-fdiagnostics-color}).
+
@end table
@node Warning Options
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 434b3db5ac3..255d6c2c7cb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2016-09-02 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c: New
+ test case.
+ * gcc.dg/plugin/plugin.exp (plugin_test_list): Add
+ diagnostic-test-show-locus-generate-patch.c to the sources
+ for diagnostic_plugin_test_show_locus.c.
+
2016-09-02 Jakub Jelinek <jakub@redhat.com>
PR c/65467
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c
new file mode 100644
index 00000000000..afbaf635401
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-generate-patch.c
@@ -0,0 +1,77 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdiagnostics-generate-patch" } */
+
+/* This is a collection of unittests for diagnostic_show_locus;
+ see the overview in diagnostic_plugin_test_show_locus.c.
+
+ In particular, note the discussion of why we need a very long line here:
+01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+ and that we can't use macros in this file. */
+
+/* Unit test for rendering of insertion fixit hints
+ (example taken from PR 62316). */
+
+void test_fixit_insert (void)
+{
+#if 0
+ int a[2][2] = { 0, 1 , 2, 3 }; /* { dg-warning "insertion hints" } */
+#endif
+}
+
+/* Unit test for rendering of "remove" fixit hints. */
+
+void test_fixit_remove (void)
+{
+#if 0
+ int a;; /* { dg-warning "example of a removal hint" } */
+#endif
+}
+
+/* Unit test for rendering of "replace" fixit hints. */
+
+void test_fixit_replace (void)
+{
+#if 0
+ gtk_widget_showall (dlg); /* { dg-warning "example of a replacement hint" } */
+#endif
+}
+
+
+
+/* Verify the output from -fdiagnostics-generate-patch.
+ We expect a header, containing the filename. This is the absolute path,
+ so we can only capture it via regexps. */
+
+/* { dg-regexp "\\-\\-\\- .*" } */
+/* { dg-regexp "\\+\\+\\+ .*" } */
+
+/* Next, we expect the diff itself. */
+/* { dg-begin-multiline-output "" }
+@@ -14,7 +14,7 @@
+ void test_fixit_insert (void)
+ {
+ #if 0
+- int a[2][2] = { 0, 1 , 2, 3 };
++ int a[2][2] = { {0, 1} , 2, 3 };
+ #endif
+ }
+
+@@ -23,7 +23,7 @@
+ void test_fixit_remove (void)
+ {
+ #if 0
+- int a;;
++ int a;
+ #endif
+ }
+
+@@ -32,7 +32,7 @@
+ void test_fixit_replace (void)
+ {
+ #if 0
+- gtk_widget_showall (dlg);
++ gtk_widget_show_all (dlg);
+ #endif
+ }
+
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 715038a0279..32ca748e2cb 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -65,7 +65,8 @@ set plugin_test_list [list \
{ diagnostic_plugin_test_show_locus.c \
diagnostic-test-show-locus-bw.c \
diagnostic-test-show-locus-color.c \
- diagnostic-test-show-locus-parseable-fixits.c } \
+ diagnostic-test-show-locus-parseable-fixits.c \
+ diagnostic-test-show-locus-generate-patch.c } \
{ diagnostic_plugin_test_tree_expression_range.c \
diagnostic-test-expressions-1.c } \
{ diagnostic_plugin_show_trees.c \
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 26079047219..4da5627b350 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -76,6 +76,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-chkp.h"
#include "omp-low.h"
#include "hsa.h"
+#include "edit-context.h"
#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
#include "dbxout.h"
@@ -1221,6 +1222,9 @@ process_options (void)
/* Some machines may reject certain combinations of options. */
targetm.target_option.override ();
+ if (flag_diagnostics_generate_patch)
+ global_dc->edit_context_ptr = new edit_context ();
+
/* Avoid any informative notes in the second run of -fcompare-debug. */
if (flag_compare_debug)
diagnostic_inhibit_notes (global_dc);
@@ -2147,6 +2151,16 @@ toplev::main (int argc, char **argv)
emit some diagnostics here. */
invoke_plugin_callbacks (PLUGIN_FINISH, NULL);
+ if (flag_diagnostics_generate_patch)
+ {
+ gcc_assert (global_dc->edit_context_ptr);
+
+ pretty_printer (pp);
+ pp_show_color (&pp) = pp_show_color (global_dc->printer);
+ global_dc->edit_context_ptr->print_diff (&pp, true);
+ pp_flush (&pp);
+ }
+
diagnostic_finish (global_dc);
finalize_plugins ();