diff options
| author | David Malcolm <dmalcolm@redhat.com> | 2025-06-23 18:46:51 -0400 |
|---|---|---|
| committer | David Malcolm <dmalcolm@redhat.com> | 2025-06-23 18:51:10 -0400 |
| commit | d0142e147486e6f319704d35930720f6dec648fb (patch) | |
| tree | 5d9039156c74a13c5b63b2793a6a2ba945bcf124 /gcc/diagnostic-output-spec.h | |
| parent | e6406aefd1a25b6dba845a52cfd9484188ff5720 (diff) | |
| download | gcc-d0142e147486e6f319704d35930720f6dec648fb.zip gcc-d0142e147486e6f319704d35930720f6dec648fb.tar.gz gcc-d0142e147486e6f319704d35930720f6dec648fb.tar.bz2 | |
libgdiagnostics: sarif-replay: add extra sinks via -fdiagnostics-add-output= [PR116792,PR116163]
This patch refactors the support for -fdiagnostics-add-output=SCHEME
from GCC's options parsing so that it is also available to
sarif-replay and to other clients of libgdiagnostics.
With this users of sarif-replay and other such tools can generate HTML
or SARIF as well as text output, using the same
-fdiagnostics-add-output=SCHEME
as GCC.
As a test, the patch adds support for this option to the dg-lint
script below "contrib". For example dg-lint can now generate text,
html, and sarif output via:
LD_LIBRARY_PATH=../build/gcc/ \
./contrib/dg-lint/dg-lint \
contrib/dg-lint/test-*.c \
-fdiagnostics-add-output=experimental-html:file=dg-lint-tests.html \
-fdiagnostics-add-output=sarif:file=dg-lint-tests.sarif
where the HTML output from dg-lint can be seen here:
https://dmalcolm.fedorapeople.org/gcc/2025-06-20/dg-lint-tests.html
the sarif output here:
https://dmalcolm.fedorapeople.org/gcc/2025-06-23/dg-lint-tests.sarif
and a screenshot of VS Code viewing the sarif output is here:
https://dmalcolm.fedorapeople.org/gcc/2025-06-23/vscode-viewing-dg-lint-sarif-output.png
As well as allowing sarif-replay to generate HTML, this patch allows
sarif-replay to also generate SARIF. Ideally this would faithfully
round-trip all the data, but it's not perfect (which I'm tracking as
PR sarif-replay/120792).
contrib/ChangeLog:
PR other/116792
PR testsuite/116163
PR sarif-replay/120792
* dg-lint/dg-lint: Add -fdiagnostics-add-output.
* dg-lint/libgdiagnostics.py: Add
diagnostic_manager_add_sink_from_spec.
(Manager.add_sink_from_spec): New.
gcc/ChangeLog:
PR other/116792
PR testsuite/116163
PR sarif-replay/120792
* Makefile.in (OBJS-libcommon): Add diagnostic-output-spec.o.
* diagnostic-format-html.cc (html_builder::html_builder): Ensure
title is non-empty.
* diagnostic-output-spec.cc: New file, taken from material in
opts-diagnostic.cc.
* diagnostic-output-spec.h: New file.
* diagnostic.cc (diagnostic_context::set_main_input_filename):
New.
* diagnostic.h (diagnostic_context::set_main_input_filename): New
decl.
* doc/libgdiagnostics/topics/compatibility.rst
(LIBGDIAGNOSTICS_ABI_2): New.
* doc/libgdiagnostics/topics/diagnostic-manager.rst
(diagnostic_manager_add_sink_from_spec): New.
(diagnostic_manager_set_analysis_target): New.
* libgdiagnostics++.h (manager::add_sink_from_spec): New.
(manager::set_analysis_target): New.
* libgdiagnostics.cc: Include "diagnostic-output-spec.h".
(struct spec_context): New.
(diagnostic_manager_add_sink_from_spec): New.
(diagnostic_manager_set_analysis_target): New.
* libgdiagnostics.h
(LIBDIAGNOSTICS_HAVE_diagnostic_manager_add_sink_from_spec): New
define.
(diagnostic_manager_add_sink_from_spec): New decl.
(LIBDIAGNOSTICS_HAVE_diagnostic_manager_set_analysis_target): New
define.
(diagnostic_manager_set_analysis_target): New decl.
* libgdiagnostics.map (LIBGDIAGNOSTICS_ABI_2): New.
* libsarifreplay.cc (sarif_replayer::handle_artifact_obj): Looks
for "analysisTarget" in roles and call set_analysis_target using
the artifact if found.
* opts-diagnostic.cc: Refactor, moving material to
diagnostic-output-spec.cc.
(struct opt_spec_context): New.
(handle_OPT_fdiagnostics_add_output_): Use opt_spec_context.
(handle_OPT_fdiagnostics_set_output_): Likewise.
* sarif-replay.cc: Define INCLUDE_STRING.
(struct options): Add m_extra_output_specs.
(usage_msg): Add -fdiagnostics-add-output=SCHEME.
(str_starts_with): New.
(parse_options): Add -fdiagnostics-add-output=SCHEME.
(main): Likewise.
* selftest-run-tests.cc (selftest::run_tests): Call
diagnostic_output_spec_cc_tests rather than
opts_diagnostic_cc_tests.
* selftest.h (selftest::diagnostic_output_spec_cc_tests):
Replace...
(selftest::opts_diagnostic_cc_tests): ...this.
gcc/testsuite/ChangeLog:
PR other/116792
PR testsuite/116163
PR sarif-replay/120792
* sarif-replay.dg/2.1.0-valid/signal-1-check-html.py: New test
script.
* sarif-replay.dg/2.1.0-valid/signal-1.c.sarif: Add html and sarif
generation to options. Invoke the new script to verify that HTML
and SARIF is generated.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/diagnostic-output-spec.h')
| -rw-r--r-- | gcc/diagnostic-output-spec.h | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/gcc/diagnostic-output-spec.h b/gcc/diagnostic-output-spec.h new file mode 100644 index 0000000..e02cdfe --- /dev/null +++ b/gcc/diagnostic-output-spec.h @@ -0,0 +1,116 @@ +/* Support for the DSL of -fdiagnostics-add-output= and + -fdiagnostics-set-output=. + Copyright (C) 2024-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_DIAGNOSTIC_OUTPUT_SPEC_H +#define GCC_DIAGNOSTIC_OUTPUT_SPEC_H + +#include "diagnostic-format.h" +#include "diagnostic-output-file.h" + +namespace diagnostics_output_spec { + +/* An abstract base class for handling the DSL of -fdiagnostics-add-output= + and -fdiagnostics-set-output=. */ + +class context +{ + public: + std::unique_ptr<diagnostic_output_format> + parse_and_make_sink (const char *, + diagnostic_context &dc); + + void + report_error (const char *gmsgid, ...) const + ATTRIBUTE_GCC_DIAG(2,3); + + void + report_unknown_key (const char *unparsed_arg, + const std::string &key, + const std::string &scheme_name, + auto_vec<const char *> &known_keys) const; + + void + report_missing_key (const char *unparsed_arg, + const std::string &key, + const std::string &scheme_name, + const char *metavar) const; + + diagnostic_output_file + open_output_file (label_text &&filename) const; + + const char * + get_option_name () const { return m_option_name; } + + line_maps * + get_affected_location_mgr () const { return m_affected_location_mgr; } + + virtual ~context () {} + + virtual void + report_error_va (const char *gmsgid, va_list *ap) const = 0; + + virtual const char * + get_base_filename () const = 0; + +protected: + context (const char *option_name, + line_maps *affected_location_mgr) + : m_option_name (option_name), + m_affected_location_mgr (affected_location_mgr) + { + } + + const char *m_option_name; + line_maps *m_affected_location_mgr; +}; + +/* A subclass that implements reporting errors via a diagnostic_context. */ + +struct gcc_spec_context : public diagnostics_output_spec::context +{ +public: + gcc_spec_context (diagnostic_context &dc, + line_maps *affected_location_mgr, + line_maps *control_location_mgr, + location_t loc, + const char *option_name) + : context (option_name, affected_location_mgr), + m_dc (dc), + m_control_location_mgr (control_location_mgr), + m_loc (loc) + {} + + void report_error_va (const char *gmsgid, va_list *ap) const final override + ATTRIBUTE_GCC_DIAG(2, 0) + { + m_dc.begin_group (); + rich_location richloc (m_control_location_mgr, m_loc); + m_dc.diagnostic_impl (&richloc, nullptr, -1, gmsgid, ap, DK_ERROR); + m_dc.end_group (); + } + + diagnostic_context &m_dc; + line_maps *m_control_location_mgr; + location_t m_loc; +}; + +} // namespace diagnostics_output_spec + +#endif |
