diff options
author | David Malcolm <dmalcolm@redhat.com> | 2024-10-29 19:12:02 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2024-10-29 19:12:02 -0400 |
commit | 0b73e9382ab51c00a79b2a6f8abbcd31d87f6814 (patch) | |
tree | 34a863f1635b75d45e8426c6803b45cfd6f2b152 /gcc/jit | |
parent | 3d8cd34a450e9ffe2b2ac8a0c8eb33fd5d613483 (diff) | |
download | gcc-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.cc | 62 | ||||
-rw-r--r-- | gcc/jit/jit-playback.cc | 8 | ||||
-rw-r--r-- | gcc/jit/jit-playback.h | 2 |
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 |