]>
Commit | Line | Data |
---|---|---|
8a43a6d0 | 1 | diff -aur gcc-3.4.0orig/gcc/c-common.c gcc-3.4.0/gcc/c-common.c |
2 | --- gcc-3.4.0orig/gcc/c-common.c 2004-03-19 01:32:59.000000000 +0000 | |
3 | +++ gcc-3.4.0/gcc/c-common.c 2004-05-10 21:05:33.000000000 +0100 | |
4 | @@ -833,7 +833,7 @@ | |
5 | handle_deprecated_attribute }, | |
6 | { "vector_size", 1, 1, false, true, false, | |
7 | handle_vector_size_attribute }, | |
8 | - { "visibility", 1, 1, true, false, false, | |
9 | + { "visibility", 1, 1, false, false, false, | |
10 | handle_visibility_attribute }, | |
11 | { "tls_model", 1, 1, true, false, false, | |
12 | handle_tls_model_attribute }, | |
13 | @@ -4886,7 +4886,16 @@ | |
14 | ||
15 | *no_add_attrs = true; | |
16 | ||
17 | - if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl)) | |
18 | + if (TYPE_P (*node)) | |
19 | + { | |
20 | + if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE) | |
21 | + { | |
22 | + warning ("`%s' attribute ignored on non-class types", | |
23 | + IDENTIFIER_POINTER (name)); | |
24 | + return NULL_TREE; | |
25 | + } | |
26 | + } | |
27 | + else if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl)) | |
28 | { | |
29 | warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); | |
30 | return NULL_TREE; | |
31 | @@ -4897,6 +4906,14 @@ | |
32 | error ("visibility arg not a string"); | |
33 | return NULL_TREE; | |
34 | } | |
35 | + | |
36 | + /* If this is a type, set the visibility on the type decl. */ | |
37 | + if (TYPE_P (decl)) | |
38 | + { | |
39 | + decl = TYPE_NAME (decl); | |
40 | + if (! decl) | |
41 | + return NULL_TREE; | |
42 | + } | |
43 | ||
44 | if (strcmp (TREE_STRING_POINTER (id), "default") == 0) | |
45 | DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; | |
46 | @@ -4908,6 +4925,14 @@ | |
47 | DECL_VISIBILITY (decl) = VISIBILITY_PROTECTED; | |
48 | else | |
49 | error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\""); | |
50 | + DECL_VISIBILITYSPECIFIED (decl) = 1; | |
51 | + | |
52 | + /* For decls only, go ahead and attach the attribute to the node as well. | |
53 | + This is needed so we can determine whether we have VISIBILITY_DEFAULT | |
54 | + because the visibility was not specified, or because it was explicitly | |
55 | + overridden from the class visibility. */ | |
56 | + if (DECL_P (*node)) | |
57 | + *no_add_attrs = false; | |
58 | ||
59 | return NULL_TREE; | |
60 | } | |
61 | ||
62 | diff -aur gcc-3.4.0orig/gcc/c-decl.c gcc-3.4.0/gcc/c-decl.c | |
63 | --- gcc-3.4.0orig/gcc/c-decl.c 2004-03-22 17:58:18.000000000 +0000 | |
64 | +++ gcc-3.4.0/gcc/c-decl.c 2004-05-10 15:16:27.000000000 +0100 | |
65 | @@ -1164,9 +1164,8 @@ | |
66 | } | |
67 | ||
68 | /* warnings */ | |
69 | - /* All decls must agree on a non-default visibility. */ | |
70 | - if (DECL_VISIBILITY (newdecl) != VISIBILITY_DEFAULT | |
71 | - && DECL_VISIBILITY (olddecl) != VISIBILITY_DEFAULT | |
72 | + /* All decls must agree on a visibility. */ | |
73 | + if (DECL_VISIBILITYSPECIFIED (newdecl) && DECL_VISIBILITYSPECIFIED (olddecl) | |
74 | && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl)) | |
75 | { | |
76 | warning ("%Jredeclaration of '%D' with different visibility " | |
77 | @@ -1361,9 +1360,12 @@ | |
78 | Currently, it can only be defined in the prototype. */ | |
79 | COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl); | |
80 | ||
81 | - /* If either declaration has a nondefault visibility, use it. */ | |
82 | - if (DECL_VISIBILITY (olddecl) != VISIBILITY_DEFAULT) | |
83 | - DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl); | |
84 | + /* Use visibility of whichever declaration had it specified */ | |
85 | + if (DECL_VISIBILITYSPECIFIED (olddecl)) | |
86 | + { | |
87 | + DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl); | |
88 | + DECL_VISIBILITYSPECIFIED (newdecl) = 1; | |
89 | + } | |
90 | ||
91 | if (TREE_CODE (newdecl) == FUNCTION_DECL) | |
92 | { | |
93 | ||
94 | diff -aur gcc-3.4.0orig/gcc/common.opt gcc-3.4.0/gcc/common.opt | |
95 | --- gcc-3.4.0orig/gcc/common.opt 2004-02-18 00:09:04.000000000 +0000 | |
96 | +++ gcc-3.4.0/gcc/common.opt 2004-05-09 08:10:50.000000000 +0100 | |
97 | @@ -718,6 +718,11 @@ | |
98 | Common | |
99 | Add extra commentary to assembler output | |
100 | ||
101 | +fvisibility= | |
102 | +Common Joined RejectNegative | |
103 | +-fvisibility=[default|internal|hidden|protected] Set the default symbol visibility | |
104 | + | |
105 | + | |
106 | fvpt | |
107 | Common | |
108 | Use expression value profiles in optimizations | |
109 | ||
110 | diff -aur gcc-3.4.0orig/gcc/c.opt gcc-3.4.0/gcc/c.opt | |
111 | --- gcc-3.4.0orig/gcc/c.opt 2004-02-18 00:09:03.000000000 +0000 | |
112 | +++ gcc-3.4.0/gcc/c.opt 2004-05-09 08:10:50.000000000 +0100 | |
113 | @@ -656,6 +656,10 @@ | |
114 | C++ ObjC++ | |
115 | Use __cxa_atexit to register destructors | |
116 | ||
117 | +fvisibility-inlines-hidden | |
118 | +C++ | |
119 | +Marks all inlined methods as having hidden visibility | |
120 | + | |
121 | fvtable-gc | |
122 | C++ ObjC++ | |
123 | Discard unused virtual functions | |
124 | diff -aur gcc-3.4.0orig/gcc/c-opts.c gcc-3.4.0/gcc/c-opts.c | |
125 | --- gcc-3.4.0orig/gcc/c-opts.c 2004-02-18 00:09:03.000000000 +0000 | |
126 | +++ gcc-3.4.0/gcc/c-opts.c 2004-05-09 08:10:50.000000000 +0100 | |
127 | @@ -912,6 +912,10 @@ | |
128 | case OPT_fuse_cxa_atexit: | |
129 | flag_use_cxa_atexit = value; | |
130 | break; | |
131 | + | |
132 | + case OPT_fvisibility_inlines_hidden: | |
133 | + visibility_options.inlineshidden = value; | |
134 | + break; | |
135 | ||
136 | case OPT_fweak: | |
137 | flag_weak = value; | |
138 | ||
139 | diff -aur gcc-3.4.0orig/gcc/cp/class.c gcc-3.4.0/gcc/cp/class.c | |
140 | --- gcc-3.4.0orig/gcc/cp/class.c 2004-03-09 07:27:23.000000000 +0000 | |
141 | +++ gcc-3.4.0/gcc/cp/class.c 2004-05-10 21:06:50.000000000 +0100 | |
142 | @@ -524,6 +524,10 @@ | |
143 | DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node), | |
144 | DECL_ALIGN (decl)); | |
145 | ||
146 | + /* The vtable's visibility is the class visibility. There is no way | |
147 | + to override the visibility for just the vtable. */ | |
148 | + DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type); | |
149 | + DECL_VISIBILITYSPECIFIED (decl) = CLASSTYPE_VISIBILITYSPECIFIED (class_type); | |
150 | import_export_vtable (decl, class_type, 0); | |
151 | ||
152 | return decl; | |
153 | @@ -2971,7 +2975,25 @@ | |
154 | continue; | |
155 | ||
156 | if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL) | |
157 | - continue; | |
158 | + { | |
159 | + /* Apply the class's visibility attribute to static members | |
160 | + which do not have a visibility attribute. */ | |
161 | + if (! lookup_attribute ("visibility", DECL_ATTRIBUTES (x))) | |
162 | + { | |
163 | + if (visibility_options.inlineshidden && DECL_INLINE (x)) | |
164 | + { | |
165 | + DECL_VISIBILITY (x) = VISIBILITY_HIDDEN; | |
166 | + DECL_VISIBILITYSPECIFIED (x) = 1; | |
167 | + } | |
168 | + else | |
169 | + { | |
170 | + DECL_VISIBILITY (x) = CLASSTYPE_VISIBILITY (current_class_type); | |
171 | + DECL_VISIBILITYSPECIFIED (x) = CLASSTYPE_VISIBILITYSPECIFIED (current_class_type); | |
172 | + } | |
173 | + } | |
174 | + | |
175 | + continue; | |
176 | + } | |
177 | ||
178 | /* Now it can only be a FIELD_DECL. */ | |
179 | ||
180 | @@ -3708,6 +3730,22 @@ | |
181 | check_for_override (x, t); | |
182 | if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x)) | |
183 | cp_error_at ("initializer specified for non-virtual method `%D'", x); | |
184 | + | |
185 | + /* Apply the class's visibility attribute to methods which do | |
186 | + not have a visibility attribute. */ | |
187 | + if (! lookup_attribute ("visibility", DECL_ATTRIBUTES (x))) | |
188 | + { | |
189 | + if (visibility_options.inlineshidden && DECL_INLINE (x)) | |
190 | + { | |
191 | + DECL_VISIBILITY (x) = VISIBILITY_HIDDEN; | |
192 | + DECL_VISIBILITYSPECIFIED (x) = 1; | |
193 | + } | |
194 | + else | |
195 | + { | |
196 | + DECL_VISIBILITY (x) = CLASSTYPE_VISIBILITY (current_class_type); | |
197 | + DECL_VISIBILITYSPECIFIED (x) = CLASSTYPE_VISIBILITYSPECIFIED (current_class_type); | |
198 | + } | |
199 | + } | |
200 | ||
201 | /* The name of the field is the original field name | |
202 | Save this in auxiliary field for later overloading. */ | |
203 | @@ -7830,3 +7868,4 @@ | |
204 | *vid->last_init = build_tree_list (NULL_TREE, init); | |
205 | vid->last_init = &TREE_CHAIN (*vid->last_init); | |
206 | } | |
207 | + | |
208 | ||
209 | diff -aur gcc-3.4.0orig/gcc/cp/cp-tree.h gcc-3.4.0/gcc/cp/cp-tree.h | |
210 | --- gcc-3.4.0orig/gcc/cp/cp-tree.h 2004-03-20 00:13:08.000000000 +0000 | |
211 | +++ gcc-3.4.0/gcc/cp/cp-tree.h 2004-05-10 20:56:56.000000000 +0100 | |
212 | @@ -1008,7 +1008,12 @@ | |
213 | #define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \ | |
214 | (lookup_base ((TYPE), (PARENT), ba_not_special | ba_quiet, NULL) \ | |
215 | != NULL_TREE) | |
216 | -\f | |
217 | + | |
218 | +/* Gives the visibility specification for a class type. */ | |
219 | +#define CLASSTYPE_VISIBILITY(TYPE) DECL_VISIBILITY (TYPE_NAME (TYPE)) | |
220 | +#define CLASSTYPE_VISIBILITYSPECIFIED(TYPE) DECL_VISIBILITYSPECIFIED (TYPE_NAME (TYPE)) | |
221 | + | |
222 | + | |
223 | /* This is a few header flags for 'struct lang_type'. Actually, | |
224 | all but the first are used only for lang_type_class; they | |
225 | are put in this structure to save space. */ | |
226 | ||
227 | diff -aur gcc-3.4.0orig/gcc/cp/decl.c gcc-3.4.0/gcc/cp/decl.c | |
228 | --- gcc-3.4.0orig/gcc/cp/decl.c 2004-04-01 21:47:21.000000000 +0100 | |
229 | +++ gcc-3.4.0/gcc/cp/decl.c 2004-05-28 21:16:11.000000000 +0100 | |
230 | @@ -1869,17 +1869,34 @@ | |
231 | DECL_COMMON (newdecl) = DECL_COMMON (olddecl); | |
232 | COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl); | |
233 | ||
234 | - /* If either declaration has a nondefault visibility, use it. */ | |
235 | - if (DECL_VISIBILITY (olddecl) != VISIBILITY_DEFAULT) | |
236 | + /* Warn about conflicting visibility specifications. */ | |
237 | + if (DECL_VISIBILITYSPECIFIED (olddecl) && DECL_VISIBILITYSPECIFIED (newdecl) | |
238 | + && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl)) | |
239 | + { | |
240 | + warning ("%J'%D': visibility attribute ignored because it", | |
241 | + newdecl, newdecl); | |
242 | + warning ("%Jconflicts with previous declaration here", olddecl); | |
243 | + } | |
244 | + /* Choose the declaration which specified visibility. */ | |
245 | + if (DECL_VISIBILITYSPECIFIED (olddecl)) | |
246 | { | |
247 | - if (DECL_VISIBILITY (newdecl) != VISIBILITY_DEFAULT | |
248 | - && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl)) | |
249 | - { | |
250 | - warning ("%J'%D': visibility attribute ignored because it", | |
251 | - newdecl, newdecl); | |
252 | - warning ("%Jconflicts with previous declaration here", olddecl); | |
253 | - } | |
254 | DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl); | |
255 | + DECL_VISIBILITYSPECIFIED (newdecl) = 1; | |
256 | + } | |
257 | + /* If it's a definition of a global operator new or operator | |
258 | + delete, it must be default visibility. */ | |
259 | + if (NEW_DELETE_OPNAME_P (DECL_NAME (newdecl)) && DECL_INITIAL (newdecl) != NULL_TREE) | |
260 | + { | |
261 | + if (!DECL_FUNCTION_MEMBER_P (newdecl) && VISIBILITY_DEFAULT != DECL_VISIBILITY (newdecl)) | |
262 | + { | |
263 | + warning ("%J`%D': ignoring non-default symbol", | |
264 | + newdecl, newdecl); | |
265 | + warning ("%Jvisibility on global operator new or delete", newdecl); | |
266 | + DECL_VISIBILITY (olddecl) = VISIBILITY_DEFAULT; | |
267 | + DECL_VISIBILITYSPECIFIED (olddecl) = 1; | |
268 | + DECL_VISIBILITY (newdecl) = VISIBILITY_DEFAULT; | |
269 | + DECL_VISIBILITYSPECIFIED (newdecl) = 1; | |
270 | + } | |
271 | } | |
272 | ||
273 | if (TREE_CODE (newdecl) == FUNCTION_DECL) | |
274 | ||
275 | diff -aur gcc-3.4.0orig/gcc/cp/method.c gcc-3.4.0/gcc/cp/method.c | |
276 | --- gcc-3.4.0orig/gcc/cp/method.c 2004-04-08 23:15:58.000000000 +0100 | |
277 | +++ gcc-3.4.0/gcc/cp/method.c 2004-05-09 08:10:52.000000000 +0100 | |
278 | @@ -394,6 +394,7 @@ | |
279 | rewrite. */ | |
280 | TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function); | |
281 | DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function); | |
282 | + DECL_VISIBILITYSPECIFIED (thunk_fndecl) = DECL_VISIBILITYSPECIFIED (function); | |
283 | ||
284 | if (flag_syntax_only) | |
285 | { | |
286 | ||
287 | diff -aur gcc-3.4.0orig/gcc/cp/optimize.c gcc-3.4.0/gcc/cp/optimize.c | |
288 | --- gcc-3.4.0orig/gcc/cp/optimize.c 2004-02-08 01:52:50.000000000 +0000 | |
289 | +++ gcc-3.4.0/gcc/cp/optimize.c 2004-05-09 08:10:52.000000000 +0100 | |
290 | @@ -155,6 +155,7 @@ | |
291 | DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn); | |
292 | TREE_PUBLIC (clone) = TREE_PUBLIC (fn); | |
293 | DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn); | |
294 | + DECL_VISIBILITYSPECIFIED (clone) = DECL_VISIBILITYSPECIFIED (fn); | |
295 | ||
296 | /* Adjust the parameter names and locations. */ | |
297 | parm = DECL_ARGUMENTS (fn); | |
298 | ||
299 | diff -aur gcc-3.4.0orig/gcc/cp/rtti.c gcc-3.4.0/gcc/cp/rtti.c | |
300 | --- gcc-3.4.0orig/gcc/cp/rtti.c 2004-03-08 23:00:26.000000000 +0000 | |
301 | +++ gcc-3.4.0/gcc/cp/rtti.c 2004-05-10 21:09:21.000000000 +0100 | |
302 | @@ -361,7 +361,11 @@ | |
303 | pushdecl_top_level_and_finish (d, NULL_TREE); | |
304 | ||
305 | if (CLASS_TYPE_P (type)) | |
306 | - CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d; | |
307 | + { | |
308 | + CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d; | |
309 | + DECL_VISIBILITY (d) = CLASSTYPE_VISIBILITY (type); | |
310 | + DECL_VISIBILITYSPECIFIED (d) = CLASSTYPE_VISIBILITYSPECIFIED (type); | |
311 | + } | |
312 | ||
313 | /* Remember the type it is for. */ | |
314 | TREE_TYPE (name) = type; | |
315 | @@ -759,6 +763,11 @@ | |
316 | TREE_STATIC (name_decl) = 1; | |
317 | DECL_EXTERNAL (name_decl) = 0; | |
318 | TREE_PUBLIC (name_decl) = 1; | |
319 | + if (CLASS_TYPE_P (target)) | |
320 | + { | |
321 | + DECL_VISIBILITY (name_decl) = CLASSTYPE_VISIBILITY (target); | |
322 | + DECL_VISIBILITYSPECIFIED (name_decl) = CLASSTYPE_VISIBILITYSPECIFIED (target); | |
323 | + } | |
324 | import_export_tinfo (name_decl, target, typeinfo_in_lib_p (target)); | |
325 | /* External name of the string containing the type's name has a | |
326 | special name. */ | |
327 | ||
328 | diff -aur gcc-3.4.0orig/gcc/c-pragma.c gcc-3.4.0/gcc/c-pragma.c | |
329 | --- gcc-3.4.0orig/gcc/c-pragma.c 2004-01-23 23:35:53.000000000 +0000 | |
330 | +++ gcc-3.4.0/gcc/c-pragma.c 2004-05-09 08:10:52.000000000 +0100 | |
331 | @@ -480,6 +480,86 @@ | |
332 | return asmname; | |
333 | } | |
334 | ||
335 | + | |
336 | +#ifdef HANDLE_PRAGMA_VISIBILITY | |
337 | +static void handle_pragma_visibility (cpp_reader *); | |
338 | + | |
339 | +/* Sets the default visibility for symbols to something other than that | |
340 | + specified on the command line. */ | |
341 | +static void | |
342 | +handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED) | |
343 | +{ /* Form is #pragma GCC visibility push(hidden)|pop */ | |
344 | + static int visstack [16], visidx; | |
345 | + tree x; | |
346 | + enum cpp_ttype token; | |
347 | + enum { bad, push, pop } action = bad; | |
348 | + | |
349 | + token = c_lex (&x); | |
350 | + if (token == CPP_NAME) | |
351 | + { | |
352 | + const char *op = IDENTIFIER_POINTER (x); | |
353 | + if (!strcmp (op, "push")) | |
354 | + action = push; | |
355 | + else if (!strcmp (op, "pop")) | |
356 | + action = pop; | |
357 | + } | |
358 | + if (bad == action) | |
359 | + GCC_BAD ("#pragma GCC visibility must be followed by push or pop"); | |
360 | + else | |
361 | + { | |
362 | + if (pop == action) | |
363 | + { | |
364 | + if (!visidx) | |
365 | + { | |
366 | + GCC_BAD ("No matching push for '#pragma GCC visibility pop'"); | |
367 | + } | |
368 | + else | |
369 | + { | |
370 | + default_visibility = visstack[--visidx]; | |
371 | + visibility_options.inpragma = (visidx>0); | |
372 | + } | |
373 | + } | |
374 | + else | |
375 | + { | |
376 | + if (c_lex (&x) != CPP_OPEN_PAREN) | |
377 | + GCC_BAD ("missing '(' after '#pragma GCC visibility push' - ignored"); | |
378 | + token = c_lex (&x); | |
379 | + if (token != CPP_NAME) | |
380 | + { | |
381 | + GCC_BAD ("malformed #pragma GCC visibility push"); | |
382 | + } | |
383 | + else if (visidx >= 16) | |
384 | + { | |
385 | + GCC_BAD ("No more than sixteen #pragma GCC visibility pushes allowed at once"); | |
386 | + } | |
387 | + else | |
388 | + { | |
389 | + const char *str = IDENTIFIER_POINTER (x); | |
390 | + visstack[visidx++] = default_visibility; | |
391 | + if (!strcmp (str, "default")) | |
392 | + default_visibility = VISIBILITY_DEFAULT; | |
393 | + else if (!strcmp (str, "internal")) | |
394 | + default_visibility = VISIBILITY_INTERNAL; | |
395 | + else if (!strcmp (str, "hidden")) | |
396 | + default_visibility = VISIBILITY_HIDDEN; | |
397 | + else if (!strcmp (str, "protected")) | |
398 | + default_visibility = VISIBILITY_PROTECTED; | |
399 | + else | |
400 | + { | |
401 | + GCC_BAD ("#pragma GCC visibility push() must specify default, internal, hidden or protected"); | |
402 | + } | |
403 | + visibility_options.inpragma = 1; | |
404 | + } | |
405 | + if (c_lex (&x) != CPP_CLOSE_PAREN) | |
406 | + GCC_BAD ("missing '(' after '#pragma GCC visibility push' - ignored"); | |
407 | + } | |
408 | + } | |
409 | + if (c_lex (&x) != CPP_EOF) | |
410 | + warning ("junk at end of '#pragma GCC visibility'"); | |
411 | +} | |
412 | + | |
413 | +#endif | |
414 | + | |
415 | /* Front-end wrapper for pragma registration to avoid dragging | |
416 | cpplib.h in almost everywhere. */ | |
417 | void | |
418 | @@ -505,6 +585,9 @@ | |
419 | #ifdef HANDLE_PRAGMA_EXTERN_PREFIX | |
420 | c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix); | |
421 | #endif | |
422 | +#ifdef HANDLE_PRAGMA_VISIBILITY | |
423 | + c_register_pragma ("GCC", "visibility", handle_pragma_visibility); | |
424 | +#endif | |
425 | ||
426 | #ifdef REGISTER_TARGET_PRAGMAS | |
427 | REGISTER_TARGET_PRAGMAS (); | |
428 | diff -aur gcc-3.4.0orig/gcc/c-pragma.h gcc-3.4.0/gcc/c-pragma.h | |
429 | --- gcc-3.4.0orig/gcc/c-pragma.h 2004-01-31 06:18:05.000000000 +0000 | |
430 | +++ gcc-3.4.0/gcc/c-pragma.h 2004-05-09 08:10:53.000000000 +0100 | |
431 | @@ -44,6 +44,11 @@ | |
432 | #define HANDLE_PRAGMA_PACK 1 | |
433 | #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ | |
434 | ||
435 | +/* It's safe to always leave visibility pragma enabled as if | |
436 | + visibility is not supported on the host OS platform the | |
437 | + statements are ignored. */ | |
438 | +#define HANDLE_PRAGMA_VISIBILITY 1 | |
439 | + | |
440 | extern void init_pragma (void); | |
441 | ||
442 | /* Front-end wrapper for pragma registration to avoid dragging | |
443 | ||
444 | ||
445 | diff -aur gcc-3.4.0orig/gcc/doc/invoke.texi gcc-3.4.0/gcc/doc/invoke.texi | |
446 | --- gcc-3.4.0orig/gcc/doc/invoke.texi 2004-04-19 00:05:36.000000000 +0100 | |
447 | +++ gcc-3.4.0/gcc/doc/invoke.texi 2004-05-28 21:29:36.000000000 +0100 | |
448 | @@ -183,7 +183,8 @@ | |
449 | -fno-optional-diags -fpermissive @gol | |
450 | -frepo -fno-rtti -fstats -ftemplate-depth-@var{n} @gol | |
451 | -fuse-cxa-atexit -fno-weak -nostdinc++ @gol | |
452 | --fno-default-inline -Wabi -Wctor-dtor-privacy @gol | |
453 | +-fno-default-inline -fvisibility-inlines-hidden @gol | |
454 | +-Wabi -Wctor-dtor-privacy @gol | |
455 | -Wnon-virtual-dtor -Wreorder @gol | |
456 | -Weffc++ -Wno-deprecated @gol | |
457 | -Wno-non-template-friend -Wold-style-cast @gol | |
458 | @@ -674,7 +675,8 @@ | |
459 | -fargument-alias -fargument-noalias @gol | |
460 | -fargument-noalias-global -fleading-underscore @gol | |
461 | -ftls-model=@var{model} @gol | |
462 | --ftrapv -fwrapv -fbounds-check} | |
463 | +-ftrapv -fwrapv -fbounds-check @gol | |
464 | +-fvisibility} | |
465 | @end table | |
466 | ||
467 | @menu | |
468 | @@ -1433,6 +1435,20 @@ | |
469 | destructors, but will only work if your C library supports | |
470 | @code{__cxa_atexit}. | |
471 | ||
472 | +@item -fvisibility-inlines-hidden | |
473 | +@opindex fvisibility-inlines-hidden | |
474 | +Causes all inlined methods to be marked with | |
475 | +@code{__attribute__ ((visibility ("hidden")))} so that they do not | |
476 | +appear in the export table of a DSO and do not require a PLT indirection | |
477 | +when used within the DSO. Enabling this option can have a dramatic effect | |
478 | +on load and link times of a DSO as it massively reduces the size of the | |
479 | +dynamic export table when the library makes heavy use of templates. While | |
480 | +it can cause bloating through duplication of code within each DSO where | |
481 | +it is used, often the wastage is less than the considerable space occupied | |
482 | +by a long symbol name in the export table which is typical when using | |
483 | +templates and namespaces. For even more savings, combine with the | |
484 | +@code{-fvisibility=hidden} switch. | |
485 | + | |
486 | @item -fno-weak | |
487 | @opindex fno-weak | |
488 | Do not use weak symbol support, even if it is provided by the linker. | |
489 | @@ -11198,6 +11214,54 @@ | |
490 | ||
491 | The default without @option{-fpic} is @code{initial-exec}; with | |
492 | @option{-fpic} the default is @code{global-dynamic}. | |
493 | + | |
494 | +@item -fvisibility=@var{default|internal|hidden|protected} | |
495 | +@opindex fvisibility | |
496 | +Set the default ELF image symbol visibility to the specified option - all | |
497 | +symbols will be marked with this unless overrided within the code. | |
498 | +Using this feature can very substantially improve linking and | |
499 | +load times of shared object libraries, produce more optimised | |
500 | +code, provide near-perfect API export and prevent symbol clashes. | |
501 | +It is @strong{strongly} recommended that you use this in any shared objects | |
502 | +you distribute. | |
503 | + | |
504 | +Despite the nomenclature, @code{default} always means public ie; | |
505 | +available to be linked against from outside the shared object. | |
506 | +@code{protected} and @code{internal} are pretty useless in real-world | |
507 | +usage so the only other commonly used option will be @code{hidden}. | |
508 | +The default if -fvisibility isn't specified is @code{default} ie; make every | |
509 | +symbol public - this causes the same behaviour as previous versions of | |
510 | +GCC. | |
511 | + | |
512 | +A good explanation of the benefits offered by ensuring ELF | |
513 | +symbols have the correct visibility is given by ``How To Write | |
514 | +Shared Libraries'' by Ulrich Drepper (which can be found at | |
515 | +@w{@uref{http://people.redhat.com/~drepper/}}) - however a superior | |
516 | +solution made possible by this option to marking things hidden when | |
517 | +the default is public is to make the default hidden and mark things | |
518 | +public. This is the norm with DLL's on Windows and with @option{-fvisibility=hidden} | |
519 | +and @code{__attribute__ ((visibility("default")))} instead of | |
520 | +@code{__declspec(dllexport)} you get almost identical semantics with | |
521 | +identical syntax. This is a great boon to those working with | |
522 | +cross-platform projects. | |
523 | + | |
524 | +For those adding visibility support to existing code, you may find | |
525 | +@samp{#pragma GCC visibility} of use. This works by you enclosing | |
526 | +the declarations you wish to set visibility for with (for example) | |
527 | +@samp{#pragma GCC visibility push(hidden)} and | |
528 | +@samp{#pragma GCC visibility pop}. These can be nested up to sixteen | |
529 | +times. Bear in mind that symbol visibility should be viewed @strong{as | |
530 | +part of the API interface contract} and thus all new code should | |
531 | +always specify visibility when it is not the default ie; declarations | |
532 | +only for use within the local DSO should @strong{always} be marked explicitly | |
533 | +as hidden as so to avoid PLT indirection overheads - making this | |
534 | +abundantly clear also aids readability and self-documentation of the code. | |
535 | +Note that due to ISO C++ specification requirements, operator new and | |
536 | +operator delete must always be of default visibility. | |
537 | + | |
538 | +An overview of these techniques, their benefits and how to use them | |
539 | +is at @w{@uref{http://www.nedprod.com/programs/gccvisibility.html}}. | |
540 | + | |
541 | @end table | |
542 | ||
543 | @c man end | |
544 | ||
545 | diff -aur gcc-3.4.0orig/gcc/flags.h gcc-3.4.0/gcc/flags.h | |
546 | --- gcc-3.4.0orig/gcc/flags.h 2004-02-18 00:09:04.000000000 +0000 | |
547 | +++ gcc-3.4.0/gcc/flags.h 2004-05-09 08:10:53.000000000 +0100 | |
548 | @@ -60,6 +60,30 @@ | |
549 | /* Nonzero means emit debugging information only for symbols which are used. */ | |
550 | extern int flag_debug_only_used_symbols; | |
551 | ||
552 | +/* Enumerate visibility settings. */ | |
553 | +#ifndef SYMBOL_VISIBILITY_DEFINED | |
554 | +#define SYMBOL_VISIBILITY_DEFINED | |
555 | +enum symbol_visibility | |
556 | +{ | |
557 | + VISIBILITY_DEFAULT, | |
558 | + VISIBILITY_INTERNAL, | |
559 | + VISIBILITY_HIDDEN, | |
560 | + VISIBILITY_PROTECTED | |
561 | +}; | |
562 | +#endif | |
563 | + | |
564 | +/* The default visibility for all symbols (unless overridden). */ | |
565 | +extern enum symbol_visibility default_visibility; | |
566 | + | |
567 | +struct visibility_flags | |
568 | +{ | |
569 | + unsigned inpragma : 1; /* True when in #pragma GCC visibility. */ | |
570 | + unsigned inlineshidden : 1; /* True when -finlineshidden in effect. */ | |
571 | +}; | |
572 | + | |
573 | +/* Global visibility options. */ | |
574 | +extern struct visibility_flags visibility_options; | |
575 | + | |
576 | /* Nonzero means do optimizations. -opt. */ | |
577 | ||
578 | extern int optimize; | |
579 | ||
580 | diff -aur gcc-3.4.0orig/gcc/opts.c gcc-3.4.0/gcc/opts.c | |
581 | --- gcc-3.4.0orig/gcc/opts.c 2004-02-18 00:09:04.000000000 +0000 | |
582 | +++ gcc-3.4.0/gcc/opts.c 2004-05-09 08:10:53.000000000 +0100 | |
583 | @@ -142,6 +142,12 @@ | |
584 | write_symbols is set to DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */ | |
585 | bool use_gnu_debug_info_extensions; | |
586 | ||
587 | +/* The default visibility for all symbols (unless overridden) */ | |
588 | +enum symbol_visibility default_visibility = VISIBILITY_DEFAULT; | |
589 | + | |
590 | +/* Global visibility options. */ | |
591 | +struct visibility_flags visibility_options; | |
592 | + | |
593 | /* Columns of --help display. */ | |
594 | static unsigned int columns = 80; | |
595 | ||
596 | @@ -1440,6 +1446,21 @@ | |
597 | flag_verbose_asm = value; | |
598 | break; | |
599 | ||
600 | + case OPT_fvisibility_: | |
601 | + { | |
602 | + if(!strcmp(arg, "default")) | |
603 | + default_visibility=VISIBILITY_DEFAULT; | |
604 | + else if(!strcmp(arg, "internal")) | |
605 | + default_visibility=VISIBILITY_INTERNAL; | |
606 | + else if(!strcmp(arg, "hidden")) | |
607 | + default_visibility=VISIBILITY_HIDDEN; | |
608 | + else if(!strcmp(arg, "protected")) | |
609 | + default_visibility=VISIBILITY_PROTECTED; | |
610 | + else | |
611 | + error("unrecognised visibility value \"%s\"", arg); | |
612 | + } | |
613 | + break; | |
614 | + | |
615 | case OPT_fweb: | |
616 | flag_web = value; | |
617 | break; | |
618 | ||
619 | diff -aur gcc-3.4.0orig/gcc/tree.c gcc-3.4.0/gcc/tree.c | |
620 | --- gcc-3.4.0orig/gcc/tree.c 2004-02-05 22:01:35.000000000 +0000 | |
621 | +++ gcc-3.4.0/gcc/tree.c 2004-05-10 15:22:52.000000000 +0100 | |
622 | @@ -2563,6 +2563,11 @@ | |
623 | layout_decl (t, 0); | |
624 | else if (code == FUNCTION_DECL) | |
625 | DECL_MODE (t) = FUNCTION_MODE; | |
626 | + | |
627 | + /* Set default visibility to whatever the user supplied with | |
628 | + visibility_specified depending on #pragma GCC visibility. */ | |
629 | + DECL_VISIBILITY (t) = default_visibility; | |
630 | + DECL_VISIBILITYSPECIFIED (t) = visibility_options.inpragma; | |
631 | ||
632 | return t; | |
633 | } | |
634 | ||
635 | diff -aur gcc-3.4.0orig/gcc/tree.h gcc-3.4.0/gcc/tree.h | |
636 | --- gcc-3.4.0orig/gcc/tree.h 2004-02-08 01:52:43.000000000 +0000 | |
637 | +++ gcc-3.4.0/gcc/tree.h 2004-05-09 08:10:54.000000000 +0100 | |
638 | @@ -1499,6 +1499,10 @@ | |
639 | /* Value of the decls's visibility attribute */ | |
640 | #define DECL_VISIBILITY(NODE) (DECL_CHECK (NODE)->decl.visibility) | |
641 | ||
642 | +/* Nonzero means that the decl had its visibility specified rather than | |
643 | + being inferred. */ | |
644 | +#define DECL_VISIBILITYSPECIFIED(NODE) (DECL_CHECK (NODE)->decl.visibility_specified) | |
645 | + | |
646 | /* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */ | |
647 | #define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable) | |
648 | ||
649 | @@ -1633,7 +1637,8 @@ | |
650 | || TREE_CODE (DECL_CONTEXT (EXP)) == TRANSLATION_UNIT_DECL) | |
651 | ||
652 | /* Enumerate visibility settings. */ | |
653 | - | |
654 | +#ifndef SYMBOL_VISIBILITY_DEFINED | |
655 | +#define SYMBOL_VISIBILITY_DEFINED | |
656 | enum symbol_visibility | |
657 | { | |
658 | VISIBILITY_DEFAULT, | |
659 | @@ -1641,6 +1646,7 @@ | |
660 | VISIBILITY_HIDDEN, | |
661 | VISIBILITY_PROTECTED | |
662 | }; | |
663 | +#endif | |
664 | ||
665 | struct function; | |
666 | ||
667 | @@ -1684,8 +1690,7 @@ | |
668 | unsigned thread_local_flag : 1; | |
669 | unsigned declared_inline_flag : 1; | |
670 | ENUM_BITFIELD(symbol_visibility) visibility : 2; | |
671 | - unsigned unused : 1; | |
672 | - /* one unused bit. */ | |
673 | + unsigned visibility_specified : 1; | |
674 | ||
675 | unsigned lang_flag_0 : 1; | |
676 | unsigned lang_flag_1 : 1; | |
677 | ||
678 | diff -aur gcc-3.4.0orig/gcc/varasm.c gcc-3.4.0/gcc/varasm.c | |
679 | --- gcc-3.4.0orig/gcc/varasm.c 2004-04-14 22:14:08.000000000 +0100 | |
680 | +++ gcc-3.4.0/gcc/varasm.c 2004-05-09 08:10:54.000000000 +0100 | |
681 | @@ -5150,8 +5150,8 @@ | |
682 | /* Static variables are always local. */ | |
683 | else if (! TREE_PUBLIC (exp)) | |
684 | local_p = true; | |
685 | - /* A variable is local if the user tells us so. */ | |
686 | - else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) | |
687 | + /* A variable is local if the user explicitly tells us so. */ | |
688 | + else if (DECL_VISIBILITYSPECIFIED (exp) && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) | |
689 | local_p = true; | |
690 | /* Otherwise, variables defined outside this object may not be local. */ | |
691 | else if (DECL_EXTERNAL (exp)) | |
692 | @@ -5159,6 +5159,9 @@ | |
693 | /* Linkonce and weak data are never local. */ | |
694 | else if (DECL_ONE_ONLY (exp) || DECL_WEAK (exp)) | |
695 | local_p = false; | |
696 | + /* If none of the above and visibility is not default, make local. */ | |
697 | + else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) | |
698 | + local_p = true; | |
699 | /* If PIC, then assume that any global name can be overridden by | |
700 | symbols resolved from other modules. */ | |
701 | else if (shlib) | |
702 |