Add support for #pragma pack(push,<n>) and #pragma pack(pop).
From-SVN: r22710
This commit is contained in:
parent
3a846e6e06
commit
e2af664c2d
9 changed files with 503 additions and 148 deletions
|
@ -1,10 +1,45 @@
|
|||
Thu Oct 1 10:42:27 1998 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* c-pragma.c: Add support for HANDLE_PRAGMA_PACK and
|
||||
HANDLE_PRAGMA_PACK_PUSH_POP.
|
||||
(push_alignment): New function: Cache an alignment requested
|
||||
by a #pragma pack(push,<n>).
|
||||
(pop_alignment): New function: Pop an alignment from the
|
||||
alignment stack.
|
||||
(insert_pack_attributes): New function: Generate __packed__
|
||||
and __aligned__ attributes for new decls whilst a #pragma pack
|
||||
is in effect.
|
||||
(add_weak): New function: Cache a #pragma weak directive.
|
||||
(handle_pragma_token): Document calling conventions. Add
|
||||
support for #pragma pack(push,<n>) and #pragma pack (pop).
|
||||
|
||||
* c-pragma.h: If HANDLE_SYSV_PRAGMA or HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
are defined enable HANDLE_PRAGMA_PACK.
|
||||
Move 'struct weak_syms' here (from varasm.c).
|
||||
Add pragma states for push and pop pragmas.
|
||||
|
||||
* c-common.c (decl_attributes): Call PRAGMA_INSERT_ATTRIBUTES
|
||||
if it is defined.
|
||||
|
||||
* c-lex.c: Replace occurances of HANDLE_SYSV_PRAGMA with
|
||||
HANDLE_GENERIC_PRAGMAS.
|
||||
|
||||
* varasm.c: Move definition of 'struct weak_syms' into
|
||||
c-pragma.h.
|
||||
(handle_pragma_weak): Deleted.
|
||||
|
||||
* config/i386/i386.h: Define HANDLE_PRAGMA_PACK_PUSH_POP.
|
||||
|
||||
* config/winnt/win-nt.h: Define HANDLE_PRAGMA_PACK_PUSH_POP.
|
||||
|
||||
* c-decl.c (start_function): Add invocation of
|
||||
SET_DEFAULT_DECL_ATTRIBUTES, if defined.
|
||||
|
||||
* tm.texi: Remove description of non-existant macro
|
||||
SET_DEFAULT_SECTION_NAME.
|
||||
|
||||
(HANDLE_SYSV_PRAGMA): Document.
|
||||
(HANDLE_PRAGMA_PACK_PUSH_POP): Document.
|
||||
|
||||
Wed Sep 30 22:27:53 1998 Robert Lipe <robertl@dgii.com>
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "obstack.h"
|
||||
#include "toplev.h"
|
||||
#include "output.h"
|
||||
#include "c-pragma.h"
|
||||
|
||||
#if USE_CPPLIB
|
||||
#include "cpplib.h"
|
||||
|
@ -420,6 +421,14 @@ decl_attributes (node, attributes, prefix_attributes)
|
|||
else if (TREE_CODE_CLASS (TREE_CODE (node)) == 't')
|
||||
type = node, is_type = 1;
|
||||
|
||||
#ifdef PRAGMA_INSERT_ATTRIBUTES
|
||||
/* If the code in c-pragma.c wants to insert some attributes then
|
||||
allow it to do so. Do this before allowing machine back ends to
|
||||
insert attributes, so that they have the opportunity to override
|
||||
anything done here. */
|
||||
PRAGMA_INSERT_ATTRIBUTES (node, & attributes, & prefix_attributes);
|
||||
#endif
|
||||
|
||||
#ifdef INSERT_ATTRIBUTES
|
||||
INSERT_ATTRIBUTES (node, & attributes, & prefix_attributes);
|
||||
#endif
|
||||
|
|
37
gcc/c-lex.c
37
gcc/c-lex.c
|
@ -110,9 +110,9 @@ static int end_of_file;
|
|||
static int nextchar = -1;
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_SYSV_PRAGMA
|
||||
static int handle_sysv_pragma PROTO((int));
|
||||
#endif /* HANDLE_SYSV_PRAGMA */
|
||||
#ifdef HANDLE_GENERIC_PRAGMAS
|
||||
static int handle_generic_pragma PROTO((int));
|
||||
#endif /* HANDLE_GENERIC_PRAGMAS */
|
||||
static int whitespace_cr PROTO((int));
|
||||
static int skip_white_space PROTO((int));
|
||||
static int skip_white_space_on_line PROTO((void));
|
||||
|
@ -543,34 +543,37 @@ check_newline ()
|
|||
if (c == '\n')
|
||||
return c;
|
||||
|
||||
#if defined HANDLE_PRAGMA || defined HANDLE_SYSV_PRAGMA
|
||||
#if defined HANDLE_PRAGMA || defined HANDLE_GENERIC_PRAGMAS
|
||||
UNGETC (c);
|
||||
token = yylex ();
|
||||
if (token != IDENTIFIER)
|
||||
goto skipline;
|
||||
#endif /* HANDLE_PRAGMA || HANDLE_GENERIC_PRAGMAS */
|
||||
|
||||
#ifdef HANDLE_PRAGMA
|
||||
/* We invoke HANDLE_PRAGMA before HANDLE_SYSV_PRAGMA
|
||||
(if both are defined), in order to give the back
|
||||
end a chance to override the interpretation of
|
||||
SYSV style pragmas. */
|
||||
/* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS (if
|
||||
both are defined), in order to give the back end a chance to
|
||||
override the interpretation of generic style pragmas. */
|
||||
#if !USE_CPPLIB
|
||||
if (nextchar >= 0)
|
||||
{
|
||||
c = nextchar, nextchar = -1;
|
||||
UNGETC (c);
|
||||
}
|
||||
#endif
|
||||
#endif /* !USE_CPPLIB */
|
||||
|
||||
if (TREE_CODE (yylval.ttype) != IDENTIFIER_NODE)
|
||||
goto skipline;
|
||||
|
||||
if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
|
||||
IDENTIFIER_POINTER (yylval.ttype)))
|
||||
return GETC ();
|
||||
#endif /* HANDLE_PRAGMA */
|
||||
|
||||
#ifdef HANDLE_SYSV_PRAGMA
|
||||
if (handle_sysv_pragma (token))
|
||||
#ifdef HANDLE_GENERIC_PRAGMAS
|
||||
if (handle_generic_pragma (token))
|
||||
return GETC ();
|
||||
#endif /* !HANDLE_SYSV_PRAGMA */
|
||||
#endif /* HANDLE_PRAGMA || HANDLE_SYSV_PRAGMA */
|
||||
#endif /* HANDLE_GENERIC_PRAGMAS */
|
||||
|
||||
/* Issue a warning message if we have been asked to do so.
|
||||
Ignoring unknown pragmas in system header file unless
|
||||
|
@ -837,17 +840,17 @@ linenum:
|
|||
return c;
|
||||
}
|
||||
|
||||
#ifdef HANDLE_SYSV_PRAGMA
|
||||
#ifdef HANDLE_GENERIC_PRAGMAS
|
||||
|
||||
/* Handle a #pragma directive.
|
||||
TOKEN is the token we read after `#pragma'. Processes the entire input
|
||||
line and returns a character for the caller to reread: either \n or EOF. */
|
||||
line and return non-zero iff the pragma has been successfully parsed. */
|
||||
|
||||
/* This function has to be in this file, in order to get at
|
||||
the token types. */
|
||||
|
||||
static int
|
||||
handle_sysv_pragma (token)
|
||||
handle_generic_pragma (token)
|
||||
register int token;
|
||||
{
|
||||
register int c;
|
||||
|
@ -883,7 +886,7 @@ handle_sysv_pragma (token)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* HANDLE_SYSV_PRAGMA */
|
||||
#endif /* HANDLE_GENERIC_PRAGMAS */
|
||||
|
||||
#define ENDFILE -1 /* token that represents end-of-file */
|
||||
|
||||
|
|
405
gcc/c-pragma.c
405
gcc/c-pragma.c
|
@ -29,50 +29,275 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "flags.h"
|
||||
#include "toplev.h"
|
||||
|
||||
#ifdef HANDLE_SYSV_PRAGMA
|
||||
#ifdef HANDLE_GENERIC_PRAGMAS
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK
|
||||
/* When structure field packing is in effect, this variable is the
|
||||
number of bits to use as the maximum alignment. When packing is not
|
||||
in effect, this is zero. */
|
||||
|
||||
extern int maximum_field_alignment;
|
||||
#endif
|
||||
|
||||
/* Handle one token of a pragma directive. TOKEN is the
|
||||
current token, and STRING is its printable form.
|
||||
Return zero if an entire pragma was parsed, but it was
|
||||
flawed in some way. Return non-zero in all other cases. */
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
typedef struct align_stack
|
||||
{
|
||||
int alignment;
|
||||
unsigned int num_pushes;
|
||||
struct align_stack * prev;
|
||||
} align_stack;
|
||||
|
||||
static struct align_stack * alignment_stack = NULL;
|
||||
|
||||
static int push_alignment PROTO((int));
|
||||
static int pop_alignment PROTO((void));
|
||||
|
||||
/* Push an alignment value onto the stack. */
|
||||
static int
|
||||
push_alignment (alignment)
|
||||
int alignment;
|
||||
{
|
||||
switch (alignment)
|
||||
{
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (alignment_stack == NULL
|
||||
|| alignment_stack->alignment != alignment)
|
||||
{
|
||||
align_stack * entry;
|
||||
|
||||
entry = (align_stack *) xmalloc (sizeof (* entry));
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
warning ("Out of memory pushing #pragma pack");
|
||||
return 0;
|
||||
}
|
||||
|
||||
entry->alignment = alignment;
|
||||
entry->num_pushes = 1;
|
||||
entry->prev = alignment_stack;
|
||||
|
||||
alignment_stack = entry;
|
||||
|
||||
if (alignment < 8)
|
||||
maximum_field_alignment = alignment * 8;
|
||||
else
|
||||
/* MSVC ignores alignments > 4. */
|
||||
maximum_field_alignment = 0;
|
||||
}
|
||||
else
|
||||
alignment_stack->num_pushes ++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Undo a push of an alignment onto the stack. */
|
||||
static int
|
||||
pop_alignment ()
|
||||
{
|
||||
if (alignment_stack == NULL)
|
||||
{
|
||||
warning ("\
|
||||
#pragma pack(pop) encountered without corresponding #pragma pack(push,<n>)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (-- alignment_stack->num_pushes == 0)
|
||||
{
|
||||
align_stack * entry;
|
||||
|
||||
entry = alignment_stack->prev;
|
||||
|
||||
if (entry == NULL || entry->alignment > 4)
|
||||
maximum_field_alignment = 0;
|
||||
else
|
||||
maximum_field_alignment = entry->alignment * 8;
|
||||
|
||||
free (alignment_stack);
|
||||
|
||||
alignment_stack = entry;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* If we are not packing, then there is nothing to do. */
|
||||
if (maximum_field_alignment == 0)
|
||||
return;
|
||||
|
||||
/* We are only interested in fields. */
|
||||
if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd'
|
||||
|| TREE_CODE (node) != FIELD_DECL)
|
||||
return;
|
||||
|
||||
/* 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 (maximum_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 (maximum_field_alignment / 8, 0),
|
||||
NULL),
|
||||
* attributes);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
|
||||
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
static int add_weak PROTO((char *, char *));
|
||||
|
||||
static int
|
||||
add_weak (name, value)
|
||||
char * name;
|
||||
char * value;
|
||||
{
|
||||
struct weak_syms * weak;
|
||||
|
||||
weak = (struct weak_syms *) permalloc (sizeof (struct weak_syms));
|
||||
|
||||
if (weak == NULL)
|
||||
return 0;
|
||||
|
||||
weak->next = weak_decls;
|
||||
weak->name = name;
|
||||
weak->value = value;
|
||||
weak_decls = weak;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* HANDLE_PRAGMA_WEAK */
|
||||
|
||||
/* Handle one token of a pragma directive. TOKEN is the current token, and
|
||||
STRING is its printable form. Some front ends do not support generating
|
||||
tokens, and will only pass in a STRING. Also some front ends will reuse
|
||||
the buffer containing STRING, so it must be copied to a local buffer if
|
||||
it needs to be preserved.
|
||||
|
||||
If STRING is non-NULL, then the return value will be ignored, and there
|
||||
will be futher calls to handle_pragma_token() in order to handle the rest of
|
||||
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. */
|
||||
|
||||
int
|
||||
handle_pragma_token (string, token)
|
||||
char *string;
|
||||
char * string;
|
||||
tree token;
|
||||
{
|
||||
static enum pragma_state state = ps_start, type;
|
||||
static char *name;
|
||||
static char *value;
|
||||
static enum pragma_state state = ps_start;
|
||||
static enum pragma_state type;
|
||||
static char * name;
|
||||
static char * value;
|
||||
static int align;
|
||||
|
||||
/* If we have reached the end of the #pragma directive then
|
||||
determine what value we should return. */
|
||||
|
||||
if (string == NULL)
|
||||
{
|
||||
int ret_val = 1;
|
||||
|
||||
if (type == ps_pack)
|
||||
int ret_val = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
abort ();
|
||||
break;
|
||||
|
||||
case ps_done:
|
||||
/* The pragma was not recognised. */
|
||||
break;
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK
|
||||
case ps_pack:
|
||||
if (state == ps_right)
|
||||
maximum_field_alignment = align * 8;
|
||||
else
|
||||
{
|
||||
warning ("malformed `#pragma pack'");
|
||||
ret_val = 0;
|
||||
maximum_field_alignment = align * 8;
|
||||
ret_val = 1;
|
||||
}
|
||||
}
|
||||
else if (type == ps_bad)
|
||||
ret_val = 0;
|
||||
else if (type == ps_weak)
|
||||
{
|
||||
else
|
||||
warning ("malformed `#pragma pack'");
|
||||
break;
|
||||
#endif /* HANDLE_PRAGMA_PACK */
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
case ps_push:
|
||||
if (state == ps_right)
|
||||
ret_val = push_alignment (align);
|
||||
else
|
||||
warning ("incomplete '#pragma pack(push,<n>)'");
|
||||
break;
|
||||
|
||||
case ps_pop:
|
||||
if (state == ps_right)
|
||||
ret_val = pop_alignment ();
|
||||
else
|
||||
warning ("missing closing parenthesis in '#pragma pack(pop)'");
|
||||
break;
|
||||
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
|
||||
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
case ps_weak:
|
||||
if (HANDLE_PRAGMA_WEAK)
|
||||
handle_pragma_weak (state, name, value);
|
||||
{
|
||||
if (state == ps_name)
|
||||
ret_val = add_weak (name, NULL);
|
||||
else if (state == ps_value)
|
||||
ret_val = add_weak (name, value);
|
||||
else
|
||||
warning ("malformed `#pragma weak'");
|
||||
}
|
||||
else
|
||||
ret_val = 1; /* Ignore the pragma. */
|
||||
break;
|
||||
#endif /* HANDLE_PRAGMA_WEAK */
|
||||
}
|
||||
|
||||
|
@ -81,96 +306,134 @@ handle_pragma_token (string, token)
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/* If we have been given a token, but it is not an identifier,
|
||||
or a small constant, then something has gone wrong. */
|
||||
if (token)
|
||||
{
|
||||
switch (TREE_CODE (token))
|
||||
{
|
||||
case IDENTIFIER_NODE:
|
||||
break;
|
||||
|
||||
case INTEGER_CST:
|
||||
if (TREE_INT_CST_HIGH (token) != 0)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ps_start:
|
||||
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
|
||||
{
|
||||
if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0)
|
||||
type = state = ps_pack;
|
||||
type = state = ps_done;
|
||||
#ifdef HANDLE_PRAGMA_PACK
|
||||
if (strcmp (string, "pack") == 0)
|
||||
type = state = ps_pack;
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
|
||||
type = state = ps_weak;
|
||||
if (strcmp (string, "weak") == 0)
|
||||
type = state = ps_weak;
|
||||
#endif
|
||||
else
|
||||
type = state = ps_done;
|
||||
}
|
||||
else
|
||||
type = state = ps_done;
|
||||
break;
|
||||
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
case ps_weak:
|
||||
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
|
||||
name = permalloc (strlen (string) + 1);
|
||||
if (name == NULL)
|
||||
{
|
||||
name = IDENTIFIER_POINTER (token);
|
||||
state = ps_name;
|
||||
warning ("Out of memory parsing #pragma weak");
|
||||
state = ps_bad;
|
||||
}
|
||||
else
|
||||
state = ps_bad;
|
||||
{
|
||||
strcpy (name, string);
|
||||
state = ps_name;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ps_name:
|
||||
state = (strcmp (string, "=") ? ps_bad : ps_equals);
|
||||
break;
|
||||
|
||||
case ps_equals:
|
||||
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
|
||||
value = permalloc (strlen (string) + 1);
|
||||
if (value == NULL)
|
||||
{
|
||||
value = IDENTIFIER_POINTER (token);
|
||||
state = ps_value;
|
||||
warning ("Out of memory parsing #pragma weak");
|
||||
state = ps_bad;
|
||||
}
|
||||
else
|
||||
state = ps_bad;
|
||||
{
|
||||
strcpy (value, string);
|
||||
state = ps_value;
|
||||
}
|
||||
break;
|
||||
|
||||
case ps_value:
|
||||
state = ps_bad;
|
||||
break;
|
||||
|
||||
#endif /* HANDLE_PRAGMA_WEAK */
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK
|
||||
case ps_pack:
|
||||
if (strcmp (string, "(") == 0)
|
||||
state = ps_left;
|
||||
else
|
||||
state = ps_bad;
|
||||
state = (strcmp (string, "(") ? ps_bad : ps_left);
|
||||
break;
|
||||
|
||||
case ps_left:
|
||||
if (token && TREE_CODE (token) == INTEGER_CST
|
||||
&& TREE_INT_CST_HIGH (token) == 0)
|
||||
switch (TREE_INT_CST_LOW (token))
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
align = TREE_INT_CST_LOW (token);
|
||||
state = ps_align;
|
||||
break;
|
||||
|
||||
default:
|
||||
state = ps_bad;
|
||||
}
|
||||
else if (! token && strcmp (string, ")") == 0)
|
||||
align = atoi (string);
|
||||
switch (align)
|
||||
{
|
||||
align = 0;
|
||||
state = ps_right;
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
state = ps_align;
|
||||
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:
|
||||
state = ps_bad;
|
||||
break;
|
||||
}
|
||||
else
|
||||
state = ps_bad;
|
||||
break;
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
case ps_pop:
|
||||
#endif
|
||||
case ps_align:
|
||||
if (strcmp (string, ")") == 0)
|
||||
state = ps_right;
|
||||
else
|
||||
state = ps_bad;
|
||||
state = (strcmp (string, ")") ? ps_bad : ps_right);
|
||||
break;
|
||||
|
||||
case ps_right:
|
||||
state = ps_bad;
|
||||
break;
|
||||
#endif /* HANDLE_PRAGMA_PACK */
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
case ps_push:
|
||||
state = (strcmp (string, ",") ? ps_bad : ps_comma);
|
||||
break;
|
||||
|
||||
case ps_comma:
|
||||
align = atoi (string);
|
||||
state = ps_align;
|
||||
break;
|
||||
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
|
||||
|
||||
case ps_bad:
|
||||
case ps_done:
|
||||
break;
|
||||
|
@ -181,4 +444,4 @@ handle_pragma_token (string, token)
|
|||
|
||||
return 1;
|
||||
}
|
||||
#endif /* HANDLE_SYSV_PRAGMA */
|
||||
#endif /* HANDLE_GENERIC_PRAGMAS */
|
||||
|
|
|
@ -18,33 +18,83 @@ along with GNU CC; see the file COPYING. If not, write to
|
|||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef HANDLE_SYSV_PRAGMA
|
||||
#ifndef _C_PRAGMA_H
|
||||
#define _C_PRAGMA_H
|
||||
|
||||
#ifdef HANDLE_SYSV_PRAGMA
|
||||
/* Support #pragma weak iff ASM_WEAKEN_LABEL and ASM_OUTPUT_DEF are
|
||||
defined. */
|
||||
#if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_DEF)
|
||||
#define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK
|
||||
#endif
|
||||
|
||||
/* We always support #pragma pack for SYSV pragmas. */
|
||||
#ifndef HANDLE_PRAGMA_PACK
|
||||
#define HANDLE_PRAGMA_PACK 1
|
||||
#endif
|
||||
#endif /* HANDLE_SYSV_PRAGMA */
|
||||
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
/* 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 */
|
||||
|
||||
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
/* This structure contains any weak symbol declarations waiting to be emitted. */
|
||||
struct weak_syms
|
||||
{
|
||||
struct weak_syms * next;
|
||||
char * name;
|
||||
char * value;
|
||||
};
|
||||
|
||||
/* Declared in varasm.c */
|
||||
extern struct weak_syms * weak_decls;
|
||||
#endif /* HANDLE_PRAGMA_WEAK */
|
||||
|
||||
|
||||
#if defined HANDLE_PRAGMA_PACK || defined HANDLE_PRAGMA_WEAK
|
||||
/* Define HANDLE_GENERIC_PRAGMAS if any kind of front-end pragma
|
||||
parsing is to be done. The code in GCC's generic C source files
|
||||
will only look for the definition of this constant. They will
|
||||
ignore definitions of HANDLE_PRAGMA_PACk and so on. */
|
||||
#define HANDLE_GENERIC_PRAGMAS 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HANDLE_GENERIC_PRAGMAS
|
||||
enum pragma_state
|
||||
{
|
||||
ps_start,
|
||||
ps_done,
|
||||
ps_bad,
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
ps_weak,
|
||||
ps_name,
|
||||
ps_equals,
|
||||
ps_value,
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_PACK
|
||||
ps_pack,
|
||||
ps_left,
|
||||
ps_align,
|
||||
ps_right
|
||||
ps_right,
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
ps_push,
|
||||
ps_pop,
|
||||
ps_comma,
|
||||
#endif
|
||||
ps_bad
|
||||
};
|
||||
|
||||
/* Output asm to handle ``#pragma weak'' */
|
||||
extern void handle_pragma_weak PROTO((enum pragma_state, char *, char *));
|
||||
|
||||
/* Handle a C style pragma */
|
||||
extern int handle_pragma_token PROTO((char *, tree));
|
||||
|
||||
#endif /* HANDLE_SYSV_PRAGMA */
|
||||
#endif /* HANDLE_GENERIC_PRAGMAS */
|
||||
#endif /* _C_PRAGMA_H */
|
||||
|
|
|
@ -2662,6 +2662,9 @@ do { \
|
|||
FAIL; \
|
||||
} while (0)
|
||||
|
||||
/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
|
||||
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
|
||||
|
||||
|
||||
/* Functions in i386.c */
|
||||
extern void override_options ();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Operating system specific defines to be used when targeting GCC for
|
||||
Windows NT 3.x.
|
||||
Copyright (C) 1994, 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
|
||||
Contributed by Douglas B. Rupp (drupp@cs.washington.edu).
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
@ -29,7 +29,7 @@ Boston, MA 02111-1307, USA. */
|
|||
#define LINK_SPEC "-stack 5000000,5000000 -noinhibit-exec %{g}"
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "-lang-c-c++-comments"
|
||||
#define CPP_SPEC ""
|
||||
|
||||
#undef STANDARD_EXEC_PREFIX
|
||||
#define STANDARD_EXEC_PREFIX ""
|
||||
|
@ -51,8 +51,11 @@ Boston, MA 02111-1307, USA. */
|
|||
#undef INCLUDE_DEFAULTS
|
||||
#define INCLUDE_DEFAULTS \
|
||||
{ \
|
||||
{ 0, 0, 0 } \
|
||||
{ 0, 0, 0, 0 } \
|
||||
}
|
||||
|
||||
#undef STDC_VALUE
|
||||
#define STDC_VALUE 0
|
||||
|
||||
/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
|
||||
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
|
||||
|
|
39
gcc/tm.texi
39
gcc/tm.texi
|
@ -7345,10 +7345,10 @@ C++, which is to pretend that the file's contents are enclosed in
|
|||
@findex HANDLE_PRAGMA
|
||||
@findex #pragma
|
||||
@findex pragma
|
||||
@item HANDLE_PRAGMA (@var{getc}, @var{ungetc}, @var{node})
|
||||
@item HANDLE_PRAGMA (@var{getc}, @var{ungetc}, @var{name})
|
||||
Define this macro if you want to implement any pragmas. If defined, it
|
||||
is a C expression whose value is 1 if the pragma was handled by the
|
||||
function, zero otherwise. The argument @var{getc} is a function of type
|
||||
macro, zero otherwise. The argument @var{getc} is a function of type
|
||||
@samp{int (*)(void)} which will return the next character in the input
|
||||
stream, or EOF if no characters are left. The argument @var{ungetc} is
|
||||
a function of type @samp{void (*)(int)} which will push a character back
|
||||
|
@ -7356,8 +7356,8 @@ into the input stream. The argument @var{name} is the word following
|
|||
#pragma in the input stream. The input stream pointer will be pointing
|
||||
just beyond the end of this word. The input stream should be left
|
||||
undistrubed if the expression returns zero, otherwise it should be
|
||||
pointing at the last character after the end of the pragma (newline or
|
||||
end-of-file).
|
||||
pointing at the next character after the end of the pragma. Any
|
||||
characters remaining on the line will be ignored.
|
||||
|
||||
It is generally a bad idea to implement new uses of @code{#pragma}. The
|
||||
only reason to define this macro is for compatibility with other
|
||||
|
@ -7371,6 +7371,37 @@ Note: older versions of this macro only had two arguments: @var{stream}
|
|||
and @var{token}. The macro was changed in order to allow it to work
|
||||
when gcc is built both with and without a cpp library.
|
||||
|
||||
@findex HANDLE_SYSV_PRAGMA
|
||||
@findex #pragma
|
||||
@findex pragma
|
||||
@item HANDLE_SYSV_PRAGMA
|
||||
Define this macro (to a value of 1) if you want the System V style
|
||||
pragmas @samp{#pragma pack(<n>)} and @samp{#pragma weak <name>
|
||||
[=<value>]} to be supported by gcc.
|
||||
|
||||
The pack pragma specifies the maximum alignment (in bytes) of fields
|
||||
within a structure, in much the same way as the @samp{__aligned__} and
|
||||
@samp{__packed__} @code{__attribute__}s do. A pack value of zero resets
|
||||
the behaviour to the default.
|
||||
|
||||
The weak pragma only works if @code{SUPPORTS_WEAK} and
|
||||
@code{ASM_WEAKEN_LABEL} are defined. If enabled it allows the creation
|
||||
of specifically named weak labels, optionally with a value.
|
||||
|
||||
@findex HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
@findex #pragma
|
||||
@findex pragma
|
||||
@item HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
Define this macro (to a value of 1) if you want to support the Win32
|
||||
style pragmas @samp{#pragma pack(push,<n>)} and @samp{#pragma
|
||||
pack(pop)}. The pack(push,<n>) pragma specifies the maximum alignment
|
||||
(in bytes) of fields within a structure, in much the same way as the
|
||||
@samp{__aligned__} and @samp{__packed__} @code{__attribute__}s do. A
|
||||
pack value of zero resets the behaviour to the default. Successive
|
||||
invocations of this pragma cause the previous values to be stacked, so
|
||||
that invocations of @samp{#pragma pack(pop)} will return to the previous
|
||||
value.
|
||||
|
||||
@findex VALID_MACHINE_DECL_ATTRIBUTE
|
||||
@item VALID_MACHINE_DECL_ATTRIBUTE (@var{decl}, @var{attributes}, @var{identifier}, @var{args})
|
||||
If defined, a C expression whose value is nonzero if @var{identifier} with
|
||||
|
|
50
gcc/varasm.c
50
gcc/varasm.c
|
@ -116,20 +116,6 @@ int size_directive_output;
|
|||
|
||||
tree last_assemble_variable_decl;
|
||||
|
||||
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
/* Any weak symbol declarations waiting to be emitted. */
|
||||
|
||||
struct weak_syms
|
||||
{
|
||||
struct weak_syms *next;
|
||||
char *name;
|
||||
char *value;
|
||||
};
|
||||
|
||||
static struct weak_syms *weak_decls;
|
||||
#endif
|
||||
|
||||
/* Nonzero if at least one function definition has been seen. */
|
||||
|
||||
static int function_defined;
|
||||
|
@ -4246,38 +4232,6 @@ output_constructor (exp, size)
|
|||
assemble_zeros (size - total_bytes);
|
||||
}
|
||||
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
/* Output asm to handle ``#pragma weak'' */
|
||||
|
||||
void
|
||||
handle_pragma_weak (what, name, value)
|
||||
enum pragma_state what;
|
||||
char *name, *value;
|
||||
{
|
||||
if (what == ps_name || what == ps_value)
|
||||
{
|
||||
struct weak_syms *weak =
|
||||
(struct weak_syms *)permalloc (sizeof (struct weak_syms));
|
||||
weak->next = weak_decls;
|
||||
weak->name = permalloc (strlen (name) + 1);
|
||||
strcpy (weak->name, name);
|
||||
|
||||
if (what != ps_value)
|
||||
weak->value = NULL_PTR;
|
||||
|
||||
else
|
||||
{
|
||||
weak->value = permalloc (strlen (value) + 1);
|
||||
strcpy (weak->value, value);
|
||||
}
|
||||
|
||||
weak_decls = weak;
|
||||
}
|
||||
else if (! (what == ps_done || what == ps_start))
|
||||
warning ("malformed `#pragma weak'");
|
||||
}
|
||||
#endif /* HANDLE_PRAGMA_WEAK */
|
||||
|
||||
/* Declare DECL to be a weak symbol. */
|
||||
|
||||
void
|
||||
|
@ -4294,6 +4248,10 @@ declare_weak (decl)
|
|||
|
||||
/* Emit any pending weak declarations. */
|
||||
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
struct weak_syms * weak_decls;
|
||||
#endif
|
||||
|
||||
void
|
||||
weak_finish ()
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue