This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Koenig lookup of template template args
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH: Koenig lookup of template template args
- From: Alex Samuel <samuel at codesourcery dot com>
- Date: Thu, 2 Sep 1999 07:53:27 -0700 (PDT)
- Organization: CodeSourcery, LLC
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("::");
}