gcc-plugin.h (plugin_event): Add PLUGIN_INFO.
2009-04-16 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. Only free plugin_name_args if failed to init. (finalize_one_plugin): New. (finalize_plugins): New. (print_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. Print version if needed. Call finalize_plugins. From-SVN: r146187
This commit is contained in:
parent
c1c5e0faa8
commit
44e9f00678
@ -1,3 +1,25 @@
|
||||
2009-04-16 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. Only free plugin_name_args
|
||||
if failed to init.
|
||||
(finalize_one_plugin): New.
|
||||
(finalize_plugins): New.
|
||||
(print_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. Print version if needed.
|
||||
Call finalize_plugins.
|
||||
|
||||
2009-04-16 Rafael Avila de Espindola <espindola@google.com>
|
||||
|
||||
* common.opt (fversion): New.
|
||||
|
@ -28,6 +28,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. */
|
||||
};
|
||||
@ -58,6 +59,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."
|
||||
|
@ -1563,7 +1563,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;
|
||||
|
||||
|
126
gcc/plugin.c
126
gcc/plugin.c
@ -47,6 +47,7 @@ const char *plugin_event_name[] =
|
||||
"PLUGIN_FINISH_UNIT",
|
||||
"PLUGIN_CXX_CP_PRE_GENERICIZE",
|
||||
"PLUGIN_FINISH",
|
||||
"PLUGIN_INFO",
|
||||
"PLUGIN_EVENT_LAST"
|
||||
};
|
||||
|
||||
@ -59,6 +60,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
|
||||
@ -450,6 +452,17 @@ register_pass (const char *plugin_name, struct plugin_pass *pass_info)
|
||||
}
|
||||
|
||||
|
||||
/* Register additional plugin information. NAME is the name passed to
|
||||
plugin_init. INFO is the information that should be registered. */
|
||||
|
||||
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.
|
||||
|
||||
@ -469,6 +482,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_TYPE:
|
||||
case PLUGIN_FINISH_UNIT:
|
||||
case PLUGIN_CXX_CP_PRE_GENERICIZE:
|
||||
@ -541,18 +557,11 @@ 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.
|
||||
/* Try to initialize PLUGIN. Return true if successful. */
|
||||
|
||||
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;
|
||||
@ -562,7 +571,7 @@ init_one_plugin (void **slot, void * ARG_UNUSED (info))
|
||||
if (!dl_handle)
|
||||
{
|
||||
error ("Cannot load plugin %s\n%s", plugin->full_name, dlerror ());
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Clear any existing error. */
|
||||
@ -576,24 +585,41 @@ init_one_plugin (void **slot, void * ARG_UNUSED (info))
|
||||
{
|
||||
error ("Cannot find %s in plugin %s\n%s", str_plugin_init_func_name,
|
||||
plugin->full_name, err);
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Call the plugin-provided initialization routine with the arguments. */
|
||||
if ((*plugin_init) (plugin->base_name, plugin->argc, plugin->argv))
|
||||
{
|
||||
error ("Fail to initialize plugin %s", plugin->full_name);
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 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 true;
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_PLUGIN */
|
||||
|
||||
/* Main plugin initialization function. Called from compile_file() in
|
||||
@ -613,11 +639,73 @@ initialize_plugins (void)
|
||||
htab_traverse_noresize (plugin_name_args_tab, init_one_plugin, NULL);
|
||||
#endif
|
||||
|
||||
timevar_pop (TV_PLUGIN_INIT);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
timevar_pop (TV_PLUGIN_INIT);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,5 +29,7 @@ extern void initialize_plugins (void);
|
||||
extern bool plugins_active_p (void);
|
||||
extern void dump_active_plugins (FILE *);
|
||||
extern void debug_active_plugins (void);
|
||||
extern void print_plugins_versions (FILE *file, const char *indent);
|
||||
extern void finalize_plugins (void);
|
||||
|
||||
#endif /* PLUGIN_H */
|
||||
|
@ -969,7 +969,6 @@ compile_file (void)
|
||||
init_final (main_input_filename);
|
||||
coverage_init (aux_base_name);
|
||||
statistics_init ();
|
||||
initialize_plugins ();
|
||||
|
||||
timevar_push (TV_PARSE);
|
||||
|
||||
@ -1164,6 +1163,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
|
||||
@ -2273,6 +2274,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 ();
|
||||
@ -2283,6 +2289,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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user