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>
|
||||
|
||||
Implement DR2061
|
||||
* name-lookup.c (push_inline_namespaces): New.
|
||||
(push_namespace): Look inside inline namespaces.
|
||||
|
||||
Inline and using namespace representation change.
|
||||
* cp-tree.h (struct lang_decl_ns): Delete ns_using. Add usings,
|
||||
inlinees as vector.
|
||||
|
|
|
|||
|
|
@ -6057,6 +6057,23 @@ pushdecl_top_level_and_finish (tree x, tree init)
|
|||
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,
|
||||
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
|
||||
|
|
@ -6076,43 +6093,36 @@ push_namespace (tree name, bool make_inline)
|
|||
if (!name)
|
||||
name = anon_identifier;
|
||||
|
||||
/* Check whether this is an extended namespace definition. */
|
||||
tree ns = get_namespace_binding (current_namespace, name);
|
||||
if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
|
||||
{
|
||||
if (tree dna = DECL_NAMESPACE_ALIAS (ns))
|
||||
{
|
||||
/* We do some error recovery for, eg, the redeclaration of M
|
||||
here:
|
||||
|
||||
namespace N {}
|
||||
namespace M = N;
|
||||
namespace M {}
|
||||
|
||||
However, in nasty cases like:
|
||||
|
||||
namespace N
|
||||
{
|
||||
namespace M = N;
|
||||
namespace M {}
|
||||
}
|
||||
|
||||
we just error out below, in duplicate_decls. */
|
||||
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;
|
||||
tree ns = NULL_TREE;
|
||||
{
|
||||
name_lookup lookup (name, 0);
|
||||
if (!lookup.search_qualified (current_namespace, /*usings=*/false))
|
||||
;
|
||||
else if (TREE_CODE (lookup.value) != NAMESPACE_DECL)
|
||||
;
|
||||
else if (tree dna = DECL_NAMESPACE_ALIAS (lookup.value))
|
||||
{
|
||||
/* A namespace alias is not allowed here, but if the alias
|
||||
is for a namespace also inside the current scope,
|
||||
accept it with a diagnostic. That's better than dying
|
||||
horribly. */
|
||||
if (is_nested_namespace (current_namespace, CP_DECL_CONTEXT (dna)))
|
||||
{
|
||||
error ("namespace alias %qD not allowed here, "
|
||||
"assuming %qD", lookup.value, dna);
|
||||
ns = dna;
|
||||
}
|
||||
}
|
||||
else
|
||||
ns = lookup.value;
|
||||
}
|
||||
|
||||
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);
|
||||
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>
|
||||
|
||||
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 {} // { 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