1 2002-02-26 Jakub Jelinek <jakub@redhat.com>
3 * attribs.c (c_common_attribute_table): Add visibility.
4 (handle_visibility_attribute): New function.
5 * varasm.c (assemble_visibility): New function.
6 * output.h (assemble_visibility): Add prototype.
7 * tree.h (MODULE_LOCAL_P): Define.
8 * crtstuff.c (__dso_handle): Use visibility attribute.
9 * config/i386/i386.h (ENCODE_SECTION_INFO): Set SYMBOL_REF_FLAG
10 for MODULE_LOCAL_P symbols too.
11 * config/ia64/ia64.c (ia64_encode_section_info): Handle
12 MODULE_LOCAL_P symbols the same way as local symbols.
13 Add SDATA_NAME_FLAG_CHAR even if decl was explicitely forced
14 into .sdata/.sbss by the user.
15 * doc/extend.texi (Function Attributes): Document visibility
18 * gcc.dg/ia64-visibility-1.c: New test.
20 --- gcc/attribs.c 2002/02/25 22:38:52 1.14
21 +++ gcc/attribs.c 2002/02/26 21:17:14 1.15
22 @@ -75,6 +75,8 @@ static tree handle_weak_attribute PARAMS
24 static tree handle_alias_attribute PARAMS ((tree *, tree, tree, int,
26 +static tree handle_visibility_attribute PARAMS ((tree *, tree, tree, int,
28 static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree,
31 @@ -148,6 +150,8 @@ static const struct attribute_spec c_com
32 handle_deprecated_attribute },
33 { "vector_size", 1, 1, false, true, false,
34 handle_vector_size_attribute },
35 + { "visibility", 1, 1, true, false, false,
36 + handle_visibility_attribute },
37 { NULL, 0, 0, false, false, false, NULL }
40 @@ -1061,6 +1065,50 @@ handle_alias_attribute (node, name, args
44 +/* Handle an "visibility" attribute; arguments as in
45 + struct attribute_spec.handler. */
48 +handle_visibility_attribute (node, name, args, flags, no_add_attrs)
52 + int flags ATTRIBUTE_UNUSED;
57 + if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl))
59 + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
60 + *no_add_attrs = true;
66 + id = TREE_VALUE (args);
67 + if (TREE_CODE (id) != STRING_CST)
69 + error ("visibility arg not a string");
70 + *no_add_attrs = true;
73 + if (strcmp (TREE_STRING_POINTER (id), "hidden")
74 + && strcmp (TREE_STRING_POINTER (id), "protected")
75 + && strcmp (TREE_STRING_POINTER (id), "internal"))
77 + error ("visibility arg must be one of \"hidden\", \"protected\" or \"internal\"");
78 + *no_add_attrs = true;
82 + assemble_visibility (decl, TREE_STRING_POINTER (id));
88 /* Handle a "no_instrument_function" attribute; arguments as in
89 struct attribute_spec.handler. */
91 --- gcc/varasm.c 2002/02/20 23:19:19 1.250
92 +++ gcc/varasm.c 2002/02/26 21:17:14 1.251
93 @@ -5160,6 +5160,25 @@ assemble_alias (decl, target)
97 +/* Emit an assembler directive to set symbol for DECL visibility to
101 +assemble_visibility (decl, visibility_type)
103 + const char *visibility_type ATTRIBUTE_UNUSED;
107 + name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
109 +#ifdef HAVE_GAS_HIDDEN
110 + fprintf (asm_out_file, "\t.%s\t%s\n", visibility_type, name);
112 + warning ("visibility attribute not supported in this configuration; ignored");
116 /* Returns 1 if the target configuration supports defining public symbols
117 so that one of them will be chosen at link time instead of generating a
118 multiply-defined symbol error, whether through the use of weak symbols or
119 --- gcc/output.h 2002/02/17 14:23:50 1.94
120 +++ gcc/output.h 2002/02/26 21:17:14 1.95
121 @@ -255,6 +255,8 @@ extern void assemble_constant_align PARA
123 extern void assemble_alias PARAMS ((tree, tree));
125 +extern void assemble_visibility PARAMS ((tree, const char *));
127 /* Output a string of literal assembler code
128 for an `asm' keyword used between functions. */
129 extern void assemble_asm PARAMS ((tree));
130 --- gcc/tree.h 2002/02/20 00:19:33 1.308
131 +++ gcc/tree.h 2002/02/26 21:17:14 1.309
132 @@ -2283,6 +2283,11 @@ extern tree merge_attributes PARAMS ((t
133 extern tree merge_dllimport_decl_attributes PARAMS ((tree, tree));
136 +/* Return true if DECL will be always resolved to a symbol defined in the
137 + same module (shared library or program). */
138 +#define MODULE_LOCAL_P(DECL) \
139 + (lookup_attribute ("visibility", DECL_ATTRIBUTES (DECL)) != NULL)
141 /* Return a version of the TYPE, qualified as indicated by the
142 TYPE_QUALS, if one exists. If no qualified version exists yet,
144 --- gcc/crtstuff.c 2002/02/05 10:31:01 1.54
145 +++ gcc/crtstuff.c 2002/02/26 21:17:14 1.55
146 @@ -213,13 +213,9 @@ STATIC void *__JCR_LIST__[]
147 in one DSO or the main program is not used in another object. The
148 dynamic linker takes care of this. */
150 -/* XXX Ideally the following should be implemented using
151 - __attribute__ ((__visibility__ ("hidden")))
152 - but the __attribute__ support is not yet there. */
153 #ifdef HAVE_GAS_HIDDEN
154 -asm (".hidden\t__dso_handle");
155 +extern void *__dso_handle __attribute__ ((__visibility__ ("hidden")));
159 void *__dso_handle = &__dso_handle;
161 --- gcc/config/i386/i386.h 2002/02/17 07:52:12 1.243
162 +++ gcc/config/i386/i386.h 2002/02/26 21:17:18 1.244
163 @@ -2266,7 +2266,9 @@ do { \
165 SYMBOL_REF_FLAG (XEXP (rtl, 0)) \
166 = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
167 - || ! TREE_PUBLIC (DECL)); \
168 + || ! TREE_PUBLIC (DECL) \
169 + || (TREE_CODE (DECL) == VAR_DECL \
170 + && MODULE_LOCAL_P (DECL))); \
174 --- gcc/config/ia64/ia64.c 2002/01/21 02:24:02 1.139
175 +++ gcc/config/ia64/ia64.c 2002/02/26 22:41:48 1.141
176 @@ -6897,13 +6904,14 @@ ia64_encode_section_info (decl)
177 statically allocated, but the space is allocated somewhere else. Such
178 decls can not be own data. */
179 if (! TARGET_NO_SDATA
180 - && TREE_STATIC (decl) && ! DECL_EXTERNAL (decl)
181 - && ! (DECL_ONE_ONLY (decl) || DECL_WEAK (decl))
182 - && ! (TREE_PUBLIC (decl)
184 - || (DECL_COMMON (decl)
185 - && (DECL_INITIAL (decl) == 0
186 - || DECL_INITIAL (decl) == error_mark_node))))
187 + && ((TREE_STATIC (decl) && ! DECL_EXTERNAL (decl)
188 + && ! (DECL_ONE_ONLY (decl) || DECL_WEAK (decl))
189 + && ! (TREE_PUBLIC (decl)
191 + || (DECL_COMMON (decl)
192 + && (DECL_INITIAL (decl) == 0
193 + || DECL_INITIAL (decl) == error_mark_node)))))
194 + || MODULE_LOCAL_P (decl))
195 /* Either the variable must be declared without a section attribute,
196 or the section must be sdata or sbss. */
197 && (DECL_SECTION_NAME (decl) == 0
198 @@ -6923,9 +6931,12 @@ ia64_encode_section_info (decl)
201 /* If this is an incomplete type with size 0, then we can't put it in
202 - sdata because it might be too big when completed. */
204 - && size <= (HOST_WIDE_INT) ia64_section_threshold
205 + sdata because it might be too big when completed.
206 + Objects bigger than threshold should have SDATA_NAME_FLAG_CHAR
207 + added if they are in .sdata or .sbss explicitely. */
208 + else if (((size > 0
209 + && size <= (HOST_WIDE_INT) ia64_section_threshold)
210 + || DECL_SECTION_NAME (decl))
211 && symbol_str[0] != SDATA_NAME_FLAG_CHAR)
213 size_t len = strlen (symbol_str);
214 --- gcc/doc/extend.texi 2002/02/23 12:59:07 1.64
215 +++ gcc/doc/extend.texi 2002/02/26 21:17:17 1.65
216 @@ -2198,7 +2198,7 @@ The @code{alias} attribute causes the de
217 alias for another symbol, which must be specified. For instance,
220 -void __f () @{ /* do something */; @}
221 +void __f () @{ /* @r{Do something.} */; @}
222 void f () __attribute__ ((weak, alias ("__f")));
225 @@ -2206,6 +2206,19 @@ declares @samp{f} to be a weak alias for
226 mangled name for the target must be used.
228 Not all target machines support this attribute.
230 +@item visibility ("@var{visibility_type}")
231 +@cindex @code{visibility} attribute
232 +The @code{visibility} attribute on ELF targets causes the declaration
233 +to be emitted with hidden, protected or internal visibility.
236 +void __attribute__ ((visibility ("protected")))
237 +f () @{ /* @r{Do something.} */; @}
238 +int i __attribute__ ((visibility ("hidden")));
241 +Not all ELF targets support this attribute.
243 @item regparm (@var{number})
244 @cindex functions that are passed arguments in registers on the 386
245 --- gcc/testsuite/gcc.dg/ia64-visibility-1.c.jj Tue Feb 26 12:30:32 2002
246 +++ gcc/testsuite/gcc.dg/ia64-visibility-1.c Tue Feb 26 12:33:26 2002
248 +/* Test visibility attribute. */
249 +/* { dg-do compile { target ia64*-*-linux* } } */
250 +/* { dg-options "-O2 -fpic" } */
251 +/* { dg-final { scan-assembler "\\.hidden.*variable_j" } } */
252 +/* { dg-final { scan-assembler "\\.hidden.*variable_m" } } */
253 +/* { dg-final { scan-assembler "\\.protected.*baz" } } */
254 +/* { dg-final { scan-assembler "gprel.*variable_i" } } */
255 +/* { dg-final { scan-assembler "gprel.*variable_j" } } */
256 +/* { dg-final { scan-assembler "ltoff.*variable_k" } } */
257 +/* { dg-final { scan-assembler "gprel.*variable_l" } } */
258 +/* { dg-final { scan-assembler "gprel.*variable_m" } } */
259 +/* { dg-final { scan-assembler "ltoff.*variable_n" } } */
261 +static int variable_i;
262 +int variable_j __attribute__((visibility ("hidden")));
264 +struct A { char a[64]; };
265 +static struct A variable_l __attribute__((section (".sbss")));
266 +struct A variable_m __attribute__((visibility ("hidden"), section(".sbss")));
267 +struct A variable_n __attribute__((section (".sbss")));
271 + return variable_i + variable_j + variable_k;
276 + variable_l.a[10] = 0;
277 + variable_m.a[10] = 0;
278 + variable_n.a[10] = 0;
281 +void __attribute__((visibility ("protected"))) baz (void)