[gcc/devel/c++-modules] c++: Hiddenness is a property of the symbol table (trunk 7cbfe0894de)
Nathan Sidwell
nathan@gcc.gnu.org
Wed Sep 30 20:27:26 GMT 2020
https://gcc.gnu.org/g:9dd9897ed3b8152d8afb8482db8732fc31e3527a
commit 9dd9897ed3b8152d8afb8482db8732fc31e3527a
Author: Nathan Sidwell <nathan@acm.org>
Date: Wed Sep 30 13:26:08 2020 -0700
c++: Hiddenness is a property of the symbol table (trunk 7cbfe0894de)
Diff:
---
ChangeLog.modules | 3 +
gcc/cp/cp-tree.h | 2 +-
gcc/cp/decl.c | 22 +---
gcc/cp/name-lookup.c | 334 +++++++++++++++++++++++++++++++++------------------
gcc/cp/name-lookup.h | 7 ++
gcc/cp/tree.c | 34 +++---
6 files changed, 246 insertions(+), 156 deletions(-)
diff --git a/ChangeLog.modules b/ChangeLog.modules
index 46ce9e32430..37148006ee0 100644
--- a/ChangeLog.modules
+++ b/ChangeLog.modules
@@ -1,5 +1,8 @@
2020-09-30 Nathan Sidwell <nathan@acm.org>
+ Apply trunk 7cbfe0894de
+ c++: Hiddenness is a property of the symbol table
+
Apply trunk adcf8a11c77
c++: Name lookup simplifications
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 501ee64af88..fa20a790032 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7678,7 +7678,7 @@ inline tree ovl_first (tree) ATTRIBUTE_PURE;
extern tree ovl_make (tree fn,
tree next = NULL_TREE);
extern tree ovl_insert (tree fn, tree maybe_ovl,
- unsigned usingness = 0);
+ int using_or_hidden = 0);
extern tree ovl_skip_hidden (tree) ATTRIBUTE_PURE;
extern void lookup_mark (tree lookup, bool val);
extern tree lookup_add (tree fns, tree lookup);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d4f1e8b3691..54ad7cf2e0b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -15165,25 +15165,9 @@ xref_tag_1 (enum tag_types tag_code, tree name,
return error_mark_node;
}
- if (how != TAG_how::HIDDEN_FRIEND && TYPE_HIDDEN_P (t))
- {
- /* This is no longer an invisible friend. Make it
- visible. */
- tree decl = TYPE_NAME (t);
-
- DECL_ANTICIPATED (decl) = false;
- DECL_FRIEND_P (decl) = false;
-
- if (TYPE_TEMPLATE_INFO (t))
- {
- tree tmpl = TYPE_TI_TEMPLATE (t);
- DECL_ANTICIPATED (tmpl) = false;
- DECL_FRIEND_P (tmpl) = false;
- }
-
- if (flag_modules)
- set_instantiating_module (TYPE_NAME (t));
- }
+ // FIXME: Do we need to push into current TU's slot?
+ if (how == TAG_how::CURRENT_ONLY)
+ set_instantiating_module (TYPE_NAME (t));
}
return t;
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index c73f7723500..8a972a26bfd 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -65,10 +65,19 @@ static name_hint suggest_alternatives_for_1 (location_t location, tree name,
#define STAT_VISIBLE(N) OVL_CHAIN (N)
#define MAYBE_STAT_DECL(N) (STAT_HACK_P (N) ? STAT_DECL (N) : N)
#define MAYBE_STAT_TYPE(N) (STAT_HACK_P (N) ? STAT_TYPE (N) : NULL_TREE)
-#define STAT_TYPE_HIDDEN_P(N) OVL_DEDUP_P (N)
+
/* When a STAT_HACK_P is true, OVL_USING_P and OVL_EXPORT_P are valid
and apply to the hacked type. */
+/* For regular (maybe) overloaded functions, we have OVL_HIDDEN_P.
+ But we also need to indicate hiddenness on implicit type decls
+ (injected friend classes), and (coming soon) decls injected from
+ block-scope externs. It is too awkward to press the existing
+ overload marking for that. If we have a hidden non-function, we
+ always create a STAT_HACK, and use these two markers as needed. */
+#define STAT_TYPE_HIDDEN_P(N) OVL_HIDDEN_P (N)
+#define STAT_DECL_HIDDEN_P(N) OVL_DEDUP_P (N)
+
/* Create a STAT_HACK node with DECL as the value binding and TYPE as
the type binding. */
@@ -841,23 +850,27 @@ name_lookup::search_namespace_only (tree scope)
dup_detect |= 1;
}
tree type = NULL_TREE;
+ tree value = bind;
if (STAT_HACK_P (bind))
{
type = STAT_TYPE (bind);
- bind = STAT_DECL (bind);
+ value = STAT_DECL (bind);
- if (!bool (want & LOOK_want::HIDDEN_FRIEND)
- && type
- && DECL_LANG_SPECIFIC (type)
- && DECL_ANTICIPATED (type))
- type = NULL_TREE;
+ if (!bool (want & LOOK_want::HIDDEN_FRIEND))
+ {
+ if (STAT_TYPE_HIDDEN_P (bind))
+ type = NULL_TREE;
+ if (STAT_DECL_HIDDEN_P (bind))
+ value = NULL_TREE;
+ else
+ value = ovl_skip_hidden (value);
+ }
}
+ else if (!bool (want & LOOK_want::HIDDEN_FRIEND))
+ value = ovl_skip_hidden (value);
- if (!bool (want & LOOK_want::HIDDEN_FRIEND))
- bind = ovl_skip_hidden (bind);
-
- marker = process_module_binding (bind, type, marker);
+ marker = process_module_binding (value, type, marker);
}
/* Scan the imported bindings. */
@@ -938,23 +951,28 @@ name_lookup::search_namespace_only (tree scope)
else
{
/* Only a current module binding, visible from the current module. */
- tree bind = *binding, type = NULL_TREE;
+ tree bind = *binding;
+ tree value = bind, type = NULL_TREE;
if (STAT_HACK_P (bind))
{
type = STAT_TYPE (bind);
- bind = STAT_DECL (bind);
+ value = STAT_DECL (bind);
- if (!bool (want & LOOK_want::HIDDEN_FRIEND)
- && DECL_LANG_SPECIFIC (type)
- && DECL_ANTICIPATED (type))
- type = NULL_TREE;
+ if (!bool (want & LOOK_want::HIDDEN_FRIEND))
+ {
+ if (STAT_TYPE_HIDDEN_P (bind))
+ type = NULL_TREE;
+ if (STAT_DECL_HIDDEN_P (bind))
+ value = NULL_TREE;
+ else
+ value = ovl_skip_hidden (value);
+ }
}
+ else if (!bool (want & LOOK_want::HIDDEN_FRIEND))
+ value = ovl_skip_hidden (value);
- if (!bool (want & LOOK_want::HIDDEN_FRIEND))
- bind = ovl_skip_hidden (bind);
-
- found |= process_binding (bind, type);
+ found |= process_binding (value, type);
}
}
@@ -2582,6 +2600,7 @@ cxx_binding_make (tree value, tree type)
/* Clear flags by default. */
LOCAL_BINDING_P (binding) = false;
INHERITED_VALUE_BINDING_P (binding) = false;
+ HIDDEN_TYPE_BINDING_P (binding) = false;
cxx_binding_init (binding, value, type);
@@ -2653,13 +2672,15 @@ pop_local_binding (tree id, tree decl)
/* The name should be bound. */
gcc_assert (binding != NULL);
- /* The DECL will be either the ordinary binding or the type
- binding for this identifier. Remove that binding. */
+ /* The DECL will be either the ordinary binding or the type binding
+ for this identifier. Remove that binding. We don't have to
+ clear HIDDEN_TYPE_BINDING_P, as the whole binding will be going
+ away. */
if (binding->value == decl)
binding->value = NULL_TREE;
else
{
- gcc_assert (binding->type == decl);
+ gcc_checking_assert (binding->type == decl);
binding->type = NULL_TREE;
}
@@ -2974,11 +2995,22 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
tree old, tree decl, bool hiding = false)
{
tree old_type = NULL_TREE;
+ bool hide_type = false;
+ bool hide_value = false;
if (!slot)
- old_type = binding->type;
+ {
+ old_type = binding->type;
+ hide_type = HIDDEN_TYPE_BINDING_P (binding);
+ if (!old_type)
+ hide_value = hide_type, hide_type = false;
+ }
else if (STAT_HACK_P (*slot))
+ {
old_type = STAT_TYPE (*slot);
+ hide_type = STAT_TYPE_HIDDEN_P (*slot);
+ hide_value = STAT_DECL_HIDDEN_P (*slot);
+ }
tree to_val = decl;
tree to_type = old_type;
@@ -3002,9 +3034,12 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
{
/* Put DECL into the type slot. */
gcc_checking_assert (!to_type);
+ hide_type = hiding;
to_type = decl;
to_val = old;
}
+ else
+ hide_value = hiding;
goto done;
}
@@ -3015,7 +3050,9 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
gcc_checking_assert (!to_type);
to_type = old;
+ hide_type = hide_value;
old = NULL_TREE;
+ hide_value = false;
}
if (DECL_DECLARES_FUNCTION_P (decl))
@@ -3058,7 +3095,7 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
decl, to_type);
local_overload = old && level && level->kind != sk_namespace;
- to_val = ovl_insert (decl, old);
+ to_val = ovl_insert (decl, old, -int (hiding));
}
else if (old)
{
@@ -3091,7 +3128,10 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
if (!DECL_EXTERNAL (old) || !DECL_EXTERNAL (decl))
goto conflict;
else if (tree match = duplicate_decls (decl, old))
- return match;
+ {
+ gcc_checking_assert (!hide_value && !hiding);
+ return match;
+ }
else
goto conflict;
}
@@ -3102,6 +3142,8 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
to_val = NULL_TREE;
}
}
+ else if (hiding)
+ hide_value = true;
done:
if (to_val)
@@ -3126,16 +3168,26 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
{
STAT_TYPE (*slot) = to_type;
STAT_DECL (*slot) = to_val;
+ STAT_TYPE_HIDDEN_P (*slot) = hide_type;
+ STAT_DECL_HIDDEN_P (*slot) = hide_value;
+ }
+ else if (to_type || hide_value)
+ {
+ *slot = stat_hack (to_val, to_type);
+ STAT_TYPE_HIDDEN_P (*slot) = hide_type;
+ STAT_DECL_HIDDEN_P (*slot) = hide_value;
}
- else if (to_type)
- *slot = stat_hack (to_val, to_type);
else
- *slot = to_val;
+ {
+ gcc_checking_assert (!hide_type);
+ *slot = to_val;
+ }
}
else
{
binding->type = to_type;
binding->value = to_val;
+ HIDDEN_TYPE_BINDING_P (binding) = hide_type || hide_value;
}
}
@@ -7757,85 +7809,37 @@ lookup_name_1 (tree name, LOOK_where where, LOOK_want want)
for (cxx_binding *iter = nullptr;
(iter = outer_binding (name, iter, bool (where & LOOK_where::CLASS)));)
{
- tree binding;
-
/* Skip entities we don't want. */
if (!bool (where & (LOCAL_BINDING_P (iter)
? LOOK_where::BLOCK : LOOK_where::CLASS)))
continue;
/* If this is the kind of thing we're looking for, we're done. */
- if (iter->value
- && (bool (want & LOOK_want::HIDDEN_LAMBDA)
- || !is_lambda_ignored_entity (iter->value))
- && qualify_lookup (iter->value, want))
- binding = iter->value;
- else if (bool (want & LOOK_want::TYPE)
- && qualify_lookup (iter->type, want))
- binding = iter->type;
- else
- binding = NULL_TREE;
-
- if (binding)
+ if (iter->value)
{
- if (TREE_CODE (binding) == TYPE_DECL && DECL_HIDDEN_P (binding))
+ tree binding = NULL_TREE;
+
+ if (!(!iter->type && HIDDEN_TYPE_BINDING_P (iter))
+ && (bool (want & LOOK_want::HIDDEN_LAMBDA)
+ || !is_lambda_ignored_entity (iter->value))
+ && qualify_lookup (iter->value, want))
+ binding = iter->value;
+ else if (bool (want & LOOK_want::TYPE)
+ && !HIDDEN_TYPE_BINDING_P (iter)
+ && iter->type)
+ binding = iter->type;
+
+ if (binding)
{
- /* A non namespace-scope binding can only be hidden in the
- presence of a local class, due to friend declarations.
-
- In particular, consider:
-
- struct C;
- void f() {
- struct A {
- friend struct B;
- friend struct C;
- void g() {
- B* b; // error: B is hidden
- C* c; // OK, finds ::C
- }
- };
- B *b; // error: B is hidden
- C *c; // OK, finds ::C
- struct B {};
- B *bb; // OK
- }
-
- The standard says that "B" is a local class in "f"
- (but not nested within "A") -- but that name lookup
- for "B" does not find this declaration until it is
- declared directly with "f".
-
- In particular:
-
- [class.friend]
-
- If a friend declaration appears in a local class and
- the name specified is an unqualified name, a prior
- declaration is looked up without considering scopes
- that are outside the innermost enclosing non-class
- scope. For a friend function declaration, if there is
- no prior declaration, the program is ill-formed. For a
- friend class declaration, if there is no prior
- declaration, the class that is specified belongs to the
- innermost enclosing non-class scope, but if it is
- subsequently referenced, its name is not found by name
- lookup until a matching declaration is provided in the
- innermost enclosing nonclass scope.
-
- So just keep looking for a non-hidden binding.
- */
- continue;
+ /* The saved lookups for an operator record 'nothing
+ found' as error_mark_node. We need to stop the search
+ here, but not return the error mark node. */
+ if (binding == error_mark_node)
+ binding = NULL_TREE;
+
+ val = binding;
+ goto found;
}
-
- /* The saved lookups for an operator record 'nothing
- found' as error_mark_node. We need to stop the search
- here, but not return the error mark node. */
- if (binding == error_mark_node)
- binding = NULL_TREE;
-
- val = binding;
- goto found;
}
}
@@ -7917,17 +7921,55 @@ lookup_elaborated_type_1 (tree name, TAG_how how)
typedef struct C {} C;
correctly. */
+ tree found = NULL_TREE;
+ bool reveal = false;
if (tree type = iter->type)
- if (qualify_lookup (type, LOOK_want::TYPE)
- && (how != TAG_how::CURRENT_ONLY
- || LOCAL_BINDING_P (iter)
- || DECL_CONTEXT (type) == iter->scope->this_entity))
- return type;
-
- if (qualify_lookup (iter->value, LOOK_want::TYPE)
- && (how != TAG_how::CURRENT_ONLY
- || !INHERITED_VALUE_BINDING_P (iter)))
- return iter->value;
+ {
+ if (qualify_lookup (type, LOOK_want::TYPE)
+ && (how != TAG_how::CURRENT_ONLY
+ || LOCAL_BINDING_P (iter)
+ || DECL_CONTEXT (type) == iter->scope->this_entity))
+ {
+ found = type;
+ if (how != TAG_how::HIDDEN_FRIEND)
+ reveal = HIDDEN_TYPE_BINDING_P (iter);
+ }
+ }
+ else
+ {
+ if (qualify_lookup (iter->value, LOOK_want::TYPE)
+ && (how != TAG_how::CURRENT_ONLY
+ || !INHERITED_VALUE_BINDING_P (iter)))
+ {
+ found = iter->value;
+ if (how != TAG_how::HIDDEN_FRIEND)
+ reveal = !iter->type && HIDDEN_TYPE_BINDING_P (iter);
+ }
+ }
+
+ if (found)
+ {
+ if (reveal)
+ {
+ /* It is no longer a hidden binding. */
+ HIDDEN_TYPE_BINDING_P (iter) = false;
+
+ /* Unanticipate the decl itself. */
+ DECL_ANTICIPATED (found) = false;
+ DECL_FRIEND_P (found) = false;
+
+ gcc_checking_assert (TREE_CODE (found) != TEMPLATE_DECL);
+
+ if (tree ti = TYPE_TEMPLATE_INFO (TREE_TYPE (found)))
+ {
+ tree tmpl = TI_TEMPLATE (ti);
+ DECL_ANTICIPATED (tmpl) = false;
+ DECL_FRIEND_P (tmpl) = false;
+ }
+ }
+
+ return found;
+ }
}
/* Now check if we can look in namespace scope. */
@@ -7942,8 +7984,10 @@ lookup_elaborated_type_1 (tree name, TAG_how how)
tree ns = b->this_entity;
if (tree *slot = find_namespace_slot (ns, name))
{
- tree bind = *slot;
+ tree found = NULL_TREE;
+ bool reveal = false;
+ tree bind = *slot;
if (TREE_CODE (bind) == MODULE_VECTOR)
bind = MODULE_VECTOR_CLUSTER (bind, 0).slots[MODULE_SLOT_CURRENT];
@@ -7951,12 +7995,67 @@ lookup_elaborated_type_1 (tree name, TAG_how how)
{
/* If this is the kind of thing we're looking for, we're done. */
if (tree type = MAYBE_STAT_TYPE (bind))
- if (qualify_lookup (type, LOOK_want::TYPE))
- return type;
+ {
+ found = type;
+ if (how != TAG_how::HIDDEN_FRIEND)
+ {
+ reveal = STAT_TYPE_HIDDEN_P (bind);
+ STAT_TYPE_HIDDEN_P (bind) = false;
+ }
+ }
+ else if (tree decl = MAYBE_STAT_DECL (bind))
+ {
+ if (qualify_lookup (decl, LOOK_want::TYPE))
+ {
+ found = decl;
- tree decl = MAYBE_STAT_DECL (*slot);
- if (qualify_lookup (decl, LOOK_want::TYPE))
- return decl;
+ if (how != TAG_how::HIDDEN_FRIEND && STAT_HACK_P (bind))
+ {
+ reveal = STAT_DECL_HIDDEN_P (bind);
+ if (reveal)
+ {
+ if (STAT_TYPE (bind))
+ STAT_DECL_HIDDEN_P (bind) = false;
+ else
+ {
+ /* There is no type, just remove the stat
+ hack. */
+ if (*slot == bind)
+ *slot = decl;
+ else
+ MODULE_VECTOR_CLUSTER (bind, 0).slots[MODULE_SLOT_CURRENT] = decl;
+ }
+ }
+ }
+ }
+ }
+
+ if (found)
+ {
+ if (reveal)
+ {
+ /* Reveal the previously hidden thing. */
+ DECL_ANTICIPATED (found) = false;
+ DECL_FRIEND_P (found) = false;
+
+ if (TREE_CODE (found) == TEMPLATE_DECL)
+ {
+ DECL_ANTICIPATED (DECL_TEMPLATE_RESULT (found)) = false;
+ DECL_FRIEND_P (DECL_TEMPLATE_RESULT (found)) = false;
+ }
+ else if (tree ti = TYPE_TEMPLATE_INFO (TREE_TYPE (found)))
+ {
+ tree tmpl = TI_TEMPLATE (ti);
+ DECL_ANTICIPATED (tmpl) = false;
+ DECL_FRIEND_P (tmpl) = false;
+ }
+#if 0
+ if (flag_modules)
+ set_instantiating_module (found);
+#endif
+ }
+ return found;
+ }
}
if (TREE_CODE (*slot) == MODULE_VECTOR)
@@ -8002,6 +8101,9 @@ lookup_elaborated_type_1 (tree name, TAG_how how)
/* Load errors could mean there's nothing here. */
continue;
+ // FIXME: if HOW is !GLOBAL, don't we need to inject
+ // this into the current tu's slot?
+
/* Extract what we can see from here. If there's no
stat_hack, then everything was exported. */
tree type = NULL_TREE;
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 7281008868d..023de39027e 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -58,6 +58,12 @@ struct cp_binding_level;
currently being defined. */
#define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited)
+/* The IMPLICIT_TYPEDEF is hidden from ordinary name lookup (it was
+ injected via a local class's friend decl). The typdef may be in the
+ VALUE or the TYPE slot. We do not get the situation where the
+ value and type slots are both filled and both hidden. */
+#define HIDDEN_TYPE_BINDING_P(NODE) ((NODE)->type_is_hidden)
+
/* Datatype that represents binding established by a declaration between
a name and a C++ entity. */
struct GTY(()) cxx_binding {
@@ -72,6 +78,7 @@ struct GTY(()) cxx_binding {
bool value_is_inherited : 1;
bool is_local : 1;
+ bool type_is_hidden : 1;
};
/* Datatype used to temporarily save C++ bindings (for implicit
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 4dbd4107393..fe1705d53aa 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2262,13 +2262,14 @@ ovl_make (tree fn, tree next)
return result;
}
-/* Add FN to the (potentially NULL) overload set OVL. USINGNESS is
- > zero if this is a using-decl. It is > 1 if we're exporting the
- using decl. We also pay attention to DECL_HIDDEN. We keep the
- hidden decls first, but remaining ones are unordered. */
+/* Add FN to the (potentially NULL) overload set OVL. USINGNESS is >
+ zero if this is a using-decl. It is > 1 if we're exporting the
+ using decl. USING_OR_HIDDEN is < 0, if FN is hidden. (A decl
+ cannot be both using and hidden.) We keep the hidden decls first,
+ but remaining ones are unordered. */
tree
-ovl_insert (tree fn, tree maybe_ovl, unsigned usingness)
+ovl_insert (tree fn, tree maybe_ovl, int using_or_hidden)
{
tree result = maybe_ovl;
tree insert_after = NULL_TREE;
@@ -2282,16 +2283,15 @@ ovl_insert (tree fn, tree maybe_ovl, unsigned usingness)
insert_after = maybe_ovl;
}
- bool hidden_p = DECL_HIDDEN_P (fn);
- if (maybe_ovl || usingness || hidden_p || TREE_CODE (fn) == TEMPLATE_DECL)
+ if (maybe_ovl || using_or_hidden || TREE_CODE (fn) == TEMPLATE_DECL)
{
maybe_ovl = ovl_make (fn, maybe_ovl);
- if (hidden_p)
+ if (using_or_hidden < 0)
OVL_HIDDEN_P (maybe_ovl) = true;
- if (usingness)
+ if (using_or_hidden > 0)
{
OVL_DEDUP_P (maybe_ovl) = OVL_USING_P (maybe_ovl) = true;
- if (usingness > 1)
+ if (using_or_hidden > 1)
OVL_EXPORT_P (maybe_ovl) = true;
}
}
@@ -2317,17 +2317,11 @@ ovl_skip_hidden (tree ovl)
for (;
ovl && TREE_CODE (ovl) == OVERLOAD && OVL_HIDDEN_P (ovl);
ovl = OVL_CHAIN (ovl))
- gcc_checking_assert (DECL_HIDDEN_P (OVL_FUNCTION (ovl)));
+ continue;
- if (ovl && TREE_CODE (ovl) != OVERLOAD && DECL_HIDDEN_P (ovl))
- {
- /* Any hidden functions should have been wrapped in an
- overload, but injected friend classes will not. */
- // FIXME: This is temporarily wrong -- consider builtin that is
- // anticipated in current TU, but known by an import
- if (!DECL_DECLARES_FUNCTION_P (ovl))
- ovl = NULL_TREE;
- }
+ /* We should not see a naked hidden decl. */
+ gcc_checking_assert (!(ovl && TREE_CODE (ovl) != OVERLOAD
+ && DECL_HIDDEN_P (ovl)));
return ovl;
}
More information about the Gcc-cvs
mailing list