->template_info)
/* Template information for an ENUMERAL_, RECORD_, UNION_TYPE, or
- BOUND_TEMPLATE_TEMPLATE_PARM type. Note that if NODE is a
- specialization of an alias template, this accessor returns the
- template info for the alias template, not the one (if any) for the
- template of the underlying type. */
+ BOUND_TEMPLATE_TEMPLATE_PARM type. This ignores any alias
+ templateness of NODE. */
#define TYPE_TEMPLATE_INFO(NODE) \
- ((TYPE_ALIAS_P (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE))) \
- ? (DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \
- ? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \
- : NULL_TREE) \
- : ((TREE_CODE (NODE) == ENUMERAL_TYPE) \
- ? ENUM_TEMPLATE_INFO (NODE) \
- : ((TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM) \
- ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \
- : (CLASS_TYPE_P (NODE) \
- ? CLASSTYPE_TEMPLATE_INFO (NODE) \
- : NULL_TREE))))
+ (TREE_CODE (NODE) == ENUMERAL_TYPE \
+ ? ENUM_TEMPLATE_INFO (NODE) \
+ : (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \
+ ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \
+ : (CLASS_TYPE_P (NODE) \
+ ? CLASSTYPE_TEMPLATE_INFO (NODE) \
+ : NULL_TREE)))
+
+/* Template information for an alias template type. */
+#define TYPE_ALIAS_TEMPLATE_INFO(NODE) \
+ (DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \
+ ? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \
+ : NULL_TREE)
+/* If NODE is a specialization of an alias template, this accessor
+ returns the template info for the alias template. Otherwise behave
+ as TYPE_TEMPLATE_INFO. */
+#define TYPE_TEMPLATE_INFO_MAYBE_ALIAS(NODE) \
+ (TYPE_ALIAS_P (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \
+ ? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \
+ : TYPE_TEMPLATE_INFO (NODE))
/* Set the template information for an ENUMERAL_, RECORD_, or
UNION_TYPE to VAL. */
if (TYPE_ALIAS_P (type))
{
- if (TYPE_TEMPLATE_INFO (type)
- && DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (type)))
+ tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (type);
+
+ if (tinfo && DECL_ALIAS_TEMPLATE_P (TI_TEMPLATE (tinfo)))
error ("specialization of alias template %qD",
- TYPE_TI_TEMPLATE (type));
+ TI_TEMPLATE (tinfo));
else
error ("explicit specialization of non-template %qT", type);
return error_mark_node;
// left alone, or untouched specializations because
// coerce_template_parms returns the unconverted template
// arguments if it sees incomplete argument packs.
- tree ti = TYPE_TEMPLATE_INFO (arg);
+ tree ti = TYPE_ALIAS_TEMPLATE_INFO (arg);
return hash_tmpl_and_args (TI_TEMPLATE (ti), TI_ARGS (ti));
}
if (TYPE_CANONICAL (arg))
/* Handle type aliases/typedefs. */
if (TYPE_ALIAS_P (t))
{
- if (TYPE_TEMPLATE_INFO (t))
- cp_walk_tree (&TYPE_TI_ARGS (t),
+ if (tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (t))
+ cp_walk_tree (&TI_ARGS (tinfo),
&find_parameter_packs_r,
ppd, ppd->visited);
*walk_subtrees = 0;
/* It's an alias template specialization if it's an alias and its
TYPE_NAME is a specialization of a primary template. */
if (TYPE_ALIAS_P (t))
- {
- tree name = TYPE_NAME (t);
- if (DECL_LANG_SPECIFIC (name))
- if (tree ti = DECL_TEMPLATE_INFO (name))
- {
- tree tmpl = TI_TEMPLATE (ti);
- return PRIMARY_TEMPLATE_P (tmpl);
- }
- }
+ if (tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (t))
+ return PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo));
+
return false;
}
bool
dependent_alias_template_spec_p (const_tree t)
{
- return (alias_template_specialization_p (t)
- && TEMPLATE_DECL_COMPLEX_ALIAS_P (DECL_TI_TEMPLATE (TYPE_NAME (t)))
- && (any_dependent_template_arguments_p
- (INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (t)))));
+ if (!alias_template_specialization_p (t))
+ return false;
+
+ tree tinfo = TYPE_ALIAS_TEMPLATE_INFO (t);
+ if (!TEMPLATE_DECL_COMPLEX_ALIAS_P (TI_TEMPLATE (tinfo)))
+ return false;
+
+ tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo));
+ if (!any_dependent_template_arguments_p (args))
+ return false;
+
+ return true;
}
/* Return the number of innermost template parameters in TMPL. */
gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
while (DECL_ALIAS_TEMPLATE_P (tmpl))
{
- tree result = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl));
- if (TYPE_TEMPLATE_INFO (result))
- {
- tree sub = TYPE_TI_TEMPLATE (result);
- if (PRIMARY_TEMPLATE_P (sub)
- && (num_innermost_template_parms (tmpl)
- == num_innermost_template_parms (sub)))
- {
- tree alias_args = INNERMOST_TEMPLATE_ARGS
- (template_parms_to_args (DECL_TEMPLATE_PARMS (tmpl)));
- if (!comp_template_args (TYPE_TI_ARGS (result), alias_args))
- break;
- /* The alias type is equivalent to the pattern of the
- underlying template, so strip the alias. */
- tmpl = sub;
- continue;
- }
- }
- break;
+ /* Determine if the alias is equivalent to an underlying template. */
+ tree orig_type = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl));
+ tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (orig_type);
+ if (!tinfo)
+ break;
+
+ tree underlying = TI_TEMPLATE (tinfo);
+ if (!PRIMARY_TEMPLATE_P (underlying)
+ || (num_innermost_template_parms (tmpl)
+ != num_innermost_template_parms (underlying)))
+ break;
+
+ tree alias_args = INNERMOST_TEMPLATE_ARGS
+ (template_parms_to_args (DECL_TEMPLATE_PARMS (tmpl)));
+ if (!comp_template_args (TI_ARGS (tinfo), alias_args))
+ break;
+
+ /* Alias is equivalent. Strip it and repeat. */
+ tmpl = underlying;
}
+
return tmpl;
}
TEMPLATE will be `template <class T> template
<class U> struct S1<T>::S2'. We must fill in the missing
arguments. */
- arglist
- = add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (templ)),
- arglist);
+ tree ti = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (TREE_TYPE (templ));
+ arglist = add_outermost_template_args (TI_ARGS (ti), arglist);
arg_depth = TMPL_ARGS_DEPTH (arglist);
}
the `C<T>' is just the same as `C'. Outside of the
class, however, such a reference is an instantiation. */
- if ((entering_scope
- || !PRIMARY_TEMPLATE_P (gen_tmpl)
- || currently_open_class (template_type))
- /* comp_template_args is expensive, check it last. */
- && comp_template_args (TYPE_TI_ARGS (template_type),
- arglist))
- return template_type;
+ if (entering_scope
+ || !PRIMARY_TEMPLATE_P (gen_tmpl)
+ || currently_open_class (template_type))
+ {
+ tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (template_type);
+
+ if (comp_template_args (TI_ARGS (tinfo), arglist))
+ return template_type;
+ }
/* If we already have this specialization, return it. */
elt.tmpl = gen_tmpl;
&& CLASS_TYPE_P (context)
&& !same_type_p (context, DECL_CONTEXT (gen_tmpl)))
{
- tree partial_inst_args;
TREE_VEC_LENGTH (arglist)--;
++processing_template_decl;
- partial_inst_args =
- tsubst (INNERMOST_TEMPLATE_ARGS
- (TYPE_TI_ARGS (TREE_TYPE (gen_tmpl))),
+ tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (TREE_TYPE (gen_tmpl));
+ tree partial_inst_args =
+ tsubst (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo)),
arglist, complain, NULL_TREE);
--processing_template_decl;
TREE_VEC_LENGTH (arglist)++;
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
- ? TYPE_TI_TEMPLATE (TREE_TYPE (found))
- : CLASSTYPE_TI_TEMPLATE (found);
+ found = (TREE_CODE (found) == TEMPLATE_DECL
+ ? found
+ : (TREE_CODE (found) == TYPE_DECL
+ ? DECL_TI_TEMPLATE (found)
+ : CLASSTYPE_TI_TEMPLATE (found)));
}
// Build template info for the new specialization.
return unify_template_deduction_failure (explain_p, parm, arg);
{
tree parmvec = TYPE_TI_ARGS (parm);
- /* An alias template name is never deduced. */
- if (TYPE_ALIAS_P (arg))
- arg = strip_typedefs (arg);
tree argvec = INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (arg));
tree full_argvec = add_to_template_args (targs, argvec);
tree parm_parms