The diagnostics subsystem has a handy dump feature, usable
during debugging via

  (gdb) call global_dc->dump ()

which prints copious amounts of information about the state
of the diagnostics subsystem to stderr.

This patch consolidates the implementation and extends it, adding
various per-sink data (generation options specific to each of text,
SARIF, and HTML).

No functional difference intended outside of the debugger.

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

gcc/ChangeLog:
        * Makefile.in (OBJS-libcommon): Add diagnostics/dumping.o.
        * diagnostics/buffering.cc: Include "diagnostics/dumping.h".
        (buffer::dump): Reimplement using diagnostics::dumping.
        * diagnostics/context.cc: Include "diagnostics/dumping.h".
        (context::dump): Reimplement using diagnostics::dumping.
        Use sink::dump_kind when listing the sinks.
        (sink::dump): Reimplement using diagnostics::dumping.
        (counters::dump): Likewise.
        * diagnostics/dumping.cc: New file.
        * diagnostics/dumping.h: New file.
        * diagnostics/file-cache.cc: Include "diagnostics/dumping.h".
        (file_cache::dump): Reimplement using diagnostics::dumping.
        (file_cache_slot::dump): Likewise.
        * diagnostics/html-sink.cc: Include "diagnostics/dumping.h".
        (html_generation_options::dump): New.
        (html_sink_buffer::dump): Reimplement using diagnostics::dumping.
        (html_builder::dump): New.
        (html_sink::dump): Reimplement using diagnostics::dumping.
        Add dump of the html_builder.
        (html_file_sink::dump): Replace with...
        (html_file_sink::dump_kind): ...this.
        (html_buffered_sink::dump_kind): New.
        * diagnostics/html-sink.h (html_generation_options::dump): New
        decl.
        * diagnostics/sarif-sink.cc: Include "diagnostics/dumping.h".
        (sarif_serialization_format_json::dump): New.
        (sarif_builder::dump): New.
        (sarif_sink_buffer::dump): Reimplement using diagnostics::dumping.
        (sarif_sink::dump): Likewise.  Add dump of the sarif_builder.
        (sarif_stream_sink::dump_kind): New.
        (sarif_file_sink::dump): Replace with...
        (sarif_file_sink::dump_kind): ...this.
        (get_dump_string_for_sarif_version): New.
        (sarif_generation_options::dump): New.
        (class buffered_sink): Rename to...
        (class sarif_buffered_sink): ...this.
        (sarif_buffered_sink::dump_kind): New.
        * diagnostics/sarif-sink.h (sarif_serialization_format::dump):
        New.
        (sarif_serialization_format_json::dump): New decl.
        (sarif_generation_options::dump): New decl.
        * diagnostics/sink.h (sink::dump_kind): New.
        * diagnostics/text-sink.cc: Include "diagnostics/dumping.h".
        (text_sink_buffer::dump): Reimplement using diagnostics::dumping.
        (text_sink::dump): Likewise.  Emit fields m_show_nesting,
        m_show_locations_in_nesting, and m_show_nesting_levels.
        * diagnostics/text-sink.h (text_sink::dump_kind): New.
---
 gcc/Makefile.in               |   1 +
 gcc/diagnostics/buffering.cc  |   5 +-
 gcc/diagnostics/context.cc    |  45 +++++++------
 gcc/diagnostics/dumping.cc    | 116 ++++++++++++++++++++++++++++++++++
 gcc/diagnostics/dumping.h     |  43 +++++++++++++
 gcc/diagnostics/file-cache.cc |  46 ++++++++------
 gcc/diagnostics/html-sink.cc  |  38 +++++++++--
 gcc/diagnostics/html-sink.h   |   2 +
 gcc/diagnostics/sarif-sink.cc |  79 +++++++++++++++++++----
 gcc/diagnostics/sarif-sink.h  |   4 ++
 gcc/diagnostics/sink.h        |   1 +
 gcc/diagnostics/text-sink.cc  |  24 +++----
 gcc/diagnostics/text-sink.h   |   4 ++
 13 files changed, 336 insertions(+), 72 deletions(-)
 create mode 100644 gcc/diagnostics/dumping.cc
 create mode 100644 gcc/diagnostics/dumping.h

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index d7d5cbe72770..a2949bc34f90 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1858,6 +1858,7 @@ OBJS-libcommon = \
        diagnostics/color.o \
        diagnostics/context.o \
        diagnostics/digraphs.o \
+       diagnostics/dumping.o \
        diagnostics/file-cache.o \
        diagnostics/output-spec.o \
        diagnostics/html-sink.o \
diff --git a/gcc/diagnostics/buffering.cc b/gcc/diagnostics/buffering.cc
index 29f039febad2..a7747b5a8f04 100644
--- a/gcc/diagnostics/buffering.cc
+++ b/gcc/diagnostics/buffering.cc
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic.h"
 #include "diagnostics/buffering.h"
 #include "diagnostics/sink.h"
+#include "diagnostics/dumping.h"
 
 namespace diagnostics {
 
@@ -122,12 +123,12 @@ void
 buffer::dump (FILE *out, int indent) const
 {
   m_diagnostic_counters.dump (out, indent + 2);
-  fprintf (out, "%*sm_per_sink_buffers:\n", indent, "");
+  dumping::emit_heading (out, indent, "m_per_sink_buffers");
   if (m_per_sink_buffers)
     for (auto per_sink_buffer_ : *m_per_sink_buffers)
       per_sink_buffer_->dump (out, indent + 2);
   else
-    fprintf (out, "%*s(none)\n", indent + 2, "");
+    dumping::emit_none (out, indent + 2);
 }
 
 bool
diff --git a/gcc/diagnostics/context.cc b/gcc/diagnostics/context.cc
index 01599bc163d3..e127c8fa4d23 100644
--- a/gcc/diagnostics/context.cc
+++ b/gcc/diagnostics/context.cc
@@ -50,6 +50,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostics/logical-locations.h"
 #include "diagnostics/buffering.h"
 #include "diagnostics/file-cache.h"
+#include "diagnostics/dumping.h"
 
 #ifdef HAVE_TERMIOS_H
 # include <termios.h>
@@ -358,33 +359,37 @@ context::finish ()
 /* Dump state of this diagnostics::context to OUT, for debugging.  */
 
 void
-context::dump (FILE *out) const
+context::dump (FILE *outfile) const
 {
-  fprintf (out, "diagnostics::context:\n");
-  m_diagnostic_counters.dump (out, 2);
-  fprintf (out, "  reference printer:\n");
-  m_reference_printer->dump (out, 4);
-  fprintf (out, "  output sinks:\n");
+  dumping::emit_heading (outfile, 0, "diagnostics::context");
+  m_diagnostic_counters.dump (outfile, 2);
+  dumping::emit_heading (outfile, 2, "reference printer");
+  m_reference_printer->dump (outfile, 4);
+  dumping::emit_heading (outfile, 2, "output sinks");
   if (m_sinks.length () > 0)
     {
       for (unsigned i = 0; i < m_sinks.length (); ++i)
        {
-         fprintf (out, "  sink %i:\n", i);
-         m_sinks[i]->dump (out, 4);
+         dumping::emit_indent (outfile, 4);
+         const sink *s = m_sinks[i];
+         fprintf (outfile, "sink %i (", i);
+         s->dump_kind (outfile);
+         fprintf (outfile, "):\n");
+         s->dump (outfile, 6);
        }
     }
   else
-    fprintf (out, "    (none):\n");
-  fprintf (out, "  diagnostic buffer:\n");
+    dumping::emit_none (outfile, 4);
+  dumping::emit_heading (outfile, 2, "diagnostic buffer");
   if (m_diagnostic_buffer)
-    m_diagnostic_buffer->dump (out, 4);
+    m_diagnostic_buffer->dump (outfile, 4);
   else
-    fprintf (out, "    (none):\n");
-  fprintf (out, "  file cache:\n");
+    dumping::emit_none (outfile, 4);
+  dumping::emit_heading (outfile, 2, "file cache");
   if (m_file_cache)
-    m_file_cache->dump (out, 4);
+    m_file_cache->dump (outfile, 4);
   else
-    fprintf (out, "    (none):\n");
+    dumping::emit_none (outfile, 4);
 }
 
 /* Return true if sufficiently severe diagnostics have been seen that
@@ -1702,7 +1707,7 @@ context::set_nesting_level (int new_level)
 void
 sink::dump (FILE *out, int indent) const
 {
-  fprintf (out, "%*sprinter:\n", indent, "");
+  dumping::emit_heading (out, indent, "printer");
   m_printer->dump (out, indent + 2);
 }
 
@@ -1789,19 +1794,19 @@ counters::counters ()
 void
 counters::dump (FILE *out, int indent) const
 {
-  fprintf (out, "%*scounts:\n", indent, "");
+  dumping::emit_heading (out, indent, "counts");
   bool none = true;
   for (int i = 0; i < static_cast<int> (kind::last_diagnostic_kind); i++)
     if (m_count_for_kind[i] > 0)
       {
-       fprintf (out, "%*s%s%i\n",
-                indent + 2, "",
+       dumping::emit_indent (out, indent + 2);
+       fprintf (out, "%s%i\n",
                 get_text_for_kind (static_cast<enum kind> (i)),
                 m_count_for_kind[i]);
        none = false;
       }
   if (none)
-    fprintf (out, "%*s(none)\n", indent + 2, "");
+    dumping::emit_none (out, indent + 2);
 }
 
 void
diff --git a/gcc/diagnostics/dumping.cc b/gcc/diagnostics/dumping.cc
new file mode 100644
index 000000000000..f0366a525c91
--- /dev/null
+++ b/gcc/diagnostics/dumping.cc
@@ -0,0 +1,116 @@
+/* Utilities for implementing "dump" functions for the diagnostics subsystem.
+   Copyright (C) 2025 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalc...@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "diagnostics/dumping.h"
+
+namespace diagnostics {
+namespace dumping {
+
+/* Emit indentation to OUTFILE for the start of a dump line.  */
+
+void
+emit_indent (FILE *outfile, int indent)
+{
+  fprintf (outfile, "%*s", indent, "");
+}
+
+/* Emit an indented line to OUTFILE showing a heading.  */
+
+void
+emit_heading (FILE *outfile, int indent,
+             const char *text)
+{
+  emit_indent (outfile, indent);
+  fprintf (outfile, "%s:\n", text);
+}
+
+/* Various specializattions that emit an indented line to OUTFILE
+   showing "label: value".  */
+
+template <>
+void
+emit_field<const char *> (FILE *outfile, int indent,
+                         const char *label, const char *value)
+{
+  emit_indent (outfile, indent);
+  fprintf (outfile, "%s: %s\n", label, value);
+}
+
+template <>
+void
+emit_field<char *> (FILE *outfile, int indent,
+                   const char *label, char *value)
+{
+  emit_indent (outfile, indent);
+  fprintf (outfile, "%s: %s\n", label, value);
+}
+
+template <>
+void
+emit_field<bool> (FILE *outfile, int indent,
+                 const char *label, bool value)
+{
+  emit_field<const char *> (outfile, indent, label,
+                           value ? "true" : "false");
+}
+
+template <>
+void
+emit_field<size_t> (FILE *outfile, int indent,
+                   const char *label, size_t value)
+{
+  emit_indent (outfile, indent);
+  fprintf (outfile, "%s: %zi\n", label, value);
+}
+
+template <>
+void
+emit_field<int> (FILE *outfile, int indent,
+                const char *label, int value)
+{
+  emit_indent (outfile, indent);
+  fprintf (outfile, "%s: %i\n", label, value);
+}
+
+template <>
+void
+emit_field<unsigned> (FILE *outfile, int indent,
+                     const char *label, unsigned value)
+{
+  emit_indent (outfile, indent);
+  fprintf (outfile, "%s: %u\n", label, value);
+}
+
+/* Emit an indented line to OUTFILE reading "(none)".  */
+
+void
+emit_none (FILE *outfile, int indent)
+{
+  emit_indent (outfile, indent);
+  fprintf (outfile, "(none)\n");
+}
+
+
+} // namespace dumping {
+} // namespace diagnostics
diff --git a/gcc/diagnostics/dumping.h b/gcc/diagnostics/dumping.h
new file mode 100644
index 000000000000..08c7ee41b64b
--- /dev/null
+++ b/gcc/diagnostics/dumping.h
@@ -0,0 +1,43 @@
+/* Utilities for implementing "dump" functions for the diagnostics subsystem.
+   Copyright (C) 2025 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalc...@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_DIAGNOSTICS_DUMP_H
+#define GCC_DIAGNOSTICS_DUMP_H
+
+namespace diagnostics {
+namespace dumping {
+
+extern void emit_indent (FILE *outfile, int indent);
+extern void emit_heading (FILE *outfile, int indent,
+                         const char *text);
+
+template <typename T>
+extern void emit_field (FILE *outfile, int indent,
+                       const char *label, T value);
+
+extern void emit_none (FILE *outfile, int indent);
+
+#define DIAGNOSTICS_DUMPING_EMIT_FIELD(FLAG) \
+  dumping::emit_field (outfile, indent, #FLAG, FLAG)
+
+} // namespace dumping
+} // namespace diagnostics
+
+#endif /* ! GCC_DIAGNOSTICS_DUMP_H */
diff --git a/gcc/diagnostics/file-cache.cc b/gcc/diagnostics/file-cache.cc
index febeb031f1bf..9acf82ebbbc3 100644
--- a/gcc/diagnostics/file-cache.cc
+++ b/gcc/diagnostics/file-cache.cc
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "cpplib.h"
 #include "diagnostics/file-cache.h"
+#include "diagnostics/dumping.h"
 #include "selftest.h"
 
 #ifndef HAVE_ICONV
@@ -473,7 +474,8 @@ file_cache::dump (FILE *out, int indent) const
 {
   for (size_t i = 0; i < m_num_file_slots; ++i)
     {
-      fprintf (out, "%*sslot[%i]:\n", indent, "", (int)i);
+      dumping::emit_indent (out, indent);
+      fprintf (out, "slot[%i]:\n", (int)i);
       m_file_slots[i].dump (out, indent + 2);
     }
 }
@@ -541,27 +543,35 @@ file_cache_slot::dump (FILE *out, int indent) const
 {
   if (!m_file_path)
     {
-      fprintf (out, "%*s(unused)\n", indent, "");
+      dumping::emit_indent (out, indent);
+      fprintf (out, "(unused)\n");
       return;
     }
-  fprintf (out, "%*sfile_path: %s\n", indent, "", m_file_path);
-  fprintf (out, "%*sfp: %p\n", indent, "", (void *)m_fp);
-  fprintf (out, "%*sneeds_read_p: %i\n", indent, "", (int)needs_read_p ());
-  fprintf (out, "%*sneeds_grow_p: %i\n", indent, "", (int)needs_grow_p ());
-  fprintf (out, "%*suse_count: %i\n", indent, "", m_use_count);
-  fprintf (out, "%*ssize: %zi\n", indent, "", m_size);
-  fprintf (out, "%*snb_read: %zi\n", indent, "", m_nb_read);
-  fprintf (out, "%*sstart_line_idx: %zi\n", indent, "", m_line_start_idx);
-  fprintf (out, "%*sline_num: %zi\n", indent, "", m_line_num);
-  fprintf (out, "%*smissing_trailing_newline: %i\n",
-          indent, "", (int)m_missing_trailing_newline);
-  fprintf (out, "%*sline records (%i):\n",
-          indent, "", m_line_record.length ());
+  dumping::emit_field (out, indent, "file_path", m_file_path);
+  {
+    dumping::emit_indent (out, indent);
+    fprintf (out, "fp: %p\n", (void *)m_fp);
+  }
+  dumping::emit_field (out, indent, "needs_read_p", needs_read_p ());
+  dumping::emit_field (out, indent, "needs_grow_p", needs_grow_p ());
+  dumping::emit_field (out, indent, "use_count", m_use_count);
+  dumping::emit_field (out, indent, "size", m_size);
+  dumping::emit_field (out, indent, "nb_read", m_nb_read);
+  dumping::emit_field (out, indent, "start_line_idx", m_line_start_idx);
+  dumping::emit_field (out, indent, "line_num", m_line_num);
+  dumping::emit_field (out, indent, "missing_trailing_newline",
+                      (int)m_missing_trailing_newline);
+  {
+    dumping::emit_indent (out, indent);
+    fprintf (out, "line records (%i):\n", m_line_record.length ());
+  }
   int idx = 0;
   for (auto &line : m_line_record)
-    fprintf (out, "%*s[%i]: line %zi: byte offsets: %zi-%zi\n",
-            indent + 2, "",
-            idx++, line.line_num, line.start_pos, line.end_pos);
+    {
+      dumping::emit_indent (out, indent);
+      fprintf (out, "[%i]: line %zi: byte offsets: %zi-%zi\n",
+              idx++, line.line_num, line.start_pos, line.end_pos);
+    }
 }
 
 /* Returns TRUE iff the cache would need to be filled with data coming
diff --git a/gcc/diagnostics/html-sink.cc b/gcc/diagnostics/html-sink.cc
index 934d8e2cb341..9309bd633280 100644
--- a/gcc/diagnostics/html-sink.cc
+++ b/gcc/diagnostics/html-sink.cc
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostics/output-file.h"
 #include "diagnostics/buffering.h"
 #include "diagnostics/paths.h"
+#include "diagnostics/dumping.h"
 #include "diagnostics/client-data-hooks.h"
 #include "selftest.h"
 #include "diagnostics/selftest-context.h"
@@ -61,6 +62,16 @@ html_generation_options::html_generation_options ()
 {
 }
 
+void
+html_generation_options::dump (FILE *outfile, int indent) const
+{
+  DIAGNOSTICS_DUMPING_EMIT_FIELD (m_css);
+  DIAGNOSTICS_DUMPING_EMIT_FIELD (m_javascript);
+  DIAGNOSTICS_DUMPING_EMIT_FIELD (m_show_state_diagrams);
+  DIAGNOSTICS_DUMPING_EMIT_FIELD (m_show_state_diagrams_sarif);
+  DIAGNOSTICS_DUMPING_EMIT_FIELD (m_show_state_diagrams_dot_src);
+}
+
 class html_builder;
 
 /* Concrete buffering implementation subclass for HTML output.  */
@@ -116,6 +127,8 @@ public:
                const line_maps *line_maps,
                const html_generation_options &html_gen_opts);
 
+  void dump (FILE *out, int indent) const;
+
   void
   set_main_input_filename (const char *name);
 
@@ -223,11 +236,12 @@ make_span (std::string class_)
 void
 html_sink_buffer::dump (FILE *out, int indent) const
 {
-  fprintf (out, "%*shtml_sink_buffer:\n", indent, "");
+  dumping::emit_heading (out, indent, "html_sink_buffer");
   int idx = 0;
   for (auto &result : m_results)
     {
-      fprintf (out, "%*sresult[%i]:\n", indent + 2, "", idx);
+      dumping::emit_indent (out, indent + 2);
+      fprintf (out, "result[%i]:\n", idx);
       result->dump (out);
       fprintf (out, "\n");
       ++idx;
@@ -469,6 +483,13 @@ html_builder::html_builder (context &dc,
   }
 }
 
+void
+html_builder::dump (FILE *out, int indent) const
+{
+  dumping::emit_heading (out, indent, "HTML generation options");
+  m_html_gen_opts.dump (out, indent + 2);
+}
+
 void
 html_builder::set_main_input_filename (const char *name)
 {
@@ -1333,8 +1354,9 @@ public:
 
   void dump (FILE *out, int indent) const override
   {
-    fprintf (out, "%*shtml_sink\n", indent, "");
     sink::dump (out, indent);
+    dumping::emit_heading (out, indent, "html_builder");
+    m_builder.dump (out, indent + 2);
   }
 
   void
@@ -1439,12 +1461,10 @@ public:
   {
     m_builder.flush_to_file (m_output_file.get_open_file ());
   }
-  void dump (FILE *out, int indent) const override
+  void dump_kind (FILE *out) const override
   {
-    fprintf (out, "%*shtml_file_sink: %s\n",
-            indent, "",
+    fprintf (out, "html_file_sink: %s",
             m_output_file.get_filename ());
-    sink::dump (out, indent);
   }
   bool machine_readable_stderr_p () const final override
   {
@@ -1607,6 +1627,10 @@ private:
     : html_sink (dc, line_maps, html_gen_opts)
     {
     }
+    void dump_kind (FILE *out) const final override
+    {
+      fprintf (out, "html_buffered_sink");
+    }
     bool machine_readable_stderr_p () const final override
     {
       return true;
diff --git a/gcc/diagnostics/html-sink.h b/gcc/diagnostics/html-sink.h
index d86bde813548..d25ceea4b832 100644
--- a/gcc/diagnostics/html-sink.h
+++ b/gcc/diagnostics/html-sink.h
@@ -30,6 +30,8 @@ struct html_generation_options
 {
   html_generation_options ();
 
+  void dump (FILE *out, int indent) const;
+
   bool m_css;
   bool m_javascript;
 
diff --git a/gcc/diagnostics/sarif-sink.cc b/gcc/diagnostics/sarif-sink.cc
index 4b27acb13ad2..0c4d77a7947e 100644
--- a/gcc/diagnostics/sarif-sink.cc
+++ b/gcc/diagnostics/sarif-sink.cc
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostics/paths.h"
 #include "diagnostics/sink.h"
 #include "diagnostics/buffering.h"
+#include "diagnostics/dumping.h"
 #include "json.h"
 #include "cpplib.h"
 #include "diagnostics/logical-locations.h"
@@ -704,6 +705,14 @@ sarif_serialization_format_json::write_to_file (FILE *outf,
   fprintf (outf, "\n");
 }
 
+void
+sarif_serialization_format_json::dump (FILE *outfile, int indent) const
+{
+  dumping::emit_indent (outfile, indent);
+  fprintf (outfile, "json\n");
+  DIAGNOSTICS_DUMPING_EMIT_FIELD (m_formatted);
+}
+
 /* A class for managing SARIF output (for -fdiagnostics-format=sarif-stderr
    and -fdiagnostics-format=sarif-file).
 
@@ -760,6 +769,8 @@ public:
                 const sarif_generation_options &sarif_gen_opts);
   ~sarif_builder ();
 
+  void dump (FILE *out, int indent) const;
+
   void set_printer (pretty_printer &printer)
   {
     m_printer = &printer;
@@ -1699,6 +1710,15 @@ sarif_builder::~sarif_builder ()
     }
 }
 
+void
+sarif_builder::dump (FILE *out, int indent) const
+{
+  dumping::emit_heading (out, indent, "serialization format");
+  m_serialization_format->dump (out, indent + 2);
+  dumping::emit_heading (out, indent, "SARIF generation options");
+  m_sarif_gen_opts.dump (out, indent + 2);
+}
+
 /* Functions at which to stop the backtrace print.  It's not
    particularly helpful to print the callers of these functions.  */
 
@@ -3803,11 +3823,12 @@ sarif_builder::make_artifact_content_object (const char 
*text) const
 void
 sarif_sink_buffer::dump (FILE *out, int indent) const
 {
-  fprintf (out, "%*ssarif_sink_buffer:\n", indent, "");
+  dumping::emit_heading (out, indent, "sarif_sink_buffer");
   int idx = 0;
   for (auto &result : m_results)
     {
-      fprintf (out, "%*sresult[%i]:\n", indent + 2, "", idx);
+      dumping::emit_indent (out, indent + 2);
+      fprintf (out, "result[%i]:\n", idx);
       result->dump (out, true);
       fprintf (out, "\n");
       ++idx;
@@ -3862,8 +3883,9 @@ public:
 
   void dump (FILE *out, int indent) const override
   {
-    fprintf (out, "%*ssarif_sink\n", indent, "");
     sink::dump (out, indent);
+    dumping::emit_heading (out, indent, "sarif_builder");
+    m_builder.dump (out, indent + 2);
   }
 
   void
@@ -3973,6 +3995,10 @@ public:
   {
     m_builder.flush_to_file (m_stream);
   }
+  void dump_kind (FILE *out) const override
+  {
+    fprintf (out, "sarif_stream_sink");
+  }
   bool machine_readable_stderr_p () const final override
   {
     return m_stream == stderr;
@@ -4001,12 +4027,10 @@ public:
   {
     m_builder.flush_to_file (m_output_file.get_open_file ());
   }
-  void dump (FILE *out, int indent) const override
+  void dump_kind (FILE *out) const override
   {
-    fprintf (out, "%*ssarif_file_sink: %s\n",
-            indent, "",
+    fprintf (out, "sarif_file_sink: %s",
             m_output_file.get_filename ());
-    sink::dump (out, indent);
   }
   bool machine_readable_stderr_p () const final override
   {
@@ -4319,6 +4343,29 @@ sarif_generation_options::sarif_generation_options ()
 {
 }
 
+static const char *
+get_dump_string_for_sarif_version (enum sarif_version version)
+{
+  switch (version)
+    {
+    default:
+      gcc_unreachable ();
+    case sarif_version::v2_1_0:
+      return "v2_1_0";
+    case sarif_version::v2_2_prerelease_2024_08_08:
+      return "v2_2_prerelease_2024_08_08";
+    }
+}
+
+void
+sarif_generation_options::dump (FILE *outfile, int indent) const
+{
+  dumping::emit_field (outfile, indent,
+                      "m_version",
+                      get_dump_string_for_sarif_version (m_version));
+  DIAGNOSTICS_DUMPING_EMIT_FIELD (m_state_graph);
+}
+
 #if CHECKING_P
 
 namespace selftest {
@@ -4406,10 +4453,10 @@ public:
   test_sarif_diagnostic_context (const char *main_input_filename,
                                 const sarif_generation_options &sarif_gen_opts)
   {
-    auto sink_ = std::make_unique<buffered_sink> (*this,
-                                                 line_table,
-                                                 true,
-                                                 sarif_gen_opts);
+    auto sink_ = std::make_unique<sarif_buffered_sink> (*this,
+                                                       line_table,
+                                                       true,
+                                                       sarif_gen_opts);
     m_sink = sink_.get (); // borrowed
     init_sarif_sink (*this, std::move (sink_));
     m_sink->set_main_input_filename (main_input_filename);
@@ -4424,10 +4471,10 @@ public:
   sarif_result &get_result (size_t idx) { return m_sink->get_result (idx); }
 
 private:
-  class buffered_sink : public sarif_sink
+  class sarif_buffered_sink : public sarif_sink
   {
   public:
-    buffered_sink (context &dc,
+    sarif_buffered_sink (context &dc,
                   const line_maps *line_maps,
                   bool formatted,
                   const sarif_generation_options &sarif_gen_opts)
@@ -4436,6 +4483,10 @@ private:
                  sarif_gen_opts)
     {
     }
+    void dump_kind (FILE *out) const final override
+    {
+      fprintf (out, "sarif_buffered_sink");
+    }
     bool machine_readable_stderr_p () const final override
     {
       return false;
@@ -4446,7 +4497,7 @@ private:
     }
   };
 
-  buffered_sink *m_sink; // borrowed
+  sarif_buffered_sink *m_sink; // borrowed
 };
 
 /* Test making a sarif_location for a complex rich_location
diff --git a/gcc/diagnostics/sarif-sink.h b/gcc/diagnostics/sarif-sink.h
index 9f8a73fd2849..e6f897b1f42e 100644
--- a/gcc/diagnostics/sarif-sink.h
+++ b/gcc/diagnostics/sarif-sink.h
@@ -73,6 +73,7 @@ public:
   virtual ~sarif_serialization_format () {}
   virtual void write_to_file (FILE *outf,
                              const json::value &top) = 0;
+  virtual void dump (FILE *out, int indent) const = 0;
 };
 
 /* Concrete subclass for serializing SARIF as JSON.  */
@@ -85,6 +86,7 @@ public:
   {
   }
   void write_to_file (FILE *outf, const json::value &top) final override;
+  void dump (FILE *out, int indent) const final override;
 
 private:
   bool m_formatted;
@@ -108,6 +110,8 @@ struct sarif_generation_options
 {
   sarif_generation_options ();
 
+  void dump (FILE *out, int indent) const;
+
   enum sarif_version m_version;
   bool m_state_graph;
 };
diff --git a/gcc/diagnostics/sink.h b/gcc/diagnostics/sink.h
index ac4e0fb64455..e1a3790b3fc2 100644
--- a/gcc/diagnostics/sink.h
+++ b/gcc/diagnostics/sink.h
@@ -36,6 +36,7 @@ class sink
 public:
   virtual ~sink () {}
 
+  virtual void dump_kind (FILE *out) const = 0;
   virtual void dump (FILE *out, int indent) const;
 
   /* Vfunc for notifying this format what the primary input file is,
diff --git a/gcc/diagnostics/text-sink.cc b/gcc/diagnostics/text-sink.cc
index bf22a2c7da9a..a7ebb305cefa 100644
--- a/gcc/diagnostics/text-sink.cc
+++ b/gcc/diagnostics/text-sink.cc
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostics/diagram.h"
 #include "diagnostics/text-sink.h"
 #include "diagnostics/buffering.h"
+#include "diagnostics/dumping.h"
 #include "text-art/theme.h"
 
 /* Disable warnings about quoting issues in the pp_xxx calls below
@@ -76,7 +77,7 @@ text_sink_buffer::text_sink_buffer (sink &sink_)
 void
 text_sink_buffer::dump (FILE *out, int indent) const
 {
-  fprintf (out, "%*stext_sink_buffer:\n", indent, "");
+  dumping::emit_heading (out, indent, "text_sink_buffer");
   m_output_buffer.dump (out, indent + 2);
 }
 
@@ -156,18 +157,19 @@ text_sink::~text_sink ()
 }
 
 void
-text_sink::dump (FILE *out, int indent) const
-{
-  fprintf (out, "%*stext_sink\n", indent, "");
-  fprintf (out, "%*sm_follows_reference_printer: %s\n",
-          indent, "",
-          m_follows_reference_printer ? "true" : "false");
-  sink::dump (out, indent);
-  fprintf (out, "%*ssaved_output_buffer:\n", indent + 2, "");
+text_sink::dump (FILE *outfile, int indent) const
+{
+  DIAGNOSTICS_DUMPING_EMIT_FIELD (m_follows_reference_printer);
+  DIAGNOSTICS_DUMPING_EMIT_FIELD (m_show_nesting);
+  DIAGNOSTICS_DUMPING_EMIT_FIELD (m_show_locations_in_nesting);
+  DIAGNOSTICS_DUMPING_EMIT_FIELD (m_show_nesting_levels);
+
+  sink::dump (outfile, indent);
+  dumping::emit_heading (outfile, indent, "saved_output_buffer");
   if (m_saved_output_buffer)
-    m_saved_output_buffer->dump (out, indent + 4);
+    m_saved_output_buffer->dump (outfile, indent + 2);
   else
-    fprintf (out, "%*s(none):\n", indent + 4, "");
+    dumping::emit_none (outfile, indent + 2);
 }
 
 void
diff --git a/gcc/diagnostics/text-sink.h b/gcc/diagnostics/text-sink.h
index bce3c039b715..e567ec821106 100644
--- a/gcc/diagnostics/text-sink.h
+++ b/gcc/diagnostics/text-sink.h
@@ -51,6 +51,10 @@ public:
   {}
   ~text_sink ();
 
+  void dump_kind (FILE *out) const override
+  {
+    fprintf (out, "text_sink");
+  }
   void dump (FILE *out, int indent) const override;
 
   std::unique_ptr<per_sink_buffer>
-- 
2.26.3

Reply via email to