diff mbox

[C++] Complete the implementation of N4230, Nested namespace definition.

Message ID CAFk2RUZhehktzawhTQ9K1H5HPffOR6T7xrGijOW2VbOZxDdMvA@mail.gmail.com
State New
Headers show

Commit Message

Ville Voutilainen Sept. 20, 2015, 9:08 p.m. UTC
Tested on Linux-PPC64.

/c-family
2015-09-20  Ville Voutilainen  <ville.voutilainen@gmail.com>

    Complete the implementation of N4230, Nested namespace definition.
    * c-cppbuiltin.c: Add __cpp_namespace_attributes and
    __cpp_nested_namespace_definitions.

/cp
2015-09-20  Ville Voutilainen  <ville.voutilainen@gmail.com>

    Complete the implementation of N4230, Nested namespace definition.
    * parser.c (cp_parser_namespace_definition): Support namespace
    attributes both before and after the namespace identifier.

/testsuite
2015-09-20  Ville Voutilainen  <ville.voutilainen@gmail.com>

    Complete the implementation of N4230, Nested namespace definition.
    * g++.dg/cpp1y/feat-cxx11-neg.C: Add tests for C++17 namespace
    attributes and nested namespace definitions.
    * g++.dg/cpp1y/feat-cxx98-neg.C: Likewise.
    * g++.dg/cpp1z/feat-cxx1z.C: Likewise.
    * g++.dg/cpp1y/feat-cxx14-neg.C: New.
    * g++.dg/cpp1z/namespace-attribs.C: Likewise.
    * g++.dg/cpp1z/nested-namespace-def1.C: Add tests for attributes
    appearing before the namespace identifier.
diff mbox

Patch

diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index 0e45a57..b222a9f 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -870,6 +870,8 @@  c_cpp_builtins (cpp_reader *pfile)
 	{
 	  /* Set feature test macros for C++1z.  */
 	  cpp_define (pfile, "__cpp_static_assert=201411");
+	  cpp_define (pfile, "__cpp_namespace_attributes=201411");
+	  cpp_define (pfile, "__cpp_nested_namespace_definitions=201411");
 	}
       if (flag_concepts)
 	/* Use a value smaller than the 201507 specified in
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 2071276..ffea989 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -11645,6 +11645,9 @@  cp_parser_declaration (cp_parser* parser)
 	       (token2.type == CPP_NAME
 		&& (cp_lexer_peek_nth_token (parser->lexer, 3)->type
 		    != CPP_EQ))
+               || (token2.type == CPP_OPEN_SQUARE
+                   && cp_lexer_peek_nth_token (parser->lexer, 2)->type
+                   == CPP_OPEN_SQUARE)
 	       /* An unnamed namespace definition.  */
 	       || token2.type == CPP_OPEN_BRACE
 	       || token2.keyword == RID_ATTRIBUTE))
@@ -16969,6 +16972,9 @@  cp_parser_namespace_definition (cp_parser* parser)
   /* Look for the `namespace' keyword.  */
   token = cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
 
+  /* Parse any specified attributes before the identifier.  */
+  attribs = cp_parser_attributes_opt (parser);
+
   /* Get the name of the namespace.  We do not attempt to distinguish
      between an original-namespace-definition and an
      extension-namespace-definition at this point.  The semantic
@@ -16978,8 +16984,15 @@  cp_parser_namespace_definition (cp_parser* parser)
   else
     identifier = NULL_TREE;
 
-  /* Parse any specified attributes.  */
-  attribs = cp_parser_attributes_opt (parser);
+  /* Parse any specified attributes after the identifier.  */
+  tree post_ident_attribs = cp_parser_attributes_opt (parser);
+  if (post_ident_attribs)
+    {
+      if (attribs)
+        attribs = chainon (attribs, post_ident_attribs);
+      else
+        attribs = post_ident_attribs;
+    }
 
   /* Start the namespace.  */
   push_namespace (identifier);
diff --git a/gcc/testsuite/g++.dg/cpp1y/feat-cxx11-neg.C b/gcc/testsuite/g++.dg/cpp1y/feat-cxx11-neg.C
index 81daa04..825d088 100644
--- a/gcc/testsuite/g++.dg/cpp1y/feat-cxx11-neg.C
+++ b/gcc/testsuite/g++.dg/cpp1y/feat-cxx11-neg.C
@@ -38,6 +38,17 @@ 
 #  error "__cpp_sized_deallocation" // { dg-error "error" }
 #endif
 
+// C++17 features:
+
+#ifndef __cpp_namespace_attributes
+#  error "__cpp_namespace_attributes" // { dg-error "error" }
+#endif
+
+#ifndef __cpp_nested_namespace_definitions
+#  error "__cpp_nested_namespace_definitions" // { dg-error "error" }
+#endif
+
+
 //  Array TS features:
 
 #ifndef __cpp_runtime_arrays
diff --git a/gcc/testsuite/g++.dg/cpp1y/feat-cxx14-neg.C b/gcc/testsuite/g++.dg/cpp1y/feat-cxx14-neg.C
new file mode 100644
index 0000000..221bd3f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/feat-cxx14-neg.C
@@ -0,0 +1,11 @@ 
+// { dg-do compile { target c++14 } }
+
+// C++17 features:
+
+#ifndef __cpp_namespace_attributes
+#  error "__cpp_namespace_attributes" // { dg-error "error" }
+#endif
+
+#ifndef __cpp_nested_namespace_definitions
+#  error "__cpp_nested_namespace_definitions" // { dg-error "error" }
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp1y/feat-cxx98-neg.C b/gcc/testsuite/g++.dg/cpp1y/feat-cxx98-neg.C
index 9c25fc3..886b3d3 100644
--- a/gcc/testsuite/g++.dg/cpp1y/feat-cxx98-neg.C
+++ b/gcc/testsuite/g++.dg/cpp1y/feat-cxx98-neg.C
@@ -113,6 +113,16 @@ 
 #  error "__cpp_sized_deallocation" // { dg-error "error" }
 #endif
 
+// C++17 features:
+
+#ifndef __cpp_namespace_attributes
+#  error "__cpp_namespace_attributes" // { dg-error "error" }
+#endif
+
+#ifndef __cpp_nested_namespace_definitions
+#  error "__cpp_nested_namespace_definitions" // { dg-error "error" }
+#endif
+
 //  C++11 attributes:
 
 #ifdef __has_cpp_attribute
diff --git a/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C b/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C
index b3e742c..ead1665 100644
--- a/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C
+++ b/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C
@@ -6,3 +6,15 @@ 
 #elif __cpp_static_assert != 201411
 #  error "__cpp_static_assert != 201411"
 #endif
+
+#ifndef __cpp_namespace_attributes
+#  error "__cpp_namespace_attributes"
+#elif __cpp_namespace_attributes != 201411
+#  error "__cpp_namespace_attributes != 201411"
+#endif
+
+#ifndef __cpp_nested_namespace_definitions
+#  error "__cpp_nested_namespace_definitions"
+#elif __cpp_nested_namespace_definitions != 201411
+#  error "__cpp_nested_namespace_definitions != 201411"
+#endif
diff --git a/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C b/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C
new file mode 100644
index 0000000..7dc2173
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/namespace-attribs.C
@@ -0,0 +1,10 @@ 
+// { dg-options "-std=c++1z" }
+
+namespace A __attribute ((visibility ("default"))) {}
+
+namespace B [[deprecated]] {} // { dg-warning "ignored" }
+
+namespace __attribute ((visibility ("default"))) C {}
+
+namespace [[deprecated]] D {} // { dg-warning "ignored" }
+
diff --git a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C
index ebdb70b..3980174 100644
--- a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C
+++ b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C
@@ -17,3 +17,7 @@  namespace G __attribute ((visibility ("default"))) ::H {} // { dg-error "cannot
 
 namespace H [[deprecated]] ::I {} // { dg-error "cannot have attributes|ignored" }
 
+namespace __attribute ((visibility ("default"))) I::J {} // { dg-error "cannot have attributes" }
+
+namespace [[deprecated]] J::K {} // { dg-error "cannot have attributes|ignored" }
+