Beispiel #1
0
bool
is_global_friend (tree scope)
{
  gcc_checking_assert (scope != NULL_TREE);

  if (global_friend == scope)
    return true;

  if (!global_friend)
    return false;

  if (is_specialization_of_friend (global_friend, scope))
    return true;

  return false;
}
Beispiel #2
0
int
is_friend (tree type, tree supplicant)
{
    int declp;
    tree list;
    tree context;

    if (supplicant == NULL_TREE || type == NULL_TREE)
        return 0;

    declp = DECL_P (supplicant);

    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))
            {
                tree friends = FRIEND_DECLS (list);
                for (; friends ; friends = TREE_CHAIN (friends))
                {
                    tree this_friend = TREE_VALUE (friends);

                    if (this_friend == NULL_TREE)
                        continue;

                    if (supplicant == this_friend)
                        return 1;

                    if (is_specialization_of_friend (supplicant, this_friend))
                        return 1;
                }
                break;
            }
        }
    }
    else
        /* It's a type.  */
    {
        if (same_type_p (supplicant, type))
            return 1;

        list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
        for (; list ; list = TREE_CHAIN (list))
        {
            tree t = TREE_VALUE (list);

            if (TREE_CODE (t) == TEMPLATE_DECL ?
                    is_specialization_of_friend (TYPE_MAIN_DECL (supplicant), t) :
                    same_type_p (supplicant, t))
                return 1;
        }
    }

    if (declp)
    {
        if (DECL_FUNCTION_MEMBER_P (supplicant))
            context = DECL_CONTEXT (supplicant);
        else
            context = NULL_TREE;
    }
    else
    {
        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)
        context = NULL_TREE;

    if (context)
        return is_friend (type, context);

    return 0;
}