mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-13 18:30:59 +08:00
c++: Template hash access
This exposes the template specialization table, so the modules machinery may access it. The hashed entity (tmpl, args & spec) is available, along with a hash table walker. We also need a way of finding or inserting entries, along with some bookkeeping fns to deal with the instantiation and (partial) specialization lists. gcc/cp/ * cp-tree.h (struct spec_entry): Moved from pt.c. (walk_specializations, match_mergeable_specialization) (get_mergeable_specialization_flags) (add_mergeable_specialization): Declare. * pt.c (struct spec_entry): Moved to cp-tree.h. (walk_specializations, match_mergeable_specialization) (get_mergeable_specialization_flags) (add_mergeable_specialization): New.
This commit is contained in:
parent
08b4d32571
commit
5bba2215c2
@ -5403,6 +5403,14 @@ public:
|
||||
hash_map<tree, tree> *saved;
|
||||
};
|
||||
|
||||
/* Entry in the specialization hash table. */
|
||||
struct GTY((for_user)) spec_entry
|
||||
{
|
||||
tree tmpl; /* The general template this is a specialization of. */
|
||||
tree args; /* The args for this (maybe-partial) specialization. */
|
||||
tree spec; /* The specialization itself. */
|
||||
};
|
||||
|
||||
/* in class.c */
|
||||
|
||||
extern int current_class_depth;
|
||||
@ -6994,6 +7002,15 @@ extern bool copy_guide_p (const_tree);
|
||||
extern bool template_guide_p (const_tree);
|
||||
extern bool builtin_guide_p (const_tree);
|
||||
extern void store_explicit_specifier (tree, tree);
|
||||
extern void walk_specializations (bool,
|
||||
void (*)(bool, spec_entry *,
|
||||
void *),
|
||||
void *);
|
||||
extern tree match_mergeable_specialization (bool is_decl, tree tmpl,
|
||||
tree args, tree spec);
|
||||
extern unsigned get_mergeable_specialization_flags (tree tmpl, tree spec);
|
||||
extern void add_mergeable_specialization (tree tmpl, tree args,
|
||||
tree spec, unsigned);
|
||||
extern tree add_outermost_template_args (tree, tree);
|
||||
extern tree add_extra_args (tree, tree);
|
||||
extern tree build_extra_args (tree, tree, tsubst_flags_t);
|
||||
|
102
gcc/cp/pt.c
102
gcc/cp/pt.c
@ -103,13 +103,6 @@ local_specialization_stack::~local_specialization_stack ()
|
||||
/* True if we've recursed into fn_type_unification too many times. */
|
||||
static bool excessive_deduction_depth;
|
||||
|
||||
struct GTY((for_user)) spec_entry
|
||||
{
|
||||
tree tmpl;
|
||||
tree args;
|
||||
tree spec;
|
||||
};
|
||||
|
||||
struct spec_hasher : ggc_ptr_hash<spec_entry>
|
||||
{
|
||||
static hashval_t hash (spec_entry *);
|
||||
@ -29625,6 +29618,101 @@ declare_integer_pack (void)
|
||||
CP_BUILT_IN_INTEGER_PACK);
|
||||
}
|
||||
|
||||
/* Walk the decl or type specialization table calling FN on each
|
||||
entry. */
|
||||
|
||||
void
|
||||
walk_specializations (bool decls_p,
|
||||
void (*fn) (bool decls_p, spec_entry *entry, void *data),
|
||||
void *data)
|
||||
{
|
||||
spec_hash_table *table = decls_p ? decl_specializations
|
||||
: type_specializations;
|
||||
spec_hash_table::iterator end (table->end ());
|
||||
for (spec_hash_table::iterator iter (table->begin ()); iter != end; ++iter)
|
||||
fn (decls_p, *iter, data);
|
||||
}
|
||||
|
||||
/* Lookup the specialization of TMPL, ARGS in the decl or type
|
||||
specialization table. Return what's there, or if SPEC is non-null,
|
||||
add it and return NULL. */
|
||||
|
||||
tree
|
||||
match_mergeable_specialization (bool decl_p, tree tmpl, tree args, tree spec)
|
||||
{
|
||||
spec_entry elt = {tmpl, args, spec};
|
||||
hash_table<spec_hasher> *specializations
|
||||
= decl_p ? decl_specializations : type_specializations;
|
||||
hashval_t hash = spec_hasher::hash (&elt);
|
||||
spec_entry **slot
|
||||
= specializations->find_slot_with_hash (&elt, hash,
|
||||
spec ? INSERT : NO_INSERT);
|
||||
spec_entry *entry = slot ? *slot: NULL;
|
||||
|
||||
if (entry)
|
||||
return entry->spec;
|
||||
|
||||
if (spec)
|
||||
{
|
||||
entry = ggc_alloc<spec_entry> ();
|
||||
*entry = elt;
|
||||
*slot = entry;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Return flags encoding whether SPEC is on the instantiation and/or
|
||||
specialization lists of TMPL. */
|
||||
|
||||
unsigned
|
||||
get_mergeable_specialization_flags (tree tmpl, tree decl)
|
||||
{
|
||||
unsigned flags = 0;
|
||||
|
||||
for (tree inst = DECL_TEMPLATE_INSTANTIATIONS (tmpl);
|
||||
inst; inst = TREE_CHAIN (inst))
|
||||
if (TREE_VALUE (inst) == decl)
|
||||
{
|
||||
flags |= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (CLASS_TYPE_P (TREE_TYPE (decl))
|
||||
&& CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl))
|
||||
&& CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)) == 2)
|
||||
/* Only need to search if DECL is a partial specialization. */
|
||||
for (tree part = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
|
||||
part; part = TREE_CHAIN (part))
|
||||
if (TREE_VALUE (part) == decl)
|
||||
{
|
||||
flags |= 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/* Add a new specialization of TMPL. FLAGS is as returned from
|
||||
get_mergeable_specialization_flags. */
|
||||
|
||||
void
|
||||
add_mergeable_specialization (tree tmpl, tree args, tree decl, unsigned flags)
|
||||
{
|
||||
if (flags & 1)
|
||||
DECL_TEMPLATE_INSTANTIATIONS (tmpl)
|
||||
= tree_cons (args, decl, DECL_TEMPLATE_INSTANTIATIONS (tmpl));
|
||||
|
||||
if (flags & 2)
|
||||
{
|
||||
/* A partial specialization. */
|
||||
DECL_TEMPLATE_SPECIALIZATIONS (tmpl)
|
||||
= tree_cons (args, decl, DECL_TEMPLATE_SPECIALIZATIONS (tmpl));
|
||||
TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (tmpl))
|
||||
= TREE_TYPE (DECL_TEMPLATE_RESULT (decl));
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up the hash tables for template instantiations. */
|
||||
|
||||
void
|
||||
|
Loading…
x
Reference in New Issue
Block a user