gccint: Plugin API

1 
1 24.2 Plugin API
1 ===============
1 
1 Plugins are activated by the compiler at specific events as defined in
1 'gcc-plugin.h'.  For each event of interest, the plugin should call
1 'register_callback' specifying the name of the event and address of the
1 callback function that will handle that event.
1 
1  The header 'gcc-plugin.h' must be the first gcc header to be included.
1 
1 24.2.1 Plugin license check
1 ---------------------------
1 
1 Every plugin should define the global symbol 'plugin_is_GPL_compatible'
1 to assert that it has been licensed under a GPL-compatible license.  If
1 this symbol does not exist, the compiler will emit a fatal error and
1 exit with the error message:
1 
1      fatal error: plugin NAME is not licensed under a GPL-compatible license
1      NAME: undefined symbol: plugin_is_GPL_compatible
1      compilation terminated
1 
1  The declared type of the symbol should be int, to match a forward
1 declaration in 'gcc-plugin.h' that suppresses C++ mangling.  It does not
1 need to be in any allocated section, though.  The compiler merely
1 asserts that the symbol exists in the global scope.  Something like this
1 is enough:
1 
1      int plugin_is_GPL_compatible;
1 
1 24.2.2 Plugin initialization
1 ----------------------------
1 
1 Every plugin should export a function called 'plugin_init' that is
1 called right after the plugin is loaded.  This function is responsible
1 for registering all the callbacks required by the plugin and do any
1 other required initialization.
1 
1  This function is called from 'compile_file' right before invoking the
1 parser.  The arguments to 'plugin_init' are:
1 
1    * 'plugin_info': Plugin invocation information.
1    * 'version': GCC version.
1 
1  The 'plugin_info' struct is defined as follows:
1 
1      struct plugin_name_args
1      {
1        char *base_name;              /* Short name of the plugin
1                                         (filename without .so suffix). */
1        const char *full_name;        /* Path to the plugin as specified with
1                                         -fplugin=. */
1        int argc;                     /* Number of arguments specified with
1                                         -fplugin-arg-.... */
1        struct plugin_argument *argv; /* Array of ARGC key-value pairs. */
1        const char *version;          /* Version string provided by plugin. */
1        const char *help;             /* Help string provided by plugin. */
1      }
1 
1  If initialization fails, 'plugin_init' must return a non-zero value.
1 Otherwise, it should return 0.
1 
1  The version of the GCC compiler loading the plugin is described by the
1 following structure:
1 
1      struct plugin_gcc_version
1      {
1        const char *basever;
1        const char *datestamp;
1        const char *devphase;
1        const char *revision;
1        const char *configuration_arguments;
1      };
1 
1  The function 'plugin_default_version_check' takes two pointers to such
1 structure and compare them field by field.  It can be used by the
1 plugin's 'plugin_init' function.
1 
1  The version of GCC used to compile the plugin can be found in the
1 symbol 'gcc_version' defined in the header 'plugin-version.h'.  The
1 recommended version check to perform looks like
1 
1      #include "plugin-version.h"
1      ...
1 
1      int
1      plugin_init (struct plugin_name_args *plugin_info,
1                   struct plugin_gcc_version *version)
1      {
1        if (!plugin_default_version_check (version, &gcc_version))
1          return 1;
1 
1      }
1 
1  but you can also check the individual fields if you want a less strict
1 check.
1 
1 24.2.3 Plugin callbacks
1 -----------------------
1 
1 Callback functions have the following prototype:
1 
1      /* The prototype for a plugin callback function.
1           gcc_data  - event-specific data provided by GCC
1           user_data - plugin-specific data provided by the plug-in.  */
1      typedef void (*plugin_callback_func)(void *gcc_data, void *user_data);
1 
1  Callbacks can be invoked at the following pre-determined events:
1 
1      enum plugin_event
1      {
1        PLUGIN_START_PARSE_FUNCTION,  /* Called before parsing the body of a function. */
1        PLUGIN_FINISH_PARSE_FUNCTION, /* After finishing parsing a function. */
1        PLUGIN_PASS_MANAGER_SETUP,    /* To hook into pass manager.  */
1        PLUGIN_FINISH_TYPE,           /* After finishing parsing a type.  */
1        PLUGIN_FINISH_DECL,           /* After finishing parsing a declaration. */
1        PLUGIN_FINISH_UNIT,           /* Useful for summary processing.  */
1        PLUGIN_PRE_GENERICIZE,        /* Allows to see low level AST in C and C++ frontends.  */
1        PLUGIN_FINISH,                /* Called before GCC exits.  */
1        PLUGIN_INFO,                  /* Information about the plugin. */
1        PLUGIN_GGC_START,             /* Called at start of GCC Garbage Collection. */
1        PLUGIN_GGC_MARKING,           /* Extend the GGC marking. */
1        PLUGIN_GGC_END,               /* Called at end of GGC. */
1        PLUGIN_REGISTER_GGC_ROOTS,    /* Register an extra GGC root table. */
1        PLUGIN_ATTRIBUTES,            /* Called during attribute registration */
1        PLUGIN_START_UNIT,            /* Called before processing a translation unit.  */
1        PLUGIN_PRAGMAS,               /* Called during pragma registration. */
1        /* Called before first pass from all_passes.  */
1        PLUGIN_ALL_PASSES_START,
1        /* Called after last pass from all_passes.  */
1        PLUGIN_ALL_PASSES_END,
1        /* Called before first ipa pass.  */
1        PLUGIN_ALL_IPA_PASSES_START,
1        /* Called after last ipa pass.  */
1        PLUGIN_ALL_IPA_PASSES_END,
1        /* Allows to override pass gate decision for current_pass.  */
1        PLUGIN_OVERRIDE_GATE,
1        /* Called before executing a pass.  */
1        PLUGIN_PASS_EXECUTION,
1        /* Called before executing subpasses of a GIMPLE_PASS in
1           execute_ipa_pass_list.  */
1        PLUGIN_EARLY_GIMPLE_PASSES_START,
1        /* Called after executing subpasses of a GIMPLE_PASS in
1           execute_ipa_pass_list.  */
1        PLUGIN_EARLY_GIMPLE_PASSES_END,
1        /* Called when a pass is first instantiated.  */
1        PLUGIN_NEW_PASS,
1      /* Called when a file is #include-d or given via the #line directive.
1         This could happen many times.  The event data is the included file path,
1         as a const char* pointer.  */
1        PLUGIN_INCLUDE_FILE,
1 
1        PLUGIN_EVENT_FIRST_DYNAMIC    /* Dummy event used for indexing callback
1                                         array.  */
1      };
1 
1  In addition, plugins can also look up the enumerator of a named event,
1 and / or generate new events dynamically, by calling the function
1 'get_named_event_id'.
1 
1  To register a callback, the plugin calls 'register_callback' with the
1 arguments:
1 
1    * 'char *name': Plugin name.
1    * 'int event': The event code.
1    * 'plugin_callback_func callback': The function that handles 'event'.
1    * 'void *user_data': Pointer to plugin-specific data.
1 
1  For the PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, and
1 PLUGIN_REGISTER_GGC_ROOTS pseudo-events the 'callback' should be null,
1 and the 'user_data' is specific.
1 
1  When the PLUGIN_PRAGMAS event is triggered (with a null pointer as data
1 from GCC), plugins may register their own pragmas.  Notice that pragmas
1 are not available from 'lto1', so plugins used with '-flto' option to
1 GCC during link-time optimization cannot use pragmas and do not even see
1 functions like 'c_register_pragma' or 'pragma_lex'.
1 
1  The PLUGIN_INCLUDE_FILE event, with a 'const char*' file path as GCC
1 data, is triggered for processing of '#include' or '#line' directives.
1 
1  The PLUGIN_FINISH event is the last time that plugins can call GCC
1 functions, notably emit diagnostics with 'warning', 'error' etc.
1