1 /* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
2 Copyright (C) 1992, 1997, 1998, 1999 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)
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. */
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;
43 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
44 typedef struct align_stack
47 unsigned int num_pushes;
49 struct align_stack * prev;
52 static struct align_stack * alignment_stack = NULL;
54 static int push_alignment PROTO((int, tree));
55 static int pop_alignment PROTO((tree));
57 /* Push an alignment value onto the stack. */
59 push_alignment (alignment, id)
74 Alignment must be a small power of two, not %d, in #pragma pack",
79 if (alignment_stack == NULL
80 || alignment_stack->alignment != alignment
85 entry = (align_stack *) xmalloc (sizeof (* entry));
89 warning ("Out of memory pushing #pragma pack");
93 entry->alignment = alignment;
94 entry->num_pushes = 1;
96 entry->prev = alignment_stack;
98 alignment_stack = entry;
100 maximum_field_alignment = alignment * 8;
103 alignment_stack->num_pushes ++;
108 /* Undo a push of an alignment onto the stack. */
115 if (alignment_stack == NULL)
118 #pragma pack (pop) encountered without matching #pragma pack (push, <n>)"
123 /* If we got an identifier, strip away everything above the target
124 entry so that the next step will restore the state just below it. */
127 for (entry = alignment_stack; entry; entry = entry->prev)
130 entry->num_pushes = 1;
131 alignment_stack = entry;
136 #pragma pack(pop, %s) encountered without matching #pragma pack(push, %s, <n>)"
137 , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
140 if (-- alignment_stack->num_pushes == 0)
142 entry = alignment_stack->prev;
145 maximum_field_alignment = 0;
147 maximum_field_alignment = entry->alignment * 8;
149 free (alignment_stack);
151 alignment_stack = entry;
157 /* Generate 'packed' and 'aligned' attributes for decls whilst a
158 #pragma pack(push... is in effect. */
160 insert_pack_attributes (node, attributes, prefix)
168 /* If we are not packing, then there is nothing to do. */
169 if (maximum_field_alignment == 0
170 || alignment_stack == NULL)
173 /* We are only interested in fields. */
174 if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd'
175 || TREE_CODE (node) != FIELD_DECL)
178 field_alignment = TYPE_ALIGN (TREE_TYPE (node));
179 if (field_alignment <= 0 || field_alignment > maximum_field_alignment)
180 field_alignment = maximum_field_alignment;
182 /* Add a 'packed' attribute. */
183 * attributes = tree_cons (get_identifier ("packed"), NULL, * attributes);
185 /* If the alignment is > 8 then add an alignment attribute as well. */
186 if (field_alignment > 8)
188 /* If the aligned attribute is already present then do not override it. */
189 for (a = * attributes; a; a = TREE_CHAIN (a))
191 tree name = TREE_PURPOSE (a);
192 if (strcmp (IDENTIFIER_POINTER (name), "aligned") == 0)
197 for (a = * prefix; a; a = TREE_CHAIN (a))
199 tree name = TREE_PURPOSE (a);
200 if (strcmp (IDENTIFIER_POINTER (name), "aligned") == 0)
206 * attributes = tree_cons
207 (get_identifier ("aligned"),
209 build_int_2 (field_alignment / 8, 0),
217 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
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)
237 static enum pragma_state state = ps_start;
238 static enum pragma_state type;
244 /* If we have reached the end of the #pragma directive then
245 determine what value we should return. */
258 /* The pragma was not recognised. */
261 #ifdef HANDLE_PRAGMA_PACK
263 if (state == ps_right)
265 maximum_field_alignment = align * 8;
269 warning ("malformed `#pragma pack'");
271 #endif /* HANDLE_PRAGMA_PACK */
273 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
275 if (state == ps_right)
276 ret_val = push_alignment (align, id);
278 warning ("malformed '#pragma pack(push[,id],<n>)'");
282 if (state == ps_right)
283 ret_val = pop_alignment (id);
285 warning ("malformed '#pragma pack(pop[,id])'");
287 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
289 #ifdef HANDLE_PRAGMA_WEAK
291 if (HANDLE_PRAGMA_WEAK)
293 if (state == ps_name)
294 ret_val = add_weak (name, NULL);
295 else if (state == ps_value)
296 ret_val = add_weak (name, value);
298 warning ("malformed `#pragma weak'");
301 ret_val = 1; /* Ignore the pragma. */
303 #endif /* HANDLE_PRAGMA_WEAK */
306 type = state = ps_start;
312 /* If we have been given a token, but it is not an identifier,
313 or a small constant, then something has gone wrong. */
316 switch (TREE_CODE (token))
318 case IDENTIFIER_NODE:
322 if (TREE_INT_CST_HIGH (token) != 0)
334 type = state = ps_done;
335 #ifdef HANDLE_PRAGMA_PACK
336 if (strcmp (string, "pack") == 0)
337 type = state = ps_pack;
339 #ifdef HANDLE_PRAGMA_WEAK
340 if (strcmp (string, "weak") == 0)
341 type = state = ps_weak;
345 #ifdef HANDLE_PRAGMA_WEAK
347 name = permalloc (strlen (string) + 1);
350 warning ("Out of memory parsing #pragma weak");
355 strcpy (name, string);
361 state = (strcmp (string, "=") ? ps_bad : ps_equals);
365 value = permalloc (strlen (string) + 1);
368 warning ("Out of memory parsing #pragma weak");
373 strcpy (value, string);
381 #endif /* HANDLE_PRAGMA_WEAK */
383 #ifdef HANDLE_PRAGMA_PACK
385 state = (strcmp (string, "(") ? ps_bad : ps_left);
390 if (token == NULL_TREE)
392 /* #pragma pack () resets packing rules to their
394 if (strcmp (string, ")") == 0)
402 else if (TREE_CODE (token) == INTEGER_CST)
405 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
406 else if (TREE_CODE (token) == IDENTIFIER_NODE)
408 if (strcmp (string, "push") == 0)
409 type = state = ps_push;
410 else if (strcmp (string, "pop") == 0)
411 type = state = ps_pop;
421 align = TREE_INT_CST_LOW (token);
439 state = (strcmp (string, ")") ? ps_bad : ps_right);
445 #endif /* HANDLE_PRAGMA_PACK */
447 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
449 state = (strcmp (string, ",") ? ps_bad : ps_pushcomma);
453 state = (strcmp (string, ",") ? ps_bad : ps_pushcomma2);
457 if (token && TREE_CODE (token) == IDENTIFIER_NODE)
464 /* else fall through */
466 if (token && TREE_CODE (token) == INTEGER_CST)
473 if (strcmp (string, ",") == 0)
476 state = (strcmp (string, ")") ? ps_bad : ps_right);
480 if (token && TREE_CODE (token) == IDENTIFIER_NODE)
488 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
500 #endif /* HANDLE_GENERIC_PRAGMAS */