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)


How's this?

Jason Merrill wrote:
On Tue, 20 Apr 2004 23:06:09 -0500, Brian Ryner <bryner@brianryner.com> wrote:


-  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;


This code should reject the attribute for types other than record/union.

Jason


--
-Brian Ryner
bryner@brianryner.com
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	22 Apr 2004 02:13:39 -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,16 @@ handle_visibility_attribute (tree *node,
 
   *no_add_attrs = true;
 
-  if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl))
+  if (TYPE_P (*node))
+    {
+      if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
+	{
+	  warning ("`%s' attribute ignored on non-class types",
+		   IDENTIFIER_POINTER (name));
+	  return NULL_TREE;
+	}
+    }
+  else if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl))
     {
       warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
       return NULL_TREE;
@@ -4867,6 +4876,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 +4894,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	22 Apr 2004 02:13:43 -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	22 Apr 2004 02:13:43 -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	22 Apr 2004 02:13:44 -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]