Next:Interacting with the pass manager, Previous:Loading Plugins, Up:Plugins [Contents][Index]
Plugins are activated by the compiler at specific events as defined ingcc-plugin.h. For each event of interest, the plugin shouldcallregister_callback specifying the name of the event andaddress of the callback function that will handle that event.
The headergcc-plugin.h must be the first gcc header to be included.
Every plugin should define the global symbolplugin_is_GPL_compatibleto assert that it has been licensed under a GPL-compatible license.If this symbol does not exist, the compiler will emit a fatal errorand exit with the error message:
fatal error: pluginname is not licensed under a GPL-compatible licensename: undefined symbol: plugin_is_GPL_compatiblecompilation terminated
The declared type of the symbol should be int, to match a forward declarationingcc-plugin.h that suppresses C++ mangling. It does not need to be inany allocated section, though. The compiler merely asserts thatthe symbol exists in the global scope. Something like this is enough:
int plugin_is_GPL_compatible;
Every plugin should export a function calledplugin_init thatis called right after the plugin is loaded. This function isresponsible for registering all the callbacks required by the pluginand do any other required initialization.
This function is called fromcompile_file right before invokingthe parser. The arguments toplugin_init are:
plugin_info: Plugin invocation information.version: GCC version.Theplugin_info struct is defined as follows:
struct plugin_name_args{ char *base_name; /* Short name of the plugin (filename without .so suffix). */ const char *full_name; /* Path to the plugin as specified with -fplugin=. */ int argc; /* Number of arguments specified with -fplugin-arg-.... */ struct plugin_argument *argv; /* Array of ARGC key-value pairs. */ const char *version; /* Version string provided by plugin. */ const char *help; /* Help string provided by plugin. */}If initialization fails,plugin_init must return a non-zerovalue. Otherwise, it should return 0.
The version of the GCC compiler loading the plugin is described by thefollowing structure:
struct plugin_gcc_version{ const char *basever; const char *datestamp; const char *devphase; const char *revision; const char *configuration_arguments;};The functionplugin_default_version_check takes two pointers tosuch structure and compare them field by field. It can be used by theplugin’splugin_init function.
The version of GCC used to compile the plugin can be found in the symbolgcc_version defined in the headerplugin-version.h. Therecommended version check to perform looks like
#include "plugin-version.h"...intplugin_init (struct plugin_name_args *plugin_info, struct plugin_gcc_version *version){ if (!plugin_default_version_check (version, &gcc_version)) return 1;}but you can also check the individual fields if you want a less strict check.
Callback functions have the following prototype:
/* The prototype for a plugin callback function. gcc_data - event-specific data provided by GCC user_data - plugin-specific data provided by the plug-in. */typedef void (*plugin_callback_func)(void *gcc_data, void *user_data);
Callbacks can be invoked at the following pre-determined events:
enum plugin_event{ PLUGIN_START_PARSE_FUNCTION, /* Called before parsing the body of a function. */ PLUGIN_FINISH_PARSE_FUNCTION, /* After finishing parsing a function. */ PLUGIN_PASS_MANAGER_SETUP, /* To hook into pass manager. */ PLUGIN_FINISH_TYPE, /* After finishing parsing a type. */ PLUGIN_FINISH_DECL, /* After finishing parsing a declaration. */ PLUGIN_FINISH_UNIT, /* Useful for summary processing. */ PLUGIN_PRE_GENERICIZE, /* Allows to see low level AST in C and C++ frontends. */ PLUGIN_FINISH, /* Called before GCC exits. */ PLUGIN_INFO, /* Information about the plugin. */ PLUGIN_GGC_START, /* Called at start of GCC Garbage Collection. */ PLUGIN_GGC_MARKING, /* Extend the GGC marking. */ PLUGIN_GGC_END, /* Called at end of GGC. */ PLUGIN_REGISTER_GGC_ROOTS, /* Register an extra GGC root table. */ PLUGIN_ATTRIBUTES, /* Called during attribute registration */ PLUGIN_START_UNIT, /* Called before processing a translation unit. */ PLUGIN_PRAGMAS, /* Called during pragma registration. */ /* Called before first pass from all_passes. */ PLUGIN_ALL_PASSES_START, /* Called after last pass from all_passes. */ PLUGIN_ALL_PASSES_END, /* Called before first ipa pass. */ PLUGIN_ALL_IPA_PASSES_START, /* Called after last ipa pass. */ PLUGIN_ALL_IPA_PASSES_END, /* Allows to override pass gate decision for current_pass. */ PLUGIN_OVERRIDE_GATE, /* Called before executing a pass. */ PLUGIN_PASS_EXECUTION, /* Called before executing subpasses of a GIMPLE_PASS in execute_ipa_pass_list. */ PLUGIN_EARLY_GIMPLE_PASSES_START, /* Called after executing subpasses of a GIMPLE_PASS in execute_ipa_pass_list. */ PLUGIN_EARLY_GIMPLE_PASSES_END, /* Called when a pass is first instantiated. */ PLUGIN_NEW_PASS,/* Called when a file is #include-d or given via the #line directive. This could happen many times. The event data is the included file path, 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. */};In addition, plugins can also look up the enumerator of a named event,and / or generate new events dynamically, by calling the functionget_named_event_id.
To register a callback, the plugin callsregister_callback withthe arguments:
char *name: Plugin name.int event: The event code.plugin_callback_func callback: The function that handlesevent.void *user_data: Pointer to plugin-specific data.For thePLUGIN_PASS_MANAGER_SETUP,PLUGIN_INFO, andPLUGIN_REGISTER_GGC_ROOTS pseudo-events thecallback should be null,and theuser_data is specific.
When thePLUGIN_PRAGMAS event is triggered (with a null pointer asdata from GCC), plugins may register their own pragmas. Notice thatpragmas are not available fromlto1, so plugins used with-flto option to GCC during link-time optimization cannot usepragmas and do not even see functions likec_register_pragma orpragma_lex.
ThePLUGIN_INCLUDE_FILE event, with aconst char* file path asGCC data, is triggered for processing of#include or#line directives.
ThePLUGIN_FINISH event is the last time that plugins can call GCCfunctions, notably emit diagnostics withwarning,erroretc.
Next:Interacting with the pass manager, Previous:Loading Plugins, Up:Plugins [Contents][Index]