Commit e2af664c by Nick Clifton Committed by Nick Clifton

Add support for #pragma pack(push,<n>) and #pragma pack(pop).

From-SVN: r22710
parent 3a846e6e
Thu Oct 1 10:42:27 1998 Nick Clifton <nickc@cygnus.com> 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 * c-decl.c (start_function): Add invocation of
SET_DEFAULT_DECL_ATTRIBUTES, if defined. SET_DEFAULT_DECL_ATTRIBUTES, if defined.
* tm.texi: Remove description of non-existant macro * tm.texi: Remove description of non-existant macro
SET_DEFAULT_SECTION_NAME. 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> Wed Sep 30 22:27:53 1998 Robert Lipe <robertl@dgii.com>
......
...@@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */
#include "obstack.h" #include "obstack.h"
#include "toplev.h" #include "toplev.h"
#include "output.h" #include "output.h"
#include "c-pragma.h"
#if USE_CPPLIB #if USE_CPPLIB
#include "cpplib.h" #include "cpplib.h"
...@@ -420,6 +421,14 @@ decl_attributes (node, attributes, prefix_attributes) ...@@ -420,6 +421,14 @@ decl_attributes (node, attributes, prefix_attributes)
else if (TREE_CODE_CLASS (TREE_CODE (node)) == 't') else if (TREE_CODE_CLASS (TREE_CODE (node)) == 't')
type = node, is_type = 1; 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 #ifdef INSERT_ATTRIBUTES
INSERT_ATTRIBUTES (node, & attributes, & prefix_attributes); INSERT_ATTRIBUTES (node, & attributes, & prefix_attributes);
#endif #endif
......
...@@ -110,9 +110,9 @@ static int end_of_file; ...@@ -110,9 +110,9 @@ static int end_of_file;
static int nextchar = -1; static int nextchar = -1;
#endif #endif
#ifdef HANDLE_SYSV_PRAGMA #ifdef HANDLE_GENERIC_PRAGMAS
static int handle_sysv_pragma PROTO((int)); static int handle_generic_pragma PROTO((int));
#endif /* HANDLE_SYSV_PRAGMA */ #endif /* HANDLE_GENERIC_PRAGMAS */
static int whitespace_cr PROTO((int)); static int whitespace_cr PROTO((int));
static int skip_white_space PROTO((int)); static int skip_white_space PROTO((int));
static int skip_white_space_on_line PROTO((void)); static int skip_white_space_on_line PROTO((void));
...@@ -543,34 +543,37 @@ check_newline () ...@@ -543,34 +543,37 @@ check_newline ()
if (c == '\n') if (c == '\n')
return c; return c;
#if defined HANDLE_PRAGMA || defined HANDLE_SYSV_PRAGMA #if defined HANDLE_PRAGMA || defined HANDLE_GENERIC_PRAGMAS
UNGETC (c); UNGETC (c);
token = yylex (); token = yylex ();
if (token != IDENTIFIER) if (token != IDENTIFIER)
goto skipline; goto skipline;
#endif /* HANDLE_PRAGMA || HANDLE_GENERIC_PRAGMAS */
#ifdef HANDLE_PRAGMA #ifdef HANDLE_PRAGMA
/* We invoke HANDLE_PRAGMA before HANDLE_SYSV_PRAGMA /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS (if
(if both are defined), in order to give the back both are defined), in order to give the back end a chance to
end a chance to override the interpretation of override the interpretation of generic style pragmas. */
SYSV style pragmas. */
#if !USE_CPPLIB #if !USE_CPPLIB
if (nextchar >= 0) if (nextchar >= 0)
{ {
c = nextchar, nextchar = -1; c = nextchar, nextchar = -1;
UNGETC (c); UNGETC (c);
} }
#endif #endif /* !USE_CPPLIB */
if (TREE_CODE (yylval.ttype) != IDENTIFIER_NODE)
goto skipline;
if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
IDENTIFIER_POINTER (yylval.ttype))) IDENTIFIER_POINTER (yylval.ttype)))
return GETC (); return GETC ();
#endif /* HANDLE_PRAGMA */ #endif /* HANDLE_PRAGMA */
#ifdef HANDLE_SYSV_PRAGMA #ifdef HANDLE_GENERIC_PRAGMAS
if (handle_sysv_pragma (token)) if (handle_generic_pragma (token))
return GETC (); return GETC ();
#endif /* !HANDLE_SYSV_PRAGMA */ #endif /* HANDLE_GENERIC_PRAGMAS */
#endif /* HANDLE_PRAGMA || HANDLE_SYSV_PRAGMA */
/* Issue a warning message if we have been asked to do so. /* Issue a warning message if we have been asked to do so.
Ignoring unknown pragmas in system header file unless Ignoring unknown pragmas in system header file unless
...@@ -837,17 +840,17 @@ linenum: ...@@ -837,17 +840,17 @@ linenum:
return c; return c;
} }
#ifdef HANDLE_SYSV_PRAGMA #ifdef HANDLE_GENERIC_PRAGMAS
/* Handle a #pragma directive. /* Handle a #pragma directive.
TOKEN is the token we read after `#pragma'. Processes the entire input 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 /* This function has to be in this file, in order to get at
the token types. */ the token types. */
static int static int
handle_sysv_pragma (token) handle_generic_pragma (token)
register int token; register int token;
{ {
register int c; register int c;
...@@ -883,7 +886,7 @@ handle_sysv_pragma (token) ...@@ -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 */ #define ENDFILE -1 /* token that represents end-of-file */
......
...@@ -29,50 +29,275 @@ Boston, MA 02111-1307, USA. */ ...@@ -29,50 +29,275 @@ Boston, MA 02111-1307, USA. */
#include "flags.h" #include "flags.h"
#include "toplev.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 /* When structure field packing is in effect, this variable is the
number of bits to use as the maximum alignment. When packing is not number of bits to use as the maximum alignment. When packing is not
in effect, this is zero. */ in effect, this is zero. */
extern int maximum_field_alignment; extern int maximum_field_alignment;
#endif
#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;
/* Handle one token of a pragma directive. TOKEN is the weak = (struct weak_syms *) permalloc (sizeof (struct weak_syms));
current token, and STRING is its printable form.
Return zero if an entire pragma was parsed, but it was if (weak == NULL)
flawed in some way. Return non-zero in all other cases. */ 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 int
handle_pragma_token (string, token) handle_pragma_token (string, token)
char *string; char * string;
tree token; tree token;
{ {
static enum pragma_state state = ps_start, type; static enum pragma_state state = ps_start;
static char *name; static enum pragma_state type;
static char *value; static char * name;
static char * value;
static int align; static int align;
/* If we have reached the end of the #pragma directive then
determine what value we should return. */
if (string == NULL) if (string == NULL)
{ {
int ret_val = 1; int ret_val = 0;
if (type == ps_pack) 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) if (state == ps_right)
maximum_field_alignment = align * 8;
else
{ {
warning ("malformed `#pragma pack'"); maximum_field_alignment = align * 8;
ret_val = 0; ret_val = 1;
} }
} else
else if (type == ps_bad) warning ("malformed `#pragma pack'");
ret_val = 0; break;
else if (type == ps_weak) #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 #ifdef HANDLE_PRAGMA_WEAK
case ps_weak:
if (HANDLE_PRAGMA_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 */ #endif /* HANDLE_PRAGMA_WEAK */
} }
...@@ -81,96 +306,134 @@ handle_pragma_token (string, token) ...@@ -81,96 +306,134 @@ handle_pragma_token (string, token)
return ret_val; 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) switch (state)
{ {
case ps_start: case ps_start:
if (token && TREE_CODE (token) == IDENTIFIER_NODE) type = state = ps_done;
{ #ifdef HANDLE_PRAGMA_PACK
if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0) if (strcmp (string, "pack") == 0)
type = state = ps_pack; type = state = ps_pack;
#endif
#ifdef HANDLE_PRAGMA_WEAK #ifdef HANDLE_PRAGMA_WEAK
else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0) if (strcmp (string, "weak") == 0)
type = state = ps_weak; type = state = ps_weak;
#endif #endif
else
type = state = ps_done;
}
else
type = state = ps_done;
break; break;
#ifdef HANDLE_PRAGMA_WEAK #ifdef HANDLE_PRAGMA_WEAK
case ps_weak: case ps_weak:
if (token && TREE_CODE (token) == IDENTIFIER_NODE) name = permalloc (strlen (string) + 1);
if (name == NULL)
{ {
name = IDENTIFIER_POINTER (token); warning ("Out of memory parsing #pragma weak");
state = ps_name; state = ps_bad;
} }
else else
state = ps_bad; {
strcpy (name, string);
state = ps_name;
}
break; break;
#endif
case ps_name: case ps_name:
state = (strcmp (string, "=") ? ps_bad : ps_equals); state = (strcmp (string, "=") ? ps_bad : ps_equals);
break; break;
case ps_equals: case ps_equals:
if (token && TREE_CODE (token) == IDENTIFIER_NODE) value = permalloc (strlen (string) + 1);
if (value == NULL)
{ {
value = IDENTIFIER_POINTER (token); warning ("Out of memory parsing #pragma weak");
state = ps_value; state = ps_bad;
} }
else else
state = ps_bad; {
strcpy (value, string);
state = ps_value;
}
break; break;
case ps_value: case ps_value:
state = ps_bad; state = ps_bad;
break; break;
#endif /* HANDLE_PRAGMA_WEAK */
#ifdef HANDLE_PRAGMA_PACK
case ps_pack: case ps_pack:
if (strcmp (string, "(") == 0) state = (strcmp (string, "(") ? ps_bad : ps_left);
state = ps_left;
else
state = ps_bad;
break; break;
case ps_left: case ps_left:
if (token && TREE_CODE (token) == INTEGER_CST align = atoi (string);
&& TREE_INT_CST_HIGH (token) == 0) switch (align)
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 = 0; case 1:
state = ps_right; 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; break;
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
case ps_pop:
#endif
case ps_align: case ps_align:
if (strcmp (string, ")") == 0) state = (strcmp (string, ")") ? ps_bad : ps_right);
state = ps_right;
else
state = ps_bad;
break; break;
case ps_right: case ps_right:
state = ps_bad; state = ps_bad;
break; 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_bad:
case ps_done: case ps_done:
break; break;
...@@ -181,4 +444,4 @@ handle_pragma_token (string, token) ...@@ -181,4 +444,4 @@ handle_pragma_token (string, token)
return 1; 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 ...@@ -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, the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */ 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 /* Support #pragma weak iff ASM_WEAKEN_LABEL and ASM_OUTPUT_DEF are
defined. */ defined. */
#if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_DEF) #if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_DEF)
#define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK #define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK
#endif #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 enum pragma_state
{ {
ps_start, ps_start,
ps_done, ps_done,
ps_bad, #ifdef HANDLE_PRAGMA_WEAK
ps_weak, ps_weak,
ps_name, ps_name,
ps_equals, ps_equals,
ps_value, ps_value,
#endif
#ifdef HANDLE_PRAGMA_PACK
ps_pack, ps_pack,
ps_left, ps_left,
ps_align, 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 */ /* Handle a C style pragma */
extern int handle_pragma_token PROTO((char *, tree)); 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 { \ ...@@ -2662,6 +2662,9 @@ do { \
FAIL; \ FAIL; \
} while (0) } while (0)
/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
/* Functions in i386.c */ /* Functions in i386.c */
extern void override_options (); extern void override_options ();
......
/* Operating system specific defines to be used when targeting GCC for /* Operating system specific defines to be used when targeting GCC for
Windows NT 3.x. 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). Contributed by Douglas B. Rupp (drupp@cs.washington.edu).
This file is part of GNU CC. This file is part of GNU CC.
...@@ -29,7 +29,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -29,7 +29,7 @@ Boston, MA 02111-1307, USA. */
#define LINK_SPEC "-stack 5000000,5000000 -noinhibit-exec %{g}" #define LINK_SPEC "-stack 5000000,5000000 -noinhibit-exec %{g}"
#undef CPP_SPEC #undef CPP_SPEC
#define CPP_SPEC "-lang-c-c++-comments" #define CPP_SPEC ""
#undef STANDARD_EXEC_PREFIX #undef STANDARD_EXEC_PREFIX
#define STANDARD_EXEC_PREFIX "" #define STANDARD_EXEC_PREFIX ""
...@@ -51,8 +51,11 @@ Boston, MA 02111-1307, USA. */ ...@@ -51,8 +51,11 @@ Boston, MA 02111-1307, USA. */
#undef INCLUDE_DEFAULTS #undef INCLUDE_DEFAULTS
#define INCLUDE_DEFAULTS \ #define INCLUDE_DEFAULTS \
{ \ { \
{ 0, 0, 0 } \ { 0, 0, 0, 0 } \
} }
#undef STDC_VALUE #undef STDC_VALUE
#define STDC_VALUE 0 #define STDC_VALUE 0
/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
...@@ -7345,10 +7345,10 @@ C++, which is to pretend that the file's contents are enclosed in ...@@ -7345,10 +7345,10 @@ C++, which is to pretend that the file's contents are enclosed in
@findex HANDLE_PRAGMA @findex HANDLE_PRAGMA
@findex #pragma @findex #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 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 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 @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 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 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 ...@@ -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 #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 just beyond the end of this word. The input stream should be left
undistrubed if the expression returns zero, otherwise it should be undistrubed if the expression returns zero, otherwise it should be
pointing at the last character after the end of the pragma (newline or pointing at the next character after the end of the pragma. Any
end-of-file). characters remaining on the line will be ignored.
It is generally a bad idea to implement new uses of @code{#pragma}. The 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 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} ...@@ -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 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. 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 @findex VALID_MACHINE_DECL_ATTRIBUTE
@item VALID_MACHINE_DECL_ATTRIBUTE (@var{decl}, @var{attributes}, @var{identifier}, @var{args}) @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 If defined, a C expression whose value is nonzero if @var{identifier} with
......
...@@ -116,20 +116,6 @@ int size_directive_output; ...@@ -116,20 +116,6 @@ int size_directive_output;
tree last_assemble_variable_decl; 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. */ /* Nonzero if at least one function definition has been seen. */
static int function_defined; static int function_defined;
...@@ -4246,38 +4232,6 @@ output_constructor (exp, size) ...@@ -4246,38 +4232,6 @@ output_constructor (exp, size)
assemble_zeros (size - total_bytes); 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. */ /* Declare DECL to be a weak symbol. */
void void
...@@ -4294,6 +4248,10 @@ declare_weak (decl) ...@@ -4294,6 +4248,10 @@ declare_weak (decl)
/* Emit any pending weak declarations. */ /* Emit any pending weak declarations. */
#ifdef HANDLE_PRAGMA_WEAK
struct weak_syms * weak_decls;
#endif
void void
weak_finish () weak_finish ()
{ {
......
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