aboutsummaryrefslogtreecommitdiff
path: root/gcc/diagnostics
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/diagnostics')
-rw-r--r--gcc/diagnostics/buffering.cc5
-rw-r--r--gcc/diagnostics/column-options.h44
-rw-r--r--gcc/diagnostics/context.cc124
-rw-r--r--gcc/diagnostics/context.h31
-rw-r--r--gcc/diagnostics/dumping.cc116
-rw-r--r--gcc/diagnostics/dumping.h43
-rw-r--r--gcc/diagnostics/file-cache.cc46
-rw-r--r--gcc/diagnostics/html-sink.cc40
-rw-r--r--gcc/diagnostics/html-sink.h2
-rw-r--r--gcc/diagnostics/metadata.h2
-rw-r--r--gcc/diagnostics/output-spec.cc14
-rw-r--r--gcc/diagnostics/sarif-sink.cc81
-rw-r--r--gcc/diagnostics/sarif-sink.h4
-rw-r--r--gcc/diagnostics/sink.h3
-rw-r--r--gcc/diagnostics/source-printing.cc8
-rw-r--r--gcc/diagnostics/text-sink.cc26
-rw-r--r--gcc/diagnostics/text-sink.h8
17 files changed, 473 insertions, 124 deletions
diff --git a/gcc/diagnostics/buffering.cc b/gcc/diagnostics/buffering.cc
index 29f039f..a7747b5 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/column-options.h b/gcc/diagnostics/column-options.h
new file mode 100644
index 0000000..86296e9
--- /dev/null
+++ b/gcc/diagnostics/column-options.h
@@ -0,0 +1,44 @@
+/* Options relating to the meaning of column numbers.
+ Copyright (C) 2000-2025 Free Software Foundation, Inc.
+
+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_COLUMN_OPTIONS_H
+#define GCC_DIAGNOSTICS_COLUMN_OPTIONS_H
+
+namespace diagnostics {
+
+/* A bundle of options relating to the meaning of column numbers. */
+
+struct column_options
+{
+ int convert_column (file_cache &fc,
+ expanded_location s) const;
+
+ /* What units to use when outputting the column number. */
+ enum diagnostics_column_unit m_column_unit;
+
+ /* The origin for the column number (1-based or 0-based typically). */
+ int m_column_origin;
+
+ /* The size of the tabstop for tab expansion. */
+ int m_tabstop;
+};
+
+} // namespace diagnostics
+
+#endif /* ! GCC_DIAGNOSTICS_COLUMN_OPTIONS_H */
diff --git a/gcc/diagnostics/context.cc b/gcc/diagnostics/context.cc
index a1441ca..c948246 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>
@@ -176,12 +177,18 @@ context::initialize (int n_opts)
m_client_aux_data = nullptr;
m_lock = 0;
m_inhibit_notes_p = false;
+
m_source_printing.colorize_source_p = false;
m_source_printing.show_labels_p = false;
m_source_printing.show_line_numbers_p = false;
m_source_printing.min_margin_width = 0;
m_source_printing.show_ruler_p = false;
m_source_printing.show_event_links_p = false;
+
+ m_column_options.m_column_unit = DIAGNOSTICS_COLUMN_UNIT_DISPLAY;
+ m_column_options.m_column_origin = 1;
+ m_column_options.m_tabstop = 8;
+
m_report_bug = false;
m_extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_none;
if (const char *var = getenv ("GCC_EXTRA_DIAGNOSTIC_OUTPUT"))
@@ -192,9 +199,6 @@ context::initialize (int n_opts)
m_extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2;
/* Silently ignore unrecognized values. */
}
- m_column_unit = DIAGNOSTICS_COLUMN_UNIT_DISPLAY;
- m_column_origin = 1;
- m_tabstop = 8;
m_escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE;
m_fixits_change_set = nullptr;
m_diagnostic_groups.m_group_nesting_depth = 0;
@@ -284,6 +288,33 @@ context::urls_init (int value)
(m_reference_printer->get_url_format ());
}
+void
+context::set_show_nesting (bool val)
+{
+ for (auto sink_ : m_sinks)
+ if (sink_->follows_reference_printer_p ())
+ if (auto text_sink_ = sink_->dyn_cast_text_sink ())
+ text_sink_->set_show_nesting (val);
+}
+
+void
+context::set_show_nesting_locations (bool val)
+{
+ for (auto sink_ : m_sinks)
+ if (sink_->follows_reference_printer_p ())
+ if (auto text_sink_ = sink_->dyn_cast_text_sink ())
+ text_sink_->set_show_locations_in_nesting (val);
+}
+
+void
+context::set_show_nesting_levels (bool val)
+{
+ for (auto sink_ : m_sinks)
+ if (sink_->follows_reference_printer_p ())
+ if (auto text_sink_ = sink_->dyn_cast_text_sink ())
+ text_sink_->set_show_nesting_levels (val);
+}
+
/* Create the file_cache, if not already created, and tell it how to
translate files on input. */
void
@@ -355,33 +386,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
@@ -671,11 +706,22 @@ convert_column_unit (file_cache &fc,
}
}
+/* Given an expanded_location, convert the column (which is in 1-based bytes)
+ to the requested units and origin. Return -1 if the column is
+ invalid (<= 0). */
+int
+column_options::convert_column (file_cache &fc,
+ expanded_location s) const
+{
+ int one_based_col = convert_column_unit (fc, m_column_unit, m_tabstop, s);
+ if (one_based_col <= 0)
+ return -1;
+ return one_based_col + (m_column_origin - 1);
+}
+
column_policy::column_policy (const context &dc)
: m_file_cache (dc.get_file_cache ()),
- m_column_unit (dc.m_column_unit),
- m_column_origin (dc.m_column_origin),
- m_tabstop (dc.m_tabstop)
+ m_column_options (dc.get_column_options ())
{
}
@@ -685,11 +731,7 @@ column_policy::column_policy (const context &dc)
int
column_policy::converted_column (expanded_location s) const
{
- int one_based_col = convert_column_unit (m_file_cache,
- m_column_unit, m_tabstop, s);
- if (one_based_col <= 0)
- return -1;
- return one_based_col + (m_column_origin - 1);
+ return m_column_options.convert_column (m_file_cache, s);
}
/* Return a string describing a location e.g. "foo.c:42:10". */
@@ -711,7 +753,7 @@ column_policy::get_location_text (const expanded_location &s,
col = converted_column (s);
}
- const char *line_col = maybe_line_and_column (line, col);
+ const char *line_col = text_sink::maybe_line_and_column (line, col);
return label_text::take (build_message_string ("%s%s%s:%s", locus_cs, file,
line_col, locus_ce));
}
@@ -1098,7 +1140,7 @@ context::get_any_inlining_info (diagnostic_info *diagnostic)
/* Retrieve the locations into which the expression about to be
diagnosed has been inlined, including those of all the callers
all the way down the inlining stack. */
- m_set_locations_cb (this, diagnostic);
+ m_set_locations_cb (*this, diagnostic);
else
{
/* When there's no callback use just the one location provided
@@ -1249,7 +1291,7 @@ context::report_diagnostic (diagnostic_info *diagnostic)
}
if (m_adjust_diagnostic_info)
- m_adjust_diagnostic_info (this, diagnostic);
+ m_adjust_diagnostic_info (*this, diagnostic);
if (diagnostic->m_kind == kind::pedwarn)
{
@@ -1385,6 +1427,8 @@ context::report_diagnostic (diagnostic_info *diagnostic)
sink_->on_report_diagnostic (*diagnostic, orig_diag_kind);
}
+ const int tabstop = get_column_options ().m_tabstop;
+
switch (m_extra_output_kind)
{
default:
@@ -1393,14 +1437,14 @@ context::report_diagnostic (diagnostic_info *diagnostic)
print_parseable_fixits (get_file_cache (),
m_reference_printer, diagnostic->m_richloc,
DIAGNOSTICS_COLUMN_UNIT_BYTE,
- m_tabstop);
+ tabstop);
pp_flush (m_reference_printer);
break;
case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2:
print_parseable_fixits (get_file_cache (),
m_reference_printer, diagnostic->m_richloc,
DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
- m_tabstop);
+ tabstop);
pp_flush (m_reference_printer);
break;
}
@@ -1690,7 +1734,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);
}
@@ -1777,19 +1821,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
@@ -2015,8 +2059,8 @@ assert_location_text (const char *expected_loc_text,
= DIAGNOSTICS_COLUMN_UNIT_BYTE)
{
diagnostics::selftest::test_context dc;
- dc.m_column_unit = column_unit;
- dc.m_column_origin = origin;
+ dc.get_column_options ().m_column_unit = column_unit;
+ dc.get_column_options ().m_column_origin = origin;
expanded_location xloc;
xloc.file = filename;
@@ -2052,8 +2096,8 @@ test_get_location_text ()
assert_location_text ("foo.c:42:", "foo.c", 42, 10, false);
assert_location_text ("foo.c:", "foo.c", 0, 10, false);
- diagnostics::maybe_line_and_column (INT_MAX, INT_MAX);
- diagnostics::maybe_line_and_column (INT_MIN, INT_MIN);
+ diagnostics::text_sink::maybe_line_and_column (INT_MAX, INT_MAX);
+ diagnostics::text_sink::maybe_line_and_column (INT_MIN, INT_MIN);
{
/* In order to test display columns vs byte columns, we need to create a
diff --git a/gcc/diagnostics/context.h b/gcc/diagnostics/context.h
index b6ec85c..dea4588 100644
--- a/gcc/diagnostics/context.h
+++ b/gcc/diagnostics/context.h
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostics/option-id-manager.h"
#include "diagnostics/context-options.h"
#include "diagnostics/source-printing-options.h"
+#include "diagnostics/column-options.h"
#include "diagnostics/counters.h"
namespace diagnostics {
@@ -99,13 +100,11 @@ public:
bool show_column,
bool colorize) const;
- int get_tabstop () const { return m_tabstop; }
+ int get_tabstop () const { return m_column_options.m_tabstop; }
private:
file_cache &m_file_cache;
- enum diagnostics_column_unit m_column_unit;
- int m_column_origin;
- int m_tabstop;
+ column_options m_column_options;
};
/* A bundle of state for printing locations within diagnostics
@@ -265,7 +264,7 @@ public:
friend class text_sink;
friend class buffer;
- typedef void (*set_locations_callback_t) (context *,
+ typedef void (*set_locations_callback_t) (const context &,
diagnostic_info *);
void initialize (int n_opts);
@@ -393,6 +392,9 @@ public:
}
void set_show_path_depths (bool val) { m_show_path_depths = val; }
void set_show_option_requested (bool val) { m_show_option_requested = val; }
+ void set_show_nesting (bool val);
+ void set_show_nesting_locations (bool val);
+ void set_show_nesting_levels (bool val);
void set_max_errors (int val) { m_max_errors = val; }
void set_escape_format (enum diagnostics_escape_format val)
{
@@ -572,7 +574,7 @@ public:
}
void
- set_adjust_diagnostic_info_callback (void (*cb) (context *,
+ set_adjust_diagnostic_info_callback (void (*cb) (const context &,
diagnostic_info *))
{
m_adjust_diagnostic_info = cb;
@@ -592,6 +594,9 @@ public:
return m_source_printing;
}
+ column_options &get_column_options () { return m_column_options; }
+ const column_options &get_column_options () const { return m_column_options; }
+
void set_caret_max_width (int value);
private:
@@ -708,7 +713,7 @@ private:
/* Client hook to adjust properties of the given diagnostic that we're
about to issue, such as its kind. */
- void (*m_adjust_diagnostic_info)(context *, diagnostic_info *);
+ void (*m_adjust_diagnostic_info)(const context &, diagnostic_info *);
/* Owned by the context; this would be a std::unique_ptr if
context had a proper ctor. */
@@ -739,6 +744,7 @@ private:
bool m_inhibit_notes_p;
source_printing_options m_source_printing;
+ column_options m_column_options;
/* True if -freport-bug option is used. */
bool m_report_bug;
@@ -748,17 +754,6 @@ private:
-fdiagnostics-parseable-fixits and GCC_EXTRA_DIAGNOSTIC_OUTPUT. */
enum diagnostics_extra_output_kind m_extra_output_kind;
-public:
- /* What units to use when outputting the column number. */
- enum diagnostics_column_unit m_column_unit;
-
- /* The origin for the column number (1-based or 0-based typically). */
- int m_column_origin;
-
- /* The size of the tabstop for tab expansion. */
- int m_tabstop;
-
-private:
/* How should non-ASCII/non-printable bytes be escaped when
a diagnostic suggests escaping the source code on output. */
enum diagnostics_escape_format m_escape_format;
diff --git a/gcc/diagnostics/dumping.cc b/gcc/diagnostics/dumping.cc
new file mode 100644
index 0000000..f0366a5
--- /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 <dmalcolm@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 0000000..08c7ee4
--- /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 <dmalcolm@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 febeb03..9acf82e 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 934d8e2..448d461 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;
@@ -470,6 +484,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)
{
gcc_assert (m_title_element);
@@ -539,7 +560,7 @@ html_builder::on_report_diagnostic (const diagnostic_info &diagnostic,
}
}
-// For ease of comparison with experimental-nesting-show-levels=yes
+// For ease of comparison with show-nesting-levels=yes
static void
add_nesting_level_attr (xml::element &element,
@@ -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 d86bde8..d25ceea 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/metadata.h b/gcc/diagnostics/metadata.h
index c28f982..39291ec 100644
--- a/gcc/diagnostics/metadata.h
+++ b/gcc/diagnostics/metadata.h
@@ -119,6 +119,8 @@ class metadata
const lazy_digraphs *m_lazy_digraphs;
};
+extern char *get_cwe_url (int cwe);
+
} // namespace diagnostics
#endif /* ! GCC_DIAGNOSTICS_METADATA_H */
diff --git a/gcc/diagnostics/output-spec.cc b/gcc/diagnostics/output-spec.cc
index 83f128c..13565f9 100644
--- a/gcc/diagnostics/output-spec.cc
+++ b/gcc/diagnostics/output-spec.cc
@@ -368,7 +368,7 @@ text_scheme_handler::make_sink (const context &ctxt,
const scheme_name_and_params &parsed_arg) const
{
bool show_color = pp_show_color (dc.get_reference_printer ());
- bool show_nesting = false;
+ bool show_nesting = true;
bool show_locations_in_nesting = true;
bool show_levels = false;
for (auto& iter : parsed_arg.m_kvs)
@@ -381,21 +381,21 @@ text_scheme_handler::make_sink (const context &ctxt,
return nullptr;
continue;
}
- if (key == "experimental-nesting")
+ if (key == "show-nesting")
{
if (!parse_bool_value (ctxt, unparsed_arg, key, value,
show_nesting))
return nullptr;
continue;
}
- if (key == "experimental-nesting-show-locations")
+ if (key == "show-nesting-locations")
{
if (!parse_bool_value (ctxt, unparsed_arg, key, value,
show_locations_in_nesting))
return nullptr;
continue;
}
- if (key == "experimental-nesting-show-levels")
+ if (key == "show-nesting-levels")
{
if (!parse_bool_value (ctxt, unparsed_arg, key, value, show_levels))
return nullptr;
@@ -405,9 +405,9 @@ text_scheme_handler::make_sink (const context &ctxt,
/* Key not found. */
auto_vec<const char *> known_keys;
known_keys.safe_push ("color");
- known_keys.safe_push ("experimental-nesting");
- known_keys.safe_push ("experimental-nesting-show-locations");
- known_keys.safe_push ("experimental-nesting-show-levels");
+ known_keys.safe_push ("show-nesting");
+ known_keys.safe_push ("show-nesting-locations");
+ known_keys.safe_push ("show-nesting-levels");
ctxt.report_unknown_key (unparsed_arg, key, get_scheme_name (),
known_keys);
return nullptr;
diff --git a/gcc/diagnostics/sarif-sink.cc b/gcc/diagnostics/sarif-sink.cc
index 4738ae9..0c4d77a 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;
@@ -1674,7 +1685,7 @@ sarif_builder::sarif_builder (diagnostics::context &dc,
(std::make_unique<sarif_array_of_unique<sarif_logical_location>> ()),
m_run_graphs
(std::make_unique<sarif_array_of_unique<sarif_graph>> ()),
- m_tabstop (dc.m_tabstop),
+ m_tabstop (dc.get_column_options ().m_tabstop),
m_serialization_format (std::move (serialization_format)),
m_sarif_gen_opts (sarif_gen_opts),
m_next_result_idx (0),
@@ -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 9f8a73f..e6f897b 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 ac4e0fb64..24eb707 100644
--- a/gcc/diagnostics/sink.h
+++ b/gcc/diagnostics/sink.h
@@ -36,6 +36,9 @@ class sink
public:
virtual ~sink () {}
+ virtual text_sink *dyn_cast_text_sink () { return nullptr; }
+
+ 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/source-printing.cc b/gcc/diagnostics/source-printing.cc
index 94b1c2d..aeda9ad 100644
--- a/gcc/diagnostics/source-printing.cc
+++ b/gcc/diagnostics/source-printing.cc
@@ -4412,7 +4412,7 @@ test_layout_x_offset_display_tab (const line_table_case &case_)
for (int tabstop = 1; tabstop != num_tabstops; ++tabstop)
{
test_context dc;
- dc.m_tabstop = tabstop;
+ dc.get_column_options ().m_tabstop = tabstop;
diagnostics::source_print_policy policy (dc);
layout test_layout (policy, richloc, nullptr);
colorizer col (*dc.get_reference_printer (),
@@ -4436,7 +4436,7 @@ test_layout_x_offset_display_tab (const line_table_case &case_)
for (int tabstop = 1; tabstop != num_tabstops; ++tabstop)
{
test_context dc;
- dc.m_tabstop = tabstop;
+ dc.get_column_options ().m_tabstop = tabstop;
static const int small_width = 24;
auto &source_printing_opts = dc.get_source_printing_options ();
source_printing_opts.max_width = small_width - 4;
@@ -6833,7 +6833,7 @@ test_tab_expansion (const line_table_case &case_)
everything too. */
{
test_context dc;
- dc.m_tabstop = tabstop;
+ dc.get_column_options ().m_tabstop = tabstop;
rich_location richloc (line_table,
linemap_position_for_column (line_table,
first_non_ws_byte_col));
@@ -6846,7 +6846,7 @@ test_tab_expansion (const line_table_case &case_)
as well. */
{
test_context dc;
- dc.m_tabstop = tabstop;
+ dc.get_column_options ().m_tabstop = tabstop;
rich_location richloc (line_table,
linemap_position_for_column (line_table,
right_quote_byte_col));
diff --git a/gcc/diagnostics/text-sink.cc b/gcc/diagnostics/text-sink.cc
index bcf91cf..a7ebb30 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
@@ -612,7 +614,7 @@ text_sink::get_location_text (const expanded_location &s) const
The result is a statically allocated buffer. */
const char *
-maybe_line_and_column (int line, int col)
+text_sink::maybe_line_and_column (int line, int col)
{
static char result[32];
diff --git a/gcc/diagnostics/text-sink.h b/gcc/diagnostics/text-sink.h
index 5c60976..f280e72 100644
--- a/gcc/diagnostics/text-sink.h
+++ b/gcc/diagnostics/text-sink.h
@@ -51,6 +51,12 @@ public:
{}
~text_sink ();
+ text_sink *dyn_cast_text_sink () final override { return this; }
+
+ 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>
@@ -127,6 +133,8 @@ public:
return m_source_printing;
}
+ static const char *maybe_line_and_column (int line, int col);
+
protected:
void print_any_cwe (const diagnostic_info &diagnostic);
void print_any_rules (const diagnostic_info &diagnostic);