This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Visibility attribute (was: proposed change: weak symbol support for Darwin)
- From: Matt Austern <austern at apple dot com>
- To: Matt Austern <austern at apple dot com>
- Cc: Alexandre Oliva <aoliva at redhat dot com>, GCC list <gcc at gcc dot gnu dot org>
- Date: Wed, 15 Oct 2003 20:55:20 -0700
- Subject: 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))