Commit 6df47b06 by Mark Mitchell

cp-tree.h (specializations_of_same_template_p): Declare.

	* cp-tree.h (specializations_of_same_template_p): Declare.
	* pt.c (specializations_of_same_template_p): New function.
	(unify): Use it.
	* search.c (get_template_base): Use it.
	(get_template_base_recursive): Likewise.

From-SVN: r22987
parent 4a7bd8e2
...@@ -2869,6 +2869,7 @@ extern int is_specialization_of PROTO((tree, tree)); ...@@ -2869,6 +2869,7 @@ extern int is_specialization_of PROTO((tree, tree));
extern int comp_template_args PROTO((tree, tree)); extern int comp_template_args PROTO((tree, tree));
extern void maybe_process_partial_specialization PROTO((tree)); extern void maybe_process_partial_specialization PROTO((tree));
extern void maybe_check_template_type PROTO((tree)); extern void maybe_check_template_type PROTO((tree));
extern int specializations_of_same_template_p PROTO((tree, tree));
extern int processing_specialization; extern int processing_specialization;
extern int processing_explicit_instantiation; extern int processing_explicit_instantiation;
......
...@@ -756,6 +756,22 @@ is_specialization_of (decl, tmpl) ...@@ -756,6 +756,22 @@ is_specialization_of (decl, tmpl)
return 0; return 0;
} }
/* Returns nonzero if T1 and T2 are instances of the same template.
(They may have different template arguments.) */
int
specializations_of_same_template_p (t1, t2)
tree t1;
tree t2;
{
/* For now, we only deal with instances of class templates, since
that is the only way in which this function is used. */
return (most_general_template (CLASSTYPE_TI_TEMPLATE (t1))
== most_general_template (CLASSTYPE_TI_TEMPLATE (t2)));
}
/* Register the specialization SPEC as a specialization of TMPL with /* Register the specialization SPEC as a specialization of TMPL with
the indicated ARGS. Returns SPEC, or an equivalent prior the indicated ARGS. Returns SPEC, or an equivalent prior
declaration, if available. */ declaration, if available. */
...@@ -7340,12 +7356,18 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) ...@@ -7340,12 +7356,18 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
can be a derived class of the deduced A. Likewise, if can be a derived class of the deduced A. Likewise, if
P is a pointer to a class of the form template-id, A P is a pointer to a class of the form template-id, A
can be a pointer to a derived class pointed to by the can be a pointer to a derived class pointed to by the
deduced A. */ deduced A.
The call to get_template_base also handles the case
where PARM and ARG are the same type, i.e., where no
derivation is involved. */
t = get_template_base (CLASSTYPE_TI_TEMPLATE (parm), arg); t = get_template_base (CLASSTYPE_TI_TEMPLATE (parm), arg);
else if else if (CLASSTYPE_TEMPLATE_INFO (arg)
(CLASSTYPE_TEMPLATE_INFO (arg) && specializations_of_same_template_p (parm, arg))
&& CLASSTYPE_TI_TEMPLATE (parm) == CLASSTYPE_TI_TEMPLATE (arg)) /* Perhaps PARM is something like S<U> and ARG is S<int>.
Then, we should unify `int' and `U'. */
t = arg; t = arg;
if (! t || t == error_mark_node) if (! t || t == error_mark_node)
return 1; return 1;
......
...@@ -3317,7 +3317,8 @@ get_template_base_recursive (binfo, rval, template, via_virtual) ...@@ -3317,7 +3317,8 @@ get_template_base_recursive (binfo, rval, template, via_virtual)
tree type = BINFO_TYPE (binfo); tree type = BINFO_TYPE (binfo);
if (CLASSTYPE_TEMPLATE_INFO (type) if (CLASSTYPE_TEMPLATE_INFO (type)
&& CLASSTYPE_TI_TEMPLATE (type) == template) && specializations_of_same_template_p (TREE_TYPE (template),
type))
{ {
if (rval == NULL_TREE || rval == type) if (rval == NULL_TREE || rval == type)
return type; return type;
...@@ -3375,7 +3376,8 @@ get_template_base (template, binfo) ...@@ -3375,7 +3376,8 @@ get_template_base (template, binfo)
my_friendly_abort (92); my_friendly_abort (92);
if (CLASSTYPE_TEMPLATE_INFO (type) if (CLASSTYPE_TEMPLATE_INFO (type)
&& CLASSTYPE_TI_TEMPLATE (type) == template) && specializations_of_same_template_p (TREE_TYPE (template),
type))
return type; return type;
rval = get_template_base_recursive (binfo, NULL_TREE, template, 0); rval = get_template_base_recursive (binfo, NULL_TREE, template, 0);
......
// Build don't link:
template <class T> struct S
{
template <class U> struct I
{
};
S();
S(S& s);
S(I<T>);
template <class U> operator I<U>();
};
S<int> f();
void g(S<int>);
void h()
{
g(f());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment