c++: Kill DECL_HIDDEN_FRIEND_P
Now hiddenness is managed by name-lookup, we no longer need DECL_HIDDEN_FRIEND_P. This removes it. Mainly by deleting its bookkeeping, but there are a couple of uses 1) two name lookups look at it to see if they found a hidden thing. In one we have the OVERLOAD, so can record OVL_HIDDEN_P. In the other we're repeating a lookup that failed, but asking for hidden things -- so if that succeeds we know the thing was hidden. (FWIW CWG recently discussed whether template specializations and instantiations should see such hidden templates anyway, there is compiler divergence.) 2) We had a confusing setting of KOENIG_P when building a non-dependent call. We don't repeat that lookup at instantiation time anyway. gcc/cp/ * cp-tree.h (struct lang_decl_fn): Remove hidden_friend_p. (DECL_HIDDEN_FRIEND_P): Delete. * call.c (add_function_candidate): Drop assert about anticipated decl. (build_new_op_1): Drop koenig lookup flagging for hidden friend. * decl.c (duplicate_decls): Drop HIDDEN_FRIEND_P updating. * name-lookup.c (do_pushdecl): Likewise. (set_decl_namespace): Discover hiddenness from OVL_HIDDEN_P. * pt.c (check_explicit_specialization): Record found_hidden explicitly.
This commit is contained in:
parent
65167982ef
commit
734eed6853
@ -2220,11 +2220,6 @@ add_function_candidate (struct z_candidate **candidates,
|
||||
int viable = 1;
|
||||
struct rejection_reason *reason = NULL;
|
||||
|
||||
/* At this point we should not see any functions which haven't been
|
||||
explicitly declared, except for friend functions which will have
|
||||
been found using argument dependent lookup. */
|
||||
gcc_assert (!DECL_ANTICIPATED (fn) || DECL_HIDDEN_FRIEND_P (fn));
|
||||
|
||||
/* The `this', `in_chrg' and VTT arguments to constructors are not
|
||||
considered in overload resolution. */
|
||||
if (DECL_CONSTRUCTOR_P (fn))
|
||||
@ -6344,11 +6339,6 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags,
|
||||
tree call = extract_call_expr (result);
|
||||
CALL_EXPR_OPERATOR_SYNTAX (call) = true;
|
||||
|
||||
if (processing_template_decl && DECL_HIDDEN_FRIEND_P (cand->fn))
|
||||
/* This prevents build_new_function_call from discarding this
|
||||
function during instantiation of the enclosing template. */
|
||||
KOENIG_LOOKUP_P (call) = 1;
|
||||
|
||||
/* Specify evaluation order as per P0145R2. */
|
||||
CALL_EXPR_ORDERED_ARGS (call) = false;
|
||||
switch (op_is_ordered (code))
|
||||
|
@ -2720,14 +2720,13 @@ struct GTY(()) lang_decl_fn {
|
||||
unsigned thunk_p : 1;
|
||||
|
||||
unsigned this_thunk_p : 1;
|
||||
unsigned hidden_friend_p : 1;
|
||||
unsigned omp_declare_reduction_p : 1;
|
||||
unsigned has_dependent_explicit_spec_p : 1;
|
||||
unsigned immediate_fn_p : 1;
|
||||
unsigned maybe_deleted : 1;
|
||||
unsigned coroutine_p : 1;
|
||||
|
||||
unsigned spare : 9;
|
||||
unsigned spare : 10;
|
||||
|
||||
/* 32-bits padding on 64-bit host. */
|
||||
|
||||
@ -4067,12 +4066,6 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
|
||||
#define DECL_OMP_PRIVATIZED_MEMBER(NODE) \
|
||||
(DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.anticipated_p)
|
||||
|
||||
/* Nonzero if NODE is a FUNCTION_DECL which was declared as a friend
|
||||
within a class but has not been declared in the surrounding scope.
|
||||
The function is invisible except via argument dependent lookup. */
|
||||
#define DECL_HIDDEN_FRIEND_P(NODE) \
|
||||
(LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->hidden_friend_p)
|
||||
|
||||
/* Nonzero if NODE is an artificial FUNCTION_DECL for
|
||||
#pragma omp declare reduction. */
|
||||
#define DECL_OMP_DECLARE_REDUCTION_P(NODE) \
|
||||
|
@ -2141,10 +2141,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
|
||||
olddecl_hidden_friend = olddecl_friend && was_hidden;
|
||||
hidden_friend = olddecl_hidden_friend && hiding;
|
||||
if (!hidden_friend)
|
||||
{
|
||||
DECL_ANTICIPATED (olddecl) = 0;
|
||||
DECL_HIDDEN_FRIEND_P (olddecl) = 0;
|
||||
}
|
||||
DECL_ANTICIPATED (olddecl) = false;
|
||||
}
|
||||
|
||||
if (TREE_CODE (newdecl) == TEMPLATE_DECL)
|
||||
@ -2892,12 +2889,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
|
||||
|
||||
DECL_UID (olddecl) = olddecl_uid;
|
||||
if (olddecl_friend)
|
||||
DECL_FRIEND_P (olddecl) = 1;
|
||||
DECL_FRIEND_P (olddecl) = true;
|
||||
if (hidden_friend)
|
||||
{
|
||||
DECL_ANTICIPATED (olddecl) = 1;
|
||||
DECL_HIDDEN_FRIEND_P (olddecl) = 1;
|
||||
}
|
||||
DECL_ANTICIPATED (olddecl) = true;
|
||||
|
||||
/* NEWDECL contains the merged attribute lists.
|
||||
Update OLDDECL to be the same. */
|
||||
|
@ -3172,7 +3172,7 @@ do_pushdecl (tree decl, bool hiding)
|
||||
return error_mark_node;
|
||||
}
|
||||
/* Hide it from ordinary lookup. */
|
||||
DECL_ANTICIPATED (decl) = DECL_HIDDEN_FRIEND_P (decl) = true;
|
||||
DECL_ANTICIPATED (decl) = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4924,8 +4924,15 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
|
||||
|
||||
/* Since decl is a function, old should contain a function decl. */
|
||||
if (!OVL_P (old))
|
||||
goto not_found;
|
||||
{
|
||||
not_found:
|
||||
/* It didn't work, go back to the explicit scope. */
|
||||
DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
|
||||
error ("%qD should have been declared inside %qD", decl, scope);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* We handle these in check_explicit_instantiation_namespace. */
|
||||
if (processing_explicit_instantiation)
|
||||
return;
|
||||
@ -4935,13 +4942,14 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
|
||||
match. But, we'll check later, when we construct the
|
||||
template. */
|
||||
return;
|
||||
|
||||
/* Instantiations or specializations of templates may be declared as
|
||||
friends in any namespace. */
|
||||
if (friendp && DECL_USE_TEMPLATE (decl))
|
||||
return;
|
||||
|
||||
tree found;
|
||||
found = NULL_TREE;
|
||||
tree found = NULL_TREE;
|
||||
bool hidden_p = false;
|
||||
|
||||
for (lkp_iterator iter (old); iter; ++iter)
|
||||
{
|
||||
@ -4957,17 +4965,20 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
|
||||
{
|
||||
if (found)
|
||||
{
|
||||
/* We found more than one matching declaration. */
|
||||
/* We found more than one matching declaration. This
|
||||
can happen if we have two inline namespace children,
|
||||
each containing a suitable declaration. */
|
||||
DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
|
||||
goto ambiguous;
|
||||
}
|
||||
found = ofn;
|
||||
hidden_p = iter.hidden_p ();
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (DECL_HIDDEN_FRIEND_P (found))
|
||||
if (hidden_p)
|
||||
{
|
||||
pedwarn (DECL_SOURCE_LOCATION (decl), 0,
|
||||
"%qD has not been declared within %qD", decl, scope);
|
||||
@ -4978,10 +4989,7 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
|
||||
goto found;
|
||||
}
|
||||
|
||||
not_found:
|
||||
/* It didn't work, go back to the explicit scope. */
|
||||
DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
|
||||
error ("%qD should have been declared inside %qD", decl, scope);
|
||||
goto not_found;
|
||||
}
|
||||
|
||||
/* Return the namespace where the current declaration is declared. */
|
||||
|
24
gcc/cp/pt.c
24
gcc/cp/pt.c
@ -2988,6 +2988,7 @@ check_explicit_specialization (tree declarator,
|
||||
tree tmpl = NULL_TREE;
|
||||
tree targs = NULL_TREE;
|
||||
bool was_template_id = (TREE_CODE (declarator) == TEMPLATE_ID_EXPR);
|
||||
bool found_hidden = false;
|
||||
|
||||
/* Make sure that the declarator is a TEMPLATE_ID_EXPR. */
|
||||
if (!was_template_id)
|
||||
@ -3008,12 +3009,15 @@ check_explicit_specialization (tree declarator,
|
||||
fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname,
|
||||
LOOK_want::NORMAL, true);
|
||||
if (fns == error_mark_node)
|
||||
/* If lookup fails, look for a friend declaration so we can
|
||||
give a better diagnostic. */
|
||||
fns = (lookup_qualified_name
|
||||
(CP_DECL_CONTEXT (decl), dname,
|
||||
LOOK_want::NORMAL | LOOK_want::HIDDEN_FRIEND,
|
||||
/*complain*/true));
|
||||
{
|
||||
/* If lookup fails, look for a friend declaration so we can
|
||||
give a better diagnostic. */
|
||||
fns = (lookup_qualified_name
|
||||
(CP_DECL_CONTEXT (decl), dname,
|
||||
LOOK_want::NORMAL | LOOK_want::HIDDEN_FRIEND,
|
||||
/*complain*/true));
|
||||
found_hidden = true;
|
||||
}
|
||||
|
||||
if (fns == error_mark_node || !is_overloaded_fn (fns))
|
||||
{
|
||||
@ -3122,8 +3126,7 @@ check_explicit_specialization (tree declarator,
|
||||
return error_mark_node;
|
||||
else
|
||||
{
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_HIDDEN_FRIEND_P (tmpl))
|
||||
if (found_hidden && TREE_CODE (decl) == FUNCTION_DECL)
|
||||
{
|
||||
auto_diagnostic_group d;
|
||||
if (pedwarn (DECL_SOURCE_LOCATION (decl), 0,
|
||||
@ -3132,8 +3135,9 @@ check_explicit_specialization (tree declarator,
|
||||
inform (DECL_SOURCE_LOCATION (tmpl),
|
||||
"friend declaration here");
|
||||
}
|
||||
else if (!ctype && !is_friend
|
||||
&& CP_DECL_CONTEXT (decl) == current_namespace)
|
||||
|
||||
if (!ctype && !is_friend
|
||||
&& CP_DECL_CONTEXT (decl) == current_namespace)
|
||||
check_unqualified_spec_or_inst (tmpl, DECL_SOURCE_LOCATION (decl));
|
||||
|
||||
tree gen_tmpl = most_general_template (tmpl);
|
||||
|
Loading…
Reference in New Issue
Block a user