aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2006-06-29 21:15:56 -0400
committerJason Merrill <jason@gcc.gnu.org>2006-06-29 21:15:56 -0400
commitb9e75696307f710a22c726e72b00e7a7161ad89f (patch)
tree93c1ec7ec5a70cb4b7384fa239594ed2f1288585 /gcc/c-common.c
parentdc2843f38c04c81e9f20a6e9e6ae9637ace6e08c (diff)
downloadgcc-b9e75696307f710a22c726e72b00e7a7161ad89f.zip
gcc-b9e75696307f710a22c726e72b00e7a7161ad89f.tar.gz
gcc-b9e75696307f710a22c726e72b00e7a7161ad89f.tar.bz2
re PR c++/26905 (default-visibility class symbol improperly resolved as hidden-visibility)
PR c++/26905 PR c++/26612 PR c++/27000 PR c++/26984 PR c++/19134 * tree.c (build_decl_stat): Don't hande #pragma visibility here. * c-common.c (c_determine_visibility): Handle it here. * c-decl.c (finish_decl): Call c_determine_visibility for functions, too. * flags.h (enum symbol_visibility): Sort from most to least visibility. * tree.h: Likewise. * varasm.c (default_assemble_visibility): Likewise. * c-common.c (handle_visibility_attribute): Complain about trying to give visibility to an already defined class, or trying to change declared visibility. Always attach the attribute. * cp/decl2.c (determine_visibility): Overhaul. (determine_visibility_from_class): Likewise. (min_vis_r, type_visibility, constrain_visibility): New fns. (constrain_visibility_for_template): Likewise. (constrain_class_visibility): Likewise. * cp/decl.c (cp_finish_decl): Call determine_visibility for function decls, too. * cp/name-lookup.c (pushtag): Call determine_visibility. * cp/decl.c (duplicate_decls): Don't copy visibility from template to specialization. * cp/pt.c (check_explicit_specialization): Likewise. (lookup_template_class, tsubst_decl): Call determine_visibility. * cp/class.c (finish_struct_1): Call constrain_class_visibility. PR c++/26905 PR c++/21675 PR c++/17470 * cp/parser.c (cp_parser_explicit_instantiation): Pass the attributes to grokdeclarator. (cp_parser_type_specifier): Allow 'enum __attribute ((...)) E'. (cp_parser_enum_specifier): Likewise. (cp_parser_elaborated_type_specifier): Apply attributes if this declares only the class. (cp_parser_class_specifier): Apply leading attributes immediately. * cp/semantics.c (begin_class_definition): Add attributes parameter, apply them to the type. * attribs.c (decl_attributes): Ignore type-in-place attributes once the type has been defined. PR c++/21581 PR c++/25915 * cp/tree.c (decl_anon_ns_mem_p): New function. * cp/cp-tree.h: Declare it. * cp/decl2.c (determine_visibility): Make anonymous namespace members static. (min_vis_r, constrain_visibility): Likewise. * cp/rtti.c (create_pseudo_type_info): Set TREE_PUBLIC on pseudo-types. * cp/decl.c (cxx_init_decl_processing): Set TREE_PUBLIC on global_namespace. * cp/name-lookup.c (push_namespace_with_attribs): Don't set TREE_PUBLIC on anonymous namespaces. From-SVN: r115086
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c64
1 files changed, 44 insertions, 20 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index dd03a25..ac7dd7d 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -4876,21 +4876,28 @@ handle_weakref_attribute (tree *node, tree ARG_UNUSED (name), tree args,
static tree
handle_visibility_attribute (tree *node, tree name, tree args,
int ARG_UNUSED (flags),
- bool *no_add_attrs)
+ bool *ARG_UNUSED (no_add_attrs))
{
tree decl = *node;
tree id = TREE_VALUE (args);
-
- *no_add_attrs = true;
+ enum symbol_visibility vis;
if (TYPE_P (*node))
{
- if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
- {
- warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
- name);
- return NULL_TREE;
- }
+ if (TREE_CODE (*node) == ENUMERAL_TYPE)
+ /* OK */;
+ else if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
+ name);
+ return NULL_TREE;
+ }
+ else if (TYPE_FIELDS (*node))
+ {
+ error ("%qE attribute ignored because %qT is already defined",
+ name, *node);
+ return NULL_TREE;
+ }
}
else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
{
@@ -4919,23 +4926,33 @@ handle_visibility_attribute (tree *node, tree name, tree args,
}
if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
- DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+ vis = VISIBILITY_DEFAULT;
else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
- DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
+ vis = VISIBILITY_INTERNAL;
else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
- DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ vis = VISIBILITY_HIDDEN;
else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
- DECL_VISIBILITY (decl) = VISIBILITY_PROTECTED;
+ vis = VISIBILITY_PROTECTED;
else
- error ("visibility argument must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
+ {
+ error ("visibility argument must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
+ vis = VISIBILITY_DEFAULT;
+ }
+
+ if (DECL_VISIBILITY_SPECIFIED (decl)
+ && vis != DECL_VISIBILITY (decl)
+ && lookup_attribute ("visibility", (TYPE_P (*node)
+ ? TYPE_ATTRIBUTES (*node)
+ : DECL_ATTRIBUTES (decl))))
+ error ("%qD redeclared with different visibility", decl);
+
+ DECL_VISIBILITY (decl) = vis;
DECL_VISIBILITY_SPECIFIED (decl) = 1;
- /* For decls only, go ahead and attach the attribute to the node as well.
- This is needed so we can determine whether we have VISIBILITY_DEFAULT
- because the visibility was not specified, or because it was explicitly
- overridden from the class visibility. */
- if (DECL_P (*node))
- *no_add_attrs = false;
+ /* Go ahead and attach the attribute to the node as well. This is needed
+ so we can determine whether we have VISIBILITY_DEFAULT because the
+ visibility was not specified, or because it was explicitly overridden
+ from the containing scope. */
return NULL_TREE;
}
@@ -4972,6 +4989,13 @@ c_determine_visibility (tree decl)
return true;
}
+ /* Set default visibility to whatever the user supplied with
+ visibility_specified depending on #pragma GCC visibility. */
+ if (!DECL_VISIBILITY_SPECIFIED (decl))
+ {
+ DECL_VISIBILITY (decl) = default_visibility;
+ DECL_VISIBILITY_SPECIFIED (decl) = visibility_options.inpragma;
+ }
return false;
}