summaryrefslogtreecommitdiff
path: root/gcc/c-pragma.c
diff options
context:
space:
mode:
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>1999-10-19 10:44:30 +0000
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>1999-10-19 10:44:30 +0000
commit231d1a2b3a4a04b41c8bbad742fc6e955e1519e8 (patch)
tree925ef3f3d7ebb9e6c59b3670bbcacbd797cf2da2 /gcc/c-pragma.c
parentf4b5ce94a03f8292b0d275ed5bb45088a49cd026 (diff)
downloadgcc-231d1a2b3a4a04b41c8bbad742fc6e955e1519e8.tar.gz
Applied Mumit Khan's patch to fix #pragma push/pop handling.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30084 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-pragma.c')
-rw-r--r--gcc/c-pragma.c79
1 files changed, 17 insertions, 62 deletions
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c
index 7cb7421d209..36aa2c4dbaf 100644
--- a/gcc/c-pragma.c
+++ b/gcc/c-pragma.c
@@ -51,6 +51,13 @@ typedef struct align_stack
static struct align_stack * alignment_stack = NULL;
+/* If we have a "global" #pragma pack(<n>) if effect when the first
+ #pragma push(pack,<n>) is encountered, this stores the the value of
+ maximum_field_alignment in effect. When the final pop_alignment()
+ happens, we restore the value to this, not to a value of 0 for
+ maximum_field_alignment. Value is in bits. */
+static int default_alignment;
+
static int push_alignment PROTO((int, tree));
static int pop_alignment PROTO((tree));
@@ -95,6 +102,12 @@ Alignment must be a small power of two, not %d, in #pragma pack",
entry->id = id;
entry->prev = alignment_stack;
+ /* The current value of maximum_field_alignment is not necessarily
+ 0 since there may be a #pragma pack(<n>) in effect; remember it
+ so that we can restore it after the final #pragma pop(). */
+ if (alignment_stack == NULL)
+ default_alignment = maximum_field_alignment;
+
alignment_stack = entry;
maximum_field_alignment = alignment * 8;
@@ -142,7 +155,7 @@ pop_alignment (id)
entry = alignment_stack->prev;
if (entry == NULL)
- maximum_field_alignment = 0;
+ maximum_field_alignment = default_alignment;
else
maximum_field_alignment = entry->alignment * 8;
@@ -153,67 +166,6 @@ pop_alignment (id)
return 1;
}
-
-/* Generate 'packed' and 'aligned' attributes for decls whilst a
- #pragma pack(push... is in effect. */
-void
-insert_pack_attributes (node, attributes, prefix)
- tree node;
- tree * attributes;
- tree * prefix;
-{
- tree a;
- int field_alignment;
-
- /* If we are not packing, then there is nothing to do. */
- if (maximum_field_alignment == 0
- || alignment_stack == NULL)
- return;
-
- /* We are only interested in fields. */
- if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd'
- || TREE_CODE (node) != FIELD_DECL)
- return;
-
- field_alignment = TYPE_ALIGN (TREE_TYPE (node));
- if (field_alignment <= 0 || field_alignment > maximum_field_alignment)
- field_alignment = maximum_field_alignment;
-
- /* Add a 'packed' attribute. */
- * attributes = tree_cons (get_identifier ("packed"), NULL, * attributes);
-
- /* If the alignment is > 8 then add an alignment attribute as well. */
- if (field_alignment > 8)
- {
- /* If the aligned attribute is already present then do not override it. */
- for (a = * attributes; a; a = TREE_CHAIN (a))
- {
- tree name = TREE_PURPOSE (a);
- if (strcmp (IDENTIFIER_POINTER (name), "aligned") == 0)
- break;
- }
-
- if (a == NULL)
- for (a = * prefix; a; a = TREE_CHAIN (a))
- {
- tree name = TREE_PURPOSE (a);
- if (strcmp (IDENTIFIER_POINTER (name), "aligned") == 0)
- break;
- }
-
- if (a == NULL)
- {
- * attributes = tree_cons
- (get_identifier ("aligned"),
- tree_cons (NULL,
- build_int_2 (field_alignment / 8, 0),
- NULL),
- * attributes);
- }
- }
-
- return;
-}
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
/* Handle one token of a pragma directive. TOKEN is the current token, and
@@ -267,6 +219,9 @@ handle_pragma_token (string, token)
if (state == ps_right)
{
maximum_field_alignment = align * 8;
+#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
+ default_alignment = maximum_field_alignment;
+#endif
ret_val = 1;
}
else