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;
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;
/* 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);
}
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. */
extern void push_binding_level (struct cp_binding_level *);
\f
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);
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'");
/* 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 `}'. */