aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-05-22 16:00:35 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-05-22 16:00:35 +0000
commit65cc14079e114bbc95843b11343aae6507ef2088 (patch)
tree4858d389a0129aa43164c26a93acbfa89e0b1404 /gcc
parent27d020cf7db55e3cc9517a8bc79e14644f54bd5a (diff)
downloadgcc-65cc14079e114bbc95843b11343aae6507ef2088.zip
gcc-65cc14079e114bbc95843b11343aae6507ef2088.tar.gz
gcc-65cc14079e114bbc95843b11343aae6507ef2088.tar.bz2
name-lookup.h (parse_using_directive): Replace with ...
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/name-lookup.c238
-rw-r--r--gcc/cp/name-lookup.h3
-rw-r--r--gcc/cp/parser.c7
-rw-r--r--gcc/cp/pt.c3
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/lookup/strong-using.C10
7 files changed, 149 insertions, 131 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8b272c8..ba03324 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index e0c2c6a..7178932 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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)
{
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 4d0fe63..84ab206 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -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);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c89dc43..cdde7a0 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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);
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 367e58d..f9980fe 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c19e471..e162c86 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..9d58fdd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/strong-using.C
@@ -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" "" }
+}