summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-05-25 18:52:47 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-05-25 18:52:47 +0000
commit44e00a7a1b398940c31b260b27a5f1f93d8017ed (patch)
tree46ae0e24e642ec27a2a21ca827419c7f58cb282a
parent63dbcd13e93578e21e0717d4990c1701d6957e3e (diff)
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
-rw-r--r--gcc/cp/ChangeLog20
-rw-r--r--gcc/cp/cp-tree.h15
-rw-r--r--gcc/cp/name-lookup.c200
-rw-r--r--gcc/cp/name-lookup.h1
-rw-r--r--gcc/cp/tree.c11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/lookup/using56.C16
-rw-r--r--gcc/testsuite/g++.dg/lookup/using57.C29
-rw-r--r--gcc/testsuite/g++.dg/lookup/using58.C18
-rw-r--r--gcc/testsuite/g++.dg/lookup/using59.C12
-rw-r--r--libcc1/ChangeLog5
-rw-r--r--libcc1/libcp1plugin.cc14
12 files changed, 137 insertions, 209 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6d71bd66b38..df36ce526a4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,23 @@
+2017-05-25 Nathan Sidwell <nathan@acm.org>
+
+ 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 <v.reichelt@netcologne.de>
* 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 66bf376584c..11f8d010dfe 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 d2c413ba1f8..0e3a16ca102 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<tree, va_gc> *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<tree, va_gc> *seen = make_tree_vector ();
- vec<tree, va_gc> *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 a2454bbcf45..ff77517744f 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<tree, va_gc> *);
-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 f11c0ae0ee3..c2d6b1c3c7f 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 9df0539a145..f9b56296468 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -6,6 +6,11 @@
2017-05-25 Nathan Sidwell <nathan@acm.org>
+ * 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 <msebor@redhat.com>
diff --git a/gcc/testsuite/g++.dg/lookup/using56.C b/gcc/testsuite/g++.dg/lookup/using56.C
new file mode 100644
index 00000000000..0174ed33eac
--- /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 00000000000..48ee2df9bc9
--- /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 <typename T> 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 00000000000..d04bce1e91f
--- /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 00000000000..3c3a73c28d5
--- /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 1969873a1fd..f22ea27c9c3 100644
--- a/libcc1/ChangeLog
+++ b/libcc1/ChangeLog
@@ -1,3 +1,8 @@
+2017-05-25 Nathan Sidwell <nathan@acm.org>
+
+ * libcp1plugin.cc (plugin_make_namespace_inline): Check and set
+ DECL_NAMESPACE_INLINE_P.
+
2017-05-23 Nathan Sidwell <nathan@acm.org>
* libcp1plugin.cc (plugin_add_using_decl): Call
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 7db74c737a0..43781adce54 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;
}