diff mbox series

c++: Adjust pushdecl/duplicate_decls API

Message ID 20a749a1-e685-3673-eff1-93b92bcf0384@acm.org
State New
Headers show
Series c++: Adjust pushdecl/duplicate_decls API | expand

Commit Message

Nathan Sidwell Sept. 25, 2020, 7:07 p.m. UTC
The decl pushing APIs and duplicate_decls take an 'is_friend' parm,
when what they actually mean is 'hide this from name lookup'.  That
conflation has gotten more anachronistic as time moved on.  We now
have anticipated builtins, and I plan to have injected extern decls
soon.  So this patch is mainly a renaming excercise.  is_friend ->
hiding.  duplicate_decls gets an additional 'was_hidden' parm.  As
I've already said, hiddenness is a property of the symbol table, not
the decl.  Builtins are now pushed requesting hiding, and pushdecl
asserts that we don't attempt to push a thing that should be hidden
without asking for it to be hidden.

This is the final piece of groundwork to get rid of a bunch of 'this
is hidden' markers on decls and move the hiding management entirely
into name lookup.

         gcc/cp/
         * cp-tree.h (duplicate_decls): Replace 'is_friend' with 'hiding'
         and add 'was_hidden'.
         * name-lookup.h (pushdecl_namespace_level): Replace 'is_friend'
         with 'hiding'.
         (pushdecl): Likewise.
         (pushdecl_top_level): Drop is_friend parm.
         * decl.c (check_no_redeclaration_friend_default_args): Rename parm
         olddelc_hidden_p.
         (duplicate_decls): Replace 'is_friend' with 'hiding'
         and 'was_hidden'.  Do minimal adjustments in body.
         (cxx_builtin_function): Pass 'hiding' to pushdecl.
         * friend.c (do_friend): Pass 'hiding' to pushdecl.
         * name-lookup.c (supplement_binding_1): Drop defaulted arg to
         duplicate_decls.
         (update_binding): Replace 'is_friend' with 'hiding'.  Drop
         defaulted arg to duplicate_decls.
         (do_pushdecl): Replace 'is_friend' with 'hiding'.  Assert no
         surprise hidhing.  Adjust duplicate_decls calls to inform of old
         decl's hiddennes.
         (pushdecl): Replace 'is_friend' with 'hiding'.
         (set_identifier_type_value_with_scope): Adjust update_binding
         call.
         (do_pushdecl_with_scope): Replace 'is_friend' with 'hiding'.
         (pushdecl_outermost_localscope): Drop default arg to
         do_pushdecl_with_scope.
         (pushdecl_namespace_level): Replace 'is_friend' with 'hiding'.
         (pushdecl_top_level): Drop is_friend parm.
         * pt.c (register_specialization): Comment duplicate_decls call
         args.
         (push_template_decl): Commont pushdecl_namespace_level.
         (tsubst_friend_function, tsubst_friend_class): Likewise.

pushing to trunk

nathan
diff mbox series

Patch

diff --git i/gcc/cp/cp-tree.h w/gcc/cp/cp-tree.h
index 321bb959120..b7f5b6b399f 100644
--- i/gcc/cp/cp-tree.h
+++ w/gcc/cp/cp-tree.h
@@ -6466,7 +6466,8 @@  extern void determine_local_discriminator	(tree);
 extern int decls_match				(tree, tree, bool = true);
 extern bool maybe_version_functions		(tree, tree, bool);
 extern tree duplicate_decls			(tree, tree,
-						 bool is_friend = false);
+						 bool hiding = false,
+						 bool was_hidden = false);
 extern tree declare_local_label			(tree);
 extern tree define_label			(location_t, tree);
 extern void check_goto				(tree);
diff --git i/gcc/cp/decl.c w/gcc/cp/decl.c
index b481bbd7b7d..c00b996294e 100644
--- i/gcc/cp/decl.c
+++ w/gcc/cp/decl.c
@@ -1341,17 +1341,16 @@  check_redeclaration_no_default_args (tree decl)
 
 static void
 check_no_redeclaration_friend_default_args (tree olddecl, tree newdecl,
-					    bool olddecl_hidden_friend_p)
+					    bool olddecl_hidden_p)
 {
-  if (!olddecl_hidden_friend_p && !DECL_FRIEND_P (newdecl))
+  if (!olddecl_hidden_p && !DECL_FRIEND_P (newdecl))
     return;
 
-  tree t1 = FUNCTION_FIRST_USER_PARMTYPE (olddecl);
-  tree t2 = FUNCTION_FIRST_USER_PARMTYPE (newdecl);
-
-  for (; t1 && t1 != void_list_node;
+  for (tree t1 = FUNCTION_FIRST_USER_PARMTYPE (olddecl),
+	 t2 = FUNCTION_FIRST_USER_PARMTYPE (newdecl);
+       t1 && t1 != void_list_node;
        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
-    if ((olddecl_hidden_friend_p && TREE_PURPOSE (t1))
+    if ((olddecl_hidden_p && TREE_PURPOSE (t1))
 	|| (DECL_FRIEND_P (newdecl) && TREE_PURPOSE (t2)))
       {
 	auto_diagnostic_group d;
@@ -1435,10 +1434,14 @@  duplicate_function_template_decls (tree newdecl, tree olddecl)
    If NEWDECL is not a redeclaration of OLDDECL, NULL_TREE is
    returned.
 
-   NEWDECL_IS_FRIEND is true if NEWDECL was declared as a friend.  */
+   HIDING is true if the new decl is being hidden.  WAS_HIDDEN is true
+   if the old decl was hidden.
+
+   Hidden decls can be anticipated builtins, injected friends, or
+   (coming soon) injected from a local-extern decl.   */
 
 tree
-duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
+duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
 {
   unsigned olddecl_uid = DECL_UID (olddecl);
   int olddecl_friend = 0, types_match = 0, hidden_friend = 0;
@@ -1510,7 +1513,7 @@  duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 	{
 	  /* Avoid warnings redeclaring built-ins which have not been
 	     explicitly declared.  */
-	  if (DECL_ANTICIPATED (olddecl))
+	  if (was_hidden)
 	    {
 	      tree t1, t2;
 
@@ -1550,7 +1553,7 @@  duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 			    types_match = decls_match (newdecl, olddecl);
 			    if (types_match)
 			      return duplicate_decls (newdecl, olddecl,
-						      newdecl_is_friend);
+						      hiding, was_hidden);
 			    TYPE_ARG_TYPES (TREE_TYPE (olddecl)) = oldargs;
 			  }
 			goto next_arg;
@@ -1985,7 +1988,7 @@  duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 		 declaration of the function or function template in the
 		 translation unit."  */
 	      check_no_redeclaration_friend_default_args
-		(olddecl, newdecl, DECL_HIDDEN_FRIEND_P (olddecl));
+		(olddecl, newdecl, was_hidden);
 	    }
 	}
     }
@@ -2075,8 +2078,8 @@  duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 	  && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)
 	  /* Don't warn about extern decl followed by definition.  */
 	  && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl))
-	  /* Don't warn about friends, let add_friend take care of it.  */
-	  && ! (newdecl_is_friend || DECL_FRIEND_P (olddecl))
+	  /* Don't warn if at least one is/was hidden.  */
+	  && !(hiding || was_hidden)
 	  /* Don't warn about declaration followed by specialization.  */
 	  && (! DECL_TEMPLATE_SPECIALIZATION (newdecl)
 	      || DECL_TEMPLATE_SPECIALIZATION (olddecl)))
@@ -2134,11 +2137,9 @@  duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
 
   if (DECL_DECLARES_FUNCTION_P (olddecl))
     {
-      olddecl_friend = DECL_FRIEND_P (olddecl);
-      olddecl_hidden_friend = DECL_HIDDEN_FRIEND_P (olddecl);
-      hidden_friend = (DECL_ANTICIPATED (olddecl)
-		       && DECL_HIDDEN_FRIEND_P (olddecl)
-		       && newdecl_is_friend);
+      olddecl_friend = DECL_FRIEND_P (STRIP_TEMPLATE (olddecl));
+      olddecl_hidden_friend = olddecl_friend && was_hidden;
+      hidden_friend = olddecl_hidden_friend && hiding;
       if (!hidden_friend)
 	{
 	  DECL_ANTICIPATED (olddecl) = 0;
@@ -4714,16 +4715,23 @@  cxx_builtin_function (tree decl)
 
   tree id = DECL_NAME (decl);
   const char *name = IDENTIFIER_POINTER (id);
+  bool hiding = false;
   if (name[0] != '_' || name[1] != '_')
-    /* In the user's namespace, it must be declared before use.  */
-    DECL_ANTICIPATED (decl) = 1;
+    {
+      /* In the user's namespace, it must be declared before use.  */
+      DECL_ANTICIPATED (decl) = 1;
+      hiding = true;
+    }
   else if (IDENTIFIER_LENGTH (id) > strlen ("___chk")
 	   && 0 != strncmp (name + 2, "builtin_", strlen ("builtin_"))
 	   && 0 == memcmp (name + IDENTIFIER_LENGTH (id) - strlen ("_chk"),
 			   "_chk", strlen ("_chk") + 1))
-    /* Treat __*_chk fortification functions as anticipated as well,
-       unless they are __builtin_*_chk.  */
-    DECL_ANTICIPATED (decl) = 1;
+    {
+      /* Treat __*_chk fortification functions as anticipated as well,
+	 unless they are __builtin_*_chk.  */
+      DECL_ANTICIPATED (decl) = 1;
+      hiding = true;
+    }
 
   /* All builtins that don't begin with an '_' should additionally
      go in the 'std' namespace.  */
@@ -4733,12 +4741,12 @@  cxx_builtin_function (tree decl)
 
       push_nested_namespace (std_node);
       DECL_CONTEXT (std_decl) = FROB_CONTEXT (std_node);
-      pushdecl (std_decl);
+      pushdecl (std_decl, hiding);
       pop_nested_namespace (std_node);
     }
 
   DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
-  decl = pushdecl (decl);
+  decl = pushdecl (decl, hiding);
 
   return decl;
 }
@@ -9925,7 +9933,7 @@  grokfndecl (tree ctype,
 	  /* Attempt to merge the declarations.  This can fail, in
 	     the case of some invalid specialization declarations.  */
 	  pushed_scope = push_scope (ctype);
-	  ok = duplicate_decls (decl, old_decl, friendp);
+	  ok = duplicate_decls (decl, old_decl);
 	  if (pushed_scope)
 	    pop_scope (pushed_scope);
 	  if (!ok)
diff --git i/gcc/cp/friend.c w/gcc/cp/friend.c
index e4841347141..6a783a9d88a 100644
--- i/gcc/cp/friend.c
+++ w/gcc/cp/friend.c
@@ -598,8 +598,8 @@  do_friend (tree ctype, tree declarator, tree decl,
       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.  */
+	     arguments before push_template_decl adds a reference to
+	     the containing template class.  */
 	  int warn = (warn_nontemplate_friend
 		      && ! funcdef_flag && ! is_friend_template
 		      && current_template_parms
@@ -614,7 +614,7 @@  do_friend (tree ctype, tree declarator, tree decl,
 	    decl = push_template_decl (decl, /*is_friend=*/true);
 	  else if (current_function_decl)
 	    /* pushdecl will check there's a local decl already.  */
-	    decl = pushdecl (decl, /*is_friend=*/true);
+	    decl = pushdecl (decl, /*hiding=*/true);
 	  else
 	    {
 	      /* We can't use pushdecl, as we might be in a template
@@ -624,7 +624,7 @@  do_friend (tree ctype, tree declarator, tree decl,
 	      tree ns = decl_namespace_context (decl);
 
 	      push_nested_namespace (ns);
-	      decl = pushdecl_namespace_level (decl, /*is_friend=*/true);
+	      decl = pushdecl_namespace_level (decl, /*hiding=*/true);
 	      pop_nested_namespace (ns);
 	    }
 
diff --git i/gcc/cp/name-lookup.c w/gcc/cp/name-lookup.c
index 0115a4bd386..184e9c873e7 100644
--- i/gcc/cp/name-lookup.c
+++ w/gcc/cp/name-lookup.c
@@ -2232,7 +2232,7 @@  supplement_binding_1 (cxx_binding *binding, tree decl)
 	   && DECL_EXTERNAL (target_decl) && DECL_EXTERNAL (target_bval)
 	   && !DECL_CLASS_SCOPE_P (target_decl))
     {
-      duplicate_decls (decl, binding->value, /*newdecl_is_friend=*/false);
+      duplicate_decls (decl, binding->value);
       ok = false;
     }
   else if (TREE_CODE (decl) == NAMESPACE_DECL
@@ -2354,7 +2354,7 @@  matching_fn_p (tree one, tree two)
 
 static tree
 update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
-		tree old, tree decl, bool is_friend)
+		tree old, tree decl, bool hiding = false)
 {
   tree to_val = decl;
   tree old_type = slot ? MAYBE_STAT_TYPE (*slot) : binding->type;
@@ -2410,13 +2410,14 @@  update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
 
 	      if (iter.using_p () && matching_fn_p (fn, decl))
 		{
+		  gcc_checking_assert (!iter.hidden_p ());
 		  /* If a function declaration in namespace scope or
 		     block scope has the same name and the same
 		     parameter-type- list (8.3.5) as a function
 		     introduced by a using-declaration, and the
 		     declarations do not declare the same function,
 		     the program is ill-formed.  [namespace.udecl]/14 */
-		  if (tree match = duplicate_decls (decl, fn, is_friend))
+		  if (tree match = duplicate_decls (decl, fn, hiding))
 		    return match;
 		  else
 		    /* FIXME: To preserve existing error behavior, we
@@ -2468,7 +2469,7 @@  update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
 	 variable, so long as they are `extern' declarations.  */
       if (!DECL_EXTERNAL (old) || !DECL_EXTERNAL (decl))
 	goto conflict;
-      else if (tree match = duplicate_decls (decl, old, false))
+      else if (tree match = duplicate_decls (decl, old))
 	return match;
       else
 	goto conflict;
@@ -2989,12 +2990,12 @@  set_local_extern_decl_linkage (tree decl, bool shadowed)
    says.  */
 
 static tree
-do_pushdecl (tree decl, bool is_friend)
+do_pushdecl (tree decl, bool hiding)
 {
   if (decl == error_mark_node)
     return error_mark_node;
 
-  if (!DECL_TEMPLATE_PARM_P (decl) && current_function_decl && !is_friend)
+  if (!DECL_TEMPLATE_PARM_P (decl) && current_function_decl && !hiding)
     set_decl_context_in_fn (current_function_decl, decl);
 
   /* The binding level we will be pushing into.  During local class
@@ -3014,6 +3015,14 @@  do_pushdecl (tree decl, bool is_friend)
       tree *slot = NULL; /* Binding slot in namespace.  */
       tree old = NULL_TREE;
 
+      if (!hiding)
+	/* We should never unknownly push an anticipated decl.  */
+	gcc_checking_assert (!((TREE_CODE (decl) == TYPE_DECL
+				|| TREE_CODE (decl) == FUNCTION_DECL
+				|| TREE_CODE (decl) == TEMPLATE_DECL)
+			       && DECL_LANG_SPECIFIC (decl)
+			       && DECL_ANTICIPATED (decl)));
+
       if (level->kind == sk_namespace)
 	{
 	  /* We look in the decl's namespace for an existing
@@ -3044,7 +3053,8 @@  do_pushdecl (tree decl, bool is_friend)
       for (ovl_iterator iter (old); iter; ++iter)
 	if (iter.using_p ())
 	  ; /* Ignore using decls here.  */
-	else if (tree match = duplicate_decls (decl, *iter, is_friend))
+	else if (tree match
+		 = duplicate_decls (decl, *iter, hiding, iter.hidden_p ()))
 	  {
 	    if (match == error_mark_node)
 	      ;
@@ -3052,7 +3062,7 @@  do_pushdecl (tree decl, bool is_friend)
 	      /* The IDENTIFIER will have the type referring to the
 		 now-smashed TYPE_DECL, because ...?  Reset it.  */
 	      SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (match));
-	    else if (iter.hidden_p () && !DECL_HIDDEN_P (match))
+	    else if (iter.hidden_p () && !hiding)
 	      {
 		/* Unhiding a previously hidden decl.  */
 		tree head = iter.reveal_node (old);
@@ -3088,7 +3098,7 @@  do_pushdecl (tree decl, bool is_friend)
 	{
 	  check_default_args (decl);
 
-	  if (is_friend)
+	  if (hiding)
 	    {
 	      if (level->kind != sk_namespace)
 		{
@@ -3126,7 +3136,7 @@  do_pushdecl (tree decl, bool is_friend)
 	  old = MAYBE_STAT_DECL (*slot);
 	}
 
-      old = update_binding (level, binding, slot, old, decl, is_friend);
+      old = update_binding (level, binding, slot, old, decl, hiding);
 
       if (old != decl)
 	/* An existing decl matched, use it.  */
@@ -3170,10 +3180,10 @@  do_pushdecl (tree decl, bool is_friend)
    we push it.  */
 
 tree
-pushdecl (tree x, bool is_friend)
+pushdecl (tree x, bool hiding)
 {
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
-  tree ret = do_pushdecl (x, is_friend);
+  tree ret = do_pushdecl (x, hiding);
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
   return ret;
 }
@@ -3780,7 +3790,7 @@  set_identifier_type_value_with_scope (tree id, tree decl, cp_binding_level *b)
     {
       tree *slot = find_namespace_slot (current_namespace, id, true);
       gcc_assert (decl);
-      update_binding (b, NULL, slot, MAYBE_STAT_DECL (*slot), decl, false);
+      update_binding (b, NULL, slot, MAYBE_STAT_DECL (*slot), decl);
 
       /* Store marker instead of real type.  */
       type = global_type_node;
@@ -3836,12 +3846,13 @@  constructor_name_p (tree name, tree type)
    closer binding level than LEVEL.  */
 
 static tree
-do_pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend)
+do_pushdecl_with_scope (tree x, cp_binding_level *level, bool hiding = false)
 {
   cp_binding_level *b;
 
   if (level->kind == sk_class)
     {
+      gcc_checking_assert (!hiding);
       b = class_binding_level;
       class_binding_level = level;
       pushdecl_class_level (x);
@@ -3854,7 +3865,7 @@  do_pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend)
 	current_function_decl = NULL_TREE;
       b = current_binding_level;
       current_binding_level = level;
-      x = pushdecl (x, is_friend);
+      x = pushdecl (x, hiding);
       current_binding_level = b;
       current_function_decl = function_decl;
     }
@@ -3874,7 +3885,7 @@  pushdecl_outermost_localscope (tree x)
        n->kind != sk_function_parms; n = b->level_chain)
     b = n;
 
-  tree ret = b ? do_pushdecl_with_scope (x, b, false) : error_mark_node;
+  tree ret = b ? do_pushdecl_with_scope (x, b) : error_mark_node;
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 
   return ret;
@@ -5072,14 +5083,13 @@  do_namespace_alias (tree alias, tree name_space)
    if appropriate.  */
 
 tree
-pushdecl_namespace_level (tree x, bool is_friend)
+pushdecl_namespace_level (tree x, bool hiding)
 {
   cp_binding_level *b = current_binding_level;
   tree t;
 
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
-  t = do_pushdecl_with_scope
-    (x, NAMESPACE_LEVEL (current_namespace), is_friend);
+  t = do_pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace), hiding);
 
   /* Now, the type_shadowed stack may screw us.  Munge it so it does
      what we want.  */
@@ -7282,11 +7292,11 @@  finish_using_directive (tree target, tree attribs)
 /* Pushes X into the global namespace.  */
 
 tree
-pushdecl_top_level (tree x, bool is_friend)
+pushdecl_top_level (tree x)
 {
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   do_push_to_top_level ();
-  x = pushdecl_namespace_level (x, is_friend);
+  x = pushdecl_namespace_level (x);
   do_pop_from_top_level ();
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
   return x;
diff --git i/gcc/cp/name-lookup.h w/gcc/cp/name-lookup.h
index 82f4d5155b7..7b463386725 100644
--- i/gcc/cp/name-lookup.h
+++ w/gcc/cp/name-lookup.h
@@ -337,7 +337,7 @@  extern tree lookup_qualified_name (tree scope, const char *name,
 				   bool = true);
 extern bool is_local_extern (tree);
 extern bool pushdecl_class_level (tree);
-extern tree pushdecl_namespace_level (tree, bool is_friend = false);
+extern tree pushdecl_namespace_level (tree, bool hiding = false);
 extern bool push_class_level_binding (tree, tree);
 extern tree get_local_decls ();
 extern int function_parm_depth (void);
@@ -363,9 +363,9 @@  extern void cp_emit_debug_info_for_using (tree, tree);
 
 extern void finish_nonmember_using_decl (tree scope, tree name);
 extern void finish_using_directive (tree target, tree attribs);
-extern tree pushdecl (tree, bool is_friend = false);
+extern tree pushdecl (tree, bool hiding = false);
 extern tree pushdecl_outermost_localscope (tree);
-extern tree pushdecl_top_level (tree, bool is_friend = false);
+extern tree pushdecl_top_level (tree);
 extern tree pushdecl_top_level_and_finish (tree, tree);
 extern tree pushtag (tree, tree, TAG_how = TAG_how::CURRENT_ONLY);
 extern int push_namespace (tree, bool make_inline = false);
diff --git i/gcc/cp/pt.c w/gcc/cp/pt.c
index a4530dba14e..199fe658f71 100644
--- i/gcc/cp/pt.c
+++ w/gcc/cp/pt.c
@@ -1635,7 +1635,7 @@  register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
 		 for the specialization, we want this to look as if
 		 there were no definition, and vice versa.  */
 	      DECL_INITIAL (fn) = NULL_TREE;
-	      duplicate_decls (spec, fn, is_friend);
+	      duplicate_decls (spec, fn, /*hiding=*/is_friend);
 	      /* The call to duplicate_decls will have applied
 		 [temp.expl.spec]:
 
@@ -1662,7 +1662,7 @@  register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
 	}
       else if (DECL_TEMPLATE_SPECIALIZATION (fn))
 	{
-	  tree dd = duplicate_decls (spec, fn, is_friend);
+	  tree dd = duplicate_decls (spec, fn, /*hiding=*/is_friend);
 	  if (dd == error_mark_node)
 	    /* We've already complained in duplicate_decls.  */
 	    return error_mark_node;
@@ -1677,7 +1677,7 @@  register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
 	}
     }
   else if (fn)
-    return duplicate_decls (spec, fn, is_friend);
+    return duplicate_decls (spec, fn, /*hiding=*/is_friend);
 
   /* A specialization must be declared in the same namespace as the
      template it is specializing.  */
@@ -6018,7 +6018,7 @@  push_template_decl (tree decl, bool is_friend)
       if (!ctx
 	  && !(is_friend && template_class_depth (current_class_type) > 0))
 	{
-	  tmpl = pushdecl_namespace_level (tmpl, is_friend);
+	  tmpl = pushdecl_namespace_level (tmpl, /*hiding=*/is_friend);
 	  if (tmpl == error_mark_node)
 	    return error_mark_node;
 
@@ -11078,7 +11078,7 @@  tsubst_friend_function (tree decl, tree args)
 	 into the namespace of the template.  */
       ns = decl_namespace_context (new_friend);
       push_nested_namespace (ns);
-      old_decl = pushdecl_namespace_level (new_friend, /*is_friend=*/true);
+      old_decl = pushdecl_namespace_level (new_friend, /*hiding=*/true);
       pop_nested_namespace (ns);
 
       if (old_decl == error_mark_node)
@@ -11323,7 +11323,7 @@  tsubst_friend_class (tree friend_tmpl, tree args)
 	    }
 
 	  /* Inject this template into the enclosing namspace scope.  */
-	  tmpl = pushdecl_namespace_level (tmpl, true);
+	  tmpl = pushdecl_namespace_level (tmpl, /*hiding=*/true);
 	}
     }