]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
pretty-print: split up pretty_printer::format into subroutines
authorDavid Malcolm <dmalcolm@redhat.com>
Tue, 3 Sep 2024 19:11:06 +0000 (15:11 -0400)
committerDavid Malcolm <dmalcolm@redhat.com>
Tue, 3 Sep 2024 19:16:39 +0000 (15:16 -0400)
The body of pretty_printer::format is almost 500 lines long,
mostly comprising two distinct phases.

This patch splits it up so that there are explicit subroutines
for the two different phases, reducing the scope of various
locals, and making it easier to e.g. put a breakpoint on phase 2.

No functional change intended.

gcc/ChangeLog:
* pretty-print-markup.h (pp_markup::context::context): Drop
params "buf" and "chunk_idx", initializing m_buf from pp.
(pp_markup::context::m_chunk_idx): Drop field.
* pretty-print.cc (pretty_printer::format): Convert param
from a text_info * to a text_info &.  Split out phase 1
and phase 2 into subroutines...
(format_phase_1): New, from pretty_printer::format.
(format_phase_2): Likewise.
* pretty-print.h (pretty_printer::format): Convert param
from a text_info * to a text_info &.
(pp_format): Update for above change.  Assert that text_info is
non-null.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
gcc/pretty-print-markup.h
gcc/pretty-print.cc
gcc/pretty-print.h

index ce2c5e9dbbe99fcebbf75e251d7a1f3e7c7196bf..de9e4bda6adeeffb1807c2f286513382eb619a8d 100644 (file)
@@ -30,13 +30,10 @@ class context
 {
 public:
   context (pretty_printer &pp,
-          output_buffer &buf,
-          unsigned chunk_idx,
           bool &quoted,
           pp_token_list *formatted_token_list)
   : m_pp (pp),
-    m_buf (buf),
-    m_chunk_idx (chunk_idx),
+    m_buf (*pp_buffer (&pp)),
     m_quoted (quoted),
     m_formatted_token_list (formatted_token_list)
   {
@@ -52,7 +49,6 @@ public:
 
   pretty_printer &m_pp;
   output_buffer &m_buf;
-  unsigned m_chunk_idx;
   bool &m_quoted;
   pp_token_list *m_formatted_token_list;
 };
index 115f376c4512efe33fd53a7e67654648f6bc9e1a..998e06e155f756b0dc1fa7c38a1a782d4833807e 100644 (file)
@@ -1589,35 +1589,79 @@ push_back_any_text (pp_token_list *tok_list,
    Phase 3 is in pp_output_formatted_text, which pops the pp_formatted_chunks
    instance.  */
 
+static void
+format_phase_1 (const text_info &text,
+               obstack &chunk_obstack,
+               pp_token_list **args,
+               pp_token_list ***formatters);
+
+static void
+format_phase_2 (pretty_printer *pp,
+               text_info &text,
+               obstack &chunk_obstack,
+               pp_token_list ***formatters);
+
 void
-pretty_printer::format (text_info *text)
+pretty_printer::format (text_info &text)
 {
-  output_buffer * const buffer = m_buffer;
+  pp_formatted_chunks *new_chunk_array = m_buffer->push_formatted_chunks ();
+  pp_token_list **args = new_chunk_array->m_args;
 
-  unsigned int chunk = 0, argno;
   pp_token_list **formatters[PP_NL_ARGMAX];
-
-  pp_formatted_chunks *new_chunk_array = buffer->push_formatted_chunks ();
-  pp_token_list **args = new_chunk_array->m_args;
+  memset (formatters, 0, sizeof formatters);
 
   /* Formatting phase 1: split up TEXT->format_spec into chunks in
      pp_buffer (PP)->args[].  Even-numbered chunks are to be output
      verbatim, odd-numbered chunks are format specifiers.
      %m, %%, %<, %>, %} and %' are replaced with the appropriate text at
      this point.  */
+  format_phase_1 (text, m_buffer->m_chunk_obstack, args, formatters);
 
-  memset (formatters, 0, sizeof formatters);
+  /* Note that you can debug the state of the chunk arrays here using
+       (gdb) call m_buffer->cur_chunk_array->dump()
+     which, given e.g. "foo: %s bar: %s" might print:
+       0: [TEXT("foo: ")]
+       1: [TEXT("s")]
+       2: [TEXT(" bar: ")]
+       3: [TEXT("s")]
+  */
+
+  /* Set output to the argument obstack, and switch line-wrapping and
+     prefixing off.  */
+  m_buffer->m_obstack = &m_buffer->m_chunk_obstack;
+  const int old_line_length = m_buffer->m_line_length;
+  const pp_wrapping_mode_t old_wrapping_mode = pp_set_verbatim_wrapping (this);
+
+  format_phase_2 (this, text, m_buffer->m_chunk_obstack, formatters);
+
+  /* If the client supplied a postprocessing object, call its "handle"
+     hook here.  */
+  if (m_format_postprocessor)
+    m_format_postprocessor->handle (this);
+
+  /* Revert to normal obstack and wrapping mode.  */
+  m_buffer->m_obstack = &m_buffer->m_formatted_obstack;
+  m_buffer->m_line_length = old_line_length;
+  pp_wrapping_mode (this) = old_wrapping_mode;
+  clear_state ();
+}
 
+static void
+format_phase_1 (const text_info &text,
+               obstack &chunk_obstack,
+               pp_token_list **args,
+               pp_token_list ***formatters)
+{
+  unsigned chunk = 0;
   unsigned int curarg = 0;
   bool any_unnumbered = false, any_numbered = false;
   pp_token_list *cur_token_list;
-  args[chunk++] = cur_token_list
-    = pp_token_list::make (buffer->m_chunk_obstack);
-  for (const char *p = text->m_format_spec; *p; )
+  args[chunk++] = cur_token_list = pp_token_list::make (chunk_obstack);
+  for (const char *p = text.m_format_spec; *p; )
     {
       while (*p != '\0' && *p != '%')
        {
-         obstack_1grow (&buffer->m_chunk_obstack, *p);
+         obstack_1grow (&chunk_obstack, *p);
          p++;
        }
 
@@ -1630,13 +1674,13 @@ pretty_printer::format (text_info *text)
          gcc_unreachable ();
 
        case '%':
-         obstack_1grow (&buffer->m_chunk_obstack, '%');
+         obstack_1grow (&chunk_obstack, '%');
          p++;
          continue;
 
        case '<':
          {
-           push_back_any_text (cur_token_list, &buffer->m_chunk_obstack);
+           push_back_any_text (cur_token_list, &chunk_obstack);
            cur_token_list->push_back<pp_token_begin_quote> ();
            p++;
            continue;
@@ -1644,14 +1688,14 @@ pretty_printer::format (text_info *text)
 
        case '>':
          {
-           push_back_any_text (cur_token_list, &buffer->m_chunk_obstack);
+           push_back_any_text (cur_token_list, &chunk_obstack);
            cur_token_list->push_back<pp_token_end_quote> ();
            p++;
            continue;
          }
        case '\'':
          {
-           push_back_any_text (cur_token_list, &buffer->m_chunk_obstack);
+           push_back_any_text (cur_token_list, &chunk_obstack);
            cur_token_list->push_back<pp_token_end_quote> ();
            p++;
          }
@@ -1659,7 +1703,7 @@ pretty_printer::format (text_info *text)
 
        case '}':
          {
-           push_back_any_text (cur_token_list, &buffer->m_chunk_obstack);
+           push_back_any_text (cur_token_list, &chunk_obstack);
            cur_token_list->push_back<pp_token_end_url> ();
            p++;
          }
@@ -1667,7 +1711,7 @@ pretty_printer::format (text_info *text)
 
        case 'R':
          {
-           push_back_any_text (cur_token_list, &buffer->m_chunk_obstack);
+           push_back_any_text (cur_token_list, &chunk_obstack);
            cur_token_list->push_back<pp_token_end_color> ();
            p++;
            continue;
@@ -1675,22 +1719,22 @@ pretty_printer::format (text_info *text)
 
        case 'm':
          {
-           const char *errstr = xstrerror (text->m_err_no);
-           obstack_grow (&buffer->m_chunk_obstack, errstr, strlen (errstr));
+           const char *errstr = xstrerror (text.m_err_no);
+           obstack_grow (&chunk_obstack, errstr, strlen (errstr));
          }
          p++;
          continue;
 
        default:
          /* Handled in phase 2.  Terminate the plain chunk here.  */
-         push_back_any_text (cur_token_list, &buffer->m_chunk_obstack);
+         push_back_any_text (cur_token_list, &chunk_obstack);
          break;
        }
 
       /* Start a new token list for the formatting args.  */
-      args[chunk] = cur_token_list
-       = pp_token_list::make (buffer->m_chunk_obstack);
+      args[chunk] = cur_token_list = pp_token_list::make (chunk_obstack);
 
+      unsigned argno;
       if (ISDIGIT (*p))
        {
          char *end;
@@ -1713,7 +1757,7 @@ pretty_printer::format (text_info *text)
       formatters[argno] = &args[chunk++];
       do
        {
-         obstack_1grow (&buffer->m_chunk_obstack, *p);
+         obstack_1grow (&chunk_obstack, *p);
          p++;
        }
       while (strchr ("qwlzt+#", p[-1]));
@@ -1726,7 +1770,7 @@ pretty_printer::format (text_info *text)
            {
              do
                {
-                 obstack_1grow (&buffer->m_chunk_obstack, *p);
+                 obstack_1grow (&chunk_obstack, *p);
                  p++;
                }
              while (ISDIGIT (p[-1]));
@@ -1735,7 +1779,7 @@ pretty_printer::format (text_info *text)
          else
            {
              gcc_assert (*p == '*');
-             obstack_1grow (&buffer->m_chunk_obstack, '*');
+             obstack_1grow (&chunk_obstack, '*');
              p++;
 
              if (ISDIGIT (*p))
@@ -1757,48 +1801,40 @@ pretty_printer::format (text_info *text)
                  curarg++;
                }
              gcc_assert (*p == 's');
-             obstack_1grow (&buffer->m_chunk_obstack, 's');
+             obstack_1grow (&chunk_obstack, 's');
              p++;
            }
        }
       if (*p == '\0')
        {
-         push_back_any_text (cur_token_list, &buffer->m_chunk_obstack);
+         push_back_any_text (cur_token_list, &chunk_obstack);
          break;
        }
 
-      obstack_1grow (&buffer->m_chunk_obstack, '\0');
-      push_back_any_text (cur_token_list, &buffer->m_chunk_obstack);
+      obstack_1grow (&chunk_obstack, '\0');
+      push_back_any_text (cur_token_list, &chunk_obstack);
 
       /* Start a new token list for the next (non-formatted) text.  */
       gcc_assert (chunk < PP_NL_ARGMAX * 2);
-      args[chunk++] = cur_token_list
-       = pp_token_list::make (buffer->m_chunk_obstack);
+      args[chunk++] = cur_token_list = pp_token_list::make (chunk_obstack);
     }
 
-  obstack_1grow (&buffer->m_chunk_obstack, '\0');
-  push_back_any_text (cur_token_list, &buffer->m_chunk_obstack);
+  obstack_1grow (&chunk_obstack, '\0');
+  push_back_any_text (cur_token_list, &chunk_obstack);
   gcc_assert (chunk < PP_NL_ARGMAX * 2);
   args[chunk] = nullptr;
+}
 
-  /* Set output to the argument obstack, and switch line-wrapping and
-     prefixing off.  */
-  buffer->m_obstack = &buffer->m_chunk_obstack;
-  const int old_line_length = buffer->m_line_length;
-  const pp_wrapping_mode_t old_wrapping_mode = pp_set_verbatim_wrapping (this);
-
-  /* Note that you can debug the state of the chunk arrays here using
-       (gdb) call buffer->cur_chunk_array->dump()
-     which, given e.g. "foo: %s bar: %s" might print:
-       0: [TEXT("foo: ")]
-       1: [TEXT("s")]
-       2: [TEXT(" bar: ")]
-       3: [TEXT("s")]
-  */
-
-  /* Second phase.  Replace each formatter with the formatted text it
-     corresponds to.  */
+/* Second phase.  Replace each formatter with pp_tokens for the formatted
+   text it corresponds to, consuming va_args from TEXT->m_args_ptr.  */
 
+static void
+format_phase_2 (pretty_printer *pp,
+               text_info &text,
+               obstack &chunk_obstack,
+               pp_token_list ***formatters)
+{
+  unsigned argno;
   for (argno = 0; formatters[argno]; argno++)
     {
       int precision = 0;
@@ -1807,8 +1843,6 @@ pretty_printer::format (text_info *text)
       bool hash = false;
       bool quote = false;
 
-      const char *p;
-
       /* We expect a single text token containing the formatter.  */
       pp_token_list *tok_list = *(formatters[argno]);
       gcc_assert (tok_list);
@@ -1817,11 +1851,12 @@ pretty_printer::format (text_info *text)
 
       /* Accumulate the value of the formatted text into here.  */
       pp_token_list *formatted_tok_list
-       = pp_token_list::make (buffer->m_chunk_obstack);
+       = pp_token_list::make (chunk_obstack);
 
       /* We do not attempt to enforce any ordering on the modifier
         characters.  */
 
+      const char *p;
       for (p = as_a <pp_token_text *> (tok_list->m_first)->m_value.get ();; p++)
        {
          switch (*p)
@@ -1869,7 +1904,7 @@ pretty_printer::format (text_info *text)
 
       if (quote)
        {
-         push_back_any_text (formatted_tok_list, &buffer->m_chunk_obstack);
+         push_back_any_text (formatted_tok_list, &chunk_obstack);
          formatted_tok_list->push_back<pp_token_begin_quote> ();
        }
 
@@ -1877,7 +1912,7 @@ pretty_printer::format (text_info *text)
        {
        case 'r':
          {
-           const char *color = va_arg (*text->m_args_ptr, const char *);
+           const char *color = va_arg (*text.m_args_ptr, const char *);
            formatted_tok_list->push_back<pp_token_begin_color>
              (label_text::borrow (color));
          }
@@ -1888,13 +1923,13 @@ pretty_printer::format (text_info *text)
            /* When quoting, print alphanumeric, punctuation, and the space
               character unchanged, and all others in hexadecimal with the
               "\x" prefix.  Otherwise print them all unchanged.  */
-           int chr = va_arg (*text->m_args_ptr, int);
+           int chr = va_arg (*text.m_args_ptr, int);
            if (ISPRINT (chr) || !quote)
-             pp_character (this, chr);
+             pp_character (pp, chr);
            else
              {
                const char str [2] = { chr, '\0' };
-               pp_quoted_string (this, str, 1);
+               pp_quoted_string (pp, str, 1);
              }
            break;
          }
@@ -1902,57 +1937,57 @@ pretty_printer::format (text_info *text)
        case 'd':
        case 'i':
          if (wide)
-           pp_wide_integer (this, va_arg (*text->m_args_ptr, HOST_WIDE_INT));
+           pp_wide_integer (pp, va_arg (*text.m_args_ptr, HOST_WIDE_INT));
          else
-           pp_integer_with_precision (this, *text->m_args_ptr, precision,
+           pp_integer_with_precision (pp, *text.m_args_ptr, precision,
                                       int, "d");
          break;
 
        case 'o':
          if (wide)
-           pp_scalar (this, "%" HOST_WIDE_INT_PRINT "o",
-                      va_arg (*text->m_args_ptr, unsigned HOST_WIDE_INT));
+           pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
+                      va_arg (*text.m_args_ptr, unsigned HOST_WIDE_INT));
          else
-           pp_integer_with_precision (this, *text->m_args_ptr, precision,
+           pp_integer_with_precision (pp, *text.m_args_ptr, precision,
                                       unsigned, "o");
          break;
 
        case 's':
          if (quote)
-           pp_quoted_string (this, va_arg (*text->m_args_ptr, const char *));
+           pp_quoted_string (pp, va_arg (*text.m_args_ptr, const char *));
          else
-           pp_string (this, va_arg (*text->m_args_ptr, const char *));
+           pp_string (pp, va_arg (*text.m_args_ptr, const char *));
          break;
 
        case 'p':
-         pp_pointer (this, va_arg (*text->m_args_ptr, void *));
+         pp_pointer (pp, va_arg (*text.m_args_ptr, void *));
          break;
 
        case 'u':
          if (wide)
-           pp_scalar (this, HOST_WIDE_INT_PRINT_UNSIGNED,
-                      va_arg (*text->m_args_ptr, unsigned HOST_WIDE_INT));
+           pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
+                      va_arg (*text.m_args_ptr, unsigned HOST_WIDE_INT));
          else
-           pp_integer_with_precision (this, *text->m_args_ptr, precision,
+           pp_integer_with_precision (pp, *text.m_args_ptr, precision,
                                       unsigned, "u");
          break;
 
        case 'f':
-         pp_double (this, va_arg (*text->m_args_ptr, double));
+         pp_double (pp, va_arg (*text.m_args_ptr, double));
          break;
 
        case 'Z':
          {
-           int *v = va_arg (*text->m_args_ptr, int *);
-           unsigned len = va_arg (*text->m_args_ptr, unsigned);
+           int *v = va_arg (*text.m_args_ptr, int *);
+           unsigned len = va_arg (*text.m_args_ptr, unsigned);
 
            for (unsigned i = 0; i < len; ++i)
              {
-               pp_scalar (this, "%i", v[i]);
+               pp_scalar (pp, "%i", v[i]);
                if (i < len - 1)
                  {
-                   pp_comma (this);
-                   pp_space (this);
+                   pp_comma (pp);
+                   pp_space (pp);
                  }
              }
            break;
@@ -1960,10 +1995,10 @@ pretty_printer::format (text_info *text)
 
        case 'x':
          if (wide)
-           pp_scalar (this, HOST_WIDE_INT_PRINT_HEX,
-                      va_arg (*text->m_args_ptr, unsigned HOST_WIDE_INT));
+           pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
+                      va_arg (*text.m_args_ptr, unsigned HOST_WIDE_INT));
          else
-           pp_integer_with_precision (this, *text->m_args_ptr, precision,
+           pp_integer_with_precision (pp, *text.m_args_ptr, precision,
                                       unsigned, "x");
          break;
 
@@ -1988,21 +2023,21 @@ pretty_printer::format (text_info *text)
                gcc_assert (*p == '*');
                p++;
                gcc_assert (*p == 's');
-               n = va_arg (*text->m_args_ptr, int);
+               n = va_arg (*text.m_args_ptr, int);
 
                /* This consumes a second entry in the formatters array.  */
                gcc_assert (formatters[argno] == formatters[argno+1]);
                argno++;
              }
 
-           s = va_arg (*text->m_args_ptr, const char *);
+           s = va_arg (*text.m_args_ptr, const char *);
 
            /* Append the lesser of precision and strlen (s) characters
               from the array (which need not be a nul-terminated string).
               Negative precision is treated as if it were omitted.  */
            size_t len = n < 0 ? strlen (s) : strnlen (s, n);
 
-           pp_append_text (this, s, s + len);
+           pp_append_text (pp, s, s + len);
          }
          break;
 
@@ -2010,7 +2045,7 @@ pretty_printer::format (text_info *text)
          {
            /* diagnostic_event_id_t *.  */
            diagnostic_event_id_ptr event_id
-             = va_arg (*text->m_args_ptr, diagnostic_event_id_ptr);
+             = va_arg (*text.m_args_ptr, diagnostic_event_id_ptr);
            gcc_assert (event_id->known_p ());
            formatted_tok_list->push_back<pp_token_event_id> (*event_id);
          }
@@ -2018,7 +2053,7 @@ pretty_printer::format (text_info *text)
 
        case '{':
          {
-           const char *url = va_arg (*text->m_args_ptr, const char *);
+           const char *url = va_arg (*text.m_args_ptr, const char *);
            formatted_tok_list->push_back<pp_token_begin_url>
              (label_text::borrow (url));
          }
@@ -2026,9 +2061,8 @@ pretty_printer::format (text_info *text)
 
        case 'e':
          {
-           pp_element *element
-             = va_arg (*text->m_args_ptr, pp_element *);
-           pp_markup::context ctxt (*this, *buffer, chunk,
+           pp_element *element = va_arg (*text.m_args_ptr, pp_element *);
+           pp_markup::context ctxt (*pp,
                                     quote, /* by reference */
                                     formatted_tok_list);
            element->add_to_phase_2 (ctxt);
@@ -2037,29 +2071,28 @@ pretty_printer::format (text_info *text)
 
        default:
          {
-           bool ok;
-
            /* Call the format decoder.
               Pass the address of "quote" so that format decoders can
               potentially disable printing of the closing quote
               (e.g. when printing "'TYPEDEF' aka 'TYPE'" in the C family
               of frontends).  */
-           gcc_assert (pp_format_decoder (this));
+           printer_fn format_decoder = pp_format_decoder (pp);
+           gcc_assert (format_decoder);
            gcc_assert (formatted_tok_list);
-           ok = m_format_decoder (this, text, p,
-                                  precision, wide, plus, hash, &quote,
-                                  *formatted_tok_list);
+           bool ok = format_decoder (pp, &text, p,
+                                     precision, wide, plus, hash, &quote,
+                                     *formatted_tok_list);
            gcc_assert (ok);
          }
        }
 
       if (quote)
        {
-         push_back_any_text (formatted_tok_list, &buffer->m_chunk_obstack);
+         push_back_any_text (formatted_tok_list, &chunk_obstack);
          formatted_tok_list->push_back<pp_token_end_quote> ();
        }
 
-      push_back_any_text (formatted_tok_list, &buffer->m_chunk_obstack);
+      push_back_any_text (formatted_tok_list, &chunk_obstack);
       delete *formatters[argno];
       *formatters[argno] = formatted_tok_list;
     }
@@ -2067,17 +2100,6 @@ pretty_printer::format (text_info *text)
   if (CHECKING_P)
     for (; argno < PP_NL_ARGMAX; argno++)
       gcc_assert (!formatters[argno]);
-
-  /* If the client supplied a postprocessing object, call its "handle"
-     hook here.  */
-  if (m_format_postprocessor)
-    m_format_postprocessor->handle (this);
-
-  /* Revert to normal obstack and wrapping mode.  */
-  buffer->m_obstack = &buffer->m_formatted_obstack;
-  buffer->m_line_length = old_line_length;
-  pp_wrapping_mode (this) = old_wrapping_mode;
-  clear_state ();
 }
 
 struct auto_obstack
index 14a6c53a4ac0b30d48d34836f8d1e02292da274c..b5ded5cdd5e0967061eafd715da2bac5c700601b 100644 (file)
@@ -282,7 +282,7 @@ public:
 
   void emit_prefix ();
 
-  void format (text_info *text);
+  void format (text_info &text);
 
   void maybe_space ();
 
@@ -579,7 +579,8 @@ extern void pp_flush (pretty_printer *);
 extern void pp_really_flush (pretty_printer *);
 inline void pp_format (pretty_printer *pp, text_info *text)
 {
-  pp->format (text);
+  gcc_assert (text);
+  pp->format (*text);
 }
 extern void pp_output_formatted_text (pretty_printer *,
                                      const urlifier * = nullptr);