Commit 945bf9e1 by Nathan Sidwell Committed by Nathan Sidwell

Implement DR2061

	gcc/
	Implement DR2061
	* name-lookup.c (push_inline_namespaces): New.
	(push_namespace): Look inside inline namespaces.

	testsuite/
	* g++.dg/cpp0x/dr2061.C: New.
	* g++.dg/parse/namespace-alias-1.C: Add more test.

From-SVN: r248521
parent 3c9feefc
2017-05-26 Nathan Sidwell <nathan@acm.org> 2017-05-26 Nathan Sidwell <nathan@acm.org>
Implement DR2061
* name-lookup.c (push_inline_namespaces): New.
(push_namespace): Look inside inline namespaces.
Inline and using namespace representation change. Inline and using namespace representation change.
* cp-tree.h (struct lang_decl_ns): Delete ns_using. Add usings, * cp-tree.h (struct lang_decl_ns): Delete ns_using. Add usings,
inlinees as vector. inlinees as vector.
......
...@@ -6057,6 +6057,23 @@ pushdecl_top_level_and_finish (tree x, tree init) ...@@ -6057,6 +6057,23 @@ pushdecl_top_level_and_finish (tree x, tree init)
return x; return x;
} }
/* Enter the namespaces from current_namerspace to NS. */
static int
push_inline_namespaces (tree ns)
{
int count = 0;
if (ns != current_namespace)
{
gcc_assert (ns != global_namespace);
count += push_inline_namespaces (CP_DECL_CONTEXT (ns));
resume_scope (NAMESPACE_LEVEL (ns));
current_namespace = ns;
count++;
}
return count;
}
/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, /* Push into the scope of the NAME namespace. If NAME is NULL_TREE,
then we enter an anonymous namespace. If MAKE_INLINE is true, then then we enter an anonymous namespace. If MAKE_INLINE is true, then
we create an inline namespace (it is up to the caller to check upon we create an inline namespace (it is up to the caller to check upon
...@@ -6076,43 +6093,36 @@ push_namespace (tree name, bool make_inline) ...@@ -6076,43 +6093,36 @@ push_namespace (tree name, bool make_inline)
if (!name) if (!name)
name = anon_identifier; name = anon_identifier;
/* Check whether this is an extended namespace definition. */ tree ns = NULL_TREE;
tree ns = get_namespace_binding (current_namespace, name); {
if (ns && TREE_CODE (ns) == NAMESPACE_DECL) name_lookup lookup (name, 0);
{ if (!lookup.search_qualified (current_namespace, /*usings=*/false))
if (tree dna = DECL_NAMESPACE_ALIAS (ns)) ;
{ else if (TREE_CODE (lookup.value) != NAMESPACE_DECL)
/* We do some error recovery for, eg, the redeclaration of M ;
here: else if (tree dna = DECL_NAMESPACE_ALIAS (lookup.value))
{
namespace N {} /* A namespace alias is not allowed here, but if the alias
namespace M = N; is for a namespace also inside the current scope,
namespace M {} accept it with a diagnostic. That's better than dying
horribly. */
However, in nasty cases like: if (is_nested_namespace (current_namespace, CP_DECL_CONTEXT (dna)))
{
namespace N error ("namespace alias %qD not allowed here, "
{ "assuming %qD", lookup.value, dna);
namespace M = N; ns = dna;
namespace M {} }
} }
else
we just error out below, in duplicate_decls. */ ns = lookup.value;
if (NAMESPACE_LEVEL (dna)->level_chain == current_binding_level) }
{
error ("namespace alias %qD not allowed here, "
"assuming %qD", ns, dna);
ns = dna;
}
else
ns = NULL_TREE;
}
}
else
ns = NULL_TREE;
bool new_ns = false; bool new_ns = false;
if (!ns) if (ns)
/* DR2061. NS might be a member of an inline namespace. We
need to push into those namespaces. */
count += push_inline_namespaces (CP_DECL_CONTEXT (ns));
else
{ {
ns = build_lang_decl (NAMESPACE_DECL, name, void_type_node); ns = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
SCOPE_DEPTH (ns) = SCOPE_DEPTH (current_namespace) + 1; SCOPE_DEPTH (ns) = SCOPE_DEPTH (current_namespace) + 1;
......
2017-05-26 Nathan Sidwell <nathan@acm.org>
* g++.dg/cpp0x/dr2061.C: New.
* g++.dg/parse/namespace-alias-1.C: Add more test.
2017-05-26 Bin Cheng <bin.cheng@arm.com> 2017-05-26 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/80815 PR tree-optimization/80815
......
// { dg-do compile { target c++11 } }
// DR2061, look inside inline namespace when pushing a namespace.
inline namespace One
{
namespace Term
{
}
inline namespace Two
{
namespace Space
{
}
}
}
namespace Term
{
void bob ();
}
namespace Space
{
void bill ();
}
inline namespace Two
{
void weed ();
}
void One::Term::bob () {}
void One::Two::Space::bill () {}
void One::Two::weed () {}
void Thing ()
{
Term::bob ();
Space::bill ();
weed ();
}
// { dg-final { scan-assembler "_ZN3One4Term3bobEv:" } }
// { dg-final { scan-assembler "_ZN3One3Two5Space4billEv:" } }
// { dg-final { scan-assembler "_ZN3One3Two4weedEv:" } }
...@@ -5,3 +5,18 @@ namespace N ...@@ -5,3 +5,18 @@ namespace N
namespace M = N; // { dg-message "previous declaration" } namespace M = N; // { dg-message "previous declaration" }
namespace M {} // { dg-error "declaration of namespace" } namespace M {} // { dg-error "declaration of namespace" }
} }
namespace A
{
namespace B
{
namespace C
{
}
}
namespace D = B::C;
namespace D // { dg-error "not allowed" }
{
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment