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.
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 <dmalcolm@redhat.com>
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. */
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, */
{
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;
}
}
+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. */
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 &,
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;
return m_context.get_diagram_theme ();
}
+ void DEBUG_FUNCTION dump () const { dump (stderr, 0); }
+
protected:
diagnostic_output_format (diagnostic_context &context)
: m_context (context)
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. */
}
}
+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. */
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);
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; }
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);
}
}
void
pp_token_list::dump (FILE *out) const
{
- fprintf (out, "[");
for (auto iter = m_first; iter; iter = iter->m_next)
{
iter->dump (out);
}
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);
}
}
/* 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. */
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;
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. */
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, */