diff options
Diffstat (limited to 'gcc/cp/name-lookup.cc')
| -rw-r--r-- | gcc/cp/name-lookup.cc | 85 |
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) |
