* gjavah.c (main): Handle --output-class-directory argument.
[official-gcc.git] / gcc / c-pragma.c
blobf9bfbe7987bf8667c368b7c8948badd29f160824
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 #ifdef HANDLE_PRAGMA_WEAK
196 static int add_weak PROTO((char *, char *));
198 static int
199 add_weak (name, value)
200 char * name;
201 char * value;
203 struct weak_syms * weak;
205 weak = (struct weak_syms *) permalloc (sizeof (struct weak_syms));
207 if (weak == NULL)
208 return 0;
210 weak->next = weak_decls;
211 weak->name = name;
212 weak->value = value;
213 weak_decls = weak;
215 return 1;
217 #endif /* HANDLE_PRAGMA_WEAK */
219 /* Handle one token of a pragma directive. TOKEN is the current token, and
220 STRING is its printable form. Some front ends do not support generating
221 tokens, and will only pass in a STRING. Also some front ends will reuse
222 the buffer containing STRING, so it must be copied to a local buffer if
223 it needs to be preserved.
225 If STRING is non-NULL, then the return value will be ignored, and there
226 will be futher calls to handle_pragma_token() in order to handle the rest of
227 the line containing the #pragma directive. If STRING is NULL, the entire
228 line has now been presented to handle_pragma_token() and the return value
229 should be zero if the pragma flawed in some way, or if the pragma was not
230 recognised, and non-zero if it was successfully handled. */
233 handle_pragma_token (string, token)
234 char * string;
235 tree token;
237 static enum pragma_state state = ps_start;
238 static enum pragma_state type;
239 static char * name;
240 static char * value;
241 static int align;
243 /* If we have reached the end of the #pragma directive then
244 determine what value we should return. */
246 if (string == NULL)
248 int ret_val = 0;
250 switch (type)
252 default:
253 abort ();
254 break;
256 case ps_done:
257 /* The pragma was not recognised. */
258 break;
260 #ifdef HANDLE_PRAGMA_PACK
261 case ps_pack:
262 if (state == ps_right)
264 maximum_field_alignment = align * 8;
265 ret_val = 1;
267 else
268 warning ("malformed `#pragma pack'");
269 break;
270 #endif /* HANDLE_PRAGMA_PACK */
272 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
273 case ps_push:
274 if (state == ps_right)
275 ret_val = push_alignment (align);
276 else
277 warning ("incomplete '#pragma pack(push,<n>)'");
278 break;
280 case ps_pop:
281 if (state == ps_right)
282 ret_val = pop_alignment ();
283 else
284 warning ("missing closing parenthesis in '#pragma pack(pop)'");
285 break;
286 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
288 #ifdef HANDLE_PRAGMA_WEAK
289 case ps_weak:
290 if (HANDLE_PRAGMA_WEAK)
292 if (state == ps_name)
293 ret_val = add_weak (name, NULL);
294 else if (state == ps_value)
295 ret_val = add_weak (name, value);
296 else
297 warning ("malformed `#pragma weak'");
299 else
300 ret_val = 1; /* Ignore the pragma. */
301 break;
302 #endif /* HANDLE_PRAGMA_WEAK */
305 type = state = ps_start;
307 return ret_val;
310 /* If we have been given a token, but it is not an identifier,
311 or a small constant, then something has gone wrong. */
312 if (token)
314 switch (TREE_CODE (token))
316 case IDENTIFIER_NODE:
317 break;
319 case INTEGER_CST:
320 if (TREE_INT_CST_HIGH (token) != 0)
321 return 0;
322 break;
324 default:
325 return 0;
329 switch (state)
331 case ps_start:
332 type = state = ps_done;
333 #ifdef HANDLE_PRAGMA_PACK
334 if (strcmp (string, "pack") == 0)
335 type = state = ps_pack;
336 #endif
337 #ifdef HANDLE_PRAGMA_WEAK
338 if (strcmp (string, "weak") == 0)
339 type = state = ps_weak;
340 #endif
341 break;
343 #ifdef HANDLE_PRAGMA_WEAK
344 case ps_weak:
345 name = permalloc (strlen (string) + 1);
346 if (name == NULL)
348 warning ("Out of memory parsing #pragma weak");
349 state = ps_bad;
351 else
353 strcpy (name, string);
354 state = ps_name;
356 break;
358 case ps_name:
359 state = (strcmp (string, "=") ? ps_bad : ps_equals);
360 break;
362 case ps_equals:
363 value = permalloc (strlen (string) + 1);
364 if (value == NULL)
366 warning ("Out of memory parsing #pragma weak");
367 state = ps_bad;
369 else
371 strcpy (value, string);
372 state = ps_value;
374 break;
376 case ps_value:
377 state = ps_bad;
378 break;
379 #endif /* HANDLE_PRAGMA_WEAK */
381 #ifdef HANDLE_PRAGMA_PACK
382 case ps_pack:
383 state = (strcmp (string, "(") ? ps_bad : ps_left);
384 break;
386 case ps_left:
388 if (token && TREE_CODE(token) == INTEGER_CST)
389 align = TREE_INT_CST_LOW(token);
390 else
391 align = atoi (string);
392 switch (align)
394 case 1:
395 case 2:
396 case 4:
397 state = ps_align;
398 break;
400 case 0:
401 state = (strcmp (string, ")") ? ps_bad : ps_right);
402 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
403 if (state == ps_bad)
405 if (strcmp (string, "push") == 0)
406 type = state = ps_push;
407 else if (strcmp (string, "pop") == 0)
408 type = state = ps_pop;
410 #endif
411 break;
413 default:
414 state = ps_bad;
415 break;
417 break;
419 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
420 case ps_pop:
421 #endif
422 case ps_align:
423 state = (strcmp (string, ")") ? ps_bad : ps_right);
424 break;
426 case ps_right:
427 state = ps_bad;
428 break;
429 #endif /* HANDLE_PRAGMA_PACK */
431 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
432 case ps_push:
433 state = (strcmp (string, ",") ? ps_bad : ps_comma);
434 break;
436 case ps_comma:
437 align = atoi (string);
438 state = ps_align;
439 break;
440 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
442 case ps_bad:
443 case ps_done:
444 break;
446 default:
447 abort ();
450 return 1;
452 #endif /* HANDLE_GENERIC_PRAGMAS */