c-pragma.c (push_alignment): Don't ignore alignments greater than 4 bytes.

* c-pragma.c (push_alignment): Don't ignore alignments greater than
	4 bytes.
	(handle_pragma_token): Likewise.
	* c-pragma.c: Support for #pragma pack (push, <id>, <n>).
	(struct align_stack): Add id field.
	(push_alignment, pop_alignment): Take id parameter.
	(handle_pragma_token): Add necessary states.
	* c-pragma.h (enum pragma_state): Add necessary states.

From-SVN: r26662
This commit is contained in:
Jason Merrill 1999-04-26 21:18:08 +00:00 committed by Jason Merrill
parent 7f1d48663e
commit 0f92adae32
3 changed files with 114 additions and 45 deletions

View File

@ -1,3 +1,15 @@
Mon Apr 26 21:17:41 1999 Jason Merrill <jason@yorick.cygnus.com>
* c-pragma.c (push_alignment): Don't ignore alignments greater than
4 bytes.
(handle_pragma_token): Likewise.
* c-pragma.c: Support for #pragma pack (push, <id>, <n>).
(struct align_stack): Add id field.
(push_alignment, pop_alignment): Take id parameter.
(handle_pragma_token): Add necessary states.
* c-pragma.h (enum pragma_state): Add necessary states.
Tue Apr 27 13:58:23 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz> Tue Apr 27 13:58:23 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* config/c4x/c4x.md (*cmpqf, *cmpqf_noov, *cmpqi_test, * config/c4x/c4x.md (*cmpqf, *cmpqf_noov, *cmpqi_test,

View File

@ -1,5 +1,5 @@
/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack. /* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc. Copyright (C) 1992, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
@ -45,18 +45,20 @@ typedef struct align_stack
{ {
int alignment; int alignment;
unsigned int num_pushes; unsigned int num_pushes;
tree id;
struct align_stack * prev; struct align_stack * prev;
} align_stack; } align_stack;
static struct align_stack * alignment_stack = NULL; static struct align_stack * alignment_stack = NULL;
static int push_alignment PROTO((int)); static int push_alignment PROTO((int, tree));
static int pop_alignment PROTO((void)); static int pop_alignment PROTO((tree));
/* Push an alignment value onto the stack. */ /* Push an alignment value onto the stack. */
static int static int
push_alignment (alignment) push_alignment (alignment, id)
int alignment; int alignment;
tree id;
{ {
switch (alignment) switch (alignment)
{ {
@ -75,7 +77,8 @@ Alignment must be a small power of two, not %d, in #pragma pack",
} }
if (alignment_stack == NULL if (alignment_stack == NULL
|| alignment_stack->alignment != alignment) || alignment_stack->alignment != alignment
|| id != NULL_TREE)
{ {
align_stack * entry; align_stack * entry;
@ -89,15 +92,12 @@ Alignment must be a small power of two, not %d, in #pragma pack",
entry->alignment = alignment; entry->alignment = alignment;
entry->num_pushes = 1; entry->num_pushes = 1;
entry->id = id;
entry->prev = alignment_stack; entry->prev = alignment_stack;
alignment_stack = entry; alignment_stack = entry;
if (alignment < 8) maximum_field_alignment = alignment * 8;
maximum_field_alignment = alignment * 8;
else
/* MSVC ignores alignments > 4. */
maximum_field_alignment = 0;
} }
else else
alignment_stack->num_pushes ++; alignment_stack->num_pushes ++;
@ -107,19 +107,38 @@ Alignment must be a small power of two, not %d, in #pragma pack",
/* Undo a push of an alignment onto the stack. */ /* Undo a push of an alignment onto the stack. */
static int static int
pop_alignment () pop_alignment (id)
tree id;
{ {
align_stack * entry;
if (alignment_stack == NULL) if (alignment_stack == NULL)
{ {
warning ("\ warning ("\
#pragma pack(pop) encountered without corresponding #pragma pack(push,<n>)"); #pragma pack (pop) encountered without matching #pragma pack (push, <n>)"
);
return 0; return 0;
} }
/* If we got an identifier, strip away everything above the target
entry so that the next step will restore the state just below it. */
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) if (-- alignment_stack->num_pushes == 0)
{ {
align_stack * entry;
entry = alignment_stack->prev; entry = alignment_stack->prev;
if (entry == NULL || entry->alignment > 4) if (entry == NULL || entry->alignment > 4)
@ -215,6 +234,7 @@ handle_pragma_token (string, token)
static char * name; static char * name;
static char * value; static char * value;
static int align; static int align;
static tree id;
/* If we have reached the end of the #pragma directive then /* If we have reached the end of the #pragma directive then
determine what value we should return. */ determine what value we should return. */
@ -248,16 +268,16 @@ handle_pragma_token (string, token)
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
case ps_push: case ps_push:
if (state == ps_right) if (state == ps_right)
ret_val = push_alignment (align); ret_val = push_alignment (align, id);
else else
warning ("incomplete '#pragma pack(push,<n>)'"); warning ("malformed '#pragma pack(push[,id],<n>)'");
break; break;
case ps_pop: case ps_pop:
if (state == ps_right) if (state == ps_right)
ret_val = pop_alignment (); ret_val = pop_alignment (id);
else else
warning ("missing closing parenthesis in '#pragma pack(pop)'"); warning ("malformed '#pragma pack(pop[,id])'");
break; break;
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
@ -279,6 +299,7 @@ handle_pragma_token (string, token)
} }
type = state = ps_start; type = state = ps_start;
id = NULL_TREE;
return ret_val; return ret_val;
} }
@ -361,40 +382,45 @@ handle_pragma_token (string, token)
case ps_left: case ps_left:
if (token && TREE_CODE(token) == INTEGER_CST) if (token == NULL_TREE)
align = TREE_INT_CST_LOW(token); state = (strcmp (string, ")") ? ps_bad : ps_right);
else if (TREE_CODE (token) == INTEGER_CST)
goto handle_align;
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
else if (TREE_CODE (token) == IDENTIFIER_NODE)
{
if (strcmp (string, "push") == 0)
type = state = ps_push;
else if (strcmp (string, "pop") == 0)
type = state = ps_pop;
else
state = ps_bad;
}
#endif
else else
align = atoi (string); state = ps_bad;
break;
handle_align:
align = TREE_INT_CST_LOW (token);
switch (align) switch (align)
{ {
case 1: case 1:
case 2: case 2:
case 4: case 4:
case 8:
case 16:
state = ps_align; state = ps_align;
break; break;
case 0:
state = (strcmp (string, ")") ? ps_bad : ps_right);
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
if (state == ps_bad)
{
if (strcmp (string, "push") == 0)
type = state = ps_push;
else if (strcmp (string, "pop") == 0)
type = state = ps_pop;
}
#endif
break;
default: default:
state = ps_bad; state = ps_bad;
break; break;
} }
break; break;
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
case ps_pop:
#endif
case ps_align: case ps_align:
state = (strcmp (string, ")") ? ps_bad : ps_right); state = (strcmp (string, ")") ? ps_bad : ps_right);
break; break;
@ -406,12 +432,44 @@ handle_pragma_token (string, token)
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
case ps_push: case ps_push:
state = (strcmp (string, ",") ? ps_bad : ps_comma); state = (strcmp (string, ",") ? ps_bad : ps_pushcomma);
break; break;
case ps_comma: case ps_pushid:
align = atoi (string); state = (strcmp (string, ",") ? ps_bad : ps_pushcomma2);
state = ps_align; break;
case ps_pushcomma:
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
{
id = token;
state = ps_pushid;
break;
}
/* else fall through */
case ps_pushcomma2:
if (token && TREE_CODE (token) == INTEGER_CST)
goto handle_align;
else
state = ps_bad;
break;
case ps_pop:
if (strcmp (string, ",") == 0)
state = ps_popcomma;
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; break;
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */

View File

@ -1,5 +1,5 @@
/* Pragma related interfaces. /* Pragma related interfaces.
Copyright (C) 1995, 1998 Free Software Foundation, Inc. Copyright (C) 1995, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
@ -88,9 +88,8 @@ enum pragma_state
ps_right, ps_right,
#endif #endif
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
ps_push, ps_push, ps_pushcomma, ps_pushid, ps_pushcomma2,
ps_pop, ps_pop, ps_popcomma,
ps_comma,
#endif #endif
ps_bad ps_bad
}; };