From: David Malcolm Date: Fri, 25 Jul 2025 19:13:46 +0000 (-0400) Subject: Introduce lazily-created.h X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bae1f7e29816b9a2287830df6dd4cde39f0208b4;p=thirdparty%2Fgcc.git Introduce lazily-created.h No functional change intended. gcc/ChangeLog: * diagnostics/context.cc: Eliminate digraphs::lazy_digraph in favor of lazily_created template. * diagnostics/context.h: Likewise. * diagnostics/digraphs.cc: Likewise, also digraphs::lazy_digraphs. * diagnostics/digraphs.h: Likewise. * diagnostics/html-sink.cc: Likewise. * diagnostics/metadata.h: Likewise. * diagnostics/sarif-sink.cc: Likewise. * diagnostics/sink.h: Likewise. * diagnostics/text-sink.h: Likewise. * lazily-created.h: New file. * libgdiagnostics.cc: Eliminate digraphs::lazy_digraph in favor of lazily_created template. gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic_plugin_test_graphs.cc: Eliminate digraphs::lazy_digraph and digraphs::lazy_digraphs in favor of lazily_created template. * gcc.dg/plugin/diagnostic_plugin_test_metadata.cc: Define INCLUDE_VECTOR since diagnostics/metadata.h now requires it. * gcc.dg/plugin/diagnostic_plugin_test_paths.cc: Likewise. Signed-off-by: David Malcolm --- diff --git a/gcc/diagnostics/context.cc b/gcc/diagnostics/context.cc index e8a87c82f23..9b235c8426d 100644 --- a/gcc/diagnostics/context.cc +++ b/gcc/diagnostics/context.cc @@ -1439,7 +1439,7 @@ context::report_verbatim (text_info &text) } void -context::report_global_digraph (const digraphs::lazy_digraph &ldg) +context::report_global_digraph (const lazily_created &ldg) { for (auto sink_ : m_sinks) sink_->report_global_digraph (ldg); diff --git a/gcc/diagnostics/context.h b/gcc/diagnostics/context.h index 8ac724a7ac2..f47370b1197 100644 --- a/gcc/diagnostics/context.h +++ b/gcc/diagnostics/context.h @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_DIAGNOSTICS_CONTEXT_H #define GCC_DIAGNOSTICS_CONTEXT_H +#include "lazily-created.h" #include "unique-argv.h" #include "diagnostics/option-classifier.h" #include "diagnostics/context-options.h" @@ -30,9 +31,7 @@ namespace diagnostics { class change_set; } - namespace digraphs { - class lazy_digraph; - } + namespace digraphs { class digraph; } namespace logical_locations { class manager; @@ -426,7 +425,7 @@ public: /* Report a directed graph associated with the run as a whole to any sinks that support directed graphs. */ void - report_global_digraph (const digraphs::lazy_digraph &); + report_global_digraph (const lazily_created &); enum kind classify_diagnostic (option_id opt_id, diff --git a/gcc/diagnostics/digraphs.cc b/gcc/diagnostics/digraphs.cc index b77390c0f1c..4a2ea4fca3c 100644 --- a/gcc/diagnostics/digraphs.cc +++ b/gcc/diagnostics/digraphs.cc @@ -351,28 +351,6 @@ diagnostics::digraphs::edge::to_json_sarif_edge () const return make_sarif_edge (*this, nullptr); } -// class lazy_digraph - -const diagnostics::digraphs::digraph & -diagnostics::digraphs::lazy_digraph::get_or_create_digraph () const -{ - if (!m_digraph) - m_digraph = create_digraph (); - gcc_assert (m_digraph); - return *m_digraph; -} - -// class lazy_digraphs - -const std::vector> & -diagnostics::digraphs::lazy_digraphs::get_or_create_digraphs () const -{ - if (!m_digraphs) - m_digraphs = create_digraphs (); - gcc_assert (m_digraphs); - return *m_digraphs; -} - #if CHECKING_P namespace diagnostics { diff --git a/gcc/diagnostics/digraphs.h b/gcc/diagnostics/digraphs.h index fc73f6e7362..7193ee48c3f 100644 --- a/gcc/diagnostics/digraphs.h +++ b/gcc/diagnostics/digraphs.h @@ -373,48 +373,6 @@ private: node &m_dst_node; }; -/* Abstract base class for lazily creating - a digraph on demand. - - This allows us to avoid the work of creating the digraph for - the common case where we just have a text sink. */ - -class lazy_digraph -{ -public: - virtual ~lazy_digraph () {} - - const digraph & - get_or_create_digraph () const; - -private: - virtual std::unique_ptr - create_digraph () const = 0; - - mutable std::unique_ptr m_digraph; -}; - -/* Abstract base class for lazily creating a collection of - digraphs on demand. - - This allows us to avoid the work of creating the digraphs for - the common case where we just have a text sink. */ - -class lazy_digraphs -{ -public: - virtual ~lazy_digraphs () {} - - const std::vector> & - get_or_create_digraphs () const; - -private: - virtual std::unique_ptr>> - create_digraphs () const = 0; - - mutable std::unique_ptr>> m_digraphs; -}; - } // namespace digraphs } // namespace diagnostics diff --git a/gcc/diagnostics/html-sink.cc b/gcc/diagnostics/html-sink.cc index 35525cb890c..07e71871d18 100644 --- a/gcc/diagnostics/html-sink.cc +++ b/gcc/diagnostics/html-sink.cc @@ -123,7 +123,7 @@ public: enum kind orig_diag_kind, html_sink_buffer *buffer); void emit_diagram (const diagram &d); - void emit_global_graph (const digraphs::lazy_digraph &); + void emit_global_graph (const lazily_created &); void end_group (); @@ -1148,7 +1148,7 @@ html_builder::make_element_for_diagnostic (const diagnostic_info &diagnostic, if (diagnostic.m_metadata) if (auto ldg = diagnostic.m_metadata->get_lazy_digraphs ()) { - auto &digraphs = ldg->get_or_create_digraphs (); + auto &digraphs = ldg->get_or_create (); for (auto &dg : digraphs) add_graph (*dg, *xp.get_insertion_point ()); } @@ -1271,9 +1271,9 @@ html_builder::add_graph (const digraphs::digraph &dg, } void -html_builder::emit_global_graph (const digraphs::lazy_digraph &ldg) +html_builder::emit_global_graph (const lazily_created &ldg) { - auto &dg = ldg.get_or_create_digraph (); + auto &dg = ldg.get_or_create (); gcc_assert (m_body_element); add_graph (dg, *m_body_element); } @@ -1392,7 +1392,8 @@ public: } void - report_global_digraph (const digraphs::lazy_digraph &ldg) final override + report_global_digraph (const lazily_created &ldg) + final override { m_builder.emit_global_graph (ldg); } diff --git a/gcc/diagnostics/metadata.h b/gcc/diagnostics/metadata.h index cdca105ebdf..c28f9821ee8 100644 --- a/gcc/diagnostics/metadata.h +++ b/gcc/diagnostics/metadata.h @@ -21,13 +21,12 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_DIAGNOSTICS_METADATA_H #define GCC_DIAGNOSTICS_METADATA_H +#include "lazily-created.h" + namespace diagnostics { class sarif_object; - - namespace digraphs { - class lazy_digraphs; - } // namespace digraphs + namespace digraphs { class digraph; } /* A bundle of additional metadata that can be associated with a diagnostic. @@ -41,6 +40,9 @@ namespace diagnostics { class metadata { public: + using lazy_digraphs + = lazily_created>>; + /* Abstract base class for referencing a rule that has been violated, such as within a coding standard, or within a specification. */ class rule @@ -97,12 +99,12 @@ class metadata const rule &get_rule (unsigned idx) const { return *(m_rules[idx]); } void - set_lazy_digraphs (const digraphs::lazy_digraphs *lazy_digraphs) + set_lazy_digraphs (const lazy_digraphs *lazy_digraphs_) { - m_lazy_digraphs = lazy_digraphs; + m_lazy_digraphs = lazy_digraphs_; } - const digraphs::lazy_digraphs * + const lazy_digraphs * get_lazy_digraphs () const { return m_lazy_digraphs; @@ -114,7 +116,7 @@ class metadata /* An optional way to create directed graphs associated with the diagnostic, for the sinks that support this (e.g. SARIF). */ - const digraphs::lazy_digraphs *m_lazy_digraphs; + const lazy_digraphs *m_lazy_digraphs; }; } // namespace diagnostics diff --git a/gcc/diagnostics/sarif-sink.cc b/gcc/diagnostics/sarif-sink.cc index 74252b4b77a..05c0a8eb3a9 100644 --- a/gcc/diagnostics/sarif-sink.cc +++ b/gcc/diagnostics/sarif-sink.cc @@ -781,7 +781,7 @@ public: void end_group (); void - report_global_digraph (const digraphs::lazy_digraph &); + report_global_digraph (const lazily_created &); std::unique_ptr take_current_result () { @@ -1908,9 +1908,9 @@ sarif_builder::end_group () void sarif_builder:: -report_global_digraph (const digraphs::lazy_digraph &ldg) +report_global_digraph (const lazily_created &ldg) { - auto &dg = ldg.get_or_create_digraph (); + auto &dg = ldg.get_or_create (); /* Presumably the location manager must be nullptr; see https://github.com/oasis-tcs/sarif-spec/issues/712 */ @@ -2075,7 +2075,7 @@ sarif_builder::make_result_object (const diagnostic_info &diagnostic, if (diagnostic.m_metadata) if (auto ldg = diagnostic.m_metadata->get_lazy_digraphs ()) { - auto &digraphs = ldg->get_or_create_digraphs (); + auto &digraphs = ldg->get_or_create (); auto graphs_arr = std::make_unique (); for (auto &iter : digraphs) graphs_arr->append (make_sarif_graph (*iter, this, @@ -3930,9 +3930,10 @@ public: } void - report_global_digraph (const digraphs::lazy_digraph &lazy_digraph) final override + report_global_digraph (const lazily_created &ldg) + final override { - m_builder.report_global_digraph (lazy_digraph); + m_builder.report_global_digraph (ldg); } sarif_builder &get_builder () { return m_builder; } diff --git a/gcc/diagnostics/sink.h b/gcc/diagnostics/sink.h index 04de99a06df..ac4e0fb6445 100644 --- a/gcc/diagnostics/sink.h +++ b/gcc/diagnostics/sink.h @@ -75,7 +75,7 @@ public: virtual void update_printer () = 0; virtual void - report_global_digraph (const digraphs::lazy_digraph &) = 0; + report_global_digraph (const lazily_created &) = 0; context &get_context () const { return m_context; } pretty_printer *get_printer () const { return m_printer.get (); } diff --git a/gcc/diagnostics/text-sink.h b/gcc/diagnostics/text-sink.h index 460e53e630c..5c60976641e 100644 --- a/gcc/diagnostics/text-sink.h +++ b/gcc/diagnostics/text-sink.h @@ -73,7 +73,8 @@ public: void update_printer () override; void - report_global_digraph (const digraphs::lazy_digraph &) final override + report_global_digraph (const lazily_created &) + final override { // no-op for text } diff --git a/gcc/lazily-created.h b/gcc/lazily-created.h new file mode 100644 index 00000000000..a6010cac8b5 --- /dev/null +++ b/gcc/lazily-created.h @@ -0,0 +1,51 @@ +/* Template for deferring object creation until the object is needed. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + Contributed by David Malcolm + +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 +. */ + +#ifndef GCC_LAZILY_CREATED_H +#define GCC_LAZILY_CREATED_H + +/* A template for deferring object creation for a type T until the object + is needed, to avoid potentially expensive creation of T unless it's + actually needed (e.g. for directed graphs associated with a diagnostic, + which are ignored by the default "text" sink). */ + +template +class lazily_created +{ + public: + virtual ~lazily_created () {} + + const T & + get_or_create () const + { + if (!m_object) + m_object = create_object (); + gcc_assert (m_object); + return *m_object; + } + +private: + virtual std::unique_ptr + create_object () const = 0; + + mutable std::unique_ptr m_object; +}; + +#endif /* ! GCC_LAZILY_CREATED_H */ diff --git a/gcc/libgdiagnostics.cc b/gcc/libgdiagnostics.cc index 7df8c95cb83..7351d33641b 100644 --- a/gcc/libgdiagnostics.cc +++ b/gcc/libgdiagnostics.cc @@ -1188,13 +1188,14 @@ private: std::vector> m_events; }; -class prebuilt_digraphs : public diagnostics::digraphs::lazy_digraphs +class prebuilt_digraphs + : public lazily_created>> { public: using digraph = diagnostics::digraphs::digraph; std::unique_ptr>> - create_digraphs () const final override + create_object () const final override { return std::make_unique>> (std::move (m_digraphs)); } @@ -1665,7 +1666,7 @@ diagnostic_manager::new_execution_path () void diagnostic_manager::take_global_graph (std::unique_ptr graph) { - class prebuilt_lazy_digraph : public diagnostics::digraphs::lazy_digraph + class prebuilt_lazy_digraph : public lazily_created { public: prebuilt_lazy_digraph (std::unique_ptr graph) @@ -1674,7 +1675,7 @@ diagnostic_manager::take_global_graph (std::unique_ptr graph) } std::unique_ptr - create_digraph () const final override + create_object () const final override { return std::move (m_graph); } diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc index fe54fe90c90..7398a290825 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_graphs.cc @@ -97,7 +97,7 @@ check_for_named_call (gimple *stmt, return call; } -class lazy_passes_graph : public diagnostics::digraphs::lazy_digraph +class lazy_passes_graph : public lazily_created { public: lazy_passes_graph (const ::gcc::pass_manager &pass_manager_) @@ -105,8 +105,9 @@ public: { } +private: std::unique_ptr - create_digraph () const final override + create_object () const final override { auto g = std::make_unique (); g->set_description ("Optimization Passes"); @@ -176,14 +177,13 @@ public: return result; } -private: const ::gcc::pass_manager &m_pass_manager; }; static void report_diag_with_graphs (location_t loc) { - class my_lazy_digraphs : public diagnostics::digraphs::lazy_digraphs + class my_lazy_digraphs : public diagnostics::metadata::lazy_digraphs { public: using diagnostic_graph = diagnostics::digraphs::digraph; @@ -191,7 +191,7 @@ report_diag_with_graphs (location_t loc) using diagnostic_edge = diagnostics::digraphs::edge; std::unique_ptr>> - create_digraphs () const final override + create_object () const final override { auto graphs = std::make_unique>> (); diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.cc index a1d003e5366..f1722583119 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.cc +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.cc @@ -1,5 +1,6 @@ /* This plugin exercises diagnostics::metadata. */ +#define INCLUDE_VECTOR #include "gcc-plugin.h" #include "config.h" #include "system.h" diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc index 2c9ff1c5b06..875f4a849e8 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.cc @@ -6,6 +6,7 @@ specific tests within the compiler's IR. We can't use any real diagnostics for this, so we have to fake it, hence this plugin. */ +#define INCLUDE_VECTOR #include "gcc-plugin.h" #include "config.h" #include "system.h"