* c++: Template hash access
@ 2020-11-19 21:24 Nathan Sidwell
0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2020-11-19 21:24 UTC (permalink / raw)
To: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 989 bytes --]
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.
This is slightly modified from the earlier posting -- one of the
functions, used for checking, isn't needed as
match_mergeable_specialization is modified to allow that use.
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.
pushing to trunk
--
Nathan Sidwell
[-- Attachment #2: 18a-c++-infra-template.diff --]
[-- Type: text/x-patch, Size: 4628 bytes --]
diff --git i/gcc/cp/cp-tree.h w/gcc/cp/cp-tree.h
index 0c4b74a8895..021de76e142 100644
--- i/gcc/cp/cp-tree.h
+++ w/gcc/cp/cp-tree.h
@@ -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);
diff --git i/gcc/cp/pt.c w/gcc/cp/pt.c
index a1b6631d691..463b1c3a57d 100644
--- i/gcc/cp/pt.c
+++ w/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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-11-19 21:24 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-19 21:24 c++: Template hash access Nathan Sidwell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).