pt.c (process_partial_specialization): Build a TEMPLATE_DECL for a partial specialization.
* pt.c (process_partial_specialization): Build a TEMPLATE_DECL for a partial specialization. (tsubst_decl): Don't clobber CLASSTYPE_TI_TEMPLATE of a partial specialization. (most_specialized_class): Adjust. From-SVN: r200263
This commit is contained in:
parent
4ab013d93a
commit
4ca5c232d0
3 changed files with 35 additions and 24 deletions
|
@ -1,5 +1,11 @@
|
|||
2013-06-20 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* pt.c (process_partial_specialization): Build a TEMPLATE_DECL for
|
||||
a partial specialization.
|
||||
(tsubst_decl): Don't clobber CLASSTYPE_TI_TEMPLATE of a partial
|
||||
specialization.
|
||||
(most_specialized_class): Adjust.
|
||||
|
||||
* cp-tree.h (DECL_TEMPLATE_PARMS, DECL_TEMPLATE_RESULT)
|
||||
(DECL_TEMPLATE_INSTANTIATIONS, DECL_TEMPLATE_SPECIALIZATIONS): Use
|
||||
TEMPLATE_DECL_CHECK.
|
||||
|
|
|
@ -3727,11 +3727,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
specializations of this template. (Full specializations are not
|
||||
recorded on this list.) The TREE_PURPOSE holds the arguments used
|
||||
in the partial specialization (e.g., for `template <class T> struct
|
||||
S<T*, int>' this will be `T*'.) The arguments will also include
|
||||
any outer template arguments. The TREE_VALUE holds the innermost
|
||||
template parameters for the specialization (e.g., `T' in the
|
||||
example above.) The TREE_TYPE is the _TYPE node for the partial
|
||||
specialization.
|
||||
S<T*, int>' this will be `T*, int'.) The arguments will also include
|
||||
any outer template arguments. The TREE_VALUE holds the TEMPLATE_DECL
|
||||
for the partial specialization. The TREE_TYPE is the _TYPE node for
|
||||
the partial specialization.
|
||||
|
||||
This list is not used for other templates. */
|
||||
#define DECL_TEMPLATE_SPECIALIZATIONS(NODE) \
|
||||
|
@ -3801,9 +3800,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
|||
#define SET_DECL_SELF_REFERENCE_P(NODE) \
|
||||
(DECL_LANG_FLAG_4 (NODE) = 1)
|
||||
|
||||
/* A `primary' template is one that has its own template header. A
|
||||
member function of a class template is a template, but not primary.
|
||||
A member template is primary. Friend templates are primary, too. */
|
||||
/* A `primary' template is one that has its own template header and is not
|
||||
a partial specialization. A member function of a class template is a
|
||||
template, but not primary. A member template is primary. Friend
|
||||
templates are primary, too. */
|
||||
|
||||
/* Returns the primary template corresponding to these parameters. */
|
||||
#define DECL_PRIMARY_TEMPLATE(NODE) \
|
||||
|
|
37
gcc/cp/pt.c
37
gcc/cp/pt.c
|
@ -4246,8 +4246,16 @@ process_partial_specialization (tree decl)
|
|||
/* We should only get here once. */
|
||||
gcc_assert (!COMPLETE_TYPE_P (type));
|
||||
|
||||
tree tmpl = build_template_decl (decl, current_template_parms,
|
||||
DECL_MEMBER_TEMPLATE_P (maintmpl));
|
||||
TREE_TYPE (tmpl) = type;
|
||||
DECL_TEMPLATE_RESULT (tmpl) = decl;
|
||||
SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
|
||||
DECL_TEMPLATE_INFO (tmpl) = build_template_info (maintmpl, specargs);
|
||||
DECL_PRIMARY_TEMPLATE (tmpl) = maintmpl;
|
||||
|
||||
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)
|
||||
= tree_cons (specargs, inner_parms,
|
||||
= tree_cons (specargs, tmpl,
|
||||
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
|
||||
TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type;
|
||||
|
||||
|
@ -10058,7 +10066,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
|
|||
RETURN (error_mark_node);
|
||||
|
||||
TREE_TYPE (r) = new_type;
|
||||
CLASSTYPE_TI_TEMPLATE (new_type) = r;
|
||||
/* For a partial specialization, we need to keep pointing to
|
||||
the primary template. */
|
||||
if (!DECL_TEMPLATE_SPECIALIZATION (t))
|
||||
CLASSTYPE_TI_TEMPLATE (new_type) = r;
|
||||
DECL_TEMPLATE_RESULT (r) = TYPE_MAIN_DECL (new_type);
|
||||
DECL_TI_ARGS (r) = CLASSTYPE_TI_ARGS (new_type);
|
||||
DECL_CONTEXT (r) = TYPE_CONTEXT (new_type);
|
||||
|
@ -18080,7 +18091,8 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
|
|||
{
|
||||
tree partial_spec_args;
|
||||
tree spec_args;
|
||||
tree parms = TREE_VALUE (t);
|
||||
tree spec_tmpl = TREE_VALUE (t);
|
||||
tree orig_parms = DECL_INNERMOST_TEMPLATE_PARMS (spec_tmpl);
|
||||
|
||||
partial_spec_args = CLASSTYPE_TI_ARGS (TREE_TYPE (t));
|
||||
|
||||
|
@ -18088,24 +18100,14 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
|
|||
|
||||
if (outer_args)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Discard the outer levels of args, and then substitute in the
|
||||
template args from the enclosing class. */
|
||||
partial_spec_args = INNERMOST_TEMPLATE_ARGS (partial_spec_args);
|
||||
partial_spec_args = tsubst_template_args
|
||||
(partial_spec_args, outer_args, tf_none, NULL_TREE);
|
||||
|
||||
/* PARMS already refers to just the innermost parms, but the
|
||||
template parms in partial_spec_args had their levels lowered
|
||||
by tsubst, so we need to do the same for the parm list. We
|
||||
can't just tsubst the TREE_VEC itself, as tsubst wants to
|
||||
treat a TREE_VEC as an argument vector. */
|
||||
parms = copy_node (parms);
|
||||
for (i = TREE_VEC_LENGTH (parms) - 1; i >= 0; --i)
|
||||
TREE_VEC_ELT (parms, i) =
|
||||
tsubst (TREE_VEC_ELT (parms, i), outer_args, tf_none, NULL_TREE);
|
||||
|
||||
/* And the same for the partial specialization TEMPLATE_DECL. */
|
||||
spec_tmpl = tsubst (spec_tmpl, outer_args, tf_none, NULL_TREE);
|
||||
}
|
||||
|
||||
partial_spec_args =
|
||||
|
@ -18120,7 +18122,10 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
|
|||
|
||||
if (partial_spec_args == error_mark_node)
|
||||
return error_mark_node;
|
||||
if (spec_tmpl == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
tree parms = DECL_INNERMOST_TEMPLATE_PARMS (spec_tmpl);
|
||||
spec_args = get_class_bindings (tmpl, parms,
|
||||
partial_spec_args,
|
||||
args);
|
||||
|
@ -18128,7 +18133,7 @@ most_specialized_class (tree type, tree tmpl, tsubst_flags_t complain)
|
|||
{
|
||||
if (outer_args)
|
||||
spec_args = add_to_template_args (outer_args, spec_args);
|
||||
list = tree_cons (spec_args, TREE_VALUE (t), list);
|
||||
list = tree_cons (spec_args, orig_parms, list);
|
||||
TREE_TYPE (list) = TREE_TYPE (t);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue