From aa09f986bc1d3934932225d64ebca03a7eed65b3 Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Tue, 21 Mar 2006 11:15:25 -0500
Subject: [PATCH] re PR c++/21581 ((optimisation) Functions in anonymous
 namespaces should default to "hidden" visibility)

        PR c++/21581
        * parser.c (cp_parser_declaration): Support attributes on
        anonymous namespaces.
        * name-lookup.c (push_namespace_with_attribs): Anonymous
        namespaces default to hidden visibility.

From-SVN: r112250
---
 gcc/cp/ChangeLog                            |  8 ++++++++
 gcc/cp/name-lookup.c                        | 15 ++++++++++++---
 gcc/cp/parser.c                             |  3 ++-
 gcc/testsuite/g++.dg/ext/visibility/anon1.C | 10 ++++++++++
 4 files changed, 32 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/visibility/anon1.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 983165551be1..d754dd00de58 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2006-03-21  Jason Merrill  <jason@redhat.com>
+
+	PR c++/21581
+	* parser.c (cp_parser_declaration): Support attributes on
+	anonymous namespaces.
+	* name-lookup.c (push_namespace_with_attribs): Anonymous 
+	namespaces default to hidden visibility.
+
 2006-03-20  Jason Merrill  <jason@redhat.com>
 
 	PR c++/21764, c++/19238
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 9b10fb4a9d7c..4af73a30763e 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3046,7 +3046,7 @@ push_namespace_with_attribs (tree name, tree attributes)
       tree name = TREE_PURPOSE (d);
       tree args = TREE_VALUE (d);
       tree x;
-      
+
       if (! is_attribute_p ("visibility", name))
 	{
 	  warning (OPT_Wattributes, "%qs attribute directive ignored",
@@ -3055,16 +3055,25 @@ push_namespace_with_attribs (tree name, tree attributes)
 	}
 
       x = args ? TREE_VALUE (args) : NULL_TREE;
-      if (x == NULL_TREE || TREE_CODE (x) != STRING_CST)
+      if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args))
 	{
-	  warning (OPT_Wattributes, "%qs attribute requires an NTBS argument",
+	  warning (OPT_Wattributes, "%qs attribute requires a single NTBS argument",
 		   IDENTIFIER_POINTER (name));
 	  continue;
 	}
 
       current_binding_level->has_visibility = 1;
       push_visibility (TREE_STRING_POINTER (x));
+      goto found;
     }
+  if (anon)
+    {
+      /* Anonymous namespaces default to hidden visibility.  This might
+	 change once we implement export.  */
+      current_binding_level->has_visibility = 1;
+      push_visibility ("hidden");
+    }
+ found:
 #endif
 
   timevar_pop (TV_NAME_LOOKUP);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e04a8e7f0d6c..c5e6b1781e66 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7066,7 +7066,8 @@ cp_parser_declaration (cp_parser* parser)
 		&& (cp_lexer_peek_nth_token (parser->lexer, 3)->type
 		    != CPP_EQ))
 	       /* An unnamed namespace definition.  */
-	       || token2.type == CPP_OPEN_BRACE))
+	       || token2.type == CPP_OPEN_BRACE
+	       || token2.keyword == RID_ATTRIBUTE))
     cp_parser_namespace_definition (parser);
   /* Objective-C++ declaration/definition.  */
   else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1.keyword))
diff --git a/gcc/testsuite/g++.dg/ext/visibility/anon1.C b/gcc/testsuite/g++.dg/ext/visibility/anon1.C
new file mode 100644
index 000000000000..9a3d8a7f8ab6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/visibility/anon1.C
@@ -0,0 +1,10 @@
+// PR c++/21581
+// Test for anonymous namespace default hidden visibility
+
+// { dg-require-visibility "" }
+// { dg-final { scan-hidden "_ZN.*1fEv" } }
+
+namespace
+{
+  int f() { }
+}