This patch provides a way to clone a pretty_printer. This is needed so that we can capture text in a label_text and make layout decisions based on it, using the policy of global_dc's printer, whilst within a call to diagnostic_show_locus. We can't print with the pretty_printer itself within a call to diagnostic_show_locus since it has partly-buffered content.
gcc/c-family/ChangeLog: * c-pretty-print.c (c_pretty_printer::clone): New vfunc implementation. * c-pretty-print.h (c_pretty_printer::clone): New vfunc decl. gcc/cp/ChangeLog: * cxx-pretty-print.c (cxx_pretty_printer::clone): New vfunc implementation. * cxx-pretty-print.h (cxx_pretty_printer::clone): New vfunc decl. * error.c (cxx_format_postprocessor::clone): New vfunc. gcc/ChangeLog: * pretty-print.c (pretty_printer::pretty_printer): New copy-ctor. (pretty_printer::clone): New vfunc implementation. * pretty-print.h (format_postprocessor::clone): New pure vfunc decl. (pretty_printer::pretty_printer): New copy-ctor decl. (pretty_printer::clone): New vfunc decl. --- gcc/c-family/c-pretty-print.c | 7 +++++++ gcc/c-family/c-pretty-print.h | 1 + gcc/cp/cxx-pretty-print.c | 8 ++++++++ gcc/cp/cxx-pretty-print.h | 2 ++ gcc/cp/error.c | 5 +++++ gcc/pretty-print.c | 34 ++++++++++++++++++++++++++++++++++ gcc/pretty-print.h | 4 ++++ 7 files changed, 61 insertions(+) diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c index 1b06cc2..9f73d23 100644 --- a/gcc/c-family/c-pretty-print.c +++ b/gcc/c-family/c-pretty-print.c @@ -2368,6 +2368,13 @@ c_pretty_printer::c_pretty_printer () parameter_list = pp_c_parameter_type_list; } +/* c_pretty_printer's implementation of pretty_printer::clone vfunc. */ + +pretty_printer * +c_pretty_printer::clone () const +{ + return new c_pretty_printer (*this); +} /* Print the tree T in full, on file FILE. */ diff --git a/gcc/c-family/c-pretty-print.h b/gcc/c-family/c-pretty-print.h index 8d69620..df21e21 100644 --- a/gcc/c-family/c-pretty-print.h +++ b/gcc/c-family/c-pretty-print.h @@ -51,6 +51,7 @@ class c_pretty_printer : public pretty_printer { public: c_pretty_printer (); + pretty_printer *clone () const OVERRIDE; // Format string, possibly translated. void translate_string (const char *); diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index 2a129a3..d9d57be 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -3012,3 +3012,11 @@ cxx_pretty_printer::cxx_pretty_printer () type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq; parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause; } + +/* cxx_pretty_printer's implementation of pretty_printer::clone vfunc. */ + +pretty_printer * +cxx_pretty_printer::clone () const +{ + return new cxx_pretty_printer (*this); +} diff --git a/gcc/cp/cxx-pretty-print.h b/gcc/cp/cxx-pretty-print.h index 347811f..dd96226 100644 --- a/gcc/cp/cxx-pretty-print.h +++ b/gcc/cp/cxx-pretty-print.h @@ -34,6 +34,8 @@ class cxx_pretty_printer : public c_pretty_printer public: cxx_pretty_printer (); + pretty_printer *clone () const OVERRIDE; + void constant (tree); void id_expression (tree); void primary_expression (tree); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index f40b90d..bc8c9dc 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -143,6 +143,11 @@ class cxx_format_postprocessor : public format_postprocessor : m_type_a (), m_type_b () {} + format_postprocessor *clone() const FINAL OVERRIDE + { + return new cxx_format_postprocessor (); + } + void handle (pretty_printer *pp) FINAL OVERRIDE; deferred_printed_type m_type_a; diff --git a/gcc/pretty-print.c b/gcc/pretty-print.c index c57a3db..89242ed 100644 --- a/gcc/pretty-print.c +++ b/gcc/pretty-print.c @@ -1588,6 +1588,32 @@ pretty_printer::pretty_printer (int maximum_length) pp_set_prefix (this, NULL); } +/* Copy constructor for pretty_printer. */ + +pretty_printer::pretty_printer (const pretty_printer &other) +: buffer (new (XCNEW (output_buffer)) output_buffer ()), + prefix (), + padding (other.padding), + maximum_length (other.maximum_length), + indent_skip (other.indent_skip), + wrapping (other.wrapping), + format_decoder (other.format_decoder), + m_format_postprocessor (NULL), + emitted_prefix (other.emitted_prefix), + need_newline (other.need_newline), + translate_identifiers (other.translate_identifiers), + show_color (other.show_color), + show_urls (other.show_urls) +{ + pp_line_cutoff (this) = maximum_length; + /* By default, we emit prefixes once per message. */ + pp_prefixing_rule (this) = pp_prefixing_rule (&other); + pp_set_prefix (this, NULL); + + if (other.m_format_postprocessor) + m_format_postprocessor = other.m_format_postprocessor->clone (); +} + pretty_printer::~pretty_printer () { if (m_format_postprocessor) @@ -1597,6 +1623,14 @@ pretty_printer::~pretty_printer () free (prefix); } +/* Base class implementation of pretty_printer::clone vfunc. */ + +pretty_printer * +pretty_printer::clone () const +{ + return new pretty_printer (*this); +} + /* Append a string delimited by START and END to the output area of PRETTY-PRINTER. No line wrapping is done. However, if beginning a new line then emit PRETTY-PRINTER's prefix and skip any leading diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h index c73fc30..493507d 100644 --- a/gcc/pretty-print.h +++ b/gcc/pretty-print.h @@ -192,6 +192,7 @@ class format_postprocessor { public: virtual ~format_postprocessor () {} + virtual format_postprocessor *clone() const = 0; virtual void handle (pretty_printer *) = 0; }; @@ -221,9 +222,12 @@ public: /* Default construct a pretty printer with specified maximum line length cut off limit. */ explicit pretty_printer (int = 0); + explicit pretty_printer (const pretty_printer &other); virtual ~pretty_printer (); + virtual pretty_printer *clone () const; + /* Where we print external representation of ENTITY. */ output_buffer *buffer; -- 1.8.5.3