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) \
#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) \
/* 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;
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);
{
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));
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 =
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);
{
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);
}
}