mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 20:01:22 -05:00
c++: Adjust pushdecl/duplicate_decls API
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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
12
gcc/cp/pt.c
12
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user