attribs.c (c_common_attribute_table): Add visibility.
* attribs.c (c_common_attribute_table): Add visibility. (handle_visibility_attribute): New function. * varasm.c (assemble_visibility): New function. * output.h (assemble_visibility): Add prototype. * tree.h (MODULE_LOCAL_P): Define. * crtstuff.c (__dso_handle): Use visibility attribute. * config/i386/i386.h (ENCODE_SECTION_INFO): Set SYMBOL_REF_FLAG for MODULE_LOCAL_P symbols too. * config/ia64/ia64.c (ia64_encode_section_info): Handle MODULE_LOCAL_P symbols the same way as local symbols. Add SDATA_NAME_FLAG_CHAR even if decl was explicitely forced into .sdata/.sbss by the user. * doc/extend.texi (Function Attributes): Document visibility attribute. * gcc.dg/ia64-visibility-1.c: New test. From-SVN: r50061
This commit is contained in:
parent
6d73371a68
commit
47bd70b56a
@ -1,3 +1,20 @@
|
||||
2002-02-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* attribs.c (c_common_attribute_table): Add visibility.
|
||||
(handle_visibility_attribute): New function.
|
||||
* varasm.c (assemble_visibility): New function.
|
||||
* output.h (assemble_visibility): Add prototype.
|
||||
* tree.h (MODULE_LOCAL_P): Define.
|
||||
* crtstuff.c (__dso_handle): Use visibility attribute.
|
||||
* config/i386/i386.h (ENCODE_SECTION_INFO): Set SYMBOL_REF_FLAG
|
||||
for MODULE_LOCAL_P symbols too.
|
||||
* config/ia64/ia64.c (ia64_encode_section_info): Handle
|
||||
MODULE_LOCAL_P symbols the same way as local symbols.
|
||||
Add SDATA_NAME_FLAG_CHAR even if decl was explicitely forced
|
||||
into .sdata/.sbss by the user.
|
||||
* doc/extend.texi (Function Attributes): Document visibility
|
||||
attribute.
|
||||
|
||||
2002-02-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR debug/5770
|
||||
|
@ -75,6 +75,8 @@ static tree handle_weak_attribute PARAMS ((tree *, tree, tree, int,
|
||||
bool *));
|
||||
static tree handle_alias_attribute PARAMS ((tree *, tree, tree, int,
|
||||
bool *));
|
||||
static tree handle_visibility_attribute PARAMS ((tree *, tree, tree, int,
|
||||
bool *));
|
||||
static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree,
|
||||
tree, int,
|
||||
bool *));
|
||||
@ -148,6 +150,8 @@ static const struct attribute_spec c_common_attribute_table[] =
|
||||
handle_deprecated_attribute },
|
||||
{ "vector_size", 1, 1, false, true, false,
|
||||
handle_vector_size_attribute },
|
||||
{ "visibility", 1, 1, true, false, false,
|
||||
handle_visibility_attribute },
|
||||
{ NULL, 0, 0, false, false, false, NULL }
|
||||
};
|
||||
|
||||
@ -1061,6 +1065,50 @@ handle_alias_attribute (node, name, args, flags, no_add_attrs)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Handle an "visibility" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
static tree
|
||||
handle_visibility_attribute (node, name, args, flags, no_add_attrs)
|
||||
tree *node;
|
||||
tree name;
|
||||
tree args;
|
||||
int flags ATTRIBUTE_UNUSED;
|
||||
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"))
|
||||
{
|
||||
error ("visibility arg must be one of \"hidden\", \"protected\" or \"internal\"");
|
||||
*no_add_attrs = true;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
assemble_visibility (decl, TREE_STRING_POINTER (id));
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Handle a "no_instrument_function" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
|
@ -2266,7 +2266,9 @@ do { \
|
||||
\
|
||||
SYMBOL_REF_FLAG (XEXP (rtl, 0)) \
|
||||
= (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
|
||||
|| ! TREE_PUBLIC (DECL)); \
|
||||
|| ! TREE_PUBLIC (DECL) \
|
||||
|| (TREE_CODE (DECL) == VAR_DECL \
|
||||
&& MODULE_LOCAL_P (DECL))); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
@ -6897,13 +6897,14 @@ ia64_encode_section_info (decl)
|
||||
statically allocated, but the space is allocated somewhere else. Such
|
||||
decls can not be own data. */
|
||||
if (! TARGET_NO_SDATA
|
||||
&& TREE_STATIC (decl) && ! DECL_EXTERNAL (decl)
|
||||
&& ! (DECL_ONE_ONLY (decl) || DECL_WEAK (decl))
|
||||
&& ! (TREE_PUBLIC (decl)
|
||||
&& (flag_pic
|
||||
|| (DECL_COMMON (decl)
|
||||
&& (DECL_INITIAL (decl) == 0
|
||||
|| DECL_INITIAL (decl) == error_mark_node))))
|
||||
&& ((TREE_STATIC (decl) && ! DECL_EXTERNAL (decl)
|
||||
&& ! (DECL_ONE_ONLY (decl) || DECL_WEAK (decl))
|
||||
&& ! (TREE_PUBLIC (decl)
|
||||
&& (flag_pic
|
||||
|| (DECL_COMMON (decl)
|
||||
&& (DECL_INITIAL (decl) == 0
|
||||
|| DECL_INITIAL (decl) == error_mark_node)))))
|
||||
|| MODULE_LOCAL_P (decl))
|
||||
/* Either the variable must be declared without a section attribute,
|
||||
or the section must be sdata or sbss. */
|
||||
&& (DECL_SECTION_NAME (decl) == 0
|
||||
@ -6923,9 +6924,12 @@ ia64_encode_section_info (decl)
|
||||
;
|
||||
|
||||
/* If this is an incomplete type with size 0, then we can't put it in
|
||||
sdata because it might be too big when completed. */
|
||||
else if (size > 0
|
||||
&& size <= (HOST_WIDE_INT) ia64_section_threshold
|
||||
sdata because it might be too big when completed.
|
||||
Objects bigger than threshold should have SDATA_NAME_FLAG_CHAR
|
||||
added if they are in .sdata or .sbss explicitely. */
|
||||
else if (((size > 0
|
||||
&& size <= (HOST_WIDE_INT) ia64_section_threshold)
|
||||
|| DECL_SECTION_NAME (decl))
|
||||
&& symbol_str[0] != SDATA_NAME_FLAG_CHAR)
|
||||
{
|
||||
size_t len = strlen (symbol_str);
|
||||
|
@ -213,13 +213,9 @@ STATIC void *__JCR_LIST__[]
|
||||
in one DSO or the main program is not used in another object. The
|
||||
dynamic linker takes care of this. */
|
||||
|
||||
/* XXX Ideally the following should be implemented using
|
||||
__attribute__ ((__visibility__ ("hidden")))
|
||||
but the __attribute__ support is not yet there. */
|
||||
#ifdef HAVE_GAS_HIDDEN
|
||||
asm (".hidden\t__dso_handle");
|
||||
extern void *__dso_handle __attribute__ ((__visibility__ ("hidden")));
|
||||
#endif
|
||||
|
||||
#ifdef CRTSTUFFS_O
|
||||
void *__dso_handle = &__dso_handle;
|
||||
#else
|
||||
|
@ -2198,7 +2198,7 @@ The @code{alias} attribute causes the declaration to be emitted as an
|
||||
alias for another symbol, which must be specified. For instance,
|
||||
|
||||
@smallexample
|
||||
void __f () @{ /* do something */; @}
|
||||
void __f () @{ /* @r{Do something.} */; @}
|
||||
void f () __attribute__ ((weak, alias ("__f")));
|
||||
@end smallexample
|
||||
|
||||
@ -2207,6 +2207,19 @@ mangled name for the target must be used.
|
||||
|
||||
Not all target machines support this attribute.
|
||||
|
||||
@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")))
|
||||
f () @{ /* @r{Do something.} */; @}
|
||||
int i __attribute__ ((visibility ("hidden")));
|
||||
@end smallexample
|
||||
|
||||
Not all ELF targets support this attribute.
|
||||
|
||||
@item regparm (@var{number})
|
||||
@cindex functions that are passed arguments in registers on the 386
|
||||
On the Intel 386, the @code{regparm} attribute causes the compiler to
|
||||
|
@ -255,6 +255,8 @@ extern void assemble_constant_align PARAMS ((tree));
|
||||
|
||||
extern void assemble_alias PARAMS ((tree, tree));
|
||||
|
||||
extern void assemble_visibility PARAMS ((tree, const char *));
|
||||
|
||||
/* Output a string of literal assembler code
|
||||
for an `asm' keyword used between functions. */
|
||||
extern void assemble_asm PARAMS ((tree));
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
* g++.dg/debug/debug4.C: New test.
|
||||
|
||||
* gcc.dg/ia64-visibility-1.c: New test.
|
||||
|
||||
2002-02-26 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* gcc.dg/debug/20020224-1.c: New.
|
||||
|
36
gcc/testsuite/gcc.dg/ia64-visibility-1.c
Normal file
36
gcc/testsuite/gcc.dg/ia64-visibility-1.c
Normal file
@ -0,0 +1,36 @@
|
||||
/* Test visibility attribute. */
|
||||
/* { dg-do compile { target ia64*-*-linux* } } */
|
||||
/* { dg-options "-O2 -fpic" } */
|
||||
/* { dg-final { scan-assembler "\\.hidden.*variable_j" } } */
|
||||
/* { dg-final { scan-assembler "\\.hidden.*variable_m" } } */
|
||||
/* { dg-final { scan-assembler "\\.protected.*baz" } } */
|
||||
/* { dg-final { scan-assembler "gprel.*variable_i" } } */
|
||||
/* { dg-final { scan-assembler "gprel.*variable_j" } } */
|
||||
/* { dg-final { scan-assembler "ltoff.*variable_k" } } */
|
||||
/* { dg-final { scan-assembler "gprel.*variable_l" } } */
|
||||
/* { dg-final { scan-assembler "gprel.*variable_m" } } */
|
||||
/* { dg-final { scan-assembler "ltoff.*variable_n" } } */
|
||||
|
||||
static int variable_i;
|
||||
int variable_j __attribute__((visibility ("hidden")));
|
||||
int variable_k;
|
||||
struct A { char a[64]; };
|
||||
static struct A variable_l __attribute__((section (".sbss")));
|
||||
struct A variable_m __attribute__((visibility ("hidden"), section(".sbss")));
|
||||
struct A variable_n __attribute__((section (".sbss")));
|
||||
|
||||
int foo (void)
|
||||
{
|
||||
return variable_i + variable_j + variable_k;
|
||||
}
|
||||
|
||||
void bar (void)
|
||||
{
|
||||
variable_l.a[10] = 0;
|
||||
variable_m.a[10] = 0;
|
||||
variable_n.a[10] = 0;
|
||||
}
|
||||
|
||||
void __attribute__((visibility ("protected"))) baz (void)
|
||||
{
|
||||
}
|
@ -2283,6 +2283,11 @@ extern tree merge_attributes PARAMS ((tree, tree));
|
||||
extern tree merge_dllimport_decl_attributes PARAMS ((tree, tree));
|
||||
#endif
|
||||
|
||||
/* Return true if DECL will be always resolved to a symbol defined in the
|
||||
same module (shared library or program). */
|
||||
#define MODULE_LOCAL_P(DECL) \
|
||||
(lookup_attribute ("visibility", DECL_ATTRIBUTES (DECL)) != NULL)
|
||||
|
||||
/* Return a version of the TYPE, qualified as indicated by the
|
||||
TYPE_QUALS, if one exists. If no qualified version exists yet,
|
||||
return NULL_TREE. */
|
||||
|
19
gcc/varasm.c
19
gcc/varasm.c
@ -5160,6 +5160,25 @@ assemble_alias (decl, target)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Emit an assembler directive to set symbol for DECL visibility to
|
||||
VISIBILITY_TYPE. */
|
||||
|
||||
void
|
||||
assemble_visibility (decl, visibility_type)
|
||||
tree decl;
|
||||
const char *visibility_type ATTRIBUTE_UNUSED;
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = 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
|
||||
}
|
||||
|
||||
/* Returns 1 if the target configuration supports defining public symbols
|
||||
so that one of them will be chosen at link time instead of generating a
|
||||
multiply-defined symbol error, whether through the use of weak symbols or
|
||||
|
Loading…
Reference in New Issue
Block a user