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
* BITS_PER_UNIT
;
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
* BITS_PER_UNIT
;
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
* BITS_PER_UNIT
;
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
),