From: David Malcolm Date: Fri, 2 Sep 2016 19:41:17 +0000 (+0000) Subject: Add -fdiagnostics-generate-patch X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=717ebe91c97c37f92ffb5a80a68eb1f6a965fce0;p=gcc.git 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. From-SVN: r239965 --- 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 + + * 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 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 + + * 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 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 ();