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 #ifdef HANDLE_PRAGMA_WEAK
196 static int add_weak
PROTO((char *, char *));
199 add_weak (name
, value
)
203 struct weak_syms
* weak
;
205 weak
= (struct weak_syms
*) permalloc (sizeof (struct weak_syms
));
210 weak
->next
= weak_decls
;
217 #endif /* HANDLE_PRAGMA_WEAK */
219 /* Handle one token of a pragma directive. TOKEN is the current token, and
220 STRING is its printable form. Some front ends do not support generating
221 tokens, and will only pass in a STRING. Also some front ends will reuse
222 the buffer containing STRING, so it must be copied to a local buffer if
223 it needs to be preserved.
225 If STRING is non-NULL, then the return value will be ignored, and there
226 will be futher calls to handle_pragma_token() in order to handle the rest of
227 the line containing the #pragma directive. If STRING is NULL, the entire
228 line has now been presented to handle_pragma_token() and the return value
229 should be zero if the pragma flawed in some way, or if the pragma was not
230 recognised, and non-zero if it was successfully handled. */
233 handle_pragma_token (string
, token
)
237 static enum pragma_state state
= ps_start
;
238 static enum pragma_state type
;
243 /* If we have reached the end of the #pragma directive then
244 determine what value we should return. */
257 /* The pragma was not recognised. */
260 #ifdef HANDLE_PRAGMA_PACK
262 if (state
== ps_right
)
264 maximum_field_alignment
= align
* 8;
268 warning ("malformed `#pragma pack'");
270 #endif /* HANDLE_PRAGMA_PACK */
272 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
274 if (state
== ps_right
)
275 ret_val
= push_alignment (align
);
277 warning ("incomplete '#pragma pack(push,<n>)'");
281 if (state
== ps_right
)
282 ret_val
= pop_alignment ();
284 warning ("missing closing parenthesis in '#pragma pack(pop)'");
286 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
288 #ifdef HANDLE_PRAGMA_WEAK
290 if (HANDLE_PRAGMA_WEAK
)
292 if (state
== ps_name
)
293 ret_val
= add_weak (name
, NULL
);
294 else if (state
== ps_value
)
295 ret_val
= add_weak (name
, value
);
297 warning ("malformed `#pragma weak'");
300 ret_val
= 1; /* Ignore the pragma. */
302 #endif /* HANDLE_PRAGMA_WEAK */
305 type
= state
= ps_start
;
310 /* If we have been given a token, but it is not an identifier,
311 or a small constant, then something has gone wrong. */
314 switch (TREE_CODE (token
))
316 case IDENTIFIER_NODE
:
320 if (TREE_INT_CST_HIGH (token
) != 0)
332 type
= state
= ps_done
;
333 #ifdef HANDLE_PRAGMA_PACK
334 if (strcmp (string
, "pack") == 0)
335 type
= state
= ps_pack
;
337 #ifdef HANDLE_PRAGMA_WEAK
338 if (strcmp (string
, "weak") == 0)
339 type
= state
= ps_weak
;
343 #ifdef HANDLE_PRAGMA_WEAK
345 name
= permalloc (strlen (string
) + 1);
348 warning ("Out of memory parsing #pragma weak");
353 strcpy (name
, string
);
359 state
= (strcmp (string
, "=") ? ps_bad
: ps_equals
);
363 value
= permalloc (strlen (string
) + 1);
366 warning ("Out of memory parsing #pragma weak");
371 strcpy (value
, string
);
379 #endif /* HANDLE_PRAGMA_WEAK */
381 #ifdef HANDLE_PRAGMA_PACK
383 state
= (strcmp (string
, "(") ? ps_bad
: ps_left
);
388 if (token
&& TREE_CODE(token
) == INTEGER_CST
)
389 align
= TREE_INT_CST_LOW(token
);
391 align
= atoi (string
);
401 state
= (strcmp (string
, ")") ? ps_bad
: ps_right
);
402 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
405 if (strcmp (string
, "push") == 0)
406 type
= state
= ps_push
;
407 else if (strcmp (string
, "pop") == 0)
408 type
= state
= ps_pop
;
419 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
423 state
= (strcmp (string
, ")") ? ps_bad
: ps_right
);
429 #endif /* HANDLE_PRAGMA_PACK */
431 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
433 state
= (strcmp (string
, ",") ? ps_bad
: ps_comma
);
437 align
= atoi (string
);
440 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
452 #endif /* HANDLE_GENERIC_PRAGMAS */