Commit 47bd70b5 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 6d73371a
2002-02-26 Jakub Jelinek <jakub@redhat.com> 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 PR debug/5770
* dwarf2out.c (rtl_for_decl_location): Return CONST_STRING for * dwarf2out.c (rtl_for_decl_location): Return CONST_STRING for
STRING_CST initializer spanning the whole variable without STRING_CST initializer spanning the whole variable without
......
...@@ -75,6 +75,8 @@ static tree handle_weak_attribute PARAMS ((tree *, tree, tree, int, ...@@ -75,6 +75,8 @@ static tree handle_weak_attribute PARAMS ((tree *, tree, tree, int,
bool *)); bool *));
static tree handle_alias_attribute PARAMS ((tree *, tree, tree, int, static tree handle_alias_attribute PARAMS ((tree *, tree, tree, int,
bool *)); bool *));
static tree handle_visibility_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree, static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree,
tree, int, tree, int,
bool *)); bool *));
...@@ -148,6 +150,8 @@ static const struct attribute_spec c_common_attribute_table[] = ...@@ -148,6 +150,8 @@ static const struct attribute_spec c_common_attribute_table[] =
handle_deprecated_attribute }, handle_deprecated_attribute },
{ "vector_size", 1, 1, false, true, false, { "vector_size", 1, 1, false, true, false,
handle_vector_size_attribute }, handle_vector_size_attribute },
{ "visibility", 1, 1, true, false, false,
handle_visibility_attribute },
{ NULL, 0, 0, false, false, false, NULL } { NULL, 0, 0, false, false, false, NULL }
}; };
...@@ -1061,6 +1065,50 @@ handle_alias_attribute (node, name, args, flags, no_add_attrs) ...@@ -1061,6 +1065,50 @@ handle_alias_attribute (node, name, args, flags, no_add_attrs)
return NULL_TREE; 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 /* Handle a "no_instrument_function" attribute; arguments as in
struct attribute_spec.handler. */ struct attribute_spec.handler. */
......
...@@ -2266,7 +2266,9 @@ do { \ ...@@ -2266,7 +2266,9 @@ do { \
\ \
SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ SYMBOL_REF_FLAG (XEXP (rtl, 0)) \
= (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
|| ! TREE_PUBLIC (DECL)); \ || ! TREE_PUBLIC (DECL) \
|| (TREE_CODE (DECL) == VAR_DECL \
&& MODULE_LOCAL_P (DECL))); \
} \ } \
} \ } \
} while (0) } while (0)
......
...@@ -6897,13 +6897,14 @@ ia64_encode_section_info (decl) ...@@ -6897,13 +6897,14 @@ ia64_encode_section_info (decl)
statically allocated, but the space is allocated somewhere else. Such statically allocated, but the space is allocated somewhere else. Such
decls can not be own data. */ decls can not be own data. */
if (! TARGET_NO_SDATA if (! TARGET_NO_SDATA
&& TREE_STATIC (decl) && ! DECL_EXTERNAL (decl) && ((TREE_STATIC (decl) && ! DECL_EXTERNAL (decl)
&& ! (DECL_ONE_ONLY (decl) || DECL_WEAK (decl)) && ! (DECL_ONE_ONLY (decl) || DECL_WEAK (decl))
&& ! (TREE_PUBLIC (decl) && ! (TREE_PUBLIC (decl)
&& (flag_pic && (flag_pic
|| (DECL_COMMON (decl) || (DECL_COMMON (decl)
&& (DECL_INITIAL (decl) == 0 && (DECL_INITIAL (decl) == 0
|| DECL_INITIAL (decl) == error_mark_node)))) || DECL_INITIAL (decl) == error_mark_node)))))
|| MODULE_LOCAL_P (decl))
/* Either the variable must be declared without a section attribute, /* Either the variable must be declared without a section attribute,
or the section must be sdata or sbss. */ or the section must be sdata or sbss. */
&& (DECL_SECTION_NAME (decl) == 0 && (DECL_SECTION_NAME (decl) == 0
...@@ -6923,9 +6924,12 @@ ia64_encode_section_info (decl) ...@@ -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 /* 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. */ sdata because it might be too big when completed.
else if (size > 0 Objects bigger than threshold should have SDATA_NAME_FLAG_CHAR
&& size <= (HOST_WIDE_INT) ia64_section_threshold 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) && symbol_str[0] != SDATA_NAME_FLAG_CHAR)
{ {
size_t len = strlen (symbol_str); size_t len = strlen (symbol_str);
......
...@@ -213,13 +213,9 @@ STATIC void *__JCR_LIST__[] ...@@ -213,13 +213,9 @@ STATIC void *__JCR_LIST__[]
in one DSO or the main program is not used in another object. The in one DSO or the main program is not used in another object. The
dynamic linker takes care of this. */ 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 #ifdef HAVE_GAS_HIDDEN
asm (".hidden\t__dso_handle"); extern void *__dso_handle __attribute__ ((__visibility__ ("hidden")));
#endif #endif
#ifdef CRTSTUFFS_O #ifdef CRTSTUFFS_O
void *__dso_handle = &__dso_handle; void *__dso_handle = &__dso_handle;
#else #else
......
...@@ -2198,7 +2198,7 @@ The @code{alias} attribute causes the declaration to be emitted as an ...@@ -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, alias for another symbol, which must be specified. For instance,
@smallexample @smallexample
void __f () @{ /* do something */; @} void __f () @{ /* @r{Do something.} */; @}
void f () __attribute__ ((weak, alias ("__f"))); void f () __attribute__ ((weak, alias ("__f")));
@end smallexample @end smallexample
...@@ -2207,6 +2207,19 @@ mangled name for the target must be used. ...@@ -2207,6 +2207,19 @@ mangled name for the target must be used.
Not all target machines support this attribute. 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}) @item regparm (@var{number})
@cindex functions that are passed arguments in registers on the 386 @cindex functions that are passed arguments in registers on the 386
On the Intel 386, the @code{regparm} attribute causes the compiler to On the Intel 386, the @code{regparm} attribute causes the compiler to
......
...@@ -255,6 +255,8 @@ extern void assemble_constant_align PARAMS ((tree)); ...@@ -255,6 +255,8 @@ extern void assemble_constant_align PARAMS ((tree));
extern void assemble_alias PARAMS ((tree, tree)); extern void assemble_alias PARAMS ((tree, tree));
extern void assemble_visibility PARAMS ((tree, const char *));
/* Output a string of literal assembler code /* Output a string of literal assembler code
for an `asm' keyword used between functions. */ for an `asm' keyword used between functions. */
extern void assemble_asm PARAMS ((tree)); extern void assemble_asm PARAMS ((tree));
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
* g++.dg/debug/debug4.C: New test. * g++.dg/debug/debug4.C: New test.
* gcc.dg/ia64-visibility-1.c: New test.
2002-02-26 Alexandre Oliva <aoliva@redhat.com> 2002-02-26 Alexandre Oliva <aoliva@redhat.com>
* gcc.dg/debug/20020224-1.c: New. * gcc.dg/debug/20020224-1.c: New.
......
/* 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)); ...@@ -2283,6 +2283,11 @@ extern tree merge_attributes PARAMS ((tree, tree));
extern tree merge_dllimport_decl_attributes PARAMS ((tree, tree)); extern tree merge_dllimport_decl_attributes PARAMS ((tree, tree));
#endif #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 /* Return a version of the TYPE, qualified as indicated by the
TYPE_QUALS, if one exists. If no qualified version exists yet, TYPE_QUALS, if one exists. If no qualified version exists yet,
return NULL_TREE. */ return NULL_TREE. */
......
...@@ -5160,6 +5160,25 @@ assemble_alias (decl, target) ...@@ -5160,6 +5160,25 @@ assemble_alias (decl, target)
#endif #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 /* 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 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 multiply-defined symbol error, whether through the use of weak symbols or
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment