public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-162] c++: add color to function decl printing
@ 2022-05-06 20:36 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2022-05-06 20:36 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:69dd5ca3484ee514c1323dfbcf4ef4358cea57bb

commit r13-162-g69dd5ca3484ee514c1323dfbcf4ef4358cea57bb
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Jun 18 05:45:02 2021 -0400

    c++: add color to function decl printing
    
    In reading C++ diagnostics, it's often hard to find the name of the function
    in the middle of the template header, return type, parameters, and template
    arguments.  So let's colorize it, and maybe the template argument bindings
    while we're at it.
    
    I've somewhat arbitrarily chosen bold green for the function name, and
    non-bold magenta for the template arguments.
    
    A side-effect of this is that when this happens in a quote (i.e. %qD), the
    rest of the quote after the function name is no longer bold.  I think that's
    acceptable; returning to the bold would require maintaining a colorize stack
    instead of the on/off controls we have now.
    
    gcc/cp/ChangeLog:
    
            * error.cc (decl_to_string): Add show_color parameter.
            (subst_to_string): Likewise.
            (cp_printer): Pass it.
            (type_to_string): Set pp_show_color.
            (dump_function_name): Use "fnname" color.
            (dump_template_bindings): Use "targs" color.
            (struct colorize_guard): New.
            (reinit_cxx_pp): Clear pp_show_color.
    
    gcc/ChangeLog:
    
            * diagnostic-color.cc: Add fnname and targs color entries.
            * doc/invoke.texi: Document them.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/diagnostic/function-color1.C: New test.

Diff:
---
 gcc/doc/invoke.texi                               | 10 +++++-
 gcc/cp/error.cc                                   | 44 +++++++++++++++++++----
 gcc/diagnostic-color.cc                           |  2 ++
 gcc/testsuite/g++.dg/diagnostic/function-color1.C | 21 +++++++++++
 4 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3f4d6f2db7b..7a35d9613a4 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -4845,7 +4845,7 @@ The default @env{GCC_COLORS} is
 error=01;31:warning=01;35:note=01;36:range1=32:range2=34:locus=01:\
 quote=01:path=01;36:fixit-insert=32:fixit-delete=31:\
 diff-filename=01:diff-hunk=32:diff-delete=31:diff-insert=32:\
-type-diff=01;32
+type-diff=01;32:fnname=01;32:targs=35
 @end smallexample
 @noindent
 where @samp{01;31} is bold red, @samp{01;35} is bold magenta,
@@ -4890,6 +4890,14 @@ SGR substring for location information, @samp{file:line} or
 @vindex quote GCC_COLORS @r{capability}
 SGR substring for information printed within quotes.
 
+@item fnname=
+@vindex fnname GCC_COLORS @r{capability}
+SGR substring for names of C++ functions.
+
+@item targs=
+@vindex targs GCC_COLORS @r{capability}
+SGR substring for C++ function template parameter bindings.
+
 @item fixit-insert=
 @vindex fixit-insert GCC_COLORS @r{capability}
 SGR substring for fix-it hints suggesting text to
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 2e9dd2c6abd..250e012c008 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cp-tree.h"
 #include "stringpool.h"
 #include "tree-diagnostic.h"
+#include "diagnostic-color.h"
 #include "langhooks-def.h"
 #include "intl.h"
 #include "cxx-pretty-print.h"
@@ -56,7 +57,7 @@ static cxx_pretty_printer * const cxx_pp = &actual_pretty_printer;
 static const char *args_to_string (tree, int);
 static const char *code_to_string (enum tree_code);
 static const char *cv_to_string (tree, int);
-static const char *decl_to_string (tree, int);
+static const char *decl_to_string (tree, int, bool);
 static const char *fndecl_to_string (tree, int);
 static const char *op_to_string	(bool, enum tree_code);
 static const char *parm_to_string (int);
@@ -390,6 +391,7 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
       else
 	{
 	  pp_cxx_whitespace (pp);
+	  pp_string (pp, colorize_start (pp_show_color (pp), "targs"));
 	  pp_cxx_left_bracket (pp);
 	  pp->translate_string ("with");
 	  pp_cxx_whitespace (pp);
@@ -400,7 +402,10 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
     ~prepost_semicolon ()
     {
       if (need_semicolon)
-	pp_cxx_right_bracket (pp);
+	{
+	  pp_cxx_right_bracket (pp);
+	  pp_string (pp, colorize_stop (pp_show_color (pp)));
+	}
     }
   } semicolon_or_introducer = {pp, false};
 
@@ -1170,6 +1175,22 @@ dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags)
     dump_type_suffix (pp, type, flags);
 }
 
+class colorize_guard
+{
+  bool colorize;
+  cxx_pretty_printer *pp;
+public:
+  colorize_guard (bool _colorize, cxx_pretty_printer *pp, const char *name)
+    : colorize (_colorize && pp_show_color (pp)), pp (pp)
+  {
+    pp_string (pp, colorize_start (colorize, name));
+  }
+  ~colorize_guard ()
+  {
+    pp_string (pp, colorize_stop (colorize));
+  }
+};
+
 /* Print an IDENTIFIER_NODE that is the name of a declaration.  */
 
 static void
@@ -1946,6 +1967,13 @@ dump_exception_spec (cxx_pretty_printer *pp, tree t, int flags)
 static void
 dump_function_name (cxx_pretty_printer *pp, tree t, int flags)
 {
+  /* Only colorize when we're printing something before the name; in
+     particular, not when printing a CALL_EXPR.  */
+  bool colorize = flags & (TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE
+			   | TFF_TEMPLATE_HEADER);
+
+  colorize_guard g (colorize, pp, "fnname");
+
   tree name = DECL_NAME (t);
 
   /* We can get here with a decl that was synthesized by language-
@@ -3088,6 +3116,7 @@ reinit_cxx_pp (void)
   cxx_pp->padding = pp_none;
   pp_indentation (cxx_pp) = 0;
   pp_needs_newline (cxx_pp) = false;
+  pp_show_color (cxx_pp) = false;
   cxx_pp->enclosing_scope = current_function_decl;
 }
 
@@ -3234,7 +3263,7 @@ location_of (tree t)
    function.  */
 
 static const char *
-decl_to_string (tree decl, int verbose)
+decl_to_string (tree decl, int verbose, bool show_color)
 {
   int flags = 0;
 
@@ -3248,6 +3277,7 @@ decl_to_string (tree decl, int verbose)
   flags |= TFF_TEMPLATE_HEADER;
 
   reinit_cxx_pp ();
+  pp_show_color (cxx_pp) = show_color;
   dump_decl (cxx_pp, decl, flags);
   return pp_ggc_formatted_text (cxx_pp);
 }
@@ -3347,6 +3377,7 @@ type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
   flags |= TFF_TEMPLATE_HEADER;
 
   reinit_cxx_pp ();
+  pp_show_color (cxx_pp) = show_color;
 
   if (postprocessed && quote && *quote)
     pp_begin_quote (cxx_pp, show_color);
@@ -3441,7 +3472,7 @@ args_to_string (tree p, int verbose)
    arguments.  */
 
 static const char *
-subst_to_string (tree p)
+subst_to_string (tree p, bool show_color)
 {
   tree decl = TREE_PURPOSE (p);
   tree targs = TREE_VALUE (p);
@@ -3453,6 +3484,7 @@ subst_to_string (tree p)
     return "";
 
   reinit_cxx_pp ();
+  pp_show_color (cxx_pp) = show_color;
   dump_template_decl (cxx_pp, TREE_PURPOSE (p), flags);
   dump_substitution (cxx_pp, NULL, tparms, targs, /*flags=*/0);
   return pp_ggc_formatted_text (cxx_pp);
@@ -4420,7 +4452,7 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
 		break;
 	      }
 	  }
-	result = decl_to_string (temp, verbose);
+	result = decl_to_string (temp, verbose, pp_show_color (pp));
       }
       break;
     case 'E': result = expr_to_string (next_tree);		break;
@@ -4437,7 +4469,7 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
     case 'O': result = op_to_string (false, next_tcode);	break;
     case 'P': result = parm_to_string (next_int);		break;
     case 'Q': result = op_to_string (true, next_tcode);		break;
-    case 'S': result = subst_to_string (next_tree);		break;
+    case 'S': result = subst_to_string (next_tree, pp_show_color (pp)); break;
     case 'T':
       {
 	result = type_to_string (next_tree, verbose, false, quoted,
diff --git a/gcc/diagnostic-color.cc b/gcc/diagnostic-color.cc
index 640adfad558..95047d78c2e 100644
--- a/gcc/diagnostic-color.cc
+++ b/gcc/diagnostic-color.cc
@@ -91,6 +91,8 @@ static struct color_cap color_dict[] =
   { "locus", SGR_SEQ (COLOR_BOLD), 5, false },
   { "quote", SGR_SEQ (COLOR_BOLD), 5, false },
   { "path", SGR_SEQ (COLOR_BOLD COLOR_SEPARATOR COLOR_FG_CYAN), 4, false },
+  { "fnname", SGR_SEQ (COLOR_BOLD COLOR_SEPARATOR COLOR_FG_GREEN), 6, false },
+  { "targs", SGR_SEQ (COLOR_FG_MAGENTA), 5, false },
   { "fixit-insert", SGR_SEQ (COLOR_FG_GREEN), 12, false },
   { "fixit-delete", SGR_SEQ (COLOR_FG_RED), 12, false },
   { "diff-filename", SGR_SEQ (COLOR_BOLD), 13, false },
diff --git a/gcc/testsuite/g++.dg/diagnostic/function-color1.C b/gcc/testsuite/g++.dg/diagnostic/function-color1.C
new file mode 100644
index 00000000000..32d9e966bdb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/function-color1.C
@@ -0,0 +1,21 @@
+// Verify colorization of printing of function declarations.
+// Use dg-*-multiline-output to avoid regexp interpretation.
+
+// { dg-options "-fdiagnostics-color=always" }
+
+template <class T> void f(short t);
+template <class T> void f(long t);
+
+int main()
+{
+  f<int>(42);
+  /* { dg-begin-multiline-output "" }
+call of overloaded '^[[01m^[[Kf<int>(int)^[[m^[[K' is ambiguous
+     { dg-end-multiline-output "" } */
+  /* { dg-begin-multiline-output "" }
+candidate: '^[[01m^[[Kvoid^[[01;32m^[[K f^[[m^[[K(short int) ^[[35m^[[K[with T = int]^[[m^[[K^[[m^[[K'
+     { dg-end-multiline-output "" } */
+}
+
+// Discard the remaining colorized output that confuses dejagnu.
+// { dg-prune-output diagnostic/function-color1.C }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-06 20:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-06 20:36 [gcc r13-162] c++: add color to function decl printing Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).