home *** CD-ROM | disk | FTP | other *** search
- Fri Jul 2 22:13:14 1999 Mumit Khan <khan@xraylith.wisc.edu>
-
- * c-pragma.h (PRAGMA_INSERT_ATTRIBUTES): Delete macro.
- (insert_pack_attributes): Delete prototype.
- (enum pragma_state): Simplify.
-
- * c-pragma.c (struct align_stack): Lose num_pushes field.
- (push_alignment): Remove redundant check for valid alignment;
- always push on stack.
- (pop_alignment): Update prototype. Implement combination rule.
- (insert_pack_attributes): Lose.
- (handle_pragma_token): Document syntax. Simplify pack(push/pop)
- attributes and implement documented syntax.
-
- Index: gcc-2.95.2/gcc/c-pragma.c
- ===================================================================
- RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/c-pragma.c,v
- retrieving revision 1.1.1.1
- diff -u -3 -p -r1.1.1.1 c-pragma.c
- --- gcc-2.95.2/gcc/c-pragma.c 1999/11/05 01:09:41 1.1.1.1
- +++ gcc-2.95.2/gcc/c-pragma.c 1999/11/05 06:37:53
- @@ -44,7 +44,6 @@ extern int maximum_field_alignment;
- typedef struct align_stack
- {
- int alignment;
- - unsigned int num_pushes;
- tree id;
- struct align_stack * prev;
- } align_stack;
- @@ -52,7 +51,7 @@ typedef struct align_stack
- static struct align_stack * alignment_stack = NULL;
-
- static int push_alignment PROTO((int, tree));
- -static int pop_alignment PROTO((tree));
- +static int pop_alignment PROTO((int, tree));
-
- /* Push an alignment value onto the stack. */
- static int
- @@ -60,159 +59,88 @@ push_alignment (alignment, id)
- int alignment;
- tree id;
- {
- - switch (alignment)
- + align_stack * entry;
- +
- + entry = (align_stack *) xmalloc (sizeof (* entry));
- +
- + if (entry == NULL)
- {
- - case 0:
- - case 1:
- - case 2:
- - case 4:
- - case 8:
- - case 16:
- - break;
- - default:
- - warning ("\
- -Alignment must be a small power of two, not %d, in #pragma pack",
- - alignment);
- + warning ("Out of memory pushing #pragma pack");
- return 0;
- }
- -
- - if (alignment_stack == NULL
- - || alignment_stack->alignment != alignment
- - || id != NULL_TREE)
- - {
- - align_stack * entry;
-
- - entry = (align_stack *) xmalloc (sizeof (* entry));
- -
- - if (entry == NULL)
- - {
- - warning ("Out of memory pushing #pragma pack");
- - return 0;
- - }
- + entry->alignment = maximum_field_alignment;
- + entry->id = id;
- + entry->prev = alignment_stack;
-
- - entry->alignment = alignment;
- - entry->num_pushes = 1;
- - entry->id = id;
- - entry->prev = alignment_stack;
- -
- - alignment_stack = entry;
- + alignment_stack = entry;
-
- - maximum_field_alignment = alignment * 8;
- - }
- - else
- - alignment_stack->num_pushes ++;
- + maximum_field_alignment = alignment;
-
- return 1;
- }
-
- -/* Undo a push of an alignment onto the stack. */
- +/* Undo a push of an alignment onto the stack. If the alignment argument
- + is > 0, then make that the new alignment after popping the stack instead
- + of using TOS. See the combination rules in the #pragma pack(pop[,id][,n])
- + syntax for details. */
- static int
- -pop_alignment (id)
- +pop_alignment (alignment, id)
- + int alignment;
- tree id;
- {
- align_stack * entry;
- -
- - if (alignment_stack == NULL)
- +
- + /* If popping an empty stack, revert to default packing. Defer warning
- + if we got an identifier. */
- + if (alignment_stack == NULL && id == NULL)
- {
- - warning ("\
- -#pragma pack (pop) encountered without matching #pragma pack (push, <n>)"
- - );
- - return 0;
- + warning
- + ("#pragma pack(pop) encountered without matching #pragma pack(push)");
- + maximum_field_alignment = 0;
- + return 1;
- }
-
- /* If we got an identifier, strip away everything above the target
- - entry so that the next step will restore the state just below it. */
- + entry so that the next step will restore the state that existed
- + just before the identifier was pushed on the stack. */
- if (id)
- - {
- - for (entry = alignment_stack; entry; entry = entry->prev)
- - if (entry->id == id)
- - {
- - entry->num_pushes = 1;
- - alignment_stack = entry;
- - break;
- - }
- - if (entry == NULL)
- - warning ("\
- -#pragma pack(pop, %s) encountered without matching #pragma pack(push, %s, <n>)"
- - , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
- - }
- -
- - if (-- alignment_stack->num_pushes == 0)
- {
- - entry = alignment_stack->prev;
- + align_stack * popped = NULL;
- + for (entry = alignment_stack; entry;
- + popped = entry, entry = entry->prev)
- + {
- + if (popped)
- + free (popped);
-
- + if (entry->id == id)
- + {
- + alignment_stack = entry;
- + break;
- + }
- + }
- if (entry == NULL)
- - maximum_field_alignment = 0;
- - else
- - maximum_field_alignment = entry->alignment * 8;
- -
- - free (alignment_stack);
- -
- - alignment_stack = entry;
- + {
- + warning
- + ("#pragma pack(pop,%s) encountered without matching #pragma pack(push,%s)",
- + IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
- + alignment_stack = NULL;
- + maximum_field_alignment = 0;
- + return 1;
- + }
- }
-
- - return 1;
- -}
- + entry = alignment_stack->prev;
-
- -/* 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;
- + /* The new alignment is either a user specified one (combination rule)
- + or restored from the stack. */
- + maximum_field_alignment =
- + (alignment > 0) ? alignment : alignment_stack->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);
- - }
- - }
- + free (alignment_stack);
- + alignment_stack = entry;
-
- - return;
- + return 1;
- }
- #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
-
- @@ -227,8 +155,52 @@ insert_pack_attributes (node, attributes
- the line containing the #pragma directive. If STRING is NULL, the entire
- line has now been presented to handle_pragma_token() and the return value
- should be zero if the pragma flawed in some way, or if the pragma was not
- - recognised, and non-zero if it was successfully handled. */
- + recognised, and non-zero if it was successfully handled.
-
- + If HANDLE_PRAGMA_WEAK is defined, handle the weak directives using
- + the following syntax:
- +
- + #pragma weak name [= alias]
- +
- + If HANDLE_PRAGMA_PACK is defined, handle the pack directives using
- + the following syntax:
- +
- + #pragma pack([n])
- +
- + Specifies packing alignment for structure and union members. The
- + packing alignment is set at the data-declaration level by the pack
- + pragma. The pragma takes effect at the first structure or union
- + declaration after the pragma is seen; the pragma has no effect on
- + definitions.
- +
- + When you use #pragma pack(n), where n is 1, 2, 4, 8, or 16, each
- + structure member after the first is stored on the smaller member type
- + or n-byte boundaries. If you use #pragma pack without an argument,
- + the alignment reverts to the default for the target.
- +
- + If HANDLE_PRAGMA_PACK_PUSH_POP is defined, also handle the
- + following syntax:
- +
- + #pragma pack({ push | pop} [,identifier] [,n])
- +
- + Each occurrence of a #pragma pack with a push argument stores the
- + current packing alignment on a stack; If you provide a value for n,
- + that value becomes the new packing value. If you specify an
- + identifier, the identifier is associated with the new packing value.
- +
- + Each occurrence of a #pragma pack with a pop argument pops the stack
- + and uses the value the new packing alignment. If you use pop and the
- + internal compiler stack is empty, the new alignment is set to be
- + the default alignment for target, and an warning is issued. If you
- + use pop and specify a value for n, that value becomes the new packing
- + value. If you use pop and specify an identifier, all values stored on
- + the stack are removed from the stack until a matching identifier is
- + found. The packing value associated with the identifier is also
- + removed from the stack and the packing value that existed just before
- + the identifier was pushed becomes the new packing value. If no
- + matching identifier is found, the packing value set to the default
- + and a warning is issued. */
- +
- int
- handle_pragma_token (string, token)
- const char * string;
- @@ -238,7 +210,7 @@ handle_pragma_token (string, token)
- static enum pragma_state type;
- static char * name;
- static char * value;
- - static int align;
- + static int align = -1;
- static tree id;
-
- /* If we have reached the end of the #pragma directive then
- @@ -262,11 +234,14 @@ handle_pragma_token (string, token)
- case ps_pack:
- if (state == ps_right)
- {
- - maximum_field_alignment = align * 8;
- + maximum_field_alignment = align;
- ret_val = 1;
- }
- else
- - warning ("malformed `#pragma pack'");
- + {
- + ret_val = 1; /* Ignore the pragma. */
- + warning ("malformed `#pragma pack'");
- + }
- break;
- #endif /* HANDLE_PRAGMA_PACK */
-
- @@ -275,14 +250,20 @@ handle_pragma_token (string, token)
- if (state == ps_right)
- ret_val = push_alignment (align, id);
- else
- - warning ("malformed '#pragma pack(push[,id],<n>)'");
- + {
- + ret_val = 1; /* Ignore the pragma. */
- + warning ("malformed '#pragma pack(push[,id][,n])'");
- + }
- break;
-
- case ps_pop:
- if (state == ps_right)
- - ret_val = pop_alignment (id);
- + ret_val = pop_alignment (align, id);
- else
- - warning ("malformed '#pragma pack(pop[,id])'");
- + {
- + ret_val = 1; /* Ignore the pragma. */
- + warning ("malformed '#pragma pack(pop[,id][,n])'");
- + }
- break;
- #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
-
- @@ -305,6 +286,7 @@ handle_pragma_token (string, token)
-
- type = state = ps_start;
- id = NULL_TREE;
- + align = -1;
-
- return ret_val;
- }
- @@ -418,6 +400,8 @@ handle_pragma_token (string, token)
- break;
-
- handle_align:
- + /* User specified alignment in bytes, but is converted to bits
- + before use. */
- align = TREE_INT_CST_LOW (token);
- switch (align)
- {
- @@ -426,10 +410,20 @@ handle_pragma_token (string, token)
- case 4:
- case 8:
- case 16:
- + align *= 8;
- state = ps_align;
- break;
-
- default:
- +#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
- + warning
- + ("Alignment must be a small power of two, not %d, in #pragma %s",
- + align, (type == ps_pop) ? "pop" : "pack");
- +#else
- + warning
- + ("Alignment must be a small power of two, not %d, in #pragma pack",
- + align);
- +#endif
- state = ps_bad;
- break;
- }
- @@ -446,45 +440,48 @@ handle_pragma_token (string, token)
-
- #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
- case ps_push:
- - state = (strcmp (string, ",") ? ps_bad : ps_pushcomma);
- - break;
- + /* If no alignment is specified, push the current alignment. */
- + align = maximum_field_alignment;
-
- - case ps_pushid:
- - state = (strcmp (string, ",") ? ps_bad : ps_pushcomma2);
- + /* fall through. */
- + case ps_pop:
- + /* If no alignment is specified, we'll just use the stored one. */
- + if (strcmp (string, ",") == 0)
- + state = ps_comma;
- + else if (strcmp (string, ")") == 0)
- + {
- + state = ps_right;
- + }
- + else
- + state = ps_bad;
- break;
-
- - case ps_pushcomma:
- + case ps_comma:
- + /* Id or <n> or both specified. */
- if (token && TREE_CODE (token) == IDENTIFIER_NODE)
- {
- id = token;
- - state = ps_pushid;
- + state = ps_id;
- break;
- }
-
- - /* else fall through */
- - case ps_pushcomma2:
- + /* else no id, but <n> specified, so fall through */
- + case ps_comma2:
- if (token && TREE_CODE (token) == INTEGER_CST)
- goto handle_align;
- else
- state = ps_bad;
- break;
-
- - case ps_pop:
- + case ps_id:
- if (strcmp (string, ",") == 0)
- - state = ps_popcomma;
- + state = ps_comma2;
- + else if (strcmp (string, ")") == 0)
- + state = ps_right;
- else
- - state = (strcmp (string, ")") ? ps_bad : ps_right);
- - break;
- -
- - case ps_popcomma:
- - if (token && TREE_CODE (token) == IDENTIFIER_NODE)
- - {
- - id = token;
- - state = ps_align;
- - }
- - else
- state = ps_bad;
- break;
- +
- #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
-
- case ps_bad:
- Index: gcc-2.95.2/gcc/c-pragma.h
- ===================================================================
- RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/c-pragma.h,v
- retrieving revision 1.1.1.1
- diff -u -3 -p -r1.1.1.1 c-pragma.h
- --- gcc-2.95.2/gcc/c-pragma.h 1999/11/05 01:09:41 1.1.1.1
- +++ gcc-2.95.2/gcc/c-pragma.h 1999/11/05 06:37:53
- @@ -39,9 +39,6 @@ Boston, MA 02111-1307, USA. */
- /* If we are supporting #pragma pack(push... then we automatically
- support #pragma pack(<n>) */
- #define HANDLE_PRAGMA_PACK 1
- -#define PRAGMA_INSERT_ATTRIBUTES(node, pattr, prefix_attr) \
- - insert_pack_attributes (node, pattr, prefix_attr)
- -extern void insert_pack_attributes PROTO((tree, tree *, tree *));
- #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
-
-
- @@ -88,8 +85,11 @@ enum pragma_state
- ps_right,
- #endif
- #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
- - ps_push, ps_pushcomma, ps_pushid, ps_pushcomma2,
- - ps_pop, ps_popcomma,
- + ps_push,
- + ps_pop,
- + ps_comma,
- + ps_comma2,
- + ps_id,
- #endif
- ps_bad
- };
-