This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

C++ PATCH: Koenig lookup of template template args


This patch address the bug reported in
    http://egcs.cygnus.com/ml/gcc-bugs/1999-08/msg00955.html

Alex Samuel
CodeSourcery, LLC



1999-09-01  Alex Samuel  <samuel@codesourcery.com>

	* decl2.c (arg_assoc_template_arg): New prototype.  New function.
	(arg_assoc_class): Use arg_assoc_template_arg for template
	arguments. 
	(arg_assoc): Likewise.
	* pt.c (mangle_class_name_for_template): Allow member template
	template arguments..



*** /dev/null	Tue May  5 13:32:27 1998
--- ttp57.C	Wed Sep  1 01:27:36 1999
***************
*** 0 ****
--- 1,45 ----
+ // Build don't link:
+ // Origin: Alex Samuel <samuel@codesourcery.com>
+ 
+ namespace NS 
+ { 
+ 
+ template <class T, int V>
+ struct Base
+ {
+ };
+ 
+ template <class T>
+ struct Z
+ {
+   const static int value_ = false;
+ };
+ 
+ template <class T>
+ struct A : 
+   public Base <T, Z<T>::value_>
+ {
+ }; 
+ 
+ template <class T> 
+ void f(T)
+ {
+ }
+ 
+ }
+ 
+ 
+ template <template <class T> class U> 
+ struct B 
+ {
+ };
+ 
+ 
+ int 
+ main ()
+ {
+   B<NS::A> ba; 
+   f (ba);  // Koenig lookup
+   return 0;
+ }
+ 



*** /dev/null	Tue May  5 13:32:27 1998
--- ttp58.C	Wed Sep  1 01:27:41 1999
***************
*** 0 ****
--- 1,48 ----
+ // Build don't link:
+ // Origin: Alex Samuel <samuel@codesourcery.com>
+ 
+ namespace NS
+ { 
+ 
+ template <class T, int V>
+ struct Base
+ {
+ };
+ 
+ template <class T>
+ struct Z
+ {
+   const static int value_ = false;
+ };
+ 
+ class Outer
+ {
+   template <class T>
+   struct A : 
+     public Base <T, Z<T>::value_>
+   {
+   }; 
+ };
+ 
+ template <class T> 
+ void f(T)
+ {
+ }
+ 
+ }
+ 
+ 
+ template <template <class T> class U> 
+ struct B 
+ {
+ };
+ 
+ 
+ int 
+ main ()
+ {
+   B<NS::Outer::A> ba; 
+   f (ba);  // Koenig lookup
+   return 0;
+ }
+ 



Index: decl2.c
===================================================================
RCS file: /cvs/egcs/egcs/gcc/cp/decl2.c,v
retrieving revision 1.245
diff -c -r1.245 decl2.c
*** decl2.c	1999/08/29 19:03:28	1.245
--- decl2.c	1999/09/01 08:30:50
***************
*** 4544,4549 ****
--- 4544,4550 ----
  static int add_function      PROTO((struct arg_lookup *, tree));
  static int arg_assoc_namespace PROTO((struct arg_lookup *, tree));
  static int arg_assoc_class   PROTO((struct arg_lookup *, tree));
+ static int arg_assoc_template_arg PROTO((struct arg_lookup*, tree));
  
  /* Add a function to the lookup structure.
     Returns 1 on error.  */
***************
*** 4607,4612 ****
--- 4608,4653 ----
    return 0;
  }
  
+ /* Adds everything associated with a template argument to the lookup
+    structure.  Returns 1 on error.  */
+ 
+ static int
+ arg_assoc_template_arg (k, arg)
+      struct arg_lookup* k;
+      tree arg;
+ {
+   /* [basic.lookup.koenig]
+ 
+      If T is a template-id, its associated namespaces and classes are
+      ... the namespaces and classes associated with the types of the
+      template arguments provided for template type parameters
+      (excluding template template parameters); the namespaces in which
+      any template template arguments are defined; and the classes in
+      which any member templates used as template template arguments
+      are defined.  [Note: non-type template arguments do not
+      contribute to the set of associated namespaces.  ]  */
+ 
+   /* Consider first template template arguments.  */
+   if (TREE_CODE (arg) == TEMPLATE_DECL)
+     {
+       tree ctx = CP_DECL_CONTEXT (arg);
+ 
+       /* It's not a member template.  */
+       if (TREE_CODE (ctx) == NAMESPACE_DECL)
+         return arg_assoc_namespace (k, ctx);
+       /* Otherwise, it must be member template.  */
+       else 
+         return arg_assoc_class (k, ctx);
+     }
+   /* It's not a template template argument, but it is a type template
+      argument.  */
+   else if (TREE_CODE_CLASS (TREE_CODE (arg)) == 't')
+     return arg_assoc_type (k, arg);
+   /* It's a non-type template argument.  */
+   else
+     return 0;
+ }
+ 
  /* Adds everything associated with class to the lookup structure.
     Returns 1 on error.  */
  
***************
*** 4653,4660 ****
    if (CLASSTYPE_TEMPLATE_INFO (type))
      {
        list = innermost_args (CLASSTYPE_TI_ARGS (type));
!       for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
! 	arg_assoc (k, TREE_VEC_ELT (list, i));
      }
  
    return 0;
--- 4694,4701 ----
    if (CLASSTYPE_TEMPLATE_INFO (type))
      {
        list = innermost_args (CLASSTYPE_TI_ARGS (type));
!       for (i = 0; i < TREE_VEC_LENGTH (list); ++i) 
!         arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
      }
  
    return 0;
***************
*** 4761,4774 ****
  
  	 If T is a template-id, its associated namespaces and classes
  	 are the namespace in which the template is defined; for
! 	 member templates, the member template's class; the namespaces
! 	 and classes associated with the types of the template
! 	 arguments provided for template type parameters (excluding
! 	 template template parameters); the namespaces in which any
! 	 template template arguments are defined; and the classes in
! 	 which any member templates used as template template
! 	 arguments are defined.  [Note: non-type template arguments do
! 	 not contribute to the set of associated namespaces.  ]   */
        tree template = TREE_OPERAND (n, 0);
        tree args = TREE_OPERAND (n, 1);
        tree ctx;
--- 4802,4808 ----
  
  	 If T is a template-id, its associated namespaces and classes
  	 are the namespace in which the template is defined; for
! 	 member templates, the member template's class...  */
        tree template = TREE_OPERAND (n, 0);
        tree args = TREE_OPERAND (n, 1);
        tree ctx;
***************
*** 4793,4816 ****
  
        /* Now the arguments.  */
        for (arg = args; arg != NULL_TREE; arg = TREE_CHAIN (arg))
! 	{
! 	  tree t = TREE_VALUE (arg);
! 
! 	  if (TREE_CODE (t) == TEMPLATE_DECL)
! 	    {
! 	      ctx = CP_DECL_CONTEXT (t);
! 	      if (TREE_CODE (ctx) == NAMESPACE_DECL)
! 		{
! 		  if (arg_assoc_namespace (k, ctx) == 1)
! 		    return 1;
! 		}
! 	      else if (arg_assoc_class (k, ctx) == 1)
! 		return 1;
! 	    }
! 	  else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't'
! 		   && arg_assoc_type (k, t) == 1)
! 	    return 1;
! 	}
      }
    else
      {
--- 4827,4834 ----
  
        /* Now the arguments.  */
        for (arg = args; arg != NULL_TREE; arg = TREE_CHAIN (arg))
! 	if (arg_assoc_template_arg (k, TREE_VALUE (arg)) == 1)
! 	  return 1;
      }
    else
      {



Index: pt.c
===================================================================
RCS file: /cvs/egcs/egcs/gcc/cp/pt.c,v
retrieving revision 1.345
diff -c -r1.345 pt.c
*** pt.c	1999/08/30 15:50:39	1.345
--- pt.c	1999/09/01 08:30:56
***************
*** 3538,3546 ****
  	      /* Already substituted with real template.  Just output 
  		 the template name here */
                tree context = DECL_CONTEXT (arg);
! 	      if (context)
! 		{
!                   my_friendly_assert (TREE_CODE (context) == NAMESPACE_DECL, 980422);
  		  cat(decl_as_string (DECL_CONTEXT (arg), 0));
  		  cat("::");
  		}
--- 3538,3550 ----
  	      /* Already substituted with real template.  Just output 
  		 the template name here */
                tree context = DECL_CONTEXT (arg);
!               if (context)
!                 {
!                   /* The template may be defined in a namespace, or
!                      may be a member template.  */
!                   my_friendly_assert (TREE_CODE (context) == NAMESPACE_DECL
!                                       || CLASS_TYPE_P (context), 
!                                       980422);
  		  cat(decl_as_string (DECL_CONTEXT (arg), 0));
  		  cat("::");
  		}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]