aboutsummaryrefslogtreecommitdiff
path: root/gcc/jit
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2024-10-29 19:12:02 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2024-10-29 19:12:02 -0400
commit0b73e9382ab51c00a79b2a6f8abbcd31d87f6814 (patch)
tree34a863f1635b75d45e8426c6803b45cfd6f2b152 /gcc/jit
parent3d8cd34a450e9ffe2b2ac8a0c8eb33fd5d613483 (diff)
downloadgcc-0b73e9382ab51c00a79b2a6f8abbcd31d87f6814.zip
gcc-0b73e9382ab51c00a79b2a6f8abbcd31d87f6814.tar.gz
gcc-0b73e9382ab51c00a79b2a6f8abbcd31d87f6814.tar.bz2
diagnostics: support multiple output formats simultaneously [PR116613]
This patch generalizes diagnostic_context so that rather than having a single output format, it has a vector of zero or more. It adds new two options: -fdiagnostics-add-output=DIAGNOSTICS-OUTPUT-SPEC -fdiagnostics-set-output=DIAGNOSTICS-OUTPUT-SPEC which both take a new configuration syntax of the form SCHEME ("text" or "sarif"), optionally followed by ":" and one or more KEY=VALUE pairs, in this form: <SCHEME> <SCHEME>:<KEY>=<VALUE> <SCHEME>:<KEY>=<VALUE>,<KEY2>=<VALUE2> ...etc where each SCHEME supports some set of keys. For example, it's now possible to use: -fdiagnostics-add-output=sarif:version=2.1,file=foo.2.1.sarif \ -fdiagnostics-add-output=sarif:version=2.2-prerelease,file=foo.2.2.sarif to add a pair of outputs, each writing to a different file, using versions 2.1 and 2.2 of the SARIF standard respectively, whilst also emitting the classic text form of the diagnostics to stderr. I hope the new syntax gives us room to potentially add new kinds of output sink in the future (e.g. RPC notifications), and to add new key/value pairs as needed by the different sinks. Implementation-wise, the diagnostic_context's m_printer which previously was used directly by the single output format now becomes a "reference printer", created by the client (such as the frontend), with defaults modified by command-line options. Each of the multiple output sinks has its own pretty_printer instance, created by cloning the context's reference printer. gcc/ChangeLog: PR other/116613 * Makefile.in (OBJS-libcommon-target): Add opts-diagnostic.o. * common.opt (fdiagnostics-add-output=): New. (fdiagnostics-set-output=): New. (diagnostics_output_format): Drop sarif-file-2.2-prerelease from enum. * common.opt.urls: Regenerate. * diagnostic-buffer.h (diagnostic_buffer::~diagnostic_buffer): New. (diagnostic_buffer::ensure_per_format_buffer): Rename to... (diagnostic_buffer::ensure_per_format_buffers): ...this. (diagnostic_buffer::m_per_format_buffer): Replace with... (diagnostic_buffer::m_per_format_buffers): ...this, updating type. * diagnostic-format-json.cc (json_output_format::update_printer): New. (json_output_format::follows_reference_printer_p): New. (diagnostic_output_format_init_json): Drop redundant call to set_path_format, as this is not a text output format. * diagnostic-format-sarif.cc: Include "diagnostic-format-text.h". (sarif_builder::set_printer): New. (sarif_builder::sarif_builder): Add "printer" param and use it for m_printer. (sarif_builder::make_location_object::escape_nonascii_renderer::render): Rather than using dc.m_printer, create a diagnostic_text_output_format instance and use its printer. (sarif_output_format::follows_reference_printer_p): New. (sarif_output_format::update_printer): New. (sarif_output_format::sarif_output_format): Pass in correct printer to m_builder's ctor. (diagnostic_output_format_init_sarif): Drop redundant call to set_path_format, as this is not a text output format. Replace calls to pp_show_color and set_token_printer with call to update_printer. Drop redundant call to set_show_highlight_colors, as this printer does not show colors. (diagnostic_output_format_init_sarif_file): Split out file opening into... (diagnostic_output_format_open_sarif_file): ...this new function. (make_sarif_sink): New. (selftest::test_make_location_object): Provide a pp for the builder. * diagnostic-format-sarif.h (diagnostic_output_format_open_sarif_file): New decl. (make_sarif_sink): New decl. * diagnostic-format-text.cc (diagnostic_text_output_format::dump): Dump sm_follows_reference_printer. (diagnostic_text_output_format::on_report_verbatim): New. (diagnostic_text_output_format::follows_reference_printer_p): New. (diagnostic_text_output_format::update_printer): New. * diagnostic-format-text.h (diagnostic_text_output_format::diagnostic_text_output_format): Add optional "follows_reference_printer" param. (diagnostic_text_output_format::on_report_verbatim): New decl. (diagnostic_text_output_format::after_diagnostic): Drop "final". (diagnostic_text_output_format::follows_reference_printer_p): New decl. (class diagnostic_text_output_format): Convert private members to protected. (diagnostic_text_output_format::m_follows_reference_printer): New field. * diagnostic-format.h (diagnostic_output_format::on_report_verbatim): New vfunc. (diagnostic_output_format::follows_reference_printer_p): New vfunc. (diagnostic_output_format::update_printer): New vfunc. (diagnostic_output_format::get_printer): Use m_printer rather than a printer from m_context. (diagnostic_output_format::diagnostic_output_format): Initialize m_printer by cloning the context's printer. (diagnostic_output_format::m_printer): New field. * diagnostic-global-context.cc (verbatim): Reimplement in terms of global_dc->report_verbatim, moving existing implementation to diagnostic_text_output_format::on_report_verbatim. (fnotice): Support multiple output sinks by using a new global_dc->supports_fnotice_on_stderr_p. * diagnostic-output-file.h (diagnostic_output_file::diagnostic_output_file): New default ctor. (diagnostic_output_file::operator=): Implement move assignment. * diagnostic-path.cc (selftest::test_interprocedural_path_1): Pass false for new param of text_output's ctor. * diagnostic-show-locus.cc (selftest::test_layout_x_offset_display_utf8): Use reference printer. (selftest::test_layout_x_offset_display_tab): Likewise. (selftest::test_one_liner_fixit_remove): Likewise. * diagnostic.cc: Include "pretty-print-urlifier.h". (diagnostic_set_caret_max_width): Update for global_dc's m_printer becoming reference printer. (diagnostic_context::initialize): Update for m_printer becoming m_reference_printer. Use ::make_unique to create it. Update for m_output_format becoming m_output_sinks. (diagnostic_context::color_init): Update the reference printer, then update the printers for any output sinks that follow it. (diagnostic_context::urls_init): Likewise. (diagnostic_context::finish): Update comment. Update for m_output_format becoming m_output_sinks. Update for m_printer becoming m_reference_printer and use "delete" on it rather than XDELETE. (diagnostic_context::dump): Update for m_printer becoming reference printer, and for multiple output sinks. (diagnostic_context::set_output_format): Reimplement for supporting multiple output sinks. (diagnostic_context::get_output_format): Likewise. (diagnostic_context::add_sink): New. (diagnostic_context::supports_fnotice_on_stderr_p): New. (diagnostic_context::set_pretty_printer): New. (diagnostic_context::refresh_output_sinks): New. (diagnostic_context::set_format_decoder): New. (diagnostic_context::set_show_highlight_colors): New. (diagnostic_context::set_prefixing_rule): New. (diagnostic_context::report_diagnostic): Update to support multiple output sinks. (diagnostic_context::report_verbatim): New. (diagnostic_context::emit_diagram): Update to support multiple output sinks. (diagnostic_context::error_recursion): Update to use m_reference_printer. (fancy_abort): Likewise. (diagnostic_context::end_group): Update to support multiple output sinks. (diagnostic_output_format::dump): Implement. (diagnostic_output_format::on_report_verbatim): Likewise. (diagnostic_output_format_init): Drop DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE_2_2_PRERELEASE. (diagnostic_context::set_diagnostic_buffer): Reimplement to support multiple output sinks. (diagnostic_context::clear_diagnostic_buffer): Likewise. (diagnostic_context::flush_diagnostic_buffer): Likewise. (diagnostic_buffer::diagnostic_buffer): Initialize m_per_format_buffers. (diagnostic_buffer::~diagnostic_buffer): New dtor. (diagnostic_buffer::dump): Reimplement to support multiple output sinks. (diagnostic_buffer::empty_p): Likewise. (diagnostic_buffer::move_to): Likewise. (diagnostic_buffer::ensure_per_format_buffer): Likewise, renaming to... (diagnostic_buffer::ensure_per_format_buffers): ...this. * diagnostic.h (DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE_2_2_PRERELEASE): Delete. (class diagnostic_context): Add friend class diagnostic_buffer. (diagnostic_context::set_pretty_printer): New decl. (diagnostic_context::refresh_output_sinks): New decl. (diagnostic_context::report_verbatim): New decl. (diagnostic_context::get_output_format): Drop. (diagnostic_context::set_show_highlight_colors): Drop body. (diagnostic_context::set_format_decoder): New decl. (diagnostic_context::set_prefixing_rule): New decl. (diagnostic_context::clone_printer): Reimplement. (diagnostic_context::get_reference_printer): New accessor. (diagnostic_context::add_sink): New decl. (diagnostic_context::supports_fnotice_on_stderr_p): New decl. (diagnostic_context::m_printer): Replace with... (diagnostic_context::m_reference_printer): ...this, and make private. (diagnostic_context::m_output_format): Replace with... (diagnostic_context::m_output_sinks): ...this. (diagnostic_format_decoder): Delete. (diagnostic_prefixing_rule): Delete. (diagnostic_ready_p): Delete. * doc/invoke.texi: Document -fdiagnostics-add-output= and -fdiagnostics-set-output=. * gcc.cc: Include "opts-diagnostic.h". (driver_handle_option): Handle cases OPT_fdiagnostics_add_output_ and OPT_fdiagnostics_set_output_. * opts-diagnostic.cc: New file. * opts-diagnostic.h (handle_OPT_fdiagnostics_add_output_): New decl. (handle_OPT_fdiagnostics_set_output_): New decl. * opts-global.cc (init_options_once): Update for global_dc's m_printer becoming reference printer. Call global_dc->refresh_output_sinks. * opts.cc (common_handle_option): Replace use of diagnostic_prefixing_rule with dc->set_prefixing_rule. Handle cases OPT_fdiagnostics_add_output_ and OPT_fdiagnostics_set_output_. Update for m_printer becoming reference printer. * selftest-diagnostic.cc (selftest::test_diagnostic_context::test_diagnostic_context): Update for m_printer becoming reference printer. (test_diagnostic_context::test_show_locus): Likewise. * selftest-run-tests.cc (selftest::run_tests): Call selftest::opts_diagnostic_cc_tests. * selftest.h (selftest::opts_diagnostic_cc_tests): New decl. * simple-diagnostic-path.cc (selftest::simple_diagnostic_path_cc_tests): Use reference printer. * toplev.cc (announce_function): Update for global_dc's m_printer becoming reference printer. (toplev::main): Likewise. * tree-diagnostic.cc (tree_diagnostics_defaults): Replace use of diagnostic_format_decoder with context->set_format_decoder. * tree-diagnostic.h (tree_dump_pretty_printer::tree_dump_pretty_printer): Update for global_dc's m_printer becoming reference printer. * tree.cc (escaped_string::escape): Likewise. (selftest::test_escaped_strings): Likewise. gcc/ada/ChangeLog: PR other/116613 * gcc-interface/misc.cc (internal_error_function): Update for m_printer becoming reference printer. gcc/analyzer/ChangeLog: PR other/116613 * analyzer-language.cc (on_finish_translation_unit): Update for m_printer becoming reference printer. * engine.cc (run_checkers): Likewise. * program-point.cc (function_point::print_source_line): Likewise. gcc/c-family/ChangeLog: PR other/116613 * c-format.cc (selftest::test_type_mismatch_range_labels): Update for m_printer becoming reference printer. (selftest::test_type_mismatch_range_labels): Likewise. gcc/c/ChangeLog: PR other/116613 * c-objc-common.cc: Include "make-unique.h". (c_initialize_diagnostics): Use unique_ptr for pretty_printer. Use context->set_format_decoder. gcc/cp/ChangeLog: PR other/116613 * error.cc (cxx_initialize_diagnostics): Use unique_ptr for pretty_printer. Use context->set_format_decoder. * module.cc (noisy_p): Update for global_dc's m_printer becoming reference printer. gcc/d/ChangeLog: PR other/116613 * d-diagnostic.cc (d_diagnostic_report_diagnostic): Update for m_printer becoming reference printer. gcc/fortran/ChangeLog: PR other/116613 * error.cc (gfc_diagnostic_build_kind_prefix): Update for global_dc's m_printer becoming reference printer. (gfc_diagnostics_init): Replace usage of diagnostic_format_decoder with global_dc->set_format_decoder. gcc/jit/ChangeLog: PR other/116613 * dummy-frontend.cc: Include "make-unique.h". (class jit_diagnostic_listener): New. (jit_begin_diagnostic): Update comment. (jit_end_diagnostic): Drop call to add_diagnostic. (jit_langhook_init): Set the output format to a new jit_diagnostic_listener. * jit-playback.cc (playback::context::add_diagnostic): Add "text" param and use that rather than trying to get the text from a pretty_printer. * jit-playback.h (playback::context::add_diagnostic): Add "text" param. gcc/testsuite/ChangeLog: PR other/116613 * gcc.dg/plugin/analyzer_cpython_plugin.c (dump_refcnt_info): Update for global_dc's m_printer becoming reference printer. * gcc.dg/plugin/crash-test-ice-in-header-sarif-2.2.c: Replace usage of -fdiagnostics-format=sarif-file-2.2-prerelease with -fdiagnostics-set-output=sarif:version=2.2-prerelease. * gcc.dg/plugin/diagnostic_plugin_test_paths.c: Update for global_dc's m_printer becoming reference printer. * gcc.dg/plugin/diagnostic_plugin_xhtml_format.c: Update for changes to output formats. * gcc.dg/plugin/expensive_selftests_plugin.c: Update for global_dc's m_printer becoming reference printer. * gcc.dg/sarif-output/add-output-sarif-defaults.c: New test. * gcc.dg/sarif-output/bad-binary-op.c: New test. * gcc.dg/sarif-output/bad-binary-op.py: New support script. * gcc.dg/sarif-output/multiple-outputs.c: New test. * gcc.dg/sarif-output/multiple-outputs.py: New support script. * lib/scansarif.exp (verify-sarif-file): Add an optional second argument specifying the expected filename of the .sarif file. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/jit')
-rw-r--r--gcc/jit/dummy-frontend.cc62
-rw-r--r--gcc/jit/jit-playback.cc8
-rw-r--r--gcc/jit/jit-playback.h2
3 files changed, 56 insertions, 16 deletions
diff --git a/gcc/jit/dummy-frontend.cc b/gcc/jit/dummy-frontend.cc
index 1216782..35475b5 100644
--- a/gcc/jit/dummy-frontend.cc
+++ b/gcc/jit/dummy-frontend.cc
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "target.h"
#include "diagnostic-format-text.h"
+#include "make-unique.h"
#include <mpfr.h>
@@ -981,6 +982,49 @@ struct ggc_root_tab jit_root_tab[] =
LAST_GGC_ROOT_TAB
};
+/* Subclass of diagnostic_output_format for libgccjit: like text
+ output, but capture the message and call add_diagnostic with it
+ on the active playback context. */
+
+class jit_diagnostic_listener : public diagnostic_text_output_format
+{
+public:
+ jit_diagnostic_listener (diagnostic_context &dc,
+ gcc::jit::playback::context &playback_ctxt)
+ : diagnostic_text_output_format (dc),
+ m_playback_ctxt (playback_ctxt)
+ {
+ }
+
+ void dump (FILE *out, int indent) const final override
+ {
+ fprintf (out, "%*sjit_diagnostic_listener\n", indent, "");
+ fprintf (out, "%*sm_playback_context: %p\n",
+ indent + 2, "",
+ (void *)&m_playback_ctxt);
+ }
+
+ void on_report_diagnostic (const diagnostic_info &info,
+ diagnostic_t orig_diag_kind)
+ {
+ JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
+
+ /* Let the text output format do most of the work. */
+ diagnostic_text_output_format::on_report_diagnostic (info, orig_diag_kind);
+
+ const char *text = pp_formatted_text (get_printer ());
+
+ /* Delegate to the playback context (and thence to the
+ recording context). */
+ gcc::jit::active_playback_ctxt->add_diagnostic (text, info);
+
+ pp_clear_output_area (get_printer ());
+ }
+
+private:
+ gcc::jit::playback::context &m_playback_ctxt;
+};
+
/* JIT-specific implementation of diagnostic callbacks. */
/* Implementation of "begin_diagnostic". */
@@ -992,24 +1036,22 @@ jit_begin_diagnostic (diagnostic_text_output_format &,
gcc_assert (gcc::jit::active_playback_ctxt);
JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
- /* No-op (apart from logging); the real error-handling is done in the
- "end_diagnostic" hook. */
+ /* No-op (apart from logging); the real error-handling is done by the
+ jit_diagnostic_listener. */
}
/* Implementation of "end_diagnostic". */
static void
-jit_end_diagnostic (diagnostic_text_output_format &text_output,
- const diagnostic_info *diagnostic,
+jit_end_diagnostic (diagnostic_text_output_format &,
+ const diagnostic_info *,
diagnostic_t)
{
gcc_assert (gcc::jit::active_playback_ctxt);
JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
- /* Delegate to the playback context (and thence to the
- recording context). */
- gcc_assert (diagnostic);
- gcc::jit::active_playback_ctxt->add_diagnostic (&text_output.get_context (), *diagnostic); // FIXME
+ /* No-op (apart from logging); the real error-handling is done by the
+ jit_diagnostic_listener. */
}
/* Language hooks. */
@@ -1030,6 +1072,10 @@ jit_langhook_init (void)
gcc_assert (global_dc);
diagnostic_text_starter (global_dc) = jit_begin_diagnostic;
diagnostic_text_finalizer (global_dc) = jit_end_diagnostic;
+ auto sink
+ = ::make_unique<jit_diagnostic_listener> (*global_dc,
+ *gcc::jit::active_playback_ctxt);
+ global_dc->set_output_format (std::move (sink));
build_common_tree_nodes (false);
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index e732c22..8dd77e4 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -3687,14 +3687,9 @@ add_error_va (location *loc, const char *fmt, va_list ap)
void
playback::context::
-add_diagnostic (diagnostic_context *diag_context,
+add_diagnostic (const char *text,
const diagnostic_info &diagnostic)
{
- /* At this point the text has been formatted into the pretty-printer's
- output buffer. */
- pretty_printer *pp = diag_context->m_printer;
- const char *text = pp_formatted_text (pp);
-
/* Get location information (if any) from the diagnostic.
The recording::context::add_error[_va] methods require a
recording::location. We can't lookup the playback::location
@@ -3714,7 +3709,6 @@ add_diagnostic (diagnostic_context *diag_context,
}
m_recording_ctxt->add_error (rec_loc, "%s", text);
- pp_clear_output_area (pp);
}
/* Dealing with the linemap API. */
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 6e97b38..77ae2ad 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -276,7 +276,7 @@ public:
get_first_error () const;
void
- add_diagnostic (diagnostic_context *context,
+ add_diagnostic (const char *text,
const diagnostic_info &diagnostic);
void