xref: /openbsd/gnu/gcc/gcc/c-pragma.c (revision 154a9ab3)
1 /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
2    Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3    2006 Free Software Foundation, Inc.
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.  */
21 
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "function.h"
29 #include "cpplib.h"
30 #include "c-pragma.h"
31 #include "flags.h"
32 #include "toplev.h"
33 #include "ggc.h"
34 #include "c-common.h"
35 #include "output.h"
36 #include "tm_p.h"
37 #include "vec.h"
38 #include "target.h"
39 #include "diagnostic.h"
40 #include "opts.h"
41 
42 #define GCC_BAD(gmsgid) \
43   do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
44 #define GCC_BAD2(gmsgid, arg) \
45   do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0)
46 
47 typedef struct align_stack GTY(())
48 {
49   int		       alignment;
50   tree		       id;
51   struct align_stack * prev;
52 } align_stack;
53 
54 static GTY(()) struct align_stack * alignment_stack;
55 
56 #ifdef HANDLE_PRAGMA_PACK
57 static void handle_pragma_pack (cpp_reader *);
58 
59 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
60 /* If we have a "global" #pragma pack(<n>) in effect when the first
61    #pragma pack(push,<n>) is encountered, this stores the value of
62    maximum_field_alignment in effect.  When the final pop_alignment()
63    happens, we restore the value to this, not to a value of 0 for
64    maximum_field_alignment.  Value is in bits.  */
65 static int default_alignment;
66 #define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \
67 	? &default_alignment \
68 	: &alignment_stack->alignment) = (ALIGN))
69 
70 static void push_alignment (int, tree);
71 static void pop_alignment (tree);
72 
73 /* Push an alignment value onto the stack.  */
74 static void
push_alignment(int alignment,tree id)75 push_alignment (int alignment, tree id)
76 {
77   align_stack * entry;
78 
79   entry = GGC_NEW (align_stack);
80 
81   entry->alignment  = alignment;
82   entry->id	    = id;
83   entry->prev	    = alignment_stack;
84 
85   /* The current value of maximum_field_alignment is not necessarily
86      0 since there may be a #pragma pack(<n>) in effect; remember it
87      so that we can restore it after the final #pragma pop().  */
88   if (alignment_stack == NULL)
89     default_alignment = maximum_field_alignment;
90 
91   alignment_stack = entry;
92 
93   maximum_field_alignment = alignment;
94 }
95 
96 /* Undo a push of an alignment onto the stack.  */
97 static void
pop_alignment(tree id)98 pop_alignment (tree id)
99 {
100   align_stack * entry;
101 
102   if (alignment_stack == NULL)
103     GCC_BAD ("#pragma pack (pop) encountered without matching #pragma pack (push)");
104 
105   /* If we got an identifier, strip away everything above the target
106      entry so that the next step will restore the state just below it.  */
107   if (id)
108     {
109       for (entry = alignment_stack; entry; entry = entry->prev)
110 	if (entry->id == id)
111 	  {
112 	    alignment_stack = entry;
113 	    break;
114 	  }
115       if (entry == NULL)
116 	warning (OPT_Wpragmas, "\
117 #pragma pack(pop, %s) encountered without matching #pragma pack(push, %s)"
118 		 , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
119     }
120 
121   entry = alignment_stack->prev;
122 
123   maximum_field_alignment = entry ? entry->alignment : default_alignment;
124 
125   alignment_stack = entry;
126 }
127 #else  /* not HANDLE_PRAGMA_PACK_PUSH_POP */
128 #define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN))
129 #define push_alignment(ID, N) \
130     GCC_BAD ("#pragma pack(push[, id], <n>) is not supported on this target")
131 #define pop_alignment(ID) \
132     GCC_BAD ("#pragma pack(pop[, id], <n>) is not supported on this target")
133 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
134 
135 /* #pragma pack ()
136    #pragma pack (N)
137 
138    #pragma pack (push)
139    #pragma pack (push, N)
140    #pragma pack (push, ID)
141    #pragma pack (push, ID, N)
142    #pragma pack (pop)
143    #pragma pack (pop, ID) */
144 static void
handle_pragma_pack(cpp_reader * ARG_UNUSED (dummy))145 handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
146 {
147   tree x, id = 0;
148   int align = -1;
149   enum cpp_ttype token;
150   enum { set, push, pop } action;
151 
152   if (pragma_lex (&x) != CPP_OPEN_PAREN)
153     GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored");
154 
155   token = pragma_lex (&x);
156   if (token == CPP_CLOSE_PAREN)
157     {
158       action = set;
159       align = initial_max_fld_align;
160     }
161   else if (token == CPP_NUMBER)
162     {
163       if (TREE_CODE (x) != INTEGER_CST)
164 	GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
165       align = TREE_INT_CST_LOW (x);
166       action = set;
167       if (pragma_lex (&x) != CPP_CLOSE_PAREN)
168 	GCC_BAD ("malformed %<#pragma pack%> - ignored");
169     }
170   else if (token == CPP_NAME)
171     {
172 #define GCC_BAD_ACTION do { if (action != pop) \
173 	  GCC_BAD ("malformed %<#pragma pack(push[, id][, <n>])%> - ignored"); \
174 	else \
175 	  GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \
176 	} while (0)
177 
178       const char *op = IDENTIFIER_POINTER (x);
179       if (!strcmp (op, "push"))
180 	action = push;
181       else if (!strcmp (op, "pop"))
182 	action = pop;
183       else
184 	GCC_BAD2 ("unknown action %qs for %<#pragma pack%> - ignored", op);
185 
186       while ((token = pragma_lex (&x)) == CPP_COMMA)
187 	{
188 	  token = pragma_lex (&x);
189 	  if (token == CPP_NAME && id == 0)
190 	    {
191 	      id = x;
192 	    }
193 	  else if (token == CPP_NUMBER && action == push && align == -1)
194 	    {
195 	      if (TREE_CODE (x) != INTEGER_CST)
196 		GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
197 	      align = TREE_INT_CST_LOW (x);
198 	      if (align == -1)
199 		action = set;
200 	    }
201 	  else
202 	    GCC_BAD_ACTION;
203 	}
204 
205       if (token != CPP_CLOSE_PAREN)
206 	GCC_BAD_ACTION;
207 #undef GCC_BAD_ACTION
208     }
209   else
210     GCC_BAD ("malformed %<#pragma pack%> - ignored");
211 
212   if (pragma_lex (&x) != CPP_EOF)
213     warning (OPT_Wpragmas, "junk at end of %<#pragma pack%>");
214 
215   if (flag_pack_struct)
216     GCC_BAD ("#pragma pack has no effect with -fpack-struct - ignored");
217 
218   if (action != pop)
219     switch (align)
220       {
221       case 0:
222       case 1:
223       case 2:
224       case 4:
225       case 8:
226       case 16:
227 	align *= BITS_PER_UNIT;
228 	break;
229       case -1:
230 	if (action == push)
231 	  {
232 	    align = maximum_field_alignment;
233 	    break;
234 	  }
235       default:
236 	GCC_BAD2 ("alignment must be a small power of two, not %d", align);
237       }
238 
239   switch (action)
240     {
241     case set:   SET_GLOBAL_ALIGNMENT (align);  break;
242     case push:  push_alignment (align, id);    break;
243     case pop:   pop_alignment (id);	       break;
244     }
245 }
246 #endif  /* HANDLE_PRAGMA_PACK */
247 
248 static GTY(()) tree pending_weaks;
249 
250 #ifdef HANDLE_PRAGMA_WEAK
251 static void apply_pragma_weak (tree, tree);
252 static void handle_pragma_weak (cpp_reader *);
253 
254 static void
apply_pragma_weak(tree decl,tree value)255 apply_pragma_weak (tree decl, tree value)
256 {
257   if (value)
258     {
259       value = build_string (IDENTIFIER_LENGTH (value),
260 			    IDENTIFIER_POINTER (value));
261       decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
262 					       build_tree_list (NULL, value)),
263 		       0);
264     }
265 
266   if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
267       && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma.  */
268       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
269     warning (OPT_Wpragmas, "applying #pragma weak %q+D after first use "
270 	     "results in unspecified behavior", decl);
271 
272   declare_weak (decl);
273 }
274 
275 void
maybe_apply_pragma_weak(tree decl)276 maybe_apply_pragma_weak (tree decl)
277 {
278   tree *p, t, id;
279 
280   /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed.  */
281 
282   /* No weak symbols pending, take the short-cut.  */
283   if (!pending_weaks)
284     return;
285   /* If it's not visible outside this file, it doesn't matter whether
286      it's weak.  */
287   if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl))
288     return;
289   /* If it's not a function or a variable, it can't be weak.
290      FIXME: what kinds of things are visible outside this file but
291      aren't functions or variables?   Should this be an assert instead?  */
292   if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
293     return;
294 
295   id = DECL_ASSEMBLER_NAME (decl);
296 
297   for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t))
298     if (id == TREE_PURPOSE (t))
299       {
300 	apply_pragma_weak (decl, TREE_VALUE (t));
301 	*p = TREE_CHAIN (t);
302 	break;
303       }
304 }
305 
306 /* Process all "#pragma weak A = B" directives where we have not seen
307    a decl for A.  */
308 void
maybe_apply_pending_pragma_weaks(void)309 maybe_apply_pending_pragma_weaks (void)
310 {
311   tree *p, t, alias_id, id, decl, *next;
312 
313   for (p = &pending_weaks; (t = *p) ; p = next)
314     {
315       next = &TREE_CHAIN (t);
316       alias_id = TREE_PURPOSE (t);
317       id = TREE_VALUE (t);
318 
319       if (TREE_VALUE (t) == NULL)
320 	continue;
321 
322       decl = build_decl (FUNCTION_DECL, alias_id, default_function_type);
323 
324       DECL_ARTIFICIAL (decl) = 1;
325       TREE_PUBLIC (decl) = 1;
326       DECL_EXTERNAL (decl) = 1;
327       DECL_WEAK (decl) = 1;
328 
329       assemble_alias (decl, id);
330     }
331 }
332 
333 /* #pragma weak name [= value] */
334 static void
handle_pragma_weak(cpp_reader * ARG_UNUSED (dummy))335 handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy))
336 {
337   tree name, value, x, decl;
338   enum cpp_ttype t;
339 
340   value = 0;
341 
342   if (pragma_lex (&name) != CPP_NAME)
343     GCC_BAD ("malformed #pragma weak, ignored");
344   t = pragma_lex (&x);
345   if (t == CPP_EQ)
346     {
347       if (pragma_lex (&value) != CPP_NAME)
348 	GCC_BAD ("malformed #pragma weak, ignored");
349       t = pragma_lex (&x);
350     }
351   if (t != CPP_EOF)
352     warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>");
353 
354   decl = identifier_global_value (name);
355   if (decl && DECL_P (decl))
356     {
357       apply_pragma_weak (decl, value);
358       if (value)
359 	assemble_alias (decl, value);
360     }
361   else
362     pending_weaks = tree_cons (name, value, pending_weaks);
363 }
364 #else
365 void
maybe_apply_pragma_weak(tree ARG_UNUSED (decl))366 maybe_apply_pragma_weak (tree ARG_UNUSED (decl))
367 {
368 }
369 
370 void
maybe_apply_pending_pragma_weaks(void)371 maybe_apply_pending_pragma_weaks (void)
372 {
373 }
374 #endif /* HANDLE_PRAGMA_WEAK */
375 
376 /* GCC supports two #pragma directives for renaming the external
377    symbol associated with a declaration (DECL_ASSEMBLER_NAME), for
378    compatibility with the Solaris and Tru64 system headers.  GCC also
379    has its own notation for this, __asm__("name") annotations.
380 
381    Corner cases of these features and their interaction:
382 
383    1) Both pragmas silently apply only to declarations with external
384       linkage (that is, TREE_PUBLIC || DECL_EXTERNAL).  Asm labels
385       do not have this restriction.
386 
387    2) In C++, both #pragmas silently apply only to extern "C" declarations.
388       Asm labels do not have this restriction.
389 
390    3) If any of the three ways of changing DECL_ASSEMBLER_NAME is
391       applied to a decl whose DECL_ASSEMBLER_NAME is already set, and the
392       new name is different, a warning issues and the name does not change.
393 
394    4) The "source name" for #pragma redefine_extname is the DECL_NAME,
395       *not* the DECL_ASSEMBLER_NAME.
396 
397    5) If #pragma extern_prefix is in effect and a declaration occurs
398       with an __asm__ name, the #pragma extern_prefix is silently
399       ignored for that declaration.
400 
401    6) If #pragma extern_prefix and #pragma redefine_extname apply to
402       the same declaration, whichever triggered first wins, and a warning
403       is issued.  (We would like to have #pragma redefine_extname always
404       win, but it can appear either before or after the declaration, and
405       if it appears afterward, we have no way of knowing whether a modified
406       DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.)  */
407 
408 static GTY(()) tree pending_redefine_extname;
409 
410 static void handle_pragma_redefine_extname (cpp_reader *);
411 
412 /* #pragma redefine_extname oldname newname */
413 static void
handle_pragma_redefine_extname(cpp_reader * ARG_UNUSED (dummy))414 handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy))
415 {
416   tree oldname, newname, decl, x;
417   enum cpp_ttype t;
418 
419   if (pragma_lex (&oldname) != CPP_NAME)
420     GCC_BAD ("malformed #pragma redefine_extname, ignored");
421   if (pragma_lex (&newname) != CPP_NAME)
422     GCC_BAD ("malformed #pragma redefine_extname, ignored");
423   t = pragma_lex (&x);
424   if (t != CPP_EOF)
425     warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>");
426 
427   if (!flag_mudflap && !targetm.handle_pragma_redefine_extname)
428     {
429       if (warn_unknown_pragmas > in_system_header)
430 	warning (OPT_Wunknown_pragmas,
431 		 "#pragma redefine_extname not supported on this target");
432       return;
433     }
434 
435   decl = identifier_global_value (oldname);
436   if (decl
437       && (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
438       && (TREE_CODE (decl) == FUNCTION_DECL
439 	  || TREE_CODE (decl) == VAR_DECL)
440       && has_c_linkage (decl))
441     {
442       if (DECL_ASSEMBLER_NAME_SET_P (decl))
443 	{
444 	  const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
445 	  name = targetm.strip_name_encoding (name);
446 
447 	  if (strcmp (name, IDENTIFIER_POINTER (newname)))
448 	    warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
449 		     "conflict with previous rename");
450 	}
451       else
452 	change_decl_assembler_name (decl, newname);
453     }
454   else
455     /* We have to add this to the rename list even if there's already
456        a global value that doesn't meet the above criteria, because in
457        C++ "struct foo {...};" puts "foo" in the current namespace but
458        does *not* conflict with a subsequent declaration of a function
459        or variable foo.  See g++.dg/other/pragma-re-2.C.  */
460     add_to_renaming_pragma_list (oldname, newname);
461 }
462 
463 /* This is called from here and from ia64.c.  */
464 void
add_to_renaming_pragma_list(tree oldname,tree newname)465 add_to_renaming_pragma_list (tree oldname, tree newname)
466 {
467   tree previous = purpose_member (oldname, pending_redefine_extname);
468   if (previous)
469     {
470       if (TREE_VALUE (previous) != newname)
471 	warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
472 		 "conflict with previous #pragma redefine_extname");
473       return;
474     }
475 
476   pending_redefine_extname
477     = tree_cons (oldname, newname, pending_redefine_extname);
478 }
479 
480 static GTY(()) tree pragma_extern_prefix;
481 
482 /* #pragma extern_prefix "prefix" */
483 static void
handle_pragma_extern_prefix(cpp_reader * ARG_UNUSED (dummy))484 handle_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy))
485 {
486   tree prefix, x;
487   enum cpp_ttype t;
488 
489   if (pragma_lex (&prefix) != CPP_STRING)
490     GCC_BAD ("malformed #pragma extern_prefix, ignored");
491   t = pragma_lex (&x);
492   if (t != CPP_EOF)
493     warning (OPT_Wpragmas, "junk at end of %<#pragma extern_prefix%>");
494 
495   if (targetm.handle_pragma_extern_prefix)
496     /* Note that the length includes the null terminator.  */
497     pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL);
498   else if (warn_unknown_pragmas > in_system_header)
499     warning (OPT_Wunknown_pragmas,
500 	     "#pragma extern_prefix not supported on this target");
501 }
502 
503 /* Hook from the front ends to apply the results of one of the preceding
504    pragmas that rename variables.  */
505 
506 tree
maybe_apply_renaming_pragma(tree decl,tree asmname)507 maybe_apply_renaming_pragma (tree decl, tree asmname)
508 {
509   tree *p, t;
510 
511   /* The renaming pragmas are only applied to declarations with
512      external linkage.  */
513   if ((TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
514       || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
515       || !has_c_linkage (decl))
516     return asmname;
517 
518   /* If the DECL_ASSEMBLER_NAME is already set, it does not change,
519      but we may warn about a rename that conflicts.  */
520   if (DECL_ASSEMBLER_NAME_SET_P (decl))
521     {
522       const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
523       oldname = targetm.strip_name_encoding (oldname);
524 
525       if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname))
526 	  warning (OPT_Wpragmas, "asm declaration ignored due to "
527 		   "conflict with previous rename");
528 
529       /* Take any pending redefine_extname off the list.  */
530       for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t))
531 	if (DECL_NAME (decl) == TREE_PURPOSE (t))
532 	  {
533 	    /* Only warn if there is a conflict.  */
534 	    if (strcmp (IDENTIFIER_POINTER (TREE_VALUE (t)), oldname))
535 	      warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
536 		       "conflict with previous rename");
537 
538 	    *p = TREE_CHAIN (t);
539 	    break;
540 	  }
541       return 0;
542     }
543 
544   /* Find out if we have a pending #pragma redefine_extname.  */
545   for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t))
546     if (DECL_NAME (decl) == TREE_PURPOSE (t))
547       {
548 	tree newname = TREE_VALUE (t);
549 	*p = TREE_CHAIN (t);
550 
551 	/* If we already have an asmname, #pragma redefine_extname is
552 	   ignored (with a warning if it conflicts).  */
553 	if (asmname)
554 	  {
555 	    if (strcmp (TREE_STRING_POINTER (asmname),
556 			IDENTIFIER_POINTER (newname)) != 0)
557 	      warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
558 		       "conflict with __asm__ declaration");
559 	    return asmname;
560 	  }
561 
562 	/* Otherwise we use what we've got; #pragma extern_prefix is
563 	   silently ignored.  */
564 	return build_string (IDENTIFIER_LENGTH (newname),
565 			     IDENTIFIER_POINTER (newname));
566       }
567 
568   /* If we've got an asmname, #pragma extern_prefix is silently ignored.  */
569   if (asmname)
570     return asmname;
571 
572   /* If #pragma extern_prefix is in effect, apply it.  */
573   if (pragma_extern_prefix)
574     {
575       const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix);
576       size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1;
577 
578       const char *id = IDENTIFIER_POINTER (DECL_NAME (decl));
579       size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl));
580 
581       char *newname = (char *) alloca (plen + ilen + 1);
582 
583       memcpy (newname,        prefix, plen);
584       memcpy (newname + plen, id, ilen + 1);
585 
586       return build_string (plen + ilen, newname);
587     }
588 
589   /* Nada.  */
590   return 0;
591 }
592 
593 
594 #ifdef HANDLE_PRAGMA_VISIBILITY
595 static void handle_pragma_visibility (cpp_reader *);
596 
597 typedef enum symbol_visibility visibility;
598 DEF_VEC_I (visibility);
599 DEF_VEC_ALLOC_I (visibility, heap);
VEC(visibility,heap)600 static VEC (visibility, heap) *visstack;
601 
602 /* Push the visibility indicated by STR onto the top of the #pragma
603    visibility stack.  */
604 
605 void
606 push_visibility (const char *str)
607 {
608   VEC_safe_push (visibility, heap, visstack,
609 		 default_visibility);
610   if (!strcmp (str, "default"))
611     default_visibility = VISIBILITY_DEFAULT;
612   else if (!strcmp (str, "internal"))
613     default_visibility = VISIBILITY_INTERNAL;
614   else if (!strcmp (str, "hidden"))
615     default_visibility = VISIBILITY_HIDDEN;
616   else if (!strcmp (str, "protected"))
617     default_visibility = VISIBILITY_PROTECTED;
618   else
619     GCC_BAD ("#pragma GCC visibility push() must specify default, internal, hidden or protected");
620   visibility_options.inpragma = 1;
621 }
622 
623 /* Pop a level of the #pragma visibility stack.  */
624 
625 void
pop_visibility(void)626 pop_visibility (void)
627 {
628   default_visibility = VEC_pop (visibility, visstack);
629   visibility_options.inpragma
630     = VEC_length (visibility, visstack) != 0;
631 }
632 
633 /* Sets the default visibility for symbols to something other than that
634    specified on the command line.  */
635 
636 static void
handle_pragma_visibility(cpp_reader * dummy ATTRIBUTE_UNUSED)637 handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
638 {
639   /* Form is #pragma GCC visibility push(hidden)|pop */
640   tree x;
641   enum cpp_ttype token;
642   enum { bad, push, pop } action = bad;
643 
644   token = pragma_lex (&x);
645   if (token == CPP_NAME)
646     {
647       const char *op = IDENTIFIER_POINTER (x);
648       if (!strcmp (op, "push"))
649 	action = push;
650       else if (!strcmp (op, "pop"))
651 	action = pop;
652     }
653   if (bad == action)
654     GCC_BAD ("#pragma GCC visibility must be followed by push or pop");
655   else
656     {
657       if (pop == action)
658 	{
659 	  if (!VEC_length (visibility, visstack))
660 	    GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
661 	  else
662 	    pop_visibility ();
663 	}
664       else
665 	{
666 	  if (pragma_lex (&x) != CPP_OPEN_PAREN)
667 	    GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
668 	  token = pragma_lex (&x);
669 	  if (token != CPP_NAME)
670 	    GCC_BAD ("malformed #pragma GCC visibility push");
671 	  else
672 	    push_visibility (IDENTIFIER_POINTER (x));
673 	  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
674 	    GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
675 	}
676     }
677   if (pragma_lex (&x) != CPP_EOF)
678     warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>");
679 }
680 
681 #endif
682 
683 static void
handle_pragma_diagnostic(cpp_reader * ARG_UNUSED (dummy))684 handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
685 {
686   const char *kind_string, *option_string;
687   unsigned int option_index;
688   enum cpp_ttype token;
689   diagnostic_t kind;
690   tree x;
691 
692   if (cfun)
693     {
694       warning (OPT_Wpragmas, "#pragma GCC diagnostic ignored inside functions");
695       return;
696     }
697 
698   token = pragma_lex (&x);
699   if (token != CPP_NAME)
700     GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>");
701   kind_string = IDENTIFIER_POINTER (x);
702   if (strcmp (kind_string, "error") == 0)
703     kind = DK_ERROR;
704   else if (strcmp (kind_string, "warning") == 0)
705     kind = DK_WARNING;
706   else if (strcmp (kind_string, "ignored") == 0)
707     kind = DK_IGNORED;
708   else
709     GCC_BAD ("expected [error|warning|ignored] after %<#pragma GCC diagnostic%>");
710 
711   token = pragma_lex (&x);
712   if (token != CPP_STRING)
713     GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind");
714   option_string = TREE_STRING_POINTER (x);
715   for (option_index = 0; option_index < cl_options_count; option_index++)
716     if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
717       {
718 	/* This overrides -Werror, for example.  */
719 	diagnostic_classify_diagnostic (global_dc, option_index, kind);
720 	/* This makes sure the option is enabled, like -Wfoo would do.  */
721 	if (cl_options[option_index].var_type == CLVC_BOOLEAN
722 	    && cl_options[option_index].flag_var
723 	    && kind != DK_IGNORED)
724 	    *(int *) cl_options[option_index].flag_var = 1;
725 	return;
726       }
727   GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
728 }
729 
730 /* A vector of registered pragma callbacks.  */
731 
732 DEF_VEC_O (pragma_handler);
733 DEF_VEC_ALLOC_O (pragma_handler, heap);
734 
VEC(pragma_handler,heap)735 static VEC(pragma_handler, heap) *registered_pragmas;
736 
737 /* Front-end wrappers for pragma registration to avoid dragging
738    cpplib.h in almost everywhere.  */
739 
740 static void
741 c_register_pragma_1 (const char *space, const char *name,
742 		     pragma_handler handler, bool allow_expansion)
743 {
744   unsigned id;
745 
746   VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
747   id = VEC_length (pragma_handler, registered_pragmas);
748   id += PRAGMA_FIRST_EXTERNAL - 1;
749 
750   /* The C++ front end allocates 6 bits in cp_token; the C front end
751      allocates 7 bits in c_token.  At present this is sufficient.  */
752   gcc_assert (id < 64);
753 
754   cpp_register_deferred_pragma (parse_in, space, name, id,
755 				allow_expansion, false);
756 }
757 
758 void
c_register_pragma(const char * space,const char * name,pragma_handler handler)759 c_register_pragma (const char *space, const char *name, pragma_handler handler)
760 {
761   c_register_pragma_1 (space, name, handler, false);
762 }
763 
764 void
c_register_pragma_with_expansion(const char * space,const char * name,pragma_handler handler)765 c_register_pragma_with_expansion (const char *space, const char *name,
766 				  pragma_handler handler)
767 {
768   c_register_pragma_1 (space, name, handler, true);
769 }
770 
771 void
c_invoke_pragma_handler(unsigned int id)772 c_invoke_pragma_handler (unsigned int id)
773 {
774   pragma_handler handler;
775 
776   id -= PRAGMA_FIRST_EXTERNAL;
777   handler = *VEC_index (pragma_handler, registered_pragmas, id);
778 
779   handler (parse_in);
780 }
781 
782 /* Set up front-end pragmas.  */
783 void
init_pragma(void)784 init_pragma (void)
785 {
786   if (flag_openmp && !flag_preprocess_only)
787     {
788       struct omp_pragma_def { const char *name; unsigned int id; };
789       static const struct omp_pragma_def omp_pragmas[] = {
790 	{ "atomic", PRAGMA_OMP_ATOMIC },
791 	{ "barrier", PRAGMA_OMP_BARRIER },
792 	{ "critical", PRAGMA_OMP_CRITICAL },
793 	{ "flush", PRAGMA_OMP_FLUSH },
794 	{ "for", PRAGMA_OMP_FOR },
795 	{ "master", PRAGMA_OMP_MASTER },
796 	{ "ordered", PRAGMA_OMP_ORDERED },
797 	{ "parallel", PRAGMA_OMP_PARALLEL },
798 	{ "section", PRAGMA_OMP_SECTION },
799 	{ "sections", PRAGMA_OMP_SECTIONS },
800 	{ "single", PRAGMA_OMP_SINGLE },
801 	{ "threadprivate", PRAGMA_OMP_THREADPRIVATE }
802       };
803 
804       const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
805       int i;
806 
807       for (i = 0; i < n_omp_pragmas; ++i)
808 	cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name,
809 				      omp_pragmas[i].id, true, true);
810     }
811 
812   cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
813 				PRAGMA_GCC_PCH_PREPROCESS, false, false);
814 
815 #ifdef HANDLE_PRAGMA_PACK
816 #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
817   c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
818 #else
819   c_register_pragma (0, "pack", handle_pragma_pack);
820 #endif
821 #endif
822 #ifdef HANDLE_PRAGMA_WEAK
823   c_register_pragma (0, "weak", handle_pragma_weak);
824 #endif
825 #ifdef HANDLE_PRAGMA_VISIBILITY
826   c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
827 #endif
828 
829   c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
830 
831   c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
832   c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
833 
834 #ifdef REGISTER_TARGET_PRAGMAS
835   REGISTER_TARGET_PRAGMAS ();
836 #endif
837 }
838 
839 #include "gt-c-pragma.h"
840