Support prefixes in diagnostic_show_locus
authorDavid Malcolm <dmalcolm@redhat.com>
Tue, 1 Oct 2019 21:58:17 +0000 (21:58 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Tue, 1 Oct 2019 21:58:17 +0000 (21:58 +0000)
Previously, diagnostic_show_locus saved and restored the pretty_printer's
prefix, clearing it for the duration of the call.

I have a patch kit in development that can benefit from applying a prefix
to the output of d_s_l, so this patch adds support to d_s_l for printing
such prefixes.

It moves the save and restore of the pp's prefix from d_s_l to all of its
callers, and updates diagnostic-show-locus.c to properly handle prefixes.

gcc/c-family/ChangeLog:
* c-opts.c (c_diagnostic_finalizer): Temporarily clear prefix when
calling diagnostic_show_locus, rather than destroying it afterwards.

gcc/ChangeLog:
* diagnostic-show-locus.c (layout::print_gap_in_line_numbering):
Call pp_emit_prefix.
(layout::print_source_line): Likewise.
(layout::start_annotation_line): Likewise.
(diagnostic_show_locus): Remove call to temporarily clear the
prefix.
(selftest::test_one_liner_fixit_remove): Add test coverage for the
interaction of pp_set_prefix with rulers and fix-it hints.
* diagnostic.c (default_diagnostic_finalizer): Temporarily clear
prefix when calling diagnostic_show_locus, rather than destroying
it afterwards.
(print_parseable_fixits): Temporarily clear prefix.
* pretty-print.c (pp_format): Save and restore line_length, rather
than assuming it is zero.
(pp_output_formatted_text): Remove assertion that line_length is
zero.

gcc/fortran/ChangeLog:
* error.c (gfc_diagnostic_starter): Clear the prefix before
calling diagnostic_show_locus.

gcc/testsuite/ChangeLog:
* gcc.dg/plugin/diagnostic_group_plugin.c (test_begin_group_cb):
Clear the prefix before emitting the "END GROUP" line.
* gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
(custom_diagnostic_finalizer): Temporarily clear prefix when
calling diagnostic_show_locus, rather than destroying it
afterwards.

From-SVN: r276433

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-opts.c
gcc/diagnostic-show-locus.c
gcc/diagnostic.c
gcc/fortran/ChangeLog
gcc/fortran/error.c
gcc/pretty-print.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.c
gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c

index b7feecc..b3a42ae 100644 (file)
@@ -1,3 +1,22 @@
+2019-10-01  David Malcolm  <dmalcolm@redhat.com>
+
+       * diagnostic-show-locus.c (layout::print_gap_in_line_numbering):
+       Call pp_emit_prefix.
+       (layout::print_source_line): Likewise.
+       (layout::start_annotation_line): Likewise.
+       (diagnostic_show_locus): Remove call to temporarily clear the
+       prefix.
+       (selftest::test_one_liner_fixit_remove): Add test coverage for the
+       interaction of pp_set_prefix with rulers and fix-it hints.
+       * diagnostic.c (default_diagnostic_finalizer): Temporarily clear
+       prefix when calling diagnostic_show_locus, rather than destroying
+       it afterwards.
+       (print_parseable_fixits): Temporarily clear prefix.
+       * pretty-print.c (pp_format): Save and restore line_length, rather
+       than assuming it is zero.
+       (pp_output_formatted_text): Remove assertion that line_length is
+       zero.
+
 2019-10-01  Jan Hubicka  <hubicka@ucw.cz>
 
        * tree-ssa-alias.c (nonoverlapping_component_refs_since_match_p):
index 811947a..0eade3c 100644 (file)
@@ -1,3 +1,8 @@
+2019-10-01  David Malcolm  <dmalcolm@redhat.com>
+
+       * c-opts.c (c_diagnostic_finalizer): Temporarily clear prefix when
+       calling diagnostic_show_locus, rather than destroying it afterwards.
+
 2019-10-01  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/91925
index 23ab4cf..949d96a 100644 (file)
@@ -168,11 +168,13 @@ c_diagnostic_finalizer (diagnostic_context *context,
                        diagnostic_info *diagnostic,
                        diagnostic_t)
 {
+  char *saved_prefix = pp_take_prefix (context->printer);
+  pp_set_prefix (context->printer, NULL);
   diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
   /* By default print macro expansion contexts in the diagnostic
      finalizer -- for tokens resulting from macro expansion.  */
   virt_loc_aware_diagnostic_finalizer (context, diagnostic);
-  pp_destroy_prefix (context->printer);
+  pp_set_prefix (context->printer, saved_prefix);
   pp_flush (context->printer);
 }
 
index 6612cbb..cb920f6 100644 (file)
@@ -1039,6 +1039,8 @@ layout::print_gap_in_line_numbering ()
 {
   gcc_assert (m_show_line_numbers_p);
 
+  pp_emit_prefix (m_pp);
+
   for (int i = 0; i < m_linenum_width + 1; i++)
     pp_character (m_pp, '.');
 
@@ -1266,6 +1268,8 @@ layout::print_source_line (linenum_type row, const char *line, int line_width,
                                                           line_width);
   line += m_x_offset;
 
+  pp_emit_prefix (m_pp);
+
   if (m_show_line_numbers_p)
     {
       int width = num_digits (row);
@@ -1346,6 +1350,7 @@ layout::should_print_annotation_line_p (linenum_type row) const
 void
 layout::start_annotation_line (char margin_char) const
 {
+  pp_emit_prefix (m_pp);
   if (m_show_line_numbers_p)
     {
       /* Print the margin.  If MARGIN_CHAR != ' ', then print up to 3
@@ -2297,9 +2302,6 @@ diagnostic_show_locus (diagnostic_context * context,
 
   context->last_location = loc;
 
-  char *saved_prefix = pp_take_prefix (context->printer);
-  pp_set_prefix (context->printer, NULL);
-
   layout layout (context, richloc, diagnostic_kind);
   for (int line_span_idx = 0; line_span_idx < layout.get_num_line_spans ();
        line_span_idx++)
@@ -2329,8 +2331,6 @@ diagnostic_show_locus (diagnostic_context * context,
           row <= last_line; row++)
        layout.print_line (row);
     }
-
-  pp_set_prefix (context->printer, saved_prefix);
 }
 
 #if CHECKING_P
@@ -2463,23 +2463,93 @@ test_one_liner_fixit_insert_after ()
                pp_formatted_text (dc.printer));
 }
 
-/* Removal fix-it hint: removal of the ".field". */
+/* Removal fix-it hint: removal of the ".field".
+   Also verify the interaction of pp_set_prefix with rulers and
+   fix-it hints.  */
 
 static void
 test_one_liner_fixit_remove ()
 {
-  test_diagnostic_context dc;
   location_t start = linemap_position_for_column (line_table, 10);
   location_t finish = linemap_position_for_column (line_table, 15);
   location_t dot = make_location (start, start, finish);
   rich_location richloc (line_table, dot);
   richloc.add_fixit_remove ();
-  diagnostic_show_locus (&dc, &richloc, DK_ERROR);
-  ASSERT_STREQ ("\n"
-               " foo = bar.field;\n"
-               "          ^~~~~~\n"
-               "          ------\n",
-               pp_formatted_text (dc.printer));
+
+  /* Normal.  */
+  {
+    test_diagnostic_context dc;
+    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
+    ASSERT_STREQ ("\n"
+                 " foo = bar.field;\n"
+                 "          ^~~~~~\n"
+                 "          ------\n",
+                 pp_formatted_text (dc.printer));
+  }
+
+  /* Test of adding a prefix.  */
+  {
+    test_diagnostic_context dc;
+    pp_prefixing_rule (dc.printer) = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
+    pp_set_prefix (dc.printer, xstrdup ("TEST PREFIX:"));
+    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
+    ASSERT_STREQ ("\n"
+                 "TEST PREFIX: foo = bar.field;\n"
+                 "TEST PREFIX:          ^~~~~~\n"
+                 "TEST PREFIX:          ------\n",
+                 pp_formatted_text (dc.printer));
+  }
+
+  /* Normal, with ruler.  */
+  {
+    test_diagnostic_context dc;
+    dc.show_ruler_p = true;
+    dc.caret_max_width = 104;
+    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
+    ASSERT_STREQ ("\n"
+                 "          0         0         0         0         0         0         0         0         0         1    \n"
+                 "          1         2         3         4         5         6         7         8         9         0    \n"
+                 " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\n"
+                 " foo = bar.field;\n"
+                 "          ^~~~~~\n"
+                 "          ------\n",
+                 pp_formatted_text (dc.printer));
+  }
+
+  /* Test of adding a prefix, with ruler.  */
+  {
+    test_diagnostic_context dc;
+    dc.show_ruler_p = true;
+    dc.caret_max_width = 50;
+    pp_prefixing_rule (dc.printer) = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
+    pp_set_prefix (dc.printer, xstrdup ("TEST PREFIX:"));
+    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
+    ASSERT_STREQ ("\n"
+                 "TEST PREFIX:          1         2         3         4         5\n"
+                 "TEST PREFIX: 12345678901234567890123456789012345678901234567890\n"
+                 "TEST PREFIX: foo = bar.field;\n"
+                 "TEST PREFIX:          ^~~~~~\n"
+                 "TEST PREFIX:          ------\n",
+                 pp_formatted_text (dc.printer));
+  }
+
+  /* Test of adding a prefix, with ruler and line numbers.  */
+  {
+    test_diagnostic_context dc;
+    dc.show_ruler_p = true;
+    dc.caret_max_width = 50;
+    dc.show_line_numbers_p = true;
+    pp_prefixing_rule (dc.printer) = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
+    pp_set_prefix (dc.printer, xstrdup ("TEST PREFIX:"));
+    diagnostic_show_locus (&dc, &richloc, DK_ERROR);
+    ASSERT_STREQ ("\n"
+                 "TEST PREFIX:      |          1         2         3         4         5\n"
+                 "TEST PREFIX:      | 12345678901234567890123456789012345678901234567890\n"
+                 "TEST PREFIX:    1 | foo = bar.field;\n"
+                 "TEST PREFIX:      |          ^~~~~~\n"
+                 "TEST PREFIX:      |          ------\n",
+                 pp_formatted_text (dc.printer));
+  }
 }
 
 /* Replace fix-it hint: replacing "field" with "m_field". */
index 96b6fa3..1b3306c 100644 (file)
@@ -663,8 +663,10 @@ default_diagnostic_finalizer (diagnostic_context *context,
                              diagnostic_info *diagnostic,
                              diagnostic_t)
 {
+  char *saved_prefix = pp_take_prefix (context->printer);
+  pp_set_prefix (context->printer, NULL);
   diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
-  pp_destroy_prefix (context->printer);
+  pp_set_prefix (context->printer, saved_prefix);
   pp_flush (context->printer);
 }
 
@@ -811,6 +813,9 @@ print_parseable_fixits (pretty_printer *pp, rich_location *richloc)
   gcc_assert (pp);
   gcc_assert (richloc);
 
+  char *saved_prefix = pp_take_prefix (pp);
+  pp_set_prefix (pp, NULL);
+
   for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++)
     {
       const fixit_hint *hint = richloc->get_fixit_hint (i);
@@ -827,6 +832,8 @@ print_parseable_fixits (pretty_printer *pp, rich_location *richloc)
       print_escaped_string (pp, hint->get_string ());
       pp_newline (pp);
     }
+
+  pp_set_prefix (pp, saved_prefix);
 }
 
 /* Update the diag_class of DIAGNOSTIC based on its location
index 694fc32..63ee15b 100644 (file)
@@ -1,3 +1,8 @@
+2019-10-01  David Malcolm  <dmalcolm@redhat.com>
+
+       * error.c (gfc_diagnostic_starter): Clear the prefix before
+       calling diagnostic_show_locus.
+
 2019-09-29  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/91641
index a0ce7a6..a7c27f0 100644 (file)
@@ -1137,6 +1137,7 @@ gfc_diagnostic_starter (diagnostic_context *context,
       free (locus_prefix);
       /* Fortran uses an empty line between locus and caret line.  */
       pp_newline (context->printer);
+      pp_set_prefix (context->printer, NULL);
       diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
       /* If the caret line was shown, the prefix does not contain the
         locus.  */
index 6948971..2b6c585 100644 (file)
@@ -1192,6 +1192,7 @@ pp_format (pretty_printer *pp, text_info *text)
   /* Set output to the argument obstack, and switch line-wrapping and
      prefixing off.  */
   buffer->obstack = &buffer->chunk_obstack;
+  const int old_line_length = buffer->line_length;
   old_wrapping_mode = pp_set_verbatim_wrapping (pp);
 
   /* Second phase.  Replace each formatter with the formatted text it
@@ -1412,7 +1413,7 @@ pp_format (pretty_printer *pp, text_info *text)
 
   /* Revert to normal obstack and wrapping mode.  */
   buffer->obstack = &buffer->formatted_obstack;
-  buffer->line_length = 0;
+  buffer->line_length = old_line_length;
   pp_wrapping_mode (pp) = old_wrapping_mode;
   pp_clear_state (pp);
 }
@@ -1427,7 +1428,6 @@ pp_output_formatted_text (pretty_printer *pp)
   const char **args = chunk_array->args;
 
   gcc_assert (buffer->obstack == &buffer->formatted_obstack);
-  gcc_assert (buffer->line_length == 0);
 
   /* This is a third phase, first 2 phases done in pp_format_args.
      Now we actually print it.  */
index f7256b5..5949f0a 100644 (file)
@@ -1,3 +1,12 @@
+2019-10-01  David Malcolm  <dmalcolm@redhat.com>
+
+       * gcc.dg/plugin/diagnostic_group_plugin.c (test_begin_group_cb):
+       Clear the prefix before emitting the "END GROUP" line.
+       * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
+       (custom_diagnostic_finalizer): Temporarily clear prefix when
+       calling diagnostic_show_locus, rather than destroying it
+       afterwards.
+
 2019-10-01  Jan Hubicka  <hubicka@ucw.cz>
 
        * gcc.dg/tree-ssa/alias-access-path-10.c: New testcase.
index 3083e12..67ca701 100644 (file)
@@ -197,6 +197,7 @@ test_begin_group_cb (diagnostic_context * context)
 static void
 test_end_group_cb (diagnostic_context * context)
 {
+  pp_set_prefix (context->printer, NULL);
   pp_string (context->printer,
             "---------------------------------- END GROUP -------------------------------");
   pp_newline_and_flush (context->printer);
index fce68a1..3f62edd 100644 (file)
@@ -135,10 +135,11 @@ custom_diagnostic_finalizer (diagnostic_context *context,
   bool old_show_color = pp_show_color (context->printer);
   if (force_show_locus_color)
     pp_show_color (context->printer) = true;
+  char *saved_prefix = pp_take_prefix (context->printer);
+  pp_set_prefix (context->printer, NULL);
   diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
   pp_show_color (context->printer) = old_show_color;
-
-  pp_destroy_prefix (context->printer);
+  pp_set_prefix (context->printer, saved_prefix);
   pp_flush (context->printer);
 }