Patch for various template template parameter update

Kriang Lerdsuwanakij lerdsuwa@scf-fs.usc.edu
Tue Feb 3 20:51:00 GMT 1998


Hi

Below are two patches that update the template template param code.  The
first patch should be applied before the second one.  

The first patch involves some code cleanup as suggested by Jason and
resolves a possible ambiguilty inside class template.  This also fixes
the ttp22.C and ttp23.C failures.

The second patch handles some changes made to 980129 snapshot and fixes
problems from the parser change in the first one.

Enjoy

Kriang

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

	* parse.y (template_parm): Use template_arg instead of PTYPENAME 
	for default template template argument.

	* pt.c (coerce_template_parms): Merge default template argument 
	codes.  Can treat RECORD_TYPE as template name if it is implicitly
	created.  Fix argument index in error message.

	* typeck.c (comptypes): Merge template argument comparison codes in 
	TEMPLATE_TEMPLATE_PARM and RECORD_TYPE.

diff -rNpc3 gcc-old/cp/parse.y gcc/cp/parse.y
*** gcc-old/cp/parse.y	Wed Jan 28 12:27:06 1998
--- gcc/cp/parse.y	Wed Jan 28 12:25:35 1998
*************** template_parm:
*** 538,556 ****
  		{ $$ = build_tree_list ($3, $1.t); }
  	| template_template_parm
  		{ $$ = build_tree_list (NULL_TREE, $1); }
! 	| template_template_parm '=' PTYPENAME
! 	  	{
! 		  tree defarg;
! 	  	  arg_looking_for_template = 1;
! 	  	  defarg = lookup_name ($3, 0);
! 	  	  arg_looking_for_template = 0;
! 			
! 		  if (!defarg || defarg == error_mark_node
! 		      || (TREE_CODE (defarg) != TEMPLATE_DECL
! 			  && TREE_CODE (defarg) != TEMPLATE_TEMPLATE_PARM))
! 		    defarg = do_identifier ($3, 1);
! 		  $$ = build_tree_list (defarg, $1);
! 	  	}
  	;
  
  template_def:
--- 538,545 ----
  		{ $$ = build_tree_list ($3, $1.t); }
  	| template_template_parm
  		{ $$ = build_tree_list (NULL_TREE, $1); }
! 	| template_template_parm '=' template_arg
! 	  	{ $$ = build_tree_list ($3, $1); }
  	;
  
  template_def:
*************** nonnested_type:
*** 3075,3084 ****
  		{
  		  if (TREE_CODE ($1) == IDENTIFIER_NODE)
  		    {
- 		      arg_looking_for_template = processing_template_arg;
  		      $$ = lookup_name ($1, 1);
- 		      arg_looking_for_template = 0;
- 
  		      if (current_class_type
  			  && TYPE_BEING_DEFINED (current_class_type)
  			  && ! IDENTIFIER_CLASS_VALUE ($1))
--- 3064,3070 ----
diff -rNpc3 gcc-old/cp/pt.c gcc/cp/pt.c
*** gcc-old/cp/pt.c	Wed Jan 28 12:27:19 1998
--- gcc/cp/pt.c	Wed Jan 28 12:25:39 1998
*************** coerce_template_parms (parms, arglist, i
*** 1688,1721 ****
        return error_mark_node;
      }
  
!   if (arglist && TREE_CODE (arglist) == TREE_VEC)
!     if (nargs == nparms)
!       vec = copy_node (arglist);
!     else
!       {
! 	/* We arrive here when a template with some default arguments
! 	   is used as template template argument.  */
! 	is_tmpl_parm = 1;
! 	vec = make_tree_vec (nparms);
! 	for (i = 0; i < nparms; i++)
! 	  {
! 	    tree arg;
! 
! 	    if (i < nargs)
! 	      arg = TREE_VEC_ELT (arglist, i);
! 	    else if (TREE_CODE (TREE_VALUE (TREE_VEC_ELT (parms, i)))
! 		     == TYPE_DECL)
! 	      arg = tsubst (TREE_PURPOSE (TREE_VEC_ELT (parms, i)),
! 			    vec, i, in_decl);
! 	    else
! 	      arg = tsubst_expr (TREE_PURPOSE (TREE_VEC_ELT (parms, i)),
! 				 vec, i, in_decl);
! 
! 	    TREE_VEC_ELT (vec, i) = arg;
! 	  }
!       }
    else
      {
        vec = make_tree_vec (nparms);
  
        for (i = 0; i < nparms; i++)
--- 1688,1701 ----
        return error_mark_node;
      }
  
!   if (arglist && TREE_CODE (arglist) == TREE_VEC && nargs == nparms)
!     vec = copy_node (arglist);
    else
      {
+       /* We can arrive here with arglist being a TREE_VEC when a 
+ 	 template with some default arguments is used as template 
+ 	 template argument.  */
+       is_tmpl_parm = TREE_CODE (arglist) == TREE_VEC;
        vec = make_tree_vec (nparms);
  
        for (i = 0; i < nparms; i++)
*************** coerce_template_parms (parms, arglist, i
*** 1723,1729 ****
  	  tree arg;
  	  tree parm = TREE_VEC_ELT (parms, i);
  
! 	  if (arglist)
  	    {
  	      arg = arglist;
  	      arglist = TREE_CHAIN (arglist);
--- 1703,1709 ----
  	  tree arg;
  	  tree parm = TREE_VEC_ELT (parms, i);
  
! 	  if (!is_tmpl_parm && arglist)
  	    {
  	      arg = arglist;
  	      arglist = TREE_CHAIN (arglist);
*************** coerce_template_parms (parms, arglist, i
*** 1733,1738 ****
--- 1713,1724 ----
  	      else
  		arg = TREE_VALUE (arg);
  	    }
+ 	  else if (is_tmpl_parm && i < nargs)
+ 	    {
+ 	      arg = TREE_VEC_ELT (arglist, i);
+ 	      if (arg == error_mark_node)
+ 		lost++;
+ 	    }
  	  else if (TREE_PURPOSE (parm) == NULL_TREE)
  	    {
  	      my_friendly_assert (!require_all_arguments, 0);
*************** coerce_template_parms (parms, arglist, i
*** 1776,1795 ****
  	  arg = TREE_VALUE (arg);
  	}
  
!       /* Check if it is a class template.  */
        is_tmpl_type = (TREE_CODE (arg) == TEMPLATE_DECL
  		      && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
  		     || (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
! 			 && !CLASSTYPE_TEMPLATE_INFO (arg));
        if (is_tmpl_type && TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
  	arg = TYPE_STUB_DECL (arg);
        
-       requires_tmpl_type = TREE_CODE (parm) == TEMPLATE_DECL;
        is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't'
  		|| is_tmpl_type
  		|| (is_tmpl_parm && TREE_CODE (arg) == TYPE_DECL);
-       requires_type = TREE_CODE (parm) == TYPE_DECL
- 		      || requires_tmpl_type;
  
        if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
  	  && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
--- 1762,1790 ----
  	  arg = TREE_VALUE (arg);
  	}
  
!       requires_tmpl_type = TREE_CODE (parm) == TEMPLATE_DECL;
!       requires_type = TREE_CODE (parm) == TYPE_DECL
! 		      || requires_tmpl_type;
! 
!       /* Check if it is a class template.  If REQUIRES_TMPL_TYPE is
true,
! 	 we also accept implicitly created TYPE_DECL as a valid argument.  */
        is_tmpl_type = (TREE_CODE (arg) == TEMPLATE_DECL
  		      && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
  		     || (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
! 			 && !CLASSTYPE_TEMPLATE_INFO (arg))
! 		     || (TREE_CODE (arg) == RECORD_TYPE
! 		         && CLASSTYPE_TEMPLATE_INFO (arg)
! 		         && TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL
! 			 && DECL_ARTIFICIAL (TYPE_NAME (arg))
! 			 && requires_tmpl_type);
        if (is_tmpl_type && TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
  	arg = TYPE_STUB_DECL (arg);
+       else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE)
+ 	arg = CLASSTYPE_TI_TEMPLATE (arg);
        
        is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't'
  		|| is_tmpl_type
  		|| (is_tmpl_parm && TREE_CODE (arg) == TYPE_DECL);
  
        if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
  	  && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
*************** coerce_template_parms (parms, arglist, i
*** 1826,1832 ****
  	  if (in_decl)
  	    {
  	      cp_error ("type/value mismatch at argument %d in template
parameter list for `%D'",
! 			i, in_decl);
  	      if (is_tmpl_type)
  		cp_error ("  expected a type, got `%T'", DECL_NAME (arg));
  	      else
--- 1821,1827 ----
  	  if (in_decl)
  	    {
  	      cp_error ("type/value mismatch at argument %d in template
parameter list for `%D'",
! 			i + 1, in_decl);
  	      if (is_tmpl_type)
  		cp_error ("  expected a type, got `%T'", DECL_NAME (arg));
  	      else
diff -rNpc3 gcc-old/cp/typeck.c gcc/cp/typeck.c
*** gcc-old/cp/typeck.c	Wed Jan 28 12:27:11 1998
--- gcc/cp/typeck.c	Wed Jan 28 12:25:43 1998
*************** comptypes (type1, type2, strict)
*** 740,749 ****
  
    switch (TREE_CODE (t1))
      {
      case RECORD_TYPE:
      case UNION_TYPE:
        if (CLASSTYPE_TEMPLATE_INFO (t1) && CLASSTYPE_TEMPLATE_INFO (t2)
! 	  && CLASSTYPE_TI_TEMPLATE (t1) == CLASSTYPE_TI_TEMPLATE (t2))
  	{
  	  int i = TREE_VEC_LENGTH (CLASSTYPE_TI_ARGS (t1));
  	  tree *p1 = &TREE_VEC_ELT (CLASSTYPE_TI_ARGS (t1), 0);
--- 740,760 ----
  
    switch (TREE_CODE (t1))
      {
+     case TEMPLATE_TEMPLATE_PARM:
+       if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
+ 	  || TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2))
+ 	return 0;
+       if (! CLASSTYPE_TEMPLATE_INFO (t1) && ! CLASSTYPE_TEMPLATE_INFO
(t2))
+ 	return 1;
+       /* Don't check inheritance.  */
+       strict = 1;
+       /* fall through */
+ 
      case RECORD_TYPE:
      case UNION_TYPE:
        if (CLASSTYPE_TEMPLATE_INFO (t1) && CLASSTYPE_TEMPLATE_INFO (t2)
! 	  && (CLASSTYPE_TI_TEMPLATE (t1) == CLASSTYPE_TI_TEMPLATE (t2)
! 	      || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM))
  	{
  	  int i = TREE_VEC_LENGTH (CLASSTYPE_TI_ARGS (t1));
  	  tree *p1 = &TREE_VEC_ELT (CLASSTYPE_TI_ARGS (t1), 0);
*************** comptypes (type1, type2, strict)
*** 835,871 ****
        /* Target types must match incl. qualifiers.  */
        val = comp_array_types (comptypes, t1, t2, strict);
        break;
- 
-     case TEMPLATE_TEMPLATE_PARM:
-       if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
- 	  || TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2))
- 	return 0;
- 
-       if (CLASSTYPE_TEMPLATE_INFO (t1) && CLASSTYPE_TEMPLATE_INFO
(t2))
- 	{
- 	  int i = TREE_VEC_LENGTH (CLASSTYPE_TI_ARGS (t1));
- 	  tree *p1 = &TREE_VEC_ELT (CLASSTYPE_TI_ARGS (t1), 0);
- 	  tree *p2 = &TREE_VEC_ELT (CLASSTYPE_TI_ARGS (t2), 0);
- 	
- 	  while (i--)
- 	    {
- 	      if (TREE_CODE_CLASS (TREE_CODE (p1[i])) == 't')
- 		{
- 		  if (! comptypes (p1[i], p2[i], 1))
- 		    return 0;
- 		}
- 	      else
- 		{
- 		  if (simple_cst_equal (p1[i], p2[i]) <= 0)
- 		    return 0;
- 		}
- 	    }
- 	  return 1;
- 	}
-       else if (CLASSTYPE_TEMPLATE_INFO (t1) || CLASSTYPE_TEMPLATE_INFO
(t2))
- 	return 0;
-       else
- 	return 1;
  
      case TEMPLATE_TYPE_PARM:
        return TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2)
--- 846,851 ----
diff -rNpc3 gcc-old/testsuite/g++.old-deja/g++.pt/ttp40.C
gcc/testsuite/g++.old-deja/g++.pt/ttp40.C
*** gcc-old/testsuite/g++.old-deja/g++.pt/ttp40.C	Wed Dec 31 16:00:00
1969
--- gcc/testsuite/g++.old-deja/g++.pt/ttp40.C	Wed Jan 28 12:13:16 1998
***************
*** 0 ****
--- 1,20 ----
+ #include <vector>
+ 
+ template<class E,template<class> class DD = std::vector> class C
+ {
+ 		DD<E> d;
+ 	public:
+ 		int f();
+ };
+ 
+ template<class E,template<class> class DD> int C<E,DD>::f()
+ {
+ 	DD<E> d2;
+ 	return d2.size();
+ }
+ 
+ int main()
+ {
+ 	C<int> c;
+ 	c.f();
+ }
diff -rNpc3 gcc-old/testsuite/g++.old-deja/g++.pt/ttp41.C
gcc/testsuite/g++.old-deja/g++.pt/ttp41.C
*** gcc-old/testsuite/g++.old-deja/g++.pt/ttp41.C	Wed Dec 31 16:00:00
1969
--- gcc/testsuite/g++.old-deja/g++.pt/ttp41.C	Wed Jan 28 12:13:20 1998
***************
*** 0 ****
--- 1,23 ----
+ template<template<class> class D,class E> class C
+ {
+ 	public:
+ 		int g() { return 1; }
+ };
+ 
+ template<class T> class D
+ {
+ 	public:
+ 		int f();
+ };
+ 
+ template<class T> int D<T>::f()
+ {
+ 	C<D,D> c;
+ 	c.g();
+ }
+ 
+ int main()
+ {
+ 	D<char> d;
+ 	d.f();
+ }

========================================================
	* error.c (dump_decl): Fix type of default arguments for template
	template parameters and nontype template parameters.

	* parse.y (template_parm): Handle invalid default template 
	template arguments here.

diff -rNpc3 gcc-old/cp/error.c gcc/cp/error.c
*** gcc-old/cp/error.c	Tue Feb  3 15:00:18 1998
--- gcc/cp/error.c	Tue Feb  3 14:59:54 1998
*************** dump_decl (t, v)
*** 786,795 ****
  		if (defval)
  		  {
  		    OB_PUTS (" = ");
! 		    if (TREE_CODE (arg) == TYPE_DECL)
  		      dump_type (defval, 1);
  		    else
! 		      dump_decl (defval, 1);
  		  }
  		
  		OB_PUTC2 (',', ' ');
--- 786,796 ----
  		if (defval)
  		  {
  		    OB_PUTS (" = ");
! 		    if (TREE_CODE (arg) == TYPE_DECL
! 			|| TREE_CODE (arg) == TEMPLATE_DECL)
  		      dump_type (defval, 1);
  		    else
! 		      dump_expr (defval, 1);
  		  }
  		
  		OB_PUTC2 (',', ' ');
diff -rNpc3 gcc-old/cp/parse.y gcc/cp/parse.y
*** gcc-old/cp/parse.y	Tue Feb  3 14:25:37 1998
--- gcc/cp/parse.y	Tue Feb  3 14:39:29 1998
*************** template_parm:
*** 513,519 ****
  	| template_template_parm
  		{ $$ = build_tree_list (NULL_TREE, $1); }
  	| template_template_parm '=' template_arg
! 	  	{ $$ = build_tree_list ($3, $1); }
  	;
  
  template_def:
--- 513,528 ----
  	| template_template_parm
  		{ $$ = build_tree_list (NULL_TREE, $1); }
  	| template_template_parm '=' template_arg
! 		{
! 		  if (TREE_CODE ($3) != TEMPLATE_DECL
! 		      && TREE_CODE ($3) != TEMPLATE_TEMPLATE_PARM
! 		      && TREE_CODE ($3) != TYPE_DECL)
! 		    {
! 		      error ("invalid default template argument");
! 		      $3 = error_mark_node;
! 		    }
! 		  $$ = build_tree_list ($3, $1);
! 		}
  	;
  
  template_def:
diff -rNpc3 gcc-old/testsuite/g++.old-deja/g++.pt/ttp41.C
gcc/testsuite/g++.old-deja/g++.pt/ttp41.C
*** gcc-old/testsuite/g++.old-deja/g++.pt/ttp41.C	Tue Feb  3 20:17:20
1998
--- gcc/testsuite/g++.old-deja/g++.pt/ttp41.C	Tue Feb  3 20:18:07 1998
*************** template<class T> class D
*** 13,19 ****
  template<class T> int D<T>::f()
  {
  	C<D,D> c;
! 	c.g();
  }
  
  int main()
--- 13,19 ----
  template<class T> int D<T>::f()
  {
  	C<D,D> c;
! 	return c.g();
  }
  
  int main()
=================================================================



More information about the Gcc mailing list