From ab09753510d568c1bbca882b0e9b599e1c36e599 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 23 Nov 2000 15:19:36 +0000 Subject: 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 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/pt.c | 49 ++++++++++++++++++++++++++----------------------- 2 files changed, 32 insertions(+), 23 deletions(-) (limited to 'gcc/cp') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4e24762..ec50f9e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2000-11-23 Nathan Sidwell + + * 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 * Make-lang.in (g++spec.o, cxxmain.o): Depend on $(CONFIG_H). diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ddcdf8a..bbc6700 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3700,9 +3700,7 @@ maybe_get_template_decl_from_type_decl (decl) 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 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 - copy it here to keep it from being reclaimed when the decl storage - is reclaimed. + otherwise.) IN_DECL, if non-NULL, is the template declaration we are trying to instantiate. @@ -3925,23 +3923,16 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) 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) - 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 - 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 well. */ is_partial_instantiation = uses_template_parms (arglist); @@ -4016,9 +4007,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) found = template; else { - /* This is a full instantiation of a member template. There - should be some partial instantiation of which this is an - instance. */ + /* This is a full instantiation of a member template. Look + for a partial instantiation of which this is an instance. */ for (found = DECL_TEMPLATE_INSTANTIATIONS (template); found; found = TREE_CHAIN (found)) @@ -4054,11 +4044,24 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) } if (!found) - my_friendly_abort (0); + { + /* There was no partial instantiation. This happens + where C is a member template of A and it's used + in something like + + template struct B { A::C m; }; + B; + + 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, - tree_cons (found, arglist, NULL_TREE)); + SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE)); DECL_TEMPLATE_INSTANTIATIONS (template) = tree_cons (arglist, t, DECL_TEMPLATE_INSTANTIATIONS (template)); -- cgit v1.1