#define GCC_ANALYZER_COMMON_H
#include "config.h"
+#define INCLUDE_LIST
#define INCLUDE_MAP
#define INCLUDE_SET
#define INCLUDE_STRING
extern void register_known_functions_lang_cp (known_function_manager &kfm);
extern void register_varargs_builtins (known_function_manager &kfm);
-/* Passed by pointer to PLUGIN_ANALYZER_INIT callbacks. */
-
-class plugin_analyzer_init_iface
-{
-public:
- virtual void register_state_machine (std::unique_ptr<state_machine>) = 0;
- virtual void register_known_function (const char *name,
- std::unique_ptr<known_function>) = 0;
- virtual logger *get_logger () const = 0;
-};
-
/* An enum for describing the direction of an access to memory. */
enum class access_direction
#pragma GCC diagnostic ignored "-Wformat-diag"
#endif
+namespace gcc {
+namespace topics {
+
+/* A topic for messages relating to the analyzer. */
+
+namespace analyzer_events {
+
+/* A message published by the analyzer as it starts up, intended for
+ subsystems/plugins that want to register additional functionality
+ within the analyzer. */
+
+struct on_ana_init
+{
+ virtual void
+ register_state_machine (std::unique_ptr<ana::state_machine>) const = 0;
+
+ virtual void
+ register_known_function (const char *name,
+ std::unique_ptr<ana::known_function>) const = 0;
+
+ virtual ana::logger *
+ get_logger () const = 0;
+};
+
+struct subscriber {
+
+ virtual ~subscriber () = default;
+
+ virtual void on_message (const on_ana_init &) = 0;
+};
+
+} // namespace gcc::topics::analyzer_events
+} // namespace gcc::topics
+} // namespace gcc
+
#if !ENABLE_ANALYZER
extern void sorry_no_analyzer ();
#endif /* #if !ENABLE_ANALYZER */
#include "attribs.h"
#include "tree-dfa.h"
#include "gimple-predict.h"
+#include "context.h"
+#include "channels.h"
#include "text-art/dump.h"
free (filename);
}
-/* Concrete subclass of plugin_analyzer_init_iface, allowing plugins
- to register new state machines. */
+/* Concrete subclass of on_ana_init, allowing plugins to register
+ new state machines. */
-class plugin_analyzer_init_impl : public plugin_analyzer_init_iface
+class impl_on_ana_init : public gcc::topics::analyzer_events::on_ana_init
{
public:
- plugin_analyzer_init_impl (std::vector<std::unique_ptr<state_machine>> &checkers,
- known_function_manager &known_fn_mgr,
- logger *logger)
+ impl_on_ana_init (std::vector<std::unique_ptr<state_machine>> &checkers,
+ known_function_manager &known_fn_mgr,
+ logger *logger)
: m_checkers (checkers),
m_known_fn_mgr (known_fn_mgr),
m_logger (logger)
{}
- void register_state_machine (std::unique_ptr<state_machine> sm) final override
+ void
+ register_state_machine (std::unique_ptr<state_machine> sm)
+ const final override
{
LOG_SCOPE (m_logger);
m_checkers.push_back (std::move (sm));
}
- void register_known_function (const char *name,
- std::unique_ptr<known_function> kf) final override
+ void
+ register_known_function (const char *name,
+ std::unique_ptr<known_function> kf)
+ const final override
{
LOG_SCOPE (m_logger);
m_known_fn_mgr.add (name, std::move (kf));
}
- logger *get_logger () const final override
+ logger *
+ get_logger () const final override
{
return m_logger;
}
register_known_functions (*eng.get_known_function_manager (),
*eng.get_model_manager ());
- plugin_analyzer_init_impl data (checkers,
- *eng.get_known_function_manager (),
- logger);
- invoke_plugin_callbacks (PLUGIN_ANALYZER_INIT, &data);
+ if (auto channel
+ = g->get_channels ().analyzer_events_channel.get_if_active ())
+ channel->publish (impl_on_ana_init (checkers,
+ *eng.get_known_function_manager (),
+ logger));
if (logger)
{
/* Forward decls of subscribers for the various topics we have
publish/subscribe channels for. */
namespace topics {
+ namespace analyzer_events { struct subscriber; }
namespace pass_events { struct subscriber; }
} // namespace gcc::topics
struct compiler_channels
{
+ pub_sub::channel<topics::analyzer_events::subscriber> analyzer_events_channel;
pub_sub::channel<topics::pass_events::subscriber> pass_events_channel;
};
as a const char* pointer. */
PLUGIN_INCLUDE_FILE,
- /* Called when -fanalyzer starts. The event data is an
- ana::plugin_analyzer_init_iface *. */
- PLUGIN_ANALYZER_INIT,
-
PLUGIN_EVENT_FIRST_DYNAMIC /* Dummy event used for indexing callback
array. */
@};
case PLUGIN_EARLY_GIMPLE_PASSES_END:
case PLUGIN_NEW_PASS:
case PLUGIN_INCLUDE_FILE:
- case PLUGIN_ANALYZER_INIT:
{
struct callback_info *new_callback;
if (!callback)
case PLUGIN_EARLY_GIMPLE_PASSES_END:
case PLUGIN_NEW_PASS:
case PLUGIN_INCLUDE_FILE:
- case PLUGIN_ANALYZER_INIT:
{
/* Iterate over every callback registered with this event and
call it. */
as a const char* pointer. */
DEFEVENT (PLUGIN_INCLUDE_FILE)
-/* Called when -fanalyzer starts. The event data is an
- ana::plugin_analyzer_init_iface *. */
-DEFEVENT (PLUGIN_ANALYZER_INIT)
-
/* When adding a new hard-coded plugin event, don't forget to edit in
file plugin.cc the functions register_callback and
invoke_plugin_callbacks_full accordingly! */
#include "digraph.h"
#include "analyzer/supergraph.h"
#include "sbitmap.h"
+#include "context.h"
+#include "channels.h"
#include "analyzer/call-string.h"
#include "analyzer/program-point.h"
#include "analyzer/store.h"
"Python/C API", "#include <Python.h>");
}
-static void
-cpython_analyzer_init_cb (void *gcc_data, void * /*user_data */)
+namespace analyzer_events = ::gcc::topics::analyzer_events;
+
+class cpython_analyzer_events_subscriber : public analyzer_events::subscriber
{
- ana::plugin_analyzer_init_iface *iface
- = (ana::plugin_analyzer_init_iface *)gcc_data;
- LOG_SCOPE (iface->get_logger ());
- if (0)
- inform (input_location, "got here: cpython_analyzer_init_cb");
+public:
+ void
+ on_message (const analyzer_events::on_ana_init &m) final override
+ {
+ LOG_SCOPE (m.get_logger ());
- init_py_structs ();
+ init_py_structs ();
- if (pyobj_record == NULL_TREE)
- {
- sorry_no_cpython_plugin ();
- return;
- }
+ if (pyobj_record == NULL_TREE)
+ {
+ sorry_no_cpython_plugin ();
+ return;
+ }
- iface->register_known_function ("PyList_Append",
- std::make_unique<kf_PyList_Append> ());
- iface->register_known_function ("PyList_New", std::make_unique<kf_PyList_New> ());
- iface->register_known_function ("PyLong_FromLong",
- std::make_unique<kf_PyLong_FromLong> ());
+ m.register_known_function ("PyList_Append",
+ std::make_unique<kf_PyList_Append> ());
+ m.register_known_function ("PyList_New",
+ std::make_unique<kf_PyList_New> ());
+ m.register_known_function ("PyLong_FromLong",
+ std::make_unique<kf_PyLong_FromLong> ());
+ m.register_known_function
+ ("__analyzer_cpython_dump_refcounts",
+ std::make_unique<kf_analyzer_cpython_dump_refcounts> ());
+ }
+} cpython_sub;
- iface->register_known_function (
- "__analyzer_cpython_dump_refcounts",
- std::make_unique<kf_analyzer_cpython_dump_refcounts> ());
-}
} // namespace ana
#endif /* #if ENABLE_ANALYZER */
register_finish_translation_unit_callback (&stash_named_types);
register_finish_translation_unit_callback (&stash_global_vars);
region_model::register_pop_frame_callback(pyobj_refcnt_checker);
- register_callback (plugin_info->base_name, PLUGIN_ANALYZER_INIT,
- ana::cpython_analyzer_init_cb,
- NULL); /* void *user_data */
+ g->get_channels ().analyzer_events_channel.add_subscriber (ana::cpython_sub);
#else
sorry_no_analyzer ();
#endif
*/
/* { dg-options "-g" } */
+#define INCLUDE_LIST
#define INCLUDE_MEMORY
#define INCLUDE_STRING
#define INCLUDE_VECTOR
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "diagnostics/event-id.h"
+#include "context.h"
+#include "channels.h"
#include "analyzer/common.h"
#include "analyzer/analyzer-logging.h"
#include "json.h"
}
}
-/* Callback handler for the PLUGIN_ANALYZER_INIT event. */
+namespace analyzer_events = ::gcc::topics::analyzer_events;
-static void
-gil_analyzer_init_cb (void *gcc_data, void */*user_data*/)
+class gil_analyzer_events_subscriber : public analyzer_events::subscriber
{
- ana::plugin_analyzer_init_iface *iface
- = (ana::plugin_analyzer_init_iface *)gcc_data;
- LOG_SCOPE (iface->get_logger ());
- if (0)
- inform (input_location, "got here: gil_analyzer_init_cb");
- iface->register_state_machine
- (std::make_unique<gil_state_machine> (iface->get_logger ()));
-}
+public:
+ void
+ on_message (const analyzer_events::on_ana_init &m) final override
+ {
+ LOG_SCOPE (m.get_logger ());
+ m.register_state_machine
+ (std::make_unique<gil_state_machine> (m.get_logger ()));
+ }
+} gil_sub;
} // namespace ana
const char *plugin_name = plugin_info->base_name;
if (0)
inform (input_location, "got here; %qs", plugin_name);
- register_callback (plugin_info->base_name,
- PLUGIN_ANALYZER_INIT,
- ana::gil_analyzer_init_cb,
- NULL); /* void *user_data */
+ g->get_channels ().analyzer_events_channel.add_subscriber (ana::gil_sub);
#else
sorry_no_analyzer ();
#endif
#include "digraph.h"
#include "analyzer/supergraph.h"
#include "sbitmap.h"
+#include "context.h"
+#include "channels.h"
#include "analyzer/call-string.h"
#include "analyzer/program-point.h"
#include "analyzer/store.h"
}
};
-/* Callback handler for the PLUGIN_ANALYZER_INIT event. */
+namespace analyzer_events = ::gcc::topics::analyzer_events;
-static void
-kernel_analyzer_init_cb (void *gcc_data, void */*user_data*/)
+class kernel_analyzer_events_subscriber : public analyzer_events::subscriber
{
- ana::plugin_analyzer_init_iface *iface
- = (ana::plugin_analyzer_init_iface *)gcc_data;
- LOG_SCOPE (iface->get_logger ());
- if (0)
- inform (input_location, "got here: kernel_analyzer_init_cb");
- iface->register_known_function
- ("copy_from_user",
- std::make_unique<known_function_copy_from_user> ());
- iface->register_known_function
- ("copy_to_user",
- std::make_unique<known_function_copy_to_user> ());
- iface->register_known_function
- ("__check_object_size",
- std::make_unique<known_function___check_object_size> ());
-}
+public:
+ void
+ on_message (const analyzer_events::on_ana_init &m) final override
+ {
+ LOG_SCOPE (m.get_logger ());
+ m.register_known_function
+ ("copy_from_user",
+ std::make_unique<known_function_copy_from_user> ());
+ m.register_known_function
+ ("copy_to_user",
+ std::make_unique<known_function_copy_to_user> ());
+ m.register_known_function
+ ("__check_object_size",
+ std::make_unique<known_function___check_object_size> ());
+ }
+} kernel_sub;
} // namespace ana
const char *plugin_name = plugin_info->base_name;
if (0)
inform (input_location, "got here; %qs", plugin_name);
- register_callback (plugin_info->base_name,
- PLUGIN_ANALYZER_INIT,
- ana::kernel_analyzer_init_cb,
- NULL); /* void *user_data */
+ g->get_channels ().analyzer_events_channel.add_subscriber (ana::kernel_sub);
#else
sorry_no_analyzer ();
#endif
#include "digraph.h"
#include "analyzer/supergraph.h"
#include "sbitmap.h"
+#include "context.h"
+#include "channels.h"
#include "analyzer/call-string.h"
#include "analyzer/program-point.h"
#include "analyzer/store.h"
}
};
-/* Callback handler for the PLUGIN_ANALYZER_INIT event. */
+namespace analyzer_events = ::gcc::topics::analyzer_events;
-static void
-known_fn_analyzer_init_cb (void *gcc_data, void */*user_data*/)
+class known_fn_analyzer_events_subscriber : public analyzer_events::subscriber
{
- ana::plugin_analyzer_init_iface *iface
- = (ana::plugin_analyzer_init_iface *)gcc_data;
- LOG_SCOPE (iface->get_logger ());
- if (0)
- inform (input_location, "got here: known_fn_analyzer_init_cb");
- iface->register_known_function
- ("returns_42",
- std::make_unique<known_function_returns_42> ());
- iface->register_known_function
- ("attempt_to_copy",
- std::make_unique<known_function_attempt_to_copy> ());
-}
+public:
+ void
+ on_message (const analyzer_events::on_ana_init &m) final override
+ {
+ LOG_SCOPE (m.get_logger ());
+ m.register_known_function
+ ("returns_42",
+ std::make_unique<known_function_returns_42> ());
+ m.register_known_function
+ ("attempt_to_copy",
+ std::make_unique<known_function_attempt_to_copy> ());
+ }
+} known_fn_sub;
} // namespace ana
const char *plugin_name = plugin_info->base_name;
if (0)
inform (input_location, "got here; %qs", plugin_name);
- register_callback (plugin_info->base_name,
- PLUGIN_ANALYZER_INIT,
- ana::known_fn_analyzer_init_cb,
- NULL); /* void *user_data */
+ g->get_channels ().analyzer_events_channel.add_subscriber (ana::known_fn_sub);
#else
sorry_no_analyzer ();
#endif