Commit eead34af by Nathan Sidwell Committed by Nathan Sidwell

[C++ PATCH] Hash mangling alias

https://gcc.gnu.org/ml/gcc-patches/2017-10/msg00618.html
	* decl2.c (struct mangled_decl_hash): New hash traits.
	(mangled_decls): Make hash_table<mangled_decl_hash>.
	(generate_mangling_alias, record_mangling): Adjust.

From-SVN: r253608
parent 24d8f6b6
2017-10-10 Nathan Sidwell <nathan@acm.org>
* decl2.c (struct mangled_decl_hash): New hash traits.
(mangled_decls): Make hash_table<mangled_decl_hash>.
(generate_mangling_alias, record_mangling): Adjust.
2017-10-10 Jason Merrill <jason@redhat.com> 2017-10-10 Jason Merrill <jason@redhat.com>
More delayed lambda capture fixes. More delayed lambda capture fixes.
......
...@@ -102,9 +102,35 @@ static GTY(()) vec<tree, va_gc> *no_linkage_decls; ...@@ -102,9 +102,35 @@ static GTY(()) vec<tree, va_gc> *no_linkage_decls;
is to be an alias for the former if the former is defined. */ is to be an alias for the former if the former is defined. */
static GTY(()) vec<tree, va_gc> *mangling_aliases; static GTY(()) vec<tree, va_gc> *mangling_aliases;
/* A hash table of mangled names to decls. Used to figure out if we /* hash traits for declarations. Hashes single decls via
need compatibility aliases. */ DECL_ASSEMBLER_NAME. */
static GTY(()) hash_map<lang_identifier *, tree> *mangled_decls;
struct mangled_decl_hash : ggc_remove <tree>
{
typedef tree value_type; /* A DECL. */
typedef tree compare_type; /* An identifier. */
static hashval_t hash (const value_type decl)
{
return IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (decl));
}
static bool equal (const value_type existing, compare_type candidate)
{
tree name = DECL_ASSEMBLER_NAME (existing);
return candidate == name;
}
static inline void mark_empty (value_type &p) {p = NULL_TREE;}
static inline bool is_empty (value_type p) {return !p;}
/* Nothing is deletable. Everything is insertable. */
static bool is_deleted (value_type) { return false; }
static void mark_deleted (value_type) { gcc_unreachable (); }
};
/* A hash table of decls keyed by mangled name. Used to figure out if
we need compatibility aliases. */
static GTY(()) hash_table<mangled_decl_hash> *mangled_decls;
/* Nonzero if we're done parsing and into end-of-file activities. */ /* Nonzero if we're done parsing and into end-of-file activities. */
...@@ -4304,12 +4330,13 @@ generate_mangling_alias (tree decl, tree id2) ...@@ -4304,12 +4330,13 @@ generate_mangling_alias (tree decl, tree id2)
return; return;
} }
bool existed; tree *slot
tree *slot = &mangled_decls->get_or_insert (id2, &existed); = mangled_decls->find_slot_with_hash (id2, IDENTIFIER_HASH_VALUE (id2),
INSERT);
/* If there's a declaration already using this mangled name, /* If there's a declaration already using this mangled name,
don't create a compatibility alias that conflicts. */ don't create a compatibility alias that conflicts. */
if (existed) if (*slot)
return; return;
tree alias = make_alias_for (decl, id2); tree alias = make_alias_for (decl, id2);
...@@ -4369,24 +4396,25 @@ void ...@@ -4369,24 +4396,25 @@ void
record_mangling (tree decl, bool need_warning) record_mangling (tree decl, bool need_warning)
{ {
if (!mangled_decls) if (!mangled_decls)
mangled_decls = hash_map<lang_identifier *, tree>::create_ggc (499); mangled_decls = hash_table<mangled_decl_hash>::create_ggc (499);
gcc_checking_assert (DECL_ASSEMBLER_NAME_SET_P (decl)); gcc_checking_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
tree id = DECL_ASSEMBLER_NAME (decl); tree id = DECL_ASSEMBLER_NAME (decl);
bool existed; tree *slot
tree *slot = &mangled_decls->get_or_insert (id, &existed); = mangled_decls->find_slot_with_hash (id, IDENTIFIER_HASH_VALUE (id),
INSERT);
/* If this is already an alias, remove the alias, because the real /* If this is already an alias, remove the alias, because the real
decl takes precedence. */ decl takes precedence. */
if (existed && DECL_ARTIFICIAL (*slot) && DECL_IGNORED_P (*slot)) if (*slot && DECL_ARTIFICIAL (*slot) && DECL_IGNORED_P (*slot))
if (symtab_node *n = symtab_node::get (*slot)) if (symtab_node *n = symtab_node::get (*slot))
if (n->cpp_implicit_alias) if (n->cpp_implicit_alias)
{ {
n->remove (); n->remove ();
existed = false; *slot = NULL_TREE;
} }
if (!existed) if (!*slot)
*slot = decl; *slot = decl;
else if (need_warning) else if (need_warning)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment