c++: imported templates and alias-template changes [PR 99283]
During development of modules, I had difficulty deciding whether the
module flags of a template should live on the decl_template_result,
the template_decl, or both. I chose the latter, and require them to
be consistent. This and a few other defects show how hard that
consistency is. Hence this patch move to holding the flags on the
template-decl-result decl. That's the entity various bits of the
parser have at the appropriate time. Once needs STRIP_TEMPLATE in a
bunch of places, which this patch adds. Also a check that we never
give a TEMPLATE_DECL to the module flag accessors.
This left a problem with how I was handling template aliases. These
were in two parts -- separating the TEMPLATE_DECL from the TYPE_DECL.
That seemed somewhat funky, but development showed it necessary. Of
course, that causes problems if the TEMPLATE_DECL cannot contain 'am
imported' information. Investigating now shows that we do not need to
treat them separately. By reverting a bit of template instantiation
machinery that caused the problem, we're back on course. I think what
has happened is that between then and now, other typedef fixes have
corrected the underlying problem this separation was working around.
It allows a bunch of cleanup in the decl streamer, as we no longer
have to handle a null TEMPLATE_DECL_RESULT.
PR c++/99283
gcc/cp/
* cp-tree.h (DECL_MODULE_CHECK): Ban TEMPLATE_DECL.
(SET_TYPE_TEMPLATE_INFO): Restore Alias template setting.
* decl.c (duplicate_decls): Remove template_decl module flag
propagation.
* module.cc (merge_kind_name): Add alias tmpl spec as a thing.
(dumper::impl::nested_name): Adjust for template-decl module flag
change.
(trees_in::assert_definition): Likewise.
(trees_in::install_entity): Likewise.
(trees_out::decl_value): Likewise. Remove alias template
separation of template and type_decl.
(trees_in::decl_value): Likewise.
(trees_out::key_mergeable): Likewise,
(trees_in::key_mergeable): Likewise.
(trees_out::decl_node): Adjust for template-decl module flag
change.
(depset:#️⃣:make_dependency): Likewise.
(get_originating_module, module_may_redeclare): Likewise.
(set_instantiating_module, set_defining_module): Likewise.
* name-lookup.c (name_lookup::search_adl): Likewise.
(do_pushdecl): Likewise.
* pt.c (build_template_decl): Likewise.
(lookup_template_class_1): Remove special alias_template handling
of DECL_TI_TEMPLATE.
(tsubst_template_decl): Likewise.
gcc/testsuite/
* g++.dg/modules/pr99283-2_a.H: New.
* g++.dg/modules/pr99283-2_b.H: New.
* g++.dg/modules/pr99283-2_c.H: New.
* g++.dg/modules/pr99283-3_a.H: New.
* g++.dg/modules/pr99283-3_b.H: New.
* g++.dg/modules/pr99283-4.H: New.
* g++.dg/modules/tpl-alias-1_a.H: Adjust scans.
* g++.dg/modules/tpl-alias-1_b.C: Adjust scans.
This commit is contained in:
parent
c314741a53
commit
d82797420c
@ -1661,9 +1661,11 @@ check_constraint_info (tree t)
|
||||
#define CONSTRAINED_PARM_PROTOTYPE(NODE) \
|
||||
DECL_INITIAL (TYPE_DECL_CHECK (NODE))
|
||||
|
||||
/* Module defines. */
|
||||
// Too many _DECLS: FUNCTION,VAR,TYPE,TEMPLATE,CONCEPT or NAMESPACE
|
||||
#define DECL_MODULE_CHECK(NODE) (NODE)
|
||||
/* Module flags on FUNCTION,VAR,TYPE,CONCEPT or NAMESPACE
|
||||
A TEMPLATE_DECL holds them on the DECL_TEMPLATE_RESULT object --
|
||||
it's just not practical to keep them consistent. */
|
||||
#define DECL_MODULE_CHECK(NODE) \
|
||||
TREE_NOT_CHECK (NODE, TEMPLATE_DECL)
|
||||
|
||||
/* In the purview of a module (including header unit). */
|
||||
#define DECL_MODULE_PURVIEW_P(N) \
|
||||
@ -3626,9 +3628,10 @@ struct GTY(()) lang_decl {
|
||||
/* Set the template information for a non-alias n ENUMERAL_, RECORD_,
|
||||
or UNION_TYPE to VAL. ALIAS's are dealt with separately. */
|
||||
#define SET_TYPE_TEMPLATE_INFO(NODE, VAL) \
|
||||
(gcc_checking_assert (TREE_CODE (NODE) == ENUMERAL_TYPE \
|
||||
|| (CLASS_TYPE_P (NODE) && !TYPE_ALIAS_P (NODE))), \
|
||||
(TYPE_LANG_SLOT_1 (NODE) = (VAL))) \
|
||||
(TREE_CODE (NODE) == ENUMERAL_TYPE \
|
||||
|| (CLASS_TYPE_P (NODE) && !TYPE_ALIAS_P (NODE)) \
|
||||
? (TYPE_LANG_SLOT_1 (NODE) = (VAL)) \
|
||||
: (DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) = (VAL))) \
|
||||
|
||||
#define TI_TEMPLATE(NODE) \
|
||||
((struct tree_template_info*)TEMPLATE_INFO_CHECK (NODE))->tmpl
|
||||
|
||||
@ -2275,10 +2275,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
|
||||
}
|
||||
}
|
||||
|
||||
DECL_MODULE_IMPORT_P (olddecl)
|
||||
= DECL_MODULE_IMPORT_P (old_result)
|
||||
= DECL_MODULE_IMPORT_P (newdecl);
|
||||
|
||||
return olddecl;
|
||||
}
|
||||
|
||||
@ -2931,19 +2927,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
|
||||
}
|
||||
}
|
||||
|
||||
if (DECL_LANG_SPECIFIC (olddecl) && DECL_TEMPLATE_INFO (olddecl))
|
||||
{
|
||||
/* Repropagate the module information to the template. */
|
||||
tree tmpl = DECL_TI_TEMPLATE (olddecl);
|
||||
|
||||
if (DECL_TEMPLATE_RESULT (tmpl) == olddecl)
|
||||
{
|
||||
DECL_MODULE_PURVIEW_P (tmpl) = DECL_MODULE_PURVIEW_P (olddecl);
|
||||
gcc_checking_assert (!DECL_MODULE_IMPORT_P (olddecl));
|
||||
DECL_MODULE_IMPORT_P (tmpl) = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (VAR_OR_FUNCTION_DECL_P (newdecl))
|
||||
{
|
||||
if (DECL_EXTERNAL (olddecl)
|
||||
|
||||
286
gcc/cp/module.cc
286
gcc/cp/module.cc
@ -2797,7 +2797,7 @@ static char const *const merge_kind_name[MK_hwm] =
|
||||
NULL, NULL,
|
||||
|
||||
"decl spec", "decl tmpl spec", /* 20,21 decl (template). */
|
||||
"alias spec", NULL, /* 22,23 alias. */
|
||||
"alias spec", "alias tmpl spec", /* 22,23 alias (template). */
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
};
|
||||
@ -4144,10 +4144,17 @@ dumper::impl::nested_name (tree t)
|
||||
if (ti && TREE_CODE (TI_TEMPLATE (ti)) == TEMPLATE_DECL
|
||||
&& (DECL_TEMPLATE_RESULT (TI_TEMPLATE (ti)) == t))
|
||||
t = TI_TEMPLATE (ti);
|
||||
tree not_tmpl = t;
|
||||
if (TREE_CODE (t) == TEMPLATE_DECL)
|
||||
fputs ("template ", stream);
|
||||
{
|
||||
fputs ("template ", stream);
|
||||
not_tmpl = DECL_TEMPLATE_RESULT (t);
|
||||
}
|
||||
|
||||
if (DECL_LANG_SPECIFIC (t) && DECL_MODULE_IMPORT_P (t))
|
||||
if (not_tmpl
|
||||
&& DECL_P (not_tmpl)
|
||||
&& DECL_LANG_SPECIFIC (not_tmpl)
|
||||
&& DECL_MODULE_IMPORT_P (not_tmpl))
|
||||
{
|
||||
/* We need to be careful here, so as to not explode on
|
||||
inconsistent data -- we're probably debugging, because
|
||||
@ -4484,9 +4491,9 @@ trees_in::assert_definition (tree decl ATTRIBUTE_UNUSED,
|
||||
gcc_assert (!is_duplicate (decl)
|
||||
? !slot
|
||||
: (slot
|
||||
|| !DECL_LANG_SPECIFIC (decl)
|
||||
|| !DECL_MODULE_PURVIEW_P (decl)
|
||||
|| (!DECL_MODULE_IMPORT_P (decl)
|
||||
|| !DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl))
|
||||
|| !DECL_MODULE_PURVIEW_P (STRIP_TEMPLATE (decl))
|
||||
|| (!DECL_MODULE_IMPORT_P (STRIP_TEMPLATE (decl))
|
||||
&& header_module_p ())));
|
||||
|
||||
if (TREE_CODE (decl) == TEMPLATE_DECL)
|
||||
@ -7445,11 +7452,12 @@ trees_in::install_entity (tree decl)
|
||||
(*entity_ary)[ident] = decl;
|
||||
|
||||
/* And into the entity map, if it's not already there. */
|
||||
if (!DECL_LANG_SPECIFIC (decl)
|
||||
|| !DECL_MODULE_ENTITY_P (decl))
|
||||
tree not_tmpl = STRIP_TEMPLATE (decl);
|
||||
if (!DECL_LANG_SPECIFIC (not_tmpl)
|
||||
|| !DECL_MODULE_ENTITY_P (not_tmpl))
|
||||
{
|
||||
retrofit_lang_decl (decl);
|
||||
DECL_MODULE_ENTITY_P (decl) = true;
|
||||
retrofit_lang_decl (not_tmpl);
|
||||
DECL_MODULE_ENTITY_P (not_tmpl) = true;
|
||||
|
||||
/* Insert into the entity hash (it cannot already be there). */
|
||||
bool existed;
|
||||
@ -7510,12 +7518,11 @@ trees_out::decl_value (tree decl, depset *dep)
|
||||
tree o = get_originating_module_decl (decl);
|
||||
bool is_mod = false;
|
||||
|
||||
if (dep && dep->is_alias_tmpl_inst ())
|
||||
/* Alias template instantiations are templatey, but
|
||||
found by name. */
|
||||
is_mod = false;
|
||||
else if (DECL_LANG_SPECIFIC (o) && DECL_MODULE_PURVIEW_P (o))
|
||||
tree not_tmpl = STRIP_TEMPLATE (o);
|
||||
if (DECL_LANG_SPECIFIC (not_tmpl)
|
||||
&& DECL_MODULE_PURVIEW_P (not_tmpl))
|
||||
is_mod = true;
|
||||
|
||||
b (is_mod);
|
||||
}
|
||||
b (dep && dep->has_defn ());
|
||||
@ -7533,26 +7540,18 @@ trees_out::decl_value (tree decl, depset *dep)
|
||||
int inner_tag = 0;
|
||||
if (TREE_CODE (decl) == TEMPLATE_DECL)
|
||||
{
|
||||
if (dep && dep->is_alias_tmpl_inst ())
|
||||
inner = NULL_TREE;
|
||||
else
|
||||
{
|
||||
inner = DECL_TEMPLATE_RESULT (decl);
|
||||
inner_tag = insert (inner, WK_value);
|
||||
}
|
||||
inner = DECL_TEMPLATE_RESULT (decl);
|
||||
inner_tag = insert (inner, WK_value);
|
||||
|
||||
if (streaming_p ())
|
||||
{
|
||||
int code = inner ? TREE_CODE (inner) : 0;
|
||||
int code = TREE_CODE (inner);
|
||||
u (code);
|
||||
if (inner)
|
||||
{
|
||||
start (inner, true);
|
||||
tree_node_bools (inner);
|
||||
dump (dumper::TREE)
|
||||
&& dump ("Writing %s:%d %C:%N%S", merge_kind_name[mk], inner_tag,
|
||||
TREE_CODE (inner), inner, inner);
|
||||
}
|
||||
start (inner, true);
|
||||
tree_node_bools (inner);
|
||||
dump (dumper::TREE)
|
||||
&& dump ("Writing %s:%d %C:%N%S", merge_kind_name[mk], inner_tag,
|
||||
TREE_CODE (inner), inner, inner);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7560,7 +7559,7 @@ trees_out::decl_value (tree decl, depset *dep)
|
||||
int type_tag = 0;
|
||||
tree stub_decl = NULL_TREE;
|
||||
int stub_tag = 0;
|
||||
if (inner && TREE_CODE (inner) == TYPE_DECL)
|
||||
if (TREE_CODE (inner) == TYPE_DECL)
|
||||
{
|
||||
type = TREE_TYPE (inner);
|
||||
bool has_type = (type == TYPE_MAIN_VARIANT (type)
|
||||
@ -7612,7 +7611,7 @@ trees_out::decl_value (tree decl, depset *dep)
|
||||
unsigned tpl_levels = 0;
|
||||
if (decl != inner)
|
||||
tpl_header (decl, &tpl_levels);
|
||||
if (inner && TREE_CODE (inner) == FUNCTION_DECL)
|
||||
if (TREE_CODE (inner) == FUNCTION_DECL)
|
||||
fn_parms_init (inner);
|
||||
|
||||
/* Now write out the merging information, and then really
|
||||
@ -7624,7 +7623,7 @@ trees_out::decl_value (tree decl, depset *dep)
|
||||
&& dump ("Wrote:%d's %s merge key %C:%N", tag,
|
||||
merge_kind_name[mk], TREE_CODE (decl), decl);
|
||||
|
||||
if (inner && TREE_CODE (inner) == FUNCTION_DECL)
|
||||
if (TREE_CODE (inner) == FUNCTION_DECL)
|
||||
fn_parms_fini (inner);
|
||||
|
||||
if (!is_key_order ())
|
||||
@ -7636,18 +7635,6 @@ trees_out::decl_value (tree decl, depset *dep)
|
||||
tree_node_vals (inner);
|
||||
tpl_parms_fini (decl, tpl_levels);
|
||||
}
|
||||
else if (!inner)
|
||||
{
|
||||
/* A template alias instantiation. */
|
||||
inner = DECL_TEMPLATE_RESULT (decl);
|
||||
if (!is_key_order ())
|
||||
tree_node (inner);
|
||||
if (streaming_p ())
|
||||
dump (dumper::TREE)
|
||||
&& dump ("Wrote(%d) alias template %C:%N",
|
||||
get_tag (inner), TREE_CODE (inner), inner);
|
||||
inner = NULL_TREE;
|
||||
}
|
||||
|
||||
if (type && !is_key_order ())
|
||||
{
|
||||
@ -7693,8 +7680,7 @@ trees_out::decl_value (tree decl, depset *dep)
|
||||
install_entity (decl, dep);
|
||||
}
|
||||
|
||||
if (inner
|
||||
&& VAR_OR_FUNCTION_DECL_P (inner)
|
||||
if (VAR_OR_FUNCTION_DECL_P (inner)
|
||||
&& DECL_LANG_SPECIFIC (inner)
|
||||
&& DECL_MODULE_ATTACHMENTS_P (inner)
|
||||
&& !is_key_order ())
|
||||
@ -7715,7 +7701,7 @@ trees_out::decl_value (tree decl, depset *dep)
|
||||
}
|
||||
|
||||
bool is_typedef = false;
|
||||
if (!type && inner && TREE_CODE (inner) == TYPE_DECL)
|
||||
if (!type && TREE_CODE (inner) == TYPE_DECL)
|
||||
{
|
||||
tree t = TREE_TYPE (inner);
|
||||
unsigned tdef_flags = 0;
|
||||
@ -7766,10 +7752,9 @@ trees_out::decl_value (tree decl, depset *dep)
|
||||
dump (dumper::TREE) && dump ("Written decl:%d %C:%N", tag,
|
||||
TREE_CODE (decl), decl);
|
||||
|
||||
if (!inner || NAMESPACE_SCOPE_P (inner))
|
||||
gcc_checking_assert (!inner
|
||||
|| !dep == (VAR_OR_FUNCTION_DECL_P (inner)
|
||||
&& DECL_LOCAL_DECL_P (inner)));
|
||||
if (NAMESPACE_SCOPE_P (inner))
|
||||
gcc_checking_assert (!dep == (VAR_OR_FUNCTION_DECL_P (inner)
|
||||
&& DECL_LOCAL_DECL_P (inner)));
|
||||
else if ((TREE_CODE (inner) == TYPE_DECL
|
||||
&& !is_typedef
|
||||
&& TYPE_NAME (TREE_TYPE (inner)) == inner)
|
||||
@ -7828,31 +7813,23 @@ trees_in::decl_value ()
|
||||
if (decl && TREE_CODE (decl) == TEMPLATE_DECL)
|
||||
{
|
||||
int code = u ();
|
||||
if (!code)
|
||||
{
|
||||
inner = NULL_TREE;
|
||||
DECL_TEMPLATE_RESULT (decl) = error_mark_node;
|
||||
}
|
||||
inner = start (code);
|
||||
if (inner && tree_node_bools (inner))
|
||||
DECL_TEMPLATE_RESULT (decl) = inner;
|
||||
else
|
||||
{
|
||||
inner = start (code);
|
||||
if (inner && tree_node_bools (inner))
|
||||
DECL_TEMPLATE_RESULT (decl) = inner;
|
||||
else
|
||||
decl = NULL_TREE;
|
||||
decl = NULL_TREE;
|
||||
|
||||
inner_tag = insert (inner);
|
||||
if (decl)
|
||||
dump (dumper::TREE)
|
||||
&& dump ("Reading:%d %C", inner_tag, TREE_CODE (inner));
|
||||
}
|
||||
inner_tag = insert (inner);
|
||||
if (decl)
|
||||
dump (dumper::TREE)
|
||||
&& dump ("Reading:%d %C", inner_tag, TREE_CODE (inner));
|
||||
}
|
||||
|
||||
tree type = NULL_TREE;
|
||||
int type_tag = 0;
|
||||
tree stub_decl = NULL_TREE;
|
||||
int stub_tag = 0;
|
||||
if (decl && inner && TREE_CODE (inner) == TYPE_DECL)
|
||||
if (decl && TREE_CODE (inner) == TYPE_DECL)
|
||||
{
|
||||
if (unsigned type_code = u ())
|
||||
{
|
||||
@ -7917,7 +7894,7 @@ trees_in::decl_value ()
|
||||
if (decl != inner)
|
||||
if (!tpl_header (decl, &tpl_levels))
|
||||
goto bail;
|
||||
if (inner && TREE_CODE (inner) == FUNCTION_DECL)
|
||||
if (TREE_CODE (inner) == FUNCTION_DECL)
|
||||
parm_tag = fn_parms_init (inner);
|
||||
|
||||
tree existing = key_mergeable (tag, mk, decl, inner, type, container, is_mod);
|
||||
@ -7972,15 +7949,6 @@ trees_in::decl_value ()
|
||||
if (!tpl_parms_fini (decl, tpl_levels))
|
||||
goto bail;
|
||||
}
|
||||
else if (!inner)
|
||||
{
|
||||
inner = tree_node ();
|
||||
DECL_TEMPLATE_RESULT (decl) = inner;
|
||||
TREE_TYPE (decl) = TREE_TYPE (inner);
|
||||
dump (dumper::TREE)
|
||||
&& dump ("Read alias template %C:%N", TREE_CODE (inner), inner);
|
||||
inner = NULL_TREE;
|
||||
}
|
||||
|
||||
if (type && (!tree_node_vals (type)
|
||||
|| (stub_decl && !tree_node_vals (stub_decl))))
|
||||
@ -8009,8 +7977,7 @@ trees_in::decl_value ()
|
||||
bool installed = install_entity (existing);
|
||||
bool is_new = existing == decl;
|
||||
|
||||
if (inner
|
||||
&& VAR_OR_FUNCTION_DECL_P (inner)
|
||||
if (VAR_OR_FUNCTION_DECL_P (inner)
|
||||
&& DECL_LANG_SPECIFIC (inner)
|
||||
&& DECL_MODULE_ATTACHMENTS_P (inner))
|
||||
{
|
||||
@ -8039,7 +8006,7 @@ trees_in::decl_value ()
|
||||
/* Regular typedefs will have a NULL TREE_TYPE at this point. */
|
||||
unsigned tdef_flags = 0;
|
||||
bool is_typedef = false;
|
||||
if (!type && inner && TREE_CODE (inner) == TYPE_DECL)
|
||||
if (!type && TREE_CODE (inner) == TYPE_DECL)
|
||||
{
|
||||
tdef_flags = u ();
|
||||
if (tdef_flags & 1)
|
||||
@ -8056,15 +8023,9 @@ trees_in::decl_value ()
|
||||
|
||||
if (installed)
|
||||
{
|
||||
/* Mark the entity as imported and add it to the entity
|
||||
array and map. */
|
||||
retrofit_lang_decl (decl);
|
||||
DECL_MODULE_IMPORT_P (decl) = true;
|
||||
if (inner_tag)
|
||||
{
|
||||
retrofit_lang_decl (inner);
|
||||
DECL_MODULE_IMPORT_P (inner) = true;
|
||||
}
|
||||
/* Mark the entity as imported. */
|
||||
retrofit_lang_decl (inner);
|
||||
DECL_MODULE_IMPORT_P (inner) = true;
|
||||
}
|
||||
|
||||
if (spec.spec)
|
||||
@ -8158,7 +8119,7 @@ trees_in::decl_value ()
|
||||
if (!is_matching_decl (existing, decl, is_typedef))
|
||||
unmatched_duplicate (existing);
|
||||
|
||||
if (inner && TREE_CODE (inner) == FUNCTION_DECL)
|
||||
if (TREE_CODE (inner) == FUNCTION_DECL)
|
||||
{
|
||||
tree e_inner = STRIP_TEMPLATE (existing);
|
||||
for (auto parm = DECL_ARGUMENTS (inner);
|
||||
@ -8211,8 +8172,7 @@ trees_in::decl_value ()
|
||||
}
|
||||
}
|
||||
|
||||
if (inner
|
||||
&& !NAMESPACE_SCOPE_P (inner)
|
||||
if (!NAMESPACE_SCOPE_P (inner)
|
||||
&& ((TREE_CODE (inner) == TYPE_DECL
|
||||
&& !is_typedef
|
||||
&& TYPE_NAME (TREE_TYPE (inner)) == inner)
|
||||
@ -8550,7 +8510,8 @@ trees_out::decl_node (tree decl, walk_kind ref)
|
||||
else if (TREE_CODE (ctx) != FUNCTION_DECL
|
||||
|| TREE_CODE (decl) == TEMPLATE_DECL
|
||||
|| (dep_hash->sneakoscope && DECL_IMPLICIT_TYPEDEF_P (decl))
|
||||
|| (DECL_LANG_SPECIFIC (decl) && DECL_MODULE_IMPORT_P (decl)))
|
||||
|| (DECL_LANG_SPECIFIC (decl)
|
||||
&& DECL_MODULE_IMPORT_P (decl)))
|
||||
{
|
||||
auto kind = (TREE_CODE (decl) == NAMESPACE_DECL
|
||||
&& !DECL_NAMESPACE_ALIAS (decl)
|
||||
@ -8607,6 +8568,7 @@ trees_out::decl_node (tree decl, walk_kind ref)
|
||||
else
|
||||
{
|
||||
tree o = get_originating_module_decl (decl);
|
||||
o = STRIP_TEMPLATE (o);
|
||||
kind = (DECL_LANG_SPECIFIC (o) && DECL_MODULE_PURVIEW_P (o)
|
||||
? "purview" : "GMF");
|
||||
}
|
||||
@ -10371,7 +10333,7 @@ trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
|
||||
gcc_checking_assert
|
||||
(match_mergeable_specialization (false, entry)
|
||||
== TREE_TYPE (existing));
|
||||
else if (mk & MK_tmpl_tmpl_mask)
|
||||
if (mk & MK_tmpl_tmpl_mask)
|
||||
existing = DECL_TI_TEMPLATE (existing);
|
||||
}
|
||||
else
|
||||
@ -10401,7 +10363,7 @@ trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
|
||||
if (IDENTIFIER_CONV_OP_P (name))
|
||||
name = conv_op_identifier;
|
||||
|
||||
if (inner && TREE_CODE (inner) == FUNCTION_DECL)
|
||||
if (TREE_CODE (inner) == FUNCTION_DECL)
|
||||
{
|
||||
/* Functions are distinguished by parameter types. */
|
||||
tree fn_type = TREE_TYPE (inner);
|
||||
@ -10737,7 +10699,7 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
|
||||
key.ret = tree_node ();
|
||||
else if (mk == MK_partial
|
||||
|| ((mk == MK_named || mk == MK_friend_spec)
|
||||
&& inner && TREE_CODE (inner) == FUNCTION_DECL))
|
||||
&& TREE_CODE (inner) == FUNCTION_DECL))
|
||||
{
|
||||
key.ret = tree_node ();
|
||||
tree arg, *arg_ptr = &key.args;
|
||||
@ -10760,11 +10722,8 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
|
||||
DECL_NAME (decl) = name;
|
||||
DECL_CONTEXT (decl) = FROB_CONTEXT (container);
|
||||
}
|
||||
if (inner)
|
||||
{
|
||||
DECL_NAME (inner) = DECL_NAME (decl);
|
||||
DECL_CONTEXT (inner) = DECL_CONTEXT (decl);
|
||||
}
|
||||
DECL_NAME (inner) = DECL_NAME (decl);
|
||||
DECL_CONTEXT (inner) = DECL_CONTEXT (decl);
|
||||
|
||||
if (mk == MK_partial)
|
||||
{
|
||||
@ -12383,20 +12342,9 @@ depset::hash::make_dependency (tree decl, entity_kind ek)
|
||||
gcc_checking_assert (TREE_CODE (decl) == OVERLOAD);
|
||||
|
||||
if (TREE_CODE (decl) == TEMPLATE_DECL)
|
||||
{
|
||||
/* The template should have copied these from its result decl. */
|
||||
tree res = DECL_TEMPLATE_RESULT (decl);
|
||||
|
||||
gcc_checking_assert (DECL_MODULE_EXPORT_P (decl)
|
||||
== DECL_MODULE_EXPORT_P (res));
|
||||
if (DECL_LANG_SPECIFIC (res))
|
||||
{
|
||||
gcc_checking_assert (DECL_MODULE_PURVIEW_P (decl)
|
||||
== DECL_MODULE_PURVIEW_P (res));
|
||||
gcc_checking_assert ((DECL_MODULE_IMPORT_P (decl)
|
||||
== DECL_MODULE_IMPORT_P (res)));
|
||||
}
|
||||
}
|
||||
/* The template should have copied these from its result decl. */
|
||||
gcc_checking_assert (DECL_MODULE_EXPORT_P (decl)
|
||||
== DECL_MODULE_EXPORT_P (DECL_TEMPLATE_RESULT (decl)));
|
||||
|
||||
depset **slot = entity_slot (decl, true);
|
||||
depset *dep = *slot;
|
||||
@ -12444,11 +12392,6 @@ depset::hash::make_dependency (tree decl, entity_kind ek)
|
||||
|
||||
*slot = redirect;
|
||||
|
||||
if (DECL_LANG_SPECIFIC (decl))
|
||||
{
|
||||
DECL_MODULE_IMPORT_P (partial) = DECL_MODULE_IMPORT_P (decl);
|
||||
DECL_MODULE_PURVIEW_P (partial) = DECL_MODULE_PURVIEW_P (decl);
|
||||
}
|
||||
depset *tmpl_dep = make_dependency (partial, EK_PARTIAL);
|
||||
gcc_checking_assert (tmpl_dep->get_entity_kind () == EK_PARTIAL);
|
||||
|
||||
@ -12478,46 +12421,48 @@ depset::hash::make_dependency (tree decl, entity_kind ek)
|
||||
&& !(*eslot)->deps.length ());
|
||||
}
|
||||
|
||||
if (ek != EK_USING
|
||||
&& DECL_LANG_SPECIFIC (decl)
|
||||
&& DECL_MODULE_IMPORT_P (decl))
|
||||
if (ek != EK_USING)
|
||||
{
|
||||
/* Store the module number and index in cluster/section, so
|
||||
we don't have to look them up again. */
|
||||
unsigned index = import_entity_index (decl);
|
||||
module_state *from = import_entity_module (index);
|
||||
/* Remap will be zero for imports from partitions, which we
|
||||
want to treat as-if declared in this TU. */
|
||||
if (from->remap)
|
||||
{
|
||||
dep->cluster = index - from->entity_lwm;
|
||||
dep->section = from->remap;
|
||||
dep->set_flag_bit<DB_IMPORTED_BIT> ();
|
||||
}
|
||||
}
|
||||
|
||||
if (ek == EK_DECL
|
||||
&& !dep->is_import ()
|
||||
&& TREE_CODE (CP_DECL_CONTEXT (decl)) == NAMESPACE_DECL
|
||||
&& !(TREE_CODE (decl) == TEMPLATE_DECL
|
||||
&& DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl)))
|
||||
{
|
||||
tree ctx = CP_DECL_CONTEXT (decl);
|
||||
tree not_tmpl = STRIP_TEMPLATE (decl);
|
||||
|
||||
if (!TREE_PUBLIC (ctx))
|
||||
/* Member of internal namespace. */
|
||||
dep->set_flag_bit<DB_IS_INTERNAL_BIT> ();
|
||||
else if (VAR_OR_FUNCTION_DECL_P (not_tmpl)
|
||||
&& DECL_THIS_STATIC (not_tmpl))
|
||||
if (DECL_LANG_SPECIFIC (not_tmpl)
|
||||
&& DECL_MODULE_IMPORT_P (not_tmpl))
|
||||
{
|
||||
/* An internal decl. This is ok in a GM entity. */
|
||||
if (!(header_module_p ()
|
||||
|| !DECL_LANG_SPECIFIC (not_tmpl)
|
||||
|| !DECL_MODULE_PURVIEW_P (not_tmpl)))
|
||||
dep->set_flag_bit<DB_IS_INTERNAL_BIT> ();
|
||||
/* Store the module number and index in cluster/section,
|
||||
so we don't have to look them up again. */
|
||||
unsigned index = import_entity_index (decl);
|
||||
module_state *from = import_entity_module (index);
|
||||
/* Remap will be zero for imports from partitions, which
|
||||
we want to treat as-if declared in this TU. */
|
||||
if (from->remap)
|
||||
{
|
||||
dep->cluster = index - from->entity_lwm;
|
||||
dep->section = from->remap;
|
||||
dep->set_flag_bit<DB_IMPORTED_BIT> ();
|
||||
}
|
||||
}
|
||||
|
||||
if (ek == EK_DECL
|
||||
&& !dep->is_import ()
|
||||
&& TREE_CODE (CP_DECL_CONTEXT (decl)) == NAMESPACE_DECL
|
||||
&& !(TREE_CODE (decl) == TEMPLATE_DECL
|
||||
&& DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl)))
|
||||
{
|
||||
tree ctx = CP_DECL_CONTEXT (decl);
|
||||
|
||||
if (!TREE_PUBLIC (ctx))
|
||||
/* Member of internal namespace. */
|
||||
dep->set_flag_bit<DB_IS_INTERNAL_BIT> ();
|
||||
else if (VAR_OR_FUNCTION_DECL_P (not_tmpl)
|
||||
&& DECL_THIS_STATIC (not_tmpl))
|
||||
{
|
||||
/* An internal decl. This is ok in a GM entity. */
|
||||
if (!(header_module_p ()
|
||||
|| !DECL_LANG_SPECIFIC (not_tmpl)
|
||||
|| !DECL_MODULE_PURVIEW_P (not_tmpl)))
|
||||
dep->set_flag_bit<DB_IS_INTERNAL_BIT> ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dep->is_import ())
|
||||
@ -18394,15 +18339,16 @@ int
|
||||
get_originating_module (tree decl, bool for_mangle)
|
||||
{
|
||||
tree owner = get_originating_module_decl (decl);
|
||||
tree not_tmpl = STRIP_TEMPLATE (owner);
|
||||
|
||||
if (!DECL_LANG_SPECIFIC (owner))
|
||||
if (!DECL_LANG_SPECIFIC (not_tmpl))
|
||||
return for_mangle ? -1 : 0;
|
||||
|
||||
if (for_mangle
|
||||
&& (DECL_MODULE_EXPORT_P (owner) || !DECL_MODULE_PURVIEW_P (owner)))
|
||||
&& (DECL_MODULE_EXPORT_P (owner) || !DECL_MODULE_PURVIEW_P (not_tmpl)))
|
||||
return -1;
|
||||
|
||||
if (!DECL_MODULE_IMPORT_P (owner))
|
||||
if (!DECL_MODULE_IMPORT_P (not_tmpl))
|
||||
return 0;
|
||||
|
||||
return get_importing_module (owner);
|
||||
@ -18426,7 +18372,8 @@ module_may_redeclare (tree decl)
|
||||
{
|
||||
module_state *me = (*modules)[0];
|
||||
module_state *them = me;
|
||||
if (DECL_LANG_SPECIFIC (decl) && DECL_MODULE_IMPORT_P (decl))
|
||||
tree not_tmpl = STRIP_TEMPLATE (decl);
|
||||
if (DECL_LANG_SPECIFIC (not_tmpl) && DECL_MODULE_IMPORT_P (not_tmpl))
|
||||
{
|
||||
/* We can be given the TEMPLATE_RESULT. We want the
|
||||
TEMPLATE_DECL. */
|
||||
@ -18468,15 +18415,15 @@ module_may_redeclare (tree decl)
|
||||
}
|
||||
|
||||
if (me == them)
|
||||
return ((DECL_LANG_SPECIFIC (decl) && DECL_MODULE_PURVIEW_P (decl))
|
||||
return ((DECL_LANG_SPECIFIC (not_tmpl) && DECL_MODULE_PURVIEW_P (not_tmpl))
|
||||
== module_purview_p ());
|
||||
|
||||
if (!me->name)
|
||||
me = me->parent;
|
||||
|
||||
/* We can't have found a GMF entity from a named module. */
|
||||
gcc_checking_assert (DECL_LANG_SPECIFIC (decl)
|
||||
&& DECL_MODULE_PURVIEW_P (decl));
|
||||
gcc_checking_assert (DECL_LANG_SPECIFIC (not_tmpl)
|
||||
&& DECL_MODULE_PURVIEW_P (not_tmpl));
|
||||
|
||||
return me && get_primary (them) == get_primary (me);
|
||||
}
|
||||
@ -18500,20 +18447,16 @@ set_instantiating_module (tree decl)
|
||||
if (!modules_p ())
|
||||
return;
|
||||
|
||||
decl = STRIP_TEMPLATE (decl);
|
||||
|
||||
if (!DECL_LANG_SPECIFIC (decl) && module_purview_p ())
|
||||
retrofit_lang_decl (decl);
|
||||
|
||||
if (DECL_LANG_SPECIFIC (decl))
|
||||
{
|
||||
DECL_MODULE_PURVIEW_P (decl) = module_purview_p ();
|
||||
/* If this was imported, we'll still be in the entity_hash. */
|
||||
DECL_MODULE_IMPORT_P (decl) = false;
|
||||
if (TREE_CODE (decl) == TEMPLATE_DECL)
|
||||
{
|
||||
tree res = DECL_TEMPLATE_RESULT (decl);
|
||||
retrofit_lang_decl (res);
|
||||
DECL_MODULE_PURVIEW_P (res) = DECL_MODULE_PURVIEW_P (decl);
|
||||
DECL_MODULE_IMPORT_P (res) = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18547,7 +18490,6 @@ set_defining_module (tree decl)
|
||||
gcc_checking_assert (!use_tpl);
|
||||
/* Get to the TEMPLATE_DECL. */
|
||||
decl = TI_TEMPLATE (ti);
|
||||
gcc_checking_assert (!DECL_MODULE_IMPORT_P (decl));
|
||||
}
|
||||
|
||||
/* Record it on the class_members list. */
|
||||
|
||||
@ -1666,8 +1666,9 @@ name_lookup::search_adl (tree fns, vec<tree, va_gc> *args)
|
||||
continue;
|
||||
|
||||
tree origin = get_originating_module_decl (TYPE_NAME (scope));
|
||||
if (!DECL_LANG_SPECIFIC (origin)
|
||||
|| !DECL_MODULE_IMPORT_P (origin))
|
||||
tree not_tmpl = STRIP_TEMPLATE (origin);
|
||||
if (!DECL_LANG_SPECIFIC (not_tmpl)
|
||||
|| !DECL_MODULE_IMPORT_P (not_tmpl))
|
||||
/* Not imported. */
|
||||
continue;
|
||||
|
||||
@ -3680,6 +3681,7 @@ do_pushdecl (tree decl, bool hiding)
|
||||
if (iter.using_p ())
|
||||
; /* Ignore using decls here. */
|
||||
else if (iter.hidden_p ()
|
||||
&& TREE_CODE (*iter) == FUNCTION_DECL
|
||||
&& DECL_LANG_SPECIFIC (*iter)
|
||||
&& DECL_MODULE_IMPORT_P (*iter))
|
||||
; /* An undeclared builtin imported from elsewhere. */
|
||||
|
||||
53
gcc/cp/pt.c
53
gcc/cp/pt.c
@ -4930,16 +4930,8 @@ build_template_decl (tree decl, tree parms, bool member_template_p)
|
||||
DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
|
||||
DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p;
|
||||
|
||||
if (modules_p ())
|
||||
{
|
||||
/* Propagate module information from the decl. */
|
||||
DECL_MODULE_EXPORT_P (tmpl) = DECL_MODULE_EXPORT_P (decl);
|
||||
if (DECL_LANG_SPECIFIC (decl))
|
||||
{
|
||||
DECL_MODULE_PURVIEW_P (tmpl) = DECL_MODULE_PURVIEW_P (decl);
|
||||
gcc_checking_assert (!DECL_MODULE_IMPORT_P (decl));
|
||||
}
|
||||
}
|
||||
/* Propagate module information from the decl. */
|
||||
DECL_MODULE_EXPORT_P (tmpl) = DECL_MODULE_EXPORT_P (decl);
|
||||
|
||||
return tmpl;
|
||||
}
|
||||
@ -10167,25 +10159,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
|
||||
}
|
||||
|
||||
/* Build template info for the new specialization. */
|
||||
if (TYPE_ALIAS_P (t))
|
||||
{
|
||||
/* This is constructed during instantiation of the alias
|
||||
decl. But for member templates of template classes, that
|
||||
is not correct as we need to refer to the partially
|
||||
instantiated template, not the most general template.
|
||||
The incorrect knowledge will not have escaped this
|
||||
instantiation process, so we're good just updating the
|
||||
template_info we made then. */
|
||||
tree ti = DECL_TEMPLATE_INFO (TYPE_NAME (t));
|
||||
gcc_checking_assert (template_args_equal (TI_ARGS (ti), arglist));
|
||||
if (TI_TEMPLATE (ti) != found)
|
||||
{
|
||||
gcc_checking_assert (DECL_TI_TEMPLATE (found) == TI_TEMPLATE (ti));
|
||||
TI_TEMPLATE (ti) = found;
|
||||
}
|
||||
}
|
||||
else
|
||||
SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));
|
||||
SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));
|
||||
|
||||
elt.spec = t;
|
||||
slot = type_specializations->find_slot_with_hash (&elt, hash, INSERT);
|
||||
@ -14297,8 +14271,7 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TREE_CODE (decl) != TYPE_DECL || !TYPE_DECL_ALIAS_P (decl))
|
||||
DECL_TI_TEMPLATE (inner) = r;
|
||||
DECL_TI_TEMPLATE (inner) = r;
|
||||
DECL_TI_ARGS (r) = DECL_TI_ARGS (inner);
|
||||
}
|
||||
|
||||
@ -14311,17 +14284,13 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain,
|
||||
/* Propagate module information from the decl. */
|
||||
DECL_MODULE_EXPORT_P (r) = DECL_MODULE_EXPORT_P (inner);
|
||||
if (DECL_LANG_SPECIFIC (inner))
|
||||
{
|
||||
DECL_MODULE_PURVIEW_P (r) = DECL_MODULE_PURVIEW_P (inner);
|
||||
/* If this is a constrained template, the above tsubst of
|
||||
inner can find the unconstrained template, which may have
|
||||
come from an import. This is ok, because we don't
|
||||
register this instantiation (see below). */
|
||||
gcc_checking_assert (!DECL_MODULE_IMPORT_P (inner)
|
||||
|| (TEMPLATE_PARMS_CONSTRAINTS
|
||||
(DECL_TEMPLATE_PARMS (t))));
|
||||
DECL_MODULE_IMPORT_P (r) = false;
|
||||
}
|
||||
/* If this is a constrained template, the above tsubst of
|
||||
inner can find the unconstrained template, which may have
|
||||
come from an import. This is ok, because we don't
|
||||
register this instantiation (see below). */
|
||||
gcc_checking_assert (!DECL_MODULE_IMPORT_P (inner)
|
||||
|| (TEMPLATE_PARMS_CONSTRAINTS
|
||||
(DECL_TEMPLATE_PARMS (t))));
|
||||
}
|
||||
|
||||
DECL_TEMPLATE_INSTANTIATIONS (r) = NULL_TREE;
|
||||
|
||||
12
gcc/testsuite/g++.dg/modules/pr99283-2_a.H
Normal file
12
gcc/testsuite/g++.dg/modules/pr99283-2_a.H
Normal file
@ -0,0 +1,12 @@
|
||||
// PR 99283 part 2 ICE on definition with qualified-name
|
||||
// { dg-additional-options -fmodule-header }
|
||||
// { dg-module-cmi {} }
|
||||
|
||||
inline namespace __cxx11 {
|
||||
|
||||
template<typename _CharT>
|
||||
class collate;
|
||||
|
||||
}
|
||||
|
||||
|
||||
22
gcc/testsuite/g++.dg/modules/pr99283-2_b.H
Normal file
22
gcc/testsuite/g++.dg/modules/pr99283-2_b.H
Normal file
@ -0,0 +1,22 @@
|
||||
// { dg-additional-options -fmodule-header }
|
||||
// { dg-module-cmi {} }
|
||||
import "pr99283-2_a.H";
|
||||
|
||||
inline namespace __cxx11 {
|
||||
template<typename _CharT>
|
||||
class collate
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
template<typename _CharT>
|
||||
void Check ()
|
||||
{
|
||||
typedef collate<char> __collate_type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
20
gcc/testsuite/g++.dg/modules/pr99283-2_c.H
Normal file
20
gcc/testsuite/g++.dg/modules/pr99283-2_c.H
Normal file
@ -0,0 +1,20 @@
|
||||
// { dg-additional-options -fmodule-header }
|
||||
// { dg-module-cmi {} }
|
||||
import "pr99283-2_a.H";
|
||||
|
||||
template<typename _CharT>
|
||||
class __cxx11::collate
|
||||
{
|
||||
};
|
||||
|
||||
template<typename _CharT>
|
||||
void Check ()
|
||||
{
|
||||
typedef collate<char> __collate_type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
31
gcc/testsuite/g++.dg/modules/pr99283-3_a.H
Normal file
31
gcc/testsuite/g++.dg/modules/pr99283-3_a.H
Normal file
@ -0,0 +1,31 @@
|
||||
// PR 99283 part 2 ICE on definition with qualified-name
|
||||
// { dg-additional-options -fmodule-header }
|
||||
// { dg-module-cmi {} }
|
||||
|
||||
template<bool, typename _Tp>
|
||||
struct enable_if;
|
||||
|
||||
template<typename _Tp>
|
||||
struct enable_if<true, _Tp>
|
||||
{ typedef _Tp type; };
|
||||
|
||||
template<typename _CharT>
|
||||
class basic_string;
|
||||
|
||||
typedef basic_string<char> string;
|
||||
|
||||
template<typename _CharT>
|
||||
class basic_string
|
||||
{
|
||||
private:
|
||||
template<typename _Tp>
|
||||
using _If_sv = typename enable_if<true, int>::type;
|
||||
|
||||
public:
|
||||
const _CharT *c_str() const noexcept;
|
||||
};
|
||||
|
||||
inline void stoi(const string& __str)
|
||||
{
|
||||
__str.c_str ();
|
||||
}
|
||||
9
gcc/testsuite/g++.dg/modules/pr99283-3_b.H
Normal file
9
gcc/testsuite/g++.dg/modules/pr99283-3_b.H
Normal file
@ -0,0 +1,9 @@
|
||||
// { dg-additional-options {-fmodule-header -fno-module-lazy} }
|
||||
// { dg-module-cmi {} }
|
||||
|
||||
template<typename _CharT>
|
||||
class basic_string;
|
||||
|
||||
typedef basic_string<char> string;
|
||||
|
||||
import "pr99283-3_a.H";
|
||||
20
gcc/testsuite/g++.dg/modules/pr99283-4.H
Normal file
20
gcc/testsuite/g++.dg/modules/pr99283-4.H
Normal file
@ -0,0 +1,20 @@
|
||||
// PR 99283 part 3, ICE with template alias as default template parm
|
||||
// of member template
|
||||
// { dg-additional-options -fmodule-header }
|
||||
// { dg-module-cmi {} }
|
||||
|
||||
template<typename _Traits>
|
||||
struct _Insert
|
||||
{
|
||||
using size_type = int;
|
||||
|
||||
template<typename _Pair>
|
||||
using _IFconsp = bool;
|
||||
|
||||
template<typename _Pair, typename = _IFconsp<_Pair>>
|
||||
int insert (_Pair&& __v);
|
||||
};
|
||||
|
||||
void Foo (typename _Insert<int>::size_type);
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "tpl-alias-1.h"
|
||||
|
||||
// { dg-final { scan-lang-dump {Writing named:-[0-9]* template_decl:'::allocator_traits<::allocator<long int>>::template rebind_alloc<_Up>'} module } }
|
||||
// { dg-final { scan-lang-dump {Writing decl spec:-[0-9]* type_decl:'::allocator_traits<::allocator<long int>>::rebind_alloc<_Up>'} module } }
|
||||
// { dg-final { scan-lang-dump {Writing:-[0-9]*'s decl spec merge key \(specialization\) type_decl:'::allocator_traits<::allocator<long int>>::rebind_alloc<_Up>'} module } }
|
||||
// { dg-final { scan-lang-dump {Wrote\(-[0-9]*\) alias template type_decl:'::allocator_traits<::allocator<long int>>::rebind_alloc<_Up>'} module } }
|
||||
// { dg-final { scan-lang-dump {Writing decl tmpl spec:-[0-9]* template_decl:'::allocator_traits<::allocator<long int>>::template rebind_alloc<_Up>'} module } }
|
||||
// { dg-final { scan-lang-dump {Writing decl tmpl spec:-[0-9]* type_decl:'::allocator_traits<::allocator<long int>>::template rebind_alloc<_Up>'} module } }
|
||||
|
||||
// { dg-final { scan-lang-dump {Writing:-[0-9]*'s alias spec merge key \(specialization\) type_decl:'::allocator_traits<::allocator<long int>>::rebind_alloc<long int>'} module } }
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
#include "tpl-alias-1.h"
|
||||
import "tpl-alias-1_a.H";
|
||||
|
||||
// { dg-final { scan-lang-dump {Read:-[0-9]*'s named merge key \(matched\) template_decl:'::allocator_traits<::allocator<long int>>::template rebind_alloc'} module } }
|
||||
// { dg-final { scan-lang-dump {Read:-[0-9]*'s decl spec merge key \(matched\) type_decl:'::allocator_traits<::allocator<_Tp>>::rebind_alloc'} module } }
|
||||
// { dg-final { scan-lang-dump {Read alias template type_decl:'::allocator_traits<::allocator<long int>>::rebind_alloc<_Up>'} module } }
|
||||
// { dg-final { scan-lang-dump {Deduping '::allocator_traits<::allocator<_Tp>>::template rebind_alloc'} module } }
|
||||
// { dg-final { scan-lang-dump {Deduping '::allocator_traits<::allocator<long int>>::template rebind_alloc<_Up>'} module } }
|
||||
// { dg-final { scan-lang-dump {Deduping '::allocator_traits<::allocator<long int>>::rebind_alloc<long int>'} module } }
|
||||
|
||||
// { dg-final { scan-lang-dump-not {merge key \(new\)} module } }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user