Mercurial > hg > CbC > CbC_gcc
comparison gcc/c-pragma.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 3bfb6c00c1e0 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack. | |
2 Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, | |
3 2006, 2007, 2008 Free Software Foundation, Inc. | |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify it under | |
8 the terms of the GNU General Public License as published by the Free | |
9 Software Foundation; either version 3, or (at your option) any later | |
10 version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GCC; see the file COPYING3. If not see | |
19 <http://www.gnu.org/licenses/>. */ | |
20 | |
21 #include "config.h" | |
22 #include "system.h" | |
23 #include "coretypes.h" | |
24 #include "tm.h" | |
25 #include "rtl.h" | |
26 #include "tree.h" | |
27 #include "function.h" | |
28 #include "cpplib.h" | |
29 #include "c-pragma.h" | |
30 #include "flags.h" | |
31 #include "toplev.h" | |
32 #include "ggc.h" | |
33 #include "c-common.h" | |
34 #include "output.h" | |
35 #include "tm_p.h" | |
36 #include "vec.h" | |
37 #include "target.h" | |
38 #include "diagnostic.h" | |
39 #include "opts.h" | |
40 | |
41 #define GCC_BAD(gmsgid) \ | |
42 do { warning (OPT_Wpragmas, gmsgid); return; } while (0) | |
43 #define GCC_BAD2(gmsgid, arg) \ | |
44 do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0) | |
45 | |
46 typedef struct align_stack GTY(()) | |
47 { | |
48 int alignment; | |
49 tree id; | |
50 struct align_stack * prev; | |
51 } align_stack; | |
52 | |
53 static GTY(()) struct align_stack * alignment_stack; | |
54 | |
55 #ifdef HANDLE_PRAGMA_PACK | |
56 static void handle_pragma_pack (cpp_reader *); | |
57 | |
58 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP | |
59 /* If we have a "global" #pragma pack(<n>) in effect when the first | |
60 #pragma pack(push,<n>) is encountered, this stores the value of | |
61 maximum_field_alignment in effect. When the final pop_alignment() | |
62 happens, we restore the value to this, not to a value of 0 for | |
63 maximum_field_alignment. Value is in bits. */ | |
64 static int default_alignment; | |
65 #define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \ | |
66 ? &default_alignment \ | |
67 : &alignment_stack->alignment) = (ALIGN)) | |
68 | |
69 static void push_alignment (int, tree); | |
70 static void pop_alignment (tree); | |
71 | |
72 /* Push an alignment value onto the stack. */ | |
73 static void | |
74 push_alignment (int alignment, tree id) | |
75 { | |
76 align_stack * entry; | |
77 | |
78 entry = GGC_NEW (align_stack); | |
79 | |
80 entry->alignment = alignment; | |
81 entry->id = id; | |
82 entry->prev = alignment_stack; | |
83 | |
84 /* The current value of maximum_field_alignment is not necessarily | |
85 0 since there may be a #pragma pack(<n>) in effect; remember it | |
86 so that we can restore it after the final #pragma pop(). */ | |
87 if (alignment_stack == NULL) | |
88 default_alignment = maximum_field_alignment; | |
89 | |
90 alignment_stack = entry; | |
91 | |
92 maximum_field_alignment = alignment; | |
93 } | |
94 | |
95 /* Undo a push of an alignment onto the stack. */ | |
96 static void | |
97 pop_alignment (tree id) | |
98 { | |
99 align_stack * entry; | |
100 | |
101 if (alignment_stack == NULL) | |
102 GCC_BAD ("#pragma pack (pop) encountered without matching #pragma pack (push)"); | |
103 | |
104 /* If we got an identifier, strip away everything above the target | |
105 entry so that the next step will restore the state just below it. */ | |
106 if (id) | |
107 { | |
108 for (entry = alignment_stack; entry; entry = entry->prev) | |
109 if (entry->id == id) | |
110 { | |
111 alignment_stack = entry; | |
112 break; | |
113 } | |
114 if (entry == NULL) | |
115 warning (OPT_Wpragmas, "\ | |
116 #pragma pack(pop, %s) encountered without matching #pragma pack(push, %s)" | |
117 , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id)); | |
118 } | |
119 | |
120 entry = alignment_stack->prev; | |
121 | |
122 maximum_field_alignment = entry ? entry->alignment : default_alignment; | |
123 | |
124 alignment_stack = entry; | |
125 } | |
126 #else /* not HANDLE_PRAGMA_PACK_PUSH_POP */ | |
127 #define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN)) | |
128 #define push_alignment(ID, N) \ | |
129 GCC_BAD ("#pragma pack(push[, id], <n>) is not supported on this target") | |
130 #define pop_alignment(ID) \ | |
131 GCC_BAD ("#pragma pack(pop[, id], <n>) is not supported on this target") | |
132 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ | |
133 | |
134 /* #pragma pack () | |
135 #pragma pack (N) | |
136 | |
137 #pragma pack (push) | |
138 #pragma pack (push, N) | |
139 #pragma pack (push, ID) | |
140 #pragma pack (push, ID, N) | |
141 #pragma pack (pop) | |
142 #pragma pack (pop, ID) */ | |
143 static void | |
144 handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy)) | |
145 { | |
146 tree x, id = 0; | |
147 int align = -1; | |
148 enum cpp_ttype token; | |
149 enum { set, push, pop } action; | |
150 | |
151 if (pragma_lex (&x) != CPP_OPEN_PAREN) | |
152 GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored"); | |
153 | |
154 token = pragma_lex (&x); | |
155 if (token == CPP_CLOSE_PAREN) | |
156 { | |
157 action = set; | |
158 align = initial_max_fld_align; | |
159 } | |
160 else if (token == CPP_NUMBER) | |
161 { | |
162 if (TREE_CODE (x) != INTEGER_CST) | |
163 GCC_BAD ("invalid constant in %<#pragma pack%> - ignored"); | |
164 align = TREE_INT_CST_LOW (x); | |
165 action = set; | |
166 if (pragma_lex (&x) != CPP_CLOSE_PAREN) | |
167 GCC_BAD ("malformed %<#pragma pack%> - ignored"); | |
168 } | |
169 else if (token == CPP_NAME) | |
170 { | |
171 #define GCC_BAD_ACTION do { if (action != pop) \ | |
172 GCC_BAD ("malformed %<#pragma pack(push[, id][, <n>])%> - ignored"); \ | |
173 else \ | |
174 GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \ | |
175 } while (0) | |
176 | |
177 const char *op = IDENTIFIER_POINTER (x); | |
178 if (!strcmp (op, "push")) | |
179 action = push; | |
180 else if (!strcmp (op, "pop")) | |
181 action = pop; | |
182 else | |
183 GCC_BAD2 ("unknown action %qs for %<#pragma pack%> - ignored", op); | |
184 | |
185 while ((token = pragma_lex (&x)) == CPP_COMMA) | |
186 { | |
187 token = pragma_lex (&x); | |
188 if (token == CPP_NAME && id == 0) | |
189 { | |
190 id = x; | |
191 } | |
192 else if (token == CPP_NUMBER && action == push && align == -1) | |
193 { | |
194 if (TREE_CODE (x) != INTEGER_CST) | |
195 GCC_BAD ("invalid constant in %<#pragma pack%> - ignored"); | |
196 align = TREE_INT_CST_LOW (x); | |
197 if (align == -1) | |
198 action = set; | |
199 } | |
200 else | |
201 GCC_BAD_ACTION; | |
202 } | |
203 | |
204 if (token != CPP_CLOSE_PAREN) | |
205 GCC_BAD_ACTION; | |
206 #undef GCC_BAD_ACTION | |
207 } | |
208 else | |
209 GCC_BAD ("malformed %<#pragma pack%> - ignored"); | |
210 | |
211 if (pragma_lex (&x) != CPP_EOF) | |
212 warning (OPT_Wpragmas, "junk at end of %<#pragma pack%>"); | |
213 | |
214 if (flag_pack_struct) | |
215 GCC_BAD ("#pragma pack has no effect with -fpack-struct - ignored"); | |
216 | |
217 if (action != pop) | |
218 switch (align) | |
219 { | |
220 case 0: | |
221 case 1: | |
222 case 2: | |
223 case 4: | |
224 case 8: | |
225 case 16: | |
226 align *= BITS_PER_UNIT; | |
227 break; | |
228 case -1: | |
229 if (action == push) | |
230 { | |
231 align = maximum_field_alignment; | |
232 break; | |
233 } | |
234 default: | |
235 GCC_BAD2 ("alignment must be a small power of two, not %d", align); | |
236 } | |
237 | |
238 switch (action) | |
239 { | |
240 case set: SET_GLOBAL_ALIGNMENT (align); break; | |
241 case push: push_alignment (align, id); break; | |
242 case pop: pop_alignment (id); break; | |
243 } | |
244 } | |
245 #endif /* HANDLE_PRAGMA_PACK */ | |
246 | |
247 struct def_pragma_macro_value GTY(()) | |
248 { | |
249 struct def_pragma_macro_value *prev; | |
250 cpp_macro *value; | |
251 }; | |
252 | |
253 struct def_pragma_macro GTY(()) | |
254 { | |
255 hashval_t hash; | |
256 const char *name; | |
257 struct def_pragma_macro_value value; | |
258 }; | |
259 | |
260 static GTY((param_is (struct def_pragma_macro))) htab_t pushed_macro_table; | |
261 | |
262 #ifdef HANDLE_PRAGMA_PUSH_POP_MACRO | |
263 /* Hash table control functions for pushed_macro_table. */ | |
264 static hashval_t | |
265 dpm_hash (const void *p) | |
266 { | |
267 return ((const struct def_pragma_macro *)p)->hash; | |
268 } | |
269 | |
270 static int | |
271 dpm_eq (const void *pa, const void *pb) | |
272 { | |
273 const struct def_pragma_macro *const a = (const struct def_pragma_macro *) pa, | |
274 *const b = (const struct def_pragma_macro *) pb; | |
275 return a->hash == b->hash && strcmp (a->name, b->name) == 0; | |
276 } | |
277 | |
278 /* #pragma push_macro("MACRO_NAME") | |
279 #pragma pop_macro("MACRO_NAME") */ | |
280 | |
281 static void | |
282 handle_pragma_push_macro (cpp_reader *reader) | |
283 { | |
284 tree x, id = 0; | |
285 enum cpp_ttype token; | |
286 struct def_pragma_macro dummy, *c; | |
287 const char *macroname; | |
288 void **slot; | |
289 | |
290 if (pragma_lex (&x) != CPP_OPEN_PAREN) | |
291 GCC_BAD ("missing %<(%> after %<#pragma push_macro%> - ignored"); | |
292 | |
293 token = pragma_lex (&id); | |
294 | |
295 /* Silently ignore */ | |
296 if (token == CPP_CLOSE_PAREN) | |
297 return; | |
298 if (token != CPP_STRING) | |
299 GCC_BAD ("invalid constant in %<#pragma push_macro%> - ignored"); | |
300 | |
301 if (pragma_lex (&x) != CPP_CLOSE_PAREN) | |
302 GCC_BAD ("missing %<)%> after %<#pragma push_macro%> - ignored"); | |
303 | |
304 if (pragma_lex (&x) != CPP_EOF) | |
305 warning (OPT_Wpragmas, "junk at end of %<#pragma push_macro%>"); | |
306 | |
307 /* Check for empty string, and silently ignore. */ | |
308 if (TREE_STRING_LENGTH (id) < 1) | |
309 return; | |
310 macroname = TREE_STRING_POINTER (id); | |
311 | |
312 if (pushed_macro_table == NULL) | |
313 pushed_macro_table = htab_create_ggc (15, dpm_hash, dpm_eq, 0); | |
314 | |
315 dummy.hash = htab_hash_string (macroname); | |
316 dummy.name = macroname; | |
317 slot = htab_find_slot_with_hash (pushed_macro_table, &dummy, | |
318 dummy.hash, INSERT); | |
319 c = (struct def_pragma_macro *) *slot; | |
320 if (c == NULL) | |
321 { | |
322 *slot = c = GGC_NEW (struct def_pragma_macro); | |
323 c->hash = dummy.hash; | |
324 c->name = ggc_alloc_string (macroname, TREE_STRING_LENGTH (id) - 1); | |
325 c->value.prev = NULL; | |
326 } | |
327 else | |
328 { | |
329 struct def_pragma_macro_value *v; | |
330 v = GGC_NEW (struct def_pragma_macro_value); | |
331 *v = c->value; | |
332 c->value.prev = v; | |
333 } | |
334 | |
335 c->value.value = cpp_push_definition (reader, macroname); | |
336 } | |
337 | |
338 static void | |
339 handle_pragma_pop_macro (cpp_reader *reader) | |
340 { | |
341 tree x, id = 0; | |
342 enum cpp_ttype token; | |
343 struct def_pragma_macro dummy, *c; | |
344 const char *macroname; | |
345 void **slot = NULL; | |
346 | |
347 if (pragma_lex (&x) != CPP_OPEN_PAREN) | |
348 GCC_BAD ("missing %<(%> after %<#pragma pop_macro%> - ignored"); | |
349 | |
350 token = pragma_lex (&id); | |
351 | |
352 /* Silently ignore */ | |
353 if (token == CPP_CLOSE_PAREN) | |
354 return; | |
355 if (token != CPP_STRING) | |
356 GCC_BAD ("invalid constant in %<#pragma pop_macro%> - ignored"); | |
357 | |
358 if (pragma_lex (&x) != CPP_CLOSE_PAREN) | |
359 GCC_BAD ("missing %<)%> after %<#pragma pop_macro%> - ignored"); | |
360 | |
361 if (pragma_lex (&x) != CPP_EOF) | |
362 warning (OPT_Wpragmas, "junk at end of %<#pragma pop_macro%>"); | |
363 | |
364 /* Check for empty string, and silently ignore. */ | |
365 if (TREE_STRING_LENGTH (id) < 1) | |
366 return; | |
367 macroname = TREE_STRING_POINTER (id); | |
368 | |
369 dummy.hash = htab_hash_string (macroname); | |
370 dummy.name = macroname; | |
371 if (pushed_macro_table) | |
372 slot = htab_find_slot_with_hash (pushed_macro_table, &dummy, | |
373 dummy.hash, NO_INSERT); | |
374 if (slot == NULL) | |
375 return; | |
376 c = (struct def_pragma_macro *) *slot; | |
377 | |
378 cpp_pop_definition (reader, c->name, c->value.value); | |
379 | |
380 if (c->value.prev) | |
381 c->value = *c->value.prev; | |
382 else | |
383 htab_clear_slot (pushed_macro_table, slot); | |
384 } | |
385 #endif /* HANDLE_PRAGMA_PUSH_POP_MACRO */ | |
386 | |
387 static GTY(()) tree pending_weaks; | |
388 | |
389 #ifdef HANDLE_PRAGMA_WEAK | |
390 static void apply_pragma_weak (tree, tree); | |
391 static void handle_pragma_weak (cpp_reader *); | |
392 | |
393 static void | |
394 apply_pragma_weak (tree decl, tree value) | |
395 { | |
396 if (value) | |
397 { | |
398 value = build_string (IDENTIFIER_LENGTH (value), | |
399 IDENTIFIER_POINTER (value)); | |
400 decl_attributes (&decl, build_tree_list (get_identifier ("alias"), | |
401 build_tree_list (NULL, value)), | |
402 0); | |
403 } | |
404 | |
405 if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl) | |
406 && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma. */ | |
407 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) | |
408 warning (OPT_Wpragmas, "applying #pragma weak %q+D after first use " | |
409 "results in unspecified behavior", decl); | |
410 | |
411 declare_weak (decl); | |
412 } | |
413 | |
414 void | |
415 maybe_apply_pragma_weak (tree decl) | |
416 { | |
417 tree *p, t, id; | |
418 | |
419 /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed. */ | |
420 | |
421 /* No weak symbols pending, take the short-cut. */ | |
422 if (!pending_weaks) | |
423 return; | |
424 /* If it's not visible outside this file, it doesn't matter whether | |
425 it's weak. */ | |
426 if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl)) | |
427 return; | |
428 /* If it's not a function or a variable, it can't be weak. | |
429 FIXME: what kinds of things are visible outside this file but | |
430 aren't functions or variables? Should this be an assert instead? */ | |
431 if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL) | |
432 return; | |
433 | |
434 id = DECL_ASSEMBLER_NAME (decl); | |
435 | |
436 for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t)) | |
437 if (id == TREE_PURPOSE (t)) | |
438 { | |
439 apply_pragma_weak (decl, TREE_VALUE (t)); | |
440 *p = TREE_CHAIN (t); | |
441 break; | |
442 } | |
443 } | |
444 | |
445 /* Process all "#pragma weak A = B" directives where we have not seen | |
446 a decl for A. */ | |
447 void | |
448 maybe_apply_pending_pragma_weaks (void) | |
449 { | |
450 tree *p, t, alias_id, id, decl, *next; | |
451 | |
452 for (p = &pending_weaks; (t = *p) ; p = next) | |
453 { | |
454 next = &TREE_CHAIN (t); | |
455 alias_id = TREE_PURPOSE (t); | |
456 id = TREE_VALUE (t); | |
457 | |
458 if (TREE_VALUE (t) == NULL) | |
459 continue; | |
460 | |
461 decl = build_decl (FUNCTION_DECL, alias_id, default_function_type); | |
462 | |
463 DECL_ARTIFICIAL (decl) = 1; | |
464 TREE_PUBLIC (decl) = 1; | |
465 DECL_EXTERNAL (decl) = 1; | |
466 DECL_WEAK (decl) = 1; | |
467 | |
468 assemble_alias (decl, id); | |
469 } | |
470 } | |
471 | |
472 /* #pragma weak name [= value] */ | |
473 static void | |
474 handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy)) | |
475 { | |
476 tree name, value, x, decl; | |
477 enum cpp_ttype t; | |
478 | |
479 value = 0; | |
480 | |
481 if (pragma_lex (&name) != CPP_NAME) | |
482 GCC_BAD ("malformed #pragma weak, ignored"); | |
483 t = pragma_lex (&x); | |
484 if (t == CPP_EQ) | |
485 { | |
486 if (pragma_lex (&value) != CPP_NAME) | |
487 GCC_BAD ("malformed #pragma weak, ignored"); | |
488 t = pragma_lex (&x); | |
489 } | |
490 if (t != CPP_EOF) | |
491 warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>"); | |
492 | |
493 decl = identifier_global_value (name); | |
494 if (decl && DECL_P (decl)) | |
495 { | |
496 apply_pragma_weak (decl, value); | |
497 if (value) | |
498 assemble_alias (decl, value); | |
499 } | |
500 else | |
501 pending_weaks = tree_cons (name, value, pending_weaks); | |
502 } | |
503 #else | |
504 void | |
505 maybe_apply_pragma_weak (tree ARG_UNUSED (decl)) | |
506 { | |
507 } | |
508 | |
509 void | |
510 maybe_apply_pending_pragma_weaks (void) | |
511 { | |
512 } | |
513 #endif /* HANDLE_PRAGMA_WEAK */ | |
514 | |
515 /* GCC supports two #pragma directives for renaming the external | |
516 symbol associated with a declaration (DECL_ASSEMBLER_NAME), for | |
517 compatibility with the Solaris and Tru64 system headers. GCC also | |
518 has its own notation for this, __asm__("name") annotations. | |
519 | |
520 Corner cases of these features and their interaction: | |
521 | |
522 1) Both pragmas silently apply only to declarations with external | |
523 linkage (that is, TREE_PUBLIC || DECL_EXTERNAL). Asm labels | |
524 do not have this restriction. | |
525 | |
526 2) In C++, both #pragmas silently apply only to extern "C" declarations. | |
527 Asm labels do not have this restriction. | |
528 | |
529 3) If any of the three ways of changing DECL_ASSEMBLER_NAME is | |
530 applied to a decl whose DECL_ASSEMBLER_NAME is already set, and the | |
531 new name is different, a warning issues and the name does not change. | |
532 | |
533 4) The "source name" for #pragma redefine_extname is the DECL_NAME, | |
534 *not* the DECL_ASSEMBLER_NAME. | |
535 | |
536 5) If #pragma extern_prefix is in effect and a declaration occurs | |
537 with an __asm__ name, the #pragma extern_prefix is silently | |
538 ignored for that declaration. | |
539 | |
540 6) If #pragma extern_prefix and #pragma redefine_extname apply to | |
541 the same declaration, whichever triggered first wins, and a warning | |
542 is issued. (We would like to have #pragma redefine_extname always | |
543 win, but it can appear either before or after the declaration, and | |
544 if it appears afterward, we have no way of knowing whether a modified | |
545 DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.) */ | |
546 | |
547 static GTY(()) tree pending_redefine_extname; | |
548 | |
549 static void handle_pragma_redefine_extname (cpp_reader *); | |
550 | |
551 /* #pragma redefine_extname oldname newname */ | |
552 static void | |
553 handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy)) | |
554 { | |
555 tree oldname, newname, decl, x; | |
556 enum cpp_ttype t; | |
557 | |
558 if (pragma_lex (&oldname) != CPP_NAME) | |
559 GCC_BAD ("malformed #pragma redefine_extname, ignored"); | |
560 if (pragma_lex (&newname) != CPP_NAME) | |
561 GCC_BAD ("malformed #pragma redefine_extname, ignored"); | |
562 t = pragma_lex (&x); | |
563 if (t != CPP_EOF) | |
564 warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>"); | |
565 | |
566 if (!flag_mudflap && !targetm.handle_pragma_redefine_extname) | |
567 { | |
568 if (warn_unknown_pragmas > in_system_header) | |
569 warning (OPT_Wunknown_pragmas, | |
570 "#pragma redefine_extname not supported on this target"); | |
571 return; | |
572 } | |
573 | |
574 decl = identifier_global_value (oldname); | |
575 if (decl | |
576 && (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)) | |
577 && (TREE_CODE (decl) == FUNCTION_DECL | |
578 || TREE_CODE (decl) == VAR_DECL) | |
579 && has_c_linkage (decl)) | |
580 { | |
581 if (DECL_ASSEMBLER_NAME_SET_P (decl)) | |
582 { | |
583 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); | |
584 name = targetm.strip_name_encoding (name); | |
585 | |
586 if (strcmp (name, IDENTIFIER_POINTER (newname))) | |
587 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " | |
588 "conflict with previous rename"); | |
589 } | |
590 else | |
591 change_decl_assembler_name (decl, newname); | |
592 } | |
593 else | |
594 /* We have to add this to the rename list even if there's already | |
595 a global value that doesn't meet the above criteria, because in | |
596 C++ "struct foo {...};" puts "foo" in the current namespace but | |
597 does *not* conflict with a subsequent declaration of a function | |
598 or variable foo. See g++.dg/other/pragma-re-2.C. */ | |
599 add_to_renaming_pragma_list (oldname, newname); | |
600 } | |
601 | |
602 /* This is called from here and from ia64.c. */ | |
603 void | |
604 add_to_renaming_pragma_list (tree oldname, tree newname) | |
605 { | |
606 tree previous = purpose_member (oldname, pending_redefine_extname); | |
607 if (previous) | |
608 { | |
609 if (TREE_VALUE (previous) != newname) | |
610 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " | |
611 "conflict with previous #pragma redefine_extname"); | |
612 return; | |
613 } | |
614 | |
615 pending_redefine_extname | |
616 = tree_cons (oldname, newname, pending_redefine_extname); | |
617 } | |
618 | |
619 static GTY(()) tree pragma_extern_prefix; | |
620 | |
621 /* #pragma extern_prefix "prefix" */ | |
622 static void | |
623 handle_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy)) | |
624 { | |
625 tree prefix, x; | |
626 enum cpp_ttype t; | |
627 | |
628 if (pragma_lex (&prefix) != CPP_STRING) | |
629 GCC_BAD ("malformed #pragma extern_prefix, ignored"); | |
630 t = pragma_lex (&x); | |
631 if (t != CPP_EOF) | |
632 warning (OPT_Wpragmas, "junk at end of %<#pragma extern_prefix%>"); | |
633 | |
634 if (targetm.handle_pragma_extern_prefix) | |
635 /* Note that the length includes the null terminator. */ | |
636 pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL); | |
637 else if (warn_unknown_pragmas > in_system_header) | |
638 warning (OPT_Wunknown_pragmas, | |
639 "#pragma extern_prefix not supported on this target"); | |
640 } | |
641 | |
642 /* Hook from the front ends to apply the results of one of the preceding | |
643 pragmas that rename variables. */ | |
644 | |
645 tree | |
646 maybe_apply_renaming_pragma (tree decl, tree asmname) | |
647 { | |
648 tree *p, t; | |
649 | |
650 /* The renaming pragmas are only applied to declarations with | |
651 external linkage. */ | |
652 if ((TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL) | |
653 || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) | |
654 || !has_c_linkage (decl)) | |
655 return asmname; | |
656 | |
657 /* If the DECL_ASSEMBLER_NAME is already set, it does not change, | |
658 but we may warn about a rename that conflicts. */ | |
659 if (DECL_ASSEMBLER_NAME_SET_P (decl)) | |
660 { | |
661 const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); | |
662 oldname = targetm.strip_name_encoding (oldname); | |
663 | |
664 if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname)) | |
665 warning (OPT_Wpragmas, "asm declaration ignored due to " | |
666 "conflict with previous rename"); | |
667 | |
668 /* Take any pending redefine_extname off the list. */ | |
669 for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t)) | |
670 if (DECL_NAME (decl) == TREE_PURPOSE (t)) | |
671 { | |
672 /* Only warn if there is a conflict. */ | |
673 if (strcmp (IDENTIFIER_POINTER (TREE_VALUE (t)), oldname)) | |
674 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " | |
675 "conflict with previous rename"); | |
676 | |
677 *p = TREE_CHAIN (t); | |
678 break; | |
679 } | |
680 return 0; | |
681 } | |
682 | |
683 /* Find out if we have a pending #pragma redefine_extname. */ | |
684 for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t)) | |
685 if (DECL_NAME (decl) == TREE_PURPOSE (t)) | |
686 { | |
687 tree newname = TREE_VALUE (t); | |
688 *p = TREE_CHAIN (t); | |
689 | |
690 /* If we already have an asmname, #pragma redefine_extname is | |
691 ignored (with a warning if it conflicts). */ | |
692 if (asmname) | |
693 { | |
694 if (strcmp (TREE_STRING_POINTER (asmname), | |
695 IDENTIFIER_POINTER (newname)) != 0) | |
696 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " | |
697 "conflict with __asm__ declaration"); | |
698 return asmname; | |
699 } | |
700 | |
701 /* Otherwise we use what we've got; #pragma extern_prefix is | |
702 silently ignored. */ | |
703 return build_string (IDENTIFIER_LENGTH (newname), | |
704 IDENTIFIER_POINTER (newname)); | |
705 } | |
706 | |
707 /* If we've got an asmname, #pragma extern_prefix is silently ignored. */ | |
708 if (asmname) | |
709 return asmname; | |
710 | |
711 /* If #pragma extern_prefix is in effect, apply it. */ | |
712 if (pragma_extern_prefix) | |
713 { | |
714 const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix); | |
715 size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1; | |
716 | |
717 const char *id = IDENTIFIER_POINTER (DECL_NAME (decl)); | |
718 size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl)); | |
719 | |
720 char *newname = (char *) alloca (plen + ilen + 1); | |
721 | |
722 memcpy (newname, prefix, plen); | |
723 memcpy (newname + plen, id, ilen + 1); | |
724 | |
725 return build_string (plen + ilen, newname); | |
726 } | |
727 | |
728 /* Nada. */ | |
729 return 0; | |
730 } | |
731 | |
732 | |
733 #ifdef HANDLE_PRAGMA_VISIBILITY | |
734 static void handle_pragma_visibility (cpp_reader *); | |
735 | |
736 typedef enum symbol_visibility visibility; | |
737 DEF_VEC_I (visibility); | |
738 DEF_VEC_ALLOC_I (visibility, heap); | |
739 static VEC (visibility, heap) *visstack; | |
740 | |
741 /* Push the visibility indicated by STR onto the top of the #pragma | |
742 visibility stack. */ | |
743 | |
744 void | |
745 push_visibility (const char *str) | |
746 { | |
747 VEC_safe_push (visibility, heap, visstack, | |
748 default_visibility); | |
749 if (!strcmp (str, "default")) | |
750 default_visibility = VISIBILITY_DEFAULT; | |
751 else if (!strcmp (str, "internal")) | |
752 default_visibility = VISIBILITY_INTERNAL; | |
753 else if (!strcmp (str, "hidden")) | |
754 default_visibility = VISIBILITY_HIDDEN; | |
755 else if (!strcmp (str, "protected")) | |
756 default_visibility = VISIBILITY_PROTECTED; | |
757 else | |
758 GCC_BAD ("#pragma GCC visibility push() must specify default, internal, hidden or protected"); | |
759 visibility_options.inpragma = 1; | |
760 } | |
761 | |
762 /* Pop a level of the #pragma visibility stack. */ | |
763 | |
764 void | |
765 pop_visibility (void) | |
766 { | |
767 default_visibility = VEC_pop (visibility, visstack); | |
768 visibility_options.inpragma | |
769 = VEC_length (visibility, visstack) != 0; | |
770 } | |
771 | |
772 /* Sets the default visibility for symbols to something other than that | |
773 specified on the command line. */ | |
774 | |
775 static void | |
776 handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED) | |
777 { | |
778 /* Form is #pragma GCC visibility push(hidden)|pop */ | |
779 tree x; | |
780 enum cpp_ttype token; | |
781 enum { bad, push, pop } action = bad; | |
782 | |
783 token = pragma_lex (&x); | |
784 if (token == CPP_NAME) | |
785 { | |
786 const char *op = IDENTIFIER_POINTER (x); | |
787 if (!strcmp (op, "push")) | |
788 action = push; | |
789 else if (!strcmp (op, "pop")) | |
790 action = pop; | |
791 } | |
792 if (bad == action) | |
793 GCC_BAD ("#pragma GCC visibility must be followed by push or pop"); | |
794 else | |
795 { | |
796 if (pop == action) | |
797 { | |
798 if (!VEC_length (visibility, visstack)) | |
799 GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>"); | |
800 else | |
801 pop_visibility (); | |
802 } | |
803 else | |
804 { | |
805 if (pragma_lex (&x) != CPP_OPEN_PAREN) | |
806 GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored"); | |
807 token = pragma_lex (&x); | |
808 if (token != CPP_NAME) | |
809 GCC_BAD ("malformed #pragma GCC visibility push"); | |
810 else | |
811 push_visibility (IDENTIFIER_POINTER (x)); | |
812 if (pragma_lex (&x) != CPP_CLOSE_PAREN) | |
813 GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored"); | |
814 } | |
815 } | |
816 if (pragma_lex (&x) != CPP_EOF) | |
817 warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>"); | |
818 } | |
819 | |
820 #endif | |
821 | |
822 static void | |
823 handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy)) | |
824 { | |
825 const char *kind_string, *option_string; | |
826 unsigned int option_index; | |
827 enum cpp_ttype token; | |
828 diagnostic_t kind; | |
829 tree x; | |
830 | |
831 if (cfun) | |
832 { | |
833 error ("#pragma GCC diagnostic not allowed inside functions"); | |
834 return; | |
835 } | |
836 | |
837 token = pragma_lex (&x); | |
838 if (token != CPP_NAME) | |
839 GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>"); | |
840 kind_string = IDENTIFIER_POINTER (x); | |
841 if (strcmp (kind_string, "error") == 0) | |
842 kind = DK_ERROR; | |
843 else if (strcmp (kind_string, "warning") == 0) | |
844 kind = DK_WARNING; | |
845 else if (strcmp (kind_string, "ignored") == 0) | |
846 kind = DK_IGNORED; | |
847 else | |
848 GCC_BAD ("expected [error|warning|ignored] after %<#pragma GCC diagnostic%>"); | |
849 | |
850 token = pragma_lex (&x); | |
851 if (token != CPP_STRING) | |
852 GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind"); | |
853 option_string = TREE_STRING_POINTER (x); | |
854 for (option_index = 0; option_index < cl_options_count; option_index++) | |
855 if (strcmp (cl_options[option_index].opt_text, option_string) == 0) | |
856 { | |
857 /* This overrides -Werror, for example. */ | |
858 diagnostic_classify_diagnostic (global_dc, option_index, kind); | |
859 /* This makes sure the option is enabled, like -Wfoo would do. */ | |
860 if (cl_options[option_index].var_type == CLVC_BOOLEAN | |
861 && cl_options[option_index].flag_var | |
862 && kind != DK_IGNORED) | |
863 *(int *) cl_options[option_index].flag_var = 1; | |
864 return; | |
865 } | |
866 GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind"); | |
867 } | |
868 | |
869 /* Parse #pragma GCC target (xxx) to set target specific options. */ | |
870 static void | |
871 handle_pragma_target(cpp_reader *ARG_UNUSED(dummy)) | |
872 { | |
873 enum cpp_ttype token; | |
874 tree x; | |
875 bool close_paren_needed_p = false; | |
876 | |
877 if (cfun) | |
878 { | |
879 error ("#pragma GCC option is not allowed inside functions"); | |
880 return; | |
881 } | |
882 | |
883 token = pragma_lex (&x); | |
884 if (token == CPP_OPEN_PAREN) | |
885 { | |
886 close_paren_needed_p = true; | |
887 token = pragma_lex (&x); | |
888 } | |
889 | |
890 if (token != CPP_STRING) | |
891 { | |
892 GCC_BAD ("%<#pragma GCC option%> is not a string"); | |
893 return; | |
894 } | |
895 | |
896 /* Strings are user options. */ | |
897 else | |
898 { | |
899 tree args = NULL_TREE; | |
900 | |
901 do | |
902 { | |
903 /* Build up the strings now as a tree linked list. Skip empty | |
904 strings. */ | |
905 if (TREE_STRING_LENGTH (x) > 0) | |
906 args = tree_cons (NULL_TREE, x, args); | |
907 | |
908 token = pragma_lex (&x); | |
909 while (token == CPP_COMMA) | |
910 token = pragma_lex (&x); | |
911 } | |
912 while (token == CPP_STRING); | |
913 | |
914 if (close_paren_needed_p) | |
915 { | |
916 if (token == CPP_CLOSE_PAREN) | |
917 token = pragma_lex (&x); | |
918 else | |
919 GCC_BAD ("%<#pragma GCC target (string [,string]...)%> does " | |
920 "not have a final %<)%>."); | |
921 } | |
922 | |
923 if (token != CPP_EOF) | |
924 { | |
925 error ("#pragma GCC target string... is badly formed"); | |
926 return; | |
927 } | |
928 | |
929 /* put arguments in the order the user typed them. */ | |
930 args = nreverse (args); | |
931 | |
932 if (targetm.target_option.pragma_parse (args, NULL_TREE)) | |
933 current_target_pragma = args; | |
934 } | |
935 } | |
936 | |
937 /* Handle #pragma GCC optimize to set optimization options. */ | |
938 static void | |
939 handle_pragma_optimize (cpp_reader *ARG_UNUSED(dummy)) | |
940 { | |
941 enum cpp_ttype token; | |
942 tree x; | |
943 bool close_paren_needed_p = false; | |
944 tree optimization_previous_node = optimization_current_node; | |
945 | |
946 if (cfun) | |
947 { | |
948 error ("#pragma GCC optimize is not allowed inside functions"); | |
949 return; | |
950 } | |
951 | |
952 token = pragma_lex (&x); | |
953 if (token == CPP_OPEN_PAREN) | |
954 { | |
955 close_paren_needed_p = true; | |
956 token = pragma_lex (&x); | |
957 } | |
958 | |
959 if (token != CPP_STRING && token != CPP_NUMBER) | |
960 { | |
961 GCC_BAD ("%<#pragma GCC optimize%> is not a string or number"); | |
962 return; | |
963 } | |
964 | |
965 /* Strings/numbers are user options. */ | |
966 else | |
967 { | |
968 tree args = NULL_TREE; | |
969 | |
970 do | |
971 { | |
972 /* Build up the numbers/strings now as a list. */ | |
973 if (token != CPP_STRING || TREE_STRING_LENGTH (x) > 0) | |
974 args = tree_cons (NULL_TREE, x, args); | |
975 | |
976 token = pragma_lex (&x); | |
977 while (token == CPP_COMMA) | |
978 token = pragma_lex (&x); | |
979 } | |
980 while (token == CPP_STRING || token == CPP_NUMBER); | |
981 | |
982 if (close_paren_needed_p) | |
983 { | |
984 if (token == CPP_CLOSE_PAREN) | |
985 token = pragma_lex (&x); | |
986 else | |
987 GCC_BAD ("%<#pragma GCC optimize (string [,string]...)%> does " | |
988 "not have a final %<)%>."); | |
989 } | |
990 | |
991 if (token != CPP_EOF) | |
992 { | |
993 error ("#pragma GCC optimize string... is badly formed"); | |
994 return; | |
995 } | |
996 | |
997 /* put arguments in the order the user typed them. */ | |
998 args = nreverse (args); | |
999 | |
1000 parse_optimize_options (args, false); | |
1001 current_optimize_pragma = chainon (current_optimize_pragma, args); | |
1002 optimization_current_node = build_optimization_node (); | |
1003 c_cpp_builtins_optimize_pragma (parse_in, | |
1004 optimization_previous_node, | |
1005 optimization_current_node); | |
1006 } | |
1007 } | |
1008 | |
1009 /* Stack of the #pragma GCC options created with #pragma GCC push_option. Save | |
1010 both the binary representation of the options and the TREE_LIST of | |
1011 strings that will be added to the function's attribute list. */ | |
1012 typedef struct opt_stack GTY(()) | |
1013 { | |
1014 struct opt_stack *prev; | |
1015 tree target_binary; | |
1016 tree target_strings; | |
1017 tree optimize_binary; | |
1018 tree optimize_strings; | |
1019 } opt_stack; | |
1020 | |
1021 static GTY(()) struct opt_stack * options_stack; | |
1022 | |
1023 /* Handle #pragma GCC push_options to save the current target and optimization | |
1024 options. */ | |
1025 | |
1026 static void | |
1027 handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy)) | |
1028 { | |
1029 enum cpp_ttype token; | |
1030 tree x = 0; | |
1031 opt_stack *p; | |
1032 | |
1033 token = pragma_lex (&x); | |
1034 if (token != CPP_EOF) | |
1035 { | |
1036 warning (OPT_Wpragmas, "junk at end of %<#pragma push_options%>"); | |
1037 return; | |
1038 } | |
1039 | |
1040 p = GGC_NEW (opt_stack); | |
1041 p->prev = options_stack; | |
1042 options_stack = p; | |
1043 | |
1044 /* Save optimization and target flags in binary format. */ | |
1045 p->optimize_binary = build_optimization_node (); | |
1046 p->target_binary = build_target_option_node (); | |
1047 | |
1048 /* Save optimization and target flags in string list format. */ | |
1049 p->optimize_strings = copy_list (current_optimize_pragma); | |
1050 p->target_strings = copy_list (current_target_pragma); | |
1051 } | |
1052 | |
1053 /* Handle #pragma GCC pop_options to restore the current target and | |
1054 optimization options from a previous push_options. */ | |
1055 | |
1056 static void | |
1057 handle_pragma_pop_options (cpp_reader *ARG_UNUSED(dummy)) | |
1058 { | |
1059 enum cpp_ttype token; | |
1060 tree x = 0; | |
1061 opt_stack *p; | |
1062 | |
1063 token = pragma_lex (&x); | |
1064 if (token != CPP_EOF) | |
1065 { | |
1066 warning (OPT_Wpragmas, "junk at end of %<#pragma pop_options%>"); | |
1067 return; | |
1068 } | |
1069 | |
1070 if (! options_stack) | |
1071 { | |
1072 warning (OPT_Wpragmas, | |
1073 "%<#pragma GCC pop_options%> without a corresponding " | |
1074 "%<#pragma GCC push_options%>"); | |
1075 return; | |
1076 } | |
1077 | |
1078 p = options_stack; | |
1079 options_stack = p->prev; | |
1080 | |
1081 if (p->target_binary != target_option_current_node) | |
1082 { | |
1083 (void) targetm.target_option.pragma_parse (NULL_TREE, p->target_binary); | |
1084 target_option_current_node = p->target_binary; | |
1085 } | |
1086 | |
1087 if (p->optimize_binary != optimization_current_node) | |
1088 { | |
1089 tree old_optimize = optimization_current_node; | |
1090 cl_optimization_restore (TREE_OPTIMIZATION (p->optimize_binary)); | |
1091 c_cpp_builtins_optimize_pragma (parse_in, old_optimize, | |
1092 p->optimize_binary); | |
1093 optimization_current_node = p->optimize_binary; | |
1094 } | |
1095 | |
1096 current_target_pragma = p->target_strings; | |
1097 current_optimize_pragma = p->optimize_strings; | |
1098 } | |
1099 | |
1100 /* Handle #pragma GCC reset_options to restore the current target and | |
1101 optimization options to the original options used on the command line. */ | |
1102 | |
1103 static void | |
1104 handle_pragma_reset_options (cpp_reader *ARG_UNUSED(dummy)) | |
1105 { | |
1106 enum cpp_ttype token; | |
1107 tree x = 0; | |
1108 tree new_optimize = optimization_default_node; | |
1109 tree new_target = target_option_default_node; | |
1110 | |
1111 token = pragma_lex (&x); | |
1112 if (token != CPP_EOF) | |
1113 { | |
1114 warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>"); | |
1115 return; | |
1116 } | |
1117 | |
1118 if (new_target != target_option_current_node) | |
1119 { | |
1120 (void) targetm.target_option.pragma_parse (NULL_TREE, new_target); | |
1121 target_option_current_node = new_target; | |
1122 } | |
1123 | |
1124 if (new_optimize != optimization_current_node) | |
1125 { | |
1126 tree old_optimize = optimization_current_node; | |
1127 cl_optimization_restore (TREE_OPTIMIZATION (new_optimize)); | |
1128 c_cpp_builtins_optimize_pragma (parse_in, old_optimize, new_optimize); | |
1129 optimization_current_node = new_optimize; | |
1130 } | |
1131 | |
1132 current_target_pragma = NULL_TREE; | |
1133 current_optimize_pragma = NULL_TREE; | |
1134 } | |
1135 | |
1136 /* Print a plain user-specified message. */ | |
1137 | |
1138 static void | |
1139 handle_pragma_message (cpp_reader *ARG_UNUSED(dummy)) | |
1140 { | |
1141 enum cpp_ttype token; | |
1142 tree x, message = 0; | |
1143 | |
1144 token = pragma_lex (&x); | |
1145 if (token == CPP_OPEN_PAREN) | |
1146 { | |
1147 token = pragma_lex (&x); | |
1148 if (token == CPP_STRING) | |
1149 message = x; | |
1150 else | |
1151 GCC_BAD ("expected a string after %<#pragma message%>"); | |
1152 if (pragma_lex (&x) != CPP_CLOSE_PAREN) | |
1153 GCC_BAD ("malformed %<#pragma message%>, ignored"); | |
1154 } | |
1155 else if (token == CPP_STRING) | |
1156 message = x; | |
1157 else | |
1158 GCC_BAD ("expected a string after %<#pragma message%>"); | |
1159 | |
1160 gcc_assert (message); | |
1161 | |
1162 if (pragma_lex (&x) != CPP_EOF) | |
1163 warning (OPT_Wpragmas, "junk at end of %<#pragma message%>"); | |
1164 | |
1165 if (TREE_STRING_LENGTH (message) > 1) | |
1166 inform (input_location, "#pragma message: %s", TREE_STRING_POINTER (message)); | |
1167 } | |
1168 | |
1169 /* A vector of registered pragma callbacks. */ | |
1170 | |
1171 DEF_VEC_O (pragma_handler); | |
1172 DEF_VEC_ALLOC_O (pragma_handler, heap); | |
1173 | |
1174 static VEC(pragma_handler, heap) *registered_pragmas; | |
1175 | |
1176 typedef struct | |
1177 { | |
1178 const char *space; | |
1179 const char *name; | |
1180 } pragma_ns_name; | |
1181 | |
1182 DEF_VEC_O (pragma_ns_name); | |
1183 DEF_VEC_ALLOC_O (pragma_ns_name, heap); | |
1184 | |
1185 static VEC(pragma_ns_name, heap) *registered_pp_pragmas; | |
1186 | |
1187 struct omp_pragma_def { const char *name; unsigned int id; }; | |
1188 static const struct omp_pragma_def omp_pragmas[] = { | |
1189 { "atomic", PRAGMA_OMP_ATOMIC }, | |
1190 { "barrier", PRAGMA_OMP_BARRIER }, | |
1191 { "critical", PRAGMA_OMP_CRITICAL }, | |
1192 { "flush", PRAGMA_OMP_FLUSH }, | |
1193 { "for", PRAGMA_OMP_FOR }, | |
1194 { "master", PRAGMA_OMP_MASTER }, | |
1195 { "ordered", PRAGMA_OMP_ORDERED }, | |
1196 { "parallel", PRAGMA_OMP_PARALLEL }, | |
1197 { "section", PRAGMA_OMP_SECTION }, | |
1198 { "sections", PRAGMA_OMP_SECTIONS }, | |
1199 { "single", PRAGMA_OMP_SINGLE }, | |
1200 { "task", PRAGMA_OMP_TASK }, | |
1201 { "taskwait", PRAGMA_OMP_TASKWAIT }, | |
1202 { "threadprivate", PRAGMA_OMP_THREADPRIVATE } | |
1203 }; | |
1204 | |
1205 void | |
1206 c_pp_lookup_pragma (unsigned int id, const char **space, const char **name) | |
1207 { | |
1208 const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas); | |
1209 int i; | |
1210 | |
1211 for (i = 0; i < n_omp_pragmas; ++i) | |
1212 if (omp_pragmas[i].id == id) | |
1213 { | |
1214 *space = "omp"; | |
1215 *name = omp_pragmas[i].name; | |
1216 return; | |
1217 } | |
1218 | |
1219 if (id >= PRAGMA_FIRST_EXTERNAL | |
1220 && (id < PRAGMA_FIRST_EXTERNAL | |
1221 + VEC_length (pragma_ns_name, registered_pp_pragmas))) | |
1222 { | |
1223 *space = VEC_index (pragma_ns_name, registered_pp_pragmas, | |
1224 id - PRAGMA_FIRST_EXTERNAL)->space; | |
1225 *name = VEC_index (pragma_ns_name, registered_pp_pragmas, | |
1226 id - PRAGMA_FIRST_EXTERNAL)->name; | |
1227 return; | |
1228 } | |
1229 | |
1230 gcc_unreachable (); | |
1231 } | |
1232 | |
1233 /* Front-end wrappers for pragma registration to avoid dragging | |
1234 cpplib.h in almost everywhere. */ | |
1235 | |
1236 static void | |
1237 c_register_pragma_1 (const char *space, const char *name, | |
1238 pragma_handler handler, bool allow_expansion) | |
1239 { | |
1240 unsigned id; | |
1241 | |
1242 if (flag_preprocess_only) | |
1243 { | |
1244 pragma_ns_name ns_name; | |
1245 | |
1246 if (!allow_expansion) | |
1247 return; | |
1248 | |
1249 ns_name.space = space; | |
1250 ns_name.name = name; | |
1251 VEC_safe_push (pragma_ns_name, heap, registered_pp_pragmas, &ns_name); | |
1252 id = VEC_length (pragma_ns_name, registered_pp_pragmas); | |
1253 id += PRAGMA_FIRST_EXTERNAL - 1; | |
1254 } | |
1255 else | |
1256 { | |
1257 VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); | |
1258 id = VEC_length (pragma_handler, registered_pragmas); | |
1259 id += PRAGMA_FIRST_EXTERNAL - 1; | |
1260 | |
1261 /* The C++ front end allocates 6 bits in cp_token; the C front end | |
1262 allocates 7 bits in c_token. At present this is sufficient. */ | |
1263 gcc_assert (id < 64); | |
1264 } | |
1265 | |
1266 cpp_register_deferred_pragma (parse_in, space, name, id, | |
1267 allow_expansion, false); | |
1268 } | |
1269 | |
1270 void | |
1271 c_register_pragma (const char *space, const char *name, pragma_handler handler) | |
1272 { | |
1273 c_register_pragma_1 (space, name, handler, false); | |
1274 } | |
1275 | |
1276 void | |
1277 c_register_pragma_with_expansion (const char *space, const char *name, | |
1278 pragma_handler handler) | |
1279 { | |
1280 c_register_pragma_1 (space, name, handler, true); | |
1281 } | |
1282 | |
1283 void | |
1284 c_invoke_pragma_handler (unsigned int id) | |
1285 { | |
1286 pragma_handler handler; | |
1287 | |
1288 id -= PRAGMA_FIRST_EXTERNAL; | |
1289 handler = *VEC_index (pragma_handler, registered_pragmas, id); | |
1290 | |
1291 handler (parse_in); | |
1292 } | |
1293 | |
1294 /* Set up front-end pragmas. */ | |
1295 void | |
1296 init_pragma (void) | |
1297 { | |
1298 if (flag_openmp) | |
1299 { | |
1300 const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas); | |
1301 int i; | |
1302 | |
1303 for (i = 0; i < n_omp_pragmas; ++i) | |
1304 cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name, | |
1305 omp_pragmas[i].id, true, true); | |
1306 } | |
1307 | |
1308 if (!flag_preprocess_only) | |
1309 cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess", | |
1310 PRAGMA_GCC_PCH_PREPROCESS, false, false); | |
1311 | |
1312 #ifdef HANDLE_PRAGMA_PACK | |
1313 #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION | |
1314 c_register_pragma_with_expansion (0, "pack", handle_pragma_pack); | |
1315 #else | |
1316 c_register_pragma (0, "pack", handle_pragma_pack); | |
1317 #endif | |
1318 #endif | |
1319 #ifdef HANDLE_PRAGMA_PUSH_POP_MACRO | |
1320 c_register_pragma (0 ,"push_macro", handle_pragma_push_macro); | |
1321 c_register_pragma (0 ,"pop_macro", handle_pragma_pop_macro); | |
1322 #endif | |
1323 #ifdef HANDLE_PRAGMA_WEAK | |
1324 c_register_pragma (0, "weak", handle_pragma_weak); | |
1325 #endif | |
1326 #ifdef HANDLE_PRAGMA_VISIBILITY | |
1327 c_register_pragma ("GCC", "visibility", handle_pragma_visibility); | |
1328 #endif | |
1329 | |
1330 c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic); | |
1331 c_register_pragma ("GCC", "target", handle_pragma_target); | |
1332 c_register_pragma ("GCC", "optimize", handle_pragma_optimize); | |
1333 c_register_pragma ("GCC", "push_options", handle_pragma_push_options); | |
1334 c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options); | |
1335 c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options); | |
1336 | |
1337 c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname); | |
1338 c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix); | |
1339 | |
1340 c_register_pragma_with_expansion (0, "message", handle_pragma_message); | |
1341 | |
1342 #ifdef REGISTER_TARGET_PRAGMAS | |
1343 REGISTER_TARGET_PRAGMAS (); | |
1344 #endif | |
1345 } | |
1346 | |
1347 #include "gt-c-pragma.h" |