]>
Commit | Line | Data |
---|---|---|
5384b728 | 1 | 2002-02-26 Jakub Jelinek <jakub@redhat.com> |
2 | ||
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 | |
16 | attribute. | |
17 | ||
18 | * gcc.dg/ia64-visibility-1.c: New test. | |
19 | ||
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 | |
23 | bool *)); | |
24 | static tree handle_alias_attribute PARAMS ((tree *, tree, tree, int, | |
25 | bool *)); | |
26 | +static tree handle_visibility_attribute PARAMS ((tree *, tree, tree, int, | |
27 | + bool *)); | |
28 | static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree, | |
29 | tree, int, | |
30 | bool *)); | |
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 } | |
38 | }; | |
39 | ||
40 | @@ -1061,6 +1065,50 @@ handle_alias_attribute (node, name, args | |
41 | return NULL_TREE; | |
42 | } | |
43 | ||
44 | +/* Handle an "visibility" attribute; arguments as in | |
45 | + struct attribute_spec.handler. */ | |
46 | + | |
47 | +static tree | |
48 | +handle_visibility_attribute (node, name, args, flags, no_add_attrs) | |
49 | + tree *node; | |
50 | + tree name; | |
51 | + tree args; | |
52 | + int flags ATTRIBUTE_UNUSED; | |
53 | + bool *no_add_attrs; | |
54 | +{ | |
55 | + tree decl = *node; | |
56 | + | |
57 | + if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl)) | |
58 | + { | |
59 | + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); | |
60 | + *no_add_attrs = true; | |
61 | + } | |
62 | + else | |
63 | + { | |
64 | + tree id; | |
65 | + | |
66 | + id = TREE_VALUE (args); | |
67 | + if (TREE_CODE (id) != STRING_CST) | |
68 | + { | |
69 | + error ("visibility arg not a string"); | |
70 | + *no_add_attrs = true; | |
71 | + return NULL_TREE; | |
72 | + } | |
73 | + if (strcmp (TREE_STRING_POINTER (id), "hidden") | |
74 | + && strcmp (TREE_STRING_POINTER (id), "protected") | |
75 | + && strcmp (TREE_STRING_POINTER (id), "internal")) | |
76 | + { | |
77 | + error ("visibility arg must be one of \"hidden\", \"protected\" or \"internal\""); | |
78 | + *no_add_attrs = true; | |
79 | + return NULL_TREE; | |
80 | + } | |
81 | + | |
82 | + assemble_visibility (decl, TREE_STRING_POINTER (id)); | |
83 | + } | |
84 | + | |
85 | + return NULL_TREE; | |
86 | +} | |
87 | + | |
88 | /* Handle a "no_instrument_function" attribute; arguments as in | |
89 | struct attribute_spec.handler. */ | |
90 | ||
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) | |
94 | #endif | |
95 | } | |
96 | ||
97 | +/* Emit an assembler directive to set symbol for DECL visibility to | |
98 | + VISIBILITY_TYPE. */ | |
99 | + | |
100 | +void | |
101 | +assemble_visibility (decl, visibility_type) | |
102 | + tree decl; | |
103 | + const char *visibility_type ATTRIBUTE_UNUSED; | |
104 | +{ | |
105 | + const char *name; | |
106 | + | |
107 | + name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); | |
108 | + | |
109 | +#ifdef HAVE_GAS_HIDDEN | |
110 | + fprintf (asm_out_file, "\t.%s\t%s\n", visibility_type, name); | |
111 | +#else | |
112 | + warning ("visibility attribute not supported in this configuration; ignored"); | |
113 | +#endif | |
114 | +} | |
115 | + | |
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 | |
122 | ||
123 | extern void assemble_alias PARAMS ((tree, tree)); | |
124 | ||
125 | +extern void assemble_visibility PARAMS ((tree, const char *)); | |
126 | + | |
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)); | |
134 | #endif | |
135 | ||
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) | |
140 | + | |
141 | /* Return a version of the TYPE, qualified as indicated by the | |
142 | TYPE_QUALS, if one exists. If no qualified version exists yet, | |
143 | return NULL_TREE. */ | |
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. */ | |
149 | ||
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"))); | |
156 | #endif | |
157 | - | |
158 | #ifdef CRTSTUFFS_O | |
159 | void *__dso_handle = &__dso_handle; | |
160 | #else | |
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 { \ | |
164 | \ | |
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))); \ | |
171 | } \ | |
172 | } \ | |
173 | } while (0) | |
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) | |
183 | - && (flag_pic | |
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) | |
190 | + && (flag_pic | |
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) | |
199 | ; | |
200 | ||
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. */ | |
203 | - else if (size > 0 | |
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) | |
212 | { | |
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, | |
218 | ||
219 | @smallexample | |
220 | -void __f () @{ /* do something */; @} | |
221 | +void __f () @{ /* @r{Do something.} */; @} | |
222 | void f () __attribute__ ((weak, alias ("__f"))); | |
223 | @end smallexample | |
224 | ||
225 | @@ -2206,6 +2206,19 @@ declares @samp{f} to be a weak alias for | |
226 | mangled name for the target must be used. | |
227 | ||
228 | Not all target machines support this attribute. | |
229 | + | |
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. | |
234 | + | |
235 | +@smallexample | |
236 | +void __attribute__ ((visibility ("protected"))) | |
237 | +f () @{ /* @r{Do something.} */; @} | |
238 | +int i __attribute__ ((visibility ("hidden"))); | |
239 | +@end smallexample | |
240 | + | |
241 | +Not all ELF targets support this attribute. | |
242 | ||
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 | |
247 | @@ -0,0 +1,36 @@ | |
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" } } */ | |
260 | + | |
261 | +static int variable_i; | |
262 | +int variable_j __attribute__((visibility ("hidden"))); | |
263 | +int variable_k; | |
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"))); | |
268 | + | |
269 | +int foo (void) | |
270 | +{ | |
271 | + return variable_i + variable_j + variable_k; | |
272 | +} | |
273 | + | |
274 | +void bar (void) | |
275 | +{ | |
276 | + variable_l.a[10] = 0; | |
277 | + variable_m.a[10] = 0; | |
278 | + variable_n.a[10] = 0; | |
279 | +} | |
280 | + | |
281 | +void __attribute__((visibility ("protected"))) baz (void) | |
282 | +{ | |
283 | +} |