mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
3c9feefc8d
commit
945bf9e13f
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:" } }
|
||||||
|
|
@ -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" }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue