[pushed:,r15-3751] analyzer: simplify dumps using tree_dump_pretty_printer [PR116613]

Message ID 20240920230556.1850401-1-dmalcolm@redhat.com
State Committed
Commit 39f7703fffee0c1a8aa999b29ae52b2a31903715
Headers
Series [pushed:,r15-3751] analyzer: simplify dumps using tree_dump_pretty_printer [PR116613] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm warning Patch is already merged
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 warning Patch is already merged

Commit Message

David Malcolm Sept. 20, 2024, 11:05 p.m. UTC
  There are numerous "dump" member functions in the analyzer with
copied-and-pasted logic.  Simplify them by moving the shared code
to a new class tree_dump_pretty_printer.

As well as reducing code duplication, this eliminates numerous
uses of pp_show_color (global_dc->m_printer), which should
ultimately help with supporting multiple diagnostic sinks.

No functional change intended.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r15-3751-g39f7703fffee0c.

gcc/analyzer/ChangeLog:
	PR other/116613
	* access-diagram.cc (access_range::dump): Simplify using
	tree_dump_pretty_printer.
	* call-details.cc (call_details::dump): Likewise.
	* call-summary.cc (call_summary::dump): Likewise.
	(call_summary_replay::dump): Likewise.
	* checker-event.cc (checker_event::debug): Likewise.
	* constraint-manager.cc (range::dump): Likewise.
	(bounded_range::dump): Likewise.
	(bounded_ranges::dump): Likewise.
	(constraint_manager::dump): Likewise.
	* engine.cc (exploded_node::dump): Likewise.
	(exploded_path::dump): Likewise.
	* program-point.cc (program_point::dump): Likewise.
	* program-state.cc (extrinsic_state::dump_to_file): Likewise.
	(sm_state_map::dump): Likewise.
	(program_state::dump_to_file): Likewise.
	* ranges.cc (symbolic_byte_offset::dump): Likewise.
	(symbolic_byte_range::dump): Likewise.
	* record-layout.cc (record_layout::dump): Likewise.
	* region-model-reachability.cc (reachable_regions::dump):
	Likewise.
	* region-model.cc (region_to_value_map::dump): Likewise.
	(region_model::dump): Likewise.
	(model_merger::dump): Likewise.
	* region.cc (region_offset::dump): Likewise.
	(region::dump): Likewise.
	* sm-malloc.cc (deallocator_set::dump): Likewise.
	* store.cc (uncertainty_t::dump): Likewise.
	(binding_key::dump): Likewise.
	(bit_range::dump): Likewise.
	(byte_range::dump): Likewise.
	(binding_map::dump): Likewise.
	(binding_cluster::dump): Likewise.
	(store::dump): Likewise.
	* supergraph.cc (superedge::dump): Likewise.
	* svalue.cc (svalue::dump): Likewise.

gcc/ChangeLog:
	PR other/116613
	* text-art/dump.h (dump_to_file): Simplify using
	tree_dump_pretty_printer.
	* tree-diagnostic.h (class tree_dump_pretty_printer): New.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
 gcc/analyzer/access-diagram.cc            |  6 +---
 gcc/analyzer/call-details.cc              |  6 +---
 gcc/analyzer/call-summary.cc              | 12 ++-----
 gcc/analyzer/checker-event.cc             |  6 +---
 gcc/analyzer/constraint-manager.cc        | 24 +++-----------
 gcc/analyzer/engine.cc                    | 12 ++-----
 gcc/analyzer/program-point.cc             |  5 +--
 gcc/analyzer/program-state.cc             | 19 ++----------
 gcc/analyzer/ranges.cc                    | 12 ++-----
 gcc/analyzer/record-layout.cc             |  5 +--
 gcc/analyzer/region-model-reachability.cc |  6 +---
 gcc/analyzer/region-model.cc              | 18 ++---------
 gcc/analyzer/region.cc                    | 12 ++-----
 gcc/analyzer/sm-malloc.cc                 |  5 +--
 gcc/analyzer/store.cc                     | 38 +++++------------------
 gcc/analyzer/supergraph.cc                |  6 +---
 gcc/analyzer/svalue.cc                    |  6 +---
 gcc/text-art/dump.h                       |  8 +----
 gcc/tree-diagnostic.h                     | 20 ++++++++++++
 19 files changed, 55 insertions(+), 171 deletions(-)
  

Patch

diff --git a/gcc/analyzer/access-diagram.cc b/gcc/analyzer/access-diagram.cc
index ddeb45a94b24..4822ae392845 100644
--- a/gcc/analyzer/access-diagram.cc
+++ b/gcc/analyzer/access-diagram.cc
@@ -544,13 +544,9 @@  access_range::dump_to_pp (pretty_printer *pp, bool simple) const
 DEBUG_FUNCTION void
 access_range::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 void
diff --git a/gcc/analyzer/call-details.cc b/gcc/analyzer/call-details.cc
index e543eda347a5..a9c613bc1822 100644
--- a/gcc/analyzer/call-details.cc
+++ b/gcc/analyzer/call-details.cc
@@ -363,12 +363,8 @@  call_details::dump_to_pp (pretty_printer *pp, bool simple) const
 DEBUG_FUNCTION void
 call_details::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple);
-  pp_flush (&pp);
 }
 
 /* Get a conjured_svalue for this call for REG,
diff --git a/gcc/analyzer/call-summary.cc b/gcc/analyzer/call-summary.cc
index ad86a5c64714..f6d22df547e3 100644
--- a/gcc/analyzer/call-summary.cc
+++ b/gcc/analyzer/call-summary.cc
@@ -146,12 +146,8 @@  call_summary::dump (const extrinsic_state &ext_state,
 		    FILE *fp,
 		    bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (fp);
+  tree_dump_pretty_printer pp (fp);
   dump_to_pp (ext_state, &pp, simple);
-  pp_flush (&pp);
 }
 
 /* Dump a multiline representation of this object to stderr.  */
@@ -885,12 +881,8 @@  call_summary_replay::dump_to_pp (pretty_printer *pp, bool simple) const
 void
 call_summary_replay::dump (FILE *fp, bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (fp);
+  tree_dump_pretty_printer pp (fp);
   dump_to_pp (&pp, simple);
-  pp_flush (&pp);
 }
 
 /* Dump a multiline representation of this object to stderr.  */
diff --git a/gcc/analyzer/checker-event.cc b/gcc/analyzer/checker-event.cc
index 90a2381d19a3..5a91d7b51ea9 100644
--- a/gcc/analyzer/checker-event.cc
+++ b/gcc/analyzer/checker-event.cc
@@ -197,13 +197,9 @@  checker_event::dump (pretty_printer *pp) const
 DEBUG_FUNCTION void
 checker_event::debug () const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump (&pp);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Hook for being notified when this event has its final id EMISSION_ID
diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc
index e19869622b6a..59487034cde7 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -182,13 +182,9 @@  range::dump_to_pp (pretty_printer *pp) const
 DEBUG_FUNCTION void
 range::dump () const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Determine if there is only one possible value for this range.
@@ -445,13 +441,9 @@  bounded_range::dump_to_pp (pretty_printer *pp, bool show_types) const
 void
 bounded_range::dump (bool show_types) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, show_types);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 json::object *
@@ -718,13 +710,9 @@  bounded_ranges::dump_to_pp (pretty_printer *pp, bool show_types) const
 DEBUG_FUNCTION void
 bounded_ranges::dump (bool show_types) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, show_types);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 json::value *
@@ -1769,12 +1757,8 @@  constraint_manager::dump_to_pp (pretty_printer *pp, bool multiline) const
 void
 constraint_manager::dump (FILE *fp) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (fp);
+  tree_dump_pretty_printer pp (fp);
   dump_to_pp (&pp, true);
-  pp_flush (&pp);
 }
 
 /* Dump a multiline representation of this constraint_manager to stderr.  */
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 74a408f0583d..0524750d7a3c 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -1419,12 +1419,8 @@  void
 exploded_node::dump (FILE *fp,
 		     const extrinsic_state &ext_state) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (fp);
+  tree_dump_pretty_printer pp (fp);
   dump_to_pp (&pp, ext_state);
-  pp_flush (&pp);
 }
 
 /* Dump a multiline representation of this node to stderr.  */
@@ -4828,12 +4824,8 @@  exploded_path::dump_to_pp (pretty_printer *pp,
 void
 exploded_path::dump (FILE *fp, const extrinsic_state *ext_state) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (fp);
+  tree_dump_pretty_printer pp (fp);
   dump_to_pp (&pp, ext_state);
-  pp_flush (&pp);
 }
 
 /* Dump this path in multiline form to stderr.  */
diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc
index 37a6c4523e64..cfb59e1ee4ea 100644
--- a/gcc/analyzer/program-point.cc
+++ b/gcc/analyzer/program-point.cc
@@ -300,11 +300,8 @@  program_point::print (pretty_printer *pp, const format &f) const
 DEBUG_FUNCTION void
 program_point::dump () const
 {
-  pretty_printer pp;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   print (&pp, format (true));
-  pp_flush (&pp);
 }
 
 /* Return a new json::object of the form
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 1d86013545c3..bce7acb99170 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -83,12 +83,8 @@  extrinsic_state::dump_to_pp (pretty_printer *pp) const
 void
 extrinsic_state::dump_to_file (FILE *outf) const
 {
-  pretty_printer pp;
-  if (outf == stderr)
-    pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (outf);
+  tree_dump_pretty_printer pp (outf);
   dump_to_pp (&pp);
-  pp_flush (&pp);
 }
 
 /* Dump a multiline representation of this state to stderr.  */
@@ -271,13 +267,9 @@  sm_state_map::print (const region_model *model,
 DEBUG_FUNCTION void
 sm_state_map::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   print (NULL, simple, true, &pp);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Return a new json::object of the form
@@ -1165,13 +1157,8 @@  program_state::dump_to_file (const extrinsic_state &ext_state,
 			     bool summarize, bool multiline,
 			     FILE *outf) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  if (outf == stderr)
-    pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (outf);
+  tree_dump_pretty_printer pp (outf);
   dump_to_pp (ext_state, summarize, multiline, &pp);
-  pp_flush (&pp);
 }
 
 /* Dump a multiline representation of this state to stderr.  */
diff --git a/gcc/analyzer/ranges.cc b/gcc/analyzer/ranges.cc
index 59dac229b59d..3323a96fed10 100644
--- a/gcc/analyzer/ranges.cc
+++ b/gcc/analyzer/ranges.cc
@@ -95,13 +95,9 @@  symbolic_byte_offset::dump_to_pp (pretty_printer *pp, bool simple) const
 void
 symbolic_byte_offset::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 json::value *
@@ -154,13 +150,9 @@  symbolic_byte_range::dump_to_pp (pretty_printer *pp,
 void
 symbolic_byte_range::dump (bool simple, region_model_manager &mgr) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple, mgr);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 json::value *
diff --git a/gcc/analyzer/record-layout.cc b/gcc/analyzer/record-layout.cc
index 59690a43b76e..e70e92a56fdd 100644
--- a/gcc/analyzer/record-layout.cc
+++ b/gcc/analyzer/record-layout.cc
@@ -83,11 +83,8 @@  record_layout::dump_to_pp (pretty_printer *pp) const
 void
 record_layout::dump () const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp);
-  pp_flush (&pp);
 }
 
 const record_layout::item *
diff --git a/gcc/analyzer/region-model-reachability.cc b/gcc/analyzer/region-model-reachability.cc
index 890546148f90..ffb08322b260 100644
--- a/gcc/analyzer/region-model-reachability.cc
+++ b/gcc/analyzer/region-model-reachability.cc
@@ -347,12 +347,8 @@  reachable_regions::dump_to_pp (pretty_printer *pp) const
 DEBUG_FUNCTION void
 reachable_regions::dump () const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp);
-  pp_flush (&pp);
 }
 
 } // namespace ana
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 3cefd9cc57af..a0fd2aad4910 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -223,13 +223,9 @@  region_to_value_map::dump_to_pp (pretty_printer *pp, bool simple,
 DEBUG_FUNCTION void
 region_to_value_map::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple, true);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Generate a JSON value for this region_to_value_map.
@@ -483,13 +479,9 @@  region_model::dump_to_pp (pretty_printer *pp, bool simple,
 void
 region_model::dump (FILE *fp, bool simple, bool multiline) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (fp);
+  tree_dump_pretty_printer pp (fp);
   dump_to_pp (&pp, simple, multiline);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Dump a multiline representation of this model to stderr.  */
@@ -7397,12 +7389,8 @@  model_merger::dump_to_pp (pretty_printer *pp, bool simple) const
 void
 model_merger::dump (FILE *fp, bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (fp);
+  tree_dump_pretty_printer pp (fp);
   dump_to_pp (&pp, simple);
-  pp_flush (&pp);
 }
 
 /* Dump a multiline representation of this merger to stderr.  */
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index c1b1ff6fe1b1..59b09e5c81ce 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -138,13 +138,9 @@  region_offset::dump_to_pp (pretty_printer *pp, bool simple) const
 DEBUG_FUNCTION void
 region_offset::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* An svalue that matches the pattern (BASE * FACTOR) + OFFSET
@@ -1015,13 +1011,9 @@  region::get_relative_concrete_byte_range (byte_range *out) const
 DEBUG_FUNCTION void
 region::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Dump a tree-like representation of this region and its constituent symbols
diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc
index bdbbbf38cc37..11c0e1b1a2fd 100644
--- a/gcc/analyzer/sm-malloc.cc
+++ b/gcc/analyzer/sm-malloc.cc
@@ -584,12 +584,9 @@  deallocator_set::deallocator_set (malloc_state_machine *sm,
 DEBUG_FUNCTION void
 deallocator_set::dump () const
 {
-  pretty_printer pp;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* struct custom_deallocator_set : public deallocator_set.  */
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 270712022e7b..6dc4bb5cad48 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -107,13 +107,9 @@  uncertainty_t::dump_to_pp (pretty_printer *pp, bool simple) const
 DEBUG_FUNCTION void
 uncertainty_t::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* class binding_key.  */
@@ -144,13 +140,9 @@  binding_key::make (store_manager *mgr, const region *r)
 DEBUG_FUNCTION void
 binding_key::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Get a description of this binding_key.  */
@@ -230,11 +222,9 @@  bit_range::dump_to_pp (pretty_printer *pp) const
 DEBUG_FUNCTION void
 bit_range::dump () const
 {
-  pretty_printer pp;
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Generate a JSON value for this bit_range.
@@ -506,11 +496,9 @@  byte_range::dump_to_pp (pretty_printer *pp) const
 DEBUG_FUNCTION void
 byte_range::dump () const
 {
-  pretty_printer pp;
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Generate a JSON value for this byte_range.
@@ -773,13 +761,9 @@  binding_map::dump_to_pp (pretty_printer *pp, bool simple,
 DEBUG_FUNCTION void
 binding_map::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple, true);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Return a new json::object of the form
@@ -1400,17 +1384,13 @@  binding_cluster::dump_to_pp (pretty_printer *pp, bool simple,
 DEBUG_FUNCTION void
 binding_cluster::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   pp_string (&pp, "  cluster for: ");
   m_base_region->dump_to_pp (&pp, simple);
   pp_string (&pp, ": ");
   pp_newline (&pp);
   dump_to_pp (&pp, simple, true);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Assert that this object is valid.  */
@@ -2636,13 +2616,9 @@  store::dump_to_pp (pretty_printer *pp, bool simple, bool multiline,
 DEBUG_FUNCTION void
 store::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple, true, NULL);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Assert that this object is valid.  */
diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc
index 6e0a4f718e45..55bd42a89a1a 100644
--- a/gcc/analyzer/supergraph.cc
+++ b/gcc/analyzer/supergraph.cc
@@ -898,13 +898,9 @@  superedge::dump (pretty_printer *pp) const
 DEBUG_FUNCTION void
 superedge::dump () const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump (&pp);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Implementation of dedge::dump_dot for superedges.
diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc
index 617d6a8cc917..663119613fb5 100644
--- a/gcc/analyzer/svalue.cc
+++ b/gcc/analyzer/svalue.cc
@@ -86,13 +86,9 @@  svalue::dump () const
 DEBUG_FUNCTION void
 svalue::dump (bool simple) const
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (stderr);
+  tree_dump_pretty_printer pp (stderr);
   dump_to_pp (&pp, simple);
   pp_newline (&pp);
-  pp_flush (&pp);
 }
 
 /* Generate a textual representation of this svalue for debugging purposes.  */
diff --git a/gcc/text-art/dump.h b/gcc/text-art/dump.h
index 74492bc58959..30b4fb9161fc 100644
--- a/gcc/text-art/dump.h
+++ b/gcc/text-art/dump.h
@@ -59,15 +59,9 @@  void dump_to_pp (const T &obj, text_art::theme *theme, pretty_printer *pp)
 template <typename T>
 void dump_to_file (const T &obj, FILE *outf)
 {
-  pretty_printer pp;
-  pp_format_decoder (&pp) = default_tree_printer;
-  if (outf == stderr)
-    pp_show_color (&pp) = pp_show_color (global_dc->m_printer);
-  pp.set_output_stream (outf);
-
+  tree_dump_pretty_printer pp (outf);
   text_art::theme *theme = global_dc->get_diagram_theme ();
   dump_to_pp (obj, theme, &pp);
-  pp_flush (&pp);
 }
 
 /* Dump OBJ to stderr, using OBJ's make_dump_widget member function.  */
diff --git a/gcc/tree-diagnostic.h b/gcc/tree-diagnostic.h
index 98ca654c946e..dbc8ef6ae013 100644
--- a/gcc/tree-diagnostic.h
+++ b/gcc/tree-diagnostic.h
@@ -55,4 +55,24 @@  void tree_diagnostics_defaults (diagnostic_context *context);
 bool default_tree_printer (pretty_printer *, text_info *, const char *,
 			   int, bool, bool, bool, bool *, pp_token_list &);
 
+/* A subclass of pretty_printer for writing "dump" functions.
+   Wires itself up to a FILE *, and colorizes if it's stderr and
+   the user requested colorization.  */
+
+class tree_dump_pretty_printer : public pretty_printer
+{
+public:
+  tree_dump_pretty_printer (FILE *outf)
+  {
+    pp_format_decoder (this) = default_tree_printer;
+    if (outf == stderr)
+      pp_show_color (this) = pp_show_color (global_dc->m_printer);
+    set_output_stream (outf);
+  }
+  ~tree_dump_pretty_printer ()
+  {
+    pp_flush (this);
+  }
+};
+
 #endif /* ! GCC_TREE_DIAGNOSTIC_H */