freebsd-nq/contrib/gcc/cp/friend.c

582 lines
17 KiB
C
Raw Normal View History

1999-08-26 09:30:50 +00:00
/* Help friends in C++.
2007-05-19 01:19:51 +00:00
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
2004-07-28 03:11:36 +00:00
Free Software Foundation, Inc.
1999-08-26 09:30:50 +00:00
2004-07-28 03:11:36 +00:00
This file is part of GCC.
1999-08-26 09:30:50 +00:00
2004-07-28 03:11:36 +00:00
GCC is free software; you can redistribute it and/or modify
1999-08-26 09:30:50 +00:00
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
2004-07-28 03:11:36 +00:00
GCC is distributed in the hope that it will be useful,
1999-08-26 09:30:50 +00:00
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
2004-07-28 03:11:36 +00:00
along with GCC; see the file COPYING. If not, write to
2007-05-19 01:19:51 +00:00
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
1999-08-26 09:30:50 +00:00
#include "config.h"
#include "system.h"
2004-07-28 03:11:36 +00:00
#include "coretypes.h"
#include "tm.h"
1999-08-26 09:30:50 +00:00
#include "tree.h"
#include "rtl.h"
#include "expr.h"
1999-08-26 09:30:50 +00:00
#include "cp-tree.h"
#include "flags.h"
#include "output.h"
#include "toplev.h"
/* Friend data structures are described in cp-tree.h. */
2003-07-11 03:40:53 +00:00
/* Returns nonzero if SUPPLICANT is a friend of TYPE. */
1999-08-26 09:30:50 +00:00
int
2004-07-28 03:11:36 +00:00
is_friend (tree type, tree supplicant)
1999-08-26 09:30:50 +00:00
{
int declp;
2004-07-28 03:11:36 +00:00
tree list;
1999-08-26 09:30:50 +00:00
tree context;
if (supplicant == NULL_TREE || type == NULL_TREE)
return 0;
declp = DECL_P (supplicant);
1999-08-26 09:30:50 +00:00
if (declp)
/* It's a function decl. */
{
tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type));
tree name = DECL_NAME (supplicant);
for (; list ; list = TREE_CHAIN (list))
{
if (name == FRIEND_NAME (list))
1999-08-26 09:30:50 +00:00
{
tree friends = FRIEND_DECLS (list);
1999-08-26 09:30:50 +00:00
for (; friends ; friends = TREE_CHAIN (friends))
{
2004-07-28 03:11:36 +00:00
tree friend = TREE_VALUE (friends);
1999-08-26 09:30:50 +00:00
2004-07-28 03:11:36 +00:00
if (friend == NULL_TREE)
continue;
2003-07-11 03:40:53 +00:00
2004-07-28 03:11:36 +00:00
if (supplicant == friend)
return 1;
2004-07-28 03:11:36 +00:00
if (is_specialization_of_friend (supplicant, friend))
1999-08-26 09:30:50 +00:00
return 1;
}
break;
}
}
}
else
/* It's a type. */
{
2007-05-19 01:19:51 +00:00
if (same_type_p (supplicant, type))
return 1;
1999-08-26 09:30:50 +00:00
list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
for (; list ; list = TREE_CHAIN (list))
{
tree t = TREE_VALUE (list);
2007-05-19 01:19:51 +00:00
if (TREE_CODE (t) == TEMPLATE_DECL ?
is_specialization_of_friend (TYPE_MAIN_DECL (supplicant), t) :
same_type_p (supplicant, t))
1999-08-26 09:30:50 +00:00
return 1;
}
2007-05-19 01:19:51 +00:00
}
1999-08-26 09:30:50 +00:00
2007-05-19 01:19:51 +00:00
if (declp)
{
if (DECL_FUNCTION_MEMBER_P (supplicant))
context = DECL_CONTEXT (supplicant);
else
context = NULL_TREE;
}
1999-08-26 09:30:50 +00:00
else
2007-05-19 01:19:51 +00:00
{
if (TYPE_CLASS_SCOPE_P (supplicant))
/* Nested classes get the same access as their enclosing types, as
per DR 45 (this is a change from the standard). */
context = TYPE_CONTEXT (supplicant);
else
/* Local classes have the same access as the enclosing function. */
context = decl_function_context (TYPE_MAIN_DECL (supplicant));
}
1999-08-26 09:30:50 +00:00
2003-07-11 03:40:53 +00:00
/* A namespace is not friend to anybody. */
1999-08-26 09:30:50 +00:00
if (context && TREE_CODE (context) == NAMESPACE_DECL)
context = NULL_TREE;
if (context)
return is_friend (type, context);
return 0;
}
/* Add a new friend to the friends of the aggregate type TYPE.
2004-07-28 03:11:36 +00:00
DECL is the FUNCTION_DECL of the friend being added.
If COMPLAIN is true, warning about duplicate friend is issued.
We want to have this diagnostics during parsing but not
when a template is being instantiated. */
1999-08-26 09:30:50 +00:00
void
2004-07-28 03:11:36 +00:00
add_friend (tree type, tree decl, bool complain)
1999-08-26 09:30:50 +00:00
{
tree typedecl;
tree list;
tree name;
2007-05-19 01:19:51 +00:00
tree ctx;
if (decl == error_mark_node)
return;
typedecl = TYPE_MAIN_DECL (type);
list = DECL_FRIENDLIST (typedecl);
name = DECL_NAME (decl);
type = TREE_TYPE (typedecl);
1999-08-26 09:30:50 +00:00
while (list)
{
if (name == FRIEND_NAME (list))
1999-08-26 09:30:50 +00:00
{
tree friends = FRIEND_DECLS (list);
1999-08-26 09:30:50 +00:00
for (; friends ; friends = TREE_CHAIN (friends))
{
if (decl == TREE_VALUE (friends))
{
2004-07-28 03:11:36 +00:00
if (complain)
2007-05-19 01:19:51 +00:00
warning (0, "%qD is already a friend of class %qT",
2004-07-28 03:11:36 +00:00
decl, type);
1999-08-26 09:30:50 +00:00
return;
}
}
2003-07-11 03:40:53 +00:00
maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
2004-07-28 03:11:36 +00:00
TREE_VALUE (list) = tree_cons (NULL_TREE, decl,
1999-08-26 09:30:50 +00:00
TREE_VALUE (list));
return;
}
list = TREE_CHAIN (list);
}
2007-05-19 01:19:51 +00:00
ctx = DECL_CONTEXT (decl);
if (ctx && CLASS_TYPE_P (ctx) && !uses_template_parms (ctx))
perform_or_defer_access_check (TYPE_BINFO (ctx), decl, decl);
2004-07-28 03:11:36 +00:00
2003-07-11 03:40:53 +00:00
maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
1999-08-26 09:30:50 +00:00
DECL_FRIENDLIST (typedecl)
2004-07-28 03:11:36 +00:00
= tree_cons (DECL_NAME (decl), build_tree_list (NULL_TREE, decl),
1999-08-26 09:30:50 +00:00
DECL_FRIENDLIST (typedecl));
if (!uses_template_parms (type))
2007-05-19 01:19:51 +00:00
DECL_BEFRIENDING_CLASSES (decl)
= tree_cons (NULL_TREE, type,
DECL_BEFRIENDING_CLASSES (decl));
1999-08-26 09:30:50 +00:00
}
/* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already
been defined, we make all of its member functions friends of
TYPE. If not, we make it a pending friend, which can later be added
when its definition is seen. If a type is defined, then its TYPE_DECL's
DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
classes that are not defined. If a type has not yet been defined,
then the DECL_WAITING_FRIENDS contains a list of types
waiting to make it their friend. Note that these two can both
2004-07-28 03:11:36 +00:00
be in use at the same time!
If COMPLAIN is true, warning about duplicate friend is issued.
We want to have this diagnostics during parsing but not
when a template is being instantiated. */
1999-08-26 09:30:50 +00:00
void
2004-07-28 03:11:36 +00:00
make_friend_class (tree type, tree friend_type, bool complain)
1999-08-26 09:30:50 +00:00
{
tree classes;
2007-05-19 01:19:51 +00:00
/* CLASS_TEMPLATE_DEPTH counts the number of template headers for
the enclosing class. FRIEND_DEPTH counts the number of template
headers used for this friend declaration. TEMPLATE_MEMBER_P,
defined inside the `if' block for TYPENAME_TYPE case, is true if
a template header in FRIEND_DEPTH is intended for DECLARATOR.
For example, the code
template <class T> struct A {
template <class U> struct B {
template <class V> template <class W>
friend class C<V>::D;
};
};
will eventually give the following results
1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U').
2. FRIEND_DEPTH equals 2 (for `V' and `W').
3. TEMPLATE_MEMBER_P is true (for `W').
The friend is a template friend iff FRIEND_DEPTH is nonzero. */
int class_template_depth = template_class_depth (type);
int friend_depth = processing_template_decl - class_template_depth;
1999-08-26 09:30:50 +00:00
if (! IS_AGGR_TYPE (friend_type))
1999-08-26 09:30:50 +00:00
{
2007-05-19 01:19:51 +00:00
error ("invalid type %qT declared %<friend%>", friend_type);
1999-08-26 09:30:50 +00:00
return;
}
2007-05-19 01:19:51 +00:00
if (friend_depth)
1999-08-26 09:30:50 +00:00
/* 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. */
2003-07-11 03:40:53 +00:00
{
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. */
2007-05-19 01:19:51 +00:00
error ("partial specialization %qT declared %<friend%>",
2003-07-11 03:40:53 +00:00
friend_type);
return;
}
}
else if (same_type_p (type, friend_type))
1999-08-26 09:30:50 +00:00
{
2004-07-28 03:11:36 +00:00
if (complain)
2007-05-19 01:19:51 +00:00
pedwarn ("class %qT is implicitly friends with itself",
2004-07-28 03:11:36 +00:00
type);
1999-08-26 09:30:50 +00:00
return;
}
/* [temp.friend]
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
2003-07-11 03:40:53 +00:00
class. */
2007-05-19 01:19:51 +00:00
if (!friend_depth)
;/* ok */
else if (TREE_CODE (friend_type) == TYPENAME_TYPE)
{
2007-05-19 01:19:51 +00:00
if (TREE_CODE (TYPENAME_TYPE_FULLNAME (friend_type))
== TEMPLATE_ID_EXPR)
{
/* template <class U> friend class T::X<U>; */
/* [temp.friend]
Friend declarations shall not declare partial
specializations. */
error ("partial specialization %qT declared %<friend%>",
friend_type);
return;
}
else
{
/* We will figure this out later. */
bool template_member_p = false;
tree ctype = TYPE_CONTEXT (friend_type);
tree name = TYPE_IDENTIFIER (friend_type);
tree decl;
if (!uses_template_parms_level (ctype, class_template_depth
+ friend_depth))
template_member_p = true;
if (class_template_depth)
{
/* We rely on tsubst_friend_class to check the
validity of the declaration later. */
if (template_member_p)
friend_type
= make_unbound_class_template (ctype,
name,
current_template_parms,
tf_error);
else
friend_type
= make_typename_type (ctype, name, class_type, tf_error);
}
else
{
decl = lookup_member (ctype, name, 0, true);
if (!decl)
{
error ("%qT is not a member of %qT", name, ctype);
return;
}
if (template_member_p && !DECL_CLASS_TEMPLATE_P (decl))
{
error ("%qT is not a member class template of %qT",
name, ctype);
error ("%q+D declared here", decl);
return;
}
if (!template_member_p && (TREE_CODE (decl) != TYPE_DECL
|| !CLASS_TYPE_P (TREE_TYPE (decl))))
{
error ("%qT is not a nested class of %qT",
name, ctype);
error ("%q+D declared here", decl);
return;
}
friend_type = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl));
}
}
}
else if (TREE_CODE (friend_type) == TEMPLATE_TYPE_PARM)
{
/* template <class T> friend class T; */
2007-05-19 01:19:51 +00:00
error ("template parameter type %qT declared %<friend%>", friend_type);
return;
}
else if (!CLASSTYPE_TEMPLATE_INFO (friend_type))
{
/* template <class T> friend class A; where A is not a template */
2007-05-19 01:19:51 +00:00
error ("%q#T is not a template", friend_type);
return;
}
2007-05-19 01:19:51 +00:00
else
/* template <class T> friend class A; where A is a template */
1999-08-26 09:30:50 +00:00
friend_type = CLASSTYPE_TI_TEMPLATE (friend_type);
2007-05-19 01:19:51 +00:00
if (friend_type == error_mark_node)
return;
2004-07-28 03:11:36 +00:00
/* See if it is already a friend. */
for (classes = CLASSTYPE_FRIEND_CLASSES (type);
classes;
classes = TREE_CHAIN (classes))
{
tree probe = TREE_VALUE (classes);
if (TREE_CODE (friend_type) == TEMPLATE_DECL)
{
if (friend_type == probe)
{
if (complain)
2007-05-19 01:19:51 +00:00
warning (0, "%qD is already a friend of %qT", probe, type);
2004-07-28 03:11:36 +00:00
break;
}
}
else if (TREE_CODE (probe) != TEMPLATE_DECL)
{
if (same_type_p (probe, friend_type))
{
if (complain)
2007-05-19 01:19:51 +00:00
warning (0, "%qT is already a friend of %qT", probe, type);
2004-07-28 03:11:36 +00:00
break;
}
}
}
2007-05-19 01:19:51 +00:00
if (!classes)
1999-08-26 09:30:50 +00:00
{
2003-07-11 03:40:53 +00:00
maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1);
1999-08-26 09:30:50 +00:00
CLASSTYPE_FRIEND_CLASSES (type)
= tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
2007-05-19 01:19:51 +00:00
if (TREE_CODE (friend_type) == TEMPLATE_DECL)
friend_type = TREE_TYPE (friend_type);
if (!uses_template_parms (type))
CLASSTYPE_BEFRIENDING_CLASSES (friend_type)
2007-05-19 01:19:51 +00:00
= tree_cons (NULL_TREE, type,
CLASSTYPE_BEFRIENDING_CLASSES (friend_type));
1999-08-26 09:30:50 +00:00
}
}
2007-05-19 01:19:51 +00:00
/* Record DECL (a FUNCTION_DECL) as a friend of the
CURRENT_CLASS_TYPE. If DECL is a member function, CTYPE is the
class of which it is a member, as named in the friend declaration.
DECLARATOR is the name of the friend. FUNCDEF_FLAG is true if the
friend declaration is a definition of the function. FLAGS is as
for grokclass fn. */
1999-08-26 09:30:50 +00:00
tree
2004-07-28 03:11:36 +00:00
do_friend (tree ctype, tree declarator, tree decl,
2007-05-19 01:19:51 +00:00
tree attrlist, enum overload_flags flags,
bool funcdef_flag)
1999-08-26 09:30:50 +00:00
{
2007-05-19 01:19:51 +00:00
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
gcc_assert (!ctype || IS_AGGR_TYPE (ctype));
1999-08-26 09:30:50 +00:00
/* Every decl that gets here is a friend of something. */
DECL_FRIEND_P (decl) = 1;
if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
{
declarator = TREE_OPERAND (declarator, 0);
if (is_overloaded_fn (declarator))
declarator = DECL_NAME (get_first_fn (declarator));
}
if (ctype)
{
2004-07-28 03:11:36 +00:00
/* CLASS_TEMPLATE_DEPTH counts the number of template headers for
the enclosing class. FRIEND_DEPTH counts the number of template
headers used for this friend declaration. TEMPLATE_MEMBER_P is
true if a template header in FRIEND_DEPTH is intended for
DECLARATOR. For example, the code
template <class T> struct A {
template <class U> struct B {
template <class V> template <class W>
friend void C<V>::f(W);
};
};
will eventually give the following results
1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U').
2. FRIEND_DEPTH equals 2 (for `V' and `W').
3. TEMPLATE_MEMBER_P is true (for `W'). */
int class_template_depth = template_class_depth (current_class_type);
int friend_depth = processing_template_decl - class_template_depth;
/* We will figure this out later. */
bool template_member_p = false;
1999-08-26 09:30:50 +00:00
tree cname = TYPE_NAME (ctype);
if (TREE_CODE (cname) == TYPE_DECL)
cname = DECL_NAME (cname);
/* A method friend. */
2004-07-28 03:11:36 +00:00
if (flags == NO_SPECIAL && declarator == cname)
DECL_CONSTRUCTOR_P (decl) = 1;
2007-05-19 01:19:51 +00:00
grokclassfn (ctype, decl, flags);
2004-07-28 03:11:36 +00:00
if (friend_depth)
{
if (!uses_template_parms_level (ctype, class_template_depth
+ friend_depth))
template_member_p = true;
}
/* A nested class may declare a member of an enclosing class
to be a friend, so we do lookup here even if CTYPE is in
the process of being defined. */
2004-07-28 03:11:36 +00:00
if (class_template_depth
|| COMPLETE_TYPE_P (ctype)
|| TYPE_BEING_DEFINED (ctype))
1999-08-26 09:30:50 +00:00
{
2004-07-28 03:11:36 +00:00
if (DECL_TEMPLATE_INFO (decl))
/* DECL is a template specialization. No need to
build a new TEMPLATE_DECL. */
;
else if (class_template_depth)
/* We rely on tsubst_friend_function to check the
validity of the declaration later. */
2007-05-19 01:19:51 +00:00
decl = push_template_decl_real (decl, /*is_friend=*/true);
2004-07-28 03:11:36 +00:00
else
2007-05-19 01:19:51 +00:00
decl = check_classfn (ctype, decl,
template_member_p
? current_template_parms
: NULL_TREE);
2004-07-28 03:11:36 +00:00
if (template_member_p && decl && TREE_CODE (decl) == FUNCTION_DECL)
decl = DECL_TI_TEMPLATE (decl);
1999-08-26 09:30:50 +00:00
if (decl)
2004-07-28 03:11:36 +00:00
add_friend (current_class_type, decl, /*complain=*/true);
1999-08-26 09:30:50 +00:00
}
else
2007-05-19 01:19:51 +00:00
error ("member %qD declared as friend before type %qT defined",
decl, ctype);
1999-08-26 09:30:50 +00:00
}
/* A global friend.
@@ or possibly a friend from a base class ?!? */
else if (TREE_CODE (decl) == FUNCTION_DECL)
{
2004-07-28 03:11:36 +00:00
int is_friend_template = PROCESSING_REAL_TEMPLATE_DECL_P ();
1999-08-26 09:30:50 +00:00
/* Friends must all go through the overload machinery,
even though they may not technically be overloaded.
Note that because classes all wind up being top-level
in their scope, their friend wind up in top-level scope as well. */
if (funcdef_flag)
SET_DECL_FRIEND_CONTEXT (decl, current_class_type);
1999-08-26 09:30:50 +00:00
if (! DECL_USE_TEMPLATE (decl))
{
/* We must check whether the decl refers to template
arguments before push_template_decl_real adds a
reference to the containing template class. */
int warn = (warn_nontemplate_friend
&& ! funcdef_flag && ! is_friend_template
&& current_template_parms
&& uses_template_parms (decl));
if (is_friend_template
|| template_class_depth (current_class_type) != 0)
/* We can't call pushdecl for a template class, since in
general, such a declaration depends on template
parameters. Instead, we call pushdecl when the class
is instantiated. */
2007-05-19 01:19:51 +00:00
decl = push_template_decl_real (decl, /*is_friend=*/true);
else if (current_function_decl)
/* 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
2003-07-11 03:40:53 +00:00
next choice will do). */
2007-05-19 01:19:51 +00:00
decl = pushdecl_maybe_friend (decl, /*is_friend=*/true);
else
{
/* We can't use pushdecl, as we might be in a template
2007-05-19 01:19:51 +00:00
class specialization, and pushdecl will insert an
unqualified friend decl into the template parameter
scope, rather than the namespace containing it. */
tree ns = decl_namespace_context (decl);
2007-05-19 01:19:51 +00:00
push_nested_namespace (ns);
2007-05-19 01:19:51 +00:00
decl = pushdecl_namespace_level (decl, /*is_friend=*/true);
pop_nested_namespace (ns);
}
1999-08-26 09:30:50 +00:00
if (warn)
1999-08-26 09:30:50 +00:00
{
static int explained;
2007-05-19 01:19:51 +00:00
warning (0, "friend declaration %q#D declares a non-template "
"function", decl);
1999-08-26 09:30:50 +00:00
if (! explained)
{
2007-05-19 01:19:51 +00:00
warning (0, "(if this is not what you intended, make sure "
"the function template has already been declared "
"and add <> after the function name here) "
"-Wno-non-template-friend disables this warning");
1999-08-26 09:30:50 +00:00
explained = 1;
}
}
}
2004-07-28 03:11:36 +00:00
if (decl == error_mark_node)
return error_mark_node;
2007-05-19 01:19:51 +00:00
add_friend (current_class_type,
2004-07-28 03:11:36 +00:00
is_friend_template ? DECL_TI_TEMPLATE (decl) : decl,
/*complain=*/true);
1999-08-26 09:30:50 +00:00
DECL_FRIEND_P (decl) = 1;
}
/* Unfortunately, we have to handle attributes here. Normally we would
handle them in start_decl_1, but since this is a friend decl start_decl_1
never gets to see it. */
/* Set attributes here so if duplicate decl, will have proper attributes. */
cplus_decl_attributes (&decl, attrlist, 0);
1999-08-26 09:30:50 +00:00
return decl;
}