From: Ville Voutilainen Date: Sat, 19 Sep 2015 04:44:01 +0000 (+0300) Subject: Implement nested namespace definitions. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=15eefe57380a7c5fe749bf8241828c6ec39d0e21;p=gcc.git Implement nested namespace definitions. /cp 2015-09-18 Ville Voutilainen Implement nested namespace definitions. * parser.c (cp_parser_namespace_definition): Grok nested namespace definitions. /testsuite 2015-09-18 Ville Voutilainen Implement nested namespace definitions. * g++.dg/cpp1z/nested-namespace-def1.C: New. * g++.dg/cpp1z/nested-namespace-def2.C: Likewise. * g++.dg/cpp1z/nested-namespace-def3.C: Likewise. * g++.dg/lookup/name-clash5.C: Adjust. * g++.dg/lookup/name-clash6.C: Likewise. From-SVN: r227932 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c72e913e1b3..373937aef93 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2015-09-18 Ville Voutilainen + + Implement nested namespace definitions. + * parser.c (cp_parser_namespace_definition): Grok nested namespace + definitions. + 2015-09-18 Manuel López-Ibáñez * parser.c (pragma_lex): Add loc argument. Rearrange the code to diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 637118c2b27..2071276dfcb 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -16953,6 +16953,8 @@ cp_parser_namespace_definition (cp_parser* parser) tree identifier, attribs; bool has_visibility; bool is_inline; + cp_token* token; + int nested_definition_count = 0; cp_ensure_no_omp_declare_simd (parser); if (cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE)) @@ -16965,7 +16967,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 @@ -16979,11 +16981,38 @@ cp_parser_namespace_definition (cp_parser* parser) /* Parse any specified attributes. */ attribs = cp_parser_attributes_opt (parser); - /* Look for the `{' to start the namespace. */ - cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE); /* Start the namespace. */ push_namespace (identifier); + /* Parse any nested namespace definition. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)) + { + if (attribs) + error_at (token->location, "a nested namespace definition cannot have attributes"); + if (cxx_dialect < cxx1z) + pedwarn (input_location, OPT_Wpedantic, + "nested namespace definitions only available with " + "-std=c++1z or -std=gnu++1z"); + if (is_inline) + error_at (token->location, "a nested namespace definition cannot be inline"); + 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; + } + ++nested_definition_count; + push_namespace (identifier); + } + } + + /* Look for the `{' to validate starting the namespace. */ + cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE); + /* "inline namespace" is equivalent to a stub namespace definition followed by a strong using directive. */ if (is_inline) @@ -17007,6 +17036,10 @@ cp_parser_namespace_definition (cp_parser* parser) if (has_visibility) pop_visibility (1); + /* Finish the nested namespace definitions. */ + while (nested_definition_count--) + pop_namespace (); + /* Finish the namespace. */ pop_namespace (); /* Look for the final `}'. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 95a19a78181..a5901a15c50 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2015-09-18 Ville Voutilainen + + Implement nested namespace definitions. + * g++.dg/cpp1z/nested-namespace-def1.C: New. + * g++.dg/cpp1z/nested-namespace-def2.C: Likewise. + * g++.dg/cpp1z/nested-namespace-def3.C: Likewise. + * g++.dg/lookup/name-clash5.C: Adjust. + * g++.dg/lookup/name-clash6.C: Likewise. + 2015-09-18 Manuel López-Ibáñez * gcc.dg/pragma-diag-5.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C new file mode 100644 index 00000000000..ebdb70b1584 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C @@ -0,0 +1,19 @@ +// { dg-options "-std=c++1z" } + +namespace A::B::C +{ + struct X {}; + namespace T::U::V { struct Y {}; } +} + +A::B::C::X x; +A::B::C::T::U::V::Y y; + +inline namespace D::E {} // { dg-error "cannot be inline" } + +namespace F::G:: {} // { dg-error "nested identifier required" } + +namespace G __attribute ((visibility ("default"))) ::H {} // { dg-error "cannot have attributes" } + +namespace H [[deprecated]] ::I {} // { dg-error "cannot have attributes|ignored" } + diff --git a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def2.C b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def2.C new file mode 100644 index 00000000000..c47a94a46de --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def2.C @@ -0,0 +1,5 @@ +// { dg-options "-std=c++11 -pedantic-errors" } + +namespace A::B::C // { dg-error "nested namespace definitions only available with" } +{ +} diff --git a/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def3.C b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def3.C new file mode 100644 index 00000000000..f2dac8f0216 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/nested-namespace-def3.C @@ -0,0 +1,5 @@ +// { dg-options "-std=c++11" } + +namespace A::B::C +{ +} diff --git a/gcc/testsuite/g++.dg/lookup/name-clash5.C b/gcc/testsuite/g++.dg/lookup/name-clash5.C index 74595c26871..9673bb9d8c6 100644 --- a/gcc/testsuite/g++.dg/lookup/name-clash5.C +++ b/gcc/testsuite/g++.dg/lookup/name-clash5.C @@ -6,8 +6,8 @@ // "[Note: a namespace name or a class template name must be unique in its // declarative region (7.3.2, clause 14). ]" -namespace N -{ // { dg-message "previous declaration" } +namespace N // { dg-message "previous declaration" } +{ } class N; // { dg-error "redeclared" } diff --git a/gcc/testsuite/g++.dg/lookup/name-clash6.C b/gcc/testsuite/g++.dg/lookup/name-clash6.C index 6918142f222..f27e04aff83 100644 --- a/gcc/testsuite/g++.dg/lookup/name-clash6.C +++ b/gcc/testsuite/g++.dg/lookup/name-clash6.C @@ -8,6 +8,6 @@ class N; // { dg-message "previous declaration" } -namespace N -{ // { dg-error "redeclared" } +namespace N // { dg-error "redeclared" } +{ }