Commit 0c0aac2f by Mark Mitchell Committed by Mark Mitchell

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
parent f099f336
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> 1999-03-27 Jason Merrill <jason@yorick.cygnus.com>
* call.c (build_field_call): Unify 'this' and non-'this' cases. * call.c (build_field_call): Unify 'this' and non-'this' cases.
......
...@@ -3028,6 +3028,8 @@ extern void do_case PROTO((tree, tree)); ...@@ -3028,6 +3028,8 @@ extern void do_case PROTO((tree, tree));
/* friend.c */ /* friend.c */
extern int is_friend PROTO((tree, tree)); extern int is_friend PROTO((tree, tree));
extern void make_friend_class 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)); extern tree do_friend PROTO((tree, tree, tree, tree, enum overload_flags, tree, int));
/* in init.c */ /* in init.c */
......
...@@ -27,9 +27,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -27,9 +27,6 @@ Boston, MA 02111-1307, USA. */
#include "output.h" #include "output.h"
#include "toplev.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. */ /* Friend data structures are described in cp-tree.h. */
/* Returns non-zero if SUPPLICANT is a friend of TYPE. */ /* Returns non-zero if SUPPLICANT is a friend of TYPE. */
...@@ -140,7 +137,7 @@ is_friend (type, supplicant) ...@@ -140,7 +137,7 @@ is_friend (type, supplicant)
/* Add a new friend to the friends of the aggregate type TYPE. /* Add a new friend to the friends of the aggregate type TYPE.
DECL is the FUNCTION_DECL of the friend being added. */ DECL is the FUNCTION_DECL of the friend being added. */
static void void
add_friend (type, decl) add_friend (type, decl)
tree type, decl; tree type, decl;
{ {
...@@ -176,15 +173,16 @@ add_friend (type, decl) ...@@ -176,15 +173,16 @@ add_friend (type, decl)
DECL_FRIENDLIST (typedecl) DECL_FRIENDLIST (typedecl)
= tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl), = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
DECL_FRIENDLIST (typedecl)); DECL_FRIENDLIST (typedecl));
DECL_BEFRIENDING_CLASSES (decl) if (!uses_template_parms (type))
= tree_cons (NULL_TREE, type, DECL_BEFRIENDING_CLASSES (decl)
DECL_BEFRIENDING_CLASSES (decl)); = tree_cons (NULL_TREE, type,
DECL_BEFRIENDING_CLASSES (decl));
} }
/* Declare that every member function NAME in FRIEND_TYPE /* Declare that every member function NAME in FRIEND_TYPE
(which may be NULL_TREE) is a friend of type TYPE. */ (which may be NULL_TREE) is a friend of type TYPE. */
static void void
add_friends (type, name, friend_type) add_friends (type, name, friend_type)
tree type, name, friend_type; tree type, name, friend_type;
{ {
...@@ -298,9 +296,10 @@ make_friend_class (type, friend_type) ...@@ -298,9 +296,10 @@ make_friend_class (type, friend_type)
= tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type)); = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
if (is_template_friend) if (is_template_friend)
friend_type = TREE_TYPE (friend_type); friend_type = TREE_TYPE (friend_type);
CLASSTYPE_BEFRIENDING_CLASSES (friend_type) if (!uses_template_parms (type))
= tree_cons (NULL_TREE, type, CLASSTYPE_BEFRIENDING_CLASSES (friend_type)
CLASSTYPE_BEFRIENDING_CLASSES (friend_type)); = tree_cons (NULL_TREE, type,
CLASSTYPE_BEFRIENDING_CLASSES (friend_type));
} }
} }
......
...@@ -2483,7 +2483,7 @@ component_decl_1: ...@@ -2483,7 +2483,7 @@ component_decl_1:
Therefore, the rules for components take care of Therefore, the rules for components take care of
this processing. To avoid registering the this processing. To avoid registering the
components more than once, we send NULL_TREE up 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. */ that there is nothing to do. */
if (!$2) if (!$2)
grok_x_components ($1.t); grok_x_components ($1.t);
......
...@@ -4961,32 +4961,19 @@ instantiate_class_template (type) ...@@ -4961,32 +4961,19 @@ instantiate_class_template (type)
{ {
tree friends; tree friends;
DECL_FRIENDLIST (typedecl)
= tree_cons (TREE_PURPOSE (t), NULL_TREE,
DECL_FRIENDLIST (typedecl));
for (friends = TREE_VALUE (t); for (friends = TREE_VALUE (t);
friends != NULL_TREE; friends != NULL_TREE;
friends = TREE_CHAIN (friends)) friends = TREE_CHAIN (friends))
{ if (TREE_PURPOSE (friends) == error_mark_node)
if (TREE_PURPOSE (friends) == error_mark_node) add_friend (type,
{ tsubst_friend_function (TREE_VALUE (friends),
TREE_VALUE (DECL_FRIENDLIST (typedecl)) args));
= tree_cons (error_mark_node, else
tsubst_friend_function (TREE_VALUE (friends), add_friends (type,
args), tsubst_copy (TREE_PURPOSE (t), args,
TREE_VALUE (DECL_FRIENDLIST (typedecl))); /*complain=*/1, NULL_TREE),
} tsubst (TREE_PURPOSE (friends), args,
else /*complain=*/1, NULL_TREE));
{
TREE_VALUE (DECL_FRIENDLIST (typedecl))
= tree_cons (tsubst (TREE_PURPOSE (friends), args,
/*complain=*/1, NULL_TREE),
NULL_TREE,
TREE_VALUE (DECL_FRIENDLIST (typedecl)));
}
}
} }
for (t = CLASSTYPE_FRIEND_CLASSES (pattern); for (t = CLASSTYPE_FRIEND_CLASSES (pattern);
......
// 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;
};
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
// Overly simplified from testcase by "B. K. Oxley" <binkley@bigfoot.com> // Overly simplified from testcase by "B. K. Oxley" <binkley@bigfoot.com>
// crash test - XFAIL *-*-*
template<class P> struct foo { template<class P> struct foo {
typedef P parent_type; typedef P parent_type;
friend parent_type; // ERROR - template parameters cannot be friends friend parent_type; // ERROR - template parameters cannot be friends - XFAIL *-*-*
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment