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
This commit is contained in:
Nathan Sidwell 2017-05-26 18:13:53 +00:00 committed by Nathan Sidwell
parent 3c9feefc8d
commit 945bf9e13f
5 changed files with 115 additions and 35 deletions

View File

@ -1,5 +1,9 @@
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.

View File

@ -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)
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;

View File

@ -1,3 +1,8 @@
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

View File

@ -0,0 +1,46 @@
// { 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:" } }

View File

@ -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" }
{
}
}