c++: template and clone fns for modules

We need to expose build_cdtor_clones, it fortunately has the desired
API -- gosh, how did that happen? :) The template machinery will need
to cache path-of-instantiation information, so add two more fields to
the tinst_level struct.  I also had to adjust the
match_mergeable_specialization API since adding it, so including that
change too.

	gcc/cp/
	* cp-tree.h (struct tinst_level): Add path & visible fields.
	(build_cdtor_clones): Declare.
	(match_mergeable_specialization): Use a spec_entry, add insert parm.
	* class.c (build_cdtor_clones): Externalize.
	* pt.c (push_tinst_level_loc): Clear new fields.
	(match_mergeable_specialization): Adjust API.
This commit is contained in:
Nathan Sidwell 2020-12-08 10:38:10 -08:00
parent 5312fa0fd9
commit dded5f78cc
3 changed files with 28 additions and 20 deletions

View file

@ -4920,7 +4920,7 @@ build_clone (tree fn, tree name, bool need_vtt_parm_p,
/* Build the clones of FN, return the number of clones built. These
will be inserted onto DECL_CHAIN of FN. */
static void
void
build_cdtor_clones (tree fn, bool needs_vtt_p, bool base_omits_inherited_p,
bool update_methods)
{

View file

@ -6196,6 +6196,13 @@ struct GTY((chain_next ("%h.next"))) tinst_level {
arguments. */
tree tldcl, targs;
/* For modules we need to know (a) the modules on the path of
instantiation and (b) the transitive imports along that path.
Note that these two bitmaps may be inherited from NEXT, if this
decl is in the same module as NEXT (or has no new information). */
bitmap path;
bitmap visible;
private:
/* Return TRUE iff the original node is a split list. */
bool split_list_p () const { return targs; }
@ -6497,6 +6504,7 @@ extern void check_abi_tags (tree);
extern tree missing_abi_tags (tree);
extern void fixup_type_variants (tree);
extern void fixup_attribute_variants (tree);
extern void build_cdtor_clones (tree, bool, bool, bool);
extern void clone_cdtor (tree, bool);
extern tree copy_operator_fn (tree, tree_code code);
extern void adjust_clone_args (tree);
@ -7189,8 +7197,8 @@ 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 tree match_mergeable_specialization (bool is_decl, spec_entry *,
bool insert = true);
extern unsigned get_mergeable_specialization_flags (tree tmpl, tree spec);
extern void add_mergeable_specialization (tree tmpl, tree args,
tree spec, unsigned);

View file

@ -1704,10 +1704,11 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
return spec;
}
/* Returns true iff two spec_entry nodes are equivalent. */
/* Restricts tree and type comparisons. */
int comparing_specializations;
/* Returns true iff two spec_entry nodes are equivalent. */
bool
spec_hasher::equal (spec_entry *e1, spec_entry *e2)
{
@ -10909,6 +10910,7 @@ push_tinst_level_loc (tree tldcl, tree targs, location_t loc)
new_level->errors = errorcount + sorrycount;
new_level->next = NULL;
new_level->refcount = 0;
new_level->path = new_level->visible = nullptr;
set_refcount_ptr (new_level->next, current_tinst_level);
set_refcount_ptr (current_tinst_level, new_level);
@ -29668,29 +29670,27 @@ walk_specializations (bool decls_p,
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. */
/* Lookup the specialization of *ELT, in the decl or type
specialization table. Return the SPEC that's already there (NULL if
nothing). If INSERT is true, and there was nothing, add the new
spec. */
tree
match_mergeable_specialization (bool decl_p, tree tmpl, tree args, tree spec)
match_mergeable_specialization (bool decl_p, spec_entry *elt, bool insert)
{
spec_entry elt = {tmpl, args, spec};
hash_table<spec_hasher> *specializations
= decl_p ? decl_specializations : type_specializations;
hashval_t hash = spec_hasher::hash (&elt);
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;
= specializations->find_slot_with_hash (elt, hash,
insert ? INSERT : NO_INSERT);
if (slot && *slot)
return (*slot)->spec;
if (spec)
if (insert)
{
entry = ggc_alloc<spec_entry> ();
*entry = elt;
auto entry = ggc_alloc<spec_entry> ();
*entry = *elt;
*slot = entry;
}