Commit ab097535 by Nathan Sidwell Committed by Nathan Sidwell

pt.c (lookup_template_class): Simplify loop exit constructs.

cp:
	* pt.c (lookup_template_class): Simplify loop exit constructs.
	Cope when there is no partial instantiation of a template
	template member.
testsuite:
	* g++.old-deja/g++.pt/instantiate9.C: New test.

From-SVN: r37698
parent 8d4af2d7
2000-11-23 Nathan Sidwell <nathan@codesourcery.com>
* pt.c (lookup_template_class): Simplify loop exit constructs.
Cope when there is no partial instantiation of a template
template member.
Thu Nov 23 02:16:47 2000 J"orn Rennecke <amylaar@redhat.com> Thu Nov 23 02:16:47 2000 J"orn Rennecke <amylaar@redhat.com>
* Make-lang.in (g++spec.o, cxxmain.o): Depend on $(CONFIG_H). * Make-lang.in (g++spec.o, cxxmain.o): Depend on $(CONFIG_H).
......
...@@ -3700,9 +3700,7 @@ maybe_get_template_decl_from_type_decl (decl) ...@@ -3700,9 +3700,7 @@ maybe_get_template_decl_from_type_decl (decl)
D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments. D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.
(Actually ARGLIST may be either a TREE_LIST or a TREE_VEC. It will (Actually ARGLIST may be either a TREE_LIST or a TREE_VEC. It will
be a TREE_LIST if called directly from the parser, and a TREE_VEC be a TREE_LIST if called directly from the parser, and a TREE_VEC
otherwise.) Since ARGLIST is build on the temp_decl_obstack, we must otherwise.)
copy it here to keep it from being reclaimed when the decl storage
is reclaimed.
IN_DECL, if non-NULL, is the template declaration we are trying to IN_DECL, if non-NULL, is the template declaration we are trying to
instantiate. instantiate.
...@@ -3925,23 +3923,16 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) ...@@ -3925,23 +3923,16 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
found = NULL_TREE; found = NULL_TREE;
} }
} }
if (!found)
{
for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
found; found = TREE_CHAIN (found))
if (comp_template_args (TREE_PURPOSE (found), arglist))
break;
if (found)
found = TREE_VALUE (found);
}
if (found) if (found)
return found; return found;
for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
found; found = TREE_CHAIN (found))
if (comp_template_args (TREE_PURPOSE (found), arglist))
return TREE_VALUE (found);
/* This type is a "partial instantiation" if any of the template /* This type is a "partial instantiation" if any of the template
arguments still inolve template parameters. Note that we set arguments still involve template parameters. Note that we set
IS_PARTIAL_INSTANTIATION for partial specializations as IS_PARTIAL_INSTANTIATION for partial specializations as
well. */ well. */
is_partial_instantiation = uses_template_parms (arglist); is_partial_instantiation = uses_template_parms (arglist);
...@@ -4016,9 +4007,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) ...@@ -4016,9 +4007,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
found = template; found = template;
else else
{ {
/* This is a full instantiation of a member template. There /* This is a full instantiation of a member template. Look
should be some partial instantiation of which this is an for a partial instantiation of which this is an instance. */
instance. */
for (found = DECL_TEMPLATE_INSTANTIATIONS (template); for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
found; found = TREE_CHAIN (found)) found; found = TREE_CHAIN (found))
...@@ -4054,11 +4044,24 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) ...@@ -4054,11 +4044,24 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
} }
if (!found) if (!found)
my_friendly_abort (0); {
/* There was no partial instantiation. This happens
where C<T> is a member template of A<T> and it's used
in something like
template <typename T> struct B { A<T>::C<int> m; };
B<float>;
Create the partial instantiation.
*/
TREE_VEC_LENGTH (arglist)--;
template = tsubst (template, arglist, /*complain=*/0, NULL_TREE);
TREE_VEC_LENGTH (arglist)++;
found = template;
}
} }
SET_TYPE_TEMPLATE_INFO (t, SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE));
tree_cons (found, arglist, NULL_TREE));
DECL_TEMPLATE_INSTANTIATIONS (template) DECL_TEMPLATE_INSTANTIATIONS (template)
= tree_cons (arglist, t, = tree_cons (arglist, t,
DECL_TEMPLATE_INSTANTIATIONS (template)); DECL_TEMPLATE_INSTANTIATIONS (template));
......
2000-11-23 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.pt/instantiate9.C: New test.
2000-11-22 Mark Mitchell <mark@codesourcery.com> 2000-11-22 Mark Mitchell <mark@codesourcery.com>
* g++.old-deja/g++.other/decl4.C: Tweak so that it fails with the * g++.old-deja/g++.other/decl4.C: Tweak so that it fails with the
......
// Build don't link:
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 22 Nov 2000 <nathan@codesourcery.com>
// Bug 789. We ICE'd trying to instantiate B<float> because there was no
// existing partial specialization of C in A<float>.
template <typename T>
struct A {
template <typename D1>
struct C { };
};
template <typename T1>
struct B {
A<T1>::C<int> s1;
};
int main()
{
B<float> b;
return 0;
}
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