@@ -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
@@ -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);
@@ -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
new file mode 100644
@@ -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
@@ -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
@@ -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
new file mode 100644
@@ -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" }
+
@@ -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" }
+