diff options
author | David Malcolm <dmalcolm@redhat.com> | 2023-10-02 12:16:55 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2023-10-02 12:16:55 -0400 |
commit | 140820265d96b0d115ade21235f8b8017fde9a5a (patch) | |
tree | 45e50166cafdee536b20ea2dec572a501554da26 /gcc/diagnostic-format-sarif.cc | |
parent | c5c565eff6277ac176d6c5c94f55859d0eb28938 (diff) | |
download | gcc-140820265d96b0d115ade21235f8b8017fde9a5a.zip gcc-140820265d96b0d115ade21235f8b8017fde9a5a.tar.gz gcc-140820265d96b0d115ade21235f8b8017fde9a5a.tar.bz2 |
diagnostics: add diagnostic_output_format class
Eliminate various global variables in the json/sarif output code by
bundling together callbacks and state into a new diagnostic_output_format
class, with per-output-format subclasses.
No functional change intended.
gcc/ChangeLog:
* diagnostic-format-json.cc (toplevel_array): Remove global in
favor of json_output_format::m_top_level_array.
(cur_group): Likewise, for json_output_format::m_cur_group.
(cur_children_array): Likewise, for
json_output_format::m_cur_children_array.
(class json_output_format): New.
(json_begin_diagnostic): Remove, in favor of
json_output_format::on_begin_diagnostic.
(json_end_diagnostic): Convert to...
(json_output_format::on_end_diagnostic): ...this.
(json_begin_group): Remove, in favor of
json_output_format::on_begin_group.
(json_end_group): Remove, in favor of
json_output_format::on_end_group.
(json_flush_to_file): Remove, in favor of
json_output_format::flush_to_file.
(json_stderr_final_cb): Remove, in favor of json_output_format
dtor.
(json_output_base_file_name): Remove global.
(class json_stderr_output_format): New.
(json_file_final_cb): Remove.
(class json_file_output_format): New.
(json_emit_diagram): Remove.
(diagnostic_output_format_init_json): Update.
(diagnostic_output_format_init_json_file): Update.
* diagnostic-format-sarif.cc (the_builder): Remove this global,
moving to a field of the sarif_output_format.
(sarif_builder::maybe_make_artifact_content_object): Use the
context's m_file_cache.
(get_source_lines): Convert to...
(sarif_builder::get_source_lines): ...this, using context's
m_file_cache.
(sarif_begin_diagnostic): Remove, in favor of
sarif_output_format::on_begin_diagnostic.
(sarif_end_diagnostic): Remove, in favor of
sarif_output_format::on_end_diagnostic.
(sarif_begin_group): Remove, in favor of
sarif_output_format::on_begin_group.
(sarif_end_group): Remove, in favor of
sarif_output_format::on_end_group.
(sarif_flush_to_file): Delete.
(sarif_stderr_final_cb): Delete.
(sarif_output_base_file_name): Delete.
(sarif_file_final_cb): Delete.
(class sarif_output_format): New.
(sarif_emit_diagram): Delete.
(class sarif_stream_output_format): New.
(class sarif_file_output_format): New.
(diagnostic_output_format_init_sarif): Update.
(diagnostic_output_format_init_sarif_stderr): Update.
(diagnostic_output_format_init_sarif_file): Update.
(diagnostic_output_format_init_sarif_stream): Update.
* diagnostic-show-locus.cc (diagnostic_show_locus): Update.
* diagnostic.cc (default_diagnostic_final_cb): Delete, moving to
diagnostic_text_output_format's dtor.
(diagnostic_initialize): Update, making a new instance of
diagnostic_text_output_format.
(diagnostic_finish): Delete m_output_format, rather than calling
final_cb.
(diagnostic_report_diagnostic): Assert that m_output_format is
non-NULL. Replace call to begin_group_cb with call to
m_output_format->on_begin_group. Replace call to
diagnostic_starter with call to
m_output_format->on_begin_diagnostic. Replace call to
diagnostic_finalizer with call to
m_output_format->on_end_diagnostic.
(diagnostic_emit_diagram): Replace both optional call to
m_diagrams.m_emission_cb and default implementation with call to
m_output_format->on_diagram. Move default implementation to
diagnostic_text_output_format::on_diagram.
(auto_diagnostic_group::~auto_diagnostic_group): Replace call to
end_group_cb with call to m_output_format->on_end_group.
(diagnostic_text_output_format::~diagnostic_text_output_format):
New, based on default_diagnostic_final_cb.
(diagnostic_text_output_format::on_begin_diagnostic): New, based
on code from diagnostic_report_diagnostic.
(diagnostic_text_output_format::on_end_diagnostic): Likewise.
(diagnostic_text_output_format::on_diagram): New, based on code
from diagnostic_emit_diagram.
* diagnostic.h (class diagnostic_output_format): New.
(class diagnostic_text_output_format): New.
(diagnostic_context::begin_diagnostic): Move to...
(diagnostic_context::m_text_callbacks::begin_diagnostic): ...here.
(diagnostic_context::start_span): Move to...
(diagnostic_context::m_text_callbacks::start_span): ...here.
(diagnostic_context::end_diagnostic): Move to...
(diagnostic_context::m_text_callbacks::end_diagnostic): ...here.
(diagnostic_context::begin_group_cb): Remove, in favor of
m_output_format->on_begin_group.
(diagnostic_context::end_group_cb): Remove, in favor of
m_output_format->on_end_group.
(diagnostic_context::final_cb): Remove, in favor of
m_output_format's dtor.
(diagnostic_context::m_output_format): New field.
(diagnostic_context::m_diagrams.m_emission_cb): Remove, in favor
of m_output_format->on_diagram.
(diagnostic_starter): Update.
(diagnostic_finalizer): Update.
(diagnostic_output_format_init_sarif_stream): New.
* input.cc (location_get_source_line): Move implementation apart from
call to diagnostic_file_cache_init to...
(file_cache::get_source_line): ...this new function...
(location_get_source_line): ...and reintroduce, rewritten in terms of
file_cache::get_source_line.
(get_source_file_content): Likewise, refactor into...
(file_cache::get_source_file_content): ...this new function.
* input.h (file_cache::get_source_line): New decl.
(file_cache::get_source_file_content): New decl.
* selftest-diagnostic.cc
(test_diagnostic_context::test_diagnostic_context): Update.
* tree-diagnostic-path.cc (event_range::print): Update for
change to diagnostic_context's start_span callback.
gcc/fortran/ChangeLog:
* error.cc (gfc_diagnostics_init): Update for change to start_span.
gcc/jit/ChangeLog:
* dummy-frontend.cc (jit_langhook_init): Update for change to
diagnostic_context callbacks.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/diagnostic_group_plugin.c
(test_begin_group_cb, test_end_group_cb): Replace with...
(class test_output_format): ...this new subclass.
(plugin_init): Update.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/diagnostic-format-sarif.cc')
-rw-r--r-- | gcc/diagnostic-format-sarif.cc | 212 |
1 files changed, 110 insertions, 102 deletions
diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index f56c4ce..d8cca21 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -215,6 +215,9 @@ private: json::object * make_reporting_descriptor_reference_object_for_cwe_id (int cwe_id); json::object *make_artifact_object (const char *filename); + char *get_source_lines (const char *filename, + int start_line, + int end_line) const; json::object *maybe_make_artifact_content_object (const char *filename) const; json::object *maybe_make_artifact_content_object (const char *filename, int start_line, @@ -248,8 +251,6 @@ private: int m_tabstop; }; -static sarif_builder *the_builder; - /* class sarif_object : public json::object. */ sarif_property_bag & @@ -1540,7 +1541,8 @@ json::object * sarif_builder::maybe_make_artifact_content_object (const char *filename) const { /* Let input.cc handle any charset conversion. */ - char_span utf8_content = get_source_file_content (filename); + char_span utf8_content + = m_context->m_file_cache->get_source_file_content (filename); if (!utf8_content) return NULL; @@ -1558,16 +1560,17 @@ sarif_builder::maybe_make_artifact_content_object (const char *filename) const /* Attempt to read the given range of lines from FILENAME; return a freshly-allocated 0-terminated buffer containing them, or NULL. */ -static char * -get_source_lines (const char *filename, - int start_line, - int end_line) +char * +sarif_builder::get_source_lines (const char *filename, + int start_line, + int end_line) const { auto_vec<char> result; for (int line = start_line; line <= end_line; line++) { - char_span line_content = location_get_source_line (filename, line); + char_span line_content + = m_context->m_file_cache->get_source_line (filename, line); if (!line_content.get_buffer ()) return NULL; result.reserve (line_content.length () + 1); @@ -1680,82 +1683,6 @@ sarif_builder::make_artifact_content_object (const char *text) const return content_obj; } -/* No-op implementation of "begin_diagnostic" for SARIF output. */ - -static void -sarif_begin_diagnostic (diagnostic_context *, diagnostic_info *) -{ -} - -/* Implementation of "end_diagnostic" for SARIF output. */ - -static void -sarif_end_diagnostic (diagnostic_context *context, diagnostic_info *diagnostic, - diagnostic_t orig_diag_kind) -{ - gcc_assert (the_builder); - the_builder->end_diagnostic (context, diagnostic, orig_diag_kind); -} - -/* No-op implementation of "begin_group_cb" for SARIF output. */ - -static void -sarif_begin_group (diagnostic_context *) -{ -} - -/* Implementation of "end_group_cb" for SARIF output. */ - -static void -sarif_end_group (diagnostic_context *) -{ - gcc_assert (the_builder); - the_builder->end_group (); -} - -/* Flush the top-level array to OUTF. */ - -static void -sarif_flush_to_file (FILE *outf) -{ - gcc_assert (the_builder); - the_builder->flush_to_file (outf); - delete the_builder; - the_builder = NULL; -} - -/* Callback for final cleanup for SARIF output to stderr. */ - -static void -sarif_stderr_final_cb (diagnostic_context *) -{ - gcc_assert (the_builder); - sarif_flush_to_file (stderr); -} - -static char *sarif_output_base_file_name; - -/* Callback for final cleanup for SARIF output to a file. */ - -static void -sarif_file_final_cb (diagnostic_context *) -{ - char *filename = concat (sarif_output_base_file_name, ".sarif", NULL); - FILE *outf = fopen (filename, "w"); - if (!outf) - { - const char *errstr = xstrerror (errno); - fnotice (stderr, "error: unable to open '%s' for writing: %s\n", - filename, errstr); - free (filename); - return; - } - gcc_assert (the_builder); - sarif_flush_to_file (outf); - fclose (outf); - free (filename); -} - /* Callback for diagnostic_context::ice_handler_cb for when an ICE occurs. */ @@ -1773,15 +1700,89 @@ sarif_ice_handler (diagnostic_context *context) fnotice (stderr, "Internal compiler error:\n"); } -/* Callback for diagnostic_context::m_diagrams.m_emission_cb. */ +class sarif_output_format : public diagnostic_output_format +{ +public: + void on_begin_group () final override + { + /* No-op, */ + } + void on_end_group () final override + { + m_builder.end_group (); + } + void + on_begin_diagnostic (diagnostic_info *) final override + { + /* No-op, */ + } + void + on_end_diagnostic (diagnostic_info *diagnostic, + diagnostic_t orig_diag_kind) final override + { + m_builder.end_diagnostic (&m_context, diagnostic, orig_diag_kind); + } + void on_diagram (const diagnostic_diagram &diagram) final override + { + m_builder.emit_diagram (&m_context, diagram); + } -static void -sarif_emit_diagram (diagnostic_context *context, - const diagnostic_diagram &diagram) +protected: + sarif_output_format (diagnostic_context &context) + : diagnostic_output_format (context), + m_builder (&context) + {} + + sarif_builder m_builder; +}; + +class sarif_stream_output_format : public sarif_output_format { - gcc_assert (the_builder); - the_builder->emit_diagram (context, diagram); -} +public: + sarif_stream_output_format (diagnostic_context &context, FILE *stream) + : sarif_output_format (context), + m_stream (stream) + { + } + ~sarif_stream_output_format () + { + m_builder.flush_to_file (m_stream); + } +private: + FILE *m_stream; +}; + +class sarif_file_output_format : public sarif_output_format +{ +public: + sarif_file_output_format (diagnostic_context &context, + const char *base_file_name) + : sarif_output_format (context), + m_base_file_name (xstrdup (base_file_name)) + { + } + ~sarif_file_output_format () + { + char *filename = concat (m_base_file_name, ".sarif", NULL); + free (m_base_file_name); + m_base_file_name = nullptr; + FILE *outf = fopen (filename, "w"); + if (!outf) + { + const char *errstr = xstrerror (errno); + fnotice (stderr, "error: unable to open '%s' for writing: %s\n", + filename, errstr); + free (filename); + return; + } + m_builder.flush_to_file (outf); + fclose (outf); + free (filename); + } + +private: + char *m_base_file_name; +}; /* Populate CONTEXT in preparation for SARIF output (either to stderr, or to a file). */ @@ -1789,16 +1790,9 @@ sarif_emit_diagram (diagnostic_context *context, static void diagnostic_output_format_init_sarif (diagnostic_context *context) { - the_builder = new sarif_builder (context); - /* Override callbacks. */ - context->begin_diagnostic = sarif_begin_diagnostic; - context->end_diagnostic = sarif_end_diagnostic; - context->begin_group_cb = sarif_begin_group; - context->end_group_cb = sarif_end_group; context->print_path = NULL; /* handled in sarif_end_diagnostic. */ context->ice_handler_cb = sarif_ice_handler; - context->m_diagrams.m_emission_cb = sarif_emit_diagram; /* The metadata is handled in SARIF format, rather than as text. */ context->show_cwe = false; @@ -1817,7 +1811,8 @@ void diagnostic_output_format_init_sarif_stderr (diagnostic_context *context) { diagnostic_output_format_init_sarif (context); - context->final_cb = sarif_stderr_final_cb; + delete context->m_output_format; + context->m_output_format = new sarif_stream_output_format (*context, stderr); } /* Populate CONTEXT in preparation for SARIF output to a file named @@ -1825,9 +1820,22 @@ diagnostic_output_format_init_sarif_stderr (diagnostic_context *context) void diagnostic_output_format_init_sarif_file (diagnostic_context *context, - const char *base_file_name) + const char *base_file_name) +{ + diagnostic_output_format_init_sarif (context); + delete context->m_output_format; + context->m_output_format = new sarif_file_output_format (*context, + base_file_name); +} + +/* Populate CONTEXT in preparation for SARIF output to STREAM. */ + +void +diagnostic_output_format_init_sarif_stream (diagnostic_context *context, + FILE *stream) { diagnostic_output_format_init_sarif (context); - context->final_cb = sarif_file_final_cb; - sarif_output_base_file_name = xstrdup (base_file_name); + delete context->m_output_format; + context->m_output_format = new sarif_stream_output_format (*context, + stream); } |