This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ patch] [PR 9283] Implement per-class visibility (new patch)
Ok, how about this version?
--
-Brian Ryner
bryner@brianryner.com
gcc/
2004-04-20 Brian Ryner <bryner@brianryner.com>
PR c++/9283
* c-common.c (c_common_attribute_table): Allow
handle_visibility_attribute to be called for types.
(handle_visibility_attribute) When given a type, set the visibility
bits on the TYPE_NAME. When given a decl, don't set no_add_attrs
so that we can check later whether the attribute was present.
gcc/cp
2004-04-20 Brian Ryner <bryner@brianryner.com>
PR c++/9283
* class.c (build_vtable): Set vtable visibility to class visibility.
(check_field_decls): Default static member visibility to class
visibility.
(check_methods): Default method visibility to class visibility.
* cp-tree.h (CLASSTYPE_VISIBILITY): Add macro.
* rtti.c (get_tinfo_decl): Set typeinfo visibility to class visibility.
(tinfo_base_init): Set typeinfo name visibility to class visibility.
Index: c-common.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.495
diff -u -p -r1.495 c-common.c
--- c-common.c 9 Apr 2004 20:08:02 -0000 1.495
+++ c-common.c 21 Apr 2004 02:37:00 -0000
@@ -832,7 +832,7 @@ const struct attribute_spec c_common_att
handle_deprecated_attribute },
{ "vector_size", 1, 1, false, true, false,
handle_vector_size_attribute },
- { "visibility", 1, 1, true, false, false,
+ { "visibility", 1, 1, false, false, false,
handle_visibility_attribute },
{ "tls_model", 1, 1, true, false, false,
handle_tls_model_attribute },
@@ -4855,7 +4855,9 @@ handle_visibility_attribute (tree *node,
*no_add_attrs = true;
- if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl))
+ if (TREE_CODE (*node) != RECORD_TYPE
+ && TREE_CODE (*node) != UNION_TYPE
+ && (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl)))
{
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
return NULL_TREE;
@@ -4867,6 +4869,14 @@ handle_visibility_attribute (tree *node,
return NULL_TREE;
}
+ /* If this is a type, set the visibility on the type decl. */
+ if (TYPE_P (decl))
+ {
+ decl = TYPE_NAME (decl);
+ if (! decl)
+ return NULL_TREE;
+ }
+
if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
@@ -4877,6 +4887,13 @@ handle_visibility_attribute (tree *node,
DECL_VISIBILITY (decl) = VISIBILITY_PROTECTED;
else
error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
+
+ /* 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;
return NULL_TREE;
}
Index: cp/class.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.607
diff -u -p -r1.607 class.c
--- cp/class.c 20 Apr 2004 02:52:17 -0000 1.607
+++ cp/class.c 21 Apr 2004 02:37:02 -0000
@@ -525,6 +525,9 @@ build_vtable (tree class_type, tree name
DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
DECL_ALIGN (decl));
+ /* The vtable's visibility is the class visibility. There is no way
+ to override the visibility for just the vtable. */
+ DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
import_export_vtable (decl, class_type, 0);
return decl;
@@ -2972,7 +2975,14 @@ check_field_decls (tree t, tree *access_
continue;
if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)
- continue;
+ {
+ /* Apply the class's visibility attribute to static members
+ which do not have a visibility attribute. */
+ if (! lookup_attribute ("visibility", DECL_ATTRIBUTES (x)))
+ DECL_VISIBILITY (x) = CLASSTYPE_VISIBILITY (current_class_type);
+
+ continue;
+ }
/* Now it can only be a FIELD_DECL. */
@@ -3704,6 +3714,11 @@ check_methods (tree t)
check_for_override (x, t);
if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x))
cp_error_at ("initializer specified for non-virtual method `%D'", x);
+
+ /* Apply the class's visibility attribute to methods which do
+ not have a visibility attribute. */
+ if (! lookup_attribute ("visibility", DECL_ATTRIBUTES (x)))
+ DECL_VISIBILITY (x) = CLASSTYPE_VISIBILITY (current_class_type);
/* The name of the field is the original field name
Save this in auxiliary field for later overloading. */
Index: cp/cp-tree.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.962
diff -u -p -r1.962 cp-tree.h
--- cp/cp-tree.h 1 Apr 2004 23:28:08 -0000 1.962
+++ cp/cp-tree.h 21 Apr 2004 02:37:03 -0000
@@ -982,6 +982,9 @@ enum languages { lang_c, lang_cplusplus,
#define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \
(lookup_base ((TYPE), (PARENT), ba_not_special | ba_quiet, NULL) \
!= NULL_TREE)
+
+/* Gives the visibility specification for a class type. */
+#define CLASSTYPE_VISIBILITY(TYPE) DECL_VISIBILITY (TYPE_NAME (TYPE))
/* This is a few header flags for 'struct lang_type'. Actually,
all but the first are used only for lang_type_class; they
Index: cp/rtti.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/rtti.c,v
retrieving revision 1.179
diff -u -p -r1.179 rtti.c
--- cp/rtti.c 8 Mar 2004 22:24:35 -0000 1.179
+++ cp/rtti.c 21 Apr 2004 02:37:03 -0000
@@ -361,7 +361,10 @@ get_tinfo_decl (tree type)
pushdecl_top_level_and_finish (d, NULL_TREE);
if (CLASS_TYPE_P (type))
- CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d;
+ {
+ CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d;
+ DECL_VISIBILITY (d) = CLASSTYPE_VISIBILITY (type);
+ }
/* Remember the type it is for. */
TREE_TYPE (name) = type;
@@ -759,6 +762,8 @@ tinfo_base_init (tree desc, tree target)
TREE_STATIC (name_decl) = 1;
DECL_EXTERNAL (name_decl) = 0;
TREE_PUBLIC (name_decl) = 1;
+ if (CLASS_TYPE_P (target))
+ DECL_VISIBILITY (name_decl) = CLASSTYPE_VISIBILITY (target);
import_export_tinfo (name_decl, target, typeinfo_in_lib_p (target));
/* External name of the string containing the type's name has a
special name. */