name-lookup.h (parse_using_directive): Replace with ...
authorNathan Sidwell <nathan@acm.org>
Mon, 22 May 2017 16:00:35 +0000 (16:00 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Mon, 22 May 2017 16:00:35 +0000 (16:00 +0000)
* name-lookup.h (parse_using_directive): Replace with ...
(finish_namespace_using_directive): ... this and ...
(finish_local_using_directive): ... this.
* name-lookup.c (add_using_namespace_1): Move later.
(add_using_namespace): Move later, add namespace_p arg, remove
indirect arg.
(push_using_directive_1): Directly recurse.
(do_using_directive, parse_using_directive): Delete, split into
...
(finish_namespace_using_directive): ... this and ...
(finish_local_using_directive): ... this.
(push_namespace): Use add_using_namespace.
* parser.c (cp_parser_using_directive): Call
finish_namespace_using_directive or finish_local_using_directive.
* pt.c (tsubst_expr): Call finish_local_using_directive.

From-SVN: r248337

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/strong-using.C [new file with mode: 0644]

index 8b272c84d25f3c06730666ca686d69adc163dc5a..ba03324ee8173731f5179e50f4761490155d280f 100644 (file)
@@ -1,5 +1,20 @@
 2017-05-22  Nathan Sidwell  <nathan@acm.org>
 
+       * name-lookup.h (parse_using_directive): Replace with ...
+       (finish_namespace_using_directive): ... this and ...
+       (finish_local_using_directive): ... this.
+       * name-lookup.c (add_using_namespace_1): Move later.
+       (add_using_namespace): Move later, add namespace_p arg, remove
+       indirect arg.
+       (push_using_directive_1): Directly recurse.
+       (do_using_directive, parse_using_directive): Delete, split into ...
+       (finish_namespace_using_directive): ... this and ...
+       (finish_local_using_directive): ... this.
+       (push_namespace): Use add_using_namespace.
+       * parser.c (cp_parser_using_directive): Call
+       finish_namespace_using_directive or finish_local_using_directive.
+       * pt.c (tsubst_expr): Call finish_local_using_directive.
+
        * cp-objcp-common.c (cp_register_dumps): Register raw dumper.
        * cp-tree.h (raw_dump_id): Declare.
        * decl2.c (raw_dump_id): Define.
index e0c2c6a666bdf5863ece0b8c7955a5779be9a173..7178932e25f983f1b720a8e0d0cb3e3005bcfbcf 100644 (file)
@@ -4337,60 +4337,6 @@ pushdecl_namespace_level (tree x, bool is_friend)
   return t;
 }
 
-/* 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 */
-
-static void
-add_using_namespace_1 (tree user, tree used, bool indirect)
-{
-  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;
-      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);
-}
-
-/* Wrapper for add_using_namespace_1.  */
-
-static void
-add_using_namespace (tree user, tree used, bool indirect)
-{
-  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
-  add_using_namespace_1 (user, used, indirect);
-  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
-}
-
 /* Process a using-declaration not appearing in class or local scope.  */
 
 void
@@ -4422,75 +4368,6 @@ do_toplevel_using_decl (tree decl, tree scope, tree name)
     binding->type = newtype;
 }
 
-/* Process a using-directive.  */
-
-void
-do_using_directive (tree name_space)
-{
-  tree context = NULL_TREE;
-
-  if (name_space == error_mark_node)
-    return;
-
-  gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
-
-  if (building_stmt_list_p ())
-    add_stmt (build_stmt (input_location, USING_STMT, name_space));
-  name_space = ORIGINAL_NAMESPACE (name_space);
-
-  if (!toplevel_bindings_p ())
-    {
-      push_using_directive (name_space);
-    }
-  else
-    {
-      /* direct usage */
-      add_using_namespace (current_namespace, name_space, 0);
-      if (current_namespace != global_namespace)
-       context = current_namespace;
-
-      /* Emit debugging info.  */
-      if (!processing_template_decl)
-       (*debug_hooks->imported_module_or_decl) (name_space, NULL_TREE,
-                                                context, false);
-    }
-}
-
-/* Deal with a using-directive seen by the parser.  Currently we only
-   handle attributes here, since they cannot appear inside a template.  */
-
-void
-parse_using_directive (tree name_space, tree attribs)
-{
-  do_using_directive (name_space);
-
-  if (attribs == error_mark_node)
-    return;
-
-  for (tree a = attribs; a; a = TREE_CHAIN (a))
-    {
-      tree name = get_attribute_name (a);
-      if (is_attribute_p ("strong", name))
-       {
-         warning (OPT_Wdeprecated, "strong using is deprecated; use inline "
-                  "namespaces instead");
-         if (!toplevel_bindings_p ())
-           error ("strong using only meaningful at namespace scope");
-         else if (name_space != error_mark_node)
-           {
-             if (!is_ancestor (current_namespace, name_space))
-               error ("current namespace %qD does not enclose strongly used namespace %qD",
-                      current_namespace, name_space);
-             DECL_NAMESPACE_ASSOCIATIONS (name_space)
-               = tree_cons (current_namespace, 0,
-                            DECL_NAMESPACE_ASSOCIATIONS (name_space));
-           }
-       }
-      else
-       warning (OPT_Wattributes, "%qD attribute directive ignored", name);
-    }
-}
-
 /* Combines two sets of overloaded functions into an OVERLOAD chain, removing
    duplicates.  The first list becomes the tail of the result.
 
@@ -5827,7 +5704,7 @@ push_using_directive_1 (tree used)
 
   /* Recursively add all namespaces used.  */
   for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
-    push_using_directive (TREE_PURPOSE (iter));
+    push_using_directive_1 (TREE_PURPOSE (iter));
 
   return ud;
 }
@@ -6363,6 +6240,113 @@ 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 */
+
+static void
+add_using_namespace_1 (tree user, tree used, bool indirect)
+{
+  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;
+      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);
+}
+
+/* Wrapper for add_using_namespace_1.  */
+
+static void
+add_using_namespace (bool namespace_level_p, 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);
+}
+
+/* Process a namespace-scope using directive.  */
+
+void
+finish_namespace_using_directive (tree target, tree attribs)
+{
+  gcc_checking_assert (namespace_bindings_p ());
+  if (target == error_mark_node)
+    return;
+
+  add_using_namespace (true, current_namespace,
+                      ORIGINAL_NAMESPACE (target));
+
+  if (attribs == error_mark_node)
+    return;
+
+  for (tree a = attribs; a; a = TREE_CHAIN (a))
+    {
+      tree name = get_attribute_name (a);
+      if (is_attribute_p ("strong", name))
+       {
+         warning (0, "strong using directive no longer supported");
+         if (CP_DECL_CONTEXT (target) == current_namespace)
+           inform (DECL_SOURCE_LOCATION (target),
+                   "you may use an inline namespace instead");
+       }
+      else
+       warning (OPT_Wattributes, "%qD attribute directive ignored", name);
+    }
+}
+
+/* Process a function-scope using-directive.  */
+
+void
+finish_local_using_directive (tree target, tree attribs)
+{
+  gcc_checking_assert (local_bindings_p ());
+  if (target == error_mark_node)
+    return;
+
+  if (attribs)
+    warning (OPT_Wattributes, "attributes ignored on local using directive");
+
+  add_stmt (build_stmt (input_location, USING_STMT, target));
+
+  push_using_directive (ORIGINAL_NAMESPACE (target));
+}
+
 /* Pushes X into the global namespace.  */
 
 tree
@@ -6468,7 +6452,7 @@ push_namespace (tree name, bool make_inline)
              DECL_NAME (ns) = NULL_TREE;
 
              if (!make_inline)
-               do_using_directive (ns);
+               add_using_namespace (true, current_namespace, ns);
            }
          else if (TREE_PUBLIC (current_namespace))
            TREE_PUBLIC (ns) = 1;
@@ -6480,7 +6464,7 @@ push_namespace (tree name, bool make_inline)
              DECL_NAMESPACE_ASSOCIATIONS (ns)
                = tree_cons (current_namespace, NULL_TREE, NULL_TREE);
              /* Import the contents of the inline namespace.  */
-             do_using_directive (ns);
+             add_using_namespace (true, current_namespace, ns);
            }
        }
     }
@@ -6525,8 +6509,6 @@ push_to_top_level (void)
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
 
-/* Wrapper for pop_from_top_level_1.  */
-
 void
 pop_from_top_level (void)
 {
index 4d0fe632093763956040c2b045a375701b8d41aa..84ab2065337db50507aeb0b05cceab2505e26df1 100644 (file)
@@ -332,11 +332,12 @@ extern tree do_class_using_decl (tree, tree);
 extern void do_using_directive (tree);
 extern cp_expr lookup_arg_dependent (tree, tree, vec<tree, va_gc> *);
 extern bool is_associated_namespace (tree, tree);
-extern void parse_using_directive (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);
 
+extern void finish_namespace_using_directive (tree, tree);
+extern void finish_local_using_directive (tree, tree);
 extern tree pushdecl_outermost_localscope (tree);
 extern tree pushdecl (tree, bool is_friend = false);
 extern tree pushdecl_top_level (tree, bool is_friend = false);
index c89dc438d5d6a9ffc01ed6ab6bcc207f3d8574bc..cdde7a0bf3eed17703500952db1666f9d9967c01 100644 (file)
@@ -18692,8 +18692,13 @@ cp_parser_using_directive (cp_parser* parser)
   namespace_decl = cp_parser_namespace_name (parser);
   /* And any specified attributes.  */
   attribs = cp_parser_attributes_opt (parser);
+
   /* Update the symbol table.  */
-  parse_using_directive (namespace_decl, attribs);
+  if (namespace_bindings_p ())
+    finish_namespace_using_directive (namespace_decl, attribs);
+  else
+    finish_local_using_directive (namespace_decl, attribs);
+
   /* Look for the final `;'.  */
   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 }
index 367e58d336871d64b34f97f68f9bebfd218f5204..f9980fef99127b1ffd085e088c50e5fc1220d3f1 100644 (file)
@@ -15672,7 +15672,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       break;
 
     case USING_STMT:
-      do_using_directive (USING_STMT_NAMESPACE (t));
+      finish_local_using_directive (USING_STMT_NAMESPACE (t),
+                                   /*attribs=*/NULL_TREE);
       break;
 
     case DECL_EXPR:
index c19e4713c0c4e33314f76f709757fce4a1083e65..e162c862e43aad4d2e1983da464cab78b66375c8 100644 (file)
@@ -1,3 +1,7 @@
+2017-05-22  Nathan Sidwell  <nathan@acm.org>
+
+       * g++.dg/lookup/strong-using.C: New.
+
 2017-05-22  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
        * gcc.target/arm/movsi_movt.c: New test.
diff --git a/gcc/testsuite/g++.dg/lookup/strong-using.C b/gcc/testsuite/g++.dg/lookup/strong-using.C
new file mode 100644 (file)
index 0000000..9d58fdd
--- /dev/null
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++11 } }
+
+namespace A
+{
+  namespace B // { dg-message "inline namespace" }
+  {
+  }
+
+  using namespace B __attribute__ ((strong)); // { dg-warning "no longer supported" "" }
+}