public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Patch for member class template problems
@ 1998-03-30 16:18 Kriang Lerdsuwanakij
  0 siblings, 0 replies; only message in thread
From: Kriang Lerdsuwanakij @ 1998-03-30 16:18 UTC (permalink / raw)
  To: egcs

Hi

I fix several problems in template code exposed by the recent addition of
member class template.  The changes are summarized below:

- instantiate_class_template now supplies unbound template arguments when
  calling tsubst.  This is required to partially instantiate templates
  inside the template class/function.  In memclass8.C, D<0> is instantiated
  while its context, C<T>, still not bound until inside main().

  The TEMPLATE_ARGS_UNBOUND_P macro is introduced to ensure that we don't 
  take into account unbound outer template arguments when reducing template 
  level.

- Name mangling mechanism inside tsubst, case FUNCTION_DECL is changed.
  It doesn't work when the function template is a member of member class
  template.  Wrong template parameters and arguments were used to build
  the mangled name.  I change the code so that unbound arguments are 
  used rather than resort to outer levels when the desired arguments are
  still not bound.  The changes only effect name mangling of partially
  instantiated templates and does not appear in object files.

--Kriang

===================================================================

	* cp-tree.h (TEMPLATE_ARGS_UNBOUND_P): New macro.
	pt.c (complete_template_args, tsubst): Use it.
	(complete_template_args): Handle member class template.
	(instantiate_class_template): Add unbound outer template
	arguments if available.
	(instantiate_decl): Do not tsubst non-template member
	function.
	(tsubst, FUNCTION_DECL): Always use innermost template
	parameters for name mangling.

===================================================================
diff -cpNr gcc-980322/cp/cp-tree.h gcc-980329/cp/cp-tree.h
*** gcc-980322/cp/cp-tree.h	Fri Mar 27 12:36:21 1998
--- gcc-980329/cp/cp-tree.h	Fri Mar 27 12:35:36 1998
*************** struct lang_decl
*** 1157,1162 ****
--- 1157,1166 ----
  #define CLASSTYPE_TI_SPEC_INFO(NODE) TI_SPEC_INFO (CLASSTYPE_TEMPLATE_INFO (NODE))
  #define INNERMOST_TEMPLATE_PARMS(NODE)  TREE_VALUE(NODE)
  
+ /* True if unbound template arguments are added to this template 
+    argument vector.  */
+ #define TEMPLATE_ARGS_UNBOUND_P(NODE)	TREE_LANG_FLAG_0 (NODE)
+ 
  #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE)
  
  #define DECL_SAVED_TREE(NODE)		DECL_MEMFUNC_POINTER_TO (NODE)
diff -cpNr gcc-980322/cp/pt.c gcc-980329/cp/pt.c
*** gcc-980322/cp/pt.c	Fri Mar 27 12:36:50 1998
--- gcc-980329/cp/pt.c	Sun Mar 29 14:16:41 1998
*************** complete_template_args (tmpl, extra_args
*** 410,419 ****
  	return extra_args;
  
        new_args = make_tree_vec (depth + 1);
  
        /* If this isn't a member template, extra_args is for the innermost
  	 template class, so skip over it.  */
!       skip = (! is_member_template (tmpl));
  
        type = DECL_REAL_CONTEXT (tmpl);
        for (i = depth; i; type = TYPE_CONTEXT (type))
--- 410,421 ----
  	return extra_args;
  
        new_args = make_tree_vec (depth + 1);
+       TEMPLATE_ARGS_UNBOUND_P (new_args) = 1;
  
        /* If this isn't a member template, extra_args is for the innermost
  	 template class, so skip over it.  */
!       skip = (! is_member_template (tmpl)
! 	      && TREE_CODE (DECL_TEMPLATE_RESULT (tmpl)) != TYPE_DECL);
  
        type = DECL_REAL_CONTEXT (tmpl);
        for (i = depth; i; type = TYPE_CONTEXT (type))
*************** instantiate_class_template (type)
*** 3188,3193 ****
--- 3190,3197 ----
  
    if (outer_args)
      args = add_to_template_args (outer_args, args);
+   else
+     args = complete_template_args (TI_TEMPLATE (template_info), args, 1);
  
    if (flag_external_templates)
      {
*************** tsubst (t, args, in_decl)
*** 3682,3687 ****
--- 3686,3696 ----
  	   more deeply nested template.  */
  	my_friendly_assert(level > 1, 0);
  	
+ 	/* Only reduce template level by 1 when outer template arguments are
+ 	   unbound.  */
+ 	if (TEMPLATE_ARGS_UNBOUND_P (args))
+ 	  levels = 1;
+ 
  	/* Make a new version of this template parameter, but with a
  	   lower level.  */
  	switch (TREE_CODE (t))
*************** tsubst (t, args, in_decl)
*** 3726,3731 ****
--- 3735,3743 ----
  	tree parms;
  	tree* new_parms;
  	tree spec;
+ 	int parm_depth;
+ 	int level_reduce;
+ 	int j;
  
  	if (TREE_CODE (decl) == TYPE_DECL
  	    && TREE_CODE (TREE_TYPE (decl)) == TEMPLATE_TEMPLATE_PARM)
*************** tsubst (t, args, in_decl)
*** 3772,3785 ****
  	DECL_TEMPLATE_INSTANTIATIONS (tmpl) = NULL_TREE;
  	SET_DECL_IMPLICIT_INSTANTIATION (tmpl);
  
  	/* The template parameters for this new template are all the
  	   template parameters for the old template, except the
  	   outermost level of parameters. */
  	for (new_parms = &DECL_TEMPLATE_PARMS (tmpl),
! 	       parms = DECL_TEMPLATE_PARMS (t);
! 	     TREE_CHAIN (parms) != NULL_TREE;
  	     new_parms = &(TREE_CHAIN (*new_parms)),
! 	       parms = TREE_CHAIN (parms))
  	  {
  	    tree new_vec = 
  	      make_tree_vec (TREE_VEC_LENGTH (TREE_VALUE (parms)));
--- 3784,3806 ----
  	DECL_TEMPLATE_INSTANTIATIONS (tmpl) = NULL_TREE;
  	SET_DECL_IMPLICIT_INSTANTIATION (tmpl);
  
+ 	level_reduce = TREE_CODE (TREE_VEC_ELT (args, 0)) != TREE_VEC
+ 		       ? 1: TREE_VEC_LENGTH (args);
+ 	/* Only reduce template level by 1 when outer template arguments are
+ 	   unbound.  */
+ 	if (level_reduce > 1 && TEMPLATE_ARGS_UNBOUND_P (args))
+ 	  level_reduce = 1;
+ 
+ 	parm_depth = list_length (DECL_TEMPLATE_PARMS (tmpl));
+ 
  	/* The template parameters for this new template are all the
  	   template parameters for the old template, except the
  	   outermost level of parameters. */
  	for (new_parms = &DECL_TEMPLATE_PARMS (tmpl),
! 	       parms = DECL_TEMPLATE_PARMS (t), j = 0;
! 	     j < parm_depth - level_reduce;
  	     new_parms = &(TREE_CHAIN (*new_parms)),
! 	       parms = TREE_CHAIN (parms), ++j)
  	  {
  	    tree new_vec = 
  	      make_tree_vec (TREE_VEC_LENGTH (TREE_VALUE (parms)));
*************** tsubst (t, args, in_decl)
*** 3801,3807 ****
  	    *new_parms = 
  	      tree_cons (build_int_2 (0, 
  				      TREE_INT_CST_HIGH 
! 				      (TREE_PURPOSE (parms)) - 1),
  			 new_vec,
  			 NULL_TREE);
  	  }
--- 3822,3828 ----
  	    *new_parms = 
  	      tree_cons (build_int_2 (0, 
  				      TREE_INT_CST_HIGH 
! 				      (TREE_PURPOSE (parms)) - level_reduce),
  			 new_vec,
  			 NULL_TREE);
  	  }
*************** tsubst (t, args, in_decl)
*** 3991,4007 ****
  
  		if (!DECL_TEMPLATE_SPECIALIZATION (tmpl)) 
  		  {
! 		    /* We pass the outermost template parameters to
! 		       build_template_decl_overload, since the innermost
! 		       template parameters are still just template
! 		       parameters; there are no corresponding subsitution
! 		       arguments.  Levels of parms that have been bound
! 		       before are not represented in DECL_TEMPLATE_PARMS.  */
  		    tparms = DECL_TEMPLATE_PARMS (tmpl);
! 		    while (tparms && TREE_CHAIN (tparms) != NULL_TREE)
! 		      tparms = TREE_CHAIN (tparms);
! 		    
! 		    targs = innermost_args (args, 0);
  		  }
  		else
  		  {
--- 4012,4037 ----
  
  		if (!DECL_TEMPLATE_SPECIALIZATION (tmpl)) 
  		  {
! 		    /* We pass the innermost template parameters to
! 		       build_template_decl_overload.  The corresponding
! 		       template arguments may come from ARGS or may
! 		       still just template parameters.  Levels of parms 
! 		       that have been bound before are not represented 
! 		       in DECL_TEMPLATE_PARMS.  */
  		    tparms = DECL_TEMPLATE_PARMS (tmpl);
! 
! 		    if (DECL_TEMPLATE_INFO (r))
! 		      {
! 			int depth1 = TREE_CODE (TREE_VEC_ELT (args, 0)) != TREE_VEC
! 				     ? 1: TREE_VEC_LENGTH (args);
! 			int depth2 = list_length (tparms);
! 			if (depth1 < depth2)
! 			  targs = DECL_TI_ARGS (r);
! 			else
! 			  targs = innermost_args (args, 0);
! 		      }
! 		    else
! 		      targs = innermost_args (args, 0);
  		  }
  		else
  		  {
*************** instantiate_decl (d)
*** 6248,6262 ****
    lineno = DECL_SOURCE_LINE (d);
    input_filename = DECL_SOURCE_FILE (d);
  
!   /* Trick tsubst into giving us a new decl in case the template changed.  */
!   save_ti = DECL_TEMPLATE_INFO (decl_pattern);
!   DECL_TEMPLATE_INFO (decl_pattern) = NULL_TREE;
!   /* decl_pattern has all but one level of template parms bound.  Only pass
!      in that one level of args.  */
!   temp = innermost_args (args, DECL_TEMPLATE_SPECIALIZATION (decl_pattern));
!   td = tsubst (decl_pattern, temp, tmpl);
!   SET_DECL_IMPLICIT_INSTANTIATION (td);
!   DECL_TEMPLATE_INFO (decl_pattern) = save_ti;
  
    /* And set up DECL_INITIAL, since tsubst doesn't.  */
    if (TREE_CODE (td) == VAR_DECL)
--- 6278,6304 ----
    lineno = DECL_SOURCE_LINE (d);
    input_filename = DECL_SOURCE_FILE (d);
  
!   if (DECL_CONTEXT (code_pattern) != NULL_TREE
!       && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (code_pattern))) == 't'
!       && ! is_member_template (code_pattern)
!       && TREE_CODE (DECL_TEMPLATE_RESULT (tmpl)) != TYPE_DECL)
!     /* For non-template member functions,  All levels of template arguments
!        is already bounded.  We don't want to do it again.  */
!     td = d;
!   else
!     {
!       /* Trick tsubst into giving us a new decl in case the template 
! 	 changed.  */
!       save_ti = DECL_TEMPLATE_INFO (decl_pattern);
!       DECL_TEMPLATE_INFO (decl_pattern) = NULL_TREE;
!       /* decl_pattern has all but one level of template parms bound.  Only
!  	 pass in that one level of args.  */
!       temp = innermost_args (args, DECL_TEMPLATE_SPECIALIZATION (decl_pattern));
! 
!       td = tsubst (decl_pattern, temp, tmpl);
!       SET_DECL_IMPLICIT_INSTANTIATION (td);
!       DECL_TEMPLATE_INFO (decl_pattern) = save_ti;
!     }
  
    /* And set up DECL_INITIAL, since tsubst doesn't.  */
    if (TREE_CODE (td) == VAR_DECL)
diff -cpNr gcc-980322/testsuite/g++.old-deja/g++.pt/memclass10.C gcc-980329/testsuite/g++.old-deja/g++.pt/memclass10.C
*** gcc-980322/testsuite/g++.old-deja/g++.pt/memclass10.C	Wed Dec 31 16:00:00 1969
--- gcc-980329/testsuite/g++.old-deja/g++.pt/memclass10.C	Fri Mar 27 12:53:09 1998
***************
*** 0 ****
--- 1,13 ----
+ template <class T> struct A {
+   template <int U> struct B {
+     template <class V> void f (V) { }
+     void g () { }
+   };
+ };
+ 
+ main ()
+ {
+   A<int>::B<1> b;
+   b.f (42);
+   b.g ();
+ }
diff -cpNr gcc-980322/testsuite/g++.old-deja/g++.pt/memclass11.C gcc-980329/testsuite/g++.old-deja/g++.pt/memclass11.C
*** gcc-980322/testsuite/g++.old-deja/g++.pt/memclass11.C	Wed Dec 31 16:00:00 1969
--- gcc-980329/testsuite/g++.old-deja/g++.pt/memclass11.C	Fri Mar 27 12:53:48 1998
***************
*** 0 ****
--- 1,20 ----
+ template <class T> struct A {
+   template <int i> struct AA {
+     template <class U> struct B {
+       template <class V> void f (V) { }
+       void g () { }
+     };
+     template <class W> struct B<W*> {
+       void h () { }
+     };
+   };
+ };
+ 
+ main ()
+ {
+   A<int>::AA<0>::B<char> b;
+   b.f (42);
+   b.g ();
+   A<double>::AA<1>::B<void*> b2;
+   b2.h ();
+ }
diff -cpNr gcc-980322/testsuite/g++.old-deja/g++.pt/memclass8.C gcc-980329/testsuite/g++.old-deja/g++.pt/memclass8.C
*** gcc-980322/testsuite/g++.old-deja/g++.pt/memclass8.C	Wed Dec 31 16:00:00 1969
--- gcc-980329/testsuite/g++.old-deja/g++.pt/memclass8.C	Fri Mar 27 12:51:20 1998
***************
*** 0 ****
--- 1,9 ----
+ template <class T> class C {
+ 	template <int i> class D {};
+ 	D<0> d;
+ };
+ 
+ int main()
+ {
+ 	C<int> c;
+ }
diff -cpNr gcc-980322/testsuite/g++.old-deja/g++.pt/memclass9.C gcc-980329/testsuite/g++.old-deja/g++.pt/memclass9.C
*** gcc-980322/testsuite/g++.old-deja/g++.pt/memclass9.C	Wed Dec 31 16:00:00 1969
--- gcc-980329/testsuite/g++.old-deja/g++.pt/memclass9.C	Fri Mar 27 12:52:52 1998
***************
*** 0 ****
--- 1,11 ----
+ template <class T> struct C {
+ 	template <int i> struct D {
+ 		template <class U> struct E {};
+ 	};
+ 	D<0>::E<T> e;
+ };
+ 
+ int main()
+ {
+ 	C<int> c;
+ }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~1998-03-30 16:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-03-30 16:18 Patch for member class template problems Kriang Lerdsuwanakij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).