c-pragma.c revision 50397
1/* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
2   Copyright (C) 1992, 1997 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.  */
20
21#include "config.h"
22#include "system.h"
23#include "rtl.h"
24#include "tree.h"
25#include "except.h"
26#include "function.h"
27#include "defaults.h"
28#include "c-pragma.h"
29#include "flags.h"
30#include "toplev.h"
31
32#ifdef HANDLE_SYSV_PRAGMA
33
34/* When structure field packing is in effect, this variable is the
35   number of bits to use as the maximum alignment.  When packing is not
36   in effect, this is zero.  */
37
38extern int maximum_field_alignment;
39
40/* File used for outputting assembler code.  */
41extern FILE *asm_out_file;
42
43/* Handle one token of a pragma directive.  TOKEN is the
44   current token, and STRING is its printable form.  */
45
46void
47handle_pragma_token (string, token)
48     char *string;
49     tree token;
50{
51  static enum pragma_state state = ps_start, type;
52  static char *name;
53  static char *value;
54  static int align;
55
56  if (string == 0)
57    {
58      if (type == ps_pack)
59	{
60	  if (state == ps_right)
61	    maximum_field_alignment = align * 8;
62	  else
63	    warning ("malformed `#pragma pack'");
64	}
65      else if (type == ps_weak)
66	{
67#ifdef HANDLE_PRAGMA_WEAK
68	  if (HANDLE_PRAGMA_WEAK)
69	    handle_pragma_weak (state, name, value);
70
71#endif /* HANDLE_PRAGMA_WEAK */
72	}
73
74      type = state = ps_start;
75      return;
76    }
77
78  switch (state)
79    {
80    case ps_start:
81      if (token && TREE_CODE (token) == IDENTIFIER_NODE)
82	{
83	  if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0)
84	    type = state = ps_pack;
85	  else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
86	    type = state = ps_weak;
87	  else
88	    {
89	      type = state = ps_done;
90
91	      /* Issue a warning message if we have been asked to do so.
92		 Ignoring unknown pragmas in system header file unless
93		 an explcit -Wunknown-pragmas has been given. */
94	      if (warn_unknown_pragmas > 1
95		  || (warn_unknown_pragmas && ! in_system_header))
96		warning ("ignoring pragma: %s", string);
97	    }
98	}
99      else
100	type = state = ps_done;
101      break;
102
103    case ps_weak:
104      if (token && TREE_CODE (token) == IDENTIFIER_NODE)
105	{
106	  name = IDENTIFIER_POINTER (token);
107	  state = ps_name;
108	}
109      else
110	state = ps_bad;
111      break;
112
113    case ps_name:
114      state = (strcmp (string, "=") ? ps_bad : ps_equals);
115      break;
116
117    case ps_equals:
118      if (token && TREE_CODE (token) == IDENTIFIER_NODE)
119	{
120	  value = IDENTIFIER_POINTER (token);
121	  state = ps_value;
122	}
123      else
124	state = ps_bad;
125      break;
126
127    case ps_value:
128      state = ps_bad;
129      break;
130
131    case ps_pack:
132      if (strcmp (string, "(") == 0)
133	state = ps_left;
134      else
135	state = ps_bad;
136      break;
137
138    case ps_left:
139      if (token && TREE_CODE (token) == INTEGER_CST
140	  && TREE_INT_CST_HIGH (token) == 0)
141	switch (TREE_INT_CST_LOW (token))
142	  {
143	  case 1:
144	  case 2:
145	  case 4:
146	    align = TREE_INT_CST_LOW (token);
147	    state = ps_align;
148	    break;
149
150	  default:
151	    state = ps_bad;
152	  }
153      else if (! token && strcmp (string, ")") == 0)
154	{
155	  align = 0;
156	  state = ps_right;
157	}
158      else
159	state = ps_bad;
160      break;
161
162    case ps_align:
163      if (strcmp (string, ")") == 0)
164	state = ps_right;
165      else
166	state = ps_bad;
167      break;
168
169    case ps_right:
170      state = ps_bad;
171      break;
172
173    case ps_bad:
174    case ps_done:
175      break;
176
177    default:
178      abort ();
179    }
180}
181#endif /* HANDLE_SYSV_PRAGMA */
182