Implement P1094R2, Nested inline namespaces.
* parser.c (cp_parser_namespace_definition): Parse the optional inline keyword in a nested-namespace-definition. Adjust push_namespace call. Formatting fix. * g++.dg/cpp2a/nested-inline-ns1.C: New test. * g++.dg/cpp2a/nested-inline-ns2.C: New test. From-SVN: r266592
This commit is contained in:
parent
d794ab85f7
commit
3b9a9fe89f
|
@ -1,3 +1,10 @@
|
|||
2018-11-28 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
Implement P1094R2, Nested inline namespaces.
|
||||
* parser.c (cp_parser_namespace_definition): Parse the optional inline
|
||||
keyword in a nested-namespace-definition. Adjust push_namespace call.
|
||||
Formatting fix.
|
||||
|
||||
2018-11-28 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
PR c++/87531
|
||||
|
|
|
@ -19004,6 +19004,7 @@ cp_parser_namespace_definition (cp_parser* parser)
|
|||
cp_ensure_no_oacc_routine (parser);
|
||||
|
||||
bool is_inline = cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE);
|
||||
const bool topmost_inline_p = is_inline;
|
||||
|
||||
if (is_inline)
|
||||
{
|
||||
|
@ -19022,6 +19023,17 @@ cp_parser_namespace_definition (cp_parser* parser)
|
|||
{
|
||||
identifier = NULL_TREE;
|
||||
|
||||
bool nested_inline_p = cp_lexer_next_token_is_keyword (parser->lexer,
|
||||
RID_INLINE);
|
||||
if (nested_inline_p && nested_definition_count != 0)
|
||||
{
|
||||
if (cxx_dialect < cxx2a)
|
||||
pedwarn (cp_lexer_peek_token (parser->lexer)->location,
|
||||
OPT_Wpedantic, "nested inline namespace definitions only "
|
||||
"available with -std=c++2a or -std=gnu++2a");
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
}
|
||||
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
|
||||
{
|
||||
identifier = cp_parser_identifier (parser);
|
||||
|
@ -19036,7 +19048,14 @@ cp_parser_namespace_definition (cp_parser* parser)
|
|||
}
|
||||
|
||||
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE))
|
||||
break;
|
||||
{
|
||||
/* Don't forget that the innermost namespace might have been
|
||||
marked as inline. Use |= because we cannot overwrite
|
||||
IS_INLINE in case the outermost namespace is inline, but
|
||||
there are no nested inlines. */
|
||||
is_inline |= nested_inline_p;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!nested_definition_count && cxx_dialect < cxx17)
|
||||
pedwarn (input_location, OPT_Wpedantic,
|
||||
|
@ -19045,7 +19064,9 @@ cp_parser_namespace_definition (cp_parser* parser)
|
|||
|
||||
/* Nested namespace names can create new namespaces (unlike
|
||||
other qualified-ids). */
|
||||
if (int count = identifier ? push_namespace (identifier) : 0)
|
||||
if (int count = (identifier
|
||||
? push_namespace (identifier, nested_inline_p)
|
||||
: 0))
|
||||
nested_definition_count += count;
|
||||
else
|
||||
cp_parser_error (parser, "nested namespace name required");
|
||||
|
@ -19058,7 +19079,7 @@ cp_parser_namespace_definition (cp_parser* parser)
|
|||
if (nested_definition_count && attribs)
|
||||
error_at (token->location,
|
||||
"a nested namespace definition cannot have attributes");
|
||||
if (nested_definition_count && is_inline)
|
||||
if (nested_definition_count && topmost_inline_p)
|
||||
error_at (token->location,
|
||||
"a nested namespace definition cannot be inline");
|
||||
|
||||
|
@ -19067,7 +19088,7 @@ cp_parser_namespace_definition (cp_parser* parser)
|
|||
|
||||
bool has_visibility = handle_namespace_attrs (current_namespace, attribs);
|
||||
|
||||
warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace);
|
||||
warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace);
|
||||
|
||||
/* Look for the `{' to validate starting the namespace. */
|
||||
matching_braces braces;
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2018-11-28 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
Implement P1094R2, Nested inline namespaces.
|
||||
* g++.dg/cpp2a/nested-inline-ns1.C: New test.
|
||||
* g++.dg/cpp2a/nested-inline-ns2.C: New test.
|
||||
|
||||
2018-11-28 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
PR c++/87531
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// P1094R2
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-options "-Wpedantic" }
|
||||
|
||||
namespace A::inline B::C { // { dg-warning "nested inline namespace definitions only" "" { target c++17_down } }
|
||||
// { dg-warning "nested namespace definitions only available" "" { target c++14_down } .-1 }
|
||||
int i;
|
||||
}
|
||||
|
||||
namespace D::E::inline F { // { dg-warning "nested inline namespace definitions only" "" { target c++17_down } }
|
||||
// { dg-warning "nested namespace definitions only available" "" { target c++14_down } .-1 }
|
||||
int j;
|
||||
}
|
||||
|
||||
inline namespace X {
|
||||
int x;
|
||||
}
|
||||
|
||||
// Make sure the namespaces are marked inline.
|
||||
void
|
||||
g ()
|
||||
{
|
||||
A::B::C::i++;
|
||||
A::C::i++;
|
||||
D::E::j++;
|
||||
D::E::F::j++;
|
||||
X::x++;
|
||||
x++;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// P1094R2
|
||||
// { dg-do compile { target c++2a } }
|
||||
|
||||
inline namespace A::B { // { dg-error "a nested namespace definition cannot be inline" }
|
||||
int i;
|
||||
}
|
||||
|
||||
namespace inline C::D { // { dg-error "expected|does not name a type" }
|
||||
int i;
|
||||
}
|
||||
|
||||
namespace E::F inline { // { dg-error "expected" }
|
||||
int i;
|
||||
}
|
||||
|
||||
namespace inline G { // { dg-error "expected|does not name a type" }
|
||||
int i;
|
||||
}
|
||||
|
||||
inline namespace inline H { // { dg-error "expected|does not name a type" }
|
||||
int i;
|
||||
}
|
||||
|
||||
inline namespace inline I::J { // { dg-error "expected|does not name a type" }
|
||||
int i;
|
||||
}
|
Loading…
Reference in New Issue