aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2018-11-28 21:39:42 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2018-11-28 21:39:42 +0000
commit3b9a9fe89faac023d85c9d3533c6e371197e204a (patch)
tree1bfdbf1020e96a1fc963ea590229baa2c1c3cad6
parentd794ab85f7b14b546701c23f357d49bbab474d39 (diff)
downloadgcc-3b9a9fe89faac023d85c9d3533c6e371197e204a.zip
gcc-3b9a9fe89faac023d85c9d3533c6e371197e204a.tar.gz
gcc-3b9a9fe89faac023d85c9d3533c6e371197e204a.tar.bz2
Implement P1094R2, Nested inline namespaces.
* parser.c (cp_parser_namespace_definition): Parse the optional inline keyword in a nested-namespace-definition. Adjust push_namespace call. Formatting fix. * g++.dg/cpp2a/nested-inline-ns1.C: New test. * g++.dg/cpp2a/nested-inline-ns2.C: New test. From-SVN: r266592
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/parser.c29
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nested-inline-ns1.C29
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nested-inline-ns2.C26
5 files changed, 93 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8b8a857..f7f2020 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-28 Marek Polacek <polacek@redhat.com>
+
+ Implement P1094R2, Nested inline namespaces.
+ * parser.c (cp_parser_namespace_definition): Parse the optional inline
+ keyword in a nested-namespace-definition. Adjust push_namespace call.
+ Formatting fix.
+
2018-11-28 Nathan Sidwell <nathan@acm.org>
PR c++/87531
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 3a98ed9..3ef1eda4 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -19004,6 +19004,7 @@ cp_parser_namespace_definition (cp_parser* parser)
cp_ensure_no_oacc_routine (parser);
bool is_inline = cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE);
+ const bool topmost_inline_p = is_inline;
if (is_inline)
{
@@ -19022,6 +19023,17 @@ cp_parser_namespace_definition (cp_parser* parser)
{
identifier = NULL_TREE;
+ bool nested_inline_p = cp_lexer_next_token_is_keyword (parser->lexer,
+ RID_INLINE);
+ if (nested_inline_p && nested_definition_count != 0)
+ {
+ if (cxx_dialect < cxx2a)
+ pedwarn (cp_lexer_peek_token (parser->lexer)->location,
+ OPT_Wpedantic, "nested inline namespace definitions only "
+ "available with -std=c++2a or -std=gnu++2a");
+ cp_lexer_consume_token (parser->lexer);
+ }
+
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
identifier = cp_parser_identifier (parser);
@@ -19036,7 +19048,14 @@ cp_parser_namespace_definition (cp_parser* parser)
}
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE))
- break;
+ {
+ /* Don't forget that the innermost namespace might have been
+ marked as inline. Use |= because we cannot overwrite
+ IS_INLINE in case the outermost namespace is inline, but
+ there are no nested inlines. */
+ is_inline |= nested_inline_p;
+ break;
+ }
if (!nested_definition_count && cxx_dialect < cxx17)
pedwarn (input_location, OPT_Wpedantic,
@@ -19045,7 +19064,9 @@ cp_parser_namespace_definition (cp_parser* parser)
/* Nested namespace names can create new namespaces (unlike
other qualified-ids). */
- if (int count = identifier ? push_namespace (identifier) : 0)
+ if (int count = (identifier
+ ? push_namespace (identifier, nested_inline_p)
+ : 0))
nested_definition_count += count;
else
cp_parser_error (parser, "nested namespace name required");
@@ -19058,7 +19079,7 @@ cp_parser_namespace_definition (cp_parser* parser)
if (nested_definition_count && attribs)
error_at (token->location,
"a nested namespace definition cannot have attributes");
- if (nested_definition_count && is_inline)
+ if (nested_definition_count && topmost_inline_p)
error_at (token->location,
"a nested namespace definition cannot be inline");
@@ -19067,7 +19088,7 @@ cp_parser_namespace_definition (cp_parser* parser)
bool has_visibility = handle_namespace_attrs (current_namespace, attribs);
- warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace);
+ warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace);
/* Look for the `{' to validate starting the namespace. */
matching_braces braces;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7406719..0ba033a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2018-11-28 Marek Polacek <polacek@redhat.com>
+
+ Implement P1094R2, Nested inline namespaces.
+ * g++.dg/cpp2a/nested-inline-ns1.C: New test.
+ * g++.dg/cpp2a/nested-inline-ns2.C: New test.
+
2018-11-28 Nathan Sidwell <nathan@acm.org>
PR c++/87531
diff --git a/gcc/testsuite/g++.dg/cpp2a/nested-inline-ns1.C b/gcc/testsuite/g++.dg/cpp2a/nested-inline-ns1.C
new file mode 100644
index 0000000..8c9573e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nested-inline-ns1.C
@@ -0,0 +1,29 @@
+// P1094R2
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wpedantic" }
+
+namespace A::inline B::C { // { dg-warning "nested inline namespace definitions only" "" { target c++17_down } }
+// { dg-warning "nested namespace definitions only available" "" { target c++14_down } .-1 }
+ int i;
+}
+
+namespace D::E::inline F { // { dg-warning "nested inline namespace definitions only" "" { target c++17_down } }
+// { dg-warning "nested namespace definitions only available" "" { target c++14_down } .-1 }
+ int j;
+}
+
+inline namespace X {
+ int x;
+}
+
+// Make sure the namespaces are marked inline.
+void
+g ()
+{
+ A::B::C::i++;
+ A::C::i++;
+ D::E::j++;
+ D::E::F::j++;
+ X::x++;
+ x++;
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/nested-inline-ns2.C b/gcc/testsuite/g++.dg/cpp2a/nested-inline-ns2.C
new file mode 100644
index 0000000..9b5f2ca
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nested-inline-ns2.C
@@ -0,0 +1,26 @@
+// P1094R2
+// { dg-do compile { target c++2a } }
+
+inline namespace A::B { // { dg-error "a nested namespace definition cannot be inline" }
+ int i;
+}
+
+namespace inline C::D { // { dg-error "expected|does not name a type" }
+ int i;
+}
+
+namespace E::F inline { // { dg-error "expected" }
+ int i;
+}
+
+namespace inline G { // { dg-error "expected|does not name a type" }
+ int i;
+}
+
+inline namespace inline H { // { dg-error "expected|does not name a type" }
+ int i;
+}
+
+inline namespace inline I::J { // { dg-error "expected|does not name a type" }
+ int i;
+}