re PR c++/109 (g++ 2.95.2 can't handle dependent friend member functions)
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 7 Feb 2002 19:49:10 +0000 (19:49 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 7 Feb 2002 19:49:10 +0000 (19:49 +0000)
cp:
PR c++/109
* decl.c (grokdeclarator): Allow friend declarations from
dependant types.
* decl2.c (handle_class_head): Don't push into template parm contexts.
* pt.c (push_template_decl_real): Template parm contexts are never
being defined.
testsuite:
* g++.dg/template/friend4.C: New test.

From-SVN: r49589

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/friend4.C [new file with mode: 0644]

index 5c463a776c882790f9058d68bdf48878e1318369..f4432532c0e313b7cf23feabe28f03512445ec11 100644 (file)
@@ -1,3 +1,12 @@
+2002-02-07  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/109
+       * decl.c (grokdeclarator): Allow friend declarations from
+       dependant types.
+       * decl2.c (handle_class_head): Don't push into template parm contexts.
+       * pt.c (push_template_decl_real): Template parm contexts are never
+       being defined.
+
 2002-02-05  Alexandre Oliva  <aoliva@redhat.com>
 
        * class.c: Include target.h.
index c1c254df90e69cacd3e18c2a80fe6646e38ba130..6fd9890d9c374afb9df0f71af0a78ec82ab371bc 100644 (file)
@@ -9612,6 +9612,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
   int explicit_char = 0;
   int defaulted_int = 0;
   int extern_langp = 0;
+  tree dependant_name = NULL_TREE;
   
   tree typedef_decl = NULL_TREE;
   const char *name;
@@ -9853,11 +9854,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              else if (TREE_CODE (cname) == TEMPLATE_TYPE_PARM
                       || TREE_CODE (cname) == BOUND_TEMPLATE_TEMPLATE_PARM)
                {
-                 error ("`%T::%D' is not a valid declarator", cname,
-                           TREE_OPERAND (decl, 1));
-                 error ("  perhaps you want `typename %T::%D' to make it a type",
-                           cname, TREE_OPERAND (decl, 1));
-                 return void_type_node;
+                 /* This might be declaring a member of a template
+                    parm to be a friend.  */
+                 ctype = cname;
+                 dependant_name = TREE_OPERAND (decl, 1);
                }
              else if (ctype == NULL_TREE)
                ctype = cname;
@@ -10349,6 +10349,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
   friendp = RIDBIT_SETP (RID_FRIEND, specbits);
   RIDBIT_RESET (RID_FRIEND, specbits);
 
+  if (dependant_name && !friendp)
+    {
+      error ("`%T::%D' is not a valid declarator", ctype, dependant_name);
+      return void_type_node;
+    }
+  
   /* Warn if two storage classes are given. Default to `auto'.  */
 
   if (RIDBIT_ANY_SET (specbits))
index 7a9a21edf083b5be79eb1a87df63c9d9625bfc2b..0cbb32100efc2e7a4f4ce5559b88f948d6b67495 100644 (file)
@@ -5258,7 +5258,9 @@ handle_class_head (aggr, scope, id, defn_p, new_type_p)
         is different to the current scope.  */
       tree context = CP_DECL_CONTEXT (decl);
 
-      *new_type_p = current != context;
+      *new_type_p = (current != context
+                    && TREE_CODE (context) != TEMPLATE_TYPE_PARM
+                    && TREE_CODE (context) != BOUND_TEMPLATE_TEMPLATE_PARM);
       if (*new_type_p)
        push_scope (context);
   
index 5084f727823fbc7526e81585d0599cb23ff391cd..9e5b20cb7bb34b7846e808e03bdd3270c62e727a 100644 (file)
@@ -2571,7 +2571,9 @@ push_template_decl_real (decl, is_friend)
 
   if (!ctx 
       || TREE_CODE (ctx) == FUNCTION_DECL
-      || TYPE_BEING_DEFINED (ctx)
+      || (TREE_CODE (ctx) != TEMPLATE_TYPE_PARM
+         && TREE_CODE (ctx) != BOUND_TEMPLATE_TEMPLATE_PARM
+         && TYPE_BEING_DEFINED (ctx))
       || (is_friend && !DECL_TEMPLATE_INFO (decl)))
     {
       if (DECL_LANG_SPECIFIC (decl)
index 635223e54fbf60de7bcd7c98a22dc4fcb8f28979..693b9a911463bbcd7f884c4218e7de8a975ee542 100644 (file)
@@ -1,3 +1,7 @@
+2002-02-07  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.dg/template/friend4.C: New test.
+
 2002-02-07  David Billinghurst <David.Billinghurst@riotinto.com>
 
        PR fortran/3743
diff --git a/gcc/testsuite/g++.dg/template/friend4.C b/gcc/testsuite/g++.dg/template/friend4.C
new file mode 100644 (file)
index 0000000..9cd3810
--- /dev/null
@@ -0,0 +1,46 @@
+// { dg-do compile }
+
+// Copyright (C) 2002 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 18 Dec 2001 <nathan@codesourcery.com>
+
+// PR 109, dependant member friends
+
+struct B
+{
+  static int foo ();
+  struct N
+  {
+    static int bar ();
+  };
+};
+
+
+template <class T>
+class A
+{
+  friend int T::foo ();
+  friend int T::N::bar ();
+  
+  private:
+  static int m;
+};
+
+template <class T>
+class C
+{
+  friend struct T::N;
+
+  private:
+  static int m;
+};
+
+
+int B::foo ()
+{
+  return A<B>::m;
+}
+
+int B::N::bar ()
+{
+  return A<B>::m + C<B>::m;
+}