OSDN Git Service

2007-03-01 Paul Brook <paul@codesourcery.com>
[pf3gnuchains/gcc-fork.git] / gcc / c-pragma.c
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
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
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
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
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
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
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
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
366 maybe_apply_pragma_weak (tree ARG_UNUSED (decl))
367 {
368 }
369
370 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
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
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
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
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);
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
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
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
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       error ("#pragma GCC diagnostic not allowed 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
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
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
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
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
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"