aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-03-27 17:33:36 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-03-27 17:33:36 +0000
commit0c0aac2fecce30d1c71554169446cae25f079234 (patch)
tree60ca8cc353fd96a0c775f1b61e4833ed942c36b0 /gcc
parentf099f336d1933243103b460498b49c7b7314d2be (diff)
downloadgcc-0c0aac2fecce30d1c71554169446cae25f079234.zip
gcc-0c0aac2fecce30d1c71554169446cae25f079234.tar.gz
gcc-0c0aac2fecce30d1c71554169446cae25f079234.tar.bz2
cp-tree.h (add_friend): Declare.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/friend.c21
-rw-r--r--gcc/cp/parse.y2
-rw-r--r--gcc/cp/pt.c33
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash32.C13
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/friend38.C4
7 files changed, 52 insertions, 38 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0138c84..96970ed 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4e6c024..9bbf39e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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 */
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index 2a69acd..285432f 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -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));
}
}
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 9e10c10..7ef6984 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -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);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8d83ffa..8855efa 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
index 0000000..68cf4df
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash32.C
@@ -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;
+};
+
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend38.C b/gcc/testsuite/g++.old-deja/g++.pt/friend38.C
index 41c7714..e3a6a06 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/friend38.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/friend38.C
@@ -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 *-*-*
};