This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]