I added a flag as well.

I noticed that the indent level is 2 in some places and 3 in others,
can either of those be abstracted out?


- Jefferson
From b1b665b91d953a05f3c0eea4ff972b59a5460151 Mon Sep 17 00:00:00 2001
From: Jefferson Carpenter <[email protected]>
Date: Sun, 4 Oct 2026 23:36:22 -0500
Subject: [PATCH] Add "-findent-template-trees" option

Indents template trees in cxx pretty printer
---
 gcc/c-family/c.opt         |   4 ++
 gcc/cp/cxx-pretty-print.cc |   7 +++
 gcc/cp/error.cc            | 117 ++++++++++++-------------------------
 gcc/pretty-print.cc        |   6 +-
 4 files changed, 53 insertions(+), 81 deletions(-)

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 3ad96a5fe78..db8a0a9655c 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -2357,6 +2357,10 @@ fpretty-templates
 C++ ObjC++ Var(flag_pretty_templates) Init(1)
 Do not pretty-print template specializations as the template signature followed by the arguments.
 
+findent-template-trees
+C++ ObjC++ Var(flag_indent_template_trees) Init(0)
+Indent template trees in C++ pretty printer
+
 fprintf-return-value
 C ObjC C++ ObjC++ LTO Optimization Var(flag_printf_return_value) Init(1)
 Treat known sprintf return values as constants.
diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc
index f844039eb99..db566508e0e 100644
--- a/gcc/cp/cxx-pretty-print.cc
+++ b/gcc/cp/cxx-pretty-print.cc
@@ -72,11 +72,15 @@ void
 pp_cxx_begin_template_argument_list (cxx_pretty_printer *pp)
 {
   pp_cxx_nonconsecutive_character (pp, '<');
+  if (flag_indent_template_trees)
+    pp_indentation (pp) += 3;
 }
 
 void
 pp_cxx_end_template_argument_list (cxx_pretty_printer *pp)
 {
+  if (flag_indent_template_trees)
+    pp_newline_and_indent (pp, -3);
   pp_cxx_nonconsecutive_character (pp, '>');
 }
 
@@ -2025,6 +2029,9 @@ pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
 
       for (idx = 0; idx < len; idx++)
 	{
+	  if (flag_indent_template_trees)
+	    pp_newline_and_indent (pp, 0);
+
 	  if (argpack)
 	    arg = TREE_VEC_ELT (argpack, idx);
 
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 47065b11e22..fca423c22f9 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -66,7 +66,7 @@ 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);
 static const char *type_to_string (tree, int, bool, bool *, bool,
-				   const char * = nullptr);
+				   const char * = nullptr, int = 0);
 
 static void dump_alias_template_specialization (cxx_pretty_printer *, tree, int);
 static void dump_type (cxx_pretty_printer *, tree, int);
@@ -2301,6 +2301,9 @@ dump_template_parms (cxx_pretty_printer *pp, tree info,
                   || TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
             pp_separate_with_comma (pp);
 
+	  if (flag_indent_template_trees)
+	    pp_newline_and_indent (pp, 0);
+
           if (!arg)
             pp_string (pp, M_("<template parameter error>"));
           else
@@ -3836,7 +3839,7 @@ op_to_string (bool assop, enum tree_code p)
 
 static const char *
 type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
-		bool show_color, const char *highlight_color)
+		bool show_color, const char *highlight_color, int indent)
 {
   int flags = 0;
   if (verbose)
@@ -3845,6 +3848,7 @@ type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
 
   reinit_cxx_pp ();
   pp_show_color (cxx_pp) = show_color;
+  pp_indentation (cxx_pp) = indent;
 
   if (postprocessed && quote && *quote)
     {
@@ -4641,23 +4645,13 @@ comparable_template_types_p (tree type_a, tree type_b)
   return TI_TEMPLATE (tinfo_a) == TI_TEMPLATE (tinfo_b);
 }
 
-/* Start a new line indented by SPC spaces on PP.  */
-
-static void
-newline_and_indent (pretty_printer *pp, int spc)
-{
-  pp_newline (pp);
-  for (int i = 0; i < spc; i++)
-    pp_space (pp);
-}
-
 /* Generate a GC-allocated string for ARG, an expression or type.  */
 
 static const char *
-arg_to_string (tree arg, bool verbose)
+arg_to_string (tree arg, bool verbose, int indent)
 {
   if (TYPE_P (arg))
-    return type_to_string (arg, verbose, true, NULL, false);
+    return type_to_string (arg, verbose, true, NULL, false, NULL, indent);
   else
     return expr_to_string (arg);
 }
@@ -4671,14 +4665,14 @@ arg_to_string (tree arg, bool verbose)
 
 static void
 print_nonequal_arg (pretty_printer *pp, tree arg, bool verbose,
-		    const char *highlight_color)
+		    const char *highlight_color, int indent)
 {
   if (!highlight_color)
     highlight_color = "type-diff";
   pp_printf (pp, "%r%s%R",
 	     highlight_color,
 	     (arg
-	      ? arg_to_string (arg, verbose)
+	      ? arg_to_string (arg, verbose, indent)
 	      : G_("(no argument)")));
 }
 
@@ -4732,8 +4726,11 @@ print_template_differences (pretty_printer *pp, tree type_a, tree type_b,
 			    const char *highlight_color_a,
 			    const char *highlight_color_b)
 {
-  if (indent)
-    newline_and_indent (pp, indent);
+  if (flag_indent_template_trees)
+    {
+      pp_newline_and_indent (pp, 0);
+      pp_indentation (pp) += indent;
+    }
 
   tree tinfo_a = TYPE_TEMPLATE_INFO (type_a);
   tree tinfo_b = TYPE_TEMPLATE_INFO (type_b);
@@ -4765,38 +4762,42 @@ print_template_differences (pretty_printer *pp, tree type_a, tree type_b,
       if (idx)
 	pp_character (pp, ',');
 
+      if (flag_indent_template_trees)
+	pp_newline_and_indent (pp, 0);
+
       tree arg_a = TREE_VEC_ELT (args_a, idx);
       tree arg_b = TREE_VEC_ELT (args_b, idx);
+
       if (arg_a == arg_b)
 	{
-	  if (indent)
-	    newline_and_indent (pp, indent + 2);
 	  /* Can do elision here, printing "[...]".  */
 	  if (flag_elide_type)
 	    pp_string (pp, G_("[...]"));
 	  else
-	    pp_string (pp, arg_to_string (arg_a, verbose));
+	    pp_string (pp, arg_to_string (arg_a, verbose, indent));
 	}
       else
 	{
-	  int new_indent = indent ? indent + 2 : 0;
 	  if (comparable_template_types_p (arg_a, arg_b))
-	    print_template_differences (pp, arg_a, arg_b, verbose, new_indent,
+	    print_template_differences (pp, arg_a, arg_b, verbose, indent,
 					highlight_color_a, highlight_color_b);
+
+	  if (flag_diagnostics_show_template_tree)
+	    {
+	      pp_character (pp, '[');
+	      print_nonequal_arg (pp, arg_a, verbose, highlight_color_a, indent);
+	      pp_string (pp, " != ");
+	      print_nonequal_arg (pp, arg_b, verbose, highlight_color_b, indent);
+	      pp_character (pp, ']');
+	    }
 	  else
-	    if (indent)
-	      {
-		newline_and_indent (pp, indent + 2);
-		pp_character (pp, '[');
-		print_nonequal_arg (pp, arg_a, verbose, highlight_color_a);
-		pp_string (pp, " != ");
-		print_nonequal_arg (pp, arg_b, verbose, highlight_color_b);
-		pp_character (pp, ']');
-	      }
-	    else
-	      print_nonequal_arg (pp, arg_a, verbose, highlight_color_a);
+	    print_nonequal_arg (pp, arg_a, verbose, highlight_color_a, indent);
 	}
     }
+
+  if (flag_indent_template_trees)
+    pp_newline_and_indent (pp, -indent);
+
   pp_printf (pp, ">");
 }
 
@@ -4828,54 +4829,12 @@ type_to_string_with_compare (tree type, tree peer, bool verbose,
   pretty_printer *pp = &inner_pp;
   pp_show_color (pp) = show_color;
 
-  print_template_differences (pp, type, peer, verbose, 0,
+  int indent = flag_indent_template_trees ? 3 : 0;
+  print_template_differences (pp, type, peer, verbose, indent,
 			      this_highlight_color, peer_highlight_color);
   return pp_ggc_formatted_text (pp);
 }
 
-/* Recursively print a tree-like comparison of TYPE_A and TYPE_B to PP,
-   indented by INDENT spaces.
-
-   For example given types:
-
-     vector<map<int,double>>
-
-   and
-
-     vector<map<double,float>>
-
-   the output with type elision would be:
-
-     vector<
-       map<
-         [...],
-         [double != float]>>
-
-   and without type-elision would be:
-
-     vector<
-       map<
-         int,
-         [double != float]>>
-
-   TYPE_A and TYPE_B must both be comparable template types
-   (as per comparable_template_types_p).
-
-   Template arguments in which both types are using the default arguments
-   are not printed; if at least one of the two types is using a non-default
-   argument, then both arguments are printed.  */
-
-static void
-print_template_tree_comparison (pretty_printer *pp, tree type_a, tree type_b,
-				bool verbose, int indent,
-				const char *highlight_color_a,
-				const char *highlight_color_b)
-{
-  print_template_differences (pp, type_a, type_b, verbose, indent,
-			      highlight_color_a,
-			      highlight_color_b);
-}
-
 /* Subroutine for use in a format_postprocessor::handle
    implementation.  Adds a chunk to the end of
    formatted output, so that it will be printed
@@ -4941,7 +4900,7 @@ cxx_format_postprocessor::handle (pretty_printer *pp)
 	    {
 	      pretty_printer inner_pp;
 	      pp_show_color (&inner_pp) = pp_show_color (pp);
-	      print_template_tree_comparison
+	      print_template_differences
 		(&inner_pp, type_a.m_tree, type_b.m_tree, type_a.m_verbose, 2,
 		 percent_h, percent_i);
 	      append_formatted_chunk (pp, pp_ggc_formatted_text (&inner_pp));
diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc
index 3cdbe46bd41..99cf5d0d657 100644
--- a/gcc/pretty-print.cc
+++ b/gcc/pretty-print.cc
@@ -1081,8 +1081,10 @@ pretty_printer::set_real_maximum_length ()
 inline void
 pretty_printer::clear_state ()
 {
-  m_emitted_prefix = false;
-  pp_indentation (this) = 0;
+  if (m_emitted_prefix) {
+    m_emitted_prefix = false;
+    pp_indentation (this) -= 3;
+  }
 }
 
 /* Print X to PP in decimal.  */
-- 
2.55.0

Reply via email to