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 51 : 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 248832186 : maybe_apply_pragma_weak (tree decl)
277 : {
278 248832186 : tree id;
279 248832186 : int i;
280 248832186 : 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 248832186 : if (vec_safe_is_empty (pending_weaks))
286 : 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 205231 : maybe_apply_pending_pragma_weaks (void)
318 : {
319 205231 : tree alias_id, id, decl;
320 205231 : int i;
321 205231 : pending_weak *pe;
322 205231 : symtab_node *target;
323 :
324 205231 : if (vec_safe_is_empty (pending_weaks))
325 205231 : 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 1185245 : maybe_apply_pragma_scalar_storage_order (tree type)
403 : {
404 1185245 : if (global_sso == SSO_NATIVE)
405 : return;
406 :
407 12 : gcc_assert (RECORD_OR_UNION_TYPE_P (type));
408 :
409 12 : if (lookup_attribute ("scalar_storage_order", TYPE_ATTRIBUTES (type)))
410 : return;
411 :
412 10 : if (global_sso == SSO_BIG_ENDIAN)
413 6 : 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 13 : handle_pragma_scalar_storage_order (cpp_reader *)
422 : {
423 13 : const char *kind_string;
424 13 : enum cpp_ttype token;
425 13 : tree x;
426 :
427 13 : 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 13 : 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 : return;
440 : }
441 :
442 10 : token = pragma_lex (&x);
443 10 : if (token != CPP_NAME)
444 1 : GCC_BAD ("missing %<big-endian%>, %<little-endian%>, or %<default%> after "
445 : "%<#pragma scalar_storage_order%>");
446 9 : kind_string = IDENTIFIER_POINTER (x);
447 9 : if (strcmp (kind_string, "default") == 0)
448 3 : global_sso = default_sso;
449 6 : else if (strcmp (kind_string, "big") == 0)
450 3 : global_sso = SSO_BIG_ENDIAN;
451 3 : else if (strcmp (kind_string, "little") == 0)
452 2 : global_sso = SSO_LITTLE_ENDIAN;
453 : else
454 9 : 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 30 : handle_pragma_redefine_extname (cpp_reader *)
503 : {
504 30 : tree oldname, newname, decls, x;
505 30 : enum cpp_ttype t;
506 30 : bool found;
507 :
508 30 : if (pragma_lex (&oldname) != CPP_NAME)
509 7 : 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 89729284 : maybe_apply_renaming_pragma (tree decl, tree asmname)
587 : {
588 89729284 : unsigned ix;
589 89729284 : pending_redefinition *p;
590 :
591 : /* The renaming pragmas are only applied to declarations with
592 : external linkage. */
593 64313083 : if (!VAR_OR_FUNCTION_DECL_P (decl)
594 79635844 : || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
595 169245974 : || !has_c_linkage (decl))
596 : 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 45956559 : if (DECL_ASSEMBLER_NAME_SET_P (decl))
601 : {
602 4584 : const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
603 4584 : oldname = targetm.strip_name_encoding (oldname);
604 :
605 5163 : 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 4587 : 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 : return NULL_TREE;
622 : }
623 :
624 : /* Find out if we have a pending #pragma redefine_extname. */
625 45951988 : 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 : 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 45951963 : if (asmname)
650 : return asmname;
651 :
652 : /* If #pragma extern_prefix is in effect, apply it. */
653 44490130 : 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 3348826 : push_visibility (const char *str, int kind)
687 : {
688 3348826 : visstack.safe_push (((int) default_visibility) | (kind << 8));
689 3348826 : if (!strcmp (str, "default"))
690 3347227 : default_visibility = VISIBILITY_DEFAULT;
691 1599 : else if (!strcmp (str, "internal"))
692 0 : default_visibility = VISIBILITY_INTERNAL;
693 1599 : else if (!strcmp (str, "hidden"))
694 1599 : 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 3348826 : visibility_options.inpragma = 1;
701 : }
702 :
703 : /* Pop a level of the #pragma visibility stack. Return true if
704 : successful. */
705 :
706 : bool
707 3348810 : pop_visibility (int kind)
708 : {
709 3348810 : if (!visstack.length ())
710 : return false;
711 3348810 : if ((visstack.last () >> 8) != kind)
712 : return false;
713 3348807 : default_visibility
714 3348807 : = (enum symbol_visibility) (visstack.pop () & 0xff);
715 3348807 : visibility_options.inpragma
716 3348807 : = visstack.length () != 0;
717 3348807 : 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 255928 : handle_pragma_visibility (cpp_reader *)
725 : {
726 : /* Form is #pragma GCC visibility push(hidden)|pop */
727 255928 : tree x;
728 255928 : enum cpp_ttype token;
729 255928 : enum { bad, push, pop } action = bad;
730 :
731 255928 : token = pragma_lex (&x);
732 255928 : if (token == CPP_NAME)
733 : {
734 255928 : const char *op = IDENTIFIER_POINTER (x);
735 255928 : if (!strcmp (op, "push"))
736 : action = push;
737 127956 : 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 255928 : if (pop == action)
746 : {
747 127956 : if (! pop_visibility (0))
748 3 : GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
749 : }
750 : else
751 : {
752 127972 : if (pragma_lex (&x) != CPP_OPEN_PAREN)
753 0 : GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
754 127972 : token = pragma_lex (&x);
755 127972 : if (token != CPP_NAME)
756 0 : GCC_BAD ("malformed %<#pragma GCC visibility push%>");
757 : else
758 127972 : push_visibility (IDENTIFIER_POINTER (x), 0);
759 127972 : if (pragma_lex (&x) != CPP_CLOSE_PAREN)
760 0 : GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
761 : }
762 : }
763 255925 : 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 15349862 : pragma_diagnostic_data () { clear (); }
790 30699724 : void clear ()
791 : {
792 30699724 : valid = false;
793 30699724 : loc_kind = loc_option = UNKNOWN_LOCATION;
794 30699724 : pd_kind = PK_INVALID;
795 30699724 : diagnostic_kind = diagnostics::kind::unspecified;
796 30699724 : kind_str = option_str = nullptr;
797 30699724 : own_option_str = false;
798 : }
799 :
800 15349862 : ~pragma_diagnostic_data ()
801 : {
802 15349862 : if (own_option_str && option_str)
803 0 : XDELETEVEC (const_cast<char *> (option_str));
804 15349862 : }
805 :
806 15349852 : void set_kind (const char *kind_string)
807 : {
808 15349852 : kind_str = kind_string;
809 :
810 15349852 : pd_kind = PK_INVALID;
811 15349852 : diagnostic_kind = diagnostics::kind::unspecified;
812 15349852 : if (strcmp (kind_str, "push") == 0)
813 4904817 : pd_kind = PK_PUSH;
814 10445035 : else if (strcmp (kind_str, "pop") == 0)
815 4904126 : pd_kind = PK_POP;
816 5540909 : else if (strcmp (kind_str, "ignored_attributes") == 0)
817 77 : pd_kind = PK_IGNORED_ATTRIBUTES;
818 5540832 : else if (strcmp (kind_str, "error") == 0)
819 : {
820 63 : pd_kind = PK_DIAGNOSTIC;
821 63 : diagnostic_kind = diagnostics::kind::error;
822 : }
823 5540769 : else if (strcmp (kind_str, "warning") == 0)
824 : {
825 63 : pd_kind = PK_DIAGNOSTIC;
826 63 : diagnostic_kind = diagnostics::kind::warning;
827 : }
828 5540706 : else if (strcmp (kind_str, "ignored") == 0)
829 : {
830 5540698 : pd_kind = PK_DIAGNOSTIC;
831 5540698 : diagnostic_kind = diagnostics::kind::ignored;
832 : }
833 15349852 : }
834 :
835 15349844 : bool needs_option () const
836 : {
837 15349844 : return pd_kind == PK_IGNORED_ATTRIBUTES
838 15349844 : || 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 15349862 : pragma_diagnostic_lex (pragma_diagnostic_data *result)
848 : {
849 15349862 : result->clear ();
850 15349862 : tree x;
851 15349862 : auto ttype = pragma_lex (&x, &result->loc_kind);
852 15349862 : if (ttype != CPP_NAME)
853 18 : return;
854 15349852 : result->set_kind (IDENTIFIER_POINTER (x));
855 15349852 : if (result->pd_kind == pragma_diagnostic_data::PK_INVALID)
856 : return;
857 :
858 15349844 : if (result->needs_option ())
859 : {
860 5540901 : ttype = pragma_lex (&x, &result->loc_option);
861 5540901 : if (ttype != CPP_STRING)
862 : return;
863 5540901 : result->option_str = TREE_STRING_POINTER (x);
864 : }
865 :
866 15349844 : 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 15349862 : handle_pragma_diagnostic_impl ()
875 : {
876 : static const bool want_diagnostics = (is_pp || !early);
877 :
878 15349862 : pragma_diagnostic_data data;
879 15349862 : pragma_diagnostic_lex (&data);
880 :
881 15349862 : 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 15349852 : switch (data.pd_kind)
892 : {
893 :
894 4904817 : case pragma_diagnostic_data::PK_PUSH:
895 4904817 : diagnostic_push_diagnostics (global_dc, input_location);
896 4904817 : return;
897 :
898 4904126 : case pragma_diagnostic_data::PK_POP:
899 4904126 : diagnostic_pop_diagnostics (global_dc, input_location);
900 4904126 : 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 5540824 : case pragma_diagnostic_data::PK_DIAGNOSTIC:
940 5540824 : 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 5540824 : gcc_assert (data.valid);
961 :
962 5540824 : unsigned int lang_mask = c_common_option_lang_mask () | CL_COMMON;
963 : /* option_string + 1 to skip the initial '-' */
964 5540824 : unsigned int option_index = find_opt (data.option_str + 1, lang_mask);
965 :
966 2718848 : if (early && !(c_option_is_from_cpp_diagnostics (option_index)
967 2718848 : || option_index == OPT_Wunknown_pragmas))
968 : return;
969 :
970 4525447 : 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 4525436 : 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 4525425 : 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 4525424 : const char *arg = NULL;
1010 4525424 : 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 4525424 : 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 4525424 : control_warning_option (option_index, (int) data.diagnostic_kind,
1019 : arg,
1020 4525424 : data.diagnostic_kind != diagnostics::kind::ignored,
1021 : input_location, lang_mask, &handlers,
1022 : &global_options, &global_options_set,
1023 : global_dc);
1024 15349862 : }
1025 :
1026 : static void
1027 7831580 : handle_pragma_diagnostic (cpp_reader *)
1028 : {
1029 7831580 : handle_pragma_diagnostic_impl<false, false> ();
1030 7831580 : }
1031 :
1032 : static void
1033 7485281 : handle_pragma_diagnostic_early (cpp_reader *)
1034 : {
1035 7485281 : handle_pragma_diagnostic_impl<true, false> ();
1036 7485281 : }
1037 :
1038 : static void
1039 33001 : handle_pragma_diagnostic_early_pp (cpp_reader *)
1040 : {
1041 33001 : handle_pragma_diagnostic_impl<true, true> ();
1042 33001 : }
1043 :
1044 : /* Parse #pragma GCC suppress_coverage begin|end to stop lines from contributing
1045 : towards (missing) coverage. */
1046 : static void
1047 698 : handle_pragma_suppress_coverage (cpp_reader*)
1048 : {
1049 698 : tree x;
1050 698 : location_t loc;
1051 698 : auto token = pragma_lex (&x);
1052 698 : enum { bad, begin, end } action = bad;
1053 :
1054 698 : if (token == CPP_NAME)
1055 : {
1056 697 : const char *op = IDENTIFIER_POINTER (x);
1057 697 : if (!strcmp (op, "begin"))
1058 : action = begin;
1059 348 : else if (!strcmp (op, "end"))
1060 : action = end;
1061 : }
1062 :
1063 : if (bad == action)
1064 4 : GCC_BAD ("%<#pragma GCC suppress_coverage%> must be followed by %<begin%> "
1065 : "or %<end%>");
1066 697 : else if (end == action)
1067 : {
1068 348 : if (!suppress_coverage_end (input_location))
1069 1 : GCC_BAD ("no matching begin for %<#pragma GCC suppress_coverage end%>");
1070 : }
1071 : else
1072 : {
1073 349 : if (!suppress_coverage_begin (input_location))
1074 1 : GCC_BAD ("%<#pragma GCC suppress_coverage begin%> "
1075 : "was already in effect, ignored");
1076 : }
1077 695 : if (pragma_lex (&x, &loc) != CPP_EOF)
1078 695 : GCC_BAD_AT (loc, "junk at end of %<#pragma GCC suppress_coverage%>");
1079 : }
1080 :
1081 : /* Parse #pragma GCC target (xxx) to set target specific options. */
1082 : static void
1083 561932 : handle_pragma_target(cpp_reader *)
1084 : {
1085 561932 : location_t loc;
1086 561932 : enum cpp_ttype token;
1087 561932 : tree x;
1088 561932 : bool close_paren_needed_p = false;
1089 :
1090 561932 : if (cfun)
1091 : {
1092 0 : error ("%<#pragma GCC option%> is not allowed inside functions");
1093 2 : return;
1094 : }
1095 :
1096 561932 : token = pragma_lex (&x, &loc);
1097 561932 : if (token == CPP_OPEN_PAREN)
1098 : {
1099 561876 : close_paren_needed_p = true;
1100 561876 : token = pragma_lex (&x, &loc);
1101 : }
1102 :
1103 561932 : if (token != CPP_STRING)
1104 2 : GCC_BAD_AT (loc, "%<#pragma GCC option%> is not a string");
1105 :
1106 : /* Strings are user options. */
1107 : else
1108 : {
1109 : tree args = NULL_TREE;
1110 :
1111 561948 : do
1112 : {
1113 : /* Build up the strings now as a tree linked list. Skip empty
1114 : strings. */
1115 561948 : if (TREE_STRING_LENGTH (x) > 0)
1116 561948 : args = tree_cons (NULL_TREE, x, args);
1117 :
1118 561948 : token = pragma_lex (&x);
1119 1123914 : while (token == CPP_COMMA)
1120 18 : token = pragma_lex (&x);
1121 : }
1122 561948 : while (token == CPP_STRING);
1123 :
1124 561930 : if (close_paren_needed_p)
1125 : {
1126 561875 : if (token == CPP_CLOSE_PAREN)
1127 561875 : token = pragma_lex (&x);
1128 : else
1129 561875 : GCC_BAD ("%<#pragma GCC target (string [,string]...)%> does "
1130 : "not have a final %<)%>");
1131 : }
1132 :
1133 561930 : if (token != CPP_EOF)
1134 : {
1135 0 : error ("%<#pragma GCC target%> string is badly formed");
1136 0 : return;
1137 : }
1138 :
1139 : /* put arguments in the order the user typed them. */
1140 561930 : args = nreverse (args);
1141 :
1142 561930 : if (targetm.target_option.pragma_parse (args, NULL_TREE))
1143 561661 : current_target_pragma = chainon (current_target_pragma, args);
1144 :
1145 : /* A target pragma can also influence optimization options. */
1146 561930 : tree current_optimize
1147 561930 : = build_optimization_node (&global_options, &global_options_set);
1148 561930 : if (current_optimize != optimization_current_node)
1149 78 : optimization_current_node = current_optimize;
1150 : }
1151 : }
1152 :
1153 : /* Handle #pragma GCC optimize to set optimization options. */
1154 : static void
1155 533 : handle_pragma_optimize (cpp_reader *)
1156 : {
1157 533 : enum cpp_ttype token;
1158 533 : tree x;
1159 533 : bool close_paren_needed_p = false;
1160 533 : tree optimization_previous_node = optimization_current_node;
1161 :
1162 533 : if (cfun)
1163 : {
1164 0 : error ("%<#pragma GCC optimize%> is not allowed inside functions");
1165 0 : return;
1166 : }
1167 :
1168 533 : token = pragma_lex (&x);
1169 533 : if (token == CPP_OPEN_PAREN)
1170 : {
1171 126 : close_paren_needed_p = true;
1172 126 : token = pragma_lex (&x);
1173 : }
1174 :
1175 533 : if (token != CPP_STRING && token != CPP_NUMBER)
1176 0 : GCC_BAD ("%<#pragma GCC optimize%> is not a string or number");
1177 :
1178 : /* Strings/numbers are user options. */
1179 : else
1180 : {
1181 : tree args = NULL_TREE;
1182 :
1183 549 : do
1184 : {
1185 : /* Build up the numbers/strings now as a list. */
1186 549 : if (token != CPP_STRING || TREE_STRING_LENGTH (x) > 0)
1187 549 : args = tree_cons (NULL_TREE, x, args);
1188 :
1189 549 : token = pragma_lex (&x);
1190 1114 : while (token == CPP_COMMA)
1191 16 : token = pragma_lex (&x);
1192 : }
1193 549 : while (token == CPP_STRING || token == CPP_NUMBER);
1194 :
1195 533 : if (close_paren_needed_p)
1196 : {
1197 126 : if (token == CPP_CLOSE_PAREN)
1198 126 : token = pragma_lex (&x);
1199 : else
1200 126 : GCC_BAD ("%<#pragma GCC optimize (string [,string]...)%> does "
1201 : "not have a final %<)%>");
1202 : }
1203 :
1204 533 : if (token != CPP_EOF)
1205 : {
1206 0 : error ("%<#pragma GCC optimize%> string is badly formed");
1207 0 : return;
1208 : }
1209 :
1210 : /* put arguments in the order the user typed them. */
1211 533 : args = nreverse (args);
1212 :
1213 533 : parse_optimize_options (args, false);
1214 533 : current_optimize_pragma = chainon (current_optimize_pragma, args);
1215 533 : optimization_current_node
1216 533 : = build_optimization_node (&global_options, &global_options_set);
1217 533 : c_cpp_builtins_optimize_pragma (parse_in,
1218 : optimization_previous_node,
1219 : optimization_current_node);
1220 : }
1221 : }
1222 :
1223 : /* Stack of the #pragma GCC options created with #pragma GCC push_option. Save
1224 : both the binary representation of the options and the TREE_LIST of
1225 : strings that will be added to the function's attribute list. */
1226 : struct GTY(()) opt_stack {
1227 : struct opt_stack *prev;
1228 : tree target_binary;
1229 : tree target_strings;
1230 : tree optimize_binary;
1231 : tree optimize_strings;
1232 : gcc_options * GTY ((skip)) saved_global_options;
1233 : };
1234 :
1235 : static GTY(()) struct opt_stack * options_stack;
1236 :
1237 : /* Handle #pragma GCC push_options to save the current target and optimization
1238 : options. */
1239 :
1240 : static void
1241 562142 : handle_pragma_push_options (cpp_reader *)
1242 : {
1243 562142 : enum cpp_ttype token;
1244 562142 : tree x = 0;
1245 :
1246 562142 : token = pragma_lex (&x);
1247 562142 : if (token != CPP_EOF)
1248 : {
1249 0 : warning (OPT_Wpragmas, "junk at end of %<#pragma GCC push_options%>");
1250 0 : return;
1251 : }
1252 :
1253 562142 : opt_stack *p = ggc_alloc<opt_stack> ();
1254 562142 : p->prev = options_stack;
1255 562142 : options_stack = p;
1256 :
1257 : /* Save optimization and target flags in binary format. */
1258 562142 : if (flag_checking)
1259 : {
1260 562142 : p->saved_global_options = XNEW (gcc_options);
1261 562142 : *p->saved_global_options = global_options;
1262 : }
1263 562142 : p->optimize_binary = build_optimization_node (&global_options,
1264 : &global_options_set);
1265 562142 : p->target_binary = build_target_option_node (&global_options,
1266 : &global_options_set);
1267 :
1268 : /* Save optimization and target flags in string list format. */
1269 562142 : p->optimize_strings = copy_list (current_optimize_pragma);
1270 562142 : p->target_strings = copy_list (current_target_pragma);
1271 : }
1272 :
1273 : /* Handle #pragma GCC pop_options to restore the current target and
1274 : optimization options from a previous push_options. */
1275 :
1276 : static void
1277 562141 : handle_pragma_pop_options (cpp_reader *)
1278 : {
1279 562141 : enum cpp_ttype token;
1280 562141 : tree x = 0;
1281 562141 : opt_stack *p;
1282 :
1283 562141 : token = pragma_lex (&x);
1284 562141 : if (token != CPP_EOF)
1285 : {
1286 0 : warning (OPT_Wpragmas, "junk at end of %<#pragma GCC pop_options%>");
1287 0 : return;
1288 : }
1289 :
1290 562141 : if (! options_stack)
1291 : {
1292 0 : warning (OPT_Wpragmas,
1293 : "%<#pragma GCC pop_options%> without a corresponding "
1294 : "%<#pragma GCC push_options%>");
1295 0 : return;
1296 : }
1297 :
1298 562141 : p = options_stack;
1299 562141 : options_stack = p->prev;
1300 :
1301 562141 : if (p->target_binary != target_option_current_node)
1302 : {
1303 556929 : (void) targetm.target_option.pragma_parse (NULL_TREE, p->target_binary);
1304 556929 : target_option_current_node = p->target_binary;
1305 : }
1306 :
1307 : /* Always restore optimization options as optimization_current_node is
1308 : * overwritten by invoke_set_current_function_hook. */
1309 1124282 : cl_optimization_restore (&global_options, &global_options_set,
1310 562141 : TREE_OPTIMIZATION (p->optimize_binary));
1311 1124282 : cl_target_option_restore (&global_options, &global_options_set,
1312 562141 : TREE_TARGET_OPTION (p->target_binary));
1313 :
1314 562141 : if (p->optimize_binary != optimization_current_node)
1315 : {
1316 52 : c_cpp_builtins_optimize_pragma (parse_in, optimization_current_node,
1317 : p->optimize_binary);
1318 52 : optimization_current_node = p->optimize_binary;
1319 : }
1320 562141 : if (flag_checking && !seen_error ())
1321 : {
1322 562137 : cl_optimization_compare (p->saved_global_options, &global_options);
1323 562137 : free (p->saved_global_options);
1324 : }
1325 :
1326 562141 : current_target_pragma = p->target_strings;
1327 562141 : current_optimize_pragma = p->optimize_strings;
1328 : }
1329 :
1330 : /* This is mostly a helper for handle_pragma_reset_options () to do the actual
1331 : work, but the C++ frontend, for example, needs an external interface to
1332 : perform this operation, since it processes target pragmas twice. (Once for
1333 : preprocessing purposes, and then again during compilation.) */
1334 :
1335 : void
1336 99222 : c_reset_target_pragmas ()
1337 : {
1338 99222 : tree new_optimize = optimization_default_node;
1339 99222 : tree new_target = target_option_default_node;
1340 99222 : if (new_target != target_option_current_node)
1341 : {
1342 41 : (void) targetm.target_option.pragma_parse (NULL_TREE, new_target);
1343 41 : target_option_current_node = new_target;
1344 : }
1345 :
1346 99222 : if (new_optimize != optimization_current_node)
1347 : {
1348 49 : tree old_optimize = optimization_current_node;
1349 49 : cl_optimization_restore (&global_options, &global_options_set,
1350 49 : TREE_OPTIMIZATION (new_optimize));
1351 49 : c_cpp_builtins_optimize_pragma (parse_in, old_optimize, new_optimize);
1352 49 : optimization_current_node = new_optimize;
1353 : }
1354 :
1355 99222 : current_target_pragma = NULL_TREE;
1356 99222 : current_optimize_pragma = NULL_TREE;
1357 99222 : }
1358 :
1359 : /* Handle #pragma GCC reset_options to restore the current target and
1360 : optimization options to the original options used on the command line. */
1361 :
1362 : static void
1363 4 : handle_pragma_reset_options (cpp_reader *)
1364 : {
1365 4 : tree x;
1366 4 : if (pragma_lex (&x) != CPP_EOF)
1367 0 : warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>");
1368 : else
1369 4 : c_reset_target_pragmas ();
1370 4 : }
1371 :
1372 : /* Print a plain user-specified message. */
1373 :
1374 : static void
1375 56 : handle_pragma_message (cpp_reader *)
1376 : {
1377 56 : location_t loc;
1378 56 : enum cpp_ttype token;
1379 56 : tree x, message = 0;
1380 :
1381 56 : token = pragma_lex (&x);
1382 56 : if (token == CPP_OPEN_PAREN)
1383 : {
1384 21 : token = pragma_lex (&x);
1385 21 : if (token == CPP_STRING)
1386 14 : message = x;
1387 : else
1388 20 : GCC_BAD ("expected a string after %<#pragma message%>");
1389 14 : if (pragma_lex (&x) != CPP_CLOSE_PAREN)
1390 1 : GCC_BAD ("malformed %<#pragma message%>, ignored");
1391 : }
1392 35 : else if (token == CPP_STRING)
1393 23 : message = x;
1394 12 : else if (token == CPP_STRING_USERDEF)
1395 3 : GCC_BAD ("string literal with user-defined suffix is invalid in this "
1396 : "context");
1397 : else
1398 9 : GCC_BAD ("expected a string after %<#pragma message%>");
1399 :
1400 36 : gcc_assert (message);
1401 :
1402 36 : if (pragma_lex (&x, &loc) != CPP_EOF)
1403 3 : warning_at (loc, OPT_Wpragmas, "junk at end of %<#pragma message%>");
1404 :
1405 36 : if (TREE_STRING_LENGTH (message) > 1)
1406 32 : inform (input_location, "%<#pragma message: %s%>",
1407 32 : TREE_STRING_POINTER (message));
1408 : }
1409 :
1410 : /* Ignore a no-op pragma that GCC recognizes, but which has no effect. */
1411 : static void
1412 16 : handle_pragma_ignore (cpp_reader *)
1413 : {
1414 16 : }
1415 :
1416 : /* Mark whether the current location is valid for a STDC pragma. */
1417 :
1418 : static bool valid_location_for_stdc_pragma;
1419 :
1420 : void
1421 131205115 : mark_valid_location_for_stdc_pragma (bool flag)
1422 : {
1423 131205115 : valid_location_for_stdc_pragma = flag;
1424 131205115 : }
1425 :
1426 : /* Return true if the current location is valid for a STDC pragma. */
1427 :
1428 : bool
1429 38290864 : valid_location_for_stdc_pragma_p (void)
1430 : {
1431 38290864 : return valid_location_for_stdc_pragma;
1432 : }
1433 :
1434 : enum pragma_switch_t { PRAGMA_ON, PRAGMA_OFF, PRAGMA_DEFAULT, PRAGMA_BAD };
1435 :
1436 : /* A STDC pragma must appear outside of external declarations or
1437 : preceding all explicit declarations and statements inside a compound
1438 : statement; its behavior is undefined if used in any other context.
1439 : It takes a switch of ON, OFF, or DEFAULT. */
1440 :
1441 : static enum pragma_switch_t
1442 66 : handle_stdc_pragma (const char *pname)
1443 : {
1444 66 : const char *arg;
1445 66 : tree t;
1446 66 : enum pragma_switch_t ret;
1447 :
1448 66 : if (!valid_location_for_stdc_pragma_p ())
1449 : {
1450 12 : warning (OPT_Wpragmas, "invalid location for %<pragma %s%>, ignored",
1451 : pname);
1452 12 : return PRAGMA_BAD;
1453 : }
1454 :
1455 54 : if (pragma_lex (&t) != CPP_NAME)
1456 : {
1457 2 : warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
1458 2 : return PRAGMA_BAD;
1459 : }
1460 :
1461 52 : arg = IDENTIFIER_POINTER (t);
1462 :
1463 52 : if (!strcmp (arg, "ON"))
1464 : ret = PRAGMA_ON;
1465 30 : else if (!strcmp (arg, "OFF"))
1466 : ret = PRAGMA_OFF;
1467 11 : else if (!strcmp (arg, "DEFAULT"))
1468 : ret = PRAGMA_DEFAULT;
1469 : else
1470 : {
1471 2 : warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
1472 2 : return PRAGMA_BAD;
1473 : }
1474 :
1475 50 : if (pragma_lex (&t) != CPP_EOF)
1476 : {
1477 2 : warning (OPT_Wpragmas, "junk at end of %<#pragma %s%>", pname);
1478 2 : return PRAGMA_BAD;
1479 : }
1480 :
1481 : return ret;
1482 : }
1483 :
1484 : /* #pragma STDC FLOAT_CONST_DECIMAL64 ON
1485 : #pragma STDC FLOAT_CONST_DECIMAL64 OFF
1486 : #pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT */
1487 :
1488 : static void
1489 69 : handle_pragma_float_const_decimal64 (cpp_reader *)
1490 : {
1491 69 : if (c_dialect_cxx ())
1492 : {
1493 3 : if (warn_unknown_pragmas > in_system_header_at (input_location))
1494 3 : warning (OPT_Wunknown_pragmas,
1495 : "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
1496 : " for C++");
1497 : return;
1498 : }
1499 :
1500 66 : if (!targetm.decimal_float_supported_p ())
1501 : {
1502 0 : if (warn_unknown_pragmas > in_system_header_at (input_location))
1503 0 : warning (OPT_Wunknown_pragmas,
1504 : "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
1505 : " on this target");
1506 : return;
1507 : }
1508 :
1509 66 : pedwarn (input_location, OPT_Wpedantic,
1510 : "ISO C does not support %<#pragma STDC FLOAT_CONST_DECIMAL64%>");
1511 :
1512 66 : switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64"))
1513 : {
1514 20 : case PRAGMA_ON:
1515 20 : set_float_const_decimal64 ();
1516 20 : break;
1517 28 : case PRAGMA_OFF:
1518 28 : case PRAGMA_DEFAULT:
1519 28 : clear_float_const_decimal64 ();
1520 28 : break;
1521 : case PRAGMA_BAD:
1522 : break;
1523 : }
1524 : }
1525 :
1526 : /* A vector of registered pragma callbacks, which is never freed. */
1527 :
1528 :
1529 : struct pragma_data
1530 : {
1531 : const char *space;
1532 : const char *name;
1533 : struct internal_pragma_handler ihandler;
1534 : };
1535 :
1536 : static vec<pragma_data> registered_pragmas;
1537 :
1538 : struct omp_pragma_def { const char *name; unsigned int id; };
1539 : static const struct omp_pragma_def oacc_pragmas[] = {
1540 : { "atomic", PRAGMA_OACC_ATOMIC },
1541 : { "cache", PRAGMA_OACC_CACHE },
1542 : { "data", PRAGMA_OACC_DATA },
1543 : { "declare", PRAGMA_OACC_DECLARE },
1544 : { "enter", PRAGMA_OACC_ENTER_DATA },
1545 : { "exit", PRAGMA_OACC_EXIT_DATA },
1546 : { "host_data", PRAGMA_OACC_HOST_DATA },
1547 : { "kernels", PRAGMA_OACC_KERNELS },
1548 : { "loop", PRAGMA_OACC_LOOP },
1549 : { "parallel", PRAGMA_OACC_PARALLEL },
1550 : { "routine", PRAGMA_OACC_ROUTINE },
1551 : { "serial", PRAGMA_OACC_SERIAL },
1552 : { "update", PRAGMA_OACC_UPDATE },
1553 : { "wait", PRAGMA_OACC_WAIT }
1554 : };
1555 : static const struct omp_pragma_def omp_pragmas[] = {
1556 : { "allocate", PRAGMA_OMP_ALLOCATE },
1557 : { "assumes", PRAGMA_OMP_ASSUMES },
1558 : { "atomic", PRAGMA_OMP_ATOMIC },
1559 : { "barrier", PRAGMA_OMP_BARRIER },
1560 : { "begin", PRAGMA_OMP_BEGIN },
1561 : { "cancel", PRAGMA_OMP_CANCEL },
1562 : { "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
1563 : { "critical", PRAGMA_OMP_CRITICAL },
1564 : { "depobj", PRAGMA_OMP_DEPOBJ },
1565 : { "dispatch", PRAGMA_OMP_DISPATCH },
1566 : { "error", PRAGMA_OMP_ERROR },
1567 : { "end", PRAGMA_OMP_END },
1568 : { "flush", PRAGMA_OMP_FLUSH },
1569 : { "groupprivate", PRAGMA_OMP_GROUPPRIVATE },
1570 : { "interop", PRAGMA_OMP_INTEROP },
1571 : { "metadirective", PRAGMA_OMP_METADIRECTIVE },
1572 : { "nothing", PRAGMA_OMP_NOTHING },
1573 : { "requires", PRAGMA_OMP_REQUIRES },
1574 : { "scope", PRAGMA_OMP_SCOPE },
1575 : { "section", PRAGMA_OMP_SECTION },
1576 : { "sections", PRAGMA_OMP_SECTIONS },
1577 : { "single", PRAGMA_OMP_SINGLE },
1578 : { "task", PRAGMA_OMP_TASK },
1579 : { "taskgroup", PRAGMA_OMP_TASKGROUP },
1580 : { "taskwait", PRAGMA_OMP_TASKWAIT },
1581 : { "taskyield", PRAGMA_OMP_TASKYIELD },
1582 : { "threadprivate", PRAGMA_OMP_THREADPRIVATE }
1583 : };
1584 : static const struct omp_pragma_def omp_pragmas_simd[] = {
1585 : { "assume", PRAGMA_OMP_ASSUME },
1586 : { "declare", PRAGMA_OMP_DECLARE },
1587 : { "distribute", PRAGMA_OMP_DISTRIBUTE },
1588 : { "for", PRAGMA_OMP_FOR },
1589 : { "loop", PRAGMA_OMP_LOOP },
1590 : { "masked", PRAGMA_OMP_MASKED },
1591 : { "master", PRAGMA_OMP_MASTER },
1592 : { "ordered", PRAGMA_OMP_ORDERED },
1593 : { "parallel", PRAGMA_OMP_PARALLEL },
1594 : { "scan", PRAGMA_OMP_SCAN },
1595 : { "simd", PRAGMA_OMP_SIMD },
1596 : { "target", PRAGMA_OMP_TARGET },
1597 : { "taskloop", PRAGMA_OMP_TASKLOOP },
1598 : { "teams", PRAGMA_OMP_TEAMS },
1599 : { "tile", PRAGMA_OMP_TILE },
1600 : { "unroll", PRAGMA_OMP_UNROLL },
1601 : };
1602 :
1603 : void
1604 40541 : c_pp_lookup_pragma (unsigned int id, const char **space, const char **name)
1605 : {
1606 40541 : const int n_oacc_pragmas = ARRAY_SIZE (oacc_pragmas);
1607 40541 : const int n_omp_pragmas = ARRAY_SIZE (omp_pragmas);
1608 40541 : const int n_omp_pragmas_simd = ARRAY_SIZE (omp_pragmas_simd);
1609 40541 : int i;
1610 :
1611 608115 : for (i = 0; i < n_oacc_pragmas; ++i)
1612 567574 : if (oacc_pragmas[i].id == id)
1613 : {
1614 0 : *space = "acc";
1615 0 : *name = oacc_pragmas[i].name;
1616 0 : return;
1617 : }
1618 :
1619 1134926 : for (i = 0; i < n_omp_pragmas; ++i)
1620 1094413 : if (omp_pragmas[i].id == id)
1621 : {
1622 28 : *space = "omp";
1623 28 : *name = omp_pragmas[i].name;
1624 28 : return;
1625 : }
1626 :
1627 688151 : for (i = 0; i < n_omp_pragmas_simd; ++i)
1628 647704 : if (omp_pragmas_simd[i].id == id)
1629 : {
1630 66 : *space = "omp";
1631 66 : *name = omp_pragmas_simd[i].name;
1632 66 : return;
1633 : }
1634 :
1635 40447 : if (id >= PRAGMA_FIRST_EXTERNAL
1636 80894 : && (id < PRAGMA_FIRST_EXTERNAL + registered_pragmas.length ()))
1637 : {
1638 40447 : *space = registered_pragmas[id - PRAGMA_FIRST_EXTERNAL].space;
1639 40447 : *name = registered_pragmas[id - PRAGMA_FIRST_EXTERNAL].name;
1640 40447 : return;
1641 : }
1642 :
1643 0 : gcc_unreachable ();
1644 : }
1645 :
1646 : /* Front-end wrappers for pragma registration to avoid dragging
1647 : cpplib.h in almost everywhere. */
1648 :
1649 : static void
1650 4007655 : c_register_pragma_1 (const char *space, const char *name,
1651 : internal_pragma_handler ihandler, bool allow_expansion)
1652 : {
1653 4007655 : unsigned id;
1654 :
1655 4007655 : pragma_data data;
1656 4007655 : data.space = space;
1657 4007655 : data.name = name;
1658 :
1659 4007655 : if (flag_preprocess_only
1660 116592 : && (cpp_get_options (parse_in)->directives_only
1661 115024 : || !(allow_expansion || ihandler.early_handler.handler_1arg)))
1662 59080 : return;
1663 :
1664 3948575 : data.ihandler = ihandler;
1665 3948575 : registered_pragmas.safe_push (data);
1666 3948575 : id = registered_pragmas.length ();
1667 7897150 : id += PRAGMA_FIRST_EXTERNAL - 1;
1668 :
1669 : /* The C front end allocates 8 bits in c_token. The C++ front end
1670 : keeps the pragma kind in the form of INTEGER_CST, so no small
1671 : limit applies. At present this is sufficient. */
1672 3948575 : gcc_assert (id < 256);
1673 :
1674 3948575 : cpp_register_deferred_pragma (parse_in, space, name, id,
1675 : allow_expansion, false);
1676 : }
1677 :
1678 : /* Register a C pragma handler, using a space and a name. It disallows pragma
1679 : expansion (if you want it, use c_register_pragma_with_expansion instead). */
1680 : void
1681 2301599 : c_register_pragma (const char *space, const char *name,
1682 : pragma_handler_1arg handler)
1683 : {
1684 2301599 : c_register_pragma_with_early_handler (space, name, handler, nullptr);
1685 2301599 : }
1686 3581141 : void c_register_pragma_with_early_handler (const char *space, const char *name,
1687 : pragma_handler_1arg handler,
1688 : pragma_handler_1arg early_handler)
1689 : {
1690 3581141 : internal_pragma_handler ihandler;
1691 :
1692 3581141 : ihandler.handler.handler_1arg = handler;
1693 3581141 : ihandler.early_handler.handler_1arg = early_handler;
1694 3581141 : ihandler.extra_data = false;
1695 3581141 : ihandler.data = NULL;
1696 3581141 : c_register_pragma_1 (space, name, ihandler, false);
1697 3581141 : }
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 disallows pragma
1701 : expansion (if you want it, use c_register_pragma_with_expansion_and_data
1702 : instead). */
1703 : void
1704 0 : c_register_pragma_with_data (const char *space, const char *name,
1705 : pragma_handler_2arg handler, void * data)
1706 : {
1707 0 : internal_pragma_handler ihandler;
1708 :
1709 0 : ihandler.handler.handler_2arg = handler;
1710 0 : ihandler.early_handler.handler_2arg = nullptr;
1711 0 : ihandler.extra_data = true;
1712 0 : ihandler.data = data;
1713 0 : c_register_pragma_1 (space, name, ihandler, false);
1714 0 : }
1715 :
1716 : /* Register a C pragma handler, using a space and a name. It allows pragma
1717 : expansion as in the following example:
1718 :
1719 : #define NUMBER 10
1720 : #pragma count (NUMBER)
1721 :
1722 : Name expansion is still disallowed. */
1723 : void
1724 426514 : c_register_pragma_with_expansion (const char *space, const char *name,
1725 : pragma_handler_1arg handler)
1726 : {
1727 426514 : internal_pragma_handler ihandler;
1728 :
1729 426514 : ihandler.handler.handler_1arg = handler;
1730 426514 : ihandler.early_handler.handler_1arg = nullptr;
1731 426514 : ihandler.extra_data = false;
1732 426514 : ihandler.data = NULL;
1733 426514 : c_register_pragma_1 (space, name, ihandler, true);
1734 426514 : }
1735 :
1736 : /* Register a C pragma handler, using a space and a name, it also carries an
1737 : extra data field which can be used by the handler. It allows pragma
1738 : expansion as in the following example:
1739 :
1740 : #define NUMBER 10
1741 : #pragma count (NUMBER)
1742 :
1743 : Name expansion is still disallowed. */
1744 : void
1745 0 : c_register_pragma_with_expansion_and_data (const char *space, const char *name,
1746 : pragma_handler_2arg handler,
1747 : void *data)
1748 : {
1749 0 : internal_pragma_handler ihandler;
1750 :
1751 0 : ihandler.handler.handler_2arg = handler;
1752 0 : ihandler.early_handler.handler_2arg = nullptr;
1753 0 : ihandler.extra_data = true;
1754 0 : ihandler.data = data;
1755 0 : c_register_pragma_1 (space, name, ihandler, true);
1756 0 : }
1757 :
1758 : void
1759 9706854 : c_invoke_pragma_handler (unsigned int id)
1760 : {
1761 9706854 : internal_pragma_handler *ihandler;
1762 9706854 : pragma_handler_1arg handler_1arg;
1763 9706854 : pragma_handler_2arg handler_2arg;
1764 :
1765 9706854 : id -= PRAGMA_FIRST_EXTERNAL;
1766 9706854 : ihandler = ®istered_pragmas[id].ihandler;
1767 9706854 : if (ihandler->extra_data)
1768 : {
1769 0 : handler_2arg = ihandler->handler.handler_2arg;
1770 0 : handler_2arg (parse_in, ihandler->data);
1771 : }
1772 : else
1773 : {
1774 9706854 : handler_1arg = ihandler->handler.handler_1arg;
1775 9706854 : handler_1arg (parse_in);
1776 : }
1777 9706854 : }
1778 :
1779 : /* In contrast to the normal handler, the early handler is optional. */
1780 : void
1781 7801485 : c_invoke_early_pragma_handler (unsigned int id)
1782 : {
1783 7801485 : internal_pragma_handler *ihandler;
1784 7801485 : pragma_handler_1arg handler_1arg;
1785 7801485 : pragma_handler_2arg handler_2arg;
1786 :
1787 7801485 : id -= PRAGMA_FIRST_EXTERNAL;
1788 7801485 : ihandler = ®istered_pragmas[id].ihandler;
1789 7801485 : if (ihandler->extra_data)
1790 : {
1791 0 : handler_2arg = ihandler->early_handler.handler_2arg;
1792 0 : if (handler_2arg)
1793 0 : handler_2arg (parse_in, ihandler->data);
1794 : }
1795 : else
1796 : {
1797 7801485 : handler_1arg = ihandler->early_handler.handler_1arg;
1798 7801485 : if (handler_1arg)
1799 7546574 : handler_1arg (parse_in);
1800 : }
1801 7801485 : }
1802 :
1803 : void
1804 40447 : c_pp_invoke_early_pragma_handler (unsigned int id)
1805 : {
1806 40447 : const auto data = ®istered_pragmas[id - PRAGMA_FIRST_EXTERNAL];
1807 40447 : pragma_handler_1arg handler = data->ihandler.early_handler.handler_1arg;
1808 40447 : if (handler)
1809 : {
1810 40429 : handler (parse_in);
1811 40429 : pragma_lex_discard_to_eol ();
1812 : }
1813 40447 : }
1814 :
1815 : /* Set up front-end pragmas. */
1816 : void
1817 213257 : init_pragma (void)
1818 : {
1819 :
1820 213257 : if (!cpp_get_options (parse_in)->directives_only)
1821 : {
1822 213126 : if (flag_openacc)
1823 : {
1824 : const int n_oacc_pragmas = ARRAY_SIZE (oacc_pragmas);
1825 : int i;
1826 :
1827 25125 : for (i = 0; i < n_oacc_pragmas; ++i)
1828 23450 : cpp_register_deferred_pragma (parse_in, "acc", oacc_pragmas[i].name,
1829 23450 : oacc_pragmas[i].id, true, true);
1830 : }
1831 :
1832 213126 : if (flag_openmp)
1833 : {
1834 : const int n_omp_pragmas = ARRAY_SIZE (omp_pragmas);
1835 : int i;
1836 :
1837 182504 : for (i = 0; i < n_omp_pragmas; ++i)
1838 175986 : cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name,
1839 175986 : omp_pragmas[i].id, true, true);
1840 : }
1841 213126 : if (flag_openmp || flag_openmp_simd)
1842 : {
1843 : const int n_omp_pragmas_simd = ARRAY_SIZE (omp_pragmas_simd);
1844 : int i;
1845 :
1846 118014 : for (i = 0; i < n_omp_pragmas_simd; ++i)
1847 111072 : cpp_register_deferred_pragma (parse_in, "omp",
1848 111072 : omp_pragmas_simd[i].name,
1849 111072 : omp_pragmas_simd[i].id, true, true);
1850 : }
1851 : }
1852 :
1853 213257 : if (!flag_preprocess_only)
1854 205970 : cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
1855 : PRAGMA_GCC_PCH_PREPROCESS, false, false);
1856 :
1857 213257 : if (!flag_preprocess_only)
1858 205970 : cpp_register_deferred_pragma (parse_in, "GCC", "ivdep", PRAGMA_IVDEP, false,
1859 : false);
1860 :
1861 213257 : if (!flag_preprocess_only)
1862 205970 : cpp_register_deferred_pragma (parse_in, "GCC", "unroll", PRAGMA_UNROLL,
1863 : false, false);
1864 :
1865 213257 : if (!flag_preprocess_only)
1866 205970 : cpp_register_deferred_pragma (parse_in, "GCC", "novector", PRAGMA_NOVECTOR,
1867 : false, false);
1868 :
1869 : #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
1870 : c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
1871 : #else
1872 213257 : c_register_pragma (0, "pack", handle_pragma_pack);
1873 : #endif
1874 213257 : c_register_pragma (0, "weak", handle_pragma_weak);
1875 :
1876 213257 : c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
1877 213257 : c_register_pragma ("GCC", "suppress_coverage",
1878 : handle_pragma_suppress_coverage);
1879 :
1880 213257 : if (flag_preprocess_only)
1881 7287 : c_register_pragma_with_early_handler ("GCC", "diagnostic",
1882 : nullptr,
1883 : handle_pragma_diagnostic_early_pp);
1884 : else
1885 205970 : c_register_pragma_with_early_handler ("GCC", "diagnostic",
1886 : handle_pragma_diagnostic,
1887 : handle_pragma_diagnostic_early);
1888 213257 : c_register_pragma_with_early_handler ("GCC", "target",
1889 : handle_pragma_target,
1890 : handle_pragma_target);
1891 213257 : c_register_pragma_with_early_handler ("GCC", "optimize",
1892 : handle_pragma_optimize,
1893 : handle_pragma_optimize);
1894 213257 : c_register_pragma_with_early_handler ("GCC", "push_options",
1895 : handle_pragma_push_options,
1896 : handle_pragma_push_options);
1897 213257 : c_register_pragma_with_early_handler ("GCC", "pop_options",
1898 : handle_pragma_pop_options,
1899 : handle_pragma_pop_options);
1900 213257 : c_register_pragma_with_early_handler ("GCC", "reset_options",
1901 : handle_pragma_reset_options,
1902 : handle_pragma_reset_options);
1903 :
1904 213257 : c_register_pragma (0, "region", handle_pragma_ignore);
1905 213257 : c_register_pragma (0, "endregion", handle_pragma_ignore);
1906 :
1907 213257 : c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
1908 : handle_pragma_float_const_decimal64);
1909 :
1910 213257 : c_register_pragma_with_expansion (0, "redefine_extname",
1911 : handle_pragma_redefine_extname);
1912 :
1913 213257 : c_register_pragma_with_expansion (0, "message", handle_pragma_message);
1914 :
1915 : #ifdef REGISTER_TARGET_PRAGMAS
1916 213257 : REGISTER_TARGET_PRAGMAS ();
1917 : #endif
1918 :
1919 213257 : global_sso = default_sso;
1920 213257 : c_register_pragma (0, "scalar_storage_order",
1921 : handle_pragma_scalar_storage_order);
1922 :
1923 : /* Allow plugins to register their own pragmas. */
1924 213257 : invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL);
1925 213257 : }
1926 :
1927 : #include "gt-c-family-c-pragma.h"
|