diff options
Diffstat (limited to 'gcc/libgdiagnostics.cc')
-rw-r--r-- | gcc/libgdiagnostics.cc | 340 |
1 files changed, 338 insertions, 2 deletions
diff --git a/gcc/libgdiagnostics.cc b/gcc/libgdiagnostics.cc index 74814c7..04812dc 100644 --- a/gcc/libgdiagnostics.cc +++ b/gcc/libgdiagnostics.cc @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #define INCLUDE_MAP +#define INCLUDE_STRING #define INCLUDE_VECTOR #include "system.h" #include "coretypes.h" @@ -32,9 +33,12 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-format-sarif.h" #include "diagnostic-format-text.h" #include "diagnostic-output-spec.h" +#include "diagnostic-digraphs.h" +#include "diagnostic-state-graphs.h" #include "logical-location.h" #include "edit-context.h" #include "libgdiagnostics.h" +#include "libgdiagnostics-private.h" class owned_nullable_string { @@ -644,6 +648,9 @@ public: return m_prev_diag_logical_loc; } + void + take_global_graph (std::unique_ptr<diagnostic_graph> graph); + private: void ensure_linemap_for_file_and_line (const diagnostic_file *file, @@ -743,17 +750,53 @@ private: owned_nullable_string m_url; }; +struct diagnostic_graph : public diagnostics::digraphs::digraph +{ + diagnostic_graph (diagnostic_manager &) {} + + diagnostic_node * + add_node_with_id (std::string id, + diagnostic_node *parent_node); + diagnostic_edge * + add_edge_with_label (const char *id, + diagnostic_node &src_node, + diagnostic_node &dst_node, + const char *label); +}; + +struct diagnostic_node : public diagnostics::digraphs::node +{ + diagnostic_node (diagnostic_graph &g, + std::string id) + : node (g, std::move (id)) + { + } +}; + +struct diagnostic_edge : public diagnostics::digraphs::edge +{ + diagnostic_edge (diagnostic_graph &g, + const char *id, + diagnostic_node &src_node, + diagnostic_node &dst_node) + : edge (g, id, src_node, dst_node) + { + } +}; + class libgdiagnostics_path_event : public diagnostic_event { public: libgdiagnostics_path_event (const diagnostic_physical_location *physical_loc, const diagnostic_logical_location *logical_loc, unsigned stack_depth, + std::unique_ptr<diagnostic_graph> state_graph, const char *gmsgid, va_list *args) : m_physical_loc (physical_loc), m_logical_loc (logical_loc), - m_stack_depth (stack_depth) + m_stack_depth (stack_depth), + m_state_graph (std::move (state_graph)) { m_desc_uncolored = make_desc (gmsgid, args, false); m_desc_colored = make_desc (gmsgid, args, true); @@ -799,6 +842,15 @@ public: return 0; } + std::unique_ptr<diagnostics::digraphs::digraph> + maybe_make_diagnostic_state_graph (bool) const final override + { + if (!m_state_graph) + return nullptr; + + return m_state_graph->clone (); + } + private: static label_text make_desc (const char *gmsgid, va_list *args, @@ -824,6 +876,7 @@ private: const diagnostic_physical_location *m_physical_loc; const diagnostic_logical_location *m_logical_loc; unsigned m_stack_depth; + std::unique_ptr<diagnostic_graph> m_state_graph; label_text m_desc_uncolored; label_text m_desc_colored; }; @@ -855,6 +908,7 @@ struct diagnostic_execution_path : public diagnostic_path add_event_va (const diagnostic_physical_location *physical_loc, const diagnostic_logical_location *logical_loc, unsigned stack_depth, + std::unique_ptr<diagnostic_graph> state_graph, const char *gmsgid, va_list *args) { @@ -862,6 +916,7 @@ struct diagnostic_execution_path : public diagnostic_path (std::make_unique<libgdiagnostics_path_event> (physical_loc, logical_loc, stack_depth, + std::move (state_graph), gmsgid, args)); return m_events.size () - 1; @@ -902,6 +957,27 @@ private: std::vector<std::unique_ptr<libgdiagnostics_path_event>> m_events; }; +class prebuilt_digraphs : public diagnostics::digraphs::lazy_digraphs +{ +public: + using digraph = diagnostics::digraphs::digraph; + + std::unique_ptr<std::vector<std::unique_ptr<digraph>>> + create_digraphs () const final override + { + return std::make_unique<std::vector<std::unique_ptr<digraph>>> (std::move (m_digraphs)); + } + + void + take_graph (std::unique_ptr<diagnostic_graph> graph) + { + m_digraphs.push_back (std::move (graph)); + } + +private: + mutable std::vector<std::unique_ptr<digraph>> m_digraphs; +}; + /* This has to be a "struct" as it is exposed in the C API. */ struct diagnostic @@ -914,7 +990,9 @@ public: m_rich_loc (diag_mgr.get_line_table ()), m_logical_loc (nullptr), m_path (nullptr) - {} + { + m_metadata.set_lazy_digraphs (&m_graphs); + } diagnostic_manager &get_manager () const { @@ -990,12 +1068,25 @@ public: m_rich_loc.set_path (path); } + void + take_graph (std::unique_ptr<diagnostic_graph> graph) + { + m_graphs.take_graph (std::move (graph)); + } + + const prebuilt_digraphs & + get_graphs () const + { + return m_graphs; + } + private: diagnostic_manager &m_diag_mgr; enum diagnostic_level m_level; impl_rich_location m_rich_loc; const diagnostic_logical_location *m_logical_loc; diagnostic_metadata m_metadata; + prebuilt_digraphs m_graphs; std::vector<std::unique_ptr<range_label>> m_labels; std::vector<std::unique_ptr<impl_rule>> m_rules; std::unique_ptr<diagnostic_execution_path> m_path; @@ -1248,6 +1339,29 @@ diagnostic_manager::new_execution_path () return new diagnostic_execution_path (*mgr); } +void +diagnostic_manager::take_global_graph (std::unique_ptr<diagnostic_graph> graph) +{ + class prebuilt_lazy_digraph : public diagnostics::digraphs::lazy_digraph + { + public: + prebuilt_lazy_digraph (std::unique_ptr<diagnostic_graph> graph) + : m_graph (std::move (graph)) + { + } + + std::unique_ptr<diagnostics::digraphs::digraph> + create_digraph () const final override + { + return std::move (m_graph); + } + + private: + mutable std::unique_ptr<diagnostic_graph> m_graph; + }; + + m_dc.report_global_digraph (prebuilt_lazy_digraph (std::move (graph))); +} /* Error-checking at the API boundary. */ #define FAIL_IF_NULL(PTR_ARG) \ @@ -1876,6 +1990,7 @@ diagnostic_execution_path_add_event (diagnostic_execution_path *path, diagnostic_event_id_t result = path->add_event_va (physical_loc, logical_loc, stack_depth, + nullptr, gmsgid, &args); va_end (args); @@ -1898,6 +2013,7 @@ diagnostic_execution_path_add_event_va (diagnostic_execution_path *path, diagnostic_event_id_t result = path->add_event_va (physical_loc, logical_loc, stack_depth, + nullptr, gmsgid, args); return as_diagnostic_event_id (result); } @@ -2048,3 +2164,223 @@ diagnostic_manager_set_analysis_target (diagnostic_manager *mgr, mgr->get_dc ().set_main_input_filename (file->get_name ()); } + +// struct diagnostic_graph : public diagnostics::digraphs::graph<foo_traits> + +diagnostic_node * +diagnostic_graph::add_node_with_id (std::string id, + diagnostic_node *parent_node) +{ + auto node_up = std::make_unique<diagnostic_node> (*this, std::move (id)); + diagnostic_node *new_node = node_up.get (); + if (parent_node) + parent_node->add_child (std::move (node_up)); + else + add_node (std::move (node_up)); + return new_node; +} + +diagnostic_edge * +diagnostic_graph::add_edge_with_label (const char *id, + diagnostic_node &src_node, + diagnostic_node &dst_node, + const char *label) +{ + auto edge_up + = std::make_unique<diagnostic_edge> (*this, id, + src_node, dst_node); + diagnostic_edge *new_edge = edge_up.get (); + if (label) + new_edge->set_label (label); + add_edge (std::move (edge_up)); + return new_edge; +} + +/* Public entrypoint. */ + +diagnostic_graph * +diagnostic_manager_new_graph (diagnostic_manager *manager) +{ + FAIL_IF_NULL (manager); + + return new diagnostic_graph (*manager); +} + +/* Public entrypoint. */ + +void +diagnostic_manager_take_global_graph (diagnostic_manager *manager, + diagnostic_graph *graph) +{ + FAIL_IF_NULL (manager); + FAIL_IF_NULL (graph); + + manager->take_global_graph (std::unique_ptr<diagnostic_graph> (graph)); +} + +void +diagnostic_take_graph (diagnostic *diag, + diagnostic_graph *graph) +{ + FAIL_IF_NULL (diag); + FAIL_IF_NULL (graph); + + diag->take_graph (std::unique_ptr<diagnostic_graph> (graph)); +} + +/* Public entrypoint. */ + +void +diagnostic_graph_release (diagnostic_graph *graph) +{ + delete graph; +} + +/* Public entrypoint. */ + +void +diagnostic_graph_set_description (diagnostic_graph *graph, + const char *desc) +{ + FAIL_IF_NULL (graph); + + graph->set_description (desc); +} + +diagnostic_node * +diagnostic_graph_add_node (diagnostic_graph *graph, + const char *id, + diagnostic_node *parent_node) +{ + FAIL_IF_NULL (graph); + FAIL_IF_NULL (id); + + return graph->add_node_with_id (id, parent_node); +} + +/* Public entrypoint. */ + +diagnostic_edge * +diagnostic_graph_add_edge (diagnostic_graph *graph, + const char *id, + diagnostic_node *src_node, + diagnostic_node *dst_node, + const char *label) +{ + FAIL_IF_NULL (graph); + FAIL_IF_NULL (src_node); + FAIL_IF_NULL (dst_node); + + return graph->add_edge_with_label (id, *src_node, *dst_node, label); +} + +/* Public entrypoint. */ + +diagnostic_node * +diagnostic_graph_get_node_by_id (diagnostic_graph *graph, + const char *id) +{ + FAIL_IF_NULL (graph); + FAIL_IF_NULL (id); + + return static_cast<diagnostic_node *> (graph->get_node_by_id (id)); +} + +/* Public entrypoint. */ + +diagnostic_edge * +diagnostic_graph_get_edge_by_id (diagnostic_graph *graph, + const char *id) +{ + FAIL_IF_NULL (graph); + FAIL_IF_NULL (id); + + return static_cast<diagnostic_edge *> (graph->get_edge_by_id (id)); +} + +/* Public entrypoint. */ + +void +diagnostic_node_set_location (diagnostic_node *node, + const diagnostic_physical_location *loc) +{ + FAIL_IF_NULL (node); + + node->set_physical_loc (loc ? loc->m_inner : UNKNOWN_LOCATION); +} + +/* Public entrypoint. */ + +void +diagnostic_node_set_label (diagnostic_node *node, + const char *label) +{ + FAIL_IF_NULL (node); + + node->set_label (label); +} + +void +diagnostic_node_set_logical_location (diagnostic_node *node, + const diagnostic_logical_location *logical_loc) +{ + FAIL_IF_NULL (node); + + node->set_logical_loc + (impl_logical_location_manager::key_from_ptr (logical_loc)); +} + +/* Private entrypoint. */ + +diagnostic_event_id +private_diagnostic_execution_path_add_event_2 (diagnostic_execution_path *path, + const diagnostic_physical_location *physical_loc, + const diagnostic_logical_location *logical_loc, + unsigned stack_depth, + diagnostic_graph *state_graph, + const char *gmsgid, ...) + +{ + FAIL_IF_NULL (path); + FAIL_IF_NULL (gmsgid); + + va_list args; + va_start (args, gmsgid); + diagnostic_event_id_t result + = path->add_event_va (physical_loc, + logical_loc, + stack_depth, + std::unique_ptr <diagnostic_graph> (state_graph), + gmsgid, &args); + va_end (args); + + return as_diagnostic_event_id (result); + +} + +/* Private entrypoint. */ + +void +private_diagnostic_graph_set_property_bag (diagnostic_graph &graph, + std::unique_ptr<json::object> properties) +{ + graph.set_property_bag (std::move (properties)); +} + +/* Private entrypoint. */ + +void +private_diagnostic_node_set_property_bag (diagnostic_node &node, + std::unique_ptr<json::object> properties) +{ + node.set_property_bag (std::move (properties)); +} + +/* Private entrypoint. */ + +void +private_diagnostic_edge_set_property_bag (diagnostic_edge &edge, + std::unique_ptr<json::object> properties) +{ + edge.set_property_bag (std::move (properties)); +} |