diff options
Diffstat (limited to 'gcc/diagnostics')
-rw-r--r-- | gcc/diagnostics/buffering.cc | 5 | ||||
-rw-r--r-- | gcc/diagnostics/column-options.h | 44 | ||||
-rw-r--r-- | gcc/diagnostics/context.cc | 124 | ||||
-rw-r--r-- | gcc/diagnostics/context.h | 31 | ||||
-rw-r--r-- | gcc/diagnostics/dumping.cc | 116 | ||||
-rw-r--r-- | gcc/diagnostics/dumping.h | 43 | ||||
-rw-r--r-- | gcc/diagnostics/file-cache.cc | 46 | ||||
-rw-r--r-- | gcc/diagnostics/html-sink.cc | 40 | ||||
-rw-r--r-- | gcc/diagnostics/html-sink.h | 2 | ||||
-rw-r--r-- | gcc/diagnostics/metadata.h | 2 | ||||
-rw-r--r-- | gcc/diagnostics/output-spec.cc | 14 | ||||
-rw-r--r-- | gcc/diagnostics/sarif-sink.cc | 81 | ||||
-rw-r--r-- | gcc/diagnostics/sarif-sink.h | 4 | ||||
-rw-r--r-- | gcc/diagnostics/sink.h | 3 | ||||
-rw-r--r-- | gcc/diagnostics/source-printing.cc | 8 | ||||
-rw-r--r-- | gcc/diagnostics/text-sink.cc | 26 | ||||
-rw-r--r-- | gcc/diagnostics/text-sink.h | 8 |
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); |