Mercurial > hg > CbC > CbC_gcc
diff gcc/plugin.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
line wrap: on
line diff
--- a/gcc/plugin.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/plugin.c Fri Oct 27 22:46:09 2017 +0900 @@ -1,5 +1,5 @@ /* Support for GCC plugin mechanism. - Copyright (C) 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2009-2017 Free Software Foundation, Inc. This file is part of GCC. @@ -23,13 +23,12 @@ #include "config.h" #include "system.h" #include "coretypes.h" +#include "options.h" +#include "tree-pass.h" #include "diagnostic-core.h" -#include "tree.h" -#include "tree-pass.h" +#include "flags.h" #include "intl.h" #include "plugin.h" -#include "timevar.h" -#include "ggc.h" #ifdef ENABLE_PLUGIN #include "plugin-version.h" @@ -51,9 +50,34 @@ const char **plugin_event_name = plugin_event_name_init; +/* Event hashtable helpers. */ + +struct event_hasher : nofree_ptr_hash <const char *> +{ + static inline hashval_t hash (const char **); + static inline bool equal (const char **, const char **); +}; + +/* Helper function for the event hash table that hashes the entry V. */ + +inline hashval_t +event_hasher::hash (const char **v) +{ + return htab_hash_string (*v); +} + +/* Helper function for the event hash table that compares the name of an + existing entry (S1) with the given string (S2). */ + +inline bool +event_hasher::equal (const char **s1, const char **s2) +{ + return !strcmp (*s1, *s2); +} + /* A hash table to map event names to the position of the names in the plugin_event_name table. */ -static htab_t event_tab; +static hash_table<event_hasher> *event_tab; /* Keep track of the limit of allocated events and space ready for allocating events. */ @@ -90,6 +114,16 @@ static const char *str_license = "plugin_is_GPL_compatible"; #endif +/* Helper function for hashing the base_name of the plugin_name_args + structure to be inserted into the hash table. */ + +static hashval_t +htab_hash_plugin (const PTR p) +{ + const struct plugin_name_args *plugin = (const struct plugin_name_args *) p; + return htab_hash_string (plugin->base_name); + } + /* Helper function for the hash table that compares the base_name of the existing entry (S1) with the given string (S2). */ @@ -149,7 +183,8 @@ plugin_name, ".so", NULL); if (access (plugin_name, R_OK)) fatal_error - ("inacessible plugin file %s expanded from short plugin name %s: %m", + (input_location, + "inaccessible plugin file %s expanded from short plugin name %s: %m", plugin_name, base_name); } else @@ -158,10 +193,11 @@ /* If this is the first -fplugin= option we encounter, create 'plugin_name_args_tab' hash table. */ if (!plugin_name_args_tab) - plugin_name_args_tab = htab_create (10, htab_hash_string, htab_str_eq, + plugin_name_args_tab = htab_create (10, htab_hash_plugin, htab_str_eq, NULL); - slot = htab_find_slot (plugin_name_args_tab, base_name, INSERT); + slot = htab_find_slot_with_hash (plugin_name_args_tab, base_name, + htab_hash_string (base_name), INSERT); /* If the same plugin (name) has been specified earlier, either emit an error or a warning message depending on if they have identical full @@ -214,16 +250,13 @@ } else if (*ptr == '=') { - if (key_parsed) - { - error ("malformed option -fplugin-arg-%s (multiple '=' signs)", - arg); - return; - } - key_len = len; - len = 0; - value_start = ptr + 1; - key_parsed = true; + if (!key_parsed) + { + key_len = len; + len = 0; + value_start = ptr + 1; + key_parsed = true; + } continue; } else @@ -251,7 +284,8 @@ /* Check if the named plugin has already been specified earlier in the command-line. */ if (plugin_name_args_tab - && ((slot = htab_find_slot (plugin_name_args_tab, name, NO_INSERT)) + && ((slot = htab_find_slot_with_hash (plugin_name_args_tab, name, + htab_hash_string (name), NO_INSERT)) != NULL)) { struct plugin_name_args *plugin = (struct plugin_name_args *) *slot; @@ -307,47 +341,46 @@ 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; + void **slot = htab_find_slot_with_hash (plugin_name_args_tab, name, + htab_hash_string (name), NO_INSERT); + struct plugin_name_args *plugin; + + if (slot == NULL) + { + error ("unable to register info for plugin %qs - plugin name not found", + name); + return; + } + plugin = (struct plugin_name_args *) *slot; plugin->version = info->version; plugin->help = info->help; } -/* Helper function for the event hash table that compares the name of an - existing entry (E1) with the given string (S2). */ - -static int -htab_event_eq (const void *e1, const void *s2) -{ - const char *s1= *(const char * const *) e1; - return !strcmp (s1, (const char *) s2); -} - /* Look up the event id for NAME. If the name is not found, return -1 if INSERT is NO_INSERT. */ int get_named_event_id (const char *name, enum insert_option insert) { - void **slot; + const char ***slot; if (!event_tab) { int i; - event_tab = htab_create (150, htab_hash_string, htab_event_eq, NULL); + event_tab = new hash_table<event_hasher> (150); for (i = 0; i < event_last; i++) { - slot = htab_find_slot (event_tab, plugin_event_name[i], INSERT); + slot = event_tab->find_slot (&plugin_event_name[i], INSERT); gcc_assert (*slot == HTAB_EMPTY_ENTRY); *slot = &plugin_event_name[i]; } } - slot = htab_find_slot (event_tab, name, insert); + slot = event_tab->find_slot (&name, insert); if (slot == NULL) return -1; if (*slot != HTAB_EMPTY_ENTRY) - return (const char **) *slot - &plugin_event_name[0]; + return *slot - &plugin_event_name[0]; if (event_last >= event_horizon) { @@ -369,7 +402,7 @@ plugin_callbacks, event_horizon); } /* All the pointers in the hash table will need to be updated. */ - htab_delete (event_tab); + delete event_tab; event_tab = NULL; } else @@ -406,10 +439,6 @@ gcc_assert (!callback); ggc_register_root_tab ((const struct ggc_root_tab*) user_data); break; - case PLUGIN_REGISTER_GGC_CACHES: - gcc_assert (!callback); - ggc_register_cache_tab ((const struct ggc_cache_tab*) user_data); - break; case PLUGIN_EVENT_FIRST_DYNAMIC: default: if (event < PLUGIN_EVENT_FIRST_DYNAMIC || event >= event_last) @@ -419,7 +448,10 @@ return; } /* Fall through. */ + case PLUGIN_START_PARSE_FUNCTION: + case PLUGIN_FINISH_PARSE_FUNCTION: case PLUGIN_FINISH_TYPE: + case PLUGIN_FINISH_DECL: case PLUGIN_START_UNIT: case PLUGIN_FINISH_UNIT: case PLUGIN_PRE_GENERICIZE: @@ -438,6 +470,7 @@ case PLUGIN_EARLY_GIMPLE_PASSES_START: case PLUGIN_EARLY_GIMPLE_PASSES_END: case PLUGIN_NEW_PASS: + case PLUGIN_INCLUDE_FILE: { struct callback_info *new_callback; if (!callback) @@ -495,7 +528,10 @@ gcc_assert (event >= PLUGIN_EVENT_FIRST_DYNAMIC); gcc_assert (event < event_last); /* Fall through. */ + case PLUGIN_START_PARSE_FUNCTION: + case PLUGIN_FINISH_PARSE_FUNCTION: case PLUGIN_FINISH_TYPE: + case PLUGIN_FINISH_DECL: case PLUGIN_START_UNIT: case PLUGIN_FINISH_UNIT: case PLUGIN_PRE_GENERICIZE: @@ -514,6 +550,7 @@ case PLUGIN_EARLY_GIMPLE_PASSES_START: case PLUGIN_EARLY_GIMPLE_PASSES_END: case PLUGIN_NEW_PASS: + case PLUGIN_INCLUDE_FILE: { /* Iterate over every callback registered with this event and call it. */ @@ -528,7 +565,6 @@ case PLUGIN_PASS_MANAGER_SETUP: case PLUGIN_REGISTER_GGC_ROOTS: - case PLUGIN_REGISTER_GGC_CACHES: gcc_assert (false); } @@ -571,7 +607,8 @@ /* Check the plugin license. */ if (dlsym (dl_handle, str_license) == NULL) - fatal_error ("plugin %s is not licensed under a GPL-compatible license\n" + fatal_error (input_location, + "plugin %s is not licensed under a GPL-compatible license\n" "%s", plugin->full_name, dlerror ()); PTR_UNION_AS_VOID_PTR (plugin_init_union) = @@ -580,6 +617,7 @@ if ((err = dlerror ()) != NULL) { + dlclose(dl_handle); error ("cannot find %s in plugin %s\n%s", str_plugin_init_func_name, plugin->full_name, err); return false; @@ -588,10 +626,12 @@ /* Call the plugin-provided initialization routine with the arguments. */ if ((*plugin_init) (plugin, &gcc_version)) { + dlclose(dl_handle); error ("fail to initialize plugin %s", plugin->full_name); return false; } - + /* leak dl_handle on purpose to ensure the plugin is loaded for the + entire run of the compiler. */ return true; } @@ -611,7 +651,8 @@ bool ok = try_init_one_plugin (plugin); if (!ok) { - htab_remove_elt (plugin_name_args_tab, plugin->base_name); + htab_remove_elt_with_hash (plugin_name_args_tab, plugin->base_name, + htab_hash_string (plugin->base_name)); XDELETE (plugin); } return 1; @@ -788,7 +829,7 @@ for (ci = plugin_callbacks[event]; ci; ci = ci->next) fprintf (file, " %s", ci->plugin_name); - putc('\n', file); + putc ('\n', file); } } @@ -817,16 +858,6 @@ } -/* Likewise, as a callback from the diagnostics code. */ - -void -plugins_internal_error_function (diagnostic_context *context ATTRIBUTE_UNUSED, - const char *msgid ATTRIBUTE_UNUSED, - va_list *ap ATTRIBUTE_UNUSED) -{ - warn_if_plugins (); -} - /* The default version check. Compares every field in VERSION. */ bool @@ -863,12 +894,13 @@ /* Retrieve the default plugin directory. The gcc driver should have passed - it as -iplugindir <dir> to the cc1 program, and it is queriable thru the + it as -iplugindir <dir> to the cc1 program, and it is queriable through the -print-file-name=plugin option to gcc. */ const char* default_plugin_dir_name (void) { if (!plugindir_string) - fatal_error ("-iplugindir <dir> option not passed from the gcc driver"); + fatal_error (input_location, + "-iplugindir <dir> option not passed from the gcc driver"); return plugindir_string; }