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 <dmalcolm@redhat.com>
}
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);
#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"
class change_set;
}
- namespace digraphs {
- class lazy_digraph;
- }
+ namespace digraphs { class digraph; }
namespace logical_locations {
class manager;
/* 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,
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 {
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
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 ();
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 ());
}
}
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);
}
}
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);
}
#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.
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
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;
/* 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
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 ()
{
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 */
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,
}
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; }
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 (); }
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
}
--- /dev/null
+/* Template for deferring object creation until the object is needed.
+ Copyright (C) 2024-2025 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@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 */
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));
}
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)
}
std::unique_ptr<diagnostics::digraphs::digraph>
- create_digraph () const final override
+ create_object () const final override
{
return std::move (m_graph);
}
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_)
{
}
+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");
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;
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>>> ();
/* This plugin exercises diagnostics::metadata. */
+#define INCLUDE_VECTOR
#include "gcc-plugin.h"
#include "config.h"
#include "system.h"
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"