diff options
author | Rafael Espindola <espindola@google.com> | 2009-04-09 10:11:19 +0000 |
---|---|---|
committer | Rafael Espindola <espindola@google.com> | 2009-04-09 10:11:19 +0000 |
commit | 6f75174ec564d556bec50cc30ec5d2fd689a965c (patch) | |
tree | 73b129490a1bbf861bbc5135fa2de9f89ba5d6a8 | |
parent | f145cbf1669f1334926bd0bc720cf707f787d2e1 (diff) |
2009-04-09 Rafael Avila de Espindola <espindola@google.com>
* gcc-plugin.h (plugin_event): Add PLUGIN_INFO.
(plugin_info): New.
* opts.c (common_handle_option): Don't call print_version.
* plugin.c (plugin_name_args): Add version.
(register_plugin_info): New.
(register_callback): Handle PLUGIN_INFO.
(try_init_one_plugin): New.
(init_one_plugin): Use try_init_one_plugin.
(finalize_one_plugin): New.
(finalize_plugins): New.
(print_options): New.
(print_version_one_plugin): New.
(print_plugins_versions): New.
* plugin.h (print_plugins_versions): New.
(finalize_plugins): New.
* toplev.c (compile_file): Don't call initialize_plugins.
(print_version): Call print_plugins_versions.
(toplev_main): Call initialize_plugins. Call print_version if needed.
Call finalize_plugins.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/plugins@145817 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog.plugins | 22 | ||||
-rw-r--r-- | gcc/gcc-plugin.h | 8 | ||||
-rw-r--r-- | gcc/opts.c | 1 | ||||
-rw-r--r-- | gcc/plugin.c | 120 | ||||
-rw-r--r-- | gcc/plugin.h | 5 | ||||
-rw-r--r-- | gcc/toplev.c | 9 |
6 files changed, 144 insertions, 21 deletions
diff --git a/gcc/ChangeLog.plugins b/gcc/ChangeLog.plugins index 24f0c539791..306d5587a2a 100644 --- a/gcc/ChangeLog.plugins +++ b/gcc/ChangeLog.plugins @@ -1,3 +1,25 @@ +2009-04-09 Rafael Avila de Espindola <espindola@google.com> + + * gcc-plugin.h (plugin_event): Add PLUGIN_INFO. + (plugin_info): New. + * opts.c (common_handle_option): Don't call print_version. + * plugin.c (plugin_name_args): Add version. + (register_plugin_info): New. + (register_callback): Handle PLUGIN_INFO. + (try_init_one_plugin): New. + (init_one_plugin): Use try_init_one_plugin. + (finalize_one_plugin): New. + (finalize_plugins): New. + (print_options): New. + (print_version_one_plugin): New. + (print_plugins_versions): New. + * plugin.h (print_plugins_versions): New. + (finalize_plugins): New. + * toplev.c (compile_file): Don't call initialize_plugins. + (print_version): Call print_plugins_versions. + (toplev_main): Call initialize_plugins. Call print_version if needed. + Call finalize_plugins. + 2009-04-07 Rafael Avila de Espindola <espindola@google.com> * common.opt (fversion): New. diff --git a/gcc/gcc-plugin.h b/gcc/gcc-plugin.h index 46f7e11c9bc..a76732b8ae0 100644 --- a/gcc/gcc-plugin.h +++ b/gcc/gcc-plugin.h @@ -27,6 +27,7 @@ enum plugin_event PLUGIN_FINISH_UNIT, /* Useful for summary processing. */ PLUGIN_CXX_CP_PRE_GENERICIZE, /* Allows to see low level AST in C++ FE. */ PLUGIN_FINISH, /* Called before GCC exits. */ + PLUGIN_INFO, /* Information about the plugin */ PLUGIN_EVENT_LAST /* Dummy event used for indexing callback array. */ }; @@ -55,6 +56,13 @@ struct plugin_pass enum pass_positioning_ops pos_op; /* how to insert the new pass. */ }; +/* Additional information about the plugin. Used by --help and --version. */ + +struct plugin_info +{ + const char *version; +}; + /* Function type for the plugin initialization routine. Each plugin module should define this as an externally-visible function with name "plugin_init." diff --git a/gcc/opts.c b/gcc/opts.c index 8f3c0c7b0f4..b2bfbbf7d0e 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -1580,7 +1580,6 @@ common_handle_option (size_t scode, const char *arg, int value, case OPT_fversion: case OPT__version: - print_version (stderr, ""); exit_after_options = true; break; diff --git a/gcc/plugin.c b/gcc/plugin.c index 9551eb866d6..b8c50c8c5d1 100644 --- a/gcc/plugin.c +++ b/gcc/plugin.c @@ -43,6 +43,7 @@ struct plugin_name_args const char *full_name; int argc; struct plugin_argument *argv; + const char *version; }; /* Hash table for the plugin_name_args objects created during command-line @@ -427,6 +428,16 @@ register_pass (const char *plugin_name, struct plugin_pass *pass_info) } } +/* Register additional plugin information. */ + +static void +register_plugin_info (const char* name, struct plugin_info *info) +{ + void **slot = htab_find_slot (plugin_name_args_tab, name, NO_INSERT); + struct plugin_name_args *plugin = (struct plugin_name_args *) *slot; + plugin->version = info->version; +} + /* Called from the plugin's initialization code. Register a single callback. This function can be called multiple times. @@ -446,6 +457,9 @@ register_callback (const char *plugin_name, case PLUGIN_PASS_MANAGER_SETUP: register_pass (plugin_name, (struct plugin_pass *) user_data); break; + case PLUGIN_INFO: + register_plugin_info (plugin_name, (struct plugin_info *) user_data); + break; case PLUGIN_FINISH_STRUCT: case PLUGIN_FINISH_UNIT: case PLUGIN_CXX_CP_PRE_GENERICIZE: @@ -511,18 +525,9 @@ invoke_plugin_callbacks (enum plugin_event event, void *gcc_data) #define PTR_UNION_AS_VOID_PTR(NAME) (NAME._q) #define PTR_UNION_AS_CAST_PTR(NAME) (NAME._nq) -/* Routine to dlopen and initialize one plugin. This function is passed to - (and called by) the hash table traverse routine. Return 1 for the - htab_traverse to continue scan, 0 to stop. - - SLOT - slot of the hash table element - INFO - auxiliary pointer handed to hash table traverse routine - (unused in this function) */ - -static int -init_one_plugin (void **slot, void * ARG_UNUSED (info)) +static bool +try_init_one_plugin (struct plugin_name_args *plugin) { - struct plugin_name_args *plugin = (struct plugin_name_args *) *slot; void *dl_handle; plugin_init_func plugin_init; char *err; @@ -532,7 +537,7 @@ init_one_plugin (void **slot, void * ARG_UNUSED (info)) if (!dl_handle) { error (G_("Cannot load plugin %s\n%s"), plugin->full_name, dlerror ()); - return 1; + return 0; } /* Clear any existing error. */ @@ -546,22 +551,37 @@ init_one_plugin (void **slot, void * ARG_UNUSED (info)) { error (G_("Cannot find %s in plugin %s\n%s"), str_plugin_init_func_name, plugin->full_name, err); - return 1; + return 0; } /* Call the plugin-provided initialization routine with the arguments. */ if ((*plugin_init) (plugin->base_name, plugin->argc, plugin->argv)) { error (G_("Fail to initialize plugin %s"), plugin->full_name); - return 1; + return 0; } - /* We can now delete the plugin_name_args object as it will no longer - be used. Note that base_name and argv fields (both of which were also - dynamically allocated) are not freed as they could still be used by - the plugin code. */ - XDELETE (plugin); + return 1; +} + +/* Routine to dlopen and initialize one plugin. This function is passed to + (and called by) the hash table traverse routine. Return 1 for the + htab_traverse to continue scan, 0 to stop. + + SLOT - slot of the hash table element + INFO - auxiliary pointer handed to hash table traverse routine + (unused in this function) */ +static int +init_one_plugin (void **slot, void * ARG_UNUSED (info)) +{ + struct plugin_name_args *plugin = (struct plugin_name_args *) *slot; + bool ok = try_init_one_plugin (plugin); + if (!ok) + { + htab_remove_elt (plugin_name_args_tab, plugin->base_name); + XDELETE (plugin); + } return 1; } @@ -577,8 +597,70 @@ initialize_plugins (void) /* Traverse and initialize each plugin specified in the command-line. */ htab_traverse_noresize (plugin_name_args_tab, init_one_plugin, NULL); +} + +/* Release memory used by one plugin. */ + +static int +finalize_one_plugin (void **slot, void * ARG_UNUSED (info)) +{ + struct plugin_name_args *plugin = (struct plugin_name_args *) *slot; + XDELETE (plugin); + return 1; +} + +/* Free memory allocated by the plugin system. */ + +void +finalize_plugins (void) +{ + if (!plugin_name_args_tab) + return; + + /* We can now delete the plugin_name_args object as it will no longer + be used. Note that base_name and argv fields (both of which were also + dynamically allocated) are not freed as they could still be used by + the plugin code. */ + + htab_traverse_noresize (plugin_name_args_tab, finalize_one_plugin, NULL); /* PLUGIN_NAME_ARGS_TAB is no longer needed, just delete it. */ htab_delete (plugin_name_args_tab); plugin_name_args_tab = NULL; } + +/* Used to pass options to htab_traverse callbacks. */ + +struct print_options +{ + FILE *file; + const char *indent; +}; + +/* Print the version of one plugin. */ + +static int +print_version_one_plugin (void **slot, void *data) +{ + struct print_options *opt = (struct print_options *) data; + struct plugin_name_args *plugin = (struct plugin_name_args *) *slot; + const char *version = plugin->version ? plugin->version : "Unknown version."; + + fprintf (opt->file, " %s%s: %s\n", opt->indent, plugin->base_name, version); + return 1; +} + +/* Print the version of each plugin. */ + +void +print_plugins_versions (FILE *file, const char *indent) +{ + struct print_options opt; + opt.file = file; + opt.indent = indent; + if (!plugin_name_args_tab || htab_elements (plugin_name_args_tab) == 0) + return; + + fprintf (file, "%sVersions of loaded plugins:\n", indent); + htab_traverse_noresize (plugin_name_args_tab, print_version_one_plugin, &opt); +} diff --git a/gcc/plugin.h b/gcc/plugin.h index 95f080278b1..3d7c6af590f 100644 --- a/gcc/plugin.h +++ b/gcc/plugin.h @@ -30,5 +30,10 @@ extern void parse_plugin_arg_opt (const char *arg); extern void invoke_plugin_callbacks (enum plugin_event event, void *gcc_data); /* Main plugin initialization function. */ extern void initialize_plugins (void); +/* Print the version of each plugin. */ +extern void print_plugins_versions (FILE *file, const char *indent); +/* Free memory allocated by the plugin system. */ +extern void finalize_plugins (void); + #endif /* PLUGIN_H */ diff --git a/gcc/toplev.c b/gcc/toplev.c index 63a6ddcbfd1..c9ee2a02632 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -968,7 +968,6 @@ compile_file (void) init_final (main_input_filename); coverage_init (aux_base_name); statistics_init (); - initialize_plugins (); timevar_push (TV_PARSE); @@ -1163,6 +1162,8 @@ print_version (FILE *file, const char *indent) file == stderr ? _(fmt4) : fmt4, indent, *indent != 0 ? " " : "", PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE)); + + print_plugins_versions (file, indent); } #ifdef ASM_COMMENT_START @@ -2270,6 +2271,11 @@ toplev_main (unsigned int argc, const char **argv) init_local_tick (); + initialize_plugins (); + + if (version_flag) + print_version (stderr, ""); + /* Exit early if we can (e.g. -help). */ if (!exit_after_options) do_compile (); @@ -2280,6 +2286,7 @@ toplev_main (unsigned int argc, const char **argv) /* Invoke registered plugin callbacks if any. */ invoke_plugin_callbacks (PLUGIN_FINISH, NULL); + finalize_plugins (); if (errorcount || sorrycount) return (FATAL_EXIT_CODE); |