summaryrefslogtreecommitdiff
path: root/gcc/cp/name-lookup.c
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-21 03:19:06 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-21 03:19:06 +0000
commit799435d8a91f69e2fe2a0b42cd0af67e4180a929 (patch)
tree6e55c5f98ba55a6fcaf4861b4df4e8d7233c36ef /gcc/cp/name-lookup.c
parent9d24686a6f8ca3fbccd12cdcce858ab2384a3d81 (diff)
downloadgcc-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.c48
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);
}