OSDN Git Service

* attribs.c (c_common_attribute_table): Add visibility.
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Feb 2002 21:17:22 +0000 (21:17 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Feb 2002 21:17:22 +0000 (21:17 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@50061 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/attribs.c
gcc/config/i386/i386.h
gcc/config/ia64/ia64.c
gcc/crtstuff.c
gcc/doc/extend.texi
gcc/output.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ia64-visibility-1.c [new file with mode: 0644]
gcc/tree.h
gcc/varasm.c

index b4da9bf..6228321 100644 (file)
@@ -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
index d046a62..2879d10 100644 (file)
@@ -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.  */
 
index ceacd6c..342105d 100644 (file)
@@ -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)
index 7ca060b..2bdc16c 100644 (file)
@@ -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);
index d3484e3..bfe6116 100644 (file)
@@ -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
index cc4e25d..f9870e7 100644 (file)
@@ -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
index 98ec391..df5cead 100644 (file)
@@ -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));
index e45f949..6f0a6fc 100644 (file)
@@ -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 (file)
index 0000000..53bc2c3
--- /dev/null
@@ -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)
+{
+}
index 89bff7e..8e17b53 100644 (file)
@@ -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.  */
index 46810c6..fa69592 100644 (file)
@@ -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