* configure: Rebuilt.
[official-gcc.git] / gcc / c-pragma.c
blob09fac1feaabd0e4b9cb8a8fa755724bc1cc73f4f
1 /* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
2 Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
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"
32 #ifdef HANDLE_GENERIC_PRAGMAS
34 #ifdef HANDLE_PRAGMA_PACK
35 /* When structure field packing is in effect, this variable is the
36 number of bits to use as the maximum alignment. When packing is not
37 in effect, this is zero. */
39 extern int maximum_field_alignment;
40 #endif
43 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
44 typedef struct align_stack
46 int alignment;
47 unsigned int num_pushes;
48 struct align_stack * prev;
49 } align_stack;
51 static struct align_stack * alignment_stack = NULL;
53 static int push_alignment PROTO((int));
54 static int pop_alignment PROTO((void));
56 /* Push an alignment value onto the stack. */
57 static int
58 push_alignment (alignment)
59 int alignment;
61 switch (alignment)
63 case 0:
64 case 1:
65 case 2:
66 case 4:
67 case 8:
68 case 16:
69 break;
70 default:
71 warning ("\
72 Alignment must be a small power of two, not %d, in #pragma pack",
73 alignment);
74 return 0;
77 if (alignment_stack == NULL
78 || alignment_stack->alignment != alignment)
80 align_stack * entry;
82 entry = (align_stack *) xmalloc (sizeof (* entry));
84 if (entry == NULL)
86 warning ("Out of memory pushing #pragma pack");
87 return 0;
90 entry->alignment = alignment;
91 entry->num_pushes = 1;
92 entry->prev = alignment_stack;
94 alignment_stack = entry;
96 if (alignment < 8)
97 maximum_field_alignment = alignment * 8;
98 else
99 /* MSVC ignores alignments > 4. */
100 maximum_field_alignment = 0;
102 else
103 alignment_stack->num_pushes ++;
105 return 1;
108 /* Undo a push of an alignment onto the stack. */
109 static int
110 pop_alignment ()
112 if (alignment_stack == NULL)
114 warning ("\
115 #pragma pack(pop) encountered without corresponding #pragma pack(push,<n>)");
116 return 0;
119 if (-- alignment_stack->num_pushes == 0)
121 align_stack * entry;
123 entry = alignment_stack->prev;
125 if (entry == NULL || entry->alignment > 4)
126 maximum_field_alignment = 0;
127 else
128 maximum_field_alignment = entry->alignment * 8;
130 free (alignment_stack);
132 alignment_stack = entry;
135 return 1;
138 /* Generate 'packed' and 'aligned' attributes for decls whilst a
139 #pragma pack(push... is in effect. */
140 void
141 insert_pack_attributes (node, attributes, prefix)
142 tree node;
143 tree * attributes;
144 tree * prefix;
146 tree a;
148 /* If we are not packing, then there is nothing to do. */
149 if (maximum_field_alignment == 0
150 || alignment_stack == NULL)
151 return;
153 /* We are only interested in fields. */
154 if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd'
155 || TREE_CODE (node) != FIELD_DECL)
156 return;
158 /* Add a 'packed' attribute. */
159 * attributes = tree_cons (get_identifier ("packed"), NULL, * attributes);
161 /* If the alignment is > 8 then add an alignment attribute as well. */
162 if (maximum_field_alignment > 8)
164 /* If the aligned attribute is already present then do not override it. */
165 for (a = * attributes; a; a = TREE_CHAIN (a))
167 tree name = TREE_PURPOSE (a);
168 if (strcmp (IDENTIFIER_POINTER (name), "aligned") == 0)
169 break;
172 if (a == NULL)
173 for (a = * prefix; a; a = TREE_CHAIN (a))
175 tree name = TREE_PURPOSE (a);
176 if (strcmp (IDENTIFIER_POINTER (name), "aligned") == 0)
177 break;
180 if (a == NULL)
182 * attributes = tree_cons
183 (get_identifier ("aligned"),
184 tree_cons (NULL,
185 build_int_2 (maximum_field_alignment / 8, 0),
186 NULL),
187 * attributes);
191 return;
193 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
195 /* Handle one token of a pragma directive. TOKEN is the current token, and
196 STRING is its printable form. Some front ends do not support generating
197 tokens, and will only pass in a STRING. Also some front ends will reuse
198 the buffer containing STRING, so it must be copied to a local buffer if
199 it needs to be preserved.
201 If STRING is non-NULL, then the return value will be ignored, and there
202 will be futher calls to handle_pragma_token() in order to handle the rest of
203 the line containing the #pragma directive. If STRING is NULL, the entire
204 line has now been presented to handle_pragma_token() and the return value
205 should be zero if the pragma flawed in some way, or if the pragma was not
206 recognised, and non-zero if it was successfully handled. */
209 handle_pragma_token (string, token)
210 const char * string;
211 tree token;
213 static enum pragma_state state = ps_start;
214 static enum pragma_state type;
215 static char * name;
216 static char * value;
217 static int align;
219 /* If we have reached the end of the #pragma directive then
220 determine what value we should return. */
222 if (string == NULL)
224 int ret_val = 0;
226 switch (type)
228 default:
229 abort ();
230 break;
232 case ps_done:
233 /* The pragma was not recognised. */
234 break;
236 #ifdef HANDLE_PRAGMA_PACK
237 case ps_pack:
238 if (state == ps_right)
240 maximum_field_alignment = align * 8;
241 ret_val = 1;
243 else
244 warning ("malformed `#pragma pack'");
245 break;
246 #endif /* HANDLE_PRAGMA_PACK */
248 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
249 case ps_push:
250 if (state == ps_right)
251 ret_val = push_alignment (align);
252 else
253 warning ("incomplete '#pragma pack(push,<n>)'");
254 break;
256 case ps_pop:
257 if (state == ps_right)
258 ret_val = pop_alignment ();
259 else
260 warning ("missing closing parenthesis in '#pragma pack(pop)'");
261 break;
262 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
264 #ifdef HANDLE_PRAGMA_WEAK
265 case ps_weak:
266 if (HANDLE_PRAGMA_WEAK)
268 if (state == ps_name)
269 ret_val = add_weak (name, NULL);
270 else if (state == ps_value)
271 ret_val = add_weak (name, value);
272 else
273 warning ("malformed `#pragma weak'");
275 else
276 ret_val = 1; /* Ignore the pragma. */
277 break;
278 #endif /* HANDLE_PRAGMA_WEAK */
281 type = state = ps_start;
283 return ret_val;
286 /* If we have been given a token, but it is not an identifier,
287 or a small constant, then something has gone wrong. */
288 if (token)
290 switch (TREE_CODE (token))
292 case IDENTIFIER_NODE:
293 break;
295 case INTEGER_CST:
296 if (TREE_INT_CST_HIGH (token) != 0)
297 return 0;
298 break;
300 default:
301 return 0;
305 switch (state)
307 case ps_start:
308 type = state = ps_done;
309 #ifdef HANDLE_PRAGMA_PACK
310 if (strcmp (string, "pack") == 0)
311 type = state = ps_pack;
312 #endif
313 #ifdef HANDLE_PRAGMA_WEAK
314 if (strcmp (string, "weak") == 0)
315 type = state = ps_weak;
316 #endif
317 break;
319 #ifdef HANDLE_PRAGMA_WEAK
320 case ps_weak:
321 name = permalloc (strlen (string) + 1);
322 if (name == NULL)
324 warning ("Out of memory parsing #pragma weak");
325 state = ps_bad;
327 else
329 strcpy (name, string);
330 state = ps_name;
332 break;
334 case ps_name:
335 state = (strcmp (string, "=") ? ps_bad : ps_equals);
336 break;
338 case ps_equals:
339 value = permalloc (strlen (string) + 1);
340 if (value == NULL)
342 warning ("Out of memory parsing #pragma weak");
343 state = ps_bad;
345 else
347 strcpy (value, string);
348 state = ps_value;
350 break;
352 case ps_value:
353 state = ps_bad;
354 break;
355 #endif /* HANDLE_PRAGMA_WEAK */
357 #ifdef HANDLE_PRAGMA_PACK
358 case ps_pack:
359 state = (strcmp (string, "(") ? ps_bad : ps_left);
360 break;
362 case ps_left:
364 if (token && TREE_CODE(token) == INTEGER_CST)
365 align = TREE_INT_CST_LOW(token);
366 else
367 align = atoi (string);
368 switch (align)
370 case 1:
371 case 2:
372 case 4:
373 state = ps_align;
374 break;
376 case 0:
377 state = (strcmp (string, ")") ? ps_bad : ps_right);
378 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
379 if (state == ps_bad)
381 if (strcmp (string, "push") == 0)
382 type = state = ps_push;
383 else if (strcmp (string, "pop") == 0)
384 type = state = ps_pop;
386 #endif
387 break;
389 default:
390 state = ps_bad;
391 break;
393 break;
395 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
396 case ps_pop:
397 #endif
398 case ps_align:
399 state = (strcmp (string, ")") ? ps_bad : ps_right);
400 break;
402 case ps_right:
403 state = ps_bad;
404 break;
405 #endif /* HANDLE_PRAGMA_PACK */
407 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
408 case ps_push:
409 state = (strcmp (string, ",") ? ps_bad : ps_comma);
410 break;
412 case ps_comma:
413 align = atoi (string);
414 state = ps_align;
415 break;
416 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
418 case ps_bad:
419 case ps_done:
420 break;
422 default:
423 abort ();
426 return 1;
428 #endif /* HANDLE_GENERIC_PRAGMAS */