You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include "config.h"
#include "system.h"
else
/* It's a type. */
{
- /* Nested classes are implicitly friends of their enclosing types, as
- per core issue 45 (this is a change from the standard). */
- for (context = supplicant;
- context && TYPE_P (context);
- context = TYPE_CONTEXT (context))
- if (type == context)
- return 1;
+ if (same_type_p (supplicant, type))
+ return 1;
list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
for (; list ; list = TREE_CHAIN (list))
}
}
- if (declp && DECL_FUNCTION_MEMBER_P (supplicant))
- context = DECL_CONTEXT (supplicant);
- else if (! declp)
- /* Local classes have the same access as the enclosing function. */
- context = decl_function_context (TYPE_MAIN_DECL (supplicant));
+ if (declp)
+ {
+ if (DECL_FUNCTION_MEMBER_P (supplicant))
+ context = DECL_CONTEXT (supplicant);
+ else
+ context = NULL_TREE;
+ }
else
- context = NULL_TREE;
+ {
+ 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));
+ }
/* A namespace is not friend to anybody. */
if (context && TREE_CODE (context) == NAMESPACE_DECL)
{
error ("%qT is not a member class template of %qT",
name, ctype);
- cp_error_at ("%qD declared here", decl);
+ error ("%q+D declared here", decl);
return;
}
if (!template_member_p && (TREE_CODE (decl) != TYPE_DECL
{
error ("%qT is not a nested class of %qT",
name, ctype);
- cp_error_at ("%qD declared here", decl);
+ error ("%q+D declared here", decl);
return;
}
}
}
-/* Main friend processor.
-
- CTYPE is the class this friend belongs to.
-
- DECLARATOR is the name of the friend.
-
- DECL is the FUNCTION_DECL that the friend is.
-
- FLAGS is just used for `grokclassfn'.
-
- QUALS say what special qualifies should apply to the object
- pointed to by `this'. */
+/* 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. */
tree
do_friend (tree ctype, tree declarator, tree decl,
tree attrlist, enum overload_flags flags,
- cp_cv_quals quals,
- int funcdef_flag)
+ bool funcdef_flag)
{
+ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+ gcc_assert (!ctype || IS_AGGR_TYPE (ctype));
+
/* Every decl that gets here is a friend of something. */
DECL_FRIEND_P (decl) = 1;
declarator = DECL_NAME (get_first_fn (declarator));
}
- gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
-
if (ctype)
{
/* CLASS_TEMPLATE_DEPTH counts the number of template headers for
if (flags == NO_SPECIAL && declarator == cname)
DECL_CONSTRUCTOR_P (decl) = 1;
- /* This will set up DECL_ARGUMENTS for us. */
- grokclassfn (ctype, decl, flags, quals);
+ grokclassfn (ctype, decl, flags);
if (friend_depth)
{
else if (class_template_depth)
/* We rely on tsubst_friend_function to check the
validity of the declaration later. */
- decl = push_template_decl_real (decl, /*is_friend=*/1);
+ decl = push_template_decl_real (decl, /*is_friend=*/true);
else
decl = check_classfn (ctype, decl,
template_member_p
general, such a declaration depends on template
parameters. Instead, we call pushdecl when the class
is instantiated. */
- decl = push_template_decl_real (decl, /*is_friend=*/1);
+ 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
next choice will do). */
- decl = pushdecl (decl);
+ decl = pushdecl_maybe_friend (decl, /*is_friend=*/true);
else
{
/* We can't use pushdecl, as we might be in a template
tree ns = decl_namespace_context (decl);
push_nested_namespace (ns);
- decl = pushdecl_namespace_level (decl);
+ decl = pushdecl_namespace_level (decl, /*is_friend=*/true);
pop_nested_namespace (ns);
}