This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for new namespace association syntax and c++/33486


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]