1 /* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
2 Copyright (C) 1992, 1997, 1998, 1999, 2000 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_PUSH_POP
35 typedef struct align_stack
38 unsigned int num_pushes;
40 struct align_stack * prev;
43 static struct align_stack * alignment_stack = NULL;
45 /* If we have a "global" #pragma pack(<n>) if effect when the first
46 #pragma push(pack,<n>) is encountered, this stores the the value of
47 maximum_field_alignment in effect. When the final pop_alignment()
48 happens, we restore the value to this, not to a value of 0 for
49 maximum_field_alignment. Value is in bits. */
50 static int default_alignment;
52 static int push_alignment PARAMS ((int, tree));
53 static int pop_alignment PARAMS ((tree));
54 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
55 static void mark_align_stack PARAMS ((void *));
58 /* Push an alignment value onto the stack. */
60 push_alignment (alignment, id)
75 Alignment must be a small power of two, not %d, in #pragma pack",
80 if (alignment_stack == NULL
81 || alignment_stack->alignment != alignment
86 entry = (align_stack *) xmalloc (sizeof (* entry));
88 entry->alignment = alignment;
89 entry->num_pushes = 1;
91 entry->prev = alignment_stack;
93 /* The current value of maximum_field_alignment is not necessarily
94 0 since there may be a #pragma pack(<n>) in effect; remember it
95 so that we can restore it after the final #pragma pop(). */
96 if (alignment_stack == NULL)
97 default_alignment = maximum_field_alignment;
99 alignment_stack = entry;
101 maximum_field_alignment = alignment * 8;
104 alignment_stack->num_pushes ++;
109 /* Undo a push of an alignment onto the stack. */
116 if (alignment_stack == NULL)
119 #pragma pack (pop) encountered without matching #pragma pack (push, <n>)"
124 /* If we got an identifier, strip away everything above the target
125 entry so that the next step will restore the state just below it. */
128 for (entry = alignment_stack; entry; entry = entry->prev)
131 entry->num_pushes = 1;
132 alignment_stack = entry;
137 #pragma pack(pop, %s) encountered without matching #pragma pack(push, %s, <n>)"
138 , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
141 if (-- alignment_stack->num_pushes == 0)
143 entry = alignment_stack->prev;
146 maximum_field_alignment = default_alignment;
148 maximum_field_alignment = entry->alignment * 8;
150 free (alignment_stack);
152 alignment_stack = entry;
157 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
159 /* Handle one token of a pragma directive. TOKEN is the current token, and
160 STRING is its printable form. Some front ends do not support generating
161 tokens, and will only pass in a STRING. Also some front ends will reuse
162 the buffer containing STRING, so it must be copied to a local buffer if
163 it needs to be preserved.
165 If STRING is non-NULL, then the return value will be ignored, and there
166 will be futher calls to handle_pragma_token in order to handle the rest of
167 the line containing the #pragma directive. If STRING is NULL, the entire
168 line has now been presented to handle_pragma_token and the return value
169 should be zero if the pragma flawed in some way, or if the pragma was not
170 recognised, and non-zero if it was successfully handled. */
173 handle_pragma_token (string, token)
177 static enum pragma_state state = ps_start;
178 static enum pragma_state type;
179 #ifdef HANDLE_PRAGMA_WEAK
183 #if defined(HANDLE_PRAGMA_PACK) || defined(HANDLE_PRAGMA_PACK_PUSH_POP)
184 static unsigned int align;
188 /* If we have reached the end of the #pragma directive then
189 determine what value we should return. */
202 /* The pragma was not recognised. */
205 #ifdef HANDLE_PRAGMA_PACK
207 if (state == ps_right)
209 maximum_field_alignment = align * 8;
210 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
211 default_alignment = maximum_field_alignment;
216 warning ("malformed `#pragma pack'");
218 #endif /* HANDLE_PRAGMA_PACK */
220 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
222 if (state == ps_right)
223 ret_val = push_alignment (align, id);
225 warning ("malformed '#pragma pack(push[,id],<n>)'");
229 if (state == ps_right)
230 ret_val = pop_alignment (id);
232 warning ("malformed '#pragma pack(pop[,id])'");
234 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
236 #ifdef HANDLE_PRAGMA_WEAK
238 if (HANDLE_PRAGMA_WEAK)
240 if (state == ps_name)
241 ret_val = add_weak (name, NULL);
242 else if (state == ps_value)
243 ret_val = add_weak (name, value);
245 warning ("malformed `#pragma weak'");
248 ret_val = 1; /* Ignore the pragma. */
250 #endif /* HANDLE_PRAGMA_WEAK */
257 type = state = ps_start;
263 /* If we have been given a token, but it is not an identifier,
264 or a small constant, then something has gone wrong. */
267 switch (TREE_CODE (token))
269 case IDENTIFIER_NODE:
273 if (TREE_INT_CST_HIGH (token) != 0)
285 type = state = ps_done;
286 #ifdef HANDLE_PRAGMA_PACK
287 if (strcmp (string, "pack") == 0)
288 type = state = ps_pack;
290 #ifdef HANDLE_PRAGMA_WEAK
291 if (strcmp (string, "weak") == 0)
292 type = state = ps_weak;
294 if (strcmp (string, "poison") == 0)
295 type = state = ps_poison;
298 #ifdef HANDLE_PRAGMA_WEAK
300 name = xstrdup (string);
305 state = (strcmp (string, "=") ? ps_bad : ps_equals);
309 value = xstrdup (string);
316 #endif /* HANDLE_PRAGMA_WEAK */
318 #ifdef HANDLE_PRAGMA_PACK
320 state = (strcmp (string, "(") ? ps_bad : ps_left);
325 if (token == NULL_TREE)
327 /* #pragma pack () resets packing rules to their
329 if (strcmp (string, ")") == 0)
337 else if (TREE_CODE (token) == INTEGER_CST)
340 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
341 else if (TREE_CODE (token) == IDENTIFIER_NODE)
343 if (strcmp (string, "push") == 0)
344 type = state = ps_push;
345 else if (strcmp (string, "pop") == 0)
346 type = state = ps_pop;
356 switch (tree_log2 (token))
364 align = 1 << tree_log2 (token);
374 state = (strcmp (string, ")") ? ps_bad : ps_right);
380 #endif /* HANDLE_PRAGMA_PACK */
382 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
384 state = (strcmp (string, ",") ? ps_bad : ps_pushcomma);
388 state = (strcmp (string, ",") ? ps_bad : ps_pushcomma2);
392 if (token && TREE_CODE (token) == IDENTIFIER_NODE)
399 /* else fall through */
401 if (token && TREE_CODE (token) == INTEGER_CST)
408 if (strcmp (string, ",") == 0)
411 state = (strcmp (string, ")") ? ps_bad : ps_right);
415 if (token && TREE_CODE (token) == IDENTIFIER_NODE)
423 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
426 if (token && TREE_CODE (token) != IDENTIFIER_NODE)
440 #endif /* HANDLE_GENERIC_PRAGMAS */
442 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
447 align_stack *a = *(align_stack **) p;
451 ggc_mark_tree (a->id);
460 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
461 ggc_add_root (&alignment_stack, 1, sizeof(alignment_stack),