Mercurial > hg > CbC > CbC_gcc
comparison gcc/c-family/c-pragma.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | 561a7518be6b |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack. | 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, | 2 Copyright (C) 1992-2017 Free Software Foundation, Inc. |
3 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. | |
4 | 3 |
5 This file is part of GCC. | 4 This file is part of GCC. |
6 | 5 |
7 GCC is free software; you can redistribute it and/or modify it under | 6 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 | 7 the terms of the GNU General Public License as published by the Free |
19 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
20 | 19 |
21 #include "config.h" | 20 #include "config.h" |
22 #include "system.h" | 21 #include "system.h" |
23 #include "coretypes.h" | 22 #include "coretypes.h" |
24 #include "tm.h" | 23 #include "target.h" |
25 #include "tree.h" | 24 #include "function.h" /* For cfun. */ |
26 #include "function.h" /* For cfun. FIXME: Does the parser know | 25 #include "c-common.h" |
27 when it is inside a function, so that | 26 #include "memmodel.h" |
28 we don't have to look at cfun? */ | 27 #include "tm_p.h" /* For REGISTER_TARGET_PRAGMAS. */ |
29 #include "cpplib.h" | 28 #include "stringpool.h" |
29 #include "cgraph.h" | |
30 #include "diagnostic.h" | |
31 #include "attribs.h" | |
32 #include "varasm.h" | |
30 #include "c-pragma.h" | 33 #include "c-pragma.h" |
31 #include "flags.h" | |
32 #include "c-common.h" | |
33 #include "output.h" | |
34 #include "tm_p.h" /* For REGISTER_TARGET_PRAGMAS (why is | |
35 this not a target hook?). */ | |
36 #include "vec.h" | |
37 #include "vecprim.h" | |
38 #include "target.h" | |
39 #include "diagnostic.h" | |
40 #include "opts.h" | 34 #include "opts.h" |
41 #include "plugin.h" | 35 #include "plugin.h" |
42 | 36 |
43 #define GCC_BAD(gmsgid) \ | 37 #define GCC_BAD(gmsgid) \ |
44 do { warning (OPT_Wpragmas, gmsgid); return; } while (0) | 38 do { warning (OPT_Wpragmas, gmsgid); return; } while (0) |
45 #define GCC_BAD2(gmsgid, arg) \ | 39 #define GCC_BAD2(gmsgid, arg) \ |
46 do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0) | 40 do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0) |
47 | 41 |
48 typedef struct GTY(()) align_stack { | 42 struct GTY(()) align_stack { |
49 int alignment; | 43 int alignment; |
50 tree id; | 44 tree id; |
51 struct align_stack * prev; | 45 struct align_stack * prev; |
52 } align_stack; | 46 }; |
53 | 47 |
54 static GTY(()) struct align_stack * alignment_stack; | 48 static GTY(()) struct align_stack * alignment_stack; |
55 | 49 |
56 static void handle_pragma_pack (cpp_reader *); | 50 static void handle_pragma_pack (cpp_reader *); |
57 | 51 |
70 | 64 |
71 /* Push an alignment value onto the stack. */ | 65 /* Push an alignment value onto the stack. */ |
72 static void | 66 static void |
73 push_alignment (int alignment, tree id) | 67 push_alignment (int alignment, tree id) |
74 { | 68 { |
75 align_stack * entry; | 69 align_stack * entry = ggc_alloc<align_stack> (); |
76 | |
77 entry = ggc_alloc_align_stack (); | |
78 | 70 |
79 entry->alignment = alignment; | 71 entry->alignment = alignment; |
80 entry->id = id; | 72 entry->id = id; |
81 entry->prev = alignment_stack; | 73 entry->prev = alignment_stack; |
82 | 74 |
221 if (action == push) | 213 if (action == push) |
222 { | 214 { |
223 align = maximum_field_alignment; | 215 align = maximum_field_alignment; |
224 break; | 216 break; |
225 } | 217 } |
218 /* FALLTHRU */ | |
226 default: | 219 default: |
227 GCC_BAD2 ("alignment must be a small power of two, not %d", align); | 220 GCC_BAD2 ("alignment must be a small power of two, not %d", align); |
228 } | 221 } |
229 | 222 |
230 switch (action) | 223 switch (action) |
233 case push: push_alignment (align, id); break; | 226 case push: push_alignment (align, id); break; |
234 case pop: pop_alignment (id); break; | 227 case pop: pop_alignment (id); break; |
235 } | 228 } |
236 } | 229 } |
237 | 230 |
238 typedef struct GTY(()) pending_weak_d | 231 struct GTY(()) pending_weak |
239 { | 232 { |
240 tree name; | 233 tree name; |
241 tree value; | 234 tree value; |
242 } pending_weak; | 235 }; |
243 | 236 |
244 DEF_VEC_O(pending_weak); | 237 |
245 DEF_VEC_ALLOC_O(pending_weak,gc); | 238 static GTY(()) vec<pending_weak, va_gc> *pending_weaks; |
246 | |
247 static GTY(()) VEC(pending_weak,gc) *pending_weaks; | |
248 | 239 |
249 static void apply_pragma_weak (tree, tree); | 240 static void apply_pragma_weak (tree, tree); |
250 static void handle_pragma_weak (cpp_reader *); | 241 static void handle_pragma_weak (cpp_reader *); |
251 | 242 |
252 static void | 243 static void |
261 0); | 252 0); |
262 } | 253 } |
263 | 254 |
264 if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl) | 255 if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl) |
265 && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma. */ | 256 && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma. */ |
257 && DECL_ASSEMBLER_NAME_SET_P (decl) | |
266 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) | 258 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) |
267 warning (OPT_Wpragmas, "applying #pragma weak %q+D after first use " | 259 warning (OPT_Wpragmas, "applying #pragma weak %q+D after first use " |
268 "results in unspecified behavior", decl); | 260 "results in unspecified behavior", decl); |
269 | 261 |
270 declare_weak (decl); | 262 declare_weak (decl); |
278 pending_weak *pe; | 270 pending_weak *pe; |
279 | 271 |
280 /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed. */ | 272 /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed. */ |
281 | 273 |
282 /* No weak symbols pending, take the short-cut. */ | 274 /* No weak symbols pending, take the short-cut. */ |
283 if (!pending_weaks) | 275 if (vec_safe_is_empty (pending_weaks)) |
284 return; | 276 return; |
285 /* If it's not visible outside this file, it doesn't matter whether | 277 /* If it's not visible outside this file, it doesn't matter whether |
286 it's weak. */ | 278 it's weak. */ |
287 if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl)) | 279 if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl)) |
288 return; | 280 return; |
289 /* If it's not a function or a variable, it can't be weak. | 281 /* If it's not a function or a variable, it can't be weak. |
290 FIXME: what kinds of things are visible outside this file but | 282 FIXME: what kinds of things are visible outside this file but |
291 aren't functions or variables? Should this be an assert instead? */ | 283 aren't functions or variables? Should this be an assert instead? */ |
292 if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL) | 284 if (!VAR_OR_FUNCTION_DECL_P (decl)) |
293 return; | 285 return; |
294 | 286 |
295 id = DECL_ASSEMBLER_NAME (decl); | 287 if (DECL_ASSEMBLER_NAME_SET_P (decl)) |
296 | 288 id = DECL_ASSEMBLER_NAME (decl); |
297 FOR_EACH_VEC_ELT (pending_weak, pending_weaks, i, pe) | 289 else |
290 { | |
291 id = DECL_ASSEMBLER_NAME (decl); | |
292 SET_DECL_ASSEMBLER_NAME (decl, NULL_TREE); | |
293 } | |
294 | |
295 FOR_EACH_VEC_ELT (*pending_weaks, i, pe) | |
298 if (id == pe->name) | 296 if (id == pe->name) |
299 { | 297 { |
300 apply_pragma_weak (decl, pe->value); | 298 apply_pragma_weak (decl, pe->value); |
301 VEC_unordered_remove (pending_weak, pending_weaks, i); | 299 pending_weaks->unordered_remove (i); |
302 break; | 300 break; |
303 } | 301 } |
304 } | 302 } |
305 | 303 |
306 /* Process all "#pragma weak A = B" directives where we have not seen | 304 /* Process all "#pragma weak A = B" directives where we have not seen |
309 maybe_apply_pending_pragma_weaks (void) | 307 maybe_apply_pending_pragma_weaks (void) |
310 { | 308 { |
311 tree alias_id, id, decl; | 309 tree alias_id, id, decl; |
312 int i; | 310 int i; |
313 pending_weak *pe; | 311 pending_weak *pe; |
314 | 312 symtab_node *target; |
315 FOR_EACH_VEC_ELT (pending_weak, pending_weaks, i, pe) | 313 |
314 if (vec_safe_is_empty (pending_weaks)) | |
315 return; | |
316 | |
317 FOR_EACH_VEC_ELT (*pending_weaks, i, pe) | |
316 { | 318 { |
317 alias_id = pe->name; | 319 alias_id = pe->name; |
318 id = pe->value; | 320 id = pe->value; |
319 | 321 |
320 if (id == NULL) | 322 if (id == NULL) |
321 continue; | 323 continue; |
322 | 324 |
325 target = symtab_node::get_for_asmname (id); | |
323 decl = build_decl (UNKNOWN_LOCATION, | 326 decl = build_decl (UNKNOWN_LOCATION, |
324 FUNCTION_DECL, alias_id, default_function_type); | 327 target ? TREE_CODE (target->decl) : FUNCTION_DECL, |
328 alias_id, default_function_type); | |
325 | 329 |
326 DECL_ARTIFICIAL (decl) = 1; | 330 DECL_ARTIFICIAL (decl) = 1; |
327 TREE_PUBLIC (decl) = 1; | 331 TREE_PUBLIC (decl) = 1; |
328 DECL_EXTERNAL (decl) = 1; | |
329 DECL_WEAK (decl) = 1; | 332 DECL_WEAK (decl) = 1; |
333 if (VAR_P (decl)) | |
334 TREE_STATIC (decl) = 1; | |
335 if (!target) | |
336 { | |
337 error ("%q+D aliased to undefined symbol %qE", | |
338 decl, id); | |
339 continue; | |
340 } | |
330 | 341 |
331 assemble_alias (decl, id); | 342 assemble_alias (decl, id); |
332 } | 343 } |
333 } | 344 } |
334 | 345 |
354 warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>"); | 365 warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>"); |
355 | 366 |
356 decl = identifier_global_value (name); | 367 decl = identifier_global_value (name); |
357 if (decl && DECL_P (decl)) | 368 if (decl && DECL_P (decl)) |
358 { | 369 { |
370 if (!VAR_OR_FUNCTION_DECL_P (decl)) | |
371 GCC_BAD2 ("%<#pragma weak%> declaration of %q+D not allowed," | |
372 " ignored", decl); | |
359 apply_pragma_weak (decl, value); | 373 apply_pragma_weak (decl, value); |
360 if (value) | 374 if (value) |
361 assemble_alias (decl, value); | 375 { |
376 DECL_EXTERNAL (decl) = 0; | |
377 if (VAR_P (decl)) | |
378 TREE_STATIC (decl) = 1; | |
379 assemble_alias (decl, value); | |
380 } | |
362 } | 381 } |
363 else | 382 else |
364 { | 383 { |
365 pending_weak *pe; | 384 pending_weak pe = {name, value}; |
366 pe = VEC_safe_push (pending_weak, gc, pending_weaks, NULL); | 385 vec_safe_push (pending_weaks, pe); |
367 pe->name = name; | 386 } |
368 pe->value = value; | 387 } |
369 } | 388 |
389 static enum scalar_storage_order_kind global_sso; | |
390 | |
391 void | |
392 maybe_apply_pragma_scalar_storage_order (tree type) | |
393 { | |
394 if (global_sso == SSO_NATIVE) | |
395 return; | |
396 | |
397 gcc_assert (RECORD_OR_UNION_TYPE_P (type)); | |
398 | |
399 if (lookup_attribute ("scalar_storage_order", TYPE_ATTRIBUTES (type))) | |
400 return; | |
401 | |
402 if (global_sso == SSO_BIG_ENDIAN) | |
403 TYPE_REVERSE_STORAGE_ORDER (type) = !BYTES_BIG_ENDIAN; | |
404 else if (global_sso == SSO_LITTLE_ENDIAN) | |
405 TYPE_REVERSE_STORAGE_ORDER (type) = BYTES_BIG_ENDIAN; | |
406 else | |
407 gcc_unreachable (); | |
408 } | |
409 | |
410 static void | |
411 handle_pragma_scalar_storage_order (cpp_reader *ARG_UNUSED(dummy)) | |
412 { | |
413 const char *kind_string; | |
414 enum cpp_ttype token; | |
415 tree x; | |
416 | |
417 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN) | |
418 { | |
419 error ("scalar_storage_order is not supported because endianness " | |
420 "is not uniform"); | |
421 return; | |
422 } | |
423 | |
424 if (c_dialect_cxx ()) | |
425 { | |
426 if (warn_unknown_pragmas > in_system_header_at (input_location)) | |
427 warning (OPT_Wunknown_pragmas, | |
428 "%<#pragma scalar_storage_order%> is not supported for C++"); | |
429 return; | |
430 } | |
431 | |
432 token = pragma_lex (&x); | |
433 if (token != CPP_NAME) | |
434 GCC_BAD ("missing [big-endian|little-endian|default] after %<#pragma scalar_storage_order%>"); | |
435 kind_string = IDENTIFIER_POINTER (x); | |
436 if (strcmp (kind_string, "default") == 0) | |
437 global_sso = default_sso; | |
438 else if (strcmp (kind_string, "big") == 0) | |
439 global_sso = SSO_BIG_ENDIAN; | |
440 else if (strcmp (kind_string, "little") == 0) | |
441 global_sso = SSO_LITTLE_ENDIAN; | |
442 else | |
443 GCC_BAD ("expected [big-endian|little-endian|default] after %<#pragma scalar_storage_order%>"); | |
370 } | 444 } |
371 | 445 |
372 /* GCC supports two #pragma directives for renaming the external | 446 /* GCC supports two #pragma directives for renaming the external |
373 symbol associated with a declaration (DECL_ASSEMBLER_NAME), for | 447 symbol associated with a declaration (DECL_ASSEMBLER_NAME), for |
374 compatibility with the Solaris and Tru64 system headers. GCC also | 448 compatibility with the Solaris and VMS system headers. GCC also |
375 has its own notation for this, __asm__("name") annotations. | 449 has its own notation for this, __asm__("name") annotations. |
376 | 450 |
377 Corner cases of these features and their interaction: | 451 Corner cases of these features and their interaction: |
378 | 452 |
379 1) Both pragmas silently apply only to declarations with external | 453 1) Both pragmas silently apply only to declarations with external |
399 is issued. (We would like to have #pragma redefine_extname always | 473 is issued. (We would like to have #pragma redefine_extname always |
400 win, but it can appear either before or after the declaration, and | 474 win, but it can appear either before or after the declaration, and |
401 if it appears afterward, we have no way of knowing whether a modified | 475 if it appears afterward, we have no way of knowing whether a modified |
402 DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.) */ | 476 DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.) */ |
403 | 477 |
404 typedef struct GTY(()) pending_redefinition_d { | 478 struct GTY(()) pending_redefinition { |
405 tree oldname; | 479 tree oldname; |
406 tree newname; | 480 tree newname; |
407 } pending_redefinition; | 481 }; |
408 | 482 |
409 DEF_VEC_O(pending_redefinition); | 483 |
410 DEF_VEC_ALLOC_O(pending_redefinition,gc); | 484 static GTY(()) vec<pending_redefinition, va_gc> *pending_redefine_extname; |
411 | |
412 static GTY(()) VEC(pending_redefinition,gc) *pending_redefine_extname; | |
413 | 485 |
414 static void handle_pragma_redefine_extname (cpp_reader *); | 486 static void handle_pragma_redefine_extname (cpp_reader *); |
415 | 487 |
416 /* #pragma redefine_extname oldname newname */ | 488 /* #pragma redefine_extname oldname newname */ |
417 static void | 489 static void |
418 handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy)) | 490 handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy)) |
419 { | 491 { |
420 tree oldname, newname, decl, x; | 492 tree oldname, newname, decls, x; |
421 enum cpp_ttype t; | 493 enum cpp_ttype t; |
494 bool found; | |
422 | 495 |
423 if (pragma_lex (&oldname) != CPP_NAME) | 496 if (pragma_lex (&oldname) != CPP_NAME) |
424 GCC_BAD ("malformed #pragma redefine_extname, ignored"); | 497 GCC_BAD ("malformed #pragma redefine_extname, ignored"); |
425 if (pragma_lex (&newname) != CPP_NAME) | 498 if (pragma_lex (&newname) != CPP_NAME) |
426 GCC_BAD ("malformed #pragma redefine_extname, ignored"); | 499 GCC_BAD ("malformed #pragma redefine_extname, ignored"); |
427 t = pragma_lex (&x); | 500 t = pragma_lex (&x); |
428 if (t != CPP_EOF) | 501 if (t != CPP_EOF) |
429 warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>"); | 502 warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>"); |
430 | 503 |
431 decl = identifier_global_value (oldname); | 504 found = false; |
432 if (decl | 505 for (decls = c_linkage_bindings (oldname); |
433 && (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)) | 506 decls; ) |
434 && (TREE_CODE (decl) == FUNCTION_DECL | 507 { |
435 || TREE_CODE (decl) == VAR_DECL) | 508 tree decl; |
436 && has_c_linkage (decl)) | 509 if (TREE_CODE (decls) == TREE_LIST) |
437 { | |
438 if (DECL_ASSEMBLER_NAME_SET_P (decl)) | |
439 { | 510 { |
440 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); | 511 decl = TREE_VALUE (decls); |
441 name = targetm.strip_name_encoding (name); | 512 decls = TREE_CHAIN (decls); |
442 | |
443 if (strcmp (name, IDENTIFIER_POINTER (newname))) | |
444 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " | |
445 "conflict with previous rename"); | |
446 } | 513 } |
447 else | 514 else |
448 change_decl_assembler_name (decl, newname); | 515 { |
449 } | 516 decl = decls; |
450 else | 517 decls = NULL_TREE; |
518 } | |
519 | |
520 if ((TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)) | |
521 && VAR_OR_FUNCTION_DECL_P (decl)) | |
522 { | |
523 found = true; | |
524 if (DECL_ASSEMBLER_NAME_SET_P (decl)) | |
525 { | |
526 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); | |
527 name = targetm.strip_name_encoding (name); | |
528 | |
529 if (!id_equal (newname, name)) | |
530 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " | |
531 "conflict with previous rename"); | |
532 } | |
533 else | |
534 symtab->change_decl_assembler_name (decl, newname); | |
535 } | |
536 } | |
537 | |
538 if (!found) | |
451 /* We have to add this to the rename list even if there's already | 539 /* We have to add this to the rename list even if there's already |
452 a global value that doesn't meet the above criteria, because in | 540 a global value that doesn't meet the above criteria, because in |
453 C++ "struct foo {...};" puts "foo" in the current namespace but | 541 C++ "struct foo {...};" puts "foo" in the current namespace but |
454 does *not* conflict with a subsequent declaration of a function | 542 does *not* conflict with a subsequent declaration of a function |
455 or variable foo. See g++.dg/other/pragma-re-2.C. */ | 543 or variable foo. See g++.dg/other/pragma-re-2.C. */ |
456 add_to_renaming_pragma_list (oldname, newname); | 544 add_to_renaming_pragma_list (oldname, newname); |
457 } | 545 } |
458 | 546 |
459 /* This is called from here and from ia64.c. */ | 547 /* This is called from here and from ia64-c.c. */ |
460 void | 548 void |
461 add_to_renaming_pragma_list (tree oldname, tree newname) | 549 add_to_renaming_pragma_list (tree oldname, tree newname) |
462 { | 550 { |
463 unsigned ix; | 551 unsigned ix; |
464 pending_redefinition *p; | 552 pending_redefinition *p; |
465 | 553 |
466 FOR_EACH_VEC_ELT (pending_redefinition, pending_redefine_extname, ix, p) | 554 FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p) |
467 if (oldname == p->oldname) | 555 if (oldname == p->oldname) |
468 { | 556 { |
469 if (p->newname != newname) | 557 if (p->newname != newname) |
470 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " | 558 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " |
471 "conflict with previous #pragma redefine_extname"); | 559 "conflict with previous #pragma redefine_extname"); |
472 return; | 560 return; |
473 } | 561 } |
474 | 562 |
475 p = VEC_safe_push (pending_redefinition, gc, pending_redefine_extname, NULL); | 563 pending_redefinition e = {oldname, newname}; |
476 p->oldname = oldname; | 564 vec_safe_push (pending_redefine_extname, e); |
477 p->newname = newname; | 565 } |
478 } | 566 |
479 | 567 /* The current prefix set by #pragma extern_prefix. */ |
480 static GTY(()) tree pragma_extern_prefix; | 568 GTY(()) tree pragma_extern_prefix; |
481 | |
482 /* #pragma extern_prefix "prefix" */ | |
483 static void | |
484 handle_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy)) | |
485 { | |
486 tree prefix, x; | |
487 enum cpp_ttype t; | |
488 | |
489 if (pragma_lex (&prefix) != CPP_STRING) | |
490 GCC_BAD ("malformed #pragma extern_prefix, ignored"); | |
491 t = pragma_lex (&x); | |
492 if (t != CPP_EOF) | |
493 warning (OPT_Wpragmas, "junk at end of %<#pragma extern_prefix%>"); | |
494 | |
495 if (targetm.handle_pragma_extern_prefix) | |
496 /* Note that the length includes the null terminator. */ | |
497 pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL); | |
498 else if (warn_unknown_pragmas > in_system_header) | |
499 warning (OPT_Wunknown_pragmas, | |
500 "#pragma extern_prefix not supported on this target"); | |
501 } | |
502 | 569 |
503 /* Hook from the front ends to apply the results of one of the preceding | 570 /* Hook from the front ends to apply the results of one of the preceding |
504 pragmas that rename variables. */ | 571 pragmas that rename variables. */ |
505 | 572 |
506 tree | 573 tree |
509 unsigned ix; | 576 unsigned ix; |
510 pending_redefinition *p; | 577 pending_redefinition *p; |
511 | 578 |
512 /* The renaming pragmas are only applied to declarations with | 579 /* The renaming pragmas are only applied to declarations with |
513 external linkage. */ | 580 external linkage. */ |
514 if ((TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL) | 581 if (!VAR_OR_FUNCTION_DECL_P (decl) |
515 || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) | 582 || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) |
516 || !has_c_linkage (decl)) | 583 || !has_c_linkage (decl)) |
517 return asmname; | 584 return asmname; |
518 | 585 |
519 /* If the DECL_ASSEMBLER_NAME is already set, it does not change, | 586 /* If the DECL_ASSEMBLER_NAME is already set, it does not change, |
526 if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname)) | 593 if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname)) |
527 warning (OPT_Wpragmas, "asm declaration ignored due to " | 594 warning (OPT_Wpragmas, "asm declaration ignored due to " |
528 "conflict with previous rename"); | 595 "conflict with previous rename"); |
529 | 596 |
530 /* Take any pending redefine_extname off the list. */ | 597 /* Take any pending redefine_extname off the list. */ |
531 FOR_EACH_VEC_ELT (pending_redefinition, pending_redefine_extname, ix, p) | 598 FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p) |
532 if (DECL_NAME (decl) == p->oldname) | 599 if (DECL_NAME (decl) == p->oldname) |
533 { | 600 { |
534 /* Only warn if there is a conflict. */ | 601 /* Only warn if there is a conflict. */ |
535 if (strcmp (IDENTIFIER_POINTER (p->newname), oldname)) | 602 if (!id_equal (p->newname, oldname)) |
536 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " | 603 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " |
537 "conflict with previous rename"); | 604 "conflict with previous rename"); |
538 | 605 |
539 VEC_unordered_remove (pending_redefinition, | 606 pending_redefine_extname->unordered_remove (ix); |
540 pending_redefine_extname, ix); | |
541 break; | 607 break; |
542 } | 608 } |
543 return 0; | 609 return NULL_TREE; |
544 } | 610 } |
545 | 611 |
546 /* Find out if we have a pending #pragma redefine_extname. */ | 612 /* Find out if we have a pending #pragma redefine_extname. */ |
547 FOR_EACH_VEC_ELT (pending_redefinition, pending_redefine_extname, ix, p) | 613 FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p) |
548 if (DECL_NAME (decl) == p->oldname) | 614 if (DECL_NAME (decl) == p->oldname) |
549 { | 615 { |
550 tree newname = p->newname; | 616 tree newname = p->newname; |
551 VEC_unordered_remove (pending_redefinition, | 617 pending_redefine_extname->unordered_remove (ix); |
552 pending_redefine_extname, ix); | |
553 | 618 |
554 /* If we already have an asmname, #pragma redefine_extname is | 619 /* If we already have an asmname, #pragma redefine_extname is |
555 ignored (with a warning if it conflicts). */ | 620 ignored (with a warning if it conflicts). */ |
556 if (asmname) | 621 if (asmname) |
557 { | 622 { |
588 | 653 |
589 return build_string (plen + ilen, newname); | 654 return build_string (plen + ilen, newname); |
590 } | 655 } |
591 | 656 |
592 /* Nada. */ | 657 /* Nada. */ |
593 return 0; | 658 return NULL_TREE; |
594 } | 659 } |
595 | 660 |
596 | 661 |
597 static void handle_pragma_visibility (cpp_reader *); | 662 static void handle_pragma_visibility (cpp_reader *); |
598 | 663 |
599 static VEC (int, heap) *visstack; | 664 static vec<int> visstack; |
600 | 665 |
601 /* Push the visibility indicated by STR onto the top of the #pragma | 666 /* Push the visibility indicated by STR onto the top of the #pragma |
602 visibility stack. KIND is 0 for #pragma GCC visibility, 1 for | 667 visibility stack. KIND is 0 for #pragma GCC visibility, 1 for |
603 C++ namespace with visibility attribute and 2 for C++ builtin | 668 C++ namespace with visibility attribute and 2 for C++ builtin |
604 ABI namespace. push_visibility/pop_visibility calls must have | 669 ABI namespace. push_visibility/pop_visibility calls must have |
606 KIND and pop using a different one. */ | 671 KIND and pop using a different one. */ |
607 | 672 |
608 void | 673 void |
609 push_visibility (const char *str, int kind) | 674 push_visibility (const char *str, int kind) |
610 { | 675 { |
611 VEC_safe_push (int, heap, visstack, | 676 visstack.safe_push (((int) default_visibility) | (kind << 8)); |
612 ((int) default_visibility) | (kind << 8)); | |
613 if (!strcmp (str, "default")) | 677 if (!strcmp (str, "default")) |
614 default_visibility = VISIBILITY_DEFAULT; | 678 default_visibility = VISIBILITY_DEFAULT; |
615 else if (!strcmp (str, "internal")) | 679 else if (!strcmp (str, "internal")) |
616 default_visibility = VISIBILITY_INTERNAL; | 680 default_visibility = VISIBILITY_INTERNAL; |
617 else if (!strcmp (str, "hidden")) | 681 else if (!strcmp (str, "hidden")) |
627 successful. */ | 691 successful. */ |
628 | 692 |
629 bool | 693 bool |
630 pop_visibility (int kind) | 694 pop_visibility (int kind) |
631 { | 695 { |
632 if (!VEC_length (int, visstack)) | 696 if (!visstack.length ()) |
633 return false; | 697 return false; |
634 if ((VEC_last (int, visstack) >> 8) != kind) | 698 if ((visstack.last () >> 8) != kind) |
635 return false; | 699 return false; |
636 default_visibility | 700 default_visibility |
637 = (enum symbol_visibility) (VEC_pop (int, visstack) & 0xff); | 701 = (enum symbol_visibility) (visstack.pop () & 0xff); |
638 visibility_options.inpragma | 702 visibility_options.inpragma |
639 = VEC_length (int, visstack) != 0; | 703 = visstack.length () != 0; |
640 return true; | 704 return true; |
641 } | 705 } |
642 | 706 |
643 /* Sets the default visibility for symbols to something other than that | 707 /* Sets the default visibility for symbols to something other than that |
644 specified on the command line. */ | 708 specified on the command line. */ |
687 } | 751 } |
688 | 752 |
689 static void | 753 static void |
690 handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy)) | 754 handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy)) |
691 { | 755 { |
692 const char *kind_string, *option_string; | 756 tree x; |
693 unsigned int option_index; | 757 location_t loc; |
694 enum cpp_ttype token; | 758 enum cpp_ttype token = pragma_lex (&x, &loc); |
759 if (token != CPP_NAME) | |
760 { | |
761 warning_at (loc, OPT_Wpragmas, | |
762 "missing [error|warning|ignored|push|pop]" | |
763 " after %<#pragma GCC diagnostic%>"); | |
764 return; | |
765 } | |
766 | |
695 diagnostic_t kind; | 767 diagnostic_t kind; |
696 tree x; | 768 const char *kind_string = IDENTIFIER_POINTER (x); |
697 struct cl_option_handlers handlers; | |
698 | |
699 token = pragma_lex (&x); | |
700 if (token != CPP_NAME) | |
701 GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>"); | |
702 kind_string = IDENTIFIER_POINTER (x); | |
703 if (strcmp (kind_string, "error") == 0) | 769 if (strcmp (kind_string, "error") == 0) |
704 kind = DK_ERROR; | 770 kind = DK_ERROR; |
705 else if (strcmp (kind_string, "warning") == 0) | 771 else if (strcmp (kind_string, "warning") == 0) |
706 kind = DK_WARNING; | 772 kind = DK_WARNING; |
707 else if (strcmp (kind_string, "ignored") == 0) | 773 else if (strcmp (kind_string, "ignored") == 0) |
715 { | 781 { |
716 diagnostic_pop_diagnostics (global_dc, input_location); | 782 diagnostic_pop_diagnostics (global_dc, input_location); |
717 return; | 783 return; |
718 } | 784 } |
719 else | 785 else |
720 GCC_BAD ("expected [error|warning|ignored|push|pop] after %<#pragma GCC diagnostic%>"); | 786 { |
721 | 787 warning_at (loc, OPT_Wpragmas, |
722 token = pragma_lex (&x); | 788 "expected [error|warning|ignored|push|pop]" |
789 " after %<#pragma GCC diagnostic%>"); | |
790 return; | |
791 } | |
792 | |
793 token = pragma_lex (&x, &loc); | |
723 if (token != CPP_STRING) | 794 if (token != CPP_STRING) |
724 GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind"); | 795 { |
725 option_string = TREE_STRING_POINTER (x); | 796 warning_at (loc, OPT_Wpragmas, |
726 set_default_handlers (&handlers); | 797 "missing option after %<#pragma GCC diagnostic%> kind"); |
727 for (option_index = 0; option_index < cl_options_count; option_index++) | 798 return; |
728 if (strcmp (cl_options[option_index].opt_text, option_string) == 0) | 799 } |
729 { | 800 |
730 control_warning_option (option_index, (int) kind, kind != DK_IGNORED, | 801 const char *option_string = TREE_STRING_POINTER (x); |
731 input_location, c_family_lang_mask, &handlers, | 802 unsigned int lang_mask = c_common_option_lang_mask () | CL_COMMON; |
732 &global_options, &global_options_set, | 803 /* option_string + 1 to skip the initial '-' */ |
733 global_dc); | 804 unsigned int option_index = find_opt (option_string + 1, lang_mask); |
734 return; | 805 if (option_index == OPT_SPECIAL_unknown) |
735 } | 806 { |
736 GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind"); | 807 warning_at (loc, OPT_Wpragmas, |
808 "unknown option after %<#pragma GCC diagnostic%> kind"); | |
809 return; | |
810 } | |
811 else if (!(cl_options[option_index].flags & CL_WARNING)) | |
812 { | |
813 warning_at (loc, OPT_Wpragmas, | |
814 "%qs is not an option that controls warnings", option_string); | |
815 return; | |
816 } | |
817 else if (!(cl_options[option_index].flags & lang_mask)) | |
818 { | |
819 char *ok_langs = write_langs (cl_options[option_index].flags); | |
820 char *bad_lang = write_langs (c_common_option_lang_mask ()); | |
821 warning_at (loc, OPT_Wpragmas, | |
822 "option %qs is valid for %s but not for %s", | |
823 option_string, ok_langs, bad_lang); | |
824 free (ok_langs); | |
825 free (bad_lang); | |
826 return; | |
827 } | |
828 | |
829 struct cl_option_handlers handlers; | |
830 set_default_handlers (&handlers, NULL); | |
831 const char *arg = NULL; | |
832 if (cl_options[option_index].flags & CL_JOINED) | |
833 arg = option_string + 1 + cl_options[option_index].opt_len; | |
834 /* FIXME: input_location isn't the best location here, but it is | |
835 what we used to do here before and changing it breaks e.g. | |
836 PR69543 and PR69558. */ | |
837 control_warning_option (option_index, (int) kind, | |
838 arg, kind != DK_IGNORED, | |
839 input_location, lang_mask, &handlers, | |
840 &global_options, &global_options_set, | |
841 global_dc); | |
737 } | 842 } |
738 | 843 |
739 /* Parse #pragma GCC target (xxx) to set target specific options. */ | 844 /* Parse #pragma GCC target (xxx) to set target specific options. */ |
740 static void | 845 static void |
741 handle_pragma_target(cpp_reader *ARG_UNUSED(dummy)) | 846 handle_pragma_target(cpp_reader *ARG_UNUSED(dummy)) |
798 | 903 |
799 /* put arguments in the order the user typed them. */ | 904 /* put arguments in the order the user typed them. */ |
800 args = nreverse (args); | 905 args = nreverse (args); |
801 | 906 |
802 if (targetm.target_option.pragma_parse (args, NULL_TREE)) | 907 if (targetm.target_option.pragma_parse (args, NULL_TREE)) |
803 current_target_pragma = args; | 908 current_target_pragma = chainon (current_target_pragma, args); |
804 } | 909 } |
805 } | 910 } |
806 | 911 |
807 /* Handle #pragma GCC optimize to set optimization options. */ | 912 /* Handle #pragma GCC optimize to set optimization options. */ |
808 static void | 913 static void |
867 /* put arguments in the order the user typed them. */ | 972 /* put arguments in the order the user typed them. */ |
868 args = nreverse (args); | 973 args = nreverse (args); |
869 | 974 |
870 parse_optimize_options (args, false); | 975 parse_optimize_options (args, false); |
871 current_optimize_pragma = chainon (current_optimize_pragma, args); | 976 current_optimize_pragma = chainon (current_optimize_pragma, args); |
872 optimization_current_node = build_optimization_node (); | 977 optimization_current_node = build_optimization_node (&global_options); |
873 c_cpp_builtins_optimize_pragma (parse_in, | 978 c_cpp_builtins_optimize_pragma (parse_in, |
874 optimization_previous_node, | 979 optimization_previous_node, |
875 optimization_current_node); | 980 optimization_current_node); |
876 } | 981 } |
877 } | 982 } |
878 | 983 |
879 /* Stack of the #pragma GCC options created with #pragma GCC push_option. Save | 984 /* Stack of the #pragma GCC options created with #pragma GCC push_option. Save |
880 both the binary representation of the options and the TREE_LIST of | 985 both the binary representation of the options and the TREE_LIST of |
881 strings that will be added to the function's attribute list. */ | 986 strings that will be added to the function's attribute list. */ |
882 typedef struct GTY(()) opt_stack { | 987 struct GTY(()) opt_stack { |
883 struct opt_stack *prev; | 988 struct opt_stack *prev; |
884 tree target_binary; | 989 tree target_binary; |
885 tree target_strings; | 990 tree target_strings; |
886 tree optimize_binary; | 991 tree optimize_binary; |
887 tree optimize_strings; | 992 tree optimize_strings; |
888 } opt_stack; | 993 }; |
889 | 994 |
890 static GTY(()) struct opt_stack * options_stack; | 995 static GTY(()) struct opt_stack * options_stack; |
891 | 996 |
892 /* Handle #pragma GCC push_options to save the current target and optimization | 997 /* Handle #pragma GCC push_options to save the current target and optimization |
893 options. */ | 998 options. */ |
895 static void | 1000 static void |
896 handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy)) | 1001 handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy)) |
897 { | 1002 { |
898 enum cpp_ttype token; | 1003 enum cpp_ttype token; |
899 tree x = 0; | 1004 tree x = 0; |
900 opt_stack *p; | |
901 | 1005 |
902 token = pragma_lex (&x); | 1006 token = pragma_lex (&x); |
903 if (token != CPP_EOF) | 1007 if (token != CPP_EOF) |
904 { | 1008 { |
905 warning (OPT_Wpragmas, "junk at end of %<#pragma push_options%>"); | 1009 warning (OPT_Wpragmas, "junk at end of %<#pragma push_options%>"); |
906 return; | 1010 return; |
907 } | 1011 } |
908 | 1012 |
909 p = ggc_alloc_opt_stack (); | 1013 opt_stack *p = ggc_alloc<opt_stack> (); |
910 p->prev = options_stack; | 1014 p->prev = options_stack; |
911 options_stack = p; | 1015 options_stack = p; |
912 | 1016 |
913 /* Save optimization and target flags in binary format. */ | 1017 /* Save optimization and target flags in binary format. */ |
914 p->optimize_binary = build_optimization_node (); | 1018 p->optimize_binary = build_optimization_node (&global_options); |
915 p->target_binary = build_target_option_node (); | 1019 p->target_binary = build_target_option_node (&global_options); |
916 | 1020 |
917 /* Save optimization and target flags in string list format. */ | 1021 /* Save optimization and target flags in string list format. */ |
918 p->optimize_strings = copy_list (current_optimize_pragma); | 1022 p->optimize_strings = copy_list (current_optimize_pragma); |
919 p->target_strings = copy_list (current_target_pragma); | 1023 p->target_strings = copy_list (current_target_pragma); |
920 } | 1024 } |
1112 static void | 1216 static void |
1113 handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy)) | 1217 handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy)) |
1114 { | 1218 { |
1115 if (c_dialect_cxx ()) | 1219 if (c_dialect_cxx ()) |
1116 { | 1220 { |
1117 if (warn_unknown_pragmas > in_system_header) | 1221 if (warn_unknown_pragmas > in_system_header_at (input_location)) |
1118 warning (OPT_Wunknown_pragmas, | 1222 warning (OPT_Wunknown_pragmas, |
1119 "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported" | 1223 "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported" |
1120 " for C++"); | 1224 " for C++"); |
1121 return; | 1225 return; |
1122 } | 1226 } |
1123 | 1227 |
1124 if (!targetm.decimal_float_supported_p ()) | 1228 if (!targetm.decimal_float_supported_p ()) |
1125 { | 1229 { |
1126 if (warn_unknown_pragmas > in_system_header) | 1230 if (warn_unknown_pragmas > in_system_header_at (input_location)) |
1127 warning (OPT_Wunknown_pragmas, | 1231 warning (OPT_Wunknown_pragmas, |
1128 "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported" | 1232 "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported" |
1129 " on this target"); | 1233 " on this target"); |
1130 return; | 1234 return; |
1131 } | 1235 } |
1132 | 1236 |
1133 pedwarn (input_location, OPT_pedantic, | 1237 pedwarn (input_location, OPT_Wpedantic, |
1134 "ISO C does not support %<#pragma STDC FLOAT_CONST_DECIMAL64%>"); | 1238 "ISO C does not support %<#pragma STDC FLOAT_CONST_DECIMAL64%>"); |
1135 | 1239 |
1136 switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64")) | 1240 switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64")) |
1137 { | 1241 { |
1138 case PRAGMA_ON: | 1242 case PRAGMA_ON: |
1145 case PRAGMA_BAD: | 1249 case PRAGMA_BAD: |
1146 break; | 1250 break; |
1147 } | 1251 } |
1148 } | 1252 } |
1149 | 1253 |
1150 /* A vector of registered pragma callbacks. */ | 1254 /* A vector of registered pragma callbacks, which is never freed. */ |
1151 | 1255 |
1152 DEF_VEC_O (pragma_handler); | 1256 static vec<internal_pragma_handler> registered_pragmas; |
1153 DEF_VEC_ALLOC_O (pragma_handler, heap); | 1257 |
1154 | 1258 struct pragma_ns_name |
1155 static VEC(pragma_handler, heap) *registered_pragmas; | |
1156 | |
1157 typedef struct | |
1158 { | 1259 { |
1159 const char *space; | 1260 const char *space; |
1160 const char *name; | 1261 const char *name; |
1161 } pragma_ns_name; | 1262 }; |
1162 | 1263 |
1163 DEF_VEC_O (pragma_ns_name); | 1264 |
1164 DEF_VEC_ALLOC_O (pragma_ns_name, heap); | 1265 static vec<pragma_ns_name> registered_pp_pragmas; |
1165 | |
1166 static VEC(pragma_ns_name, heap) *registered_pp_pragmas; | |
1167 | 1266 |
1168 struct omp_pragma_def { const char *name; unsigned int id; }; | 1267 struct omp_pragma_def { const char *name; unsigned int id; }; |
1268 static const struct omp_pragma_def oacc_pragmas[] = { | |
1269 { "atomic", PRAGMA_OACC_ATOMIC }, | |
1270 { "cache", PRAGMA_OACC_CACHE }, | |
1271 { "data", PRAGMA_OACC_DATA }, | |
1272 { "declare", PRAGMA_OACC_DECLARE }, | |
1273 { "enter", PRAGMA_OACC_ENTER_DATA }, | |
1274 { "exit", PRAGMA_OACC_EXIT_DATA }, | |
1275 { "host_data", PRAGMA_OACC_HOST_DATA }, | |
1276 { "kernels", PRAGMA_OACC_KERNELS }, | |
1277 { "loop", PRAGMA_OACC_LOOP }, | |
1278 { "parallel", PRAGMA_OACC_PARALLEL }, | |
1279 { "routine", PRAGMA_OACC_ROUTINE }, | |
1280 { "update", PRAGMA_OACC_UPDATE }, | |
1281 { "wait", PRAGMA_OACC_WAIT } | |
1282 }; | |
1169 static const struct omp_pragma_def omp_pragmas[] = { | 1283 static const struct omp_pragma_def omp_pragmas[] = { |
1170 { "atomic", PRAGMA_OMP_ATOMIC }, | 1284 { "atomic", PRAGMA_OMP_ATOMIC }, |
1171 { "barrier", PRAGMA_OMP_BARRIER }, | 1285 { "barrier", PRAGMA_OMP_BARRIER }, |
1286 { "cancel", PRAGMA_OMP_CANCEL }, | |
1287 { "cancellation", PRAGMA_OMP_CANCELLATION_POINT }, | |
1172 { "critical", PRAGMA_OMP_CRITICAL }, | 1288 { "critical", PRAGMA_OMP_CRITICAL }, |
1289 { "end", PRAGMA_OMP_END_DECLARE_TARGET }, | |
1173 { "flush", PRAGMA_OMP_FLUSH }, | 1290 { "flush", PRAGMA_OMP_FLUSH }, |
1174 { "for", PRAGMA_OMP_FOR }, | |
1175 { "master", PRAGMA_OMP_MASTER }, | 1291 { "master", PRAGMA_OMP_MASTER }, |
1176 { "ordered", PRAGMA_OMP_ORDERED }, | |
1177 { "parallel", PRAGMA_OMP_PARALLEL }, | |
1178 { "section", PRAGMA_OMP_SECTION }, | 1292 { "section", PRAGMA_OMP_SECTION }, |
1179 { "sections", PRAGMA_OMP_SECTIONS }, | 1293 { "sections", PRAGMA_OMP_SECTIONS }, |
1180 { "single", PRAGMA_OMP_SINGLE }, | 1294 { "single", PRAGMA_OMP_SINGLE }, |
1181 { "task", PRAGMA_OMP_TASK }, | 1295 { "task", PRAGMA_OMP_TASK }, |
1296 { "taskgroup", PRAGMA_OMP_TASKGROUP }, | |
1182 { "taskwait", PRAGMA_OMP_TASKWAIT }, | 1297 { "taskwait", PRAGMA_OMP_TASKWAIT }, |
1298 { "taskyield", PRAGMA_OMP_TASKYIELD }, | |
1183 { "threadprivate", PRAGMA_OMP_THREADPRIVATE } | 1299 { "threadprivate", PRAGMA_OMP_THREADPRIVATE } |
1184 }; | 1300 }; |
1301 static const struct omp_pragma_def omp_pragmas_simd[] = { | |
1302 { "declare", PRAGMA_OMP_DECLARE }, | |
1303 { "distribute", PRAGMA_OMP_DISTRIBUTE }, | |
1304 { "for", PRAGMA_OMP_FOR }, | |
1305 { "ordered", PRAGMA_OMP_ORDERED }, | |
1306 { "parallel", PRAGMA_OMP_PARALLEL }, | |
1307 { "simd", PRAGMA_OMP_SIMD }, | |
1308 { "target", PRAGMA_OMP_TARGET }, | |
1309 { "taskloop", PRAGMA_OMP_TASKLOOP }, | |
1310 { "teams", PRAGMA_OMP_TEAMS }, | |
1311 }; | |
1185 | 1312 |
1186 void | 1313 void |
1187 c_pp_lookup_pragma (unsigned int id, const char **space, const char **name) | 1314 c_pp_lookup_pragma (unsigned int id, const char **space, const char **name) |
1188 { | 1315 { |
1316 const int n_oacc_pragmas = sizeof (oacc_pragmas) / sizeof (*oacc_pragmas); | |
1189 const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas); | 1317 const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas); |
1318 const int n_omp_pragmas_simd = sizeof (omp_pragmas_simd) | |
1319 / sizeof (*omp_pragmas); | |
1190 int i; | 1320 int i; |
1321 | |
1322 for (i = 0; i < n_oacc_pragmas; ++i) | |
1323 if (oacc_pragmas[i].id == id) | |
1324 { | |
1325 *space = "acc"; | |
1326 *name = oacc_pragmas[i].name; | |
1327 return; | |
1328 } | |
1191 | 1329 |
1192 for (i = 0; i < n_omp_pragmas; ++i) | 1330 for (i = 0; i < n_omp_pragmas; ++i) |
1193 if (omp_pragmas[i].id == id) | 1331 if (omp_pragmas[i].id == id) |
1194 { | 1332 { |
1195 *space = "omp"; | 1333 *space = "omp"; |
1196 *name = omp_pragmas[i].name; | 1334 *name = omp_pragmas[i].name; |
1197 return; | 1335 return; |
1198 } | 1336 } |
1199 | 1337 |
1338 for (i = 0; i < n_omp_pragmas_simd; ++i) | |
1339 if (omp_pragmas_simd[i].id == id) | |
1340 { | |
1341 *space = "omp"; | |
1342 *name = omp_pragmas_simd[i].name; | |
1343 return; | |
1344 } | |
1345 | |
1346 if (id == PRAGMA_CILK_SIMD) | |
1347 { | |
1348 *space = NULL; | |
1349 *name = "simd"; | |
1350 return; | |
1351 } | |
1352 | |
1353 if (id == PRAGMA_CILK_GRAINSIZE) | |
1354 { | |
1355 *space = "cilk"; | |
1356 *name = "grainsize"; | |
1357 return; | |
1358 } | |
1359 | |
1200 if (id >= PRAGMA_FIRST_EXTERNAL | 1360 if (id >= PRAGMA_FIRST_EXTERNAL |
1201 && (id < PRAGMA_FIRST_EXTERNAL | 1361 && (id < PRAGMA_FIRST_EXTERNAL + registered_pp_pragmas.length ())) |
1202 + VEC_length (pragma_ns_name, registered_pp_pragmas))) | 1362 { |
1203 { | 1363 *space = registered_pp_pragmas[id - PRAGMA_FIRST_EXTERNAL].space; |
1204 *space = VEC_index (pragma_ns_name, registered_pp_pragmas, | 1364 *name = registered_pp_pragmas[id - PRAGMA_FIRST_EXTERNAL].name; |
1205 id - PRAGMA_FIRST_EXTERNAL)->space; | |
1206 *name = VEC_index (pragma_ns_name, registered_pp_pragmas, | |
1207 id - PRAGMA_FIRST_EXTERNAL)->name; | |
1208 return; | 1365 return; |
1209 } | 1366 } |
1210 | 1367 |
1211 gcc_unreachable (); | 1368 gcc_unreachable (); |
1212 } | 1369 } |
1214 /* Front-end wrappers for pragma registration to avoid dragging | 1371 /* Front-end wrappers for pragma registration to avoid dragging |
1215 cpplib.h in almost everywhere. */ | 1372 cpplib.h in almost everywhere. */ |
1216 | 1373 |
1217 static void | 1374 static void |
1218 c_register_pragma_1 (const char *space, const char *name, | 1375 c_register_pragma_1 (const char *space, const char *name, |
1219 pragma_handler handler, bool allow_expansion) | 1376 internal_pragma_handler ihandler, bool allow_expansion) |
1220 { | 1377 { |
1221 unsigned id; | 1378 unsigned id; |
1222 | 1379 |
1223 if (flag_preprocess_only) | 1380 if (flag_preprocess_only) |
1224 { | 1381 { |
1227 if (!allow_expansion) | 1384 if (!allow_expansion) |
1228 return; | 1385 return; |
1229 | 1386 |
1230 ns_name.space = space; | 1387 ns_name.space = space; |
1231 ns_name.name = name; | 1388 ns_name.name = name; |
1232 VEC_safe_push (pragma_ns_name, heap, registered_pp_pragmas, &ns_name); | 1389 registered_pp_pragmas.safe_push (ns_name); |
1233 id = VEC_length (pragma_ns_name, registered_pp_pragmas); | 1390 id = registered_pp_pragmas.length (); |
1234 id += PRAGMA_FIRST_EXTERNAL - 1; | 1391 id += PRAGMA_FIRST_EXTERNAL - 1; |
1235 } | 1392 } |
1236 else | 1393 else |
1237 { | 1394 { |
1238 VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); | 1395 registered_pragmas.safe_push (ihandler); |
1239 id = VEC_length (pragma_handler, registered_pragmas); | 1396 id = registered_pragmas.length (); |
1240 id += PRAGMA_FIRST_EXTERNAL - 1; | 1397 id += PRAGMA_FIRST_EXTERNAL - 1; |
1241 | 1398 |
1242 /* The C++ front end allocates 6 bits in cp_token; the C front end | 1399 /* The C front end allocates 8 bits in c_token. The C++ front end |
1243 allocates 7 bits in c_token. At present this is sufficient. */ | 1400 keeps the pragma kind in the form of INTEGER_CST, so no small |
1244 gcc_assert (id < 64); | 1401 limit applies. At present this is sufficient. */ |
1402 gcc_assert (id < 256); | |
1245 } | 1403 } |
1246 | 1404 |
1247 cpp_register_deferred_pragma (parse_in, space, name, id, | 1405 cpp_register_deferred_pragma (parse_in, space, name, id, |
1248 allow_expansion, false); | 1406 allow_expansion, false); |
1249 } | 1407 } |
1250 | 1408 |
1409 /* Register a C pragma handler, using a space and a name. It disallows pragma | |
1410 expansion (if you want it, use c_register_pragma_with_expansion instead). */ | |
1251 void | 1411 void |
1252 c_register_pragma (const char *space, const char *name, pragma_handler handler) | 1412 c_register_pragma (const char *space, const char *name, |
1253 { | 1413 pragma_handler_1arg handler) |
1254 c_register_pragma_1 (space, name, handler, false); | 1414 { |
1255 } | 1415 internal_pragma_handler ihandler; |
1256 | 1416 |
1417 ihandler.handler.handler_1arg = handler; | |
1418 ihandler.extra_data = false; | |
1419 ihandler.data = NULL; | |
1420 c_register_pragma_1 (space, name, ihandler, false); | |
1421 } | |
1422 | |
1423 /* Register a C pragma handler, using a space and a name, it also carries an | |
1424 extra data field which can be used by the handler. It disallows pragma | |
1425 expansion (if you want it, use c_register_pragma_with_expansion_and_data | |
1426 instead). */ | |
1427 void | |
1428 c_register_pragma_with_data (const char *space, const char *name, | |
1429 pragma_handler_2arg handler, void * data) | |
1430 { | |
1431 internal_pragma_handler ihandler; | |
1432 | |
1433 ihandler.handler.handler_2arg = handler; | |
1434 ihandler.extra_data = true; | |
1435 ihandler.data = data; | |
1436 c_register_pragma_1 (space, name, ihandler, false); | |
1437 } | |
1438 | |
1439 /* Register a C pragma handler, using a space and a name. It allows pragma | |
1440 expansion as in the following example: | |
1441 | |
1442 #define NUMBER 10 | |
1443 #pragma count (NUMBER) | |
1444 | |
1445 Name expansion is still disallowed. */ | |
1257 void | 1446 void |
1258 c_register_pragma_with_expansion (const char *space, const char *name, | 1447 c_register_pragma_with_expansion (const char *space, const char *name, |
1259 pragma_handler handler) | 1448 pragma_handler_1arg handler) |
1260 { | 1449 { |
1261 c_register_pragma_1 (space, name, handler, true); | 1450 internal_pragma_handler ihandler; |
1451 | |
1452 ihandler.handler.handler_1arg = handler; | |
1453 ihandler.extra_data = false; | |
1454 ihandler.data = NULL; | |
1455 c_register_pragma_1 (space, name, ihandler, true); | |
1456 } | |
1457 | |
1458 /* Register a C pragma handler, using a space and a name, it also carries an | |
1459 extra data field which can be used by the handler. It allows pragma | |
1460 expansion as in the following example: | |
1461 | |
1462 #define NUMBER 10 | |
1463 #pragma count (NUMBER) | |
1464 | |
1465 Name expansion is still disallowed. */ | |
1466 void | |
1467 c_register_pragma_with_expansion_and_data (const char *space, const char *name, | |
1468 pragma_handler_2arg handler, | |
1469 void *data) | |
1470 { | |
1471 internal_pragma_handler ihandler; | |
1472 | |
1473 ihandler.handler.handler_2arg = handler; | |
1474 ihandler.extra_data = true; | |
1475 ihandler.data = data; | |
1476 c_register_pragma_1 (space, name, ihandler, true); | |
1262 } | 1477 } |
1263 | 1478 |
1264 void | 1479 void |
1265 c_invoke_pragma_handler (unsigned int id) | 1480 c_invoke_pragma_handler (unsigned int id) |
1266 { | 1481 { |
1267 pragma_handler handler; | 1482 internal_pragma_handler *ihandler; |
1483 pragma_handler_1arg handler_1arg; | |
1484 pragma_handler_2arg handler_2arg; | |
1268 | 1485 |
1269 id -= PRAGMA_FIRST_EXTERNAL; | 1486 id -= PRAGMA_FIRST_EXTERNAL; |
1270 handler = *VEC_index (pragma_handler, registered_pragmas, id); | 1487 ihandler = ®istered_pragmas[id]; |
1271 | 1488 if (ihandler->extra_data) |
1272 handler (parse_in); | 1489 { |
1490 handler_2arg = ihandler->handler.handler_2arg; | |
1491 handler_2arg (parse_in, ihandler->data); | |
1492 } | |
1493 else | |
1494 { | |
1495 handler_1arg = ihandler->handler.handler_1arg; | |
1496 handler_1arg (parse_in); | |
1497 } | |
1273 } | 1498 } |
1274 | 1499 |
1275 /* Set up front-end pragmas. */ | 1500 /* Set up front-end pragmas. */ |
1276 void | 1501 void |
1277 init_pragma (void) | 1502 init_pragma (void) |
1278 { | 1503 { |
1504 if (flag_openacc) | |
1505 { | |
1506 const int n_oacc_pragmas | |
1507 = sizeof (oacc_pragmas) / sizeof (*oacc_pragmas); | |
1508 int i; | |
1509 | |
1510 for (i = 0; i < n_oacc_pragmas; ++i) | |
1511 cpp_register_deferred_pragma (parse_in, "acc", oacc_pragmas[i].name, | |
1512 oacc_pragmas[i].id, true, true); | |
1513 } | |
1514 | |
1279 if (flag_openmp) | 1515 if (flag_openmp) |
1280 { | 1516 { |
1281 const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas); | 1517 const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas); |
1282 int i; | 1518 int i; |
1283 | 1519 |
1284 for (i = 0; i < n_omp_pragmas; ++i) | 1520 for (i = 0; i < n_omp_pragmas; ++i) |
1285 cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name, | 1521 cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name, |
1286 omp_pragmas[i].id, true, true); | 1522 omp_pragmas[i].id, true, true); |
1287 } | 1523 } |
1524 if (flag_openmp || flag_openmp_simd) | |
1525 { | |
1526 const int n_omp_pragmas_simd = sizeof (omp_pragmas_simd) | |
1527 / sizeof (*omp_pragmas); | |
1528 int i; | |
1529 | |
1530 for (i = 0; i < n_omp_pragmas_simd; ++i) | |
1531 cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas_simd[i].name, | |
1532 omp_pragmas_simd[i].id, true, true); | |
1533 } | |
1534 | |
1535 if (flag_cilkplus) | |
1536 cpp_register_deferred_pragma (parse_in, NULL, "simd", PRAGMA_CILK_SIMD, | |
1537 true, false); | |
1288 | 1538 |
1289 if (!flag_preprocess_only) | 1539 if (!flag_preprocess_only) |
1290 cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess", | 1540 cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess", |
1291 PRAGMA_GCC_PCH_PREPROCESS, false, false); | 1541 PRAGMA_GCC_PCH_PREPROCESS, false, false); |
1542 | |
1543 if (!flag_preprocess_only) | |
1544 cpp_register_deferred_pragma (parse_in, "GCC", "ivdep", PRAGMA_IVDEP, false, | |
1545 false); | |
1546 | |
1547 if (flag_cilkplus) | |
1548 cpp_register_deferred_pragma (parse_in, "cilk", "grainsize", | |
1549 PRAGMA_CILK_GRAINSIZE, true, false); | |
1292 | 1550 |
1293 #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION | 1551 #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION |
1294 c_register_pragma_with_expansion (0, "pack", handle_pragma_pack); | 1552 c_register_pragma_with_expansion (0, "pack", handle_pragma_pack); |
1295 #else | 1553 #else |
1296 c_register_pragma (0, "pack", handle_pragma_pack); | 1554 c_register_pragma (0, "pack", handle_pragma_pack); |
1297 #endif | 1555 #endif |
1298 c_register_pragma (0, "weak", handle_pragma_weak); | 1556 c_register_pragma (0, "weak", handle_pragma_weak); |
1557 | |
1299 c_register_pragma ("GCC", "visibility", handle_pragma_visibility); | 1558 c_register_pragma ("GCC", "visibility", handle_pragma_visibility); |
1300 | 1559 |
1301 c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic); | 1560 c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic); |
1302 c_register_pragma ("GCC", "target", handle_pragma_target); | 1561 c_register_pragma ("GCC", "target", handle_pragma_target); |
1303 c_register_pragma ("GCC", "optimize", handle_pragma_optimize); | 1562 c_register_pragma ("GCC", "optimize", handle_pragma_optimize); |
1306 c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options); | 1565 c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options); |
1307 | 1566 |
1308 c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64", | 1567 c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64", |
1309 handle_pragma_float_const_decimal64); | 1568 handle_pragma_float_const_decimal64); |
1310 | 1569 |
1311 c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname); | 1570 c_register_pragma_with_expansion (0, "redefine_extname", |
1312 c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix); | 1571 handle_pragma_redefine_extname); |
1313 | 1572 |
1314 c_register_pragma_with_expansion (0, "message", handle_pragma_message); | 1573 c_register_pragma_with_expansion (0, "message", handle_pragma_message); |
1315 | 1574 |
1316 #ifdef REGISTER_TARGET_PRAGMAS | 1575 #ifdef REGISTER_TARGET_PRAGMAS |
1317 REGISTER_TARGET_PRAGMAS (); | 1576 REGISTER_TARGET_PRAGMAS (); |
1318 #endif | 1577 #endif |
1319 | 1578 |
1579 global_sso = default_sso; | |
1580 c_register_pragma (0, "scalar_storage_order", | |
1581 handle_pragma_scalar_storage_order); | |
1582 | |
1320 /* Allow plugins to register their own pragmas. */ | 1583 /* Allow plugins to register their own pragmas. */ |
1321 invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL); | 1584 invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL); |
1322 } | 1585 } |
1323 | 1586 |
1324 #include "gt-c-family-c-pragma.h" | 1587 #include "gt-c-family-c-pragma.h" |