Commit 6bdb985f by Mark Mitchell Committed by Mark Mitchell

pt.c (instantiate_class_template): Don't try to figure out what specialization…

pt.c (instantiate_class_template): Don't try to figure out what specialization to use for a partial instantiation.

	* pt.c (instantiate_class_template): Don't try to figure out what
	specialization to use for a partial instantiation.  Correct
	typos in a couple of comments.  Avoid calling uses_template_parms
	multiple times.

From-SVN: r23808
parent c9a3de16
1998-11-23 Mark Mitchell <mark@markmitchell.com>
* pt.c (instantiate_class_template): Don't try to figure out what
specialization to use for a partial instantiation. Correct
typos in a couple of comments. Avoid calling uses_template_parms
multiple times.
1998-11-23 Benjamin Kosnik <bkoz@cygnus.com> 1998-11-23 Benjamin Kosnik <bkoz@cygnus.com>
* method.c (process_overload_item): Add call to * method.c (process_overload_item): Add call to
......
...@@ -4452,6 +4452,7 @@ instantiate_class_template (type) ...@@ -4452,6 +4452,7 @@ instantiate_class_template (type)
{ {
tree template, args, pattern, t; tree template, args, pattern, t;
tree typedecl; tree typedecl;
int is_partial_instantiation;
if (type == error_mark_node) if (type == error_mark_node)
return error_mark_node; return error_mark_node;
...@@ -4465,29 +4466,52 @@ instantiate_class_template (type) ...@@ -4465,29 +4466,52 @@ instantiate_class_template (type)
argument coercion and such is simply lost. */ argument coercion and such is simply lost. */
push_momentary (); push_momentary ();
/* Figure out which template is being instantiated. */
template = most_general_template (CLASSTYPE_TI_TEMPLATE (type)); template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
args = CLASSTYPE_TI_ARGS (type);
my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279); my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279);
t = most_specialized_class (template, args);
if (t == error_mark_node) /* Figure out which arguments are being used to do the
instantiation. */
args = CLASSTYPE_TI_ARGS (type);
is_partial_instantiation = uses_template_parms (args);
if (is_partial_instantiation)
/* There's no telling which specialization is appropriate at this
point. Since all peeking at the innards of this partial
instantiation are extensions (like the "implicit typename"
extension, which allows users to omit the keyword `typename' on
names that are declared as types in template base classes), we
are free to do what we please.
Trying to figure out which partial instantiation to use can
cause a crash. (Some of the template arguments don't even have
types.) So, we just use the most general version. */
t = NULL_TREE;
else
{ {
char *str = "candidates are:"; t = most_specialized_class (template, args);
cp_error ("ambiguous class template instantiation for `%#T'", type);
for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t; t = TREE_CHAIN (t)) if (t == error_mark_node)
{ {
if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), char *str = "candidates are:";
args)) cp_error ("ambiguous class template instantiation for `%#T'", type);
for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t;
t = TREE_CHAIN (t))
{ {
cp_error_at ("%s %+#T", str, TREE_TYPE (t)); if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t),
str = " "; args))
{
cp_error_at ("%s %+#T", str, TREE_TYPE (t));
str = " ";
}
} }
TYPE_BEING_DEFINED (type) = 1;
type = error_mark_node;
goto end;
} }
TYPE_BEING_DEFINED (type) = 1;
type = error_mark_node;
goto end;
} }
else if (t)
if (t)
pattern = TREE_TYPE (t); pattern = TREE_TYPE (t);
else else
pattern = TREE_TYPE (template); pattern = TREE_TYPE (template);
...@@ -4523,14 +4547,14 @@ instantiate_class_template (type) ...@@ -4523,14 +4547,14 @@ instantiate_class_template (type)
args = inner_args; args = inner_args;
} }
if (pedantic && uses_template_parms (args)) if (pedantic && is_partial_instantiation)
{ {
/* If there are still template parameters amongst the args, then /* If this is a partial instantiation, then we can't instantiate
we can't instantiate the type; there's no telling whether or not one the type; there's no telling whether or not one of the
of the template parameters might eventually be instantiated to some template parameters might eventually be instantiated to some
value that results in a specialization being used. We do the value that results in a specialization being used. We do
type as complete so that, for example, declaring one of its mark the type as complete so that, for example, declaring one
members to be a friend will not be rejected. */ of its members to be a friend will not be rejected. */
TYPE_SIZE (type) = integer_zero_node; TYPE_SIZE (type) = integer_zero_node;
goto end; goto end;
} }
...@@ -4603,7 +4627,7 @@ instantiate_class_template (type) ...@@ -4603,7 +4627,7 @@ instantiate_class_template (type)
/* If this is a partial instantiation, don't tsubst anything. We will /* If this is a partial instantiation, don't tsubst anything. We will
only use this type for implicit typename, so the actual contents don't only use this type for implicit typename, so the actual contents don't
matter. All that matters is whether a particular name is a type. */ matter. All that matters is whether a particular name is a type. */
if (uses_template_parms (type)) if (is_partial_instantiation)
{ {
TYPE_BINFO_BASETYPES (type) = TYPE_BINFO_BASETYPES (pattern); TYPE_BINFO_BASETYPES (type) = TYPE_BINFO_BASETYPES (pattern);
TYPE_FIELDS (type) = TYPE_FIELDS (pattern); TYPE_FIELDS (type) = TYPE_FIELDS (pattern);
...@@ -7335,7 +7359,7 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) ...@@ -7335,7 +7359,7 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
return 0; return 0;
/* If PARM uses template parameters, then we can't bail out here, /* If PARM uses template parameters, then we can't bail out here,
even in ARG == PARM, since we won't record unifications for the even if ARG == PARM, since we won't record unifications for the
template parameters. We might need them if we're trying to template parameters. We might need them if we're trying to
figure out which of two things is more specialized. */ figure out which of two things is more specialized. */
if (arg == parm && !uses_template_parms (parm)) if (arg == parm && !uses_template_parms (parm))
......
// Build don't link:
template <class T, int I>
struct S {
};
template <int I>
struct S <double, I> {
};
template <class T>
void f ()
{
S<double, T::x> s;
}
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