xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/c-family/c-pragma.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
2    Copyright (C) 1992-2015 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 "tm.h"
24 #include "hash-set.h"
25 #include "machmode.h"
26 #include "vec.h"
27 #include "double-int.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "options.h"
32 #include "wide-int.h"
33 #include "inchash.h"
34 #include "tree.h"
35 #include "stringpool.h"
36 #include "attribs.h"
37 #include "varasm.h"
38 #include "hashtab.h"
39 #include "hash-set.h"
40 #include "vec.h"
41 #include "machmode.h"
42 #include "hard-reg-set.h"
43 #include "input.h"
44 #include "function.h"		/* For cfun.  FIXME: Does the parser know
45 				   when it is inside a function, so that
46 				   we don't have to look at cfun?  */
47 #include "cpplib.h"
48 #include "c-pragma.h"
49 #include "flags.h"
50 #include "c-common.h"
51 #include "tm_p.h"		/* For REGISTER_TARGET_PRAGMAS (why is
52 				   this not a target hook?).  */
53 #include "target.h"
54 #include "diagnostic.h"
55 #include "opts.h"
56 #include "plugin.h"
57 #include "hash-map.h"
58 #include "is-a.h"
59 #include "plugin-api.h"
60 #include "ipa-ref.h"
61 #include "cgraph.h"
62 
63 #define GCC_BAD(gmsgid) \
64   do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
65 #define GCC_BAD2(gmsgid, arg) \
66   do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0)
67 
68 typedef struct GTY(()) align_stack {
69   int		       alignment;
70   tree		       id;
71   struct align_stack * prev;
72 } align_stack;
73 
74 static GTY(()) struct align_stack * alignment_stack;
75 
76 static void handle_pragma_pack (cpp_reader *);
77 
78 /* If we have a "global" #pragma pack(<n>) in effect when the first
79    #pragma pack(push,<n>) is encountered, this stores the value of
80    maximum_field_alignment in effect.  When the final pop_alignment()
81    happens, we restore the value to this, not to a value of 0 for
82    maximum_field_alignment.  Value is in bits.  */
83 static int default_alignment;
84 #define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \
85 	? &default_alignment \
86 	: &alignment_stack->alignment) = (ALIGN))
87 
88 static void push_alignment (int, tree);
89 static void pop_alignment (tree);
90 
91 /* Push an alignment value onto the stack.  */
92 static void
93 push_alignment (int alignment, tree id)
94 {
95   align_stack * entry = ggc_alloc<align_stack> ();
96 
97   entry->alignment  = alignment;
98   entry->id	    = id;
99   entry->prev	    = alignment_stack;
100 
101   /* The current value of maximum_field_alignment is not necessarily
102      0 since there may be a #pragma pack(<n>) in effect; remember it
103      so that we can restore it after the final #pragma pop().  */
104   if (alignment_stack == NULL)
105     default_alignment = maximum_field_alignment;
106 
107   alignment_stack = entry;
108 
109   maximum_field_alignment = alignment;
110 }
111 
112 /* Undo a push of an alignment onto the stack.  */
113 static void
114 pop_alignment (tree id)
115 {
116   align_stack * entry;
117 
118   if (alignment_stack == NULL)
119     GCC_BAD ("#pragma pack (pop) encountered without matching #pragma pack (push)");
120 
121   /* If we got an identifier, strip away everything above the target
122      entry so that the next step will restore the state just below it.  */
123   if (id)
124     {
125       for (entry = alignment_stack; entry; entry = entry->prev)
126 	if (entry->id == id)
127 	  {
128 	    alignment_stack = entry;
129 	    break;
130 	  }
131       if (entry == NULL)
132 	warning (OPT_Wpragmas, "\
133 #pragma pack(pop, %E) encountered without matching #pragma pack(push, %E)"
134 		 , id, id);
135     }
136 
137   entry = alignment_stack->prev;
138 
139   maximum_field_alignment = entry ? entry->alignment : default_alignment;
140 
141   alignment_stack = entry;
142 }
143 
144 /* #pragma pack ()
145    #pragma pack (N)
146 
147    #pragma pack (push)
148    #pragma pack (push, N)
149    #pragma pack (push, ID)
150    #pragma pack (push, ID, N)
151    #pragma pack (pop)
152    #pragma pack (pop, ID) */
153 static void
154 handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
155 {
156   tree x, id = 0;
157   int align = -1;
158   enum cpp_ttype token;
159   enum { set, push, pop } action;
160 
161   if (pragma_lex (&x) != CPP_OPEN_PAREN)
162     GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored");
163 
164   token = pragma_lex (&x);
165   if (token == CPP_CLOSE_PAREN)
166     {
167       action = set;
168       align = initial_max_fld_align;
169     }
170   else if (token == CPP_NUMBER)
171     {
172       if (TREE_CODE (x) != INTEGER_CST)
173 	GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
174       align = TREE_INT_CST_LOW (x);
175       action = set;
176       if (pragma_lex (&x) != CPP_CLOSE_PAREN)
177 	GCC_BAD ("malformed %<#pragma pack%> - ignored");
178     }
179   else if (token == CPP_NAME)
180     {
181 #define GCC_BAD_ACTION do { if (action != pop) \
182 	  GCC_BAD ("malformed %<#pragma pack(push[, id][, <n>])%> - ignored"); \
183 	else \
184 	  GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \
185 	} while (0)
186 
187       const char *op = IDENTIFIER_POINTER (x);
188       if (!strcmp (op, "push"))
189 	action = push;
190       else if (!strcmp (op, "pop"))
191 	action = pop;
192       else
193 	GCC_BAD2 ("unknown action %qE for %<#pragma pack%> - ignored", x);
194 
195       while ((token = pragma_lex (&x)) == CPP_COMMA)
196 	{
197 	  token = pragma_lex (&x);
198 	  if (token == CPP_NAME && id == 0)
199 	    {
200 	      id = x;
201 	    }
202 	  else if (token == CPP_NUMBER && action == push && align == -1)
203 	    {
204 	      if (TREE_CODE (x) != INTEGER_CST)
205 		GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
206 	      align = TREE_INT_CST_LOW (x);
207 	      if (align == -1)
208 		action = set;
209 	    }
210 	  else
211 	    GCC_BAD_ACTION;
212 	}
213 
214       if (token != CPP_CLOSE_PAREN)
215 	GCC_BAD_ACTION;
216 #undef GCC_BAD_ACTION
217     }
218   else
219     GCC_BAD ("malformed %<#pragma pack%> - ignored");
220 
221   if (pragma_lex (&x) != CPP_EOF)
222     warning (OPT_Wpragmas, "junk at end of %<#pragma pack%>");
223 
224   if (flag_pack_struct)
225     GCC_BAD ("#pragma pack has no effect with -fpack-struct - ignored");
226 
227   if (action != pop)
228     switch (align)
229       {
230       case 0:
231       case 1:
232       case 2:
233       case 4:
234       case 8:
235       case 16:
236 	align *= BITS_PER_UNIT;
237 	break;
238       case -1:
239 	if (action == push)
240 	  {
241 	    align = maximum_field_alignment;
242 	    break;
243 	  }
244       default:
245 	GCC_BAD2 ("alignment must be a small power of two, not %d", align);
246       }
247 
248   switch (action)
249     {
250     case set:   SET_GLOBAL_ALIGNMENT (align);  break;
251     case push:  push_alignment (align, id);    break;
252     case pop:   pop_alignment (id);	       break;
253     }
254 }
255 
256 typedef struct GTY(()) pending_weak_d
257 {
258   tree name;
259   tree value;
260 } pending_weak;
261 
262 
263 static GTY(()) vec<pending_weak, va_gc> *pending_weaks;
264 
265 static void apply_pragma_weak (tree, tree);
266 static void handle_pragma_weak (cpp_reader *);
267 
268 static void
269 apply_pragma_weak (tree decl, tree value)
270 {
271   if (value)
272     {
273       value = build_string (IDENTIFIER_LENGTH (value),
274 			    IDENTIFIER_POINTER (value));
275       decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
276 					       build_tree_list (NULL, value)),
277 		       0);
278     }
279 
280   if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
281       && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma.  */
282       && DECL_ASSEMBLER_NAME_SET_P (decl)
283       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
284     warning (OPT_Wpragmas, "applying #pragma weak %q+D after first use "
285 	     "results in unspecified behavior", decl);
286 
287   declare_weak (decl);
288 }
289 
290 void
291 maybe_apply_pragma_weak (tree decl)
292 {
293   tree id;
294   int i;
295   pending_weak *pe;
296 
297   /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed.  */
298 
299   /* No weak symbols pending, take the short-cut.  */
300   if (vec_safe_is_empty (pending_weaks))
301     return;
302   /* If it's not visible outside this file, it doesn't matter whether
303      it's weak.  */
304   if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl))
305     return;
306   /* If it's not a function or a variable, it can't be weak.
307      FIXME: what kinds of things are visible outside this file but
308      aren't functions or variables?   Should this be an assert instead?  */
309   if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
310     return;
311 
312   if (DECL_ASSEMBLER_NAME_SET_P (decl))
313     id = DECL_ASSEMBLER_NAME (decl);
314   else
315     {
316       id = DECL_ASSEMBLER_NAME (decl);
317       SET_DECL_ASSEMBLER_NAME (decl, NULL_TREE);
318     }
319 
320   FOR_EACH_VEC_ELT (*pending_weaks, i, pe)
321     if (id == pe->name)
322       {
323 	apply_pragma_weak (decl, pe->value);
324 	pending_weaks->unordered_remove (i);
325 	break;
326       }
327 }
328 
329 /* Process all "#pragma weak A = B" directives where we have not seen
330    a decl for A.  */
331 void
332 maybe_apply_pending_pragma_weaks (void)
333 {
334   tree alias_id, id, decl;
335   int i;
336   pending_weak *pe;
337   symtab_node *target;
338 
339   if (vec_safe_is_empty (pending_weaks))
340     return;
341 
342   FOR_EACH_VEC_ELT (*pending_weaks, i, pe)
343     {
344       alias_id = pe->name;
345       id = pe->value;
346 
347       if (id == NULL)
348 	continue;
349 
350       target = symtab_node::get_for_asmname (id);
351       decl = build_decl (UNKNOWN_LOCATION,
352 			 target ? TREE_CODE (target->decl) : FUNCTION_DECL,
353 			 alias_id, default_function_type);
354 
355       DECL_ARTIFICIAL (decl) = 1;
356       TREE_PUBLIC (decl) = 1;
357       DECL_WEAK (decl) = 1;
358       if (TREE_CODE (decl) == VAR_DECL)
359 	TREE_STATIC (decl) = 1;
360       if (!target)
361 	{
362 	  error ("%q+D aliased to undefined symbol %qE",
363 		 decl, id);
364 	  continue;
365 	}
366 
367       assemble_alias (decl, id);
368     }
369 }
370 
371 /* #pragma weak name [= value] */
372 static void
373 handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy))
374 {
375   tree name, value, x, decl;
376   enum cpp_ttype t;
377 
378   value = 0;
379 
380   if (pragma_lex (&name) != CPP_NAME)
381     GCC_BAD ("malformed #pragma weak, ignored");
382   t = pragma_lex (&x);
383   if (t == CPP_EQ)
384     {
385       if (pragma_lex (&value) != CPP_NAME)
386 	GCC_BAD ("malformed #pragma weak, ignored");
387       t = pragma_lex (&x);
388     }
389   if (t != CPP_EOF)
390     warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>");
391 
392   decl = identifier_global_value (name);
393   if (decl && DECL_P (decl))
394     {
395       if (!VAR_OR_FUNCTION_DECL_P (decl))
396 	GCC_BAD2 ("%<#pragma weak%> declaration of %q+D not allowed,"
397 		  " ignored", decl);
398       apply_pragma_weak (decl, value);
399       if (value)
400 	{
401 	  DECL_EXTERNAL (decl) = 0;
402 	  if (TREE_CODE (decl) == VAR_DECL)
403 	    TREE_STATIC (decl) = 1;
404 	  assemble_alias (decl, value);
405 	}
406     }
407   else
408     {
409       pending_weak pe = {name, value};
410       vec_safe_push (pending_weaks, pe);
411     }
412 }
413 
414 /* GCC supports two #pragma directives for renaming the external
415    symbol associated with a declaration (DECL_ASSEMBLER_NAME), for
416    compatibility with the Solaris and VMS system headers.  GCC also
417    has its own notation for this, __asm__("name") annotations.
418 
419    Corner cases of these features and their interaction:
420 
421    1) Both pragmas silently apply only to declarations with external
422       linkage (that is, TREE_PUBLIC || DECL_EXTERNAL).  Asm labels
423       do not have this restriction.
424 
425    2) In C++, both #pragmas silently apply only to extern "C" declarations.
426       Asm labels do not have this restriction.
427 
428    3) If any of the three ways of changing DECL_ASSEMBLER_NAME is
429       applied to a decl whose DECL_ASSEMBLER_NAME is already set, and the
430       new name is different, a warning issues and the name does not change.
431 
432    4) The "source name" for #pragma redefine_extname is the DECL_NAME,
433       *not* the DECL_ASSEMBLER_NAME.
434 
435    5) If #pragma extern_prefix is in effect and a declaration occurs
436       with an __asm__ name, the #pragma extern_prefix is silently
437       ignored for that declaration.
438 
439    6) If #pragma extern_prefix and #pragma redefine_extname apply to
440       the same declaration, whichever triggered first wins, and a warning
441       is issued.  (We would like to have #pragma redefine_extname always
442       win, but it can appear either before or after the declaration, and
443       if it appears afterward, we have no way of knowing whether a modified
444       DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.)  */
445 
446 typedef struct GTY(()) pending_redefinition_d {
447   tree oldname;
448   tree newname;
449 } pending_redefinition;
450 
451 
452 static GTY(()) vec<pending_redefinition, va_gc> *pending_redefine_extname;
453 
454 static void handle_pragma_redefine_extname (cpp_reader *);
455 
456 /* #pragma redefine_extname oldname newname */
457 static void
458 handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy))
459 {
460   tree oldname, newname, decls, x;
461   enum cpp_ttype t;
462   bool found;
463 
464   if (pragma_lex (&oldname) != CPP_NAME)
465     GCC_BAD ("malformed #pragma redefine_extname, ignored");
466   if (pragma_lex (&newname) != CPP_NAME)
467     GCC_BAD ("malformed #pragma redefine_extname, ignored");
468   t = pragma_lex (&x);
469   if (t != CPP_EOF)
470     warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>");
471 
472   found = false;
473   for (decls = c_linkage_bindings (oldname);
474        decls; )
475     {
476       tree decl;
477       if (TREE_CODE (decls) == TREE_LIST)
478 	{
479 	  decl = TREE_VALUE (decls);
480 	  decls = TREE_CHAIN (decls);
481 	}
482       else
483 	{
484 	  decl = decls;
485 	  decls = NULL_TREE;
486 	}
487 
488       if ((TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
489 	  && (TREE_CODE (decl) == FUNCTION_DECL
490 	      || TREE_CODE (decl) == VAR_DECL))
491 	{
492 	  found = true;
493 	  if (DECL_ASSEMBLER_NAME_SET_P (decl))
494 	    {
495 	      const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
496 	      name = targetm.strip_name_encoding (name);
497 
498 	      if (strcmp (name, IDENTIFIER_POINTER (newname)))
499 		warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
500 			 "conflict with previous rename");
501 	    }
502 	  else
503 	    symtab->change_decl_assembler_name (decl, newname);
504 	}
505     }
506 
507   if (!found)
508     /* We have to add this to the rename list even if there's already
509        a global value that doesn't meet the above criteria, because in
510        C++ "struct foo {...};" puts "foo" in the current namespace but
511        does *not* conflict with a subsequent declaration of a function
512        or variable foo.  See g++.dg/other/pragma-re-2.C.  */
513     add_to_renaming_pragma_list (oldname, newname);
514 }
515 
516 /* This is called from here and from ia64-c.c.  */
517 void
518 add_to_renaming_pragma_list (tree oldname, tree newname)
519 {
520   unsigned ix;
521   pending_redefinition *p;
522 
523   FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
524     if (oldname == p->oldname)
525       {
526 	if (p->newname != newname)
527 	  warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
528 		   "conflict with previous #pragma redefine_extname");
529 	return;
530       }
531 
532   pending_redefinition e = {oldname, newname};
533   vec_safe_push (pending_redefine_extname, e);
534 }
535 
536 /* The current prefix set by #pragma extern_prefix.  */
537 GTY(()) tree pragma_extern_prefix;
538 
539 /* Hook from the front ends to apply the results of one of the preceding
540    pragmas that rename variables.  */
541 
542 tree
543 maybe_apply_renaming_pragma (tree decl, tree asmname)
544 {
545   unsigned ix;
546   pending_redefinition *p;
547 
548   /* The renaming pragmas are only applied to declarations with
549      external linkage.  */
550   if ((TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
551       || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
552       || !has_c_linkage (decl))
553     return asmname;
554 
555   /* If the DECL_ASSEMBLER_NAME is already set, it does not change,
556      but we may warn about a rename that conflicts.  */
557   if (DECL_ASSEMBLER_NAME_SET_P (decl))
558     {
559       const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
560       oldname = targetm.strip_name_encoding (oldname);
561 
562       if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname))
563 	  warning (OPT_Wpragmas, "asm declaration ignored due to "
564 		   "conflict with previous rename");
565 
566       /* Take any pending redefine_extname off the list.  */
567       FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
568 	if (DECL_NAME (decl) == p->oldname)
569 	  {
570 	    /* Only warn if there is a conflict.  */
571 	    if (strcmp (IDENTIFIER_POINTER (p->newname), oldname))
572 	      warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
573 		       "conflict with previous rename");
574 
575 	    pending_redefine_extname->unordered_remove (ix);
576 	    break;
577 	  }
578       return 0;
579     }
580 
581   /* Find out if we have a pending #pragma redefine_extname.  */
582   FOR_EACH_VEC_SAFE_ELT (pending_redefine_extname, ix, p)
583     if (DECL_NAME (decl) == p->oldname)
584       {
585 	tree newname = p->newname;
586 	pending_redefine_extname->unordered_remove (ix);
587 
588 	/* If we already have an asmname, #pragma redefine_extname is
589 	   ignored (with a warning if it conflicts).  */
590 	if (asmname)
591 	  {
592 	    if (strcmp (TREE_STRING_POINTER (asmname),
593 			IDENTIFIER_POINTER (newname)) != 0)
594 	      warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
595 		       "conflict with __asm__ declaration");
596 	    return asmname;
597 	  }
598 
599 	/* Otherwise we use what we've got; #pragma extern_prefix is
600 	   silently ignored.  */
601 	return build_string (IDENTIFIER_LENGTH (newname),
602 			     IDENTIFIER_POINTER (newname));
603       }
604 
605   /* If we've got an asmname, #pragma extern_prefix is silently ignored.  */
606   if (asmname)
607     return asmname;
608 
609   /* If #pragma extern_prefix is in effect, apply it.  */
610   if (pragma_extern_prefix)
611     {
612       const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix);
613       size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1;
614 
615       const char *id = IDENTIFIER_POINTER (DECL_NAME (decl));
616       size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl));
617 
618       char *newname = (char *) alloca (plen + ilen + 1);
619 
620       memcpy (newname,        prefix, plen);
621       memcpy (newname + plen, id, ilen + 1);
622 
623       return build_string (plen + ilen, newname);
624     }
625 
626   /* Nada.  */
627   return 0;
628 }
629 
630 
631 static void handle_pragma_visibility (cpp_reader *);
632 
633 static vec<int> visstack;
634 
635 /* Push the visibility indicated by STR onto the top of the #pragma
636    visibility stack.  KIND is 0 for #pragma GCC visibility, 1 for
637    C++ namespace with visibility attribute and 2 for C++ builtin
638    ABI namespace.  push_visibility/pop_visibility calls must have
639    matching KIND, it is not allowed to push visibility using one
640    KIND and pop using a different one.  */
641 
642 void
643 push_visibility (const char *str, int kind)
644 {
645   visstack.safe_push (((int) default_visibility) | (kind << 8));
646   if (!strcmp (str, "default"))
647     default_visibility = VISIBILITY_DEFAULT;
648   else if (!strcmp (str, "internal"))
649     default_visibility = VISIBILITY_INTERNAL;
650   else if (!strcmp (str, "hidden"))
651     default_visibility = VISIBILITY_HIDDEN;
652   else if (!strcmp (str, "protected"))
653     default_visibility = VISIBILITY_PROTECTED;
654   else
655     GCC_BAD ("#pragma GCC visibility push() must specify default, internal, hidden or protected");
656   visibility_options.inpragma = 1;
657 }
658 
659 /* Pop a level of the #pragma visibility stack.  Return true if
660    successful.  */
661 
662 bool
663 pop_visibility (int kind)
664 {
665   if (!visstack.length ())
666     return false;
667   if ((visstack.last () >> 8) != kind)
668     return false;
669   default_visibility
670     = (enum symbol_visibility) (visstack.pop () & 0xff);
671   visibility_options.inpragma
672     = visstack.length () != 0;
673   return true;
674 }
675 
676 /* Sets the default visibility for symbols to something other than that
677    specified on the command line.  */
678 
679 static void
680 handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
681 {
682   /* Form is #pragma GCC visibility push(hidden)|pop */
683   tree x;
684   enum cpp_ttype token;
685   enum { bad, push, pop } action = bad;
686 
687   token = pragma_lex (&x);
688   if (token == CPP_NAME)
689     {
690       const char *op = IDENTIFIER_POINTER (x);
691       if (!strcmp (op, "push"))
692 	action = push;
693       else if (!strcmp (op, "pop"))
694 	action = pop;
695     }
696   if (bad == action)
697     GCC_BAD ("#pragma GCC visibility must be followed by push or pop");
698   else
699     {
700       if (pop == action)
701 	{
702 	  if (! pop_visibility (0))
703 	    GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
704 	}
705       else
706 	{
707 	  if (pragma_lex (&x) != CPP_OPEN_PAREN)
708 	    GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
709 	  token = pragma_lex (&x);
710 	  if (token != CPP_NAME)
711 	    GCC_BAD ("malformed #pragma GCC visibility push");
712 	  else
713 	    push_visibility (IDENTIFIER_POINTER (x), 0);
714 	  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
715 	    GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
716 	}
717     }
718   if (pragma_lex (&x) != CPP_EOF)
719     warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>");
720 }
721 
722 static void
723 handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
724 {
725   const char *kind_string, *option_string;
726   unsigned int option_index;
727   enum cpp_ttype token;
728   diagnostic_t kind;
729   tree x;
730   struct cl_option_handlers handlers;
731 
732   token = pragma_lex (&x);
733   if (token != CPP_NAME)
734     GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>");
735   kind_string = IDENTIFIER_POINTER (x);
736   if (strcmp (kind_string, "error") == 0)
737     kind = DK_ERROR;
738   else if (strcmp (kind_string, "warning") == 0)
739     kind = DK_WARNING;
740   else if (strcmp (kind_string, "ignored") == 0)
741     kind = DK_IGNORED;
742   else if (strcmp (kind_string, "push") == 0)
743     {
744       diagnostic_push_diagnostics (global_dc, input_location);
745       return;
746     }
747   else if (strcmp (kind_string, "pop") == 0)
748     {
749       diagnostic_pop_diagnostics (global_dc, input_location);
750       return;
751     }
752   else
753     GCC_BAD ("expected [error|warning|ignored|push|pop] after %<#pragma GCC diagnostic%>");
754 
755   token = pragma_lex (&x);
756   if (token != CPP_STRING)
757     GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind");
758   option_string = TREE_STRING_POINTER (x);
759   set_default_handlers (&handlers);
760   for (option_index = 0; option_index < cl_options_count; option_index++)
761     if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
762       {
763 	control_warning_option (option_index, (int) kind, kind != DK_IGNORED,
764 				input_location, c_family_lang_mask, &handlers,
765 				&global_options, &global_options_set,
766 				global_dc);
767 	return;
768       }
769   GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
770 }
771 
772 /*  Parse #pragma GCC target (xxx) to set target specific options.  */
773 static void
774 handle_pragma_target(cpp_reader *ARG_UNUSED(dummy))
775 {
776   enum cpp_ttype token;
777   tree x;
778   bool close_paren_needed_p = false;
779 
780   if (cfun)
781     {
782       error ("#pragma GCC option is not allowed inside functions");
783       return;
784     }
785 
786   token = pragma_lex (&x);
787   if (token == CPP_OPEN_PAREN)
788     {
789       close_paren_needed_p = true;
790       token = pragma_lex (&x);
791     }
792 
793   if (token != CPP_STRING)
794     {
795       GCC_BAD ("%<#pragma GCC option%> is not a string");
796       return;
797     }
798 
799   /* Strings are user options.  */
800   else
801     {
802       tree args = NULL_TREE;
803 
804       do
805 	{
806 	  /* Build up the strings now as a tree linked list.  Skip empty
807 	     strings.  */
808 	  if (TREE_STRING_LENGTH (x) > 0)
809 	    args = tree_cons (NULL_TREE, x, args);
810 
811 	  token = pragma_lex (&x);
812 	  while (token == CPP_COMMA)
813 	    token = pragma_lex (&x);
814 	}
815       while (token == CPP_STRING);
816 
817       if (close_paren_needed_p)
818 	{
819 	  if (token == CPP_CLOSE_PAREN)
820 	    token = pragma_lex (&x);
821 	  else
822 	    GCC_BAD ("%<#pragma GCC target (string [,string]...)%> does "
823 		     "not have a final %<)%>");
824 	}
825 
826       if (token != CPP_EOF)
827 	{
828 	  error ("#pragma GCC target string... is badly formed");
829 	  return;
830 	}
831 
832       /* put arguments in the order the user typed them.  */
833       args = nreverse (args);
834 
835       if (targetm.target_option.pragma_parse (args, NULL_TREE))
836 	current_target_pragma = args;
837     }
838 }
839 
840 /* Handle #pragma GCC optimize to set optimization options.  */
841 static void
842 handle_pragma_optimize (cpp_reader *ARG_UNUSED(dummy))
843 {
844   enum cpp_ttype token;
845   tree x;
846   bool close_paren_needed_p = false;
847   tree optimization_previous_node = optimization_current_node;
848 
849   if (cfun)
850     {
851       error ("#pragma GCC optimize is not allowed inside functions");
852       return;
853     }
854 
855   token = pragma_lex (&x);
856   if (token == CPP_OPEN_PAREN)
857     {
858       close_paren_needed_p = true;
859       token = pragma_lex (&x);
860     }
861 
862   if (token != CPP_STRING && token != CPP_NUMBER)
863     {
864       GCC_BAD ("%<#pragma GCC optimize%> is not a string or number");
865       return;
866     }
867 
868   /* Strings/numbers are user options.  */
869   else
870     {
871       tree args = NULL_TREE;
872 
873       do
874 	{
875 	  /* Build up the numbers/strings now as a list.  */
876 	  if (token != CPP_STRING || TREE_STRING_LENGTH (x) > 0)
877 	    args = tree_cons (NULL_TREE, x, args);
878 
879 	  token = pragma_lex (&x);
880 	  while (token == CPP_COMMA)
881 	    token = pragma_lex (&x);
882 	}
883       while (token == CPP_STRING || token == CPP_NUMBER);
884 
885       if (close_paren_needed_p)
886 	{
887 	  if (token == CPP_CLOSE_PAREN)
888 	    token = pragma_lex (&x);
889 	  else
890 	    GCC_BAD ("%<#pragma GCC optimize (string [,string]...)%> does "
891 		     "not have a final %<)%>");
892 	}
893 
894       if (token != CPP_EOF)
895 	{
896 	  error ("#pragma GCC optimize string... is badly formed");
897 	  return;
898 	}
899 
900       /* put arguments in the order the user typed them.  */
901       args = nreverse (args);
902 
903       parse_optimize_options (args, false);
904       current_optimize_pragma = chainon (current_optimize_pragma, args);
905       optimization_current_node = build_optimization_node (&global_options);
906       c_cpp_builtins_optimize_pragma (parse_in,
907 				      optimization_previous_node,
908 				      optimization_current_node);
909     }
910 }
911 
912 /* Stack of the #pragma GCC options created with #pragma GCC push_option.  Save
913    both the binary representation of the options and the TREE_LIST of
914    strings that will be added to the function's attribute list.  */
915 typedef struct GTY(()) opt_stack {
916   struct opt_stack *prev;
917   tree target_binary;
918   tree target_strings;
919   tree optimize_binary;
920   tree optimize_strings;
921 } opt_stack;
922 
923 static GTY(()) struct opt_stack * options_stack;
924 
925 /* Handle #pragma GCC push_options to save the current target and optimization
926    options.  */
927 
928 static void
929 handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy))
930 {
931   enum cpp_ttype token;
932   tree x = 0;
933 
934   token = pragma_lex (&x);
935   if (token != CPP_EOF)
936     {
937       warning (OPT_Wpragmas, "junk at end of %<#pragma push_options%>");
938       return;
939     }
940 
941   opt_stack *p = ggc_alloc<opt_stack> ();
942   p->prev = options_stack;
943   options_stack = p;
944 
945   /* Save optimization and target flags in binary format.  */
946   p->optimize_binary = build_optimization_node (&global_options);
947   p->target_binary = build_target_option_node (&global_options);
948 
949   /* Save optimization and target flags in string list format.  */
950   p->optimize_strings = copy_list (current_optimize_pragma);
951   p->target_strings = copy_list (current_target_pragma);
952 }
953 
954 /* Handle #pragma GCC pop_options to restore the current target and
955    optimization options from a previous push_options.  */
956 
957 static void
958 handle_pragma_pop_options (cpp_reader *ARG_UNUSED(dummy))
959 {
960   enum cpp_ttype token;
961   tree x = 0;
962   opt_stack *p;
963 
964   token = pragma_lex (&x);
965   if (token != CPP_EOF)
966     {
967       warning (OPT_Wpragmas, "junk at end of %<#pragma pop_options%>");
968       return;
969     }
970 
971   if (! options_stack)
972     {
973       warning (OPT_Wpragmas,
974 	       "%<#pragma GCC pop_options%> without a corresponding "
975 	       "%<#pragma GCC push_options%>");
976       return;
977     }
978 
979   p = options_stack;
980   options_stack = p->prev;
981 
982   if (p->target_binary != target_option_current_node)
983     {
984       (void) targetm.target_option.pragma_parse (NULL_TREE, p->target_binary);
985       target_option_current_node = p->target_binary;
986     }
987 
988   if (p->optimize_binary != optimization_current_node)
989     {
990       tree old_optimize = optimization_current_node;
991       cl_optimization_restore (&global_options,
992 			       TREE_OPTIMIZATION (p->optimize_binary));
993       c_cpp_builtins_optimize_pragma (parse_in, old_optimize,
994 				      p->optimize_binary);
995       optimization_current_node = p->optimize_binary;
996     }
997 
998   current_target_pragma = p->target_strings;
999   current_optimize_pragma = p->optimize_strings;
1000 }
1001 
1002 /* Handle #pragma GCC reset_options to restore the current target and
1003    optimization options to the original options used on the command line.  */
1004 
1005 static void
1006 handle_pragma_reset_options (cpp_reader *ARG_UNUSED(dummy))
1007 {
1008   enum cpp_ttype token;
1009   tree x = 0;
1010   tree new_optimize = optimization_default_node;
1011   tree new_target = target_option_default_node;
1012 
1013   token = pragma_lex (&x);
1014   if (token != CPP_EOF)
1015     {
1016       warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>");
1017       return;
1018     }
1019 
1020   if (new_target != target_option_current_node)
1021     {
1022       (void) targetm.target_option.pragma_parse (NULL_TREE, new_target);
1023       target_option_current_node = new_target;
1024     }
1025 
1026   if (new_optimize != optimization_current_node)
1027     {
1028       tree old_optimize = optimization_current_node;
1029       cl_optimization_restore (&global_options,
1030 			       TREE_OPTIMIZATION (new_optimize));
1031       c_cpp_builtins_optimize_pragma (parse_in, old_optimize, new_optimize);
1032       optimization_current_node = new_optimize;
1033     }
1034 
1035   current_target_pragma = NULL_TREE;
1036   current_optimize_pragma = NULL_TREE;
1037 }
1038 
1039 /* Print a plain user-specified message.  */
1040 
1041 static void
1042 handle_pragma_message (cpp_reader *ARG_UNUSED(dummy))
1043 {
1044   enum cpp_ttype token;
1045   tree x, message = 0;
1046 
1047   token = pragma_lex (&x);
1048   if (token == CPP_OPEN_PAREN)
1049     {
1050       token = pragma_lex (&x);
1051       if (token == CPP_STRING)
1052         message = x;
1053       else
1054         GCC_BAD ("expected a string after %<#pragma message%>");
1055       if (pragma_lex (&x) != CPP_CLOSE_PAREN)
1056         GCC_BAD ("malformed %<#pragma message%>, ignored");
1057     }
1058   else if (token == CPP_STRING)
1059     message = x;
1060   else
1061     GCC_BAD ("expected a string after %<#pragma message%>");
1062 
1063   gcc_assert (message);
1064 
1065   if (pragma_lex (&x) != CPP_EOF)
1066     warning (OPT_Wpragmas, "junk at end of %<#pragma message%>");
1067 
1068   if (TREE_STRING_LENGTH (message) > 1)
1069     inform (input_location, "#pragma message: %s", TREE_STRING_POINTER (message));
1070 }
1071 
1072 /* Mark whether the current location is valid for a STDC pragma.  */
1073 
1074 static bool valid_location_for_stdc_pragma;
1075 
1076 void
1077 mark_valid_location_for_stdc_pragma (bool flag)
1078 {
1079   valid_location_for_stdc_pragma = flag;
1080 }
1081 
1082 /* Return true if the current location is valid for a STDC pragma.  */
1083 
1084 bool
1085 valid_location_for_stdc_pragma_p (void)
1086 {
1087   return valid_location_for_stdc_pragma;
1088 }
1089 
1090 enum pragma_switch_t { PRAGMA_ON, PRAGMA_OFF, PRAGMA_DEFAULT, PRAGMA_BAD };
1091 
1092 /* A STDC pragma must appear outside of external declarations or
1093    preceding all explicit declarations and statements inside a compound
1094    statement; its behavior is undefined if used in any other context.
1095    It takes a switch of ON, OFF, or DEFAULT.  */
1096 
1097 static enum pragma_switch_t
1098 handle_stdc_pragma (const char *pname)
1099 {
1100   const char *arg;
1101   tree t;
1102   enum pragma_switch_t ret;
1103 
1104   if (!valid_location_for_stdc_pragma_p ())
1105     {
1106       warning (OPT_Wpragmas, "invalid location for %<pragma %s%>, ignored",
1107 	       pname);
1108       return PRAGMA_BAD;
1109     }
1110 
1111   if (pragma_lex (&t) != CPP_NAME)
1112     {
1113       warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
1114       return PRAGMA_BAD;
1115     }
1116 
1117   arg = IDENTIFIER_POINTER (t);
1118 
1119   if (!strcmp (arg, "ON"))
1120     ret = PRAGMA_ON;
1121   else if (!strcmp (arg, "OFF"))
1122     ret = PRAGMA_OFF;
1123   else if (!strcmp (arg, "DEFAULT"))
1124     ret = PRAGMA_DEFAULT;
1125   else
1126     {
1127       warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
1128       return PRAGMA_BAD;
1129     }
1130 
1131   if (pragma_lex (&t) != CPP_EOF)
1132     {
1133       warning (OPT_Wpragmas, "junk at end of %<#pragma %s%>", pname);
1134       return PRAGMA_BAD;
1135     }
1136 
1137   return ret;
1138 }
1139 
1140 /* #pragma STDC FLOAT_CONST_DECIMAL64 ON
1141    #pragma STDC FLOAT_CONST_DECIMAL64 OFF
1142    #pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT */
1143 
1144 static void
1145 handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy))
1146 {
1147   if (c_dialect_cxx ())
1148     {
1149       if (warn_unknown_pragmas > in_system_header_at (input_location))
1150 	warning (OPT_Wunknown_pragmas,
1151 		 "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
1152 		 " for C++");
1153       return;
1154     }
1155 
1156   if (!targetm.decimal_float_supported_p ())
1157     {
1158       if (warn_unknown_pragmas > in_system_header_at (input_location))
1159 	warning (OPT_Wunknown_pragmas,
1160 		 "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported"
1161 		 " on this target");
1162       return;
1163     }
1164 
1165   pedwarn (input_location, OPT_Wpedantic,
1166 	   "ISO C does not support %<#pragma STDC FLOAT_CONST_DECIMAL64%>");
1167 
1168   switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64"))
1169     {
1170     case PRAGMA_ON:
1171       set_float_const_decimal64 ();
1172       break;
1173     case PRAGMA_OFF:
1174     case PRAGMA_DEFAULT:
1175       clear_float_const_decimal64 ();
1176       break;
1177     case PRAGMA_BAD:
1178       break;
1179     }
1180 }
1181 
1182 /* A vector of registered pragma callbacks, which is never freed.   */
1183 
1184 static vec<internal_pragma_handler> registered_pragmas;
1185 
1186 typedef struct
1187 {
1188   const char *space;
1189   const char *name;
1190 } pragma_ns_name;
1191 
1192 
1193 static vec<pragma_ns_name> registered_pp_pragmas;
1194 
1195 struct omp_pragma_def { const char *name; unsigned int id; };
1196 static const struct omp_pragma_def oacc_pragmas[] = {
1197   { "cache", PRAGMA_OACC_CACHE },
1198   { "data", PRAGMA_OACC_DATA },
1199   { "enter", PRAGMA_OACC_ENTER_DATA },
1200   { "exit", PRAGMA_OACC_EXIT_DATA },
1201   { "kernels", PRAGMA_OACC_KERNELS },
1202   { "loop", PRAGMA_OACC_LOOP },
1203   { "parallel", PRAGMA_OACC_PARALLEL },
1204   { "update", PRAGMA_OACC_UPDATE },
1205   { "wait", PRAGMA_OACC_WAIT }
1206 };
1207 static const struct omp_pragma_def omp_pragmas[] = {
1208   { "atomic", PRAGMA_OMP_ATOMIC },
1209   { "barrier", PRAGMA_OMP_BARRIER },
1210   { "cancel", PRAGMA_OMP_CANCEL },
1211   { "cancellation", PRAGMA_OMP_CANCELLATION_POINT },
1212   { "critical", PRAGMA_OMP_CRITICAL },
1213   { "end", PRAGMA_OMP_END_DECLARE_TARGET },
1214   { "flush", PRAGMA_OMP_FLUSH },
1215   { "master", PRAGMA_OMP_MASTER },
1216   { "ordered", PRAGMA_OMP_ORDERED },
1217   { "section", PRAGMA_OMP_SECTION },
1218   { "sections", PRAGMA_OMP_SECTIONS },
1219   { "single", PRAGMA_OMP_SINGLE },
1220   { "task", PRAGMA_OMP_TASK },
1221   { "taskgroup", PRAGMA_OMP_TASKGROUP },
1222   { "taskwait", PRAGMA_OMP_TASKWAIT },
1223   { "taskyield", PRAGMA_OMP_TASKYIELD },
1224   { "threadprivate", PRAGMA_OMP_THREADPRIVATE }
1225 };
1226 static const struct omp_pragma_def omp_pragmas_simd[] = {
1227   { "declare", PRAGMA_OMP_DECLARE_REDUCTION },
1228   { "distribute", PRAGMA_OMP_DISTRIBUTE },
1229   { "for", PRAGMA_OMP_FOR },
1230   { "parallel", PRAGMA_OMP_PARALLEL },
1231   { "simd", PRAGMA_OMP_SIMD },
1232   { "target", PRAGMA_OMP_TARGET },
1233   { "teams", PRAGMA_OMP_TEAMS },
1234 };
1235 
1236 void
1237 c_pp_lookup_pragma (unsigned int id, const char **space, const char **name)
1238 {
1239   const int n_oacc_pragmas = sizeof (oacc_pragmas) / sizeof (*oacc_pragmas);
1240   const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
1241   const int n_omp_pragmas_simd = sizeof (omp_pragmas_simd)
1242 				 / sizeof (*omp_pragmas);
1243   int i;
1244 
1245   for (i = 0; i < n_oacc_pragmas; ++i)
1246     if (oacc_pragmas[i].id == id)
1247       {
1248 	*space = "acc";
1249 	*name = oacc_pragmas[i].name;
1250 	return;
1251       }
1252 
1253   for (i = 0; i < n_omp_pragmas; ++i)
1254     if (omp_pragmas[i].id == id)
1255       {
1256 	*space = "omp";
1257 	*name = omp_pragmas[i].name;
1258 	return;
1259       }
1260 
1261   for (i = 0; i < n_omp_pragmas_simd; ++i)
1262     if (omp_pragmas_simd[i].id == id)
1263       {
1264 	*space = "omp";
1265 	*name = omp_pragmas_simd[i].name;
1266 	return;
1267       }
1268 
1269   if (id == PRAGMA_CILK_SIMD)
1270     {
1271       *space = NULL;
1272       *name = "simd";
1273       return;
1274     }
1275 
1276   if (id == PRAGMA_CILK_GRAINSIZE)
1277     {
1278       *space = "cilk";
1279       *name = "grainsize";
1280       return;
1281     }
1282 
1283   if (id >= PRAGMA_FIRST_EXTERNAL
1284       && (id < PRAGMA_FIRST_EXTERNAL + registered_pp_pragmas.length ()))
1285     {
1286       *space = registered_pp_pragmas[id - PRAGMA_FIRST_EXTERNAL].space;
1287       *name = registered_pp_pragmas[id - PRAGMA_FIRST_EXTERNAL].name;
1288       return;
1289     }
1290 
1291   gcc_unreachable ();
1292 }
1293 
1294 /* Front-end wrappers for pragma registration to avoid dragging
1295    cpplib.h in almost everywhere.  */
1296 
1297 static void
1298 c_register_pragma_1 (const char *space, const char *name,
1299                      internal_pragma_handler ihandler, bool allow_expansion)
1300 {
1301   unsigned id;
1302 
1303   if (flag_preprocess_only)
1304     {
1305       pragma_ns_name ns_name;
1306 
1307       if (!allow_expansion)
1308 	return;
1309 
1310       ns_name.space = space;
1311       ns_name.name = name;
1312       registered_pp_pragmas.safe_push (ns_name);
1313       id = registered_pp_pragmas.length ();
1314       id += PRAGMA_FIRST_EXTERNAL - 1;
1315     }
1316   else
1317     {
1318       registered_pragmas.safe_push (ihandler);
1319       id = registered_pragmas.length ();
1320       id += PRAGMA_FIRST_EXTERNAL - 1;
1321 
1322       /* The C++ front end allocates 6 bits in cp_token; the C front end
1323 	 allocates 7 bits in c_token.  At present this is sufficient.  */
1324       gcc_assert (id < 64);
1325     }
1326 
1327   cpp_register_deferred_pragma (parse_in, space, name, id,
1328 				allow_expansion, false);
1329 }
1330 
1331 /* Register a C pragma handler, using a space and a name.  It disallows pragma
1332    expansion (if you want it, use c_register_pragma_with_expansion instead).  */
1333 void
1334 c_register_pragma (const char *space, const char *name,
1335                    pragma_handler_1arg handler)
1336 {
1337   internal_pragma_handler ihandler;
1338 
1339   ihandler.handler.handler_1arg = handler;
1340   ihandler.extra_data = false;
1341   ihandler.data = NULL;
1342   c_register_pragma_1 (space, name, ihandler, false);
1343 }
1344 
1345 /* Register a C pragma handler, using a space and a name, it also carries an
1346    extra data field which can be used by the handler.  It disallows pragma
1347    expansion (if you want it, use c_register_pragma_with_expansion_and_data
1348    instead).  */
1349 void
1350 c_register_pragma_with_data (const char *space, const char *name,
1351                              pragma_handler_2arg handler, void * data)
1352 {
1353   internal_pragma_handler ihandler;
1354 
1355   ihandler.handler.handler_2arg = handler;
1356   ihandler.extra_data = true;
1357   ihandler.data = data;
1358   c_register_pragma_1 (space, name, ihandler, false);
1359 }
1360 
1361 /* Register a C pragma handler, using a space and a name.  It allows pragma
1362    expansion as in the following example:
1363 
1364    #define NUMBER 10
1365    #pragma count (NUMBER)
1366 
1367    Name expansion is still disallowed.  */
1368 void
1369 c_register_pragma_with_expansion (const char *space, const char *name,
1370 				  pragma_handler_1arg handler)
1371 {
1372   internal_pragma_handler ihandler;
1373 
1374   ihandler.handler.handler_1arg = handler;
1375   ihandler.extra_data = false;
1376   ihandler.data = NULL;
1377   c_register_pragma_1 (space, name, ihandler, true);
1378 }
1379 
1380 /* Register a C pragma handler, using a space and a name, it also carries an
1381    extra data field which can be used by the handler.  It allows pragma
1382    expansion as in the following example:
1383 
1384    #define NUMBER 10
1385    #pragma count (NUMBER)
1386 
1387    Name expansion is still disallowed.  */
1388 void
1389 c_register_pragma_with_expansion_and_data (const char *space, const char *name,
1390                                            pragma_handler_2arg handler,
1391                                            void *data)
1392 {
1393   internal_pragma_handler ihandler;
1394 
1395   ihandler.handler.handler_2arg = handler;
1396   ihandler.extra_data = true;
1397   ihandler.data = data;
1398   c_register_pragma_1 (space, name, ihandler, true);
1399 }
1400 
1401 void
1402 c_invoke_pragma_handler (unsigned int id)
1403 {
1404   internal_pragma_handler *ihandler;
1405   pragma_handler_1arg handler_1arg;
1406   pragma_handler_2arg handler_2arg;
1407 
1408   id -= PRAGMA_FIRST_EXTERNAL;
1409   ihandler = &registered_pragmas[id];
1410   if (ihandler->extra_data)
1411     {
1412       handler_2arg = ihandler->handler.handler_2arg;
1413       handler_2arg (parse_in, ihandler->data);
1414     }
1415   else
1416     {
1417       handler_1arg = ihandler->handler.handler_1arg;
1418       handler_1arg (parse_in);
1419     }
1420 }
1421 
1422 /* Set up front-end pragmas.  */
1423 void
1424 init_pragma (void)
1425 {
1426   if (flag_openacc)
1427     {
1428       const int n_oacc_pragmas
1429 	= sizeof (oacc_pragmas) / sizeof (*oacc_pragmas);
1430       int i;
1431 
1432       for (i = 0; i < n_oacc_pragmas; ++i)
1433 	cpp_register_deferred_pragma (parse_in, "acc", oacc_pragmas[i].name,
1434 				      oacc_pragmas[i].id, true, true);
1435     }
1436 
1437   if (flag_openmp)
1438     {
1439       const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
1440       int i;
1441 
1442       for (i = 0; i < n_omp_pragmas; ++i)
1443 	cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name,
1444 				      omp_pragmas[i].id, true, true);
1445     }
1446   if (flag_openmp || flag_openmp_simd)
1447     {
1448       const int n_omp_pragmas_simd = sizeof (omp_pragmas_simd)
1449 				     / sizeof (*omp_pragmas);
1450       int i;
1451 
1452       for (i = 0; i < n_omp_pragmas_simd; ++i)
1453 	cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas_simd[i].name,
1454 				      omp_pragmas_simd[i].id, true, true);
1455     }
1456 
1457   if (flag_cilkplus)
1458     cpp_register_deferred_pragma (parse_in, NULL, "simd", PRAGMA_CILK_SIMD,
1459 				  true, false);
1460 
1461   if (!flag_preprocess_only)
1462     cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
1463 				  PRAGMA_GCC_PCH_PREPROCESS, false, false);
1464 
1465   if (!flag_preprocess_only)
1466     cpp_register_deferred_pragma (parse_in, "GCC", "ivdep", PRAGMA_IVDEP, false,
1467 				  false);
1468 
1469   if (flag_cilkplus)
1470     cpp_register_deferred_pragma (parse_in, "cilk", "grainsize",
1471 				  PRAGMA_CILK_GRAINSIZE, true, false);
1472 
1473 #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
1474   c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
1475 #else
1476   c_register_pragma (0, "pack", handle_pragma_pack);
1477 #endif
1478   c_register_pragma (0, "weak", handle_pragma_weak);
1479   c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
1480 
1481   c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
1482   c_register_pragma ("GCC", "target", handle_pragma_target);
1483   c_register_pragma ("GCC", "optimize", handle_pragma_optimize);
1484   c_register_pragma ("GCC", "push_options", handle_pragma_push_options);
1485   c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options);
1486   c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options);
1487 
1488   c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64",
1489 		     handle_pragma_float_const_decimal64);
1490 
1491   c_register_pragma_with_expansion (0, "redefine_extname",
1492 				    handle_pragma_redefine_extname);
1493 
1494   c_register_pragma_with_expansion (0, "message", handle_pragma_message);
1495 
1496 #ifdef REGISTER_TARGET_PRAGMAS
1497   REGISTER_TARGET_PRAGMAS ();
1498 #endif
1499 
1500   /* Allow plugins to register their own pragmas. */
1501   invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL);
1502 }
1503 
1504 #include "gt-c-family-c-pragma.h"
1505