]>
gcc.gnu.org Git - gcc.git/blob - gcc/c-pragma.c
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)
152 /* We are only interested in fields. */
153 if (TREE_CODE_CLASS (TREE_CODE (node
)) != 'd'
154 || TREE_CODE (node
) != FIELD_DECL
)
157 /* Add a 'packed' attribute. */
158 * attributes
= tree_cons (get_identifier ("packed"), NULL
, * attributes
);
160 /* If the alignment is > 8 then add an alignment attribute as well. */
161 if (maximum_field_alignment
> 8)
163 /* If the aligned attribute is already present then do not override it. */
164 for (a
= * attributes
; a
; a
= TREE_CHAIN (a
))
166 tree name
= TREE_PURPOSE (a
);
167 if (strcmp (IDENTIFIER_POINTER (name
), "aligned") == 0)
172 for (a
= * prefix
; a
; a
= TREE_CHAIN (a
))
174 tree name
= TREE_PURPOSE (a
);
175 if (strcmp (IDENTIFIER_POINTER (name
), "aligned") == 0)
181 * attributes
= tree_cons
182 (get_identifier ("aligned"),
184 build_int_2 (maximum_field_alignment
/ 8, 0),
192 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
194 #ifdef HANDLE_PRAGMA_WEAK
195 static int add_weak
PROTO((char *, char *));
198 add_weak (name
, value
)
202 struct weak_syms
* weak
;
204 weak
= (struct weak_syms
*) permalloc (sizeof (struct weak_syms
));
209 weak
->next
= weak_decls
;
216 #endif /* HANDLE_PRAGMA_WEAK */
218 /* Handle one token of a pragma directive. TOKEN is the current token, and
219 STRING is its printable form. Some front ends do not support generating
220 tokens, and will only pass in a STRING. Also some front ends will reuse
221 the buffer containing STRING, so it must be copied to a local buffer if
222 it needs to be preserved.
224 If STRING is non-NULL, then the return value will be ignored, and there
225 will be futher calls to handle_pragma_token() in order to handle the rest of
226 the line containing the #pragma directive. If STRING is NULL, the entire
227 line has now been presented to handle_pragma_token() and the return value
228 should be zero if the pragma flawed in some way, or if the pragma was not
229 recognised, and non-zero if it was successfully handled. */
232 handle_pragma_token (string
, token
)
236 static enum pragma_state state
= ps_start
;
237 static enum pragma_state type
;
242 /* If we have reached the end of the #pragma directive then
243 determine what value we should return. */
256 /* The pragma was not recognised. */
259 #ifdef HANDLE_PRAGMA_PACK
261 if (state
== ps_right
)
263 maximum_field_alignment
= align
* 8;
267 warning ("malformed `#pragma pack'");
269 #endif /* HANDLE_PRAGMA_PACK */
271 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
273 if (state
== ps_right
)
274 ret_val
= push_alignment (align
);
276 warning ("incomplete '#pragma pack(push,<n>)'");
280 if (state
== ps_right
)
281 ret_val
= pop_alignment ();
283 warning ("missing closing parenthesis in '#pragma pack(pop)'");
285 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
287 #ifdef HANDLE_PRAGMA_WEAK
289 if (HANDLE_PRAGMA_WEAK
)
291 if (state
== ps_name
)
292 ret_val
= add_weak (name
, NULL
);
293 else if (state
== ps_value
)
294 ret_val
= add_weak (name
, value
);
296 warning ("malformed `#pragma weak'");
299 ret_val
= 1; /* Ignore the pragma. */
301 #endif /* HANDLE_PRAGMA_WEAK */
304 type
= state
= ps_start
;
309 /* If we have been given a token, but it is not an identifier,
310 or a small constant, then something has gone wrong. */
313 switch (TREE_CODE (token
))
315 case IDENTIFIER_NODE
:
319 if (TREE_INT_CST_HIGH (token
) != 0)
331 type
= state
= ps_done
;
332 #ifdef HANDLE_PRAGMA_PACK
333 if (strcmp (string
, "pack") == 0)
334 type
= state
= ps_pack
;
336 #ifdef HANDLE_PRAGMA_WEAK
337 if (strcmp (string
, "weak") == 0)
338 type
= state
= ps_weak
;
342 #ifdef HANDLE_PRAGMA_WEAK
344 name
= permalloc (strlen (string
) + 1);
347 warning ("Out of memory parsing #pragma weak");
352 strcpy (name
, string
);
358 state
= (strcmp (string
, "=") ? ps_bad
: ps_equals
);
362 value
= permalloc (strlen (string
) + 1);
365 warning ("Out of memory parsing #pragma weak");
370 strcpy (value
, string
);
378 #endif /* HANDLE_PRAGMA_WEAK */
380 #ifdef HANDLE_PRAGMA_PACK
382 state
= (strcmp (string
, "(") ? ps_bad
: ps_left
);
386 align
= atoi (string
);
396 state
= (strcmp (string
, ")") ? ps_bad
: ps_right
);
397 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
400 if (strcmp (string
, "push") == 0)
401 type
= state
= ps_push
;
402 else if (strcmp (string
, "pop") == 0)
403 type
= state
= ps_pop
;
414 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
418 state
= (strcmp (string
, ")") ? ps_bad
: ps_right
);
424 #endif /* HANDLE_PRAGMA_PACK */
426 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
428 state
= (strcmp (string
, ",") ? ps_bad
: ps_comma
);
432 align
= atoi (string
);
435 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
447 #endif /* HANDLE_GENERIC_PRAGMAS */
This page took 0.054229 seconds and 5 git commands to generate.