From 44e00a7a1b398940c31b260b27a5f1f93d8017ed Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 25 May 2017 18:52:47 +0000 Subject: [PATCH] Kill DECL_NAMESPACE_USERS, DECL_NAMESPACE_ASSOCIATIONS. gcc/cp/ Kill DECL_NAMESPACE_USERS, DECL_NAMESPACE_ASSOCIATIONS. * cp-tree.h (lang_decl_ns): Remove ns_users field. (DECL_NAMESPACE_USERS, DECL_NAMESPACE_ASSOCIATIONS): Delete. (TREE_INDIRECT_USING): Delete. * name-lookup.h (is_associated_namespace): Delete. * name-lookup.c (name_lookup::search_usings name_lookup::do_queue_usings): Usings are always direct. (is_associated_namespace): Delete. (handle_namespace_attrs): Use DECL_NAMESPACE_INLINE_P. (namespace_ancestor_1, namespace_ancestor): Delete. (push_using_directive_1, push_using_directive): Delete. (add_using_namespace_1): Delete. (add_using_namespace): Reimplement. (emit_debug_info_using_namespace): New. (finish_namespace_using_directive, finish_local_using_directive push_namespace): Adjust. * tree.c (cp_free_lang_data): Remove DECL_NAMESPACE_USERS handling. libcc1/ * libcp1plugin.cc (plugin_make_namespace_inline): Check and set DECL_NAMESPACE_INLINE_P. gcc/testsuite/ * g++.dg/lookup/using56.C: New. * g++.dg/lookup/using57.C: New. * g++.dg/lookup/using58.C: New. * g++.dg/lookup/using59.C: New. From-SVN: r248467 --- gcc/cp/ChangeLog | 20 ++++ gcc/cp/cp-tree.h | 15 --- gcc/cp/name-lookup.c | 200 +++++----------------------------- gcc/cp/name-lookup.h | 1 - gcc/cp/tree.c | 11 +- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/g++.dg/lookup/using56.C | 16 +++ gcc/testsuite/g++.dg/lookup/using57.C | 29 +++++ gcc/testsuite/g++.dg/lookup/using58.C | 18 +++ gcc/testsuite/g++.dg/lookup/using59.C | 12 ++ libcc1/ChangeLog | 5 + libcc1/libcp1plugin.cc | 14 +-- 12 files changed, 137 insertions(+), 209 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/using56.C create mode 100644 gcc/testsuite/g++.dg/lookup/using57.C create mode 100644 gcc/testsuite/g++.dg/lookup/using58.C create mode 100644 gcc/testsuite/g++.dg/lookup/using59.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6d71bd6..df36ce5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,23 @@ +2017-05-25 Nathan Sidwell + + Kill DECL_NAMESPACE_USERS, DECL_NAMESPACE_ASSOCIATIONS. + * cp-tree.h (lang_decl_ns): Remove ns_users field. + (DECL_NAMESPACE_USERS, DECL_NAMESPACE_ASSOCIATIONS): Delete. + (TREE_INDIRECT_USING): Delete. + * name-lookup.h (is_associated_namespace): Delete. + * name-lookup.c (name_lookup::search_usings, + name_lookup::do_queue_usings): Usings are always direct. + (is_associated_namespace): Delete. + (handle_namespace_attrs): Use DECL_NAMESPACE_INLINE_P. + (namespace_ancestor_1, namespace_ancestor): Delete. + (push_using_directive_1, push_using_directive): Delete. + (add_using_namespace_1): Delete. + (add_using_namespace): Reimplement. + (emit_debug_info_using_namespace): New. + (finish_namespace_using_directive, finish_local_using_directive, + push_namespace): Adjust. + * tree.c (cp_free_lang_data): Remove DECL_NAMESPACE_USERS handling. + 2017-05-25 Volker Reichelt * semantics.c (finish_handler_parms): Warn about non-reference type diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 66bf376..11f8d01 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -328,7 +328,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; BASELINK_QUALIFIED_P (in BASELINK) TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR) TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX) - TREE_INDIRECT_USING (in a TREE_LIST of using-directives) ATTR_IS_DEPENDENT (in the TREE_LIST for an attribute) ABI_TAG_IMPLICIT (in the TREE_LIST for the argument of abi_tag) CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR) @@ -2513,7 +2512,6 @@ struct GTY(()) lang_decl_ns { struct lang_decl_base base; cp_binding_level *level; tree ns_using; - tree ns_users; }; /* DECL_LANG_SPECIFIC for parameters. */ @@ -3085,15 +3083,6 @@ struct GTY(()) lang_decl { that is the common ancestor. */ #define DECL_NAMESPACE_USING(NODE) (LANG_DECL_NS_CHECK (NODE)->ns_using) -/* In a NAMESPACE_DECL, the DECL_INITIAL is used to record all users - of a namespace, to record the transitive closure of using namespace. */ -#define DECL_NAMESPACE_USERS(NODE) (LANG_DECL_NS_CHECK (NODE)->ns_users) - -/* In a NAMESPACE_DECL, the list of namespaces which have associated - themselves with this one. */ -#define DECL_NAMESPACE_ASSOCIATIONS(NODE) \ - DECL_INITIAL (NAMESPACE_DECL_CHECK (NODE)) - /* In a NAMESPACE_DECL, points to the original namespace if this is a namespace alias. */ #define DECL_NAMESPACE_ALIAS(NODE) \ @@ -3107,10 +3096,6 @@ struct GTY(()) lang_decl { && CP_DECL_CONTEXT (NODE) == global_namespace \ && DECL_NAME (NODE) == std_identifier) -/* In a TREE_LIST concatenating using directives, indicate indirect - directives */ -#define TREE_INDIRECT_USING(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE)) - /* In a TREE_LIST in an attribute list, indicates that the attribute must be applied at instantiation time. */ #define ATTR_IS_DEPENDENT(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE)) diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index d2c413b..0e3a16c 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -533,8 +533,7 @@ name_lookup::search_usings (tree scope) /* Look in direct usings. */ for (tree usings = DECL_NAMESPACE_USING (scope); usings; usings = TREE_CHAIN (usings)) - if (!TREE_INDIRECT_USING (usings)) - found |= search_qualified (TREE_PURPOSE (usings), true); + found |= search_qualified (TREE_PURPOSE (usings), true); /* Look in its inline children. */ for (tree inner = NAMESPACE_LEVEL (scope)->namespaces; @@ -607,8 +606,7 @@ name_lookup::using_queue * name_lookup::do_queue_usings (using_queue *queue, int depth, tree usings) { for (; usings; usings = TREE_CHAIN (usings)) - if (!TREE_INDIRECT_USING (usings)) - queue = queue_namespace (queue, depth, TREE_PURPOSE (usings)); + queue = queue_namespace (queue, depth, TREE_PURPOSE (usings)); return queue; } @@ -1019,7 +1017,6 @@ static void consider_binding_level (tree name, cp_binding_level *lvl, bool look_within_fields, enum lookup_name_fuzzy_kind kind); -static tree push_using_directive (tree); static void diagnose_name_conflict (tree, tree); /* ADL lookup of NAME. FNS is the result of regular lookup, and we @@ -1036,47 +1033,6 @@ lookup_arg_dependent (tree name, tree fns, vec *args) return fns; } -/* Returns true iff CURRENT has declared itself to be an associated - namespace of SCOPE via a strong using-directive (or transitive chain - thereof). Both are namespaces. */ - -bool -is_associated_namespace (tree current, tree scope) -{ - vec *seen = make_tree_vector (); - vec *todo = make_tree_vector (); - tree t; - bool ret; - - while (1) - { - if (scope == current) - { - ret = true; - break; - } - vec_safe_push (seen, scope); - for (t = DECL_NAMESPACE_ASSOCIATIONS (scope); t; t = TREE_CHAIN (t)) - if (!vec_member (TREE_PURPOSE (t), seen)) - vec_safe_push (todo, TREE_PURPOSE (t)); - if (!todo->is_empty ()) - { - scope = todo->last (); - todo->pop (); - } - else - { - ret = false; - break; - } - } - - release_tree_vector (seen); - release_tree_vector (todo); - - return ret; -} - /* Compute the chain index of a binding_entry given the HASH value of its name and the total COUNT of chains. COUNT is assumed to be a power of 2. */ @@ -4426,15 +4382,15 @@ handle_namespace_attrs (tree ns, tree attributes) } else if (is_attribute_p ("abi_tag", name)) { - if (!DECL_NAMESPACE_ASSOCIATIONS (ns)) + if (!DECL_NAME (ns)) { - warning (OPT_Wattributes, "ignoring %qD attribute on non-inline " + warning (OPT_Wattributes, "ignoring %qD attribute on anonymous " "namespace", name); continue; } - if (!DECL_NAME (ns)) + if (!DECL_NAMESPACE_INLINE_P (ns)) { - warning (OPT_Wattributes, "ignoring %qD attribute on anonymous " + warning (OPT_Wattributes, "ignoring %qD attribute on non-inline " "namespace", name); continue; } @@ -4479,32 +4435,6 @@ pop_decl_namespace (void) decl_namespace_list->pop (); } -/* Return the namespace that is the common ancestor - of two given namespaces. */ - -static tree -namespace_ancestor_1 (tree ns1, tree ns2) -{ - tree nsr; - if (is_ancestor (ns1, ns2)) - nsr = ns1; - else - nsr = namespace_ancestor_1 (CP_DECL_CONTEXT (ns1), ns2); - return nsr; -} - -/* Wrapper for namespace_ancestor_1. */ - -static tree -namespace_ancestor (tree ns1, tree ns2) -{ - tree nsr; - bool subtime = timevar_cond_start (TV_NAME_LOOKUP); - nsr = namespace_ancestor_1 (ns1, ns2); - timevar_cond_stop (TV_NAME_LOOKUP, subtime); - return nsr; -} - /* Process a namespace-alias declaration. */ void @@ -5537,44 +5467,6 @@ is_local_extern (tree decl) return false; } -/* Add namespace to using_directives. Return NULL_TREE if nothing was - changed (i.e. there was already a directive), or the fresh - TREE_LIST otherwise. */ - -static tree -push_using_directive_1 (tree used) -{ - tree ud = current_binding_level->using_directives; - tree iter, ancestor; - - /* Check if we already have this. */ - if (purpose_member (used, ud) != NULL_TREE) - return NULL_TREE; - - ancestor = namespace_ancestor (current_decl_namespace (), used); - ud = current_binding_level->using_directives; - ud = tree_cons (used, ancestor, ud); - current_binding_level->using_directives = ud; - - /* Recursively add all namespaces used. */ - for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter)) - push_using_directive_1 (TREE_PURPOSE (iter)); - - return ud; -} - -/* Wrapper for push_using_directive_1. */ - -static tree -push_using_directive (tree used) -{ - tree ret; - bool subtime = timevar_cond_start (TV_NAME_LOOKUP); - ret = push_using_directive_1 (used); - timevar_cond_stop (TV_NAME_LOOKUP, subtime); - return ret; -} - /* The type TYPE is being declared. If it is a class template, or a specialization of a class template, do any processing required and perform error-checking. If IS_FRIEND is nonzero, this TYPE is @@ -6094,64 +5986,29 @@ do_pop_nested_namespace (tree ns) do_pop_from_top_level (); } -/* Insert USED into the using list of USER. Set INDIRECT_flag if this - directive is not directly from the source. Also find the common - ancestor and let our users know about the new namespace */ +/* Add TARGET to USINGS, if it does not already exist there. + We used to build the complete graph of usings at this point, from + the POV of the source namespaces. Now we build that as we perform + the unqualified search. */ static void -add_using_namespace_1 (tree user, tree used, bool indirect) +add_using_namespace (tree &usings, tree target) { - tree t; - /* Using oneself is a no-op. */ - if (user == used) - return; - gcc_assert (TREE_CODE (user) == NAMESPACE_DECL); - gcc_assert (TREE_CODE (used) == NAMESPACE_DECL); - /* Check if we already have this. */ - t = purpose_member (used, DECL_NAMESPACE_USING (user)); - if (t != NULL_TREE) - { - if (!indirect) - /* Promote to direct usage. */ - TREE_INDIRECT_USING (t) = 0; + for (tree probe = usings; probe; probe = TREE_CHAIN (probe)) + if (target == TREE_PURPOSE (probe)) return; - } - - /* Add used to the user's using list. */ - DECL_NAMESPACE_USING (user) - = tree_cons (used, namespace_ancestor (user, used), - DECL_NAMESPACE_USING (user)); - - TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect; - /* Add user to the used's users list. */ - DECL_NAMESPACE_USERS (used) - = tree_cons (user, 0, DECL_NAMESPACE_USERS (used)); - - /* Recursively add all namespaces used. */ - for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t)) - /* indirect usage */ - add_using_namespace_1 (user, TREE_PURPOSE (t), 1); - - /* Tell everyone using us about the new used namespaces. */ - for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t)) - add_using_namespace_1 (TREE_PURPOSE (t), used, 1); + usings = tree_cons (target, NULL_TREE, usings); } -/* Wrapper for add_using_namespace_1. */ +/* Tell the debug system of a using directive. */ static void -add_using_namespace (bool namespace_level_p, tree from, tree target) +emit_debug_info_using_namespace (tree from, tree target) { - bool subtime = timevar_cond_start (TV_NAME_LOOKUP); - add_using_namespace_1 (from, target, false); - if (namespace_level_p) - { - /* Emit debugging info. */ - tree context = from != global_namespace ? from : NULL_TREE; - debug_hooks->imported_module_or_decl (target, NULL_TREE, context, false); - } - timevar_cond_stop (TV_NAME_LOOKUP, subtime); + /* Emit debugging info. */ + tree context = from != global_namespace ? from : NULL_TREE; + debug_hooks->imported_module_or_decl (target, NULL_TREE, context, false); } /* Process a namespace-scope using directive. */ @@ -6163,8 +6020,10 @@ finish_namespace_using_directive (tree target, tree attribs) if (target == error_mark_node) return; - add_using_namespace (true, current_namespace, + add_using_namespace (DECL_NAMESPACE_USING (current_namespace), ORIGINAL_NAMESPACE (target)); + emit_debug_info_using_namespace (current_namespace, + ORIGINAL_NAMESPACE (target)); if (attribs == error_mark_node) return; @@ -6198,7 +6057,8 @@ finish_local_using_directive (tree target, tree attribs) add_stmt (build_stmt (input_location, USING_STMT, target)); - push_using_directive (ORIGINAL_NAMESPACE (target)); + add_using_namespace (current_binding_level->using_directives, + ORIGINAL_NAMESPACE (target)); } /* Pushes X into the global namespace. */ @@ -6306,20 +6166,14 @@ push_namespace (tree name, bool make_inline) DECL_NAME (ns) = NULL_TREE; if (!make_inline) - add_using_namespace (true, current_namespace, ns); + add_using_namespace (DECL_NAMESPACE_USING (current_namespace), + ns); } else if (TREE_PUBLIC (current_namespace)) TREE_PUBLIC (ns) = 1; if (make_inline) - { - DECL_NAMESPACE_INLINE_P (ns) = true; - /* Set up namespace association. */ - DECL_NAMESPACE_ASSOCIATIONS (ns) - = tree_cons (current_namespace, NULL_TREE, NULL_TREE); - /* Import the contents of the inline namespace. */ - add_using_namespace (true, current_namespace, ns); - } + DECL_NAMESPACE_INLINE_P (ns) = true; } } diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index a2454bb..ff77517 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -325,7 +325,6 @@ extern void do_namespace_alias (tree, tree); extern tree do_class_using_decl (tree, tree); extern void do_using_directive (tree); extern tree lookup_arg_dependent (tree, tree, vec *); -extern bool is_associated_namespace (tree, tree); extern tree innermost_non_namespace_value (tree); extern cxx_binding *outer_binding (tree, cxx_binding *, bool); extern void cp_emit_debug_info_for_using (tree, tree); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index f11c0ae..c2d6b1c 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -5123,14 +5123,9 @@ cp_free_lang_data (tree t) TREE_STATIC (t) = 0; } if (TREE_CODE (t) == NAMESPACE_DECL) - { - /* The list of users of a namespace isn't useful for the middle-end - or debug generators. */ - DECL_NAMESPACE_USERS (t) = NULL_TREE; - /* Neither do we need the leftover chaining of namespaces - from the binding level. */ - DECL_CHAIN (t) = NULL_TREE; - } + /* We do not need the leftover chaining of namespaces from the + binding level. */ + DECL_CHAIN (t) = NULL_TREE; } /* Stub for c-common. Please keep in sync with c-decl.c. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9df0539..f9b5629 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -6,6 +6,11 @@ 2017-05-25 Nathan Sidwell + * g++.dg/lookup/using56.C: New. + * g++.dg/lookup/using57.C: New. + * g++.dg/lookup/using58.C: New. + * g++.dg/lookup/using59.C: New. + * g++.dg/lookup/using17.C: Adjust diagnostics. 2017-05-25 Martin Sebor diff --git a/gcc/testsuite/g++.dg/lookup/using56.C b/gcc/testsuite/g++.dg/lookup/using56.C new file mode 100644 index 0000000..0174ed3 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/using56.C @@ -0,0 +1,16 @@ + +// The anticipated decl for 'log' got retained, leading to confusion */ + +extern double log (double) throw (); + +namespace std +{ + using ::log; + float log (float) throw (); + long double log (long double) throw (); +} + +void Foo (double x) +{ + std::log (x); +} diff --git a/gcc/testsuite/g++.dg/lookup/using57.C b/gcc/testsuite/g++.dg/lookup/using57.C new file mode 100644 index 0000000..48ee2df --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/using57.C @@ -0,0 +1,29 @@ +// Addr of function from multiple namespaces + +namespace X +{ + void Foo (int); + void Foo (short); +} + +namespace Y +{ + void Foo (float); + void Foo (double); +} + +template void Foo (T *); + +using namespace X; + +using namespace Y; + +void (*(Baz ())) (float) +{ + return Foo; +} + +void (*(Bar ())) (void *) +{ + return Foo; +} diff --git a/gcc/testsuite/g++.dg/lookup/using58.C b/gcc/testsuite/g++.dg/lookup/using58.C new file mode 100644 index 0000000..d04bce1 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/using58.C @@ -0,0 +1,18 @@ + + +void Foo (int); +void Foo (double); + +namespace Y +{ + void Baz (int); // { dg-message "previous declaration" } +} + +void X () +{ + using ::Foo; + extern void Foo (int); + + using Y::Baz; + extern void Baz (int); // { dg-error "conflicts with" } +} diff --git a/gcc/testsuite/g++.dg/lookup/using59.C b/gcc/testsuite/g++.dg/lookup/using59.C new file mode 100644 index 0000000..3c3a73c --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/using59.C @@ -0,0 +1,12 @@ + +namespace Y +{ + extern int I; // { dg-message "previous declaration" } +} + +using Y::I; +extern int I; // { dg-error "conflicts with a previous" } + +extern int J; +extern int J; // { dg-message "previous declaration" } +extern char J; // { dg-error "conflicting declaration" } diff --git a/libcc1/ChangeLog b/libcc1/ChangeLog index 1969873..f22ea27 100644 --- a/libcc1/ChangeLog +++ b/libcc1/ChangeLog @@ -1,3 +1,8 @@ +2017-05-25 Nathan Sidwell + + * libcp1plugin.cc (plugin_make_namespace_inline): Check and set + DECL_NAMESPACE_INLINE_P. + 2017-05-23 Nathan Sidwell * libcp1plugin.cc (plugin_add_using_decl): Call diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc index 7db74c7..43781ad 100644 --- a/libcc1/libcp1plugin.cc +++ b/libcc1/libcp1plugin.cc @@ -930,20 +930,10 @@ plugin_make_namespace_inline (cc1_plugin::connection *) tree parent_ns = CP_DECL_CONTEXT (inline_ns); - if (purpose_member (DECL_NAMESPACE_ASSOCIATIONS (inline_ns), - parent_ns)) + if (DECL_NAMESPACE_INLINE_P (inline_ns)) return 0; - pop_namespace (); - - gcc_assert (current_namespace == parent_ns); - - DECL_NAMESPACE_ASSOCIATIONS (inline_ns) - = tree_cons (parent_ns, 0, - DECL_NAMESPACE_ASSOCIATIONS (inline_ns)); - do_using_directive (inline_ns); - - push_namespace (DECL_NAME (inline_ns)); + DECL_NAMESPACE_INLINE_P (inline_ns) = true; return 1; } -- 2.7.4