aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2002-02-26 22:17:22 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2002-02-26 22:17:22 +0100
commit47bd70b56aa4ccc10fd0e90a7fae4c94d991bb30 (patch)
treebf177b7375ac3fceb1bd51f1f20b2ff845e3fbba
parent6d73371a68e805956981592bdc2a631acaab2a33 (diff)
downloadgcc-47bd70b56aa4ccc10fd0e90a7fae4c94d991bb30.zip
gcc-47bd70b56aa4ccc10fd0e90a7fae4c94d991bb30.tar.gz
gcc-47bd70b56aa4ccc10fd0e90a7fae4c94d991bb30.tar.bz2
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
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/attribs.c48
-rw-r--r--gcc/config/i386/i386.h4
-rw-r--r--gcc/config/ia64/ia64.c24
-rw-r--r--gcc/crtstuff.c6
-rw-r--r--gcc/doc/extend.texi15
-rw-r--r--gcc/output.h2
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/gcc.dg/ia64-visibility-1.c36
-rw-r--r--gcc/tree.h5
-rw-r--r--gcc/varasm.c19
11 files changed, 161 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b4da9bf..6228321 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,22 @@
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
* dwarf2out.c (rtl_for_decl_location): Return CONST_STRING for
STRING_CST initializer spanning the whole variable without
diff --git a/gcc/attribs.c b/gcc/attribs.c
index d046a62..2879d10 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -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. */
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index ceacd6c..342105d 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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)
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 7ca060b..2bdc16c 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -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);
diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c
index d3484e3..bfe6116 100644
--- a/gcc/crtstuff.c
+++ b/gcc/crtstuff.c
@@ -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
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index cc4e25d..f9870e7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -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
diff --git a/gcc/output.h b/gcc/output.h
index 98ec391..df5cead 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -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));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e45f949..6f0a6fc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/ia64-visibility-1.c b/gcc/testsuite/gcc.dg/ia64-visibility-1.c
new file mode 100644
index 0000000..53bc2c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ia64-visibility-1.c
@@ -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)
+{
+}
diff --git a/gcc/tree.h b/gcc/tree.h
index 89bff7e..8e17b53 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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. */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 46810c6..fa69592 100644
--- a/gcc/varasm.c
+++ b/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