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 /* If we have a "global" #pragma pack(<n>) if effect when the first
55 #pragma push(pack,<n>) is encountered, this stores the the value of
56 maximum_field_alignment in effect. When the final pop_alignment()
57 happens, we restore the value to this, not to a value of 0 for
58 maximum_field_alignment. Value is in bits. */
59 static int default_alignment
;
61 static int push_alignment
PROTO((int, tree
));
62 static int pop_alignment
PROTO((tree
));
64 /* Push an alignment value onto the stack. */
66 push_alignment (alignment
, id
)
81 Alignment must be a small power of two, not %d, in #pragma pack",
86 if (alignment_stack
== NULL
87 || alignment_stack
->alignment
!= alignment
92 entry
= (align_stack
*) xmalloc (sizeof (* entry
));
96 warning ("Out of memory pushing #pragma pack");
100 entry
->alignment
= alignment
;
101 entry
->num_pushes
= 1;
103 entry
->prev
= alignment_stack
;
105 /* The current value of maximum_field_alignment is not necessarily
106 0 since there may be a #pragma pack(<n>) in effect; remember it
107 so that we can restore it after the final #pragma pop(). */
108 if (alignment_stack
== NULL
)
109 default_alignment
= maximum_field_alignment
;
111 alignment_stack
= entry
;
113 maximum_field_alignment
= alignment
* 8;
116 alignment_stack
->num_pushes
++;
121 /* Undo a push of an alignment onto the stack. */
128 if (alignment_stack
== NULL
)
131 #pragma pack (pop) encountered without matching #pragma pack (push, <n>)"
136 /* If we got an identifier, strip away everything above the target
137 entry so that the next step will restore the state just below it. */
140 for (entry
= alignment_stack
; entry
; entry
= entry
->prev
)
143 entry
->num_pushes
= 1;
144 alignment_stack
= entry
;
149 #pragma pack(pop, %s) encountered without matching #pragma pack(push, %s, <n>)"
150 , IDENTIFIER_POINTER (id
), IDENTIFIER_POINTER (id
));
153 if (-- alignment_stack
->num_pushes
== 0)
155 entry
= alignment_stack
->prev
;
158 maximum_field_alignment
= default_alignment
;
160 maximum_field_alignment
= entry
->alignment
* 8;
162 free (alignment_stack
);
164 alignment_stack
= entry
;
169 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
171 /* Handle one token of a pragma directive. TOKEN is the current token, and
172 STRING is its printable form. Some front ends do not support generating
173 tokens, and will only pass in a STRING. Also some front ends will reuse
174 the buffer containing STRING, so it must be copied to a local buffer if
175 it needs to be preserved.
177 If STRING is non-NULL, then the return value will be ignored, and there
178 will be futher calls to handle_pragma_token() in order to handle the rest of
179 the line containing the #pragma directive. If STRING is NULL, the entire
180 line has now been presented to handle_pragma_token() and the return value
181 should be zero if the pragma flawed in some way, or if the pragma was not
182 recognised, and non-zero if it was successfully handled. */
185 handle_pragma_token (string
, token
)
189 static enum pragma_state state
= ps_start
;
190 static enum pragma_state type
;
191 #ifdef HANDLE_PRAGMA_WEAK
195 #if defined(HANDLE_PRAGMA_PACK) || defined(HANDLE_PRAGMA_PACK_PUSH_POP)
200 /* If we have reached the end of the #pragma directive then
201 determine what value we should return. */
214 /* The pragma was not recognised. */
217 #ifdef HANDLE_PRAGMA_PACK
219 if (state
== ps_right
)
221 maximum_field_alignment
= align
* 8;
222 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
223 default_alignment
= maximum_field_alignment
;
228 warning ("malformed `#pragma pack'");
230 #endif /* HANDLE_PRAGMA_PACK */
232 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
234 if (state
== ps_right
)
235 ret_val
= push_alignment (align
, id
);
237 warning ("malformed '#pragma pack(push[,id],<n>)'");
241 if (state
== ps_right
)
242 ret_val
= pop_alignment (id
);
244 warning ("malformed '#pragma pack(pop[,id])'");
246 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
248 #ifdef HANDLE_PRAGMA_WEAK
250 if (HANDLE_PRAGMA_WEAK
)
252 if (state
== ps_name
)
253 ret_val
= add_weak (name
, NULL
);
254 else if (state
== ps_value
)
255 ret_val
= add_weak (name
, value
);
257 warning ("malformed `#pragma weak'");
260 ret_val
= 1; /* Ignore the pragma. */
262 #endif /* HANDLE_PRAGMA_WEAK */
269 type
= state
= ps_start
;
275 /* If we have been given a token, but it is not an identifier,
276 or a small constant, then something has gone wrong. */
279 switch (TREE_CODE (token
))
281 case IDENTIFIER_NODE
:
285 if (TREE_INT_CST_HIGH (token
) != 0)
297 type
= state
= ps_done
;
298 #ifdef HANDLE_PRAGMA_PACK
299 if (strcmp (string
, "pack") == 0)
300 type
= state
= ps_pack
;
302 #ifdef HANDLE_PRAGMA_WEAK
303 if (strcmp (string
, "weak") == 0)
304 type
= state
= ps_weak
;
306 if (strcmp (string
, "poison") == 0)
307 type
= state
= ps_poison
;
310 #ifdef HANDLE_PRAGMA_WEAK
312 name
= permalloc (strlen (string
) + 1);
315 warning ("Out of memory parsing #pragma weak");
320 strcpy (name
, string
);
326 state
= (strcmp (string
, "=") ? ps_bad
: ps_equals
);
330 value
= permalloc (strlen (string
) + 1);
333 warning ("Out of memory parsing #pragma weak");
338 strcpy (value
, string
);
346 #endif /* HANDLE_PRAGMA_WEAK */
348 #ifdef HANDLE_PRAGMA_PACK
350 state
= (strcmp (string
, "(") ? ps_bad
: ps_left
);
355 if (token
== NULL_TREE
)
357 /* #pragma pack () resets packing rules to their
359 if (strcmp (string
, ")") == 0)
367 else if (TREE_CODE (token
) == INTEGER_CST
)
370 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
371 else if (TREE_CODE (token
) == IDENTIFIER_NODE
)
373 if (strcmp (string
, "push") == 0)
374 type
= state
= ps_push
;
375 else if (strcmp (string
, "pop") == 0)
376 type
= state
= ps_pop
;
386 align
= TREE_INT_CST_LOW (token
);
404 state
= (strcmp (string
, ")") ? ps_bad
: ps_right
);
410 #endif /* HANDLE_PRAGMA_PACK */
412 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
414 state
= (strcmp (string
, ",") ? ps_bad
: ps_pushcomma
);
418 state
= (strcmp (string
, ",") ? ps_bad
: ps_pushcomma2
);
422 if (token
&& TREE_CODE (token
) == IDENTIFIER_NODE
)
429 /* else fall through */
431 if (token
&& TREE_CODE (token
) == INTEGER_CST
)
438 if (strcmp (string
, ",") == 0)
441 state
= (strcmp (string
, ")") ? ps_bad
: ps_right
);
445 if (token
&& TREE_CODE (token
) == IDENTIFIER_NODE
)
453 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
456 if (token
&& TREE_CODE (token
) != IDENTIFIER_NODE
)
470 #endif /* HANDLE_GENERIC_PRAGMAS */
472 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
477 align_stack
*a
= *(align_stack
**) p
;
481 ggc_mark_tree (a
->id
);
490 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
491 ggc_add_root (&alignment_stack
, 1, sizeof(alignment_stack
),