c++: Kill DECL_HIDDEN_FRIEND_P
authorNathan Sidwell <nathan@acm.org>
Wed, 30 Sep 2020 13:23:15 +0000 (06:23 -0700)
committerNathan Sidwell <nathan@acm.org>
Wed, 30 Sep 2020 13:44:19 +0000 (06:44 -0700)
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.

gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/name-lookup.c
gcc/cp/pt.c

index 1e5fffe20ae09e16535081f082fe747b208c548b..dce229ccf7e21e18f52ccef82a068451f72de914 100644 (file)
@@ -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))
index 42d0d76bf2181fc296163636a6b98e0fdabc6fd5..48a4074b3707cc688dbc4749ae4a64f170a53b3e 100644 (file)
@@ -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) \
index 617b96e02e4d99beaaaf1e295205cae38c141dbd..14742c115ad50861a56072afdaa8366692816c57 100644 (file)
@@ -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.  */
index bc60d343f7e45aa467d2d3d90a49bb856478c76f..8cd6fe382715066a3c02d3cfd1f77ef027c50854 100644 (file)
@@ -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.  */
index a09633751ca98f0eaa123e744508d56baf74fcfc..652b4583b35ec792c3d0aa56b4dd8addc2a2730e 100644 (file)
@@ -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);