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 "ed, 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, "e, - *formatted_tok_list); + bool ok = format_decoder (pp, &text, p, + precision, wide, plus, hash, "e, + *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);