diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-21 03:19:06 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-21 03:19:06 +0000 |
commit | 799435d8a91f69e2fe2a0b42cd0af67e4180a929 (patch) | |
tree | 6e55c5f98ba55a6fcaf4861b4df4e8d7233c36ef /gcc/cp/name-lookup.c | |
parent | 9d24686a6f8ca3fbccd12cdcce858ab2384a3d81 (diff) | |
download | gcc-799435d8a91f69e2fe2a0b42cd0af67e4180a929.tar.gz |
PR c++/21764
* c-pragma.c (visstack): Move out of handle_pragma_visibility.
(push_visibility, pop_visibility): Likewise.
* c-pragma.h: Declare them.
* cp/name-lookup.h (struct cp_binding_level): Add has_visibility
bitfield.
* cp/name-lookup.c: Include c-pragma.h.
(push_namespace_with_attribs): Split out from push_namespace.
Push visibility if appropriate. Set TREE_PUBLIC on namespaces.
(leave_scope): Pop visibility if appropriate.
* cp/parser.c (cp_parser_declaration, cp_parser_namespace_name): Allow
attributes on namespace declarations.
PR c++/19238
* cp/decl.c (cp_finish_decl): Call determine_visibility later.
(start_preparsed_function): Likewise.
* cp/cp-tree.h (CP_TYPE_CONTEXT, TYPE_NAMESPACE_SCOPE_P): New macros.
(TYPE_CLASS_SCOPE_P, TYPE_FUNCTION_SCOPE_P): New macros.
* cp/decl2.c (determine_visibility_from_class): Split out from...
(determine_visibility): ...here. Handle function scope and
nested classes.
(import_export_decl): Move visibility handling to
determine_visibility_from_class.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@112239 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/name-lookup.c')
-rw-r--r-- | gcc/cp/name-lookup.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index ebf8a3365ed..9b10fb4a9d7 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -31,6 +31,7 @@ Boston, MA 02110-1301, USA. */ #include "toplev.h" #include "diagnostic.h" #include "debug.h" +#include "c-pragma.h" /* The bindings for a particular name in a particular scope. */ @@ -1330,11 +1331,16 @@ 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; /* Namespace-scopes are left most probably temporarily, not - completely; they can be reopen later, e.g. in namespace-extension + completely; they can be reopened later, e.g. in namespace-extension or any name binding activity that requires us to resume a namespace. For classes, we cache some binding levels. For other scopes, we just make the structure available for reuse. */ @@ -2958,6 +2964,15 @@ current_decl_namespace (void) void push_namespace (tree name) { + push_namespace_with_attribs (name, NULL_TREE); +} + +/* Same, but specify attributes to apply to the namespace. The attributes + only apply to the current namespace-body, not to any later extensions. */ + +void +push_namespace_with_attribs (tree name, tree attributes) +{ tree d = NULL_TREE; int need_new = 1; int implicit_use = 0; @@ -3004,6 +3019,7 @@ push_namespace (tree name) /* Make a new namespace, binding the name to it. */ d = build_lang_decl (NAMESPACE_DECL, name, void_type_node); DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace); + TREE_PUBLIC (d) = 1; pushdecl (d); if (anon) { @@ -3021,6 +3037,36 @@ push_namespace (tree name) /* 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) + { + warning (OPT_Wattributes, "%qs attribute requires an NTBS argument", + IDENTIFIER_POINTER (name)); + continue; + } + + current_binding_level->has_visibility = 1; + push_visibility (TREE_STRING_POINTER (x)); + } +#endif + timevar_pop (TV_NAME_LOOKUP); } |