diff options
author | Nathan Sidwell <nathan@acm.org> | 2017-10-06 14:19:23 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2017-10-06 14:19:23 +0000 |
commit | 9bc3f4206615c69934344ea3681f9446bdc1a1f5 (patch) | |
tree | 1f36d628d50134cf505369a6074ff953c04e9e15 | |
parent | 513d5564225f8baa2ddeafde9edb9e10b62e30ce (diff) | |
download | gcc-9bc3f4206615c69934344ea3681f9446bdc1a1f5.zip gcc-9bc3f4206615c69934344ea3681f9446bdc1a1f5.tar.gz gcc-9bc3f4206615c69934344ea3681f9446bdc1a1f5.tar.bz2 |
[C++ PATCH] hash-table for extern-c fns.
https://gcc.gnu.org/ml/gcc-patches/2017-10/msg00376.html
Use hash_table for extern "C" names
* name-lookup.c (extern_c_fns): Use hash_table.
(check_extern_c_conflict): Adjust.
(c_linkage_bindings): Adjust.
From-SVN: r253493
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 50 |
2 files changed, 40 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ef053a5..7292fee 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2017-10-06 Nathan Sidwell <nathan@acm.org> + Use hash_table for extern "C" names + * name-lookup.c (extern_c_fns): Use hash_table. + (check_extern_c_conflict): Adjust. + (c_linkage_bindings): Adjust. + Use hash_table for namespace bindings * cp-tree.h (struct named_decl_hash): New. (lang_decl_ns): Change type of bindings field. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 84f7381..fb86310 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2511,9 +2511,9 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot, return decl; } -/* Map of identifiers to extern C functions (or LISTS thereof). */ +/* Table of identifiers to extern C functions (or LISTS thereof). */ -static GTY(()) hash_map<lang_identifier *, tree> *extern_c_fns; +static GTY(()) hash_table<named_decl_hash> *extern_c_fns; /* DECL has C linkage. If we have an existing instance, make sure it has the same exception specification [7.5, 7.6]. If there's no @@ -2527,17 +2527,15 @@ check_extern_c_conflict (tree decl) return; if (!extern_c_fns) - extern_c_fns = hash_map<lang_identifier *,tree>::create_ggc (127); + extern_c_fns = hash_table<named_decl_hash>::create_ggc (127); - bool existed; - tree *slot = &extern_c_fns->get_or_insert (DECL_NAME (decl), &existed); - if (!existed) - *slot = decl; - else + tree *slot = extern_c_fns + ->find_slot_with_hash (DECL_NAME (decl), + IDENTIFIER_HASH_VALUE (DECL_NAME (decl)), INSERT); + if (tree old = *slot) { - tree old = *slot; - if (TREE_CODE (old) == TREE_LIST) - old = TREE_VALUE (old); + if (TREE_CODE (old) == OVERLOAD) + old = OVL_FUNCTION (old); int mismatch = 0; if (DECL_CONTEXT (old) == DECL_CONTEXT (decl)) @@ -2563,9 +2561,24 @@ check_extern_c_conflict (tree decl) "due to different exception specifications"); } else - /* Chain it on for c_linkage_binding's use. */ - *slot = tree_cons (NULL_TREE, decl, *slot); + { + if (old == *slot) + /* The hash table expects OVERLOADS, so construct one with + OLD as both the function and the chain. This allocate + an excess OVERLOAD node, but it's rare to have multiple + extern "C" decls of the same name. And we save + complicating the hash table logic (which is used + elsewhere). */ + *slot = ovl_make (old, old); + + slot = &OVL_CHAIN (*slot); + + /* Chain it on for c_linkage_binding's use. */ + *slot = tree_cons (NULL_TREE, decl, *slot); + } } + else + *slot = decl; } /* Returns a list of C-linkage decls with the name NAME. Used in @@ -2575,8 +2588,15 @@ tree c_linkage_bindings (tree name) { if (extern_c_fns) - if (tree *slot = extern_c_fns->get (name)) - return *slot; + if (tree *slot = extern_c_fns + ->find_slot_with_hash (name, IDENTIFIER_HASH_VALUE (name), NO_INSERT)) + { + tree result = *slot; + if (TREE_CODE (result) == OVERLOAD) + result = OVL_CHAIN (result); + return result; + } + return NULL_TREE; } |