cp-tree.h (add_friend): Declare.
authorMark Mitchell <mark@codesourcery.com>
Sat, 27 Mar 1999 17:33:36 +0000 (17:33 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sat, 27 Mar 1999 17:33:36 +0000 (17:33 +0000)
* cp-tree.h (add_friend): Declare.
(add_friends): Likewise.
* friend.c (add_friend): Make it global.  Don't add to
DECL_BEFRIENDING_CLASSES if the befriending class is a template.
(add_friends): Make it global.
(make_friend_class): Don't add to DECL_BEFRIENDING_CLASSES if the
befriending class is a template.
* parse.y (component_decl_1): Fix typo in comment.
* parse.c: Regenerated.
* pt.c (instantiate_class_template): Use add_friend and
add_friends rather that duplicating some of their functionality
here.

From-SVN: r26020

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/friend.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.pt/crash32.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/friend38.C

index 0138c8461b47fc6c40db32aaad5fa19533c70456..96970ed736ea65ba71d7074501242842cb8b7e4a 100644 (file)
@@ -1,3 +1,18 @@
+1999-03-27  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (add_friend): Declare.
+       (add_friends): Likewise.
+       * friend.c (add_friend): Make it global.  Don't add to
+       DECL_BEFRIENDING_CLASSES if the befriending class is a template.
+       (add_friends): Make it global.
+       (make_friend_class): Don't add to DECL_BEFRIENDING_CLASSES if the
+       befriending class is a template.
+       * parse.y (component_decl_1): Fix typo in comment.
+       * parse.c: Regenerated.
+       * pt.c (instantiate_class_template): Use add_friend and
+       add_friends rather that duplicating some of their functionality
+       here.
+       
 1999-03-27  Jason Merrill  <jason@yorick.cygnus.com>
 
        * call.c (build_field_call): Unify 'this' and non-'this' cases.
index 4e6c024cc41b6e220caae7e4122c76780db9de87..9bbf39ee3d5a58c41273b813064b0472c1725f24 100644 (file)
@@ -3028,6 +3028,8 @@ extern void do_case                               PROTO((tree, tree));
 /* friend.c */
 extern int is_friend                           PROTO((tree, tree));
 extern void make_friend_class                  PROTO((tree, tree));
+extern void add_friend                          PROTO((tree, tree));
+extern void add_friends                         PROTO((tree, tree, tree));
 extern tree do_friend                          PROTO((tree, tree, tree, tree, enum overload_flags, tree, int));
 
 /* in init.c */
index 2a69acd8d84d688cdcfc8d6299b873ae922d3d61..285432f5ccd64d9694359f03952bc620509e5e7d 100644 (file)
@@ -27,9 +27,6 @@ Boston, MA 02111-1307, USA.  */
 #include "output.h"
 #include "toplev.h"
 
-static void add_friend PROTO((tree, tree));
-static void add_friends PROTO((tree, tree, tree));
-
 /* Friend data structures are described in cp-tree.h.  */
 
 /* Returns non-zero if SUPPLICANT is a friend of TYPE.  */
@@ -140,7 +137,7 @@ is_friend (type, supplicant)
 /* Add a new friend to the friends of the aggregate type TYPE.
    DECL is the FUNCTION_DECL of the friend being added.  */
 
-static void
+void
 add_friend (type, decl)
      tree type, decl;
 {
@@ -176,15 +173,16 @@ add_friend (type, decl)
   DECL_FRIENDLIST (typedecl)
     = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
                 DECL_FRIENDLIST (typedecl));
-  DECL_BEFRIENDING_CLASSES (decl) 
-    = tree_cons (NULL_TREE, type,
-                DECL_BEFRIENDING_CLASSES (decl));
+  if (!uses_template_parms (type))
+    DECL_BEFRIENDING_CLASSES (decl) 
+      = tree_cons (NULL_TREE, type,
+                  DECL_BEFRIENDING_CLASSES (decl));
 }
 
 /* Declare that every member function NAME in FRIEND_TYPE
    (which may be NULL_TREE) is a friend of type TYPE.  */
 
-static void
+void
 add_friends (type, name, friend_type)
      tree type, name, friend_type;
 {
@@ -298,9 +296,10 @@ make_friend_class (type, friend_type)
        = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
       if (is_template_friend)
        friend_type = TREE_TYPE (friend_type);
-      CLASSTYPE_BEFRIENDING_CLASSES (friend_type)
-       = tree_cons (NULL_TREE, type, 
-                    CLASSTYPE_BEFRIENDING_CLASSES (friend_type)); 
+      if (!uses_template_parms (type))
+       CLASSTYPE_BEFRIENDING_CLASSES (friend_type)
+         = tree_cons (NULL_TREE, type, 
+                      CLASSTYPE_BEFRIENDING_CLASSES (friend_type)); 
     }
 }
 
index 9e10c106682aac227fed1edd12370efca48f8202..7ef6984b93104972f63af8a5a8cd58b9f24461b0 100644 (file)
@@ -2483,7 +2483,7 @@ component_decl_1:
                     Therefore, the rules for components take care of
                     this processing.  To avoid registering the
                     components more than once, we send NULL_TREE up
-                    here; that lets finish_member_declaration now
+                    here; that lets finish_member_declaration know
                     that there is nothing to do.  */
                  if (!$2)
                    grok_x_components ($1.t);
index 8d83ffafcb50a0266fc0df538b88ed93a2bad882..8855efa311e4f30381d3745a77249c4c33787934 100644 (file)
@@ -4961,32 +4961,19 @@ instantiate_class_template (type)
     {
       tree friends;
 
-      DECL_FRIENDLIST (typedecl)
-       = tree_cons (TREE_PURPOSE (t), NULL_TREE, 
-                    DECL_FRIENDLIST (typedecl));
-
       for (friends = TREE_VALUE (t);
           friends != NULL_TREE;
           friends = TREE_CHAIN (friends))
-       {
-         if (TREE_PURPOSE (friends) == error_mark_node)
-           {
-             TREE_VALUE (DECL_FRIENDLIST (typedecl))
-               = tree_cons (error_mark_node, 
-                            tsubst_friend_function (TREE_VALUE (friends),
-                                                    args),
-                            TREE_VALUE (DECL_FRIENDLIST (typedecl)));
-           }
-         else
-           {
-             TREE_VALUE (DECL_FRIENDLIST (typedecl))
-               = tree_cons (tsubst (TREE_PURPOSE (friends), args, 
-                                    /*complain=*/1, NULL_TREE),
-                            NULL_TREE,
-                            TREE_VALUE (DECL_FRIENDLIST (typedecl)));
-
-           }
-       }
+       if (TREE_PURPOSE (friends) == error_mark_node)
+         add_friend (type, 
+                     tsubst_friend_function (TREE_VALUE (friends),
+                                             args));
+       else
+         add_friends (type, 
+                      tsubst_copy (TREE_PURPOSE (t), args,
+                                   /*complain=*/1, NULL_TREE),
+                      tsubst (TREE_PURPOSE (friends), args,
+                              /*complain=*/1, NULL_TREE));
     }
 
   for (t = CLASSTYPE_FRIEND_CLASSES (pattern);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash32.C b/gcc/testsuite/g++.old-deja/g++.pt/crash32.C
new file mode 100644 (file)
index 0000000..68cf4df
--- /dev/null
@@ -0,0 +1,13 @@
+// Build don't link:
+// Origin: Jason Merrill <jason@cygnus.com>
+
+template <class T> struct A
+{
+  struct B;
+};
+
+template<class T> struct C
+{
+  friend typename A<T>::B;
+};
+
index 41c7714acc555754b97a94bafe878eeec957207b..e3a6a060ef6afd2da2c57c037ffca3d3f61e1e1b 100644 (file)
@@ -2,9 +2,7 @@
 
 // Overly simplified from testcase by "B. K. Oxley" <binkley@bigfoot.com>
 
-// crash test - XFAIL *-*-*
-
 template<class P> struct foo {
   typedef P parent_type;
-  friend parent_type; // ERROR - template parameters cannot be friends
+  friend parent_type; // ERROR - template parameters cannot be friends - XFAIL *-*-*
 };