Kill DECL_NAMESPACE_USERS, DECL_NAMESPACE_ASSOCIATIONS.
authorNathan Sidwell <nathan@acm.org>
Thu, 25 May 2017 18:52:47 +0000 (18:52 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 25 May 2017 18:52:47 +0000 (18:52 +0000)
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

12 files changed:
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/using56.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/using57.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/using58.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lookup/using59.C [new file with mode: 0644]
libcc1/ChangeLog
libcc1/libcp1plugin.cc

index 6d71bd66b38776ad9cc5092a6225b10e4e1e7409..df36ce526a4db90702122a36e30256c7a00c0ba6 100644 (file)
@@ -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
index 66bf376584c22afa37280cb142f87d75f95b1902..11f8d010dfe418b443a3fb81e27a43cdecace608 100644 (file)
@@ -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))
index d2c413ba1f8b05120bf8316aa52f0b8f38a2616f..0e3a16ca102b3fc5b66b319fb8af371efc84d8b9 100644 (file)
@@ -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;
        }
     }
 
index a2454bbcf45d52a886dd1a76817ae3154531531f..ff77517744f30107ffbe7114dd9f217b5b5171d8 100644 (file)
@@ -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);
index f11c0ae0ee3d3e49dd09f1796c683dabdd107570..c2d6b1c3c7f22f3a05c7794ec000f023f5f6f913 100644 (file)
@@ -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.
index 9df0539a14534aa45042d95a5e8e6c150b823449..f9b56296468af314a4385d6d133609a14598559c 100644 (file)
@@ -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 (file)
index 0000000..0174ed3
--- /dev/null
@@ -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 (file)
index 0000000..48ee2df
--- /dev/null
@@ -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 (file)
index 0000000..d04bce1
--- /dev/null
@@ -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 (file)
index 0000000..3c3a73c
--- /dev/null
@@ -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" }
index 1969873a1fdd5b0adad1fbd7a4a5dee913b0745d..f22ea27c9c35db9c5ea1882afe2a835a48ffb7ae 100644 (file)
@@ -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
index 7db74c737a0d778624b342b495391579fc59281f..43781adce54120cf8c2d02de2830466a0352653f 100644 (file)
@@ -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;
 }