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]

PATCH: (Darwin weak symbol support): introduce decl visibility bits


This patch changes the internal representation of the "visibility" attribute.
Currently the compiler uses an attribute structure hanging off the decl's
attribute list; this patch gets rid of that structure and introduces a visibility
bit field. Previously decls had three unused bits; I grabbed two of them.


This patch is the first step in weak symbol support for Darwin.  It's
necessary because, on Darwin at least, weak symbol support involves
manipulating symbol visibility, and attribute structures, which rely on
string lookup, are an expensive way to do that.

Testing: applied to mainline, bootstrapped on linux, ran 'make check'. No
regress. (No changes in test results for g++, g77, or objc. In the C test suite,
two tests that failed on the unmodified tree passed with my patch. I don't
think that's really because I fixed any bugs with this patch; I'm inclined to call
it experimental error.)


OK to commit to mainline?

--Matt


Index: gcc/c-common.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/c-common.c,v retrieving revision 1.465 diff -p -r1.465 c-common.c *** gcc/c-common.c 20 Oct 2003 22:03:32 -0000 1.465 --- gcc/c-common.c 5 Nov 2003 20:07:40 -0000 *************** handle_visibility_attribute (tree *node, *** 4929,4961 **** 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;
  }
--- 4929,4960 ----
  			     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_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+ else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
+ DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
+ else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
+ DECL_VISIBILITY (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.450
diff -p -r1.450 tree.h
*** gcc/tree.h	26 Oct 2003 08:31:09 -0000	1.450
--- gcc/tree.h	5 Nov 2003 20:07:40 -0000
*************** struct tree_type GTY(())
*** 1491,1496 ****
--- 1491,1499 ----
  #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(())
*** 1631,1636 ****
--- 1634,1649 ----
    (! 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(())
*** 1672,1679 ****
    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;
--- 1685,1693 ----
    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 {
*** 2007,2021 ****

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:

--- 2021,2026 ----
*************** extern void make_decl_one_only (tree);
*** 2969,2975 ****
  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);
--- 2974,2979 ----
Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.396
diff -p -r1.396 varasm.c
*** gcc/varasm.c	4 Nov 2003 09:14:18 -0000	1.396
--- gcc/varasm.c	5 Nov 2003 20:07:40 -0000
*************** default_assemble_visibility (tree decl,
*** 4430,4436 ****
  static void
  maybe_assemble_visibility (tree decl)
  {
!   enum symbol_visibility vis = decl_visibility (decl);

    if (vis != VISIBILITY_DEFAULT)
      (* targetm.asm_out.visibility) (decl, vis);
--- 4430,4436 ----
  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)
*** 4532,4561 ****
    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.
--- 4532,4537 ----
*************** default_binds_local_p_1 (tree exp, int s
*** 5131,5137 ****
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))
--- 5107,5113 ----
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: gcc/cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1150
diff -p -r1.1150 decl.c
*** gcc/cp/decl.c 24 Oct 2003 07:59:40 -0000 1.1150
--- gcc/cp/decl.c 5 Nov 2003 20:07:40 -0000
*************** duplicate_decls (tree newdecl, tree oldd
*** 1850,1855 ****
--- 1850,1856 ----
TREE_ADDRESSABLE (newdecl) = TREE_ADDRESSABLE (olddecl);
TREE_ASM_WRITTEN (newdecl) = TREE_ASM_WRITTEN (olddecl);
DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
+ DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);


    if (TREE_CODE (newdecl) == FUNCTION_DECL)
Index: gcc/cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.270
diff -p -r1.270 method.c
*** gcc/cp/method.c	24 Oct 2003 07:59:40 -0000	1.270
--- gcc/cp/method.c	5 Nov 2003 20:07:40 -0000
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 383,388 ****
--- 383,389 ----
    /* The linkage of the function may have changed.  FIXME in linkage
       rewrite.  */
    TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
+   DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);

    if (flag_syntax_only)
      {
Index: gcc/cp/optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/optimize.c,v
retrieving revision 1.101
diff -p -r1.101 optimize.c
*** gcc/cp/optimize.c	22 Sep 2003 05:09:23 -0000	1.101
--- gcc/cp/optimize.c	5 Nov 2003 20:07:40 -0000
*************** maybe_clone_body (tree fn)
*** 158,163 ****
--- 158,164 ----
        DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
        DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
        TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
+       DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);

        /* Adjust the parameter names and locations.  */
        parm = DECL_ARGUMENTS (fn);


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