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.
---
 gcc/diagnostics/context.cc                    |  2 +-
 gcc/diagnostics/context.h                     |  7 ++-
 gcc/diagnostics/digraphs.cc                   | 22 --------
 gcc/diagnostics/digraphs.h                    | 42 ---------------
 gcc/diagnostics/html-sink.cc                  | 11 ++--
 gcc/diagnostics/metadata.h                    | 18 ++++---
 gcc/diagnostics/sarif-sink.cc                 | 13 ++---
 gcc/diagnostics/sink.h                        |  2 +-
 gcc/diagnostics/text-sink.h                   |  3 +-
 gcc/lazily-created.h                          | 51 +++++++++++++++++++
 gcc/libgdiagnostics.cc                        |  9 ++--
 .../plugin/diagnostic_plugin_test_graphs.cc   | 10 ++--
 .../plugin/diagnostic_plugin_test_metadata.cc |  1 +
 .../plugin/diagnostic_plugin_test_paths.cc    |  1 +
 14 files changed, 93 insertions(+), 99 deletions(-)
 create mode 100644 gcc/lazily-created.h

diff --git a/gcc/diagnostics/context.cc b/gcc/diagnostics/context.cc
index e8a87c82f23e..9b235c8426d4 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<digraphs::digraph> &ldg)
 {
   for (auto sink_ : m_sinks)
     sink_->report_global_digraph (ldg);
diff --git a/gcc/diagnostics/context.h b/gcc/diagnostics/context.h
index 8ac724a7ac2a..f47370b11973 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<digraphs::digraph> &);
 
   enum kind
   classify_diagnostic (option_id opt_id,
diff --git a/gcc/diagnostics/digraphs.cc b/gcc/diagnostics/digraphs.cc
index b77390c0f1c7..4a2ea4fca3c7 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<std::unique_ptr<diagnostics::digraphs::digraph>> &
-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 fc73f6e73623..7193ee48c3fa 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<digraph>
-  create_digraph () const = 0;
-
-  mutable std::unique_ptr<digraph> 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<std::unique_ptr<digraph>> &
-  get_or_create_digraphs () const;
-
-private:
-  virtual std::unique_ptr<std::vector<std::unique_ptr<digraph>>>
-  create_digraphs () const = 0;
-
-  mutable std::unique_ptr<std::vector<std::unique_ptr<digraph>>> m_digraphs;
-};
-
 } // namespace digraphs
 } // namespace diagnostics
 
diff --git a/gcc/diagnostics/html-sink.cc b/gcc/diagnostics/html-sink.cc
index 35525cb890c5..07e71871d181 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<digraphs::digraph> &);
 
   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<digraphs::digraph> &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<digraphs::digraph> &ldg)
+    final override
   {
     m_builder.emit_global_graph (ldg);
   }
diff --git a/gcc/diagnostics/metadata.h b/gcc/diagnostics/metadata.h
index cdca105ebdfd..c28f9821ee8b 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<std::vector<std::unique_ptr<digraphs::digraph>>>;
+
   /* 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 74252b4b77a1..05c0a8eb3a92 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<digraphs::digraph> &);
 
   std::unique_ptr<sarif_result> 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<digraphs::digraph> &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<json::array> ();
        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<digraphs::digraph> &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 04de99a06df1..ac4e0fb64455 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<digraphs::digraph> &) = 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 460e53e630cb..5c60976641ef 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<digraphs::digraph> &)
+    final override
   {
     // no-op for text
   }
diff --git a/gcc/lazily-created.h b/gcc/lazily-created.h
new file mode 100644
index 000000000000..a6010cac8b57
--- /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 <dmalc...@redhat.com>
+
+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
+<http://www.gnu.org/licenses/>.  */
+
+#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 <typename T>
+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<T>
+  create_object () const = 0;
+
+  mutable std::unique_ptr<T> m_object;
+};
+
+#endif /* ! GCC_LAZILY_CREATED_H */
diff --git a/gcc/libgdiagnostics.cc b/gcc/libgdiagnostics.cc
index 7df8c95cb83d..7351d33641bc 100644
--- a/gcc/libgdiagnostics.cc
+++ b/gcc/libgdiagnostics.cc
@@ -1188,13 +1188,14 @@ private:
   std::vector<std::unique_ptr<libgdiagnostics_path_event>> m_events;
 };
 
-class prebuilt_digraphs : public diagnostics::digraphs::lazy_digraphs
+class prebuilt_digraphs
+  : public 
lazily_created<std::vector<std::unique_ptr<diagnostics::digraphs::digraph>>>
 {
 public:
   using digraph = diagnostics::digraphs::digraph;
 
   std::unique_ptr<std::vector<std::unique_ptr<digraph>>>
-  create_digraphs () const final override
+  create_object () const final override
   {
     return std::make_unique<std::vector<std::unique_ptr<digraph>>> (std::move 
(m_digraphs));
   }
@@ -1665,7 +1666,7 @@ diagnostic_manager::new_execution_path ()
 void
 diagnostic_manager::take_global_graph (std::unique_ptr<diagnostic_graph> graph)
 {
-  class prebuilt_lazy_digraph : public diagnostics::digraphs::lazy_digraph
+  class prebuilt_lazy_digraph : public 
lazily_created<diagnostics::digraphs::digraph>
   {
   public:
     prebuilt_lazy_digraph (std::unique_ptr<diagnostic_graph> graph)
@@ -1674,7 +1675,7 @@ diagnostic_manager::take_global_graph 
(std::unique_ptr<diagnostic_graph> graph)
     }
 
     std::unique_ptr<diagnostics::digraphs::digraph>
-    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 fe54fe90c90c..7398a2908258 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<diagnostics::digraphs::digraph>
 {
 public:
   lazy_passes_graph (const ::gcc::pass_manager &pass_manager_)
@@ -105,8 +105,9 @@ public:
   {
   }
 
+private:
   std::unique_ptr<diagnostics::digraphs::digraph>
-  create_digraph () const final override
+  create_object () const final override
   {
     auto g = std::make_unique<diagnostics::digraphs::digraph> ();
     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<std::vector<std::unique_ptr<diagnostic_graph>>>
-    create_digraphs () const final override
+    create_object () const final override
     {
       auto graphs
        = std::make_unique<std::vector<std::unique_ptr<diagnostic_graph>>> ();
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 a1d003e53664..f1722583119c 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 2c9ff1c5b065..875f4a849e8c 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"
-- 
2.26.3

Reply via email to