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
This commit is contained in:
parent
27d020cf7d
commit
65cc14079e
7 changed files with 149 additions and 131 deletions
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
10
gcc/testsuite/g++.dg/lookup/strong-using.C
Normal file
10
gcc/testsuite/g++.dg/lookup/strong-using.C
Normal file
|
@ -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" "" }
|
||||
}
|
Loading…
Add table
Reference in a new issue