Line data Source code
1 : /* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
2 : Copyright (C) 1992-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #include "config.h"
21 : #include "system.h"
22 : #include "coretypes.h"
23 : #include "target.h"
24 : #include "function.h" /* For cfun. */
25 : #include "c-common.h"
26 : #include "memmodel.h"
27 : #include "tm_p.h" /* For REGISTER_TARGET_PRAGMAS. */
28 : #include "stringpool.h"
29 : #include "cgraph.h"
30 : #include "diagnostic.h"
31 : #include "attribs.h"
32 : #include "varasm.h"
33 : #include "c-pragma.h"
34 : #include "opts.h"
35 : #include "plugin.h"
36 : #include "opt-suggestions.h"
37 :
38 : #define GCC_BAD(gmsgid) \
39 : do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
40 : #define GCC_BAD2(gmsgid, arg) \
41 : do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0)
42 : #define GCC_BAD_AT(loc, gmsgid) \
43 : do { warning_at (loc, OPT_Wpragmas, gmsgid); return; } while (0)
44 : #define GCC_BAD2_AT(loc, gmsgid, arg) \
45 : do { warning_at (loc, OPT_Wpragmas, gmsgid, arg); return; } while (0)
46 :
47 : struct GTY(()) align_stack {
48 : int alignment;
49 : tree id;
50 : struct align_stack * prev;
51 : };
52 :
53 : static GTY(()) struct align_stack * alignment_stack;
54 :
55 : static void handle_pragma_pack (cpp_reader *);
56 :
57 : /* If we have a "global" #pragma pack(<n>) in effect when the first
58 : #pragma pack(push,<n>) is encountered, this stores the value of
59 : maximum_field_alignment in effect. When the final pop_alignment()
60 : happens, we restore the value to this, not to a value of 0 for
61 : maximum_field_alignment. Value is in bits. */
62 : static int default_alignment;
63 : #define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \
64 : ? &default_alignment \
65 : : &alignment_stack->alignment) = (ALIGN))
66 :
67 : static void push_alignment (int, tree);
68 : static void pop_alignment (tree);
69 :
70 : /* Push an alignment value onto the stack. */
71 : static void
72 22 : push_alignment (int alignment, tree id)
73 : {
74 22 : align_stack * entry = ggc_alloc<align_stack> ();
75 :
76 22 : entry->alignment = alignment;
77 22 : entry->id = id;
78 22 : entry->prev = alignment_stack;
79 :
80 : /* The current value of maximum_field_alignment is not necessarily
81 : 0 since there may be a #pragma pack(<n>) in effect; remember it
82 : so that we can restore it after the final #pragma pop(). */
83 22 : if (alignment_stack == NULL)
84 19 : default_alignment = maximum_field_alignment;
85 :
86 22 : alignment_stack = entry;
87 :
88 22 : maximum_field_alignment = alignment;
89 22 : }
90 :
91 : /* Undo a push of an alignment onto the stack. */
92 : static void
93 24 : pop_alignment (tree id)
94 : {
95 24 : align_stack * entry;
96 :
97 24 : if (alignment_stack == NULL)
98 2 : GCC_BAD ("%<#pragma pack (pop)%> encountered without matching "
99 : "%<#pragma pack (push)%>");
100 :
101 : /* If we got an identifier, strip away everything above the target
102 : entry so that the next step will restore the state just below it. */
103 22 : if (id)
104 : {
105 9 : for (entry = alignment_stack; entry; entry = entry->prev)
106 6 : if (entry->id == id)
107 : {
108 2 : alignment_stack = entry;
109 2 : break;
110 : }
111 5 : if (entry == NULL)
112 3 : warning (OPT_Wpragmas,
113 : "%<#pragma pack(pop, %E)%> encountered without matching "
114 : "%<#pragma pack(push, %E)%>"
115 : , id, id);
116 : }
117 :
118 22 : entry = alignment_stack->prev;
119 :
120 22 : maximum_field_alignment = entry ? entry->alignment : default_alignment;
121 :
122 22 : alignment_stack = entry;
123 : }
124 :
125 : /* #pragma pack ()
126 : #pragma pack (N)
127 :
128 : #pragma pack (push)
129 : #pragma pack (push, N)
130 : #pragma pack (push, ID)
131 : #pragma pack (push, ID, N)
132 : #pragma pack (pop)
133 : #pragma pack (pop, ID) */
134 : static void
135 187 : handle_pragma_pack (cpp_reader *)
136 : {
137 187 : location_t loc;
138 187 : tree x, id = 0;
139 187 : int align = -1;
140 187 : enum cpp_ttype token;
141 187 : enum { set, push, pop } action;
142 :
143 187 : if (pragma_lex (&x) != CPP_OPEN_PAREN)
144 13 : GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored");
145 :
146 186 : token = pragma_lex (&x, &loc);
147 186 : if (token == CPP_CLOSE_PAREN)
148 : {
149 15 : action = set;
150 15 : align = initial_max_fld_align;
151 : }
152 171 : else if (token == CPP_NUMBER)
153 : {
154 116 : if (TREE_CODE (x) != INTEGER_CST)
155 2 : GCC_BAD_AT (loc, "invalid constant in %<#pragma pack%> - ignored");
156 114 : align = TREE_INT_CST_LOW (x);
157 114 : action = set;
158 114 : if (pragma_lex (&x) != CPP_CLOSE_PAREN)
159 1 : GCC_BAD ("malformed %<#pragma pack%> - ignored");
160 : }
161 55 : else if (token == CPP_NAME)
162 : {
163 : #define GCC_BAD_ACTION do { if (action != pop) \
164 : GCC_BAD ("malformed %<#pragma pack(push[, id][, <n>])%> - ignored"); \
165 : else \
166 : GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \
167 : } while (0)
168 :
169 54 : const char *op = IDENTIFIER_POINTER (x);
170 54 : if (!strcmp (op, "push"))
171 : action = push;
172 28 : else if (!strcmp (op, "pop"))
173 : action = pop;
174 : else
175 3 : GCC_BAD2_AT (loc, "unknown action %qE for %<#pragma pack%> - ignored",
176 : x);
177 :
178 75 : while ((token = pragma_lex (&x)) == CPP_COMMA)
179 : {
180 28 : token = pragma_lex (&x, &loc);
181 28 : if (token == CPP_NAME && id == 0)
182 : {
183 16 : id = x;
184 : }
185 12 : else if (token == CPP_NUMBER && action == push && align == -1)
186 : {
187 11 : if (TREE_CODE (x) != INTEGER_CST)
188 3 : GCC_BAD_AT (loc,
189 : "invalid constant in %<#pragma pack%> - ignored");
190 8 : align = TREE_INT_CST_LOW (x);
191 8 : if (align == -1)
192 0 : action = set;
193 : }
194 : else
195 76 : GCC_BAD_ACTION;
196 : }
197 :
198 47 : if (token != CPP_CLOSE_PAREN)
199 0 : GCC_BAD_ACTION;
200 : #undef GCC_BAD_ACTION
201 : }
202 : else
203 1 : GCC_BAD ("malformed %<#pragma pack%> - ignored");
204 :
205 175 : if (pragma_lex (&x, &loc) != CPP_EOF)
206 1 : warning_at (loc, OPT_Wpragmas, "junk at end of %<#pragma pack%>");
207 :
208 175 : if (flag_pack_struct)
209 0 : GCC_BAD ("%<#pragma pack%> has no effect with %<-fpack-struct%> - ignored");
210 :
211 175 : if (action != pop)
212 151 : switch (align)
213 : {
214 135 : case 0:
215 135 : case 1:
216 135 : case 2:
217 135 : case 4:
218 135 : case 8:
219 135 : case 16:
220 135 : align *= BITS_PER_UNIT;
221 135 : break;
222 15 : case -1:
223 15 : if (action == push)
224 : {
225 15 : align = maximum_field_alignment;
226 15 : break;
227 : }
228 : /* FALLTHRU */
229 1 : default:
230 1 : GCC_BAD2 ("alignment must be a small power of two, not %d", align);
231 : }
232 :
233 150 : switch (action)
234 : {
235 128 : case set: SET_GLOBAL_ALIGNMENT (align); break;
236 22 : case push: push_alignment (align, id); break;
237 24 : case pop: pop_alignment (id); break;
238 : }
239 : }
240 :
241 : struct GTY(()) pending_weak
242 : {
243 : tree name;
244 : tree value;
245 : };
246 :
247 :
248 : static GTY(()) vec<pending_weak, va_gc> *pending_weaks;
249 :
250 : static void apply_pragma_weak (tree, tree);
251 : static void handle_pragma_weak (cpp_reader *);
252 :
253 : static void
254 97 : apply_pragma_weak (tree decl, tree value)
255 : {
256 97 : if (value)
257 : {
258 7 : value = build_string (IDENTIFIER_LENGTH (value),
259 7 : IDENTIFIER_POINTER (value));
260 7 : decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
261 : build_tree_list (NULL, value)),
262 : 0);
263 : }
264 :
265 176 : if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
266 17 : && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma. */
267 3 : && DECL_ASSEMBLER_NAME_SET_P (decl)
268 97 : && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
269 0 : warning (OPT_Wpragmas, "applying %<#pragma weak %+D%> after first use "
270 : "results in unspecified behavior", decl);
271 :
272 97 : declare_weak (decl);
273 97 : }
274 :
275 : void
276 240510984 : maybe_apply_pragma_weak (tree decl)
277 : {
278 240510984 : tree id;
279 240510984 : int i;
280 240510984 : pending_weak *pe;
281 :
282 : /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed. */
283 :
284 : /* No weak symbols pending, take the short-cut. */
285 240510984 : if (vec_safe_is_empty (pending_weaks))
286 240510984 : return;
287 : /* If it's not visible outside this file, it doesn't matter whether
288 : it's weak. */
289 683 : if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl))
290 : return;
291 : /* If it's not a function or a variable, it can't be weak.
292 : FIXME: what kinds of things are visible outside this file but
293 : aren't functions or variables? Should this be an assert instead? */
294 114 : if (!VAR_OR_FUNCTION_DECL_P (decl))
295 : return;
296 :
297 114 : if (DECL_ASSEMBLER_NAME_SET_P (decl))
298 7 : id = DECL_ASSEMBLER_NAME (decl);
299 : else
300 : {
301 107 : id = DECL_ASSEMBLER_NAME (decl);
302 107 : SET_DECL_ASSEMBLER_NAME (decl, NULL_TREE);
303 : }
304 :
305 203 : FOR_EACH_VEC_ELT (*pending_weaks, i, pe)
306 114 : if (id == pe->name)
307 : {
308 25 : apply_pragma_weak (decl, pe->value);
309 25 : pending_weaks->unordered_remove (i);
310 25 : break;
311 : }
312 : }
313 :
314 : /* Process all "#pragma weak A = B" directives where we have not seen
315 : a decl for A. */
316 : void
317 200660 : maybe_apply_pending_pragma_weaks (void)
318 : {
319 200660 : tree alias_id, id, decl;
320 200660 : int i;
321 200660 : pending_weak *pe;
322 200660 : symtab_node *target;
323 :
324 200660 : if (vec_safe_is_empty (pending_weaks))
325 200660 : return;
326 :
327 42 : FOR_EACH_VEC_ELT (*pending_weaks, i, pe)
328 : {
329 21 : alias_id = pe->name;
330 21 : id = pe->value;
331 :
332 21 : if (id == NULL)
333 16 : continue;
334 :
335 5 : target = symtab_node::get_for_asmname (id);
336 10 : decl = build_decl (UNKNOWN_LOCATION,
337 5 : target ? TREE_CODE (target->decl) : FUNCTION_DECL,
338 : alias_id, default_function_type);
339 :
340 5 : DECL_ARTIFICIAL (decl) = 1;
341 5 : TREE_PUBLIC (decl) = 1;
342 5 : DECL_WEAK (decl) = 1;
343 5 : if (VAR_P (decl))
344 1 : TREE_STATIC (decl) = 1;
345 5 : if (!target)
346 : {
347 0 : error ("%q+D aliased to undefined symbol %qE",
348 : decl, id);
349 0 : continue;
350 : }
351 :
352 5 : assemble_alias (decl, id);
353 : }
354 : }
355 :
356 : /* #pragma weak name [= value] */
357 : static void
358 122 : handle_pragma_weak (cpp_reader *)
359 : {
360 122 : tree name, value, x, decl;
361 122 : enum cpp_ttype t;
362 :
363 122 : value = 0;
364 :
365 122 : if (pragma_lex (&name) != CPP_NAME)
366 4 : GCC_BAD ("malformed %<#pragma weak%>, ignored");
367 122 : t = pragma_lex (&x);
368 122 : if (t == CPP_EQ)
369 : {
370 16 : if (pragma_lex (&value) != CPP_NAME)
371 3 : GCC_BAD ("malformed %<#pragma weak%>, ignored");
372 13 : t = pragma_lex (&x);
373 : }
374 119 : if (t != CPP_EOF)
375 0 : warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>");
376 :
377 119 : decl = identifier_global_value (name);
378 119 : if (decl && DECL_P (decl))
379 : {
380 73 : if (!VAR_OR_FUNCTION_DECL_P (decl))
381 1 : GCC_BAD2 ("%<#pragma weak%> declaration of %q+D not allowed,"
382 : " ignored", decl);
383 72 : apply_pragma_weak (decl, value);
384 72 : if (value)
385 : {
386 3 : DECL_EXTERNAL (decl) = 0;
387 3 : if (VAR_P (decl))
388 2 : TREE_STATIC (decl) = 1;
389 3 : assemble_alias (decl, value);
390 : }
391 : }
392 : else
393 : {
394 46 : pending_weak pe = {name, value};
395 46 : vec_safe_push (pending_weaks, pe);
396 : }
397 : }
398 :
399 : static enum scalar_storage_order_kind global_sso;
400 :
401 : void
402 1177591 : maybe_apply_pragma_scalar_storage_order (tree type)
403 : {
404 1177591 : if (global_sso == SSO_NATIVE)
405 : return;
406 :
407 11 : gcc_assert (RECORD_OR_UNION_TYPE_P (type));
408 :
409 11 : if (lookup_attribute ("scalar_storage_order", TYPE_ATTRIBUTES (type)))
410 : return;
411 :
412 9 : if (global_sso == SSO_BIG_ENDIAN)
413 5 : TYPE_REVERSE_STORAGE_ORDER (type) = !BYTES_BIG_ENDIAN;
414 4 : else if (global_sso == SSO_LITTLE_ENDIAN)
415 4 : TYPE_REVERSE_STORAGE_ORDER (type) = BYTES_BIG_ENDIAN;
416 : else
417 0 : gcc_unreachable ();
418 : }
419 :
420 : static void
421 12 : handle_pragma_scalar_storage_order (cpp_reader *)
422 : {
423 12 : const char *kind_string;
424 12 : enum cpp_ttype token;
425 12 : tree x;
426 :
427 12 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
428 : {
429 : error ("%<scalar_storage_order%> is not supported because endianness "
430 : "is not uniform");
431 5 : return;
432 : }
433 :
434 12 : if (c_dialect_cxx ())
435 : {
436 3 : if (warn_unknown_pragmas > in_system_header_at (input_location))
437 3 : warning (OPT_Wunknown_pragmas,
438 : "%<#pragma scalar_storage_order%> is not supported for C++");
439 3 : return;
440 : }
441 :
442 9 : token = pragma_lex (&x);
443 9 : if (token != CPP_NAME)
444 1 : GCC_BAD ("missing %<big-endian%>, %<little-endian%>, or %<default%> after "
445 : "%<#pragma scalar_storage_order%>");
446 8 : kind_string = IDENTIFIER_POINTER (x);
447 8 : if (strcmp (kind_string, "default") == 0)
448 3 : global_sso = default_sso;
449 5 : else if (strcmp (kind_string, "big") == 0)
450 2 : global_sso = SSO_BIG_ENDIAN;
451 3 : else if (strcmp (kind_string, "little") == 0)
452 2 : global_sso = SSO_LITTLE_ENDIAN;
453 : else
454 8 : GCC_BAD ("expected %<big-endian%>, %<little-endian%>, or %<default%> after "
455 : "%<#pragma scalar_storage_order%>");
456 : }
457 :
458 : /* GCC supports two #pragma directives for renaming the external
459 : symbol associated with a declaration (DECL_ASSEMBLER_NAME), for
460 : compatibility with the Solaris and VMS system headers. GCC also
461 : has its own notation for this, __asm__("name") annotations.
462 :
463 : Corner cases of these features and their interaction:
464 :
465 : 1) Both pragmas silently apply only to declarations with external
466 : linkage (that is, TREE_PUBLIC || DECL_EXTERNAL). Asm labels
467 : do not have this restriction.
468 :
469 : 2) In C++, both #pragmas silently apply only to extern "C" declarations.
470 : Asm labels do not have this restriction.
471 :
472 : 3) If any of the three ways of changing DECL_ASSEMBLER_NAME is
473 : applied to a decl whose DECL_ASSEMBLER_NAME is already set, and the
474 : new name is different, a warning issues and the name does not change.
475 :
476 : 4) The "source name" for #pragma redefine_extname is the DECL_NAME,
477 : *not* the DECL_ASSEMBLER_NAME.
478 :
479 : 5) If #pragma extern_prefix is in effect and a declaration occurs
480 : with an __asm__ name, the #pragma extern_prefix is silently
481 : ignored for that declaration.
482 :
483 : 6) If #pragma extern_prefix and #pragma redefine_extname apply to
484 : the same declaration, whichever triggered first wins, and a warning
485 : is issued. (We would like to have #pragma redefine_extname always
486 : win, but it can appear either before or after the declaration, and
487 : if it appears afterward, we have no way of knowing whether a modified
488 : DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.) */
489 :
490 : struct GTY(()) pending_redefinition {
491 : tree oldname;
492 : tree newname;
493 : };
494 :
495 :
496 : static GTY(()) vec<pending_redefinition, va_gc> *pending_redefine_extname;
497 :
498 : static void handle_pragma_redefine_extname (cpp_reader *);
499 :
500 : /* #pragma redefine_extname oldname newname */
501 : static void
502 26 : handle_pragma_redefine_extname (cpp_reader *)
503 : {
504 26 : tree oldname, newname, decls, x;
505 26 : enum cpp_ttype t;
506 26 : bool found;
507 :
508 26 : if (pragma_lex (&oldname) != CPP_NAME)
509 3 : GCC_BAD ("malformed %<#pragma redefine_extname%>, ignored");
510 25 : if (pragma_lex (&newname) != CPP_NAME)
511 2 : GCC_BAD ("malformed %<#pragma redefine_extname%>, ignored");
512 23 : t = pragma_lex (&x);
513 23 : if (t != CPP_EOF)
514 1 : warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>");
515 :
516 23 : found = false;
517 23 : for (decls = c_linkage_bindings (oldname);
518 33 : decls; )
519 : {
520 10 : tree decl;
521 10 : if (TREE_CODE (decls) == TREE_LIST)
522 : {
523 3 : decl = TREE_VALUE (decls);
524 3 : decls = TREE_CHAIN (decls);
525 : }
526 : else
527 : {
528 : decl = decls;
529 : decls = NULL_TREE;
530 : }
531 :
532 0 : if ((TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
533 10 : && VAR_OR_FUNCTION_DECL_P (decl))
534 : {
535 10 : found = true;
536 10 : if (DECL_ASSEMBLER_NAME_SET_P (decl))
537 : {
538 0 : const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
539 0 : name = targetm.strip_name_encoding (name);
540 :
541 0 : if (!id_equal (newname, name))
542 0 : warning (OPT_Wpragmas, "%<#pragma redefine_extname%> "
543 : "ignored due to conflict with previous rename");
544 : }
545 : else
546 10 : symtab->change_decl_assembler_name (decl, newname);
547 : }
548 : }
549 :
550 23 : if (!found)
551 : /* We have to add this to the rename list even if there's already
552 : a global value that doesn't meet the above criteria, because in
553 : C++ "struct foo {...};" puts "foo" in the current namespace but
554 : does *not* conflict with a subsequent declaration of a function
555 : or variable foo. See g++.dg/other/pragma-re-2.C. */
556 16 : add_to_renaming_pragma_list (oldname, newname);
557 : }
558 :
559 : /* This is called from here and from ia64-c.cc. */
560 : void
561 16 : add_to_renaming_pragma_list (tree oldname, tree newname)
562 : {
563 16 : unsigned ix;
564 16 : pending_redefinition *p;
565 :
566 20 : FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
567 4 : if (oldname == p->oldname)
568 : {
569 0 : if (p->newname != newname)
570 0 : warning (OPT_Wpragmas, "%<#pragma redefine_extname%> ignored due to "
571 : "conflict with previous %<#pragma redefine_extname%>");
572 0 : return;
573 : }
574 :
575 16 : pending_redefinition e = {oldname, newname};
576 16 : vec_safe_push (pending_redefine_extname, e);
577 : }
578 :
579 : /* The current prefix set by #pragma extern_prefix. */
580 : GTY(()) tree pragma_extern_prefix;
581 :
582 : /* Hook from the front ends to apply the results of one of the preceding
583 : pragmas that rename variables. */
584 :
585 : tree
586 88864579 : maybe_apply_renaming_pragma (tree decl, tree asmname)
587 : {
588 88864579 : unsigned ix;
589 88864579 : pending_redefinition *p;
590 :
591 : /* The renaming pragmas are only applied to declarations with
592 : external linkage. */
593 60614856 : if (!VAR_OR_FUNCTION_DECL_P (decl)
594 79492064 : || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
595 168245153 : || !has_c_linkage (decl))
596 45132637 : return asmname;
597 :
598 : /* If the DECL_ASSEMBLER_NAME is already set, it does not change,
599 : but we may warn about a rename that conflicts. */
600 43731942 : if (DECL_ASSEMBLER_NAME_SET_P (decl))
601 : {
602 4572 : const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
603 4572 : oldname = targetm.strip_name_encoding (oldname);
604 :
605 5151 : if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname))
606 7 : warning (OPT_Wpragmas, "%<asm%> declaration ignored due to "
607 : "conflict with previous rename");
608 :
609 : /* Take any pending redefine_extname off the list. */
610 4575 : FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
611 3 : if (DECL_NAME (decl) == p->oldname)
612 : {
613 : /* Only warn if there is a conflict. */
614 0 : if (!id_equal (p->newname, oldname))
615 0 : warning (OPT_Wpragmas, "%<#pragma redefine_extname%> ignored "
616 : "due to conflict with previous rename");
617 :
618 0 : pending_redefine_extname->unordered_remove (ix);
619 0 : break;
620 : }
621 4572 : return NULL_TREE;
622 : }
623 :
624 : /* Find out if we have a pending #pragma redefine_extname. */
625 43727383 : FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
626 25 : if (DECL_NAME (decl) == p->oldname)
627 : {
628 12 : tree newname = p->newname;
629 12 : pending_redefine_extname->unordered_remove (ix);
630 :
631 : /* If we already have an asmname, #pragma redefine_extname is
632 : ignored (with a warning if it conflicts). */
633 12 : if (asmname)
634 : {
635 0 : if (strcmp (TREE_STRING_POINTER (asmname),
636 0 : IDENTIFIER_POINTER (newname)) != 0)
637 0 : warning (OPT_Wpragmas, "%<#pragma redefine_extname%> ignored "
638 : "due to conflict with %<asm%> declaration");
639 0 : return asmname;
640 : }
641 :
642 : /* Otherwise we use what we've got; #pragma extern_prefix is
643 : silently ignored. */
644 12 : return build_string (IDENTIFIER_LENGTH (newname),
645 12 : IDENTIFIER_POINTER (newname));
646 : }
647 :
648 : /* If we've got an asmname, #pragma extern_prefix is silently ignored. */
649 43727358 : if (asmname)
650 : return asmname;
651 :
652 : /* If #pragma extern_prefix is in effect, apply it. */
653 42313519 : if (pragma_extern_prefix)
654 : {
655 0 : const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix);
656 0 : size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1;
657 :
658 0 : const char *id = IDENTIFIER_POINTER (DECL_NAME (decl));
659 0 : size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl));
660 :
661 0 : char *newname = (char *) alloca (plen + ilen + 1);
662 :
663 0 : memcpy (newname, prefix, plen);
664 0 : memcpy (newname + plen, id, ilen + 1);
665 :
666 0 : return build_string (plen + ilen, newname);
667 : }
668 :
669 : /* Nada. */
670 : return NULL_TREE;
671 : }
672 :
673 :
674 : static void handle_pragma_visibility (cpp_reader *);
675 :
676 : static vec<int> visstack;
677 :
678 : /* Push the visibility indicated by STR onto the top of the #pragma
679 : visibility stack. KIND is 0 for #pragma GCC visibility, 1 for
680 : C++ namespace with visibility attribute and 2 for C++ builtin
681 : ABI namespace. push_visibility/pop_visibility calls must have
682 : matching KIND, it is not allowed to push visibility using one
683 : KIND and pop using a different one. */
684 :
685 : void
686 3063774 : push_visibility (const char *str, int kind)
687 : {
688 3063774 : visstack.safe_push (((int) default_visibility) | (kind << 8));
689 3063774 : if (!strcmp (str, "default"))
690 3062183 : default_visibility = VISIBILITY_DEFAULT;
691 1591 : else if (!strcmp (str, "internal"))
692 0 : default_visibility = VISIBILITY_INTERNAL;
693 1591 : else if (!strcmp (str, "hidden"))
694 1591 : default_visibility = VISIBILITY_HIDDEN;
695 0 : else if (!strcmp (str, "protected"))
696 0 : default_visibility = VISIBILITY_PROTECTED;
697 : else
698 0 : GCC_BAD ("%<#pragma GCC visibility push()%> must specify %<default%>, "
699 : "%<internal%>, %<hidden%> or %<protected%>");
700 3063774 : visibility_options.inpragma = 1;
701 : }
702 :
703 : /* Pop a level of the #pragma visibility stack. Return true if
704 : successful. */
705 :
706 : bool
707 3063758 : pop_visibility (int kind)
708 : {
709 3063758 : if (!visstack.length ())
710 : return false;
711 3063758 : if ((visstack.last () >> 8) != kind)
712 : return false;
713 3063755 : default_visibility
714 3063755 : = (enum symbol_visibility) (visstack.pop () & 0xff);
715 3063755 : visibility_options.inpragma
716 3063755 : = visstack.length () != 0;
717 3063755 : return true;
718 : }
719 :
720 : /* Sets the default visibility for symbols to something other than that
721 : specified on the command line. */
722 :
723 : static void
724 236230 : handle_pragma_visibility (cpp_reader *)
725 : {
726 : /* Form is #pragma GCC visibility push(hidden)|pop */
727 236230 : tree x;
728 236230 : enum cpp_ttype token;
729 236230 : enum { bad, push, pop } action = bad;
730 :
731 236230 : token = pragma_lex (&x);
732 236230 : if (token == CPP_NAME)
733 : {
734 236230 : const char *op = IDENTIFIER_POINTER (x);
735 236230 : if (!strcmp (op, "push"))
736 : action = push;
737 118107 : else if (!strcmp (op, "pop"))
738 : action = pop;
739 : }
740 : if (bad == action)
741 3 : GCC_BAD ("%<#pragma GCC visibility%> must be followed by %<push%> "
742 : "or %<pop%>");
743 : else
744 : {
745 236230 : if (pop == action)
746 : {
747 118107 : if (! pop_visibility (0))
748 3 : GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
749 : }
750 : else
751 : {
752 118123 : if (pragma_lex (&x) != CPP_OPEN_PAREN)
753 0 : GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
754 118123 : token = pragma_lex (&x);
755 118123 : if (token != CPP_NAME)
756 0 : GCC_BAD ("malformed %<#pragma GCC visibility push%>");
757 : else
758 118123 : push_visibility (IDENTIFIER_POINTER (x), 0);
759 118123 : if (pragma_lex (&x) != CPP_CLOSE_PAREN)
760 0 : GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
761 : }
762 : }
763 236227 : if (pragma_lex (&x) != CPP_EOF)
764 0 : warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>");
765 : }
766 :
767 : /* Helper routines for parsing #pragma GCC diagnostic. */
768 : class pragma_diagnostic_data
769 : {
770 : pragma_diagnostic_data (const pragma_diagnostic_data &) = delete;
771 : pragma_diagnostic_data& operator= (const pragma_diagnostic_data &) = delete;
772 :
773 : public:
774 : bool valid;
775 : location_t loc_kind, loc_option;
776 : enum pd_kind_t
777 : {
778 : PK_INVALID,
779 : PK_PUSH,
780 : PK_POP,
781 : PK_IGNORED_ATTRIBUTES,
782 : PK_DIAGNOSTIC,
783 : } pd_kind;
784 : enum diagnostics::kind diagnostic_kind;
785 : const char *kind_str;
786 : const char *option_str;
787 : bool own_option_str;
788 :
789 13320204 : pragma_diagnostic_data () { clear (); }
790 26640408 : void clear ()
791 : {
792 26640408 : valid = false;
793 26640408 : loc_kind = loc_option = UNKNOWN_LOCATION;
794 26640408 : pd_kind = PK_INVALID;
795 26640408 : diagnostic_kind = diagnostics::kind::unspecified;
796 26640408 : kind_str = option_str = nullptr;
797 26640408 : own_option_str = false;
798 : }
799 :
800 13320204 : ~pragma_diagnostic_data ()
801 : {
802 13320204 : if (own_option_str && option_str)
803 0 : XDELETEVEC (const_cast<char *> (option_str));
804 13320204 : }
805 :
806 13320194 : void set_kind (const char *kind_string)
807 : {
808 13320194 : kind_str = kind_string;
809 :
810 13320194 : pd_kind = PK_INVALID;
811 13320194 : diagnostic_kind = diagnostics::kind::unspecified;
812 13320194 : if (strcmp (kind_str, "push") == 0)
813 4271912 : pd_kind = PK_PUSH;
814 9048282 : else if (strcmp (kind_str, "pop") == 0)
815 4271269 : pd_kind = PK_POP;
816 4777013 : else if (strcmp (kind_str, "ignored_attributes") == 0)
817 77 : pd_kind = PK_IGNORED_ATTRIBUTES;
818 4776936 : else if (strcmp (kind_str, "error") == 0)
819 : {
820 64 : pd_kind = PK_DIAGNOSTIC;
821 64 : diagnostic_kind = diagnostics::kind::error;
822 : }
823 4776872 : else if (strcmp (kind_str, "warning") == 0)
824 : {
825 63 : pd_kind = PK_DIAGNOSTIC;
826 63 : diagnostic_kind = diagnostics::kind::warning;
827 : }
828 4776809 : else if (strcmp (kind_str, "ignored") == 0)
829 : {
830 4776801 : pd_kind = PK_DIAGNOSTIC;
831 4776801 : diagnostic_kind = diagnostics::kind::ignored;
832 : }
833 13320194 : }
834 :
835 13320186 : bool needs_option () const
836 : {
837 13320186 : return pd_kind == PK_IGNORED_ATTRIBUTES
838 13320186 : || pd_kind == PK_DIAGNOSTIC;
839 : }
840 :
841 : };
842 :
843 : /* This will call into either the C or C++ frontends as appropriate to get
844 : tokens from libcpp for the pragma. */
845 :
846 : static void
847 13320204 : pragma_diagnostic_lex (pragma_diagnostic_data *result)
848 : {
849 13320204 : result->clear ();
850 13320204 : tree x;
851 13320204 : auto ttype = pragma_lex (&x, &result->loc_kind);
852 13320204 : if (ttype != CPP_NAME)
853 18 : return;
854 13320194 : result->set_kind (IDENTIFIER_POINTER (x));
855 13320194 : if (result->pd_kind == pragma_diagnostic_data::PK_INVALID)
856 : return;
857 :
858 13320186 : if (result->needs_option ())
859 : {
860 4777005 : ttype = pragma_lex (&x, &result->loc_option);
861 4777005 : if (ttype != CPP_STRING)
862 : return;
863 4777005 : result->option_str = TREE_STRING_POINTER (x);
864 : }
865 :
866 13320186 : result->valid = true;
867 : }
868 :
869 : /* Handle #pragma GCC diagnostic. Early mode is used by frontends (such as C++)
870 : that do not process the deferred pragma while they are consuming tokens; they
871 : can use early mode to make sure diagnostics affecting the preprocessor itself
872 : are correctly modified by the #pragma. */
873 : template<bool early, bool is_pp> static void
874 13320204 : handle_pragma_diagnostic_impl ()
875 : {
876 : static const bool want_diagnostics = (is_pp || !early);
877 :
878 13320204 : pragma_diagnostic_data data;
879 13320204 : pragma_diagnostic_lex (&data);
880 :
881 13320204 : if (!data.kind_str)
882 : {
883 : if (want_diagnostics)
884 7 : warning_at (data.loc_kind, OPT_Wpragmas,
885 : "missing %<error%>, %<warning%>, %<ignored%>, %<push%>, "
886 : "%<pop%>, or %<ignored_attributes%> after "
887 : "%<#pragma GCC diagnostic%>");
888 7 : return;
889 : }
890 :
891 13320194 : switch (data.pd_kind)
892 : {
893 :
894 4271912 : case pragma_diagnostic_data::PK_PUSH:
895 4271912 : diagnostic_push_diagnostics (global_dc, input_location);
896 : return;
897 :
898 4271269 : case pragma_diagnostic_data::PK_POP:
899 4271269 : diagnostic_pop_diagnostics (global_dc, input_location);
900 : return;
901 :
902 : case pragma_diagnostic_data::PK_IGNORED_ATTRIBUTES:
903 : {
904 : if (early)
905 : return;
906 44 : if (!data.option_str)
907 : {
908 0 : warning_at (data.loc_option, OPT_Wpragmas,
909 : "missing attribute name after %<#pragma GCC diagnostic "
910 : "ignored_attributes%>");
911 0 : return;
912 : }
913 44 : char *args = xstrdup (data.option_str);
914 44 : const size_t l = strlen (args);
915 44 : if (l == 0)
916 : {
917 0 : warning_at (data.loc_option, OPT_Wpragmas,
918 : "missing argument to %<#pragma GCC "
919 : "diagnostic ignored_attributes%>");
920 0 : free (args);
921 0 : return;
922 : }
923 44 : else if (args[l - 1] == ',')
924 : {
925 0 : warning_at (data.loc_option, OPT_Wpragmas,
926 : "trailing %<,%> in arguments for "
927 : "%<#pragma GCC diagnostic ignored_attributes%>");
928 0 : free (args);
929 0 : return;
930 : }
931 44 : auto_vec<char *> v;
932 108 : for (char *p = strtok (args, ","); p; p = strtok (NULL, ","))
933 64 : v.safe_push (p);
934 44 : handle_ignored_attributes_option (&v);
935 44 : free (args);
936 : return;
937 44 : }
938 :
939 4776928 : case pragma_diagnostic_data::PK_DIAGNOSTIC:
940 4776928 : if (!data.option_str)
941 : {
942 : if (want_diagnostics)
943 0 : warning_at (data.loc_option, OPT_Wpragmas,
944 : "missing option after %<#pragma GCC diagnostic%> kind");
945 0 : return;
946 : }
947 : break;
948 :
949 5 : default:
950 : if (want_diagnostics)
951 5 : warning_at (data.loc_kind, OPT_Wpragmas,
952 : "expected %<error%>, %<warning%>, %<ignored%>, %<push%>, "
953 : "%<pop%>, %<ignored_attributes%> after "
954 : "%<#pragma GCC diagnostic%>");
955 5 : return;
956 :
957 : }
958 :
959 : gcc_assert (data.pd_kind == pragma_diagnostic_data::PK_DIAGNOSTIC);
960 4776928 : gcc_assert (data.valid);
961 :
962 4776928 : unsigned int lang_mask = c_common_option_lang_mask () | CL_COMMON;
963 : /* option_string + 1 to skip the initial '-' */
964 4776928 : unsigned int option_index = find_opt (data.option_str + 1, lang_mask);
965 :
966 2335857 : if (early && !(c_option_is_from_cpp_diagnostics (option_index)
967 2335857 : || option_index == OPT_Wunknown_pragmas))
968 : return;
969 :
970 3956690 : if (option_index == OPT_SPECIAL_unknown)
971 : {
972 : if (want_diagnostics)
973 : {
974 11 : auto_diagnostic_group d;
975 11 : if (warning_at (data.loc_option, OPT_Wpragmas,
976 : "unknown option after %<#pragma GCC diagnostic%> kind"))
977 : {
978 11 : option_proposer op;
979 11 : const char *hint = op.suggest_option (data.option_str + 1);
980 11 : if (hint)
981 4 : inform (data.loc_option, "did you mean %<-%s%>?", hint);
982 11 : }
983 11 : }
984 11 : return;
985 : }
986 3956679 : else if (!(cl_options[option_index].flags & CL_WARNING))
987 : {
988 : if (want_diagnostics)
989 11 : warning_at (data.loc_option, OPT_Wpragmas,
990 : "%qs is not an option that controls warnings",
991 : data.option_str);
992 11 : return;
993 : }
994 3956668 : else if (!(cl_options[option_index].flags & lang_mask))
995 : {
996 : if (want_diagnostics)
997 : {
998 1 : char *ok_langs = write_langs (cl_options[option_index].flags);
999 1 : char *bad_lang = write_langs (c_common_option_lang_mask ());
1000 1 : warning_at (data.loc_option, OPT_Wpragmas,
1001 : "option %qs is valid for %s but not for %s",
1002 : data.option_str, ok_langs, bad_lang);
1003 1 : free (ok_langs);
1004 1 : free (bad_lang);
1005 : }
1006 1 : return;
1007 : }
1008 :
1009 3956667 : const char *arg = NULL;
1010 3956667 : if (cl_options[option_index].flags & CL_JOINED)
1011 17 : arg = data.option_str + 1 + cl_options[option_index].opt_len;
1012 :
1013 : struct cl_option_handlers handlers;
1014 3956667 : set_default_handlers (&handlers, NULL);
1015 : /* FIXME: input_location isn't the best location here, but it is
1016 : what we used to do here before and changing it breaks e.g.
1017 : PR69543 and PR69558. */
1018 3956667 : control_warning_option (option_index, (int) data.diagnostic_kind,
1019 : arg,
1020 3956667 : data.diagnostic_kind != diagnostics::kind::ignored,
1021 : input_location, lang_mask, &handlers,
1022 : &global_options, &global_options_set,
1023 : global_dc);
1024 13320204 : }
1025 :
1026 : static void
1027 6819485 : handle_pragma_diagnostic (cpp_reader *)
1028 : {
1029 6819485 : handle_pragma_diagnostic_impl<false, false> ();
1030 6819485 : }
1031 :
1032 : static void
1033 6474875 : handle_pragma_diagnostic_early (cpp_reader *)
1034 : {
1035 6474875 : handle_pragma_diagnostic_impl<true, false> ();
1036 6474875 : }
1037 :
1038 : static void
1039 25844 : handle_pragma_diagnostic_early_pp (cpp_reader *)
1040 : {
1041 25844 : handle_pragma_diagnostic_impl<true, true> ();
1042 25844 : }
1043 :
1044 : /* Parse #pragma GCC target (xxx) to set target specific options. */
1045 : static void
1046 559015 : handle_pragma_target(cpp_reader *)
1047 : {
1048 559015 : location_t loc;
1049 559015 : enum cpp_ttype token;
1050 559015 : tree x;
1051 559015 : bool close_paren_needed_p = false;
1052 :
1053 559015 : if (cfun)
1054 : {
1055 0 : error ("%<#pragma GCC option%> is not allowed inside functions");
1056 2 : return;
1057 : }
1058 :
1059 559015 : token = pragma_lex (&x, &loc);
1060 559015 : if (token == CPP_OPEN_PAREN)
1061 : {
1062 558959 : close_paren_needed_p = true;
1063 558959 : token = pragma_lex (&x, &loc);
1064 : }
1065 :
1066 559015 : if (token != CPP_STRING)
1067 2 : GCC_BAD_AT (loc, "%<#pragma GCC option%> is not a string");
1068 :
1069 : /* Strings are user options. */
1070 : else
1071 : {
1072 : tree args = NULL_TREE;
1073 :
1074 559031 : do
1075 : {
1076 : /* Build up the strings now as a tree linked list. Skip empty
1077 : strings. */
1078 559031 : if (TREE_STRING_LENGTH (x) > 0)
1079 559031 : args = tree_cons (NULL_TREE, x, args);
1080 :
1081 559031 : token = pragma_lex (&x);
1082 1118080 : while (token == CPP_COMMA)
1083 18 : token = pragma_lex (&x);
1084 : }
1085 559031 : while (token == CPP_STRING);
1086 :
1087 559013 : if (close_paren_needed_p)
1088 : {
1089 558958 : if (token == CPP_CLOSE_PAREN)
1090 558958 : token = pragma_lex (&x);
1091 : else
1092 558958 : GCC_BAD ("%<#pragma GCC target (string [,string]...)%> does "
1093 : "not have a final %<)%>");
1094 : }
1095 :
1096 559013 : if (token != CPP_EOF)
1097 : {
1098 0 : error ("%<#pragma GCC target%> string is badly formed");
1099 0 : return;
1100 : }
1101 :
1102 : /* put arguments in the order the user typed them. */
1103 559013 : args = nreverse (args);
1104 :
1105 559013 : if (targetm.target_option.pragma_parse (args, NULL_TREE))
1106 558744 : current_target_pragma = chainon (current_target_pragma, args);
1107 :
1108 : /* A target pragma can also influence optimization options. */
1109 559013 : tree current_optimize
1110 559013 : = build_optimization_node (&global_options, &global_options_set);
1111 559013 : if (current_optimize != optimization_current_node)
1112 78 : optimization_current_node = current_optimize;
1113 : }
1114 : }
1115 :
1116 : /* Handle #pragma GCC optimize to set optimization options. */
1117 : static void
1118 533 : handle_pragma_optimize (cpp_reader *)
1119 : {
1120 533 : enum cpp_ttype token;
1121 533 : tree x;
1122 533 : bool close_paren_needed_p = false;
1123 533 : tree optimization_previous_node = optimization_current_node;
1124 :
1125 533 : if (cfun)
1126 : {
1127 0 : error ("%<#pragma GCC optimize%> is not allowed inside functions");
1128 0 : return;
1129 : }
1130 :
1131 533 : token = pragma_lex (&x);
1132 533 : if (token == CPP_OPEN_PAREN)
1133 : {
1134 126 : close_paren_needed_p = true;
1135 126 : token = pragma_lex (&x);
1136 : }
1137 :
1138 533 : if (token != CPP_STRING && token != CPP_NUMBER)
1139 0 : GCC_BAD ("%<#pragma GCC optimize%> is not a string or number");
1140 :
1141 : /* Strings/numbers are user options. */
1142 : else
1143 : {
1144 : tree args = NULL_TREE;
1145 :
1146 549 : do
1147 : {
1148 : /* Build up the numbers/strings now as a list. */
1149 549 : if (token != CPP_STRING || TREE_STRING_LENGTH (x) > 0)
1150 549 : args = tree_cons (NULL_TREE, x, args);
1151 :
1152 549 : token = pragma_lex (&x);
1153 1114 : while (token == CPP_COMMA)
1154 16 : token = pragma_lex (&x);
1155 : }
1156 549 : while (token == CPP_STRING || token == CPP_NUMBER);
1157 :
1158 533 : if (close_paren_needed_p)
1159 : {
1160 126 : if (token == CPP_CLOSE_PAREN)
1161 126 : token = pragma_lex (&x);
1162 : else
1163 126 : GCC_BAD ("%<#pragma GCC optimize (string [,string]...)%> does "
1164 : "not have a final %<)%>");
1165 : }
1166 :
1167 533 : if (token != CPP_EOF)
1168 : {
1169 0 : error ("%<#pragma GCC optimize%> string is badly formed");
1170 0 : return;
1171 : }
1172 :
1173 : /* put arguments in the order the user typed them. */
1174 533 : args = nreverse (args);
1175 :
1176 533 : parse_optimize_options (args, false);
1177 533 : current_optimize_pragma = chainon (current_optimize_pragma, args);
1178 533 : optimization_current_node
1179 533 : = build_optimization_node (&global_options, &global_options_set);
1180 533 : c_cpp_builtins_optimize_pragma (parse_in,
1181 : optimization_previous_node,
1182 : optimization_current_node);
1183 : }
1184 : }
1185 :
1186 : /* Stack of the #pragma GCC options created with #pragma GCC push_option. Save
1187 : both the binary representation of the options and the TREE_LIST of
1188 : strings that will be added to the function's attribute list. */
1189 : struct GTY(()) opt_stack {
1190 : struct opt_stack *prev;
1191 : tree target_binary;
1192 : tree target_strings;
1193 : tree optimize_binary;
1194 : tree optimize_strings;
1195 : gcc_options * GTY ((skip)) saved_global_options;
1196 : };
1197 :
1198 : static GTY(()) struct opt_stack * options_stack;
1199 :
1200 : /* Handle #pragma GCC push_options to save the current target and optimization
1201 : options. */
1202 :
1203 : static void
1204 559225 : handle_pragma_push_options (cpp_reader *)
1205 : {
1206 559225 : enum cpp_ttype token;
1207 559225 : tree x = 0;
1208 :
1209 559225 : token = pragma_lex (&x);
1210 559225 : if (token != CPP_EOF)
1211 : {
1212 0 : warning (OPT_Wpragmas, "junk at end of %<#pragma GCC push_options%>");
1213 0 : return;
1214 : }
1215 :
1216 559225 : opt_stack *p = ggc_alloc<opt_stack> ();
1217 559225 : p->prev = options_stack;
1218 559225 : options_stack = p;
1219 :
1220 : /* Save optimization and target flags in binary format. */
1221 559225 : if (flag_checking)
1222 : {
1223 559225 : p->saved_global_options = XNEW (gcc_options);
1224 559225 : *p->saved_global_options = global_options;
1225 : }
1226 559225 : p->optimize_binary = build_optimization_node (&global_options,
1227 : &global_options_set);
1228 559225 : p->target_binary = build_target_option_node (&global_options,
1229 : &global_options_set);
1230 :
1231 : /* Save optimization and target flags in string list format. */
1232 559225 : p->optimize_strings = copy_list (current_optimize_pragma);
1233 559225 : p->target_strings = copy_list (current_target_pragma);
1234 : }
1235 :
1236 : /* Handle #pragma GCC pop_options to restore the current target and
1237 : optimization options from a previous push_options. */
1238 :
1239 : static void
1240 559224 : handle_pragma_pop_options (cpp_reader *)
1241 : {
1242 559224 : enum cpp_ttype token;
1243 559224 : tree x = 0;
1244 559224 : opt_stack *p;
1245 :
1246 559224 : token = pragma_lex (&x);
1247 559224 : if (token != CPP_EOF)
1248 : {
1249 0 : warning (OPT_Wpragmas, "junk at end of %<#pragma GCC pop_options%>");
1250 0 : return;
1251 : }
1252 :
1253 559224 : if (! options_stack)
1254 : {
1255 0 : warning (OPT_Wpragmas,
1256 : "%<#pragma GCC pop_options%> without a corresponding "
1257 : "%<#pragma GCC push_options%>");
1258 0 : return;
1259 : }
1260 :
1261 559224 : p = options_stack;
1262 559224 : options_stack = p->prev;
1263 :
1264 559224 : if (p->target_binary != target_option_current_node)
1265 : {
1266 554043 : (void) targetm.target_option.pragma_parse (NULL_TREE, p->target_binary);
1267 554043 : target_option_current_node = p->target_binary;
1268 : }
1269 :
1270 : /* Always restore optimization options as optimization_current_node is
1271 : * overwritten by invoke_set_current_function_hook. */
1272 1118448 : cl_optimization_restore (&global_options, &global_options_set,
1273 559224 : TREE_OPTIMIZATION (p->optimize_binary));
1274 1118448 : cl_target_option_restore (&global_options, &global_options_set,
1275 559224 : TREE_TARGET_OPTION (p->target_binary));
1276 :
1277 559224 : if (p->optimize_binary != optimization_current_node)
1278 : {
1279 53 : c_cpp_builtins_optimize_pragma (parse_in, optimization_current_node,
1280 : p->optimize_binary);
1281 53 : optimization_current_node = p->optimize_binary;
1282 : }
1283 559224 : if (flag_checking && !seen_error ())
1284 : {
1285 559220 : cl_optimization_compare (p->saved_global_options, &global_options);
1286 559220 : free (p->saved_global_options);
1287 : }
1288 :
1289 559224 : current_target_pragma = p->target_strings;
1290 559224 : current_optimize_pragma = p->optimize_strings;
1291 : }
1292 :
1293 : /* This is mostly a helper for handle_pragma_reset_options () to do the actual
1294 : work, but the C++ frontend, for example, needs an external interface to
1295 : perform this operation, since it processes target pragmas twice. (Once for
1296 : preprocessing purposes, and then again during compilation.) */
1297 :
1298 : void
1299 95996 : c_reset_target_pragmas ()
1300 : {
1301 95996 : tree new_optimize = optimization_default_node;
1302 95996 : tree new_target = target_option_default_node;
1303 95996 : if (new_target != target_option_current_node)
1304 : {
1305 41 : (void) targetm.target_option.pragma_parse (NULL_TREE, new_target);
1306 41 : target_option_current_node = new_target;
1307 : }
1308 :
1309 95996 : if (new_optimize != optimization_current_node)
1310 : {
1311 49 : tree old_optimize = optimization_current_node;
1312 49 : cl_optimization_restore (&global_options, &global_options_set,
1313 49 : TREE_OPTIMIZATION (new_optimize));
1314 49 : c_cpp_builtins_optimize_pragma (parse_in, old_optimize, new_optimize);
1315 49 : optimization_current_node = new_optimize;
1316 : }
1317 :
1318 95996 : current_target_pragma = NULL_TREE;
1319 95996 : current_optimize_pragma = NULL_TREE;
1320 95996 : }
1321 :
1322 : /* Handle #pragma GCC reset_options to restore the current target and
1323 : optimization options to the original options used on the command line. */
1324 :
1325 : static void
1326 4 : handle_pragma_reset_options (cpp_reader *)
1327 : {
1328 4 : tree x;
1329 4 : if (pragma_lex (&x) != CPP_EOF)
1330 0 : warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>");
1331 : else
1332 4 : c_reset_target_pragmas ();
1333 4 : }
1334 :
1335 : /* Print a plain user-specified message. */
1336 :
1337 : static void
1338 56 : handle_pragma_message (cpp_reader *)
1339 : {
1340 56 : location_t loc;
1341 56 : enum cpp_ttype token;
1342 56 : tree x, message = 0;
1343 :
1344 56 : token = pragma_lex (&x);
1345 56 : if (token == CPP_OPEN_PAREN)
1346 : {
1347 21 : token = pragma_lex (&x);
1348 21 : if (token == CPP_STRING)
1349 14 : message = x;
1350 : else
1351 20 : GCC_BAD ("expected a string after %<#pragma message%>");
1352 14 : if (pragma_lex (&x) != CPP_CLOSE_PAREN)
1353 1 : GCC_BAD ("malformed %<#pragma message%>, ignored");
1354 : }
1355 35 : else if (token == CPP_STRING)
1356 23 : message = x;
1357 12 : else if (token == CPP_STRING_USERDEF)
1358 3 : GCC_BAD ("string literal with user-defined suffix is invalid in this "
1359 : "context");
1360 : else
1361 9 : GCC_BAD ("expected a string after %<#pragma message%>");
1362 :
1363 36 : gcc_assert (message);
1364 :
1365 36 : if (pragma_lex (&x, &loc) != CPP_EOF)
1366 3 : warning_at (loc, OPT_Wpragmas, "junk at end of %<#pragma message%>");
1367 :
1368 36 : if (TREE_STRING_LENGTH (message) > 1)
1369 32 : inform (input_location, "%<#pragma message: %s%>",
1370 32 : TREE_STRING_POINTER (message));
1371 : }
1372 :
1373 : /* Ignore a no-op pragma that GCC recognizes, but which has no effect. */
1374 : static void
1375 16 : handle_pragma_ignore (cpp_reader *)
1376 : {
1377 16 : }
1378 :
1379 : /* Mark whether the current location is valid for a STDC pragma. */
1380 :
1381 : static bool valid_location_for_stdc_pragma;
1382 :
1383 : void
1384 127814714 : mark_valid_location_for_stdc_pragma (bool flag)
1385 : {
1386 127814714 : valid_location_for_stdc_pragma = flag;
1387 127814714 : }
1388 :
1389 : /* Return true if the current location is valid for a STDC pragma. */
1390 :
1391 : bool
1392 37190484 : valid_location_for_stdc_pragma_p (void)
1393 : {
1394 37190484 : return valid_location_for_stdc_pragma;
1395 : }
1396 :
1397 : enum pragma_switch_t { PRAGMA_ON, PRAGMA_OFF, PRAGMA_DEFAULT, PRAGMA_BAD };
1398 :
1399 : /* A STDC pragma must appear outside of external declarations or
1400 : preceding all explicit declarations and statements inside a compound
1401 : statement; its behavior is undefined if used in any other context.
1402 : It takes a switch of ON, OFF, or DEFAULT. */
1403 :
1404 : static enum pragma_switch_t
1405 66 : handle_stdc_pragma (const char *pname)
1406 : {
1407 66 : const char *arg;
1408 66 : tree t;
1409 66 : enum pragma_switch_t ret;
1410 :
1411 66 : if (!valid_location_for_stdc_pragma_p ())
1412 : {
1413 12 : warning (OPT_Wpragmas, "invalid location for %<pragma %s%>, ignored",
1414 : pname);
1415 12 : return PRAGMA_BAD;
1416 : }
1417 :
1418 54 : if (pragma_lex (&t) != CPP_NAME)
1419 : {
1420 2 : warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
1421 2 : return PRAGMA_BAD;
1422 : }
1423 :
1424 52 : arg = IDENTIFIER_POINTER (t);
1425 :
1426 52 : if (!strcmp (arg, "ON"))
1427 : ret = PRAGMA_ON;
1428 30 : else if (!strcmp (arg, "OFF"))
1429 : ret = PRAGMA_OFF;
1430 11 : else if (!strcmp (arg, "DEFAULT"))
1431 : ret = PRAGMA_DEFAULT;
1432 : else
1433 : {
1434 2 : warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
1435 2 : return PRAGMA_BAD;
1436 : }
1437 :
1438 50 : if (pragma_lex (&t) != CPP_EOF)
1439 : {
1440 2 : warning (OPT_Wpragmas, "junk at end of %<#pragma %s%>", pname);
1441 2 : return PRAGMA_BAD;
1442 : }
1443 :
1444 : return ret;
1445 : }
1446 :
1447 : /* #pragma STDC FLOAT_CONST_DECIMAL64 ON
1448 : #pragma STDC FLOAT_CONST_DECIMAL64 OFF
1449 : #pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT */
1450 :
1451 : static void
1452 69 : handle_pragma_float_const_decimal64 (cpp_reader *)
1453 : {
1454 69 : if (c_dialect_cxx ())
1455 : {
1456 3 : if (warn_unknown_pragmas > in_system_header_at (input_location))
1457 3 : warning (OPT_Wunknown_pragmas,
1458 : "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
1459 : " for C++");
1460 3 : return;
1461 : }
1462 :
1463 66 : if (!targetm.decimal_float_supported_p ())
1464 : {
1465 0 : if (warn_unknown_pragmas > in_system_header_at (input_location))
1466 0 : warning (OPT_Wunknown_pragmas,
1467 : "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
1468 : " on this target");
1469 0 : return;
1470 : }
1471 :
1472 66 : pedwarn (input_location, OPT_Wpedantic,
1473 : "ISO C does not support %<#pragma STDC FLOAT_CONST_DECIMAL64%>");
1474 :
1475 66 : switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64"))
1476 : {
1477 20 : case PRAGMA_ON:
1478 20 : set_float_const_decimal64 ();
1479 20 : break;
1480 28 : case PRAGMA_OFF:
1481 28 : case PRAGMA_DEFAULT:
1482 28 : clear_float_const_decimal64 ();
1483 28 : break;
1484 : case PRAGMA_BAD:
1485 : break;
1486 : }
1487 : }
1488 :
1489 : /* A vector of registered pragma callbacks, which is never freed. */
1490 :
1491 :
1492 : struct pragma_data
1493 : {
1494 : const char *space;
1495 : const char *name;
1496 : struct internal_pragma_handler ihandler;
1497 : };
1498 :
1499 : static vec<pragma_data> registered_pragmas;
1500 :
1501 : struct omp_pragma_def { const char *name; unsigned int id; };
1502 : static const struct omp_pragma_def oacc_pragmas[] = {
1503 : { "atomic", PRAGMA_OACC_ATOMIC },
1504 : { "cache", PRAGMA_OACC_CACHE },
1505 : { "data", PRAGMA_OACC_DATA },
1506 : { "declare", PRAGMA_OACC_DECLARE },
1507 : { "enter", PRAGMA_OACC_ENTER_DATA },
1508 : { "exit", PRAGMA_OACC_EXIT_DATA },
1509 : { "host_data", PRAGMA_OACC_HOST_DATA },
1510 : { "kernels", PRAGMA_OACC_KERNELS },
1511 : { "loop", PRAGMA_OACC_LOOP },
1512 : { "parallel", PRAGMA_OACC_PARALLEL },
1513 : { "routine", PRAGMA_OACC_ROUTINE },
1514 : { "serial", PRAGMA_OACC_SERIAL },
1515 : { "update", PRAGMA_OACC_UPDATE },
1516 : { "wait", PRAGMA_OACC_WAIT }
1517 : };
1518 : static const struct omp_pragma_def omp_pragmas[] = {
1519 : { "allocate", PRAGMA_OMP_ALLOCATE },
1520 : { "assumes", PRAGMA_OMP_ASSUMES },
1521 : { "atomic", PRAGMA_OMP_ATOMIC },
1522 : { "barrier", PRAGMA_OMP_BARRIER },
1523 : { "begin", PRAGMA_OMP_BEGIN },
1524 : { "cancel", PRAGMA_OMP_CANCEL },
1525 : { "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
1526 : { "critical", PRAGMA_OMP_CRITICAL },
1527 : { "depobj", PRAGMA_OMP_DEPOBJ },
1528 : { "dispatch", PRAGMA_OMP_DISPATCH },
1529 : { "error", PRAGMA_OMP_ERROR },
1530 : { "end", PRAGMA_OMP_END },
1531 : { "flush", PRAGMA_OMP_FLUSH },
1532 : { "groupprivate", PRAGMA_OMP_GROUPPRIVATE },
1533 : { "interop", PRAGMA_OMP_INTEROP },
1534 : { "metadirective", PRAGMA_OMP_METADIRECTIVE },
1535 : { "nothing", PRAGMA_OMP_NOTHING },
1536 : { "requires", PRAGMA_OMP_REQUIRES },
1537 : { "scope", PRAGMA_OMP_SCOPE },
1538 : { "section", PRAGMA_OMP_SECTION },
1539 : { "sections", PRAGMA_OMP_SECTIONS },
1540 : { "single", PRAGMA_OMP_SINGLE },
1541 : { "task", PRAGMA_OMP_TASK },
1542 : { "taskgroup", PRAGMA_OMP_TASKGROUP },
1543 : { "taskwait", PRAGMA_OMP_TASKWAIT },
1544 : { "taskyield", PRAGMA_OMP_TASKYIELD },
1545 : { "threadprivate", PRAGMA_OMP_THREADPRIVATE }
1546 : };
1547 : static const struct omp_pragma_def omp_pragmas_simd[] = {
1548 : { "assume", PRAGMA_OMP_ASSUME },
1549 : { "declare", PRAGMA_OMP_DECLARE },
1550 : { "distribute", PRAGMA_OMP_DISTRIBUTE },
1551 : { "for", PRAGMA_OMP_FOR },
1552 : { "loop", PRAGMA_OMP_LOOP },
1553 : { "masked", PRAGMA_OMP_MASKED },
1554 : { "master", PRAGMA_OMP_MASTER },
1555 : { "ordered", PRAGMA_OMP_ORDERED },
1556 : { "parallel", PRAGMA_OMP_PARALLEL },
1557 : { "scan", PRAGMA_OMP_SCAN },
1558 : { "simd", PRAGMA_OMP_SIMD },
1559 : { "target", PRAGMA_OMP_TARGET },
1560 : { "taskloop", PRAGMA_OMP_TASKLOOP },
1561 : { "teams", PRAGMA_OMP_TEAMS },
1562 : { "tile", PRAGMA_OMP_TILE },
1563 : { "unroll", PRAGMA_OMP_UNROLL },
1564 : };
1565 :
1566 : void
1567 33384 : c_pp_lookup_pragma (unsigned int id, const char **space, const char **name)
1568 : {
1569 33384 : const int n_oacc_pragmas = ARRAY_SIZE (oacc_pragmas);
1570 33384 : const int n_omp_pragmas = ARRAY_SIZE (omp_pragmas);
1571 33384 : const int n_omp_pragmas_simd = ARRAY_SIZE (omp_pragmas_simd);
1572 33384 : int i;
1573 :
1574 500760 : for (i = 0; i < n_oacc_pragmas; ++i)
1575 467376 : if (oacc_pragmas[i].id == id)
1576 : {
1577 0 : *space = "acc";
1578 0 : *name = oacc_pragmas[i].name;
1579 0 : return;
1580 : }
1581 :
1582 934530 : for (i = 0; i < n_omp_pragmas; ++i)
1583 901174 : if (omp_pragmas[i].id == id)
1584 : {
1585 28 : *space = "omp";
1586 28 : *name = omp_pragmas[i].name;
1587 28 : return;
1588 : }
1589 :
1590 566482 : for (i = 0; i < n_omp_pragmas_simd; ++i)
1591 533192 : if (omp_pragmas_simd[i].id == id)
1592 : {
1593 66 : *space = "omp";
1594 66 : *name = omp_pragmas_simd[i].name;
1595 66 : return;
1596 : }
1597 :
1598 33290 : if (id >= PRAGMA_FIRST_EXTERNAL
1599 66580 : && (id < PRAGMA_FIRST_EXTERNAL + registered_pragmas.length ()))
1600 : {
1601 33290 : *space = registered_pragmas[id - PRAGMA_FIRST_EXTERNAL].space;
1602 33290 : *name = registered_pragmas[id - PRAGMA_FIRST_EXTERNAL].name;
1603 33290 : return;
1604 : }
1605 :
1606 0 : gcc_unreachable ();
1607 : }
1608 :
1609 : /* Front-end wrappers for pragma registration to avoid dragging
1610 : cpplib.h in almost everywhere. */
1611 :
1612 : static void
1613 3698656 : c_register_pragma_1 (const char *space, const char *name,
1614 : internal_pragma_handler ihandler, bool allow_expansion)
1615 : {
1616 3698656 : unsigned id;
1617 :
1618 3698656 : pragma_data data;
1619 3698656 : data.space = space;
1620 3698656 : data.name = name;
1621 :
1622 3698656 : if (flag_preprocess_only
1623 101505 : && (cpp_get_options (parse_in)->directives_only
1624 100080 : || !(allow_expansion || ihandler.early_handler.handler_1arg)))
1625 48129 : return;
1626 :
1627 3650527 : data.ihandler = ihandler;
1628 3650527 : registered_pragmas.safe_push (data);
1629 3650527 : id = registered_pragmas.length ();
1630 7301054 : id += PRAGMA_FIRST_EXTERNAL - 1;
1631 :
1632 : /* The C front end allocates 8 bits in c_token. The C++ front end
1633 : keeps the pragma kind in the form of INTEGER_CST, so no small
1634 : limit applies. At present this is sufficient. */
1635 3650527 : gcc_assert (id < 256);
1636 :
1637 3650527 : cpp_register_deferred_pragma (parse_in, space, name, id,
1638 : allow_expansion, false);
1639 : }
1640 :
1641 : /* Register a C pragma handler, using a space and a name. It disallows pragma
1642 : expansion (if you want it, use c_register_pragma_with_expansion instead). */
1643 : void
1644 2033336 : c_register_pragma (const char *space, const char *name,
1645 : pragma_handler_1arg handler)
1646 : {
1647 2033336 : c_register_pragma_with_early_handler (space, name, handler, nullptr);
1648 2033336 : }
1649 3282326 : void c_register_pragma_with_early_handler (const char *space, const char *name,
1650 : pragma_handler_1arg handler,
1651 : pragma_handler_1arg early_handler)
1652 : {
1653 3282326 : internal_pragma_handler ihandler;
1654 :
1655 3282326 : ihandler.handler.handler_1arg = handler;
1656 3282326 : ihandler.early_handler.handler_1arg = early_handler;
1657 3282326 : ihandler.extra_data = false;
1658 3282326 : ihandler.data = NULL;
1659 3282326 : c_register_pragma_1 (space, name, ihandler, false);
1660 3282326 : }
1661 :
1662 : /* Register a C pragma handler, using a space and a name, it also carries an
1663 : extra data field which can be used by the handler. It disallows pragma
1664 : expansion (if you want it, use c_register_pragma_with_expansion_and_data
1665 : instead). */
1666 : void
1667 0 : c_register_pragma_with_data (const char *space, const char *name,
1668 : pragma_handler_2arg handler, void * data)
1669 : {
1670 0 : internal_pragma_handler ihandler;
1671 :
1672 0 : ihandler.handler.handler_2arg = handler;
1673 0 : ihandler.early_handler.handler_2arg = nullptr;
1674 0 : ihandler.extra_data = true;
1675 0 : ihandler.data = data;
1676 0 : c_register_pragma_1 (space, name, ihandler, false);
1677 0 : }
1678 :
1679 : /* Register a C pragma handler, using a space and a name. It allows pragma
1680 : expansion as in the following example:
1681 :
1682 : #define NUMBER 10
1683 : #pragma count (NUMBER)
1684 :
1685 : Name expansion is still disallowed. */
1686 : void
1687 416330 : c_register_pragma_with_expansion (const char *space, const char *name,
1688 : pragma_handler_1arg handler)
1689 : {
1690 416330 : internal_pragma_handler ihandler;
1691 :
1692 416330 : ihandler.handler.handler_1arg = handler;
1693 416330 : ihandler.early_handler.handler_1arg = nullptr;
1694 416330 : ihandler.extra_data = false;
1695 416330 : ihandler.data = NULL;
1696 416330 : c_register_pragma_1 (space, name, ihandler, true);
1697 416330 : }
1698 :
1699 : /* Register a C pragma handler, using a space and a name, it also carries an
1700 : extra data field which can be used by the handler. It allows pragma
1701 : expansion as in the following example:
1702 :
1703 : #define NUMBER 10
1704 : #pragma count (NUMBER)
1705 :
1706 : Name expansion is still disallowed. */
1707 : void
1708 0 : c_register_pragma_with_expansion_and_data (const char *space, const char *name,
1709 : pragma_handler_2arg handler,
1710 : void *data)
1711 : {
1712 0 : internal_pragma_handler ihandler;
1713 :
1714 0 : ihandler.handler.handler_2arg = handler;
1715 0 : ihandler.early_handler.handler_2arg = nullptr;
1716 0 : ihandler.extra_data = true;
1717 0 : ihandler.data = data;
1718 0 : c_register_pragma_1 (space, name, ihandler, true);
1719 0 : }
1720 :
1721 : void
1722 8665385 : c_invoke_pragma_handler (unsigned int id)
1723 : {
1724 8665385 : internal_pragma_handler *ihandler;
1725 8665385 : pragma_handler_1arg handler_1arg;
1726 8665385 : pragma_handler_2arg handler_2arg;
1727 :
1728 8665385 : id -= PRAGMA_FIRST_EXTERNAL;
1729 8665385 : ihandler = ®istered_pragmas[id].ihandler;
1730 8665385 : if (ihandler->extra_data)
1731 : {
1732 0 : handler_2arg = ihandler->handler.handler_2arg;
1733 0 : handler_2arg (parse_in, ihandler->data);
1734 : }
1735 : else
1736 : {
1737 8665385 : handler_1arg = ihandler->handler.handler_1arg;
1738 8665385 : handler_1arg (parse_in);
1739 : }
1740 8665385 : }
1741 :
1742 : /* In contrast to the normal handler, the early handler is optional. */
1743 : void
1744 6771094 : c_invoke_early_pragma_handler (unsigned int id)
1745 : {
1746 6771094 : internal_pragma_handler *ihandler;
1747 6771094 : pragma_handler_1arg handler_1arg;
1748 6771094 : pragma_handler_2arg handler_2arg;
1749 :
1750 6771094 : id -= PRAGMA_FIRST_EXTERNAL;
1751 6771094 : ihandler = ®istered_pragmas[id].ihandler;
1752 6771094 : if (ihandler->extra_data)
1753 : {
1754 0 : handler_2arg = ihandler->early_handler.handler_2arg;
1755 0 : if (handler_2arg)
1756 0 : handler_2arg (parse_in, ihandler->data);
1757 : }
1758 : else
1759 : {
1760 6771094 : handler_1arg = ihandler->early_handler.handler_1arg;
1761 6771094 : if (handler_1arg)
1762 6536390 : handler_1arg (parse_in);
1763 : }
1764 6771094 : }
1765 :
1766 : void
1767 33290 : c_pp_invoke_early_pragma_handler (unsigned int id)
1768 : {
1769 33290 : const auto data = ®istered_pragmas[id - PRAGMA_FIRST_EXTERNAL];
1770 33290 : pragma_handler_1arg handler = data->ihandler.early_handler.handler_1arg;
1771 33290 : if (handler)
1772 : {
1773 33272 : handler (parse_in);
1774 33272 : pragma_lex_discard_to_eol ();
1775 : }
1776 33290 : }
1777 :
1778 : /* Set up front-end pragmas. */
1779 : void
1780 208165 : init_pragma (void)
1781 : {
1782 :
1783 208165 : if (!cpp_get_options (parse_in)->directives_only)
1784 : {
1785 208037 : if (flag_openacc)
1786 : {
1787 : const int n_oacc_pragmas = ARRAY_SIZE (oacc_pragmas);
1788 : int i;
1789 :
1790 25110 : for (i = 0; i < n_oacc_pragmas; ++i)
1791 23436 : cpp_register_deferred_pragma (parse_in, "acc", oacc_pragmas[i].name,
1792 23436 : oacc_pragmas[i].id, true, true);
1793 : }
1794 :
1795 208037 : if (flag_openmp)
1796 : {
1797 : const int n_omp_pragmas = ARRAY_SIZE (omp_pragmas);
1798 : int i;
1799 :
1800 177268 : for (i = 0; i < n_omp_pragmas; ++i)
1801 170937 : cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name,
1802 170937 : omp_pragmas[i].id, true, true);
1803 : }
1804 208037 : if (flag_openmp || flag_openmp_simd)
1805 : {
1806 : const int n_omp_pragmas_simd = ARRAY_SIZE (omp_pragmas_simd);
1807 : int i;
1808 :
1809 114818 : for (i = 0; i < n_omp_pragmas_simd; ++i)
1810 108064 : cpp_register_deferred_pragma (parse_in, "omp",
1811 108064 : omp_pragmas_simd[i].name,
1812 108064 : omp_pragmas_simd[i].id, true, true);
1813 : }
1814 : }
1815 :
1816 208165 : if (!flag_preprocess_only)
1817 201398 : cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
1818 : PRAGMA_GCC_PCH_PREPROCESS, false, false);
1819 :
1820 208165 : if (!flag_preprocess_only)
1821 201398 : cpp_register_deferred_pragma (parse_in, "GCC", "ivdep", PRAGMA_IVDEP, false,
1822 : false);
1823 :
1824 208165 : if (!flag_preprocess_only)
1825 201398 : cpp_register_deferred_pragma (parse_in, "GCC", "unroll", PRAGMA_UNROLL,
1826 : false, false);
1827 :
1828 208165 : if (!flag_preprocess_only)
1829 201398 : cpp_register_deferred_pragma (parse_in, "GCC", "novector", PRAGMA_NOVECTOR,
1830 : false, false);
1831 :
1832 : #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
1833 : c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
1834 : #else
1835 208165 : c_register_pragma (0, "pack", handle_pragma_pack);
1836 : #endif
1837 208165 : c_register_pragma (0, "weak", handle_pragma_weak);
1838 :
1839 208165 : c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
1840 :
1841 208165 : if (flag_preprocess_only)
1842 6767 : c_register_pragma_with_early_handler ("GCC", "diagnostic",
1843 : nullptr,
1844 : handle_pragma_diagnostic_early_pp);
1845 : else
1846 201398 : c_register_pragma_with_early_handler ("GCC", "diagnostic",
1847 : handle_pragma_diagnostic,
1848 : handle_pragma_diagnostic_early);
1849 208165 : c_register_pragma_with_early_handler ("GCC", "target",
1850 : handle_pragma_target,
1851 : handle_pragma_target);
1852 208165 : c_register_pragma_with_early_handler ("GCC", "optimize",
1853 : handle_pragma_optimize,
1854 : handle_pragma_optimize);
1855 208165 : c_register_pragma_with_early_handler ("GCC", "push_options",
1856 : handle_pragma_push_options,
1857 : handle_pragma_push_options);
1858 208165 : c_register_pragma_with_early_handler ("GCC", "pop_options",
1859 : handle_pragma_pop_options,
1860 : handle_pragma_pop_options);
1861 208165 : c_register_pragma_with_early_handler ("GCC", "reset_options",
1862 : handle_pragma_reset_options,
1863 : handle_pragma_reset_options);
1864 :
1865 208165 : c_register_pragma (0, "region", handle_pragma_ignore);
1866 208165 : c_register_pragma (0, "endregion", handle_pragma_ignore);
1867 :
1868 208165 : c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
1869 : handle_pragma_float_const_decimal64);
1870 :
1871 208165 : c_register_pragma_with_expansion (0, "redefine_extname",
1872 : handle_pragma_redefine_extname);
1873 :
1874 208165 : c_register_pragma_with_expansion (0, "message", handle_pragma_message);
1875 :
1876 : #ifdef REGISTER_TARGET_PRAGMAS
1877 208165 : REGISTER_TARGET_PRAGMAS ();
1878 : #endif
1879 :
1880 208165 : global_sso = default_sso;
1881 208165 : c_register_pragma (0, "scalar_storage_order",
1882 : handle_pragma_scalar_storage_order);
1883 :
1884 : /* Allow plugins to register their own pragmas. */
1885 208165 : invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL);
1886 208165 : }
1887 :
1888 : #include "gt-c-family-c-pragma.h"
|