aboutsummaryrefslogtreecommitdiff
path: root/gcc/diagnostic-format-sarif.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2023-10-02 12:16:55 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2023-10-02 12:16:55 -0400
commit140820265d96b0d115ade21235f8b8017fde9a5a (patch)
tree45e50166cafdee536b20ea2dec572a501554da26 /gcc/diagnostic-format-sarif.cc
parentc5c565eff6277ac176d6c5c94f55859d0eb28938 (diff)
downloadgcc-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.cc212
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);
}