Now that overloads are kept ordered, I can replace the existing
remove_hidden_names fn with ovl_skip_hidden.
The former works by scanning the overloads, then if it discovers a
hidden one, copying the list (from the beginning) omitting the hidden
ones. Now, overloads aren't usually huge, but this forces scanning on
every lookup, and is O(N^2), so bad. ovl_skip_hidden simply drops the
OVL_HIDDEN_P nodes at the start of an overload. Often doing nothing.
For extra badness, lookup_name_real was applying remove_hidden_names to
a result that had already had it run!
Applied to trunk.
nathan
--
Nathan Sidwell
2017-05-24 Nathan Sidwell <nat...@acm.org>
* cp-tree.h (ovl_skip_hidden): Declare.
* tree.c (ovl_skip_hidden): New.
* name-lookup.c (arg_assoc_namespace): Call ovl_skip_hidden.
(lookup_arg_dependent_1): Likewise.
(ambiguous_decl): Use DECL_HIDDEN_P, ovl_skip_hidden.
(hidden_name_p, remove_hidden_names): Delete.
(lookup_name_real_1): Do not strip hidden names.
* name-lookup.h (hidden_name_p, remove_hidden_names): Delete.
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 248422)
+++ cp/cp-tree.h (working copy)
@@ -6852,6 +6852,7 @@ extern tree ovl_make (tree fn,
tree next = NULL_TREE);
extern tree ovl_insert (tree fn, tree maybe_ovl,
bool using_p = false);
+extern tree ovl_skip_hidden (tree);
extern tree lookup_add (tree fns, tree lookup);
extern void lookup_keep (tree lookup, bool keep);
extern int is_overloaded_fn (tree);
Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c (revision 248422)
+++ cp/name-lookup.c (working copy)
@@ -275,14 +275,10 @@ arg_assoc_namespace (struct arg_lookup *
if (!value)
return false;
+ value = ovl_skip_hidden (value);
+
for (; value; value = OVL_NEXT (value))
{
- /* We don't want to find arbitrary hidden functions via argument
- dependent lookup. We only want to find friends of associated
- classes, which we'll do via arg_assoc_class. */
- if (hidden_name_p (OVL_CURRENT (value)))
- continue;
-
if (add_function (k, OVL_CURRENT (value)))
return true;
}
@@ -630,7 +626,7 @@ lookup_arg_dependent_1 (tree name, tree
/* Remove any hidden friend functions from the list of functions
found so far. They will be added back by arg_assoc_class as
appropriate. */
- fns = remove_hidden_names (fns);
+ fns = ovl_skip_hidden (fns);
k.name = name;
k.args = args;
@@ -4347,7 +4343,7 @@ ambiguous_decl (struct scope_binding *ol
/* Copy the type. */
type = new_binding->type;
if (LOOKUP_NAMESPACES_ONLY (flags)
- || (type && hidden_name_p (type) && !(flags & LOOKUP_HIDDEN)))
+ || (type && !(flags & LOOKUP_HIDDEN) && DECL_HIDDEN_P (type)))
type = NULL_TREE;
/* Copy the value. */
@@ -4355,7 +4351,7 @@ ambiguous_decl (struct scope_binding *ol
if (val)
{
if (!(flags & LOOKUP_HIDDEN))
- val = remove_hidden_names (val);
+ val = ovl_skip_hidden (val);
if (val)
switch (TREE_CODE (val))
{
@@ -4465,59 +4461,6 @@ qualify_lookup (tree val, int flags)
return true;
}
-/* Given a lookup that returned VAL, decide if we want to ignore it or
- not based on DECL_ANTICIPATED. */
-
-bool
-hidden_name_p (tree val)
-{
- if (DECL_P (val)
- && DECL_LANG_SPECIFIC (val)
- && TYPE_FUNCTION_OR_TEMPLATE_DECL_P (val)
- && DECL_ANTICIPATED (val))
- return true;
- if (TREE_CODE (val) == OVERLOAD)
- {
- for (tree o = val; o; o = OVL_CHAIN (o))
- if (!hidden_name_p (OVL_FUNCTION (o)))
- return false;
- return true;
- }
- return false;
-}
-
-/* Remove any hidden declarations from a possibly overloaded set
- of functions. */
-
-tree
-remove_hidden_names (tree fns)
-{
- if (!fns)
- return fns;
-
- if (DECL_P (fns) && hidden_name_p (fns))
- fns = NULL_TREE;
- else if (TREE_CODE (fns) == OVERLOAD)
- {
- tree o;
-
- for (o = fns; o; o = OVL_NEXT (o))
- if (hidden_name_p (OVL_CURRENT (o)))
- break;
- if (o)
- {
- tree n = NULL_TREE;
-
- for (o = fns; o; o = OVL_NEXT (o))
- if (!hidden_name_p (OVL_CURRENT (o)))
- n = lookup_add (OVL_CURRENT (o), n);
- fns = n;
- }
- }
-
- return fns;
-}
-
/* Suggest alternatives for NAME, an IDENTIFIER_NODE for which name
lookup failed. Search through all available namespaces and print out
possible candidates. If no exact matches are found, and
@@ -5337,10 +5280,6 @@ lookup_name_real_1 (tree name, int prefe
if (!val)
val = unqualified_namespace_lookup (name, flags);
- /* Anticipated built-ins and friends aren't found by normal lookup. */
- if (val && !(flags & LOOKUP_HIDDEN))
- val = remove_hidden_names (val);
-
/* If we have a single function from a using decl, pull it out. */
if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val))
val = OVL_FUNCTION (val);
Index: cp/name-lookup.h
===================================================================
--- cp/name-lookup.h (revision 248422)
+++ cp/name-lookup.h (working copy)
@@ -308,8 +308,6 @@ extern tree lookup_name_real (tree, int,
extern tree lookup_type_scope (tree, tag_scope);
extern tree get_namespace_binding (tree ns, tree id);
extern void set_global_binding (tree id, tree val);
-extern bool hidden_name_p (tree);
-extern tree remove_hidden_names (tree);
extern tree lookup_qualified_name (tree, tree, int, bool, /*hidden*/bool = false);
extern tree lookup_name_nonclass (tree);
extern tree lookup_name_innermost_nonclass_level (tree);
Index: cp/tree.c
===================================================================
--- cp/tree.c (revision 248422)
+++ cp/tree.c (working copy)
@@ -2204,6 +2204,27 @@ ovl_insert (tree fn, tree maybe_ovl, boo
return result;
}
+/* Skip any hidden names at the beginning of OVL. */
+
+tree
+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)));
+
+ 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. */
+ gcc_checking_assert (!DECL_DECLARES_FUNCTION_P (ovl));
+ ovl = NULL_TREE;
+ }
+
+ return ovl;
+}
+
/* NODE is an OVL_HIDDEN_P node which is now revealed. */
tree