diff options
author | Jason Merrill <jason@redhat.com> | 2007-10-04 04:48:23 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2007-10-04 04:48:23 -0400 |
commit | 65567efaa82178fcfe63bee2c81f06a541cd72a4 (patch) | |
tree | bae096b4fe2cf8e3db8b3a02fa456bfff47ef358 | |
parent | dcdc83a1857653c02c8997e5787c6a41244bdb95 (diff) | |
download | gcc-65567efaa82178fcfe63bee2c81f06a541cd72a4.zip gcc-65567efaa82178fcfe63bee2c81f06a541cd72a4.tar.gz gcc-65567efaa82178fcfe63bee2c81f06a541cd72a4.tar.bz2 |
re PR c++/32470 (fvisibility=hidden without effect in some cases)
PR c++/32470
* name-lookup.c (push_namespace_with_attrs): Fold back into...
(push_namespace): Here.
(handle_namespace_attrs): New fn for the attr code.
(leave_scope): Don't pop_visibility.
* name-lookup.h (struct cp_binding_level): Remove has_visibility.
* parser.c (cp_parser_namespace_definition): Call
handle_namespace_attrs and pop_visibility as appropriate.
From-SVN: r129003
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 94 | ||||
-rw-r--r-- | gcc/cp/name-lookup.h | 8 | ||||
-rw-r--r-- | gcc/cp/parser.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/visibility/namespace2.C | 20 |
5 files changed, 90 insertions, 53 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2e33534..0cec087 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 2007-10-03 Jason Merrill <jason@redhat.com> + PR c++/32470 + * name-lookup.c (push_namespace_with_attrs): Fold back into... + (push_namespace): Here. + (handle_namespace_attrs): New fn for the attr code. + (leave_scope): Don't pop_visibility. + * name-lookup.h (struct cp_binding_level): Remove has_visibility. + * parser.c (cp_parser_namespace_definition): Call + handle_namespace_attrs and pop_visibility as appropriate. + PR c++/11756 * mangle.c (write_type) [TYPEOF_TYPE]: Just sorry. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 70a395b..a7bb710 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1364,11 +1364,6 @@ leave_scope (void) is_class_level = 0; } -#ifdef HANDLE_PRAGMA_VISIBILITY - if (scope->has_visibility) - pop_visibility (); -#endif - /* Move one nesting level up. */ current_binding_level = scope->level_chain; @@ -3027,20 +3022,59 @@ current_decl_namespace (void) return result; } -/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we - select a name that is unique to this compilation unit. */ +/* Process any ATTRIBUTES on a namespace definition. Currently only + attribute visibility is meaningful, which is a property of the syntactic + block rather than the namespace as a whole, so we don't touch the + NAMESPACE_DECL at all. Returns true if attribute visibility is seen. */ -void -push_namespace (tree name) +bool +handle_namespace_attrs (tree ns, tree attributes) { - push_namespace_with_attribs (name, NULL_TREE); -} + tree d; + bool saw_vis = false; + + for (d = attributes; d; d = TREE_CHAIN (d)) + { + tree name = TREE_PURPOSE (d); + tree args = TREE_VALUE (d); + +#ifdef HANDLE_PRAGMA_VISIBILITY + if (is_attribute_p ("visibility", name)) + { + tree x = args ? TREE_VALUE (args) : NULL_TREE; + if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args)) + { + warning (OPT_Wattributes, + "%qD attribute requires a single NTBS argument", + name); + continue; + } + + if (!TREE_PUBLIC (ns)) + warning (OPT_Wattributes, + "%qD attribute is meaningless since members of the " + "anonymous namespace get local symbols", name); + + push_visibility (TREE_STRING_POINTER (x)); + saw_vis = true; + } + else +#endif + { + warning (OPT_Wattributes, "%qD attribute directive ignored", + name); + continue; + } + } -/* Same, but specify attributes to apply to the namespace. The attributes - only apply to the current namespace-body, not to any later extensions. */ + return saw_vis; +} + +/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we + select a name that is unique to this compilation unit. */ void -push_namespace_with_attribs (tree name, tree attributes) +push_namespace (tree name) { tree d = NULL_TREE; int need_new = 1; @@ -3107,38 +3141,6 @@ push_namespace_with_attribs (tree name, tree attributes) /* Enter the name space. */ current_namespace = d; -#ifdef HANDLE_PRAGMA_VISIBILITY - /* Clear has_visibility in case a previous namespace-definition had a - visibility attribute and this one doesn't. */ - current_binding_level->has_visibility = 0; - for (d = attributes; d; d = TREE_CHAIN (d)) - { - 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", - IDENTIFIER_POINTER (name)); - continue; - } - - x = args ? TREE_VALUE (args) : NULL_TREE; - if (x == NULL_TREE || TREE_CODE (x) != STRING_CST || TREE_CHAIN (args)) - { - 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; - } - found: -#endif - timevar_pop (TV_NAME_LOOKUP); } diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 88551f2..7da57be 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -255,11 +255,7 @@ struct cp_binding_level GTY(()) unsigned more_cleanups_ok : 1; unsigned have_cleanups : 1; - /* Nonzero if this level has associated visibility which we should pop - when leaving the scope. */ - unsigned has_visibility : 1; - - /* 23 bits left to fill a 32-bit word. */ + /* 24 bits left to fill a 32-bit word. */ }; /* The binding level currently in effect. */ @@ -307,10 +303,10 @@ extern void pop_inner_scope (tree, tree); extern void push_binding_level (struct cp_binding_level *); extern void push_namespace (tree); -extern void push_namespace_with_attribs (tree, tree); extern void pop_namespace (void); extern void push_nested_namespace (tree); extern void pop_nested_namespace (tree); +extern bool handle_namespace_attrs (tree, tree); extern void pushlevel_class (void); extern void poplevel_class (void); extern tree pushdecl_with_scope (tree, cxx_scope *, bool); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ede0d7e..3720b55 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11475,6 +11475,7 @@ static void cp_parser_namespace_definition (cp_parser* parser) { tree identifier, attribs; + bool has_visibility; /* Look for the `namespace' keyword. */ cp_parser_require_keyword (parser, RID_NAMESPACE, "`namespace'"); @@ -11494,9 +11495,18 @@ cp_parser_namespace_definition (cp_parser* parser) /* Look for the `{' to start the namespace. */ cp_parser_require (parser, CPP_OPEN_BRACE, "`{'"); /* Start the namespace. */ - push_namespace_with_attribs (identifier, attribs); + push_namespace (identifier); + + has_visibility = handle_namespace_attrs (current_namespace, attribs); + /* Parse the body of the namespace. */ cp_parser_namespace_body (parser); + +#ifdef HANDLE_PRAGMA_VISIBILITY + if (has_visibility) + pop_visibility (); +#endif + /* Finish the namespace. */ pop_namespace (); /* Look for the final `}'. */ diff --git a/gcc/testsuite/g++.dg/ext/visibility/namespace2.C b/gcc/testsuite/g++.dg/ext/visibility/namespace2.C new file mode 100644 index 0000000..5e6e71f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/namespace2.C @@ -0,0 +1,20 @@ +// PR c++/32470 + +// { dg-require-visibility } +// { dg-options "-fvisibility=hidden" } +// { dg-final { scan-hidden "_ZN4Test4testEv" } } + +namespace std __attribute__((__visibility__("default"))) { + template<typename _CharT> + class basic_streambuf + { + friend void getline(); + }; + extern template class basic_streambuf<char>; +} + +class Test +{ + void test(); +}; +void Test::test() { } |