public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH for new namespace association syntax and c++/33486
@ 2008-02-25  8:24 Jason Merrill
  2008-02-26  2:22 ` Mark Mitchell
  0 siblings, 1 reply; 5+ messages in thread
From: Jason Merrill @ 2008-02-25  8:24 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 619 bytes --]

I've been dissatisfied with the "strong using" syntax for namespace 
association, and have revised the standardization proposal to use 
"inline namespace" instead.  This patch implements that new syntax and 
changes libstdc++ to use it.  As you can see, it's a pretty 
straightforward change.

This patch also fixes c++/33486, a problem where we have two parallel 
inline namespaces and need arg-dependent lookup to find a declaration in 
one of them when given a type in the other.  Simply making the 
association two-way for argument-dependent lookup fixes the problem.

Tested x86_64-pc-linux-gnu, applied to trunk.

[-- Attachment #2: inline-ns.patch --]
[-- Type: text/x-patch, Size: 8455 bytes --]

2008-02-24  Jason Merrill  <jason@redhat.com>

	* 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.

Index: gcc/cp/name-lookup.c
===================================================================
*** gcc/cp/name-lookup.c	(revision 132442)
--- gcc/cp/name-lookup.c	(working copy)
*************** arg_assoc_namespace (struct arg_lookup *
*** 4419,4424 ****
--- 4419,4431 ----
      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;
Index: gcc/cp/parser.c
===================================================================
*** gcc/cp/parser.c	(revision 132442)
--- gcc/cp/parser.c	(working copy)
*************** cp_parser_declaration (cp_parser* parser
*** 7737,7742 ****
--- 7737,7746 ----
  	       || 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);
*************** cp_parser_namespace_definition (cp_parse
*** 11562,11567 ****
--- 11566,11580 ----
  {
    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'");
*************** cp_parser_namespace_definition (cp_parse
*** 11583,11588 ****
--- 11596,11616 ----
    /* 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.  */
Index: gcc/testsuite/g++.dg/lookup/strong-using-1.C
===================================================================
*** gcc/testsuite/g++.dg/lookup/strong-using-1.C	(revision 132442)
--- gcc/testsuite/g++.dg/lookup/strong-using-1.C	(working copy)
***************
*** 3,12 ****
  // { dg-do compile }
  
  namespace fool {
!   namespace foo {
      template <class T> void swap(T, T);
    }
-   using namespace foo __attribute__((strong));
    template <class T> void swap(T);
  }
  
--- 3,11 ----
  // { dg-do compile }
  
  namespace fool {
!   inline namespace foo {
      template <class T> void swap(T, T);
    }
    template <class T> void swap(T);
  }
  
Index: gcc/testsuite/g++.dg/lookup/strong-using-5.C
===================================================================
*** gcc/testsuite/g++.dg/lookup/strong-using-5.C	(revision 0)
--- gcc/testsuite/g++.dg/lookup/strong-using-5.C	(revision 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());
+ }
Index: gcc/testsuite/g++.dg/lookup/strong-using-2.C
===================================================================
*** gcc/testsuite/g++.dg/lookup/strong-using-2.C	(revision 132442)
--- gcc/testsuite/g++.dg/lookup/strong-using-2.C	(working copy)
***************
*** 3,18 ****
  // { dg-do compile }
  
  namespace foo {
!   namespace foo_impl {
      class T; // { dg-error "T" "" }
    }
-   using namespace foo_impl __attribute__((strong));
  }
  namespace bar {
!   namespace bar_impl {
      class T; // { dg-error "T" "" }
    }
-   using namespace bar_impl __attribute__((strong));
    using namespace foo;
  }
  namespace baz {
--- 3,16 ----
  // { dg-do compile }
  
  namespace foo {
!   inline namespace foo_impl {
      class T; // { dg-error "T" "" }
    }
  }
  namespace bar {
!   inline namespace bar_impl {
      class T; // { dg-error "T" "" }
    }
    using namespace foo;
  }
  namespace baz {
Index: gcc/testsuite/g++.dg/lookup/strong-using-3.C
===================================================================
*** gcc/testsuite/g++.dg/lookup/strong-using-3.C	(revision 132442)
--- gcc/testsuite/g++.dg/lookup/strong-using-3.C	(working copy)
***************
*** 3,12 ****
  // { dg-do compile }
  
  namespace bar {
!   namespace foo {
      template <class T> void f(T, T);
    }
-   using namespace foo __attribute__((strong));
    template <class T> void f(T);
  }
  
--- 3,11 ----
  // { dg-do compile }
  
  namespace bar {
!   inline namespace foo {
      template <class T> void f(T, T);
    }
    template <class T> void f(T);
  }
  
Index: libstdc++-v3/include/bits/c++config
===================================================================
*** libstdc++-v3/include/bits/c++config	(revision 132442)
--- libstdc++-v3/include/bits/c++config	(working copy)
***************
*** 180,190 ****
  namespace std
  { 
    namespace __norm { } 
!   namespace __debug { }
!   namespace __cxx1998 { }
! 
!   using namespace __debug __attribute__ ((strong)); 
!   using namespace __cxx1998 __attribute__ ((strong)); 
  }
  #endif
  
--- 180,187 ----
  namespace std
  { 
    namespace __norm { } 
!   inline namespace __debug { }
!   inline namespace __cxx1998 { }
  }
  #endif
  
*************** namespace std
*** 193,203 ****
  namespace std
  { 
    namespace __norm { } 
!   namespace __parallel { }
!   namespace __cxx1998 { }
! 
!   using namespace __parallel __attribute__ ((strong));
!   using namespace __cxx1998 __attribute__ ((strong)); 
  }
  #endif
  
--- 190,197 ----
  namespace std
  { 
    namespace __norm { } 
!   inline namespace __parallel { }
!   inline namespace __cxx1998 { }
  }
  #endif
  
*************** namespace std
*** 205,226 ****
  #if _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
  namespace std
  {
!   namespace _6 { }
!   using namespace _6 __attribute__ ((strong));
  }
  
  namespace __gnu_cxx 
  { 
!   namespace _6 { }
!   using namespace _6 __attribute__ ((strong));
  }
  
  namespace std
  {
    namespace tr1 
    { 
!     namespace _6 { }
!     using namespace _6 __attribute__ ((strong));
    }
  }
  #endif
--- 199,217 ----
  #if _GLIBCXX_NAMESPACE_ASSOCIATION_VERSION
  namespace std
  {
!   inline namespace _6 { }
  }
  
  namespace __gnu_cxx 
  { 
!   inline namespace _6 { }
  }
  
  namespace std
  {
    namespace tr1 
    { 
!     inline namespace _6 { }
    }
  }
  #endif
*************** _GLIBCXX_BEGIN_NAMESPACE(std)
*** 235,242 ****
  # define _GLIBCXX_LDBL_NAMESPACE __gnu_cxx_ldbl128::
  # define _GLIBCXX_BEGIN_LDBL_NAMESPACE namespace __gnu_cxx_ldbl128 {
  # define _GLIBCXX_END_LDBL_NAMESPACE }
!   namespace __gnu_cxx_ldbl128 { }
!   using namespace __gnu_cxx_ldbl128 __attribute__((__strong__));
  #else
  # define _GLIBCXX_LDBL_NAMESPACE
  # define _GLIBCXX_BEGIN_LDBL_NAMESPACE
--- 226,232 ----
  # define _GLIBCXX_LDBL_NAMESPACE __gnu_cxx_ldbl128::
  # define _GLIBCXX_BEGIN_LDBL_NAMESPACE namespace __gnu_cxx_ldbl128 {
  # define _GLIBCXX_END_LDBL_NAMESPACE }
!   inline namespace __gnu_cxx_ldbl128 { }
  #else
  # define _GLIBCXX_LDBL_NAMESPACE
  # define _GLIBCXX_BEGIN_LDBL_NAMESPACE

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-02-26  5:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-02-25  8:24 C++ PATCH for new namespace association syntax and c++/33486 Jason Merrill
2008-02-26  2:22 ` Mark Mitchell
2008-02-26  4:27   ` Jason Merrill
2008-02-26  5:10     ` Mark Mitchell
2008-02-26  6:12       ` Doug Gregor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).