This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
PATCH for nested template classes
- To: Jason Merrill <jason at cygnus dot com>
- Subject: PATCH for nested template classes
- From: Mark Mitchell <mmitchell at usa dot net>
- Date: Mon, 20 Apr 1998 15:28:43 -0700
- Cc: egcs-bugs at cygnus dot com
- Reply-to: mmitchell at usa dot net
The following:
template <class T>
class S
{
template <class U>
class S2 {
S2(const S2<U>& s2u) {}
};
};
caused a complain that `S2' was not a template type. This is bogus,
of course. Here's a fix.
--
Mark Mitchell <mmitchell@usa.net>
http://home.earthlink.net/~mbmitchell
Consulting Services Available
Mon Apr 20 14:56:57 1998 Mark Mitchell <mmitchell@usa.net>
* pt.c (get_template_decl_from_type_decl): New function.
(lookup_template_class): Use it.
Index: pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.117
diff -c -p -r1.117 pt.c
*** pt.c 1998/04/17 21:25:37 1.117
--- pt.c 1998/04/20 21:53:13
*************** static tree reduce_template_parm_level P
*** 100,106 ****
--- 99,106 ----
static tree build_template_decl PROTO((tree, tree));
static int mark_template_parm PROTO((tree, void *));
static tree tsubst_friend_function PROTO((tree, tree));
static tree get_bindings_real PROTO((tree, tree, tree, int));
+ static tree get_template_decl_from_type_decl PROTO((tree));
/* Do any processing required when DECL (a member template declaration
using TEMPLATE_PARAMETERS as its innermost parameter list) is
*************** lookup_template_function (fns, arglist)
*** 2696,2702 ****
--- 2744,2772 ----
fns, arglist);
}
+ /* Within the scope of a template class S<T>, the name S gets bound
+ (in build_self_reference) to a TYPE_DECL for the class, not a
+ TEMPLATE_DECL. If TYPEDECL is a TYPE_DECL for current_class_type,
+ or one of its enclosing classes, and that type is a template,
+ return the associated TEMPLATE_DECL. */
+ tree
+ get_template_decl_from_type_decl (type_decl)
+ tree type_decl;
+ {
+ if (TREE_CODE (type_decl) == TYPE_DECL)
+ {
+ tree t;
+
+ for (t = current_class_type; t != NULL_TREE; t = TYPE_CONTEXT (t))
+ if (comptypes (TREE_TYPE (type_decl), t, 1)
+ && CLASSTYPE_TEMPLATE_INFO (t))
+ return CLASSTYPE_TI_TEMPLATE (t);
+ }
+
+ return NULL_TREE;
+ }
+
/* Given an IDENTIFIER_NODE (type TEMPLATE_DECL) and a chain of
parameters, find the desired type.
*************** lookup_template_class (d1, arglist, in_d
*** 2730,2736 ****
{
template = IDENTIFIER_NAMESPACE_VALUE (d1); /* XXX */
if (! template)
! template = IDENTIFIER_CLASS_VALUE (d1);
}
if (template)
context = DECL_CONTEXT (template);
--- 2800,2814 ----
{
template = IDENTIFIER_NAMESPACE_VALUE (d1); /* XXX */
if (! template)
! {
! template = IDENTIFIER_CLASS_VALUE (d1);
! if (TREE_CODE (template) == TYPE_DECL)
! {
! tree t = get_template_decl_from_type_decl (template);
! if (t != NULL_TREE)
! template = t;
! }
! }
}
if (template)
context = DECL_CONTEXT (template);
Index: ../testsuite/g++.old-deja/g++.pt/memclass8.C
===================================================================
RCS file: memclass8.C
diff -N memclass8.C
*** /dev/null Mon Dec 31 20:00:00 1979
--- memclass8.C Mon Apr 20 14:55:47 1998
***************
*** 0 ****
--- 1,11 ----
+ // Build don't link:
+
+ template <class T>
+ class S
+ {
+ template <class U>
+ class S2 {
+ S2(const S2<U>& s2u) {}
+ };
+ };
+