diff options
Diffstat (limited to 'gcc/diagnostic-format-sarif.cc')
-rw-r--r-- | gcc/diagnostic-format-sarif.cc | 107 |
1 files changed, 100 insertions, 7 deletions
diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index fd29ac2..5e48398 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" +#define INCLUDE_VECTOR #include "system.h" #include "coretypes.h" #include "diagnostic.h" @@ -29,6 +30,8 @@ along with GCC; see the file COPYING3. If not see #include "cpplib.h" #include "logical-location.h" #include "diagnostic-client-data-hooks.h" +#include "diagnostic-diagram.h" +#include "text-art/canvas.h" class sarif_builder; @@ -66,8 +69,13 @@ public: diagnostic_info *diagnostic, diagnostic_t orig_diag_kind, sarif_builder *builder); + void on_diagram (diagnostic_context *context, + const diagnostic_diagram &diagram, + sarif_builder *builder); private: + void add_related_location (json::object *location_obj); + json::array *m_related_locations_arr; }; @@ -135,7 +143,8 @@ public: void end_diagnostic (diagnostic_context *context, diagnostic_info *diagnostic, diagnostic_t orig_diag_kind); - + void emit_diagram (diagnostic_context *context, + const diagnostic_diagram &diagram); void end_group (); void flush_to_file (FILE *outf); @@ -144,6 +153,9 @@ public: json::object *make_location_object (const rich_location &rich_loc, const logical_location *logical_loc); json::object *make_message_object (const char *msg) const; + json::object * + make_message_object_for_diagram (diagnostic_context *context, + const diagnostic_diagram &diagram); private: sarif_result *make_result_object (diagnostic_context *context, @@ -261,12 +273,6 @@ sarif_result::on_nested_diagnostic (diagnostic_context *context, diagnostic_t /*orig_diag_kind*/, sarif_builder *builder) { - if (!m_related_locations_arr) - { - m_related_locations_arr = new json::array (); - set ("relatedLocations", m_related_locations_arr); - } - /* We don't yet generate meaningful logical locations for notes; sometimes these will related to current_function_decl, but often they won't. */ @@ -277,6 +283,39 @@ sarif_result::on_nested_diagnostic (diagnostic_context *context, pp_clear_output_area (context->printer); location_obj->set ("message", message_obj); + add_related_location (location_obj); +} + +/* Handle diagrams that occur within a diagnostic group. + The closest thing in SARIF seems to be to add a location to the + "releatedLocations" property (SARIF v2.1.0 section 3.27.22), + and to put the diagram into the "message" property of that location + (SARIF v2.1.0 section 3.28.5). */ + +void +sarif_result::on_diagram (diagnostic_context *context, + const diagnostic_diagram &diagram, + sarif_builder *builder) +{ + json::object *location_obj = new json::object (); + json::object *message_obj + = builder->make_message_object_for_diagram (context, diagram); + location_obj->set ("message", message_obj); + + add_related_location (location_obj); +} + +/* Add LOCATION_OBJ to this result's "relatedLocations" array, + creating it if it doesn't yet exist. */ + +void +sarif_result::add_related_location (json::object *location_obj) +{ + if (!m_related_locations_arr) + { + m_related_locations_arr = new json::array (); + set ("relatedLocations", m_related_locations_arr); + } m_related_locations_arr->append (location_obj); } @@ -348,6 +387,18 @@ sarif_builder::end_diagnostic (diagnostic_context *context, } } +/* Implementation of diagnostic_context::m_diagrams.m_emission_cb + for SARIF output. */ + +void +sarif_builder::emit_diagram (diagnostic_context *context, + const diagnostic_diagram &diagram) +{ + /* We must be within the emission of a top-level diagnostic. */ + gcc_assert (m_cur_group_result); + m_cur_group_result->on_diagram (context, diagram, this); +} + /* Implementation of "end_group_cb" for SARIF output. */ void @@ -1115,6 +1166,37 @@ sarif_builder::make_message_object (const char *msg) const return message_obj; } +/* Make a message object (SARIF v2.1.0 section 3.11) for DIAGRAM. + We emit the diagram as a code block within the Markdown part + of the message. */ + +json::object * +sarif_builder::make_message_object_for_diagram (diagnostic_context *context, + const diagnostic_diagram &diagram) +{ + json::object *message_obj = new json::object (); + + /* "text" property (SARIF v2.1.0 section 3.11.8). */ + message_obj->set ("text", new json::string (diagram.get_alt_text ())); + + char *saved_prefix = pp_take_prefix (context->printer); + pp_set_prefix (context->printer, NULL); + + /* "To produce a code block in Markdown, simply indent every line of + the block by at least 4 spaces or 1 tab." + Here we use 4 spaces. */ + diagram.get_canvas ().print_to_pp (context->printer, " "); + pp_set_prefix (context->printer, saved_prefix); + + /* "markdown" property (SARIF v2.1.0 section 3.11.9). */ + message_obj->set ("markdown", + new json::string (pp_formatted_text (context->printer))); + + pp_clear_output_area (context->printer); + + return message_obj; +} + /* Make a multiformatMessageString object (SARIF v2.1.0 section 3.12) for MSG. */ @@ -1630,6 +1712,16 @@ sarif_ice_handler (diagnostic_context *context) fnotice (stderr, "Internal compiler error:\n"); } +/* Callback for diagnostic_context::m_diagrams.m_emission_cb. */ + +static void +sarif_emit_diagram (diagnostic_context *context, + const diagnostic_diagram &diagram) +{ + gcc_assert (the_builder); + the_builder->emit_diagram (context, diagram); +} + /* Populate CONTEXT in preparation for SARIF output (either to stderr, or to a file). */ @@ -1645,6 +1737,7 @@ diagnostic_output_format_init_sarif (diagnostic_context *context) 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; |