diff --git a/gcc/pretty-print-markup.h b/gcc/pretty-print-markup.h
index ce2c5e9dbbe99fcebbf75e251d7a1f3e7c7196bf..de9e4bda6adeeffb1807c2f286513382eb619a8d 100644
--- a/gcc/pretty-print-markup.h
+++ b/gcc/pretty-print-markup.h
@@ -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;
 };
diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc
index 115f376c4512efe33fd53a7e67654648f6bc9e1a..998e06e155f756b0dc1fa7c38a1a782d4833807e 100644
--- a/gcc/pretty-print.cc
+++ b/gcc/pretty-print.cc
@@ -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
diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h
index 14a6c53a4ac0b30d48d34836f8d1e02292da274c..b5ded5cdd5e0967061eafd715da2bac5c700601b 100644
--- a/gcc/pretty-print.h
+++ b/gcc/pretty-print.h
@@ -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);