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)
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;
48 struct align_stack * prev;
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. */
58 push_alignment (alignment)
72 Alignment must be a small power of two, not %d, in #pragma pack",
77 if (alignment_stack == NULL
78 || alignment_stack->alignment != alignment)
82 entry = (align_stack *) xmalloc (sizeof (* entry));
86 warning ("Out of memory pushing #pragma pack");
90 entry->alignment = alignment;
91 entry->num_pushes = 1;
92 entry->prev = alignment_stack;
94 alignment_stack = entry;
97 maximum_field_alignment = alignment * 8;
99 /* MSVC ignores alignments > 4. */
100 maximum_field_alignment = 0;
103 alignment_stack->num_pushes ++;
108 /* Undo a push of an alignment onto the stack. */
112 if (alignment_stack == NULL)
115 #pragma pack(pop) encountered without corresponding #pragma pack(push,<n>)");
119 if (-- alignment_stack->num_pushes == 0)
123 entry = alignment_stack->prev;
125 if (entry == NULL || entry->alignment > 4)
126 maximum_field_alignment = 0;
128 maximum_field_alignment = entry->alignment * 8;
130 free (alignment_stack);
132 alignment_stack = entry;
138 /* Generate 'packed' and 'aligned' attributes for decls whilst a
139 #pragma pack(push... is in effect. */
141 insert_pack_attributes (node, attributes, prefix)
148 /* If we are not packing, then there is nothing to do. */
149 if (maximum_field_alignment == 0
150 || alignment_stack == NULL)
153 /* We are only interested in fields. */
154 if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd'
155 || TREE_CODE (node) != FIELD_DECL)
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)
173 for (a = * prefix; a; a = TREE_CHAIN (a))
175 tree name = TREE_PURPOSE (a);
176 if (strcmp (IDENTIFIER_POINTER (name), "aligned") == 0)
182 * attributes = tree_cons
183 (get_identifier ("aligned"),
185 build_int_2 (maximum_field_alignment / 8, 0),
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)
213 static enum pragma_state state = ps_start;
214 static enum pragma_state type;
219 /* If we have reached the end of the #pragma directive then
220 determine what value we should return. */
233 /* The pragma was not recognised. */
236 #ifdef HANDLE_PRAGMA_PACK
238 if (state == ps_right)
240 maximum_field_alignment = align * 8;
244 warning ("malformed `#pragma pack'");
246 #endif /* HANDLE_PRAGMA_PACK */
248 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
250 if (state == ps_right)
251 ret_val = push_alignment (align);
253 warning ("incomplete '#pragma pack(push,<n>)'");
257 if (state == ps_right)
258 ret_val = pop_alignment ();
260 warning ("missing closing parenthesis in '#pragma pack(pop)'");
262 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
264 #ifdef HANDLE_PRAGMA_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);
273 warning ("malformed `#pragma weak'");
276 ret_val = 1; /* Ignore the pragma. */
278 #endif /* HANDLE_PRAGMA_WEAK */
281 type = state = ps_start;
286 /* If we have been given a token, but it is not an identifier,
287 or a small constant, then something has gone wrong. */
290 switch (TREE_CODE (token))
292 case IDENTIFIER_NODE:
296 if (TREE_INT_CST_HIGH (token) != 0)
308 type = state = ps_done;
309 #ifdef HANDLE_PRAGMA_PACK
310 if (strcmp (string, "pack") == 0)
311 type = state = ps_pack;
313 #ifdef HANDLE_PRAGMA_WEAK
314 if (strcmp (string, "weak") == 0)
315 type = state = ps_weak;
319 #ifdef HANDLE_PRAGMA_WEAK
321 name = permalloc (strlen (string) + 1);
324 warning ("Out of memory parsing #pragma weak");
329 strcpy (name, string);
335 state = (strcmp (string, "=") ? ps_bad : ps_equals);
339 value = permalloc (strlen (string) + 1);
342 warning ("Out of memory parsing #pragma weak");
347 strcpy (value, string);
355 #endif /* HANDLE_PRAGMA_WEAK */
357 #ifdef HANDLE_PRAGMA_PACK
359 state = (strcmp (string, "(") ? ps_bad : ps_left);
364 if (token && TREE_CODE(token) == INTEGER_CST)
365 align = TREE_INT_CST_LOW(token);
367 align = atoi (string);
377 state = (strcmp (string, ")") ? ps_bad : ps_right);
378 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
381 if (strcmp (string, "push") == 0)
382 type = state = ps_push;
383 else if (strcmp (string, "pop") == 0)
384 type = state = ps_pop;
395 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
399 state = (strcmp (string, ")") ? ps_bad : ps_right);
405 #endif /* HANDLE_PRAGMA_PACK */
407 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
409 state = (strcmp (string, ",") ? ps_bad : ps_comma);
413 align = atoi (string);
416 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
428 #endif /* HANDLE_GENERIC_PRAGMAS */