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]

__attribute__((visibility("default")))


The following is needed if we are to ever support command-line
options that cause all symbols that do not have an explicit
visibility attribute to be given a visibility other than "default".

Such a thing was proposed by Intel folks some months ago, and
it didn't seem unreasonable to me.  I'm still trying to decide
if I'm going to go ahead and implement their proposal.  I can
see a use for at least -fvisibility=protected in the Linux kernel...

Applied to mainline, since no released version supports the
visibility attribute yet.


r~


	* c-common.c (handle_visibility_attribute): Accept "default".
	* tree.h (enum symbol_visibility): New.
	(decl_visibility): Declare.
	* target.h (gcc_target.visibility): Take visibility arg as integer.
	* varasm.c (default_assemble_visibility): Likewise.
	(decl_visibility): New.
	(maybe_assemble_visibility): Use it.
	* output.h (default_assemble_visibility): Update prototype.
	* config/rs6000/rs6000.c (rs6000_assemble_visibility): Take
	visibility arg as integer.
	* doc/extend.texi: Document default visibility.

Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.390
diff -c -p -d -r1.390 c-common.c
*** c-common.c	31 Oct 2002 06:57:28 -0000	1.390
--- c-common.c	27 Nov 2002 06:06:53 -0000
*************** handle_visibility_attribute (node, name,
*** 5891,5899 ****
  	}
        if (strcmp (TREE_STRING_POINTER (id), "hidden")
  	  && strcmp (TREE_STRING_POINTER (id), "protected")
! 	  && strcmp (TREE_STRING_POINTER (id), "internal"))
  	{
! 	  error ("visibility arg must be one of \"hidden\", \"protected\" or \"internal\"");
  	  *no_add_attrs = true;
  	  return NULL_TREE;
  	}
--- 5891,5900 ----
  	}
        if (strcmp (TREE_STRING_POINTER (id), "hidden")
  	  && strcmp (TREE_STRING_POINTER (id), "protected")
! 	  && strcmp (TREE_STRING_POINTER (id), "internal")
! 	  && strcmp (TREE_STRING_POINTER (id), "default"))
  	{
! 	  error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
  	  *no_add_attrs = true;
  	  return NULL_TREE;
  	}
Index: output.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/output.h,v
retrieving revision 1.114
diff -c -p -d -r1.114 output.h
*** output.h	22 Oct 2002 07:59:40 -0000	1.114
--- output.h	27 Nov 2002 06:06:54 -0000
*************** extern void assemble_constant_align	PARA
*** 253,259 ****
  
  extern void assemble_alias		PARAMS ((tree, tree));
  
! extern void default_assemble_visibility	PARAMS ((tree, const char *));
  
  /* Output a string of literal assembler code
     for an `asm' keyword used between functions.  */
--- 253,259 ----
  
  extern void assemble_alias		PARAMS ((tree, tree));
  
! extern void default_assemble_visibility	PARAMS ((tree, int));
  
  /* Output a string of literal assembler code
     for an `asm' keyword used between functions.  */
Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.42
diff -c -p -d -r1.42 target.h
*** target.h	16 Nov 2002 17:52:53 -0000	1.42
--- target.h	27 Nov 2002 06:06:54 -0000
*************** struct gcc_target
*** 74,80 ****
  
      /* Emit an assembler directive to set visibility for the symbol
         associated with the tree decl.  */
!     void (* visibility) PARAMS ((tree, const char *));
  
      /* Output the assembler code for entry to a function.  */
      void (* function_prologue) PARAMS ((FILE *, HOST_WIDE_INT));
--- 74,80 ----
  
      /* Emit an assembler directive to set visibility for the symbol
         associated with the tree decl.  */
!     void (* visibility) PARAMS ((tree, int));
  
      /* Output the assembler code for entry to a function.  */
      void (* function_prologue) PARAMS ((FILE *, HOST_WIDE_INT));
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.363
diff -c -p -d -r1.363 tree.h
*** tree.h	27 Nov 2002 02:47:44 -0000	1.363
--- tree.h	27 Nov 2002 06:06:54 -0000
*************** enum tls_model {
*** 2133,2138 ****
--- 2133,2148 ----
  };
  
  extern enum tls_model flag_tls_default;
+ 
+ /* Enumerate visibility settings.  */
+ 
+ enum symbol_visibility
+ {
+   VISIBILITY_DEFAULT,
+   VISIBILITY_INTERNAL,
+   VISIBILITY_HIDDEN,
+   VISIBILITY_PROTECTED
+ };
  
  /* A pointer-to-function member type looks like:
  
*************** extern void make_decl_one_only		PARAMS (
*** 3043,3048 ****
--- 3053,3059 ----
  extern int supports_one_only		PARAMS ((void));
  extern void variable_section		PARAMS ((tree, int));
  enum tls_model decl_tls_model		PARAMS ((tree));
+ enum symbol_visibility decl_visibility	PARAMS ((tree));
  
  /* In fold-const.c */
  extern int div_and_round_double		PARAMS ((enum tree_code, int,
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.321
diff -c -p -d -r1.321 varasm.c
*** varasm.c	26 Nov 2002 12:36:09 -0000	1.321
--- varasm.c	27 Nov 2002 06:06:54 -0000
*************** assemble_alias (decl, target)
*** 4643,4662 ****
  }
  
  /* Emit an assembler directive to set symbol for DECL visibility to
!    VISIBILITY_TYPE.  */
  
  void
! default_assemble_visibility (decl, visibility_type)
       tree decl;
!      const char *visibility_type ATTRIBUTE_UNUSED;
  {
!   const char *name;
  
    name = (* targetm.strip_name_encoding)
  	 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
  
  #ifdef HAVE_GAS_HIDDEN
!   fprintf (asm_out_file, "\t.%s\t%s\n", visibility_type, name);
  #else
    warning ("visibility attribute not supported in this configuration; ignored");
  #endif
--- 4643,4667 ----
  }
  
  /* Emit an assembler directive to set symbol for DECL visibility to
!    the visibility type VIS, which must not be VISIBILITY_DEFAULT.  */
  
  void
! default_assemble_visibility (decl, vis)
       tree decl;
!      int vis;
  {
!   static const char * const visibility_types[] = {
!     NULL, "internal", "hidden", "protected"
!   };
! 
!   const char *name, *type;
  
    name = (* targetm.strip_name_encoding)
  	 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+   type = visibility_types[vis];
  
  #ifdef HAVE_GAS_HIDDEN
!   fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
  #else
    warning ("visibility attribute not supported in this configuration; ignored");
  #endif
*************** static void
*** 4668,4680 ****
  maybe_assemble_visibility (decl)
       tree decl;
  {
!   tree visibility = lookup_attribute ("visibility", DECL_ATTRIBUTES (decl));
!   if (visibility)
!     {
!       const char *type
! 	= TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (visibility)));
!       (* targetm.asm_out.visibility) (decl, type);
!     }
  }
  
  /* Returns 1 if the target configuration supports defining public symbols
--- 4673,4682 ----
  maybe_assemble_visibility (decl)
       tree decl;
  {
!   enum symbol_visibility vis = decl_visibility (decl);
! 
!   if (vis != VISIBILITY_DEFAULT)
!     (* targetm.asm_out.visibility) (decl, vis);
  }
  
  /* Returns 1 if the target configuration supports defining public symbols
*************** decl_tls_model (decl)
*** 4773,4778 ****
--- 4775,4805 ----
      kind = flag_tls_default;
  
    return kind;
+ }
+ 
+ enum symbol_visibility
+ decl_visibility (decl)
+      tree decl;
+ {
+   tree attr = lookup_attribute ("visibility", DECL_ATTRIBUTES (decl));
+ 
+   if (attr)
+     {
+       const char *which = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
+ 
+       if (strcmp (which, "default") == 0)
+ 	return VISIBILITY_DEFAULT;
+       if (strcmp (which, "internal") == 0)
+ 	return VISIBILITY_INTERNAL;
+       if (strcmp (which, "hidden") == 0)
+ 	return VISIBILITY_HIDDEN;
+       if (strcmp (which, "protected") == 0)
+ 	return VISIBILITY_PROTECTED;
+ 
+       abort ();
+     }
+ 
+   return VISIBILITY_DEFAULT;
  }
  
  /* Select a set of attributes for section NAME based on the properties
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.400
diff -c -p -d -r1.400 rs6000.c
*** config/rs6000/rs6000.c	25 Nov 2002 19:40:00 -0000	1.400
--- config/rs6000/rs6000.c	27 Nov 2002 06:06:55 -0000
*************** static int constant_pool_expr_1 PARAMS (
*** 186,192 ****
  static struct machine_function * rs6000_init_machine_status PARAMS ((void));
  static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
  #ifdef HAVE_GAS_HIDDEN
! static void rs6000_assemble_visibility PARAMS ((tree, const char *));
  #endif
  static int rs6000_ra_ever_killed PARAMS ((void));
  static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
--- 186,192 ----
  static struct machine_function * rs6000_init_machine_status PARAMS ((void));
  static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
  #ifdef HAVE_GAS_HIDDEN
! static void rs6000_assemble_visibility PARAMS ((tree, int));
  #endif
  static int rs6000_ra_ever_killed PARAMS ((void));
  static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
*************** rs6000_assemble_integer (x, size, aligne
*** 8157,8179 ****
     VISIBILITY_TYPE.  */
  
  static void
! rs6000_assemble_visibility (decl, visibility_type)
       tree decl;
!      const char *visibility_type;
  {
-   default_assemble_visibility (decl, visibility_type);
- 
    /* Functions need to have their entry point symbol visibility set as
       well as their descriptor symbol visibility.  */
    if (DEFAULT_ABI == ABI_AIX && TREE_CODE (decl) == FUNCTION_DECL)
      {
!       const char *name;
  
        name = ((* targetm.strip_name_encoding)
  	      (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
  
!       fprintf (asm_out_file, "\t.%s\t.%s\n", visibility_type, name);
      }
  }
  #endif
  
--- 8157,8185 ----
     VISIBILITY_TYPE.  */
  
  static void
! rs6000_assemble_visibility (decl, vis)
       tree decl;
!      int vis;
  {
    /* Functions need to have their entry point symbol visibility set as
       well as their descriptor symbol visibility.  */
    if (DEFAULT_ABI == ABI_AIX && TREE_CODE (decl) == FUNCTION_DECL)
      {
!       static const char * const visibility_types[] = {
!         NULL, "internal", "hidden", "protected"
!       };
! 
!       const char *name, *type;
  
        name = ((* targetm.strip_name_encoding)
  	      (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
+       type = visibility_types[vis];
  
!       fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
!       fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
      }
+   else
+     default_assemble_visibility (decl, vis);
  }
  #endif
  
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.107
diff -c -p -d -r1.107 extend.texi
*** doc/extend.texi	16 Oct 2002 13:14:21 -0000	1.107
--- doc/extend.texi	27 Nov 2002 06:16:30 -0000
*************** Not all target machines support this att
*** 2307,2313 ****
  @item visibility ("@var{visibility_type}")
  @cindex @code{visibility} attribute
  The @code{visibility} attribute on ELF targets causes the declaration
! to be emitted with hidden, protected or internal visibility.
  
  @smallexample
  void __attribute__ ((visibility ("protected")))
--- 2307,2313 ----
  @item visibility ("@var{visibility_type}")
  @cindex @code{visibility} attribute
  The @code{visibility} attribute on ELF targets causes the declaration
! to be emitted with default, hidden, protected or internal visibility.
  
  @smallexample
  void __attribute__ ((visibility ("protected")))
*************** int i __attribute__ ((visibility ("hidde
*** 2318,2323 ****
--- 2318,2328 ----
  See the ELF gABI for complete details, but the short story is
  
  @table @dfn
+ @item default
+ Default visibility is the normal case for ELF.  This value is 
+ available for the visibiliy attribute to override other options
+ that may change the assumed visibility of symbols.
+ 
  @item hidden
  Hidden visibility indicates that the symbol will not be placed into
  the dynamic symbol table, so no other @dfn{module} (executable or


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