DB_HIDDEN_BIT, /* A hidden binding. */
/* The following bits are not independent, but enumerating them is
awkward. */
- DB_ALIAS_TMPL_INST_BIT, /* An alias template instantiation. */
- DB_ALIAS_SPEC_BIT, /* Specialization of an alias template
- (in both spec tables). */
- DB_TYPE_SPEC_BIT, /* Specialization in the type table.
- */
+ DB_TYPE_SPEC_BIT, /* Specialization in the type table. */
DB_FRIEND_SPEC_BIT, /* An instantiated template friend. */
};
{
return get_flag_bit<DB_UNREACHED_BIT> ();
}
- bool is_alias_tmpl_inst () const
- {
- return get_flag_bit<DB_ALIAS_TMPL_INST_BIT> ();
- }
- bool is_alias () const
- {
- return get_flag_bit<DB_ALIAS_SPEC_BIT> ();
- }
bool is_hidden () const
{
return get_flag_bit<DB_HIDDEN_BIT> ();
MK_template_mask = 0x10, /* A template specialization. */
MK_tmpl_decl_mask = 0x4, /* In decl table. */
- MK_tmpl_alias_mask = 0x2, /* Also in type table */
MK_tmpl_tmpl_mask = 0x1, /* We want TEMPLATE_DECL. */
MK_type_spec = MK_template_mask,
MK_decl_spec = MK_template_mask | MK_tmpl_decl_mask,
- MK_alias_spec = MK_decl_spec | MK_tmpl_alias_mask,
MK_hwm = 0x20
};
NULL, NULL,
"decl spec", "decl tmpl spec", /* 20,21 decl (template). */
- "alias spec", "alias tmpl spec", /* 22,23 alias (template). */
+ NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
};
gcc_checking_assert
(TREE_VISITED (((lang_tree_node *)t)->template_decl.arguments));
gcc_checking_assert
- (TREE_VISITED (((lang_tree_node *)t)->template_decl.result)
- || dep_hash->find_dependency (t)->is_alias_tmpl_inst ());
+ (TREE_VISITED (((lang_tree_node *)t)->template_decl.result));
if (DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (t))
WT (DECL_CHAIN (t));
break;
{
bool is_type = TREE_CODE (inner) == TYPE_DECL;
spec.spec = is_type ? type : inner;
- add_mergeable_specialization (!is_type, false,
- &spec, decl, spec_flags);
+ add_mergeable_specialization (!is_type, &spec, decl, spec_flags);
}
else if (mk & MK_template_mask)
{
bool is_type = !(mk & MK_tmpl_decl_mask);
spec.spec = is_type ? type : mk & MK_tmpl_tmpl_mask ? inner : decl;
- add_mergeable_specialization (!is_type,
- !is_type && mk & MK_tmpl_alias_mask,
- &spec, decl, spec_flags);
+ add_mergeable_specialization (!is_type, &spec, decl, spec_flags);
}
if (NAMESPACE_SCOPE_P (decl)
if (!e)
{
spec.spec = inner;
- add_mergeable_specialization (true, false, &spec, decl, spec_flags);
+ add_mergeable_specialization (true, &spec, decl, spec_flags);
}
else if (e != existing)
set_overrun ();
mk = MK_friend_spec;
else if (dep->is_type_spec ())
mk = MK_type_spec;
- else if (dep->is_alias ())
- mk = MK_alias_spec;
else
mk = MK_decl_spec;
gcc_assert (existing);
if (mk & MK_tmpl_decl_mask)
{
- if (mk & MK_tmpl_alias_mask)
- /* It should be in both tables. */
- gcc_checking_assert
- (same_type_p (match_mergeable_specialization (false, entry),
- TREE_TYPE (existing)));
if (mk & MK_tmpl_tmpl_mask)
existing = DECL_TI_TEMPLATE (existing);
}
bindings. */
*slot = dep = make_entity (decl, ek, has_def);
- if (TREE_CODE (decl) == TEMPLATE_DECL)
- {
- if (DECL_ALIAS_TEMPLATE_P (decl) && DECL_TEMPLATE_INFO (decl))
- dep->set_flag_bit<DB_ALIAS_TMPL_INST_BIT> ();
- else if (CHECKING_P)
- /* The template_result should otherwise not be in the
- table, or be an empty redirect (created above). */
- if (auto *eslot = entity_slot (DECL_TEMPLATE_RESULT (decl), false))
- gcc_checking_assert ((*eslot)->get_entity_kind () == EK_REDIRECT
- && !(*eslot)->deps.length ());
- }
+ if (CHECKING_P && TREE_CODE (decl) == TEMPLATE_DECL)
+ /* The template_result should otherwise not be in the
+ table, or be an empty redirect (created above). */
+ if (auto *eslot = entity_slot (DECL_TEMPLATE_RESULT (decl), false))
+ gcc_checking_assert ((*eslot)->get_entity_kind () == EK_REDIRECT
+ && !(*eslot)->deps.length ());
if (ek != EK_USING)
{
heuristic. We don't attempt to replicate that algorithm, but
observe its behaviour and reproduce it upon read back. */
- gcc_checking_assert (DECL_ALIAS_TEMPLATE_P (entry->tmpl)
- || TREE_CODE (entry->spec) == ENUMERAL_TYPE
+ gcc_checking_assert (TREE_CODE (entry->spec) == ENUMERAL_TYPE
|| DECL_CLASS_TEMPLATE_P (entry->tmpl));
- /* Only alias templates can appear in both tables (and
- if they're in the type table they must also be in the decl
- table). */
- gcc_checking_assert
- (!match_mergeable_specialization (true, entry)
- == !DECL_ALIAS_TEMPLATE_P (entry->tmpl));
+ gcc_checking_assert (!match_mergeable_specialization (true, entry));
}
else if (VAR_OR_FUNCTION_DECL_P (entry->spec))
gcc_checking_assert (!DECL_LOCAL_DECL_P (entry->spec));
spec_entry *entry = data.pop ();
tree spec = entry->spec;
int use_tpl = 0;
- bool is_alias = false;
bool is_friend = false;
if (decl_p && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (entry->tmpl))
instantiation. */
is_friend = true;
- if (!decl_p && DECL_ALIAS_TEMPLATE_P (entry->tmpl))
- {
- spec = TYPE_NAME (spec);
- is_alias = true;
- }
-
- if (decl_p || is_alias)
+ if (decl_p)
{
if (tree ti = DECL_TEMPLATE_INFO (spec))
{
gcc_checking_assert (!TREE_VISITED (spec));
depset *dep = make_dependency (spec, depset::EK_SPECIALIZATION);
if (dep->is_special ())
- {
- /* An already located specialization, this must be the TYPE
- corresponding to an alias_decl we found in the decl
- table. */
- spec_entry *other = reinterpret_cast <spec_entry *> (dep->deps[0]);
- gcc_checking_assert (!decl_p && is_alias && !dep->is_type_spec ());
- gcc_checking_assert (other->tmpl == entry->tmpl
- && template_args_equal (other->args, entry->args)
- && TREE_TYPE (other->spec) == entry->spec);
- dep->set_flag_bit<DB_ALIAS_SPEC_BIT> ();
- }
+ gcc_unreachable ();
else
{
- gcc_checking_assert (decl_p || !is_alias);
if (dep->get_entity_kind () == depset::EK_REDIRECT)
dep = dep->deps[0];
else if (dep->get_entity_kind () == depset::EK_SPECIALIZATION)
/* Now we should have enough arguments. */
gcc_assert (parm_depth == arg_depth);
+ if (DECL_ALIAS_TEMPLATE_P (gen_tmpl))
+ {
+ /* The user referred to a specialization of an alias
+ template represented by GEN_TMPL.
+
+ [temp.alias]/2 says:
+
+ When a template-id refers to the specialization of an
+ alias template, it is equivalent to the associated
+ type obtained by substitution of its
+ template-arguments for the template-parameters in the
+ type-id of the alias template. */
+
+ t = instantiate_alias_template (gen_tmpl, arglist, complain);
+ /* Note that the call above (by indirectly calling
+ register_specialization in tsubst_decl) registers the
+ TYPE_DECL representing the specialization of the alias
+ template. So next time someone substitutes ARGLIST for
+ the template parms into the alias template (GEN_TMPL),
+ she'll get that TYPE_DECL back. */
+
+ if (t == error_mark_node)
+ return error_mark_node;
+ return TREE_TYPE (t);
+ }
+
/* From here on, we're only interested in the most general
template. */
lookup. This prevents redundant checks on previously
instantiated specializations. */
if (flag_concepts
- && !DECL_ALIAS_TEMPLATE_P (gen_tmpl)
&& !constraints_satisfied_p (gen_tmpl, arglist))
{
if (complain & tf_error)
context = global_namespace;
/* Create the type. */
- if (DECL_ALIAS_TEMPLATE_P (gen_tmpl))
- {
- /* The user referred to a specialization of an alias
- template represented by GEN_TMPL.
-
- [temp.alias]/2 says:
-
- When a template-id refers to the specialization of an
- alias template, it is equivalent to the associated
- type obtained by substitution of its
- template-arguments for the template-parameters in the
- type-id of the alias template. */
-
- t = tsubst (TREE_TYPE (gen_tmpl), arglist, complain, in_decl);
- /* Note that the call above (by indirectly calling
- register_specialization in tsubst_decl) registers the
- TYPE_DECL representing the specialization of the alias
- template. So next time someone substitutes ARGLIST for
- the template parms into the alias template (GEN_TMPL),
- she'll get that TYPE_DECL back. */
-
- if (t == error_mark_node)
- return t;
- }
- else if (TREE_CODE (template_type) == ENUMERAL_TYPE)
+ if (TREE_CODE (template_type) == ENUMERAL_TYPE)
{
if (!is_dependent_type)
{
}
}
- if (OVERLOAD_TYPE_P (t)
- && !DECL_ALIAS_TEMPLATE_P (gen_tmpl))
+ if (OVERLOAD_TYPE_P (t))
{
static const char *tags[] = {"abi_tag", "may_alias"};
{
TREE_VEC_LENGTH (arglist)--;
++processing_template_decl;
- tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (TREE_TYPE (gen_tmpl));
+ tree tinfo = TYPE_TEMPLATE_INFO (TREE_TYPE (gen_tmpl));
tree partial_inst_args =
tsubst (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo)),
arglist, complain, NULL_TREE);
TEMPLATE_PARM_LEVEL. */
found = tsubst (gen_tmpl, arglist, tf_none, NULL_TREE);
TREE_VEC_LENGTH (arglist)++;
- /* FOUND is either a proper class type, or an alias
- template specialization. In the later case, it's a
- TYPE_DECL, resulting from the substituting of arguments
- for parameters in the TYPE_DECL of the alias template
- done earlier. So be careful while getting the template
- of FOUND. */
found = (TREE_CODE (found) == TEMPLATE_DECL
? found
- : (TREE_CODE (found) == TYPE_DECL
- ? DECL_TI_TEMPLATE (found)
- : CLASSTYPE_TI_TEMPLATE (found)));
+ : CLASSTYPE_TI_TEMPLATE (found));
if (DECL_CLASS_TEMPLATE_P (found)
&& CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (found)))
DECL_TEMPLATE_INSTANTIATIONS (found));
if (TREE_CODE (template_type) == ENUMERAL_TYPE
- && !uses_template_parms (current_nonlambda_scope ())
- && !DECL_ALIAS_TEMPLATE_P (gen_tmpl))
+ && !uses_template_parms (current_nonlambda_scope ()))
/* Now that the type has been registered on the instantiations
list, we set up the enumerators. Because the enumeration
constants may involve the enumeration type itself, we make
get_mergeable_specialization_flags. */
void
-add_mergeable_specialization (bool decl_p, bool alias_p, spec_entry *elt,
- tree decl, unsigned flags)
+add_mergeable_specialization (bool decl_p, spec_entry *elt, tree decl,
+ unsigned flags)
{
hashval_t hash = spec_hasher::hash (elt);
if (decl_p)
auto entry = ggc_alloc<spec_entry> ();
*entry = *elt;
*slot = entry;
-
- if (alias_p)
- {
- elt->spec = TREE_TYPE (elt->spec);
- gcc_checking_assert (elt->spec);
- }
}
-
- if (!decl_p || alias_p)
+ else
{
auto *slot = type_specializations->find_slot_with_hash (elt, hash, INSERT);