This is the first stab, I haven't written the tests yet. Feedback would be most welcome; should I put this code into a separate function? Is the minor code duplication with the regular namespace definition ok?
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 3a68dd7..00f18fb 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -16750,7 +16750,7 @@ cp_parser_namespace_definition (cp_parser* parser) tree identifier, attribs; bool has_visibility; bool is_inline; - + cp_token* token; cp_ensure_no_omp_declare_simd (parser); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE)) { @@ -16762,7 +16762,7 @@ cp_parser_namespace_definition (cp_parser* parser) is_inline = false; /* Look for the `namespace' keyword. */ - cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE); + token = cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE); /* Get the name of the namespace. We do not attempt to distinguish between an original-namespace-definition and an @@ -16776,6 +16776,33 @@ cp_parser_namespace_definition (cp_parser* parser) /* Parse any specified attributes. */ attribs = cp_parser_attributes_opt (parser); + if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)) + { + if (is_inline) + error_at (token->location, "a nested %<namespace%> definition cannot be inline"); + push_namespace (identifier); + int nest_count = 0; + while (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)) + { + cp_lexer_consume_token (parser->lexer); + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + identifier = cp_parser_identifier (parser); + else + { + cp_parser_error (parser, "nested identifier required"); + break; + } + ++nest_count; + push_namespace (identifier); + } + cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE); + cp_parser_namespace_body (parser); + while (nest_count--) + pop_namespace (); + pop_namespace (); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); + return; + } /* Look for the `{' to start the namespace. */ cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE); /* Start the namespace. */