aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2008-02-25 01:26:24 -0500
committerJason Merrill <jason@gcc.gnu.org>2008-02-25 01:26:24 -0500
commit4cfaec1cefa9e393cceb88fa818c7c2530e75289 (patch)
treeb3e9a71438b63c4eab718359b3976d6d06ff3474 /gcc
parentc9be0915bde2e7c447889dc651ee561e1d742ee1 (diff)
downloadgcc-4cfaec1cefa9e393cceb88fa818c7c2530e75289.zip
gcc-4cfaec1cefa9e393cceb88fa818c7c2530e75289.tar.gz
gcc-4cfaec1cefa9e393cceb88fa818c7c2530e75289.tar.bz2
re PR c++/33486 (namespace association doesn't handle parallel namespaces)
* gcc/cp/parser.c (cp_parser_declaration): Handle 'inline namespace'. (cp_parser_namespace_definition): Likewise. PR c++/33486 * gcc/cp/name-lookup.c (arg_assoc_namespace): Look down into inline namespaces, too. * libstdc++-v3/include/bits/c++config: Use 'inline namespace' instead of strong using. From-SVN: r132611
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/name-lookup.c7
-rw-r--r--gcc/cp/parser.c28
-rw-r--r--gcc/testsuite/g++.dg/lookup/strong-using-1.C3
-rw-r--r--gcc/testsuite/g++.dg/lookup/strong-using-2.C6
-rw-r--r--gcc/testsuite/g++.dg/lookup/strong-using-3.C3
-rw-r--r--gcc/testsuite/g++.dg/lookup/strong-using-5.C24
7 files changed, 72 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f7fba35..3341c1b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2008-02-24 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_declaration): Handle "inline namespace".
+ (cp_parser_namespace_definition): Likewise.
+
+ PR c++/33486
+ * name-lookup.c (arg_assoc_namespace): Look down into inline
+ namespaces, too.
+
2008-02-23 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
* typeck.c (check_for_casting_away_constness): Use 1 single
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index ded1d2e..4a43cfa 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4419,6 +4419,13 @@ arg_assoc_namespace (struct arg_lookup *k, tree scope)
if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
return true;
+ /* Also look down into inline namespaces. */
+ for (value = DECL_NAMESPACE_USING (scope); value;
+ value = TREE_CHAIN (value))
+ if (is_associated_namespace (scope, TREE_PURPOSE (value)))
+ if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
+ return true;
+
value = namespace_binding (k->name, scope);
if (!value)
return false;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a5bd055..cb00593 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7737,6 +7737,10 @@ cp_parser_declaration (cp_parser* parser)
|| token2.type == CPP_OPEN_BRACE
|| token2.keyword == RID_ATTRIBUTE))
cp_parser_namespace_definition (parser);
+ /* An inline (associated) namespace definition. */
+ else if (token1.keyword == RID_INLINE
+ && token2.keyword == RID_NAMESPACE)
+ cp_parser_namespace_definition (parser);
/* Objective-C++ declaration/definition. */
else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1.keyword))
cp_parser_objc_declaration (parser);
@@ -11562,6 +11566,15 @@ cp_parser_namespace_definition (cp_parser* parser)
{
tree identifier, attribs;
bool has_visibility;
+ bool is_inline;
+
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE))
+ {
+ is_inline = true;
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ is_inline = false;
/* Look for the `namespace' keyword. */
cp_parser_require_keyword (parser, RID_NAMESPACE, "`namespace'");
@@ -11583,6 +11596,21 @@ cp_parser_namespace_definition (cp_parser* parser)
/* Start the namespace. */
push_namespace (identifier);
+ /* "inline namespace" is equivalent to a stub namespace definition
+ followed by a strong using directive. */
+ if (is_inline)
+ {
+ tree namespace = current_namespace;
+ /* Set up namespace association. */
+ DECL_NAMESPACE_ASSOCIATIONS (namespace)
+ = tree_cons (CP_DECL_CONTEXT (namespace), NULL_TREE,
+ DECL_NAMESPACE_ASSOCIATIONS (namespace));
+ /* Import the contents of the inline namespace. */
+ pop_namespace ();
+ do_using_directive (namespace);
+ push_namespace (identifier);
+ }
+
has_visibility = handle_namespace_attrs (current_namespace, attribs);
/* Parse the body of the namespace. */
diff --git a/gcc/testsuite/g++.dg/lookup/strong-using-1.C b/gcc/testsuite/g++.dg/lookup/strong-using-1.C
index a16fd6a..739dc93 100644
--- a/gcc/testsuite/g++.dg/lookup/strong-using-1.C
+++ b/gcc/testsuite/g++.dg/lookup/strong-using-1.C
@@ -3,10 +3,9 @@
// { dg-do compile }
namespace fool {
- namespace foo {
+ inline namespace foo {
template <class T> void swap(T, T);
}
- using namespace foo __attribute__((strong));
template <class T> void swap(T);
}
diff --git a/gcc/testsuite/g++.dg/lookup/strong-using-2.C b/gcc/testsuite/g++.dg/lookup/strong-using-2.C
index 21e47cb..5c4b425 100644
--- a/gcc/testsuite/g++.dg/lookup/strong-using-2.C
+++ b/gcc/testsuite/g++.dg/lookup/strong-using-2.C
@@ -3,16 +3,14 @@
// { dg-do compile }
namespace foo {
- namespace foo_impl {
+ inline namespace foo_impl {
class T; // { dg-error "T" "" }
}
- using namespace foo_impl __attribute__((strong));
}
namespace bar {
- namespace bar_impl {
+ inline namespace bar_impl {
class T; // { dg-error "T" "" }
}
- using namespace bar_impl __attribute__((strong));
using namespace foo;
}
namespace baz {
diff --git a/gcc/testsuite/g++.dg/lookup/strong-using-3.C b/gcc/testsuite/g++.dg/lookup/strong-using-3.C
index 9b4d3c3..17c5032 100644
--- a/gcc/testsuite/g++.dg/lookup/strong-using-3.C
+++ b/gcc/testsuite/g++.dg/lookup/strong-using-3.C
@@ -3,10 +3,9 @@
// { dg-do compile }
namespace bar {
- namespace foo {
+ inline namespace foo {
template <class T> void f(T, T);
}
- using namespace foo __attribute__((strong));
template <class T> void f(T);
}
diff --git a/gcc/testsuite/g++.dg/lookup/strong-using-5.C b/gcc/testsuite/g++.dg/lookup/strong-using-5.C
new file mode 100644
index 0000000..789c8e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/strong-using-5.C
@@ -0,0 +1,24 @@
+// PR c++/33486
+
+namespace A
+{
+ inline namespace B
+ {
+ struct T
+ {
+ struct U { };
+ U f();
+ };
+ }
+
+ inline namespace C
+ {
+ void g (T::U);
+ }
+}
+
+int main()
+{
+ A::T t;
+ g(t.f());
+}