diff mbox

[RFC] Implement N4230, Nested namespace definition

Message ID CAFk2RUapPR0O_rkaz2ihy20-QqNFHCXCs0QqYQdRYtOaCy5N9A@mail.gmail.com
State New
Headers show

Commit Message

Ville Voutilainen Sept. 16, 2015, 11:55 a.m. UTC
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?

Comments

Jason Merrill Sept. 17, 2015, 8:11 p.m. UTC | #1
On 09/16/2015 07:55 AM, Ville Voutilainen wrote:
> 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?

I think I'd prefer to keep it in the same function, but avoid the code 
duplication.

Jason
diff mbox

Patch

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.  */