aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@gmail.com>2015-09-19 07:44:01 +0300
committerVille Voutilainen <ville@gcc.gnu.org>2015-09-19 07:44:01 +0300
commit15eefe57380a7c5fe749bf8241828c6ec39d0e21 (patch)
treedb1daefebcd5b20b84cf4046bcb5f43800753de4 /gcc
parent8e33db8fc08900f77200506f2cdf5c50e2fbfcba (diff)
downloadgcc-15eefe57380a7c5fe749bf8241828c6ec39d0e21.zip
gcc-15eefe57380a7c5fe749bf8241828c6ec39d0e21.tar.gz
gcc-15eefe57380a7c5fe749bf8241828c6ec39d0e21.tar.bz2
Implement nested namespace definitions.
/cp 2015-09-18 Ville Voutilainen <ville.voutilainen@gmail.com> Implement nested namespace definitions. * parser.c (cp_parser_namespace_definition): Grok nested namespace definitions. /testsuite 2015-09-18 Ville Voutilainen <ville.voutilainen@gmail.com> 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c39
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/nested-namespace-def1.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/nested-namespace-def2.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/nested-namespace-def3.C5
-rw-r--r--gcc/testsuite/g++.dg/lookup/name-clash5.C4
-rw-r--r--gcc/testsuite/g++.dg/lookup/name-clash6.C4
8 files changed, 84 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c72e913..373937a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2015-09-18 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Implement nested namespace definitions.
+ * parser.c (cp_parser_namespace_definition): Grok nested namespace
+ definitions.
+
2015-09-18 Manuel López-Ibáñez <manu@gcc.gnu.org>
* parser.c (pragma_lex): Add loc argument. Rearrange the code to
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 637118c..2071276 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 95a19a7..a5901a1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2015-09-18 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ 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 <manu@gcc.gnu.org>
* 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 0000000..ebdb70b
--- /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 0000000..c47a94a
--- /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 0000000..f2dac8f
--- /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 74595c2..9673bb9 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 6918142..f27e04a 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" }
+{
}