summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/friend.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/friend.c')
-rw-r--r--contrib/gcc/cp/friend.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/contrib/gcc/cp/friend.c b/contrib/gcc/cp/friend.c
index 441be67..9280a09 100644
--- a/contrib/gcc/cp/friend.c
+++ b/contrib/gcc/cp/friend.c
@@ -30,7 +30,7 @@ Boston, MA 02111-1307, USA. */
/* Friend data structures are described in cp-tree.h. */
-/* Returns non-zero if SUPPLICANT is a friend of TYPE. */
+/* Returns nonzero if SUPPLICANT is a friend of TYPE. */
int
is_friend (type, supplicant)
@@ -64,6 +64,10 @@ is_friend (type, supplicant)
if (supplicant == TREE_VALUE (friends))
return 1;
+ /* We haven't completed the instantiation yet. */
+ if (TREE_CODE (supplicant) == TEMPLATE_DECL)
+ return 1;
+
/* Temporarily, we are more lenient to deal with
nested friend functions, for which there can be
more than one FUNCTION_DECL, despite being the
@@ -114,7 +118,7 @@ is_friend (type, supplicant)
else
context = NULL_TREE;
- /* A namespace is not friend to anybody. */
+ /* A namespace is not friend to anybody. */
if (context && TREE_CODE (context) == NAMESPACE_DECL)
context = NULL_TREE;
@@ -159,6 +163,9 @@ add_friend (type, decl)
return;
}
}
+
+ maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
+
TREE_VALUE (list) = tree_cons (error_mark_node, decl,
TREE_VALUE (list));
return;
@@ -166,6 +173,8 @@ add_friend (type, decl)
list = TREE_CHAIN (list);
}
+ maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
+
DECL_FRIENDLIST (typedecl)
= tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
DECL_FRIENDLIST (typedecl));
@@ -198,24 +207,25 @@ make_friend_class (type, friend_type)
return;
}
- if (CLASS_TYPE_P (friend_type)
- && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type)
- && uses_template_parms (friend_type))
- {
- /* [temp.friend]
-
- Friend declarations shall not declare partial
- specializations. */
- error ("partial specialization `%T' declared `friend'",
- friend_type);
- return;
- }
-
if (processing_template_decl > template_class_depth (type))
/* If the TYPE is a template then it makes sense for it to be
friends with itself; this means that each instantiation is
friends with all other instantiations. */
- is_template_friend = 1;
+ {
+ if (CLASS_TYPE_P (friend_type)
+ && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type)
+ && uses_template_parms (friend_type))
+ {
+ /* [temp.friend]
+ Friend declarations shall not declare partial
+ specializations. */
+ error ("partial specialization `%T' declared `friend'",
+ friend_type);
+ return;
+ }
+
+ is_template_friend = 1;
+ }
else if (same_type_p (type, friend_type))
{
pedwarn ("class `%T' is implicitly friends with itself",
@@ -230,7 +240,7 @@ make_friend_class (type, friend_type)
A friend of a class or class template can be a function or
class template, a specialization of a function template or
class template, or an ordinary (nontemplate) function or
- class. */
+ class. */
if (!is_template_friend)
;/* ok */
else if (TREE_CODE (friend_type) == TYPENAME_TYPE)
@@ -267,6 +277,8 @@ make_friend_class (type, friend_type)
TREE_VALUE (classes), type);
else
{
+ maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1);
+
CLASSTYPE_FRIEND_CLASSES (type)
= tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
if (is_template_friend)
@@ -396,14 +408,14 @@ do_friend (ctype, declarator, decl, parmdecls, attrlist,
/* This must be a local class, so pushdecl will be ok, and
insert an unqualified friend into the local scope
(rather than the containing namespace scope, which the
- next choice will do). */
+ next choice will do). */
decl = pushdecl (decl);
else
{
/* We can't use pushdecl, as we might be in a template
class specialization, and pushdecl will insert an
unqualified friend decl into the template parameter
- scope, rather than the namespace containing it. */
+ scope, rather than the namespace containing it. */
tree ns = decl_namespace_context (decl);
push_nested_namespace (ns);
OpenPOWER on IntegriCloud