aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/name-lookup.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/name-lookup.cc')
-rw-r--r--gcc/cp/name-lookup.cc85
1 files changed, 52 insertions, 33 deletions
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index b753061..4c07fd4 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -1338,6 +1338,7 @@ name_lookup::adl_namespace_fns (tree scope, bitmap imports,
bind = STAT_VISIBLE (bind);
}
+ bind = ovl_skip_hidden (bind);
if (on_inst_path || visible)
add_fns (bind);
else
@@ -1372,11 +1373,14 @@ name_lookup::adl_class_fns (tree type)
{
tree fn = TREE_VALUE (friends);
- /* Only interested in global functions with potentially hidden
- (i.e. unqualified) declarations. */
+ /* Before C++20, ADL just makes hidden friends visible, so we
+ only include functions in the same namespace. After C++20,
+ include all namespace-scope functions. */
if (!context)
context = decl_namespace_context (type);
- if (CP_DECL_CONTEXT (fn) != context)
+ if (cxx_dialect < cxx20
+ ? CP_DECL_CONTEXT (fn) != context
+ : !DECL_NAMESPACE_SCOPE_P (fn))
continue;
dedup (true);
@@ -4063,6 +4067,11 @@ pushdecl (tree decl, bool hiding)
}
}
+ /* Skip a hidden builtin we failed to match already. There can
+ only be one. */
+ if (old && anticipated_builtin_p (old))
+ old = OVL_CHAIN (old);
+
/* Check for redeclaring an import. */
if (slot && *slot && TREE_CODE (*slot) == BINDING_VECTOR)
if (tree match
@@ -4081,11 +4090,6 @@ pushdecl (tree decl, bool hiding)
/* We are pushing a new decl. */
- /* Skip a hidden builtin we failed to match already. There can
- only be one. */
- if (old && anticipated_builtin_p (old))
- old = OVL_CHAIN (old);
-
if (hiding)
; /* Hidden bindings don't shadow anything. */
else
@@ -5400,7 +5404,11 @@ do_nonmember_using_decl (name_lookup &lookup, bool fn_scope_p,
namespace. We will still want to insert it if
it is revealing a not-revealed thing. */
found = true;
- if (!revealing_p)
+ if (old.hidden_p ())
+ /* The function was merged with a hidden built-in;
+ insert it again as not hidden. */
+ found = false;
+ else if (!revealing_p)
;
else if (old.using_p ())
{
@@ -9007,7 +9015,8 @@ pop_nested_namespace (tree ns)
unqualified search. */
static void
-add_using_namespace (vec<tree, va_gc> *&usings, tree target)
+add_using_namespace (vec<tree, va_gc> *&usings, tree target,
+ bool imported = false)
{
/* Find if this using already exists. */
tree old = NULL_TREE;
@@ -9024,15 +9033,18 @@ add_using_namespace (vec<tree, va_gc> *&usings, tree target)
{
decl = build_lang_decl (USING_DECL, NULL_TREE, NULL_TREE);
USING_DECL_DECLS (decl) = target;
+ DECL_MODULE_IMPORT_P (decl) = imported;
}
- /* Update purviewness and exportedness in case that has changed. */
+ /* Update module flags in case that has changed. */
if (modules_p ())
{
if (module_purview_p ())
DECL_MODULE_PURVIEW_P (decl) = true;
if (module_exporting_p ())
DECL_MODULE_EXPORT_P (decl) = true;
+ if (!imported)
+ DECL_MODULE_IMPORT_P (decl) = false;
}
if (!old)
@@ -9040,13 +9052,14 @@ add_using_namespace (vec<tree, va_gc> *&usings, tree target)
}
/* Convenience overload for the above, taking the user as its first
- parameter. */
+ parameter, for use when importing a using-directive. */
void
-add_using_namespace (tree ns, tree target)
+add_imported_using_namespace (tree ns, tree target)
{
add_using_namespace (NAMESPACE_LEVEL (ns)->using_directives,
- ORIGINAL_NAMESPACE (target));
+ ORIGINAL_NAMESPACE (target),
+ /*imported=*/true);
}
/* Tell the debug system of a using directive. */
@@ -9251,6 +9264,28 @@ make_namespace_finish (tree ns, tree *slot, bool from_import = false)
add_using_namespace (NAMESPACE_LEVEL (ctx)->using_directives, ns);
}
+/* NS is a possibly-imported namespace that is now needed for
+ a declaration. Add it to the current TU's binding slot. */
+
+void
+expose_existing_namespace (tree ns)
+{
+ if (!modules_p ())
+ return;
+
+ tree bind = *find_namespace_slot (CP_DECL_CONTEXT (ns), DECL_NAME (ns));
+ if (bind != ns)
+ {
+ auto &cluster = BINDING_VECTOR_CLUSTER (bind, 0);
+ binding_slot &slot = cluster.slots[BINDING_SLOT_CURRENT];
+ gcc_checking_assert (!(tree)slot || (tree)slot == ns);
+ slot = ns;
+ }
+
+ if (module_purview_p ())
+ DECL_MODULE_PURVIEW_P (ns) = true;
+}
+
/* Push into the scope of the NAME namespace. If NAME is NULL_TREE,
then we enter an anonymous namespace. If MAKE_INLINE is true, then
we create an inline namespace (it is up to the caller to check upon
@@ -9332,25 +9367,9 @@ push_namespace (tree name, bool make_inline)
/* DR2061. NS might be a member of an inline namespace. We
need to push into those namespaces. */
if (modules_p ())
- {
- for (tree parent, ctx = ns; ctx != current_namespace;
- ctx = parent)
- {
- parent = CP_DECL_CONTEXT (ctx);
-
- tree bind = *find_namespace_slot (parent, DECL_NAME (ctx), false);
- if (bind != ctx)
- {
- auto &cluster = BINDING_VECTOR_CLUSTER (bind, 0);
- binding_slot &slot = cluster.slots[BINDING_SLOT_CURRENT];
- gcc_checking_assert (!(tree)slot || (tree)slot == ctx);
- slot = ctx;
- }
-
- if (module_purview_p ())
- DECL_MODULE_PURVIEW_P (ctx) = true;
- }
- }
+ for (tree ctx = ns; ctx != current_namespace;
+ ctx = CP_DECL_CONTEXT (ctx))
+ expose_existing_namespace (ctx);
count += push_inline_namespaces (CP_DECL_CONTEXT (ns));
if (DECL_SOURCE_LOCATION (ns) == BUILTINS_LOCATION)