This is the mail archive of the gcc@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: Visibility attribute (was: proposed change: weak symbol support for Darwin)


On Wednesday, October 15, 2003, at 06:33 PM, Matt Austern wrote:

On Monday, October 13, 2003, at 05:46 PM, Alexandre Oliva wrote:

On Oct 13, 2003, Matt Austern <austern@apple.com> wrote:

symbols that are public within a dynamic library but that aren't
exported beyond the scope of the library boundary.

Like attribute hidden?

I didn't know about the visibility attribute until Alexandre pointed it out to me. But now that I've looked at it, I can answer that question...

Yes, Apple's notion of private extern symbols looks very much
like __attribute__ ((visibility("hidden"))).  It looks so
similar that it would be silly to have two separate
mechanisms.

So I have changed my mind.  I don't want to take one bit in a
decl node for private_extern.  Instead I want to take two bits
and use them for enum symbol_visibility.  Attributes are a
fine user-level syntax, but I don't like using the attribute
mechanism internally for this.

To be more precise, this is the sort of thing I have in mind. Caveat: I haven't tested this code yet, so it's quite possible there are typos and such. I'm posting it to show the general idea I have in mind. If people agree it's the right approach, then I'll test it and submit it as an official patch.

--Matt

Index: gcc/c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.463
diff -p -r1.463 c-common.c
*** gcc/c-common.c	12 Oct 2003 22:09:20 -0000	1.463
--- gcc/c-common.c	16 Oct 2003 03:48:50 -0000
*************** handle_visibility_attribute (tree *node,
*** 4915,4947 ****
  			     bool *no_add_attrs)
  {
    tree decl = *node;

    if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl))
      {
        warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
!       *no_add_attrs = true;
      }
-   else
-     {
-       tree id;

! id = TREE_VALUE (args);
! if (TREE_CODE (id) != STRING_CST)
! {
! error ("visibility arg not a string");
! *no_add_attrs = true;
! return NULL_TREE;
! }
! 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;
! }
}


    return NULL_TREE;
  }
--- 4915,4946 ----
  			     bool *no_add_attrs)
  {
    tree decl = *node;
+   tree id = TREE_VALUE (args);
+
+   *no_add_attrs = true;

    if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl))
      {
        warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
!       return NULL_TREE;
      }

! if (TREE_CODE (id) != STRING_CST)
! {
! error ("visibility arg not a string");
! return NULL_TREE;
}
+
+ if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
+ DECL_VISIBILIY (decl) == VISIBILITY_DEFAULT;
+ else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
+ DECL_VISIBILIY (decl) == VISIBILITY_INTERNAL;
+ else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
+ DECL_VISIBILIY (decl) == VISIBILITY_HIDDEN;
+ else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
+ DECL_VISIBILIY (decl) == VISIBILITY_PROTECTED;
+ else
+ error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");


    return NULL_TREE;
  }
Index: gcc/tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.448
diff -p -r1.448 tree.h
*** gcc/tree.h	9 Oct 2003 05:44:51 -0000	1.448
--- gcc/tree.h	16 Oct 2003 03:48:53 -0000
*************** struct tree_type GTY(())
*** 1489,1494 ****
--- 1489,1497 ----
  #define DECL_DECLARED_INLINE_P(NODE) \
    (FUNCTION_DECL_CHECK (NODE)->decl.declared_inline_flag)

+ /* Value of the decls's visibility attribute */
+ #define DECL_VISIBILITY(NODE) (DECL_CHECK (node)->decl.visibility)
+
/* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */
#define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable)


*************** struct tree_type GTY(())
*** 1629,1634 ****
--- 1632,1647 ----
    (! DECL_CONTEXT (EXP)						\
     || TREE_CODE (DECL_CONTEXT (EXP)) == TRANSLATION_UNIT_DECL)

+ /* Enumerate visibility settings.  */
+
+ enum symbol_visibility
+ {
+   VISIBILITY_DEFAULT,
+   VISIBILITY_INTERNAL,
+   VISIBILITY_HIDDEN,
+   VISIBILITY_PROTECTED
+ };
+
  struct function;

  struct tree_decl GTY(())
*************** struct tree_decl GTY(())
*** 1670,1677 ****
    unsigned uninlinable : 1;
    unsigned thread_local_flag : 1;
    unsigned declared_inline_flag : 1;
!   unsigned unused : 3;
!   /* three unused bits.  */

    unsigned lang_flag_0 : 1;
    unsigned lang_flag_1 : 1;
--- 1683,1691 ----
    unsigned uninlinable : 1;
    unsigned thread_local_flag : 1;
    unsigned declared_inline_flag : 1;
!   enum symbol_visibility visibility : 2;
!   unsigned unused : 1;
!   /* one unused bit.  */

    unsigned lang_flag_0 : 1;
    unsigned lang_flag_1 : 1;
*************** enum tls_model {
*** 2005,2019 ****

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:

--- 2019,2024 ----
*************** extern void make_decl_one_only (tree);
*** 2967,2973 ****
  extern int supports_one_only (void);
  extern void variable_section (tree, int);
  enum tls_model decl_tls_model (tree);
- enum symbol_visibility decl_visibility (tree);
  extern void resolve_unique_section (tree, int, int);
  extern void mark_referenced (tree);
  extern void notice_global_symbol (tree);
--- 2972,2977 ----
Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.391
diff -p -r1.391 varasm.c
*** gcc/varasm.c	11 Oct 2003 17:38:28 -0000	1.391
--- gcc/varasm.c	16 Oct 2003 03:48:56 -0000
*************** default_assemble_visibility (tree decl,
*** 4417,4423 ****
  static void
  maybe_assemble_visibility (tree decl)
  {
!   enum symbol_visibility vis = decl_visibility (decl);

    if (vis != VISIBILITY_DEFAULT)
      (* targetm.asm_out.visibility) (decl, vis);
--- 4417,4423 ----
  static void
  maybe_assemble_visibility (tree decl)
  {
!   enum symbol_visibility vis = DECL_VISIBILITY (decl);

    if (vis != VISIBILITY_DEFAULT)
      (* targetm.asm_out.visibility) (decl, vis);
*************** decl_tls_model (tree decl)
*** 4519,4548 ****
    return kind;
  }

- enum symbol_visibility
- decl_visibility (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
of DECL and whether or not RELOC indicates that DECL's initializer
might contain runtime relocations.
--- 4519,4524 ----
*************** default_binds_local_p_1 (tree exp, int s
*** 5118,5124 ****
else if (! TREE_PUBLIC (exp))
local_p = true;
/* A variable is local if the user tells us so. */
! else if (decl_visibility (exp) != VISIBILITY_DEFAULT)
local_p = true;
/* Otherwise, variables defined outside this object may not be local. */
else if (DECL_EXTERNAL (exp))
--- 5094,5100 ----
else if (! TREE_PUBLIC (exp))
local_p = true;
/* A variable is local if the user tells us so. */
! else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
local_p = true;
/* Otherwise, variables defined outside this object may not be local. */
else if (DECL_EXTERNAL (exp))



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