This commit expands on r15-3973-g4c7a58ac2617e2, which added
debug "dump" member functiosn to pretty_printer and output_buffer.

This followup adds "dump" member functions to diagnostic_context and
diagnostic_format, extends the existing dump functions and adds
indentation to make it much easier to see the various relationships
between context, format, printer, etc.

Hence you can now do:

(gdb) call global_dc->dump ()

and get a useful summary of what the diagnostic subsystem is doing;
for example:

(gdb) call global_dc->dump()
diagnostic_context:
  counts:
  output format:
    sarif_output_format
  printer:
    m_show_color: false
    m_url_format: bel
    m_buffer:
      m_formatted_obstack current object: length 0:
      m_chunk_obstack current object: length 0:
      pp_formatted_chunks: depth 0
        0: TEXT("Function ")]
        1: BEGIN_QUOTE, TEXT("program"), END_QUOTE]
        2: TEXT(" requires an argument list at ")]
        3: TEXT("(1)")]

showing the counts of all diagnostic kind that are non-zero (none yet),
that we have a sarif output format, and the printer is part-way through
formatting a string.

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

gcc/ChangeLog:
        * diagnostic-format-json.cc (json_output_format::dump): New.
        * diagnostic-format-sarif.cc (sarif_output_format::dump): New.
        (sarif_file_output_format::dump): New.
        * diagnostic-format-text.cc (diagnostic_text_output_format::dump):
        New.
        * diagnostic-format-text.h (diagnostic_text_output_format::dump):
        New decl.
        * diagnostic-format.h (diagnostic_output_format::dump): New decls.
        * diagnostic.cc (diagnostic_context::dump): New.
        (diagnostic_output_format::dump): New.
        * diagnostic.h (diagnostic_context::dump): New decls.
        * pretty-print-format-impl.h (pp_formatted_chunks::dump): Add
        "indent" param.
        * pretty-print.cc (bytes_per_hexdump_line): New constant.
        (print_hexdump_line): New.
        (print_hexdump): New.
        (output_buffer::dump): Add "indent" param and use it.  Add
        hexdump of current object in m_formatted_obstack and
        m_chunk_obstack.
        (pp_formatted_chunks::dump): Add "indent" param and use it.
        (pretty_printer::dump): Likewise.  Add dumping of m_show_color
        and m_url_format.
        * pretty-print.h (output_buffer::dump): Add "indent" param.
        (pretty_printer::dump): Likewise.

gcc/testsuite/ChangeLog:
        * gcc.dg/plugin/diagnostic_plugin_xhtml_format.c
        (xhtml_output_format::dump): New.

Signed-off-by: David Malcolm <dmalc...@redhat.com>
---
 gcc/diagnostic-format-json.cc                 |  6 ++
 gcc/diagnostic-format-sarif.cc                | 13 +++
 gcc/diagnostic-format-text.cc                 |  7 ++
 gcc/diagnostic-format-text.h                  |  3 +
 gcc/diagnostic-format.h                       |  4 +
 gcc/diagnostic.cc                             | 24 +++++
 gcc/diagnostic.h                              |  3 +
 gcc/pretty-print-format-impl.h                |  4 +-
 gcc/pretty-print.cc                           | 96 +++++++++++++++++--
 gcc/pretty-print.h                            |  8 +-
 .../plugin/diagnostic_plugin_xhtml_format.c   |  6 ++
 11 files changed, 160 insertions(+), 14 deletions(-)

diff --git a/gcc/diagnostic-format-json.cc b/gcc/diagnostic-format-json.cc
index b4c1f13ee671..4f035dd2fae3 100644
--- a/gcc/diagnostic-format-json.cc
+++ b/gcc/diagnostic-format-json.cc
@@ -38,6 +38,12 @@ along with GCC; see the file COPYING3.  If not see
 class json_output_format : public diagnostic_output_format
 {
 public:
+  void dump (FILE *out, int indent) const override
+  {
+    fprintf (out, "%*sjson_output_format\n", indent, "");
+    diagnostic_output_format::dump (out, indent);
+  }
+
   void on_begin_group () final override
   {
     /* No-op.  */
diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc
index 89ac9a5424c9..f64c83ad6e14 100644
--- a/gcc/diagnostic-format-sarif.cc
+++ b/gcc/diagnostic-format-sarif.cc
@@ -3302,6 +3302,12 @@ public:
     gcc_assert (!pending_result);
   }
 
+  void dump (FILE *out, int indent) const override
+  {
+    fprintf (out, "%*ssarif_output_format\n", indent, "");
+    diagnostic_output_format::dump (out, indent);
+  }
+
   void on_begin_group () final override
   {
     /* No-op,  */
@@ -3386,6 +3392,13 @@ public:
   {
     m_builder.flush_to_file (m_output_file.get_open_file ());
   }
+  void dump (FILE *out, int indent) const override
+  {
+    fprintf (out, "%*ssarif_file_output_format: %s\n",
+            indent, "",
+            m_output_file.get_filename ());
+    diagnostic_output_format::dump (out, indent);
+  }
   bool machine_readable_stderr_p () const final override
   {
     return false;
diff --git a/gcc/diagnostic-format-text.cc b/gcc/diagnostic-format-text.cc
index 0d58d5fb082d..f6ec88155c7f 100644
--- a/gcc/diagnostic-format-text.cc
+++ b/gcc/diagnostic-format-text.cc
@@ -69,6 +69,13 @@ 
diagnostic_text_output_format::~diagnostic_text_output_format ()
     }
 }
 
+void
+diagnostic_text_output_format::dump (FILE *out, int indent) const
+{
+  fprintf (out, "%*sdiagnostic_text_output_format\n", indent, "");
+  diagnostic_output_format::dump (out, indent);
+}
+
 /* Implementation of diagnostic_output_format::on_report_diagnostic vfunc
    for GCC's standard textual output.  */
 
diff --git a/gcc/diagnostic-format-text.h b/gcc/diagnostic-format-text.h
index 2e57e27c739d..d3b10dd518ae 100644
--- a/gcc/diagnostic-format-text.h
+++ b/gcc/diagnostic-format-text.h
@@ -39,6 +39,9 @@ public:
     m_includes_seen (nullptr)
   {}
   ~diagnostic_text_output_format ();
+
+  void dump (FILE *out, int indent) const override;
+
   void on_begin_group () override {}
   void on_end_group () override {}
   void on_report_diagnostic (const diagnostic_info &,
diff --git a/gcc/diagnostic-format.h b/gcc/diagnostic-format.h
index 1fd3fe0c64e8..e514c6f1ced8 100644
--- a/gcc/diagnostic-format.h
+++ b/gcc/diagnostic-format.h
@@ -32,6 +32,8 @@ class diagnostic_output_format
 public:
   virtual ~diagnostic_output_format () {}
 
+  virtual void dump (FILE *out, int indent) const;
+
   virtual void on_begin_group () = 0;
   virtual void on_end_group () = 0;
 
@@ -52,6 +54,8 @@ public:
     return m_context.get_diagram_theme ();
   }
 
+  void DEBUG_FUNCTION dump () const { dump (stderr, 0); }
+
 protected:
   diagnostic_output_format (diagnostic_context &context)
   : m_context (context)
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 4a1e347776e9..2a72717d16d0 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -418,6 +418,24 @@ diagnostic_context::finish ()
   m_original_argv = nullptr;
 }
 
+/* Dump state of this diagnostic_context to OUT, for debugging.  */
+
+void
+diagnostic_context::dump (FILE *out) const
+{
+  fprintf (out, "diagnostic_context:\n");
+  fprintf (out, "  counts:\n");
+  for (int i = 0; i < DK_LAST_DIAGNOSTIC_KIND; i++)
+    if (m_diagnostic_count[i] > 0)
+      fprintf (out, "    %s%i\n",
+              get_diagnostic_kind_text (static_cast<diagnostic_t> (i)),
+              m_diagnostic_count[i]);
+  fprintf (out, "  output format:\n");
+  m_output_format->dump (out, 4);
+  fprintf (out, "  printer:\n");
+  m_printer->dump (out, 4);
+}
+
 /* Return true if sufficiently severe diagnostics have been seen that
    we ought to exit with a non-zero exit code.  */
 
@@ -1555,6 +1573,12 @@ diagnostic_context::end_group ()
     }
 }
 
+void
+diagnostic_output_format::dump (FILE *, int) const
+{
+  /* No-op for now.  */
+}
+
 /* Set the output format for CONTEXT to FORMAT, using BASE_FILE_NAME for
    file-based output formats.  */
 
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index dbb3803ffb19..edd221f1a8ce 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -477,6 +477,9 @@ public:
 
   void finish ();
 
+  void dump (FILE *out) const;
+  void DEBUG_FUNCTION dump () const { dump (stderr); }
+
   bool execution_failed_p () const;
 
   void set_original_argv (unique_argv original_argv);
diff --git a/gcc/pretty-print-format-impl.h b/gcc/pretty-print-format-impl.h
index ec4425c9dafb..8c969cdfed73 100644
--- a/gcc/pretty-print-format-impl.h
+++ b/gcc/pretty-print-format-impl.h
@@ -373,8 +373,8 @@ public:
 
   void append_formatted_chunk (obstack &s, const char *content);
 
-  void dump (FILE *out) const;
-  void DEBUG_FUNCTION dump () const { dump (stderr); }
+  void dump (FILE *out, int indent) const;
+  void DEBUG_FUNCTION dump () const { dump (stderr, 0); }
 
   // For use in selftests
   pp_formatted_chunks *get_prev () const { return m_prev; }
diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc
index 18c4b2fa3509..8082dbcdddda 100644
--- a/gcc/pretty-print.cc
+++ b/gcc/pretty-print.cc
@@ -794,18 +794,75 @@ output_buffer::pop_formatted_chunks ()
   obstack_free (&m_chunk_obstack, old_top);
 }
 
+static const int bytes_per_hexdump_line = 16;
+
+static void
+print_hexdump_line (FILE *out, int indent,
+                   const void *buf, size_t size, size_t line_start_idx)
+{
+  fprintf (out, "%*s%08lx: ", indent, "", (unsigned long)line_start_idx);
+  for (size_t offset = 0; offset < bytes_per_hexdump_line; ++offset)
+    {
+      const size_t idx = line_start_idx + offset;
+      if (idx < size)
+       fprintf (out, "%02x ", ((const unsigned char *)buf)[idx]);
+      else
+       fprintf (out, "   ");
+    }
+  fprintf (out, "| ");
+  for (size_t offset = 0; offset < bytes_per_hexdump_line; ++offset)
+    {
+      const size_t idx = line_start_idx + offset;
+      if (idx < size)
+       {
+         unsigned char ch = ((const unsigned char *)buf)[idx];
+         if (!ISPRINT (ch))
+           ch = '.';
+         fputc (ch, out);
+       }
+      else
+       break;
+    }
+  fprintf (out, "\n");
+
+}
+
+static void
+print_hexdump (FILE *out, int indent, const void *buf, size_t size)
+{
+  for (size_t idx = 0; idx < size; idx += bytes_per_hexdump_line)
+    print_hexdump_line (out, indent, buf, size, idx);
+}
+
 /* Dump state of this output_buffer to OUT, for debugging.  */
 
 void
-output_buffer::dump (FILE *out) const
+output_buffer::dump (FILE *out, int indent) const
 {
+  {
+    size_t obj_size = obstack_object_size (&m_formatted_obstack);
+    fprintf (out, "%*sm_formatted_obstack current object: length %li:\n",
+            indent, "", (long)obj_size);
+    print_hexdump (out, indent + 2,
+                  m_formatted_obstack.object_base, obj_size);
+  }
+  {
+    size_t obj_size = obstack_object_size (&m_chunk_obstack);
+    fprintf (out, "%*sm_chunk_obstack current object: length %li:\n",
+            indent, "", (long)obj_size);
+    print_hexdump (out, indent + 2,
+                  m_chunk_obstack.object_base, obj_size);
+  }
+
   int depth = 0;
   for (pp_formatted_chunks *iter = m_cur_formatted_chunks;
        iter;
        iter = iter->m_prev, depth++)
     {
-      fprintf (out, "pp_formatted_chunks: depth %i\n", depth);
-      iter->dump (out);
+      fprintf (out, "%*spp_formatted_chunks: depth %i\n",
+              indent, "",
+              depth);
+      iter->dump (out, indent + 2);
     }
 }
 
@@ -1505,7 +1562,6 @@ pp_token_list::apply_urlifier (const urlifier &urlifier)
 void
 pp_token_list::dump (FILE *out) const
 {
-  fprintf (out, "[");
   for (auto iter = m_first; iter; iter = iter->m_next)
     {
       iter->dump (out);
@@ -1532,11 +1588,13 @@ pp_formatted_chunks::append_formatted_chunk (obstack 
&s, const char *content)
 }
 
 void
-pp_formatted_chunks::dump (FILE *out) const
+pp_formatted_chunks::dump (FILE *out, int indent) const
 {
   for (size_t idx = 0; m_args[idx]; ++idx)
     {
-      fprintf (out, "%i: ", (int)idx);
+      fprintf (out, "%*s%i: ",
+              indent, "",
+              (int)idx);
       m_args[idx]->dump (out);
     }
 }
@@ -3035,9 +3093,31 @@ pretty_printer::end_url ()
 /* Dump state of this pretty_printer to OUT, for debugging.  */
 
 void
-pretty_printer::dump (FILE *out) const
+pretty_printer::dump (FILE *out, int indent) const
 {
-  m_buffer->dump (out);
+  fprintf (out, "%*sm_show_color: %s\n",
+          indent, "",
+          m_show_color ? "true" : "false");
+
+  fprintf (out, "%*sm_url_format: ", indent, "");
+  switch (m_url_format)
+    {
+    case URL_FORMAT_NONE:
+      fprintf (out, "none");
+      break;
+    case URL_FORMAT_ST:
+      fprintf (out, "st");
+      break;
+    case URL_FORMAT_BEL:
+      fprintf (out, "bel");
+      break;
+    default:
+      gcc_unreachable ();
+    }
+  fprintf (out, "\n");
+
+  fprintf (out, "%*sm_buffer:\n", indent, "");
+  m_buffer->dump (out, indent + 2);
 }
 
 /* class pp_markup::context.  */
diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h
index ec64a167327b..05dbb1986da8 100644
--- a/gcc/pretty-print.h
+++ b/gcc/pretty-print.h
@@ -93,8 +93,8 @@ public:
   pp_formatted_chunks *push_formatted_chunks ();
   void pop_formatted_chunks ();
 
-  void dump (FILE *out) const;
-  void DEBUG_FUNCTION dump () const { dump (stderr); }
+  void dump (FILE *out, int indent) const;
+  void DEBUG_FUNCTION dump () const { dump (stderr, 0); }
 
   /* Obstack where the text is built up.  */
   struct obstack m_formatted_obstack;
@@ -316,8 +316,8 @@ public:
   void set_real_maximum_length ();
   int remaining_character_count_for_line ();
 
-  void dump (FILE *out) const;
-  void DEBUG_FUNCTION dump () const { dump (stderr); }
+  void dump (FILE *out, int indent) const;
+  void DEBUG_FUNCTION dump () const { dump (stderr, 0); }
 
 private:
   /* Where we print external representation of ENTITY.  */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.c 
b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.c
index c74ecb018efa..d38250761b73 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.c
@@ -594,6 +594,12 @@ public:
     gcc_assert (!pending_diag);
   }
 
+  void dump (FILE *out, int indent) const override
+  {
+    fprintf (out, "%*xhtml_output_format\n", indent, "");
+    diagnostic_output_format::dump (out, indent);
+  }
+
   void on_begin_group () final override
   {
     /* No-op,  */
-- 
2.26.3

Reply via email to