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
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING.  If not, write to the Free
19Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2002110-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
47typedef struct align_stack GTY(())
48{
49  int		       alignment;
50  tree		       id;
51  struct align_stack * prev;
52} align_stack;
53
54static GTY(()) struct align_stack * alignment_stack;
55
56#ifdef HANDLE_PRAGMA_PACK
57static 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.  */
65static int default_alignment;
66#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \
67	? &default_alignment \
68	: &alignment_stack->alignment) = (ALIGN))
69
70static void push_alignment (int, tree);
71static void pop_alignment (tree);
72
73/* Push an alignment value onto the stack.  */
74static void
75push_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.  */
97static void
98pop_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) */
144static void
145handle_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
248static GTY(()) tree pending_weaks;
249
250#ifdef HANDLE_PRAGMA_WEAK
251static void apply_pragma_weak (tree, tree);
252static void handle_pragma_weak (cpp_reader *);
253
254static void
255apply_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
275void
276maybe_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.  */
308void
309maybe_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] */
334static void
335handle_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
365void
366maybe_apply_pragma_weak (tree ARG_UNUSED (decl))
367{
368}
369
370void
371maybe_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
408static GTY(()) tree pending_redefine_extname;
409
410static void handle_pragma_redefine_extname (cpp_reader *);
411
412/* #pragma redefine_extname oldname newname */
413static void
414handle_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.  */
464void
465add_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
480static GTY(()) tree pragma_extern_prefix;
481
482/* #pragma extern_prefix "prefix" */
483static void
484handle_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
506tree
507maybe_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
595static void handle_pragma_visibility (cpp_reader *);
596
597typedef enum symbol_visibility visibility;
598DEF_VEC_I (visibility);
599DEF_VEC_ALLOC_I (visibility, heap);
600static VEC (visibility, heap) *visstack;
601
602/* Push the visibility indicated by STR onto the top of the #pragma
603   visibility stack.  */
604
605void
606push_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
625void
626pop_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
636static void
637handle_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
683static void
684handle_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
732DEF_VEC_O (pragma_handler);
733DEF_VEC_ALLOC_O (pragma_handler, heap);
734
735static VEC(pragma_handler, heap) *registered_pragmas;
736
737/* Front-end wrappers for pragma registration to avoid dragging
738   cpplib.h in almost everywhere.  */
739
740static void
741c_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
758void
759c_register_pragma (const char *space, const char *name, pragma_handler handler)
760{
761  c_register_pragma_1 (space, name, handler, false);
762}
763
764void
765c_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
771void
772c_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.  */
783void
784init_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