diff options
author | Jason Merrill <jason@redhat.com> | 2006-06-29 21:15:56 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2006-06-29 21:15:56 -0400 |
commit | b9e75696307f710a22c726e72b00e7a7161ad89f (patch) | |
tree | 93c1ec7ec5a70cb4b7384fa239594ed2f1288585 /gcc/c-common.c | |
parent | dc2843f38c04c81e9f20a6e9e6ae9637ace6e08c (diff) | |
download | gcc-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.c | 64 |
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; } |