Commit 0f92adae by Jason Merrill Committed by Jason Merrill

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
parent 7f1d4866
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,
......
/* 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 ...@@ -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", ...@@ -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", ...@@ -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", ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 */
......
/* 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 ...@@ -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
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment