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
));
94 entry
->alignment
= alignment
;
95 entry
->num_pushes
= 1;
97 entry
->prev
= alignment_stack
;
99 /* The current value of maximum_field_alignment is not necessarily
100 0 since there may be a #pragma pack(<n>) in effect; remember it
101 so that we can restore it after the final #pragma pop(). */
102 if (alignment_stack
== NULL
)
103 default_alignment
= maximum_field_alignment
;
105 alignment_stack
= entry
;
107 maximum_field_alignment
= alignment
* 8;
110 alignment_stack
->num_pushes
++;
115 /* Undo a push of an alignment onto the stack. */
122 if (alignment_stack
== NULL
)
125 #pragma pack (pop) encountered without matching #pragma pack (push, <n>)"
130 /* If we got an identifier, strip away everything above the target
131 entry so that the next step will restore the state just below it. */
134 for (entry
= alignment_stack
; entry
; entry
= entry
->prev
)
137 entry
->num_pushes
= 1;
138 alignment_stack
= entry
;
143 #pragma pack(pop, %s) encountered without matching #pragma pack(push, %s, <n>)"
144 , IDENTIFIER_POINTER (id
), IDENTIFIER_POINTER (id
));
147 if (-- alignment_stack
->num_pushes
== 0)
149 entry
= alignment_stack
->prev
;
152 maximum_field_alignment
= default_alignment
;
154 maximum_field_alignment
= entry
->alignment
* 8;
156 free (alignment_stack
);
158 alignment_stack
= entry
;
163 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
165 /* Handle one token of a pragma directive. TOKEN is the current token, and
166 STRING is its printable form. Some front ends do not support generating
167 tokens, and will only pass in a STRING. Also some front ends will reuse
168 the buffer containing STRING, so it must be copied to a local buffer if
169 it needs to be preserved.
171 If STRING is non-NULL, then the return value will be ignored, and there
172 will be futher calls to handle_pragma_token() in order to handle the rest of
173 the line containing the #pragma directive. If STRING is NULL, the entire
174 line has now been presented to handle_pragma_token() and the return value
175 should be zero if the pragma flawed in some way, or if the pragma was not
176 recognised, and non-zero if it was successfully handled. */
179 handle_pragma_token (string
, token
)
183 static enum pragma_state state
= ps_start
;
184 static enum pragma_state type
;
185 #ifdef HANDLE_PRAGMA_WEAK
189 #if defined(HANDLE_PRAGMA_PACK) || defined(HANDLE_PRAGMA_PACK_PUSH_POP)
194 /* If we have reached the end of the #pragma directive then
195 determine what value we should return. */
208 /* The pragma was not recognised. */
211 #ifdef HANDLE_PRAGMA_PACK
213 if (state
== ps_right
)
215 maximum_field_alignment
= align
* 8;
216 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
217 default_alignment
= maximum_field_alignment
;
222 warning ("malformed `#pragma pack'");
224 #endif /* HANDLE_PRAGMA_PACK */
226 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
228 if (state
== ps_right
)
229 ret_val
= push_alignment (align
, id
);
231 warning ("malformed '#pragma pack(push[,id],<n>)'");
235 if (state
== ps_right
)
236 ret_val
= pop_alignment (id
);
238 warning ("malformed '#pragma pack(pop[,id])'");
240 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
242 #ifdef HANDLE_PRAGMA_WEAK
244 if (HANDLE_PRAGMA_WEAK
)
246 if (state
== ps_name
)
247 ret_val
= add_weak (name
, NULL
);
248 else if (state
== ps_value
)
249 ret_val
= add_weak (name
, value
);
251 warning ("malformed `#pragma weak'");
254 ret_val
= 1; /* Ignore the pragma. */
256 #endif /* HANDLE_PRAGMA_WEAK */
263 type
= state
= ps_start
;
269 /* If we have been given a token, but it is not an identifier,
270 or a small constant, then something has gone wrong. */
273 switch (TREE_CODE (token
))
275 case IDENTIFIER_NODE
:
279 if (TREE_INT_CST_HIGH (token
) != 0)
291 type
= state
= ps_done
;
292 #ifdef HANDLE_PRAGMA_PACK
293 if (strcmp (string
, "pack") == 0)
294 type
= state
= ps_pack
;
296 #ifdef HANDLE_PRAGMA_WEAK
297 if (strcmp (string
, "weak") == 0)
298 type
= state
= ps_weak
;
300 if (strcmp (string
, "poison") == 0)
301 type
= state
= ps_poison
;
304 #ifdef HANDLE_PRAGMA_WEAK
306 name
= permalloc (strlen (string
) + 1);
309 warning ("Out of memory parsing #pragma weak");
314 strcpy (name
, string
);
320 state
= (strcmp (string
, "=") ? ps_bad
: ps_equals
);
324 value
= permalloc (strlen (string
) + 1);
327 warning ("Out of memory parsing #pragma weak");
332 strcpy (value
, string
);
340 #endif /* HANDLE_PRAGMA_WEAK */
342 #ifdef HANDLE_PRAGMA_PACK
344 state
= (strcmp (string
, "(") ? ps_bad
: ps_left
);
349 if (token
== NULL_TREE
)
351 /* #pragma pack () resets packing rules to their
353 if (strcmp (string
, ")") == 0)
361 else if (TREE_CODE (token
) == INTEGER_CST
)
364 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
365 else if (TREE_CODE (token
) == IDENTIFIER_NODE
)
367 if (strcmp (string
, "push") == 0)
368 type
= state
= ps_push
;
369 else if (strcmp (string
, "pop") == 0)
370 type
= state
= ps_pop
;
380 align
= TREE_INT_CST_LOW (token
);
398 state
= (strcmp (string
, ")") ? ps_bad
: ps_right
);
404 #endif /* HANDLE_PRAGMA_PACK */
406 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
408 state
= (strcmp (string
, ",") ? ps_bad
: ps_pushcomma
);
412 state
= (strcmp (string
, ",") ? ps_bad
: ps_pushcomma2
);
416 if (token
&& TREE_CODE (token
) == IDENTIFIER_NODE
)
423 /* else fall through */
425 if (token
&& TREE_CODE (token
) == INTEGER_CST
)
432 if (strcmp (string
, ",") == 0)
435 state
= (strcmp (string
, ")") ? ps_bad
: ps_right
);
439 if (token
&& TREE_CODE (token
) == IDENTIFIER_NODE
)
447 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
450 if (token
&& TREE_CODE (token
) != IDENTIFIER_NODE
)
464 #endif /* HANDLE_GENERIC_PRAGMAS */
466 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
471 align_stack
*a
= *(align_stack
**) p
;
475 ggc_mark_tree (a
->id
);
484 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
485 ggc_add_root (&alignment_stack
, 1, sizeof(alignment_stack
),