This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch to support #pragma pack(push,<n>) and #pragma pack(pop)


Hi Guys,

  I would like to submit the patch below for inclusion into EGCS.  It
implements the pragmas "pack(push,<n>)" and "pack(pop)" as specified
by Microsoft's compilers.  This will allow the i386 and win-nt ports
to use header files containing these pragmas.

This patch is being submitted as a change to the machine independent
part of gcc (specifically gcc/c-pragma.c) because:

	a) it is used by more than one port,
and	b) c-pragma.c already contains code to implement #pragma
	   pack(<n>) and this is just an extension to that code.

One possibly controversial feature of this patch is that it moves the
code for handle_pragma_weak() from gcc/varasm.c into gcc/c-pragma.c.
I did this because I feel that it is better to keep as much of the
pragma parsing/handling code as possible in one file.  The downside of
this change is that I had to modify the Makefile.in files for Fortran
and Chill in order to have them include ../c-pragma.o in their builds.

This patch implements a new target macro called HANDLE_PRAGMA_PACK_PUSH_POP
which, if defined, enables the parsing of the push and pop pragmas.

Another feature of the patch is that it removes the occurance of
HANDLE_SYSV_PRAGMA from the C source files.  Instead this macro is
handled by gcc/c-pragma.h which defines the more general
HANDLE_GENERIC_PRAGMAS if any of the special pragma handling code is
enabled.  Then the C source files (c-lex.c, cp/lex.c, etc) need only
test for the presence of this one macro.  I am not particularly set on
the name, however, should someone have a better suggestion...

As a side effect of this change, HANDLE_SYSV_PRAGMA is now documented
in tm.texi as well. 

Cheers
	Nick

------------------------patches in gcc directory---------------------

Tue Sep 15 10:18:36 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 'struct weak_syms' into c-pragma.h.
	(handle_pragma_weak): Deleted.

	* tm.texi (HANDLE_SYSV_PRAGMA): Document.
	(HANDLE_PRAGMA_PACK_PUSH_POP): Document.

	* config/i386/i386.h: Define HANDLE_PRAGMA_PACK_PUSH_POP.

	* config/winnt/win-nt.h: Define HANDLE_PRAGMA_PACK_PUSH_POP.


Index: c-pragma.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-pragma.c,v
retrieving revision 1.8
diff -p -w -r1.8 c-pragma.c
*** c-pragma.c	1998/09/02 09:59:51	1.8
--- c-pragma.c	1998/09/15 16:56:24
*************** Boston, MA 02111-1307, USA.  */
*** 29,78 ****
  #include "flags.h"
  #include "toplev.h"
  
! #ifdef HANDLE_SYSV_PRAGMA
  
  /* 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;
  
! /* 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.  */
  
  int
  handle_pragma_token (string, token)
       char *string;
       tree token;
  {
!   static enum pragma_state state = ps_start, type;
    static char *name;
    static char *value;
    static int align;
  
    if (string == NULL)
      {
!       int ret_val = 1;
        
!       if (type == ps_pack)
  	{
  	  if (state == ps_right)
  	    maximum_field_alignment = align * 8;
  	  else
- 	    {
  	      warning ("malformed `#pragma pack'");
! 	      ret_val = 0;
! 	    }
! 	}
!       else if (type == ps_bad)
! 	ret_val = 0;
!       else if (type == ps_weak)
! 	{
  #ifdef HANDLE_PRAGMA_WEAK
  	  if (HANDLE_PRAGMA_WEAK)
! 	    handle_pragma_weak (state, name, value);
  #endif /* HANDLE_PRAGMA_WEAK */
  	}
  
--- 29,305 ----
  #include "flags.h"
  #include "toplev.h"
  
! #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
+ 
+ 
+ #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
! struct weak_syms * weak_decls;
! 
! 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;
       tree token;
  {
!   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 = 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;
+ 	      ret_val = 1;
+ 	    }
  	  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)
! 	    {
! 	      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 */
  	}
  
*************** handle_pragma_token (string, token)
*** 81,175 ****
        return ret_val;
      }
  
    switch (state)
      {
      case ps_start:
!       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
! 	{
! 	  if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0)
  	    type = state = ps_pack;
  #ifdef HANDLE_PRAGMA_WEAK
! 	  else if (strcmp (IDENTIFIER_POINTER (token), "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 = IDENTIFIER_POINTER (token);
! 	  state = ps_name;
  	}
        else
! 	state = ps_bad;
        break;
- #endif
        
      case ps_name:
        state = (strcmp (string, "=") ? ps_bad : ps_equals);
        break;
  
      case ps_equals:
!       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
  	{
! 	  value = IDENTIFIER_POINTER (token);
! 	  state = ps_value;
  	}
        else
! 	state = ps_bad;
        break;
  
      case ps_value:
        state = ps_bad;
        break;
  
      case ps_pack:
!       if (strcmp (string, "(") == 0)
! 	state = ps_left;
!       else
! 	state = ps_bad;
        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 = 0;
- 	  state = ps_right;
- 	}
-       else
- 	state = ps_bad;
        break;
  
      case ps_align:
!       if (strcmp (string, ")") == 0)
! 	state = ps_right;
!       else
! 	state = ps_bad;
        break;
  
      case ps_right:
        state = ps_bad;
        break;
  
      case ps_bad:
      case ps_done:
--- 308,440 ----
        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:
!       type = state = ps_done;
! #ifdef HANDLE_PRAGMA_PACK
!       if (strcmp (string, "pack") == 0)
  	type = state = ps_pack;
+ #endif
  #ifdef HANDLE_PRAGMA_WEAK
!       if (strcmp (string, "weak") == 0)
  	type = state = ps_weak;
  #endif	  
        break;
        
  #ifdef HANDLE_PRAGMA_WEAK
      case ps_weak:
!       name = permalloc (strlen (string) + 1);
!       if (name == NULL)
  	{
! 	  warning ("Out of memory parsing #pragma weak");
! 	  state = ps_bad;
  	}
        else
! 	{
! 	  strcpy (name, string);
! 	  state = ps_name;
! 	}
        break;
        
      case ps_name:
        state = (strcmp (string, "=") ? ps_bad : ps_equals);
        break;
  
      case ps_equals:
!       value = permalloc (strlen (string) + 1);
!       if (value == NULL)
  	{
! 	  warning ("Out of memory parsing #pragma weak");
! 	  state = ps_bad;
  	}
        else
! 	{
! 	  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:
!       state = (strcmp (string, "(") ? ps_bad : ps_left);
        break;
  
      case ps_left:
!       align = atoi (string);
!       switch (align)
  	{
  	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;
  	}
        break;
  
+ #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
+     case ps_pop:
+ #endif
      case ps_align:
!       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:
*************** handle_pragma_token (string, token)
*** 181,184 ****
  
    return 1;
  }
! #endif /* HANDLE_SYSV_PRAGMA */
--- 446,449 ----
  
    return 1;
  }
! #endif /* HANDLE_GENERIC_PRAGMAS */


Index: c-pragma.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-pragma.h,v
retrieving revision 1.3
diff -p -w -r1.3 c-pragma.h
*** c-pragma.h	1998/09/02 09:59:52	1.3
--- c-pragma.h	1998/09/15 16:56:33
*************** along with GNU CC; see the file COPYING.
*** 18,50 ****
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
! #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
  
  enum pragma_state
  {
    ps_start,
    ps_done,
!   ps_bad,
    ps_weak,
    ps_name,
    ps_equals,
    ps_value,
    ps_pack,
    ps_left,
    ps_align,
!   ps_right
  };
  
- /* 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 */
--- 18,99 ----
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
! #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;
+ };
+ 
+ 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,
! #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,
! #endif
! #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
!   ps_push,
!   ps_pop,
!   ps_comma,
! #endif
!   ps_bad
  };
  
  /* Handle a C style pragma */
  extern int handle_pragma_token PROTO((char *, tree));
  
! #endif /* HANDLE_GENERIC_PRAGMAS */
! #endif /* _C_PRAGMA_H */


Index: c-common.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-common.c,v
retrieving revision 1.31
diff -p -w -r1.31 c-common.c
*** c-common.c	1998/09/02 09:59:54	1.31
--- c-common.c	1998/09/15 16:56:02
*************** Boston, MA 02111-1307, USA.  */
*** 27,32 ****
--- 27,33 ----
  #include "obstack.h"
  #include "toplev.h"
  #include "output.h"
+ #include "c-pragma.h"
  
  #if USE_CPPLIB
  #include "cpplib.h"
*************** decl_attributes (node, attributes, prefi
*** 420,425 ****
--- 421,434 ----
    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


Index: c-lex.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/c-lex.c,v
retrieving revision 1.30
diff -p -w -r1.30 c-lex.c
*** c-lex.c	1998/09/09 22:02:02	1.30
--- c-lex.c	1998/09/15 16:56:14
*************** static int end_of_file;
*** 114,122 ****
  static int nextchar = -1;
  #endif
  
! #ifdef HANDLE_SYSV_PRAGMA
! static int handle_sysv_pragma		PROTO((int));
! #endif /* HANDLE_SYSV_PRAGMA */
  static int whitespace_cr		PROTO((int));
  static int skip_white_space		PROTO((int));
  static int skip_white_space_on_line	PROTO((void));
--- 114,122 ----
  static int nextchar = -1;
  #endif
  
! #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));
*************** check_newline ()
*** 547,563 ****
  	      if (c == '\n')
  		return c;
  
! #if defined HANDLE_PRAGMA || defined HANDLE_SYSV_PRAGMA	      
  	      UNGETC (c);
  	      token = yylex ();
  	      if (token != IDENTIFIER)
  		goto skipline;
  	      
  #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.  */
  #if !USE_CPPLIB
  	      if (nextchar >= 0)
  		{
--- 547,562 ----
  	      if (c == '\n')
  		return c;
  
! #if defined HANDLE_PRAGMA || defined HANDLE_GENERIC_PRAGMAS
  	      UNGETC (c);
  	      token = yylex ();
  	      if (token != IDENTIFIER)
  		goto skipline;
  	      
  #ifdef HANDLE_PRAGMA
! 	      /* 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)
  		{
*************** check_newline ()
*** 570,580 ****
  		return GETC ();
  #endif /* HANDLE_PRAGMA */
  	      
! #ifdef HANDLE_SYSV_PRAGMA
! 	      if (handle_sysv_pragma (token))
  		return GETC ();
! #endif /* !HANDLE_SYSV_PRAGMA */
! #endif /* HANDLE_PRAGMA || HANDLE_SYSV_PRAGMA */
  	      
  	      /* Issue a warning message if we have been asked to do so.
  		 Ignoring unknown pragmas in system header file unless
--- 569,579 ----
  		return GETC ();
  #endif /* HANDLE_PRAGMA */
  	      
! #ifdef HANDLE_GENERIC_PRAGMAS
! 	      if (handle_generic_pragma (token))
  		return GETC ();
! #endif /* !HANDLE_GENERIC_PRAGMAS */
! #endif /* HANDLE_PRAGMA || HANDLE_GENERIC_PRAGMAS */
  	      
  	      /* Issue a warning message if we have been asked to do so.
  		 Ignoring unknown pragmas in system header file unless
*************** linenum:
*** 841,857 ****
    return c;
  }
  
! #ifdef HANDLE_SYSV_PRAGMA
  
  /* 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.  */
  
  /* This function has to be in this file, in order to get at
     the token types.  */
  
  static int
! handle_sysv_pragma (token)
       register int token;
  {
    register int c;
--- 840,856 ----
    return c;
  }
  
! #ifdef HANDLE_GENERIC_PRAGMAS
  
  /* Handle a #pragma directive.
     TOKEN is the token we read after `#pragma'.  Processes the entire input
!    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_generic_pragma (token)
       register int token;
  {
    register int c;
*************** handle_sysv_pragma (token)
*** 887,893 ****
      }
  }
  
! #endif /* HANDLE_SYSV_PRAGMA */
  
  #define ENDFILE -1  /* token that represents end-of-file */
  
--- 886,892 ----
      }
  }
  
! #endif /* HANDLE_GENERIC_PRAGMAS */
  
  #define ENDFILE -1  /* token that represents end-of-file */
  

Index: varasm.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/varasm.c,v
retrieving revision 1.39
diff -p -w -r1.39 varasm.c
*** varasm.c	1998/09/02 09:59:53	1.39
--- varasm.c	1998/09/15 21:12:28
*************** int size_directive_output;
*** 116,135 ****
  
  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;
--- 116,121 ----
*************** output_constructor (exp, size)
*** 4243,4280 ****
    if (total_bytes < 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.  */
  
--- 4229,4234 ----


Index: tm.texi
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tm.texi,v
retrieving revision 1.49
diff -p -w -r1.49 tm.texi
*** tm.texi	1998/09/02 09:59:56	1.49
--- tm.texi	1998/09/15 16:56:50
*************** Note: older versions of this macro only 
*** 7341,7346 ****
--- 7341,7377 ----
  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


Index: config/i386/i386.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/i386/i386.h,v
retrieving revision 1.34
diff -p -w -r1.34 i386.h
*** i386.h	1998/09/08 22:48:00	1.34
--- i386.h	1998/09/15 16:59:26
*************** do {									\
*** 2660,2665 ****
--- 2660,2668 ----
      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 ();


Index: config/winnt/win-nt.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/winnt/win-nt.h,v
retrieving revision 1.1.1.3
diff -p -w -r1.1.1.3 win-nt.h
*** win-nt.h	1997/12/06 17:29:28	1.1.1.3
--- win-nt.h	1998/09/15 17:00:20
*************** Boston, MA 02111-1307, USA.  */
*** 56,58 ****
--- 56,61 ----
  
  #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



------------------------patches in c++ subdirectory---------------------

Tue Sep 15 10:18:36 1998  Nick Clifton  <nickc@cygnus.com>

	* lex.c: Replace occurances of HANDLE_SYSV_PRAGMA with
	HANDLE_GENERIC_PRAGMAS.


Index: cp/lex.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/lex.c,v
retrieving revision 1.74
diff -p -w -r1.74 lex.c
*** lex.c	1998/09/07 14:25:12	1.74
--- lex.c	1998/09/15 16:58:27
*************** static void store_pending_inline PROTO((
*** 79,86 ****
  static void reinit_parse_for_expr PROTO((struct obstack *));
  static int *init_cpp_parse PROTO((void));
  static int handle_cp_pragma PROTO((char *));
! #ifdef HANDLE_SYSV_PRAGMA
! static int handle_sysv_pragma PROTO((int));
  #endif
  #ifdef GATHER_STATISTICS
  #ifdef REDUCE_LENGTH
--- 79,86 ----
  static void reinit_parse_for_expr PROTO((struct obstack *));
  static int *init_cpp_parse PROTO((void));
  static int handle_cp_pragma PROTO((char *));
! #ifdef HANDLE_GENERIC_PRAGMAS
! static int handle_generic_pragma PROTO((int));
  #endif
  #ifdef GATHER_STATISTICS
  #ifdef REDUCE_LENGTH
*************** check_newline ()
*** 2309,2315 ****
  		goto skipline;
  
  #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.  */
--- 2309,2315 ----
  		goto skipline;
  
  #ifdef HANDLE_PRAGMA
! 	      /* 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
  		 SYSV style pragmas.  */
*************** check_newline ()
*** 2318,2327 ****
  		goto skipline;
  #endif /* HANDLE_PRAGMA */
  	      
! #ifdef HANDLE_SYSV_PRAGMA
! 	      if (handle_sysv_pragma (token))
  		goto skipline;
! #endif /* !HANDLE_SYSV_PRAGMA */
  
  	      /* Issue a warning message if we have been asked to do so.
  		 Ignoring unknown pragmas in system header file unless
--- 2318,2327 ----
  		goto skipline;
  #endif /* HANDLE_PRAGMA */
  	      
! #ifdef HANDLE_GENERIC_PRAGMAS
! 	      if (handle_generic_pragma (token))
  		goto skipline;
! #endif /* HANDLE_GENERIC_PRAGMAS */
  
  	      /* Issue a warning message if we have been asked to do so.
  		 Ignoring unknown pragmas in system header file unless
*************** handle_cp_pragma (pname)
*** 4934,4950 ****
    return 0;
  }
  
! #ifdef HANDLE_SYSV_PRAGMA
  
! /* Handle a #pragma directive.  INPUT is the current input stream,
!    and C is a character to reread.  Processes the entire input line
!    and returns a character for the caller to reread: either \n or EOF.  */
  
  /* This function has to be in this file, in order to get at
     the token types.  */
  
  static int
! handle_sysv_pragma (token)
       register int token;
  {
    for (;;)
--- 4934,4950 ----
    return 0;
  }
  
! #ifdef HANDLE_GENERIC_PRAGMAS
  
! /* Handle a #pragma directive.  TOKEN is the type of the word following
!    the #pragma directive on the line.  Process the entire input line and
!    return non-zero iff the directive successfully parsed.  */
  
  /* This function has to be in this file, in order to get at
     the token types.  */
  
  static int
! handle_generic_pragma (token)
       register int token;
  {
    for (;;)
*************** handle_sysv_pragma (token)
*** 4977,4983 ****
  	default:
  	  return handle_pragma_token (NULL_PTR, NULL_TREE);
  	}
        token = real_yylex ();
      }
  }
! #endif /* HANDLE_SYSV_PRAGMA */
--- 4977,4984 ----
  	default:
  	  return handle_pragma_token (NULL_PTR, NULL_TREE);
  	}
+       
        token = real_yylex ();
      }
  }
! #endif /* HANDLE_GENERIC_PRAGMAS */



------------------------patches in fortran subdirectory---------------------

Tue Sep 15 10:18:36 1998  Nick Clifton  <nickc@cygnus.com>

	* lex.c: Replace occurances of HANDLE_SYSV_PRAGMA with
	HANDLE_GENERIC_PRAGMAS.

	* Makefile.in: Add ../c-pragma.o to imported objects list.


Index: f/lex.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/f/lex.c,v
retrieving revision 1.7
diff -p -w -r1.7 lex.c
*** lex.c	1998/09/02 10:02:27	1.7
--- lex.c	1998/09/15 16:58:41
*************** ffelex_hash_ (FILE *finput)
*** 1145,1154 ****
  	      if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer))
  		goto skipline;
  #endif /* HANDLE_PRAGMA */
! #ifdef HANDLE_SYSV_PRAGMA
! 	      if (handle_sysv_pragma (buffer))
  		goto skipline;
! #endif /* !HANDLE_SYSV_PRAGMA */
  
  	      /* Issue a warning message if we have been asked to do so.
  		 Ignoring unknown pragmas in system header file unless
--- 1145,1154 ----
  	      if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer))
  		goto skipline;
  #endif /* HANDLE_PRAGMA */
! #ifdef HANDLE_GENERIC_PRAGMAS
! 	      if (handle_generic_pragma (buffer))
  		goto skipline;
! #endif /* !HANDLE_GENERIC_PRAGMAS */
  
  	      /* Issue a warning message if we have been asked to do so.
  		 Ignoring unknown pragmas in system header file unless

Index: f/Makefile.in
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/f/Makefile.in,v
retrieving revision 1.14
diff -p -w -r1.14 Makefile.in
*** Makefile.in	1998/09/05 10:26:32	1.14
--- Makefile.in	1998/09/15 16:58:57
*************** F77_OBJS = \
*** 206,213 ****
   where.o
  
  # Language-independent object files.
! OBJS = `cat ../stamp-objlist`
! OBJDEPS = ../stamp-objlist
  
  compiler: ../f771$(exeext)
  ../f771$(exeext): $(P) $(F77_OBJS) $(OBJDEPS) $(LIBDEPS)
--- 206,213 ----
   where.o
  
  # Language-independent object files.
! OBJS = `cat ../stamp-objlist` ../c-pragma.o
! OBJDEPS = ../stamp-objlist ../c-pragma.o
  
  compiler: ../f771$(exeext)
  ../f771$(exeext): $(P) $(F77_OBJS) $(OBJDEPS) $(LIBDEPS)




------------------------patches in chill subdirectory---------------------

Tue Sep 15 10:18:36 1998  Nick Clifton  <nickc@cygnus.com>

	* lex.c: Replace occurances of HANDLE_SYSV_PRAGMA with
	HANDLE_GENERIC_PRAGMAS.
	(handle_generic_pragma): New function: Parse generic pragmas.

	* Makefile.in: Add ../c-pragma.o to imported objects list.


Index: ch/lex.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/ch/lex.c,v
retrieving revision 1.2
diff -p -w -r1.2 lex.c
*** lex.c	1998/09/02 10:04:26	1.2
--- lex.c	1998/09/15 16:58:15
*************** pragma_ungetc (arg)
*** 1511,1516 ****
--- 1511,1559 ----
  }
  #endif /* HANDLE_PRAGMA */
  
+ #ifdef HANDLE_GENERIC_PRAGMAS
+ /* Handle a generic #pragma directive.
+    BUFFER contains the text we read after `#pragma'.  Processes the entire input
+    line and return non-zero iff the pragma was successfully processed.  */
+ 
+ static int
+ handle_generic_pragma (buffer)
+      char * buffer;
+ {
+   register int c;
+ 
+   for (;;)
+     {
+       char * buff;
+       
+       handle_pragma_token (buffer, NULL);
+ 
+       c = getc (finput);
+ 
+       while (c == ' ' || c == '\t')
+ 	c = getc (finput);
+       ungetc (c, finput);
+       
+       if (c == '\n' || c == EOF)
+ 	return handle_pragma_token (NULL, NULL);
+ 
+       /* Read the next word of the pragma into the buffer.  */
+       buff = buffer;
+       do
+ 	{
+ 	  * buff ++ = c;
+ 	  c = getc (finput);
+ 	}
+       while (c != EOF && isascii (c) && ! isspace (c) && c != '\n'
+ 	     && buff < buffer + 128); /* XXX shared knowledge about size of buffer.  */
+       
+       ungetc (c, finput);
+       
+       * -- buff = 0;
+     }
+ }
+ #endif /* HANDLE_GENERIC_PRAGMAS */
+ 
  /* At the beginning of a line, increment the line number and process
     any #-directive on this line.  If the line is a #-directive, read
     the entire line and return a newline.  Otherwise, return the line's
*************** check_newline ()
*** 1588,1595 ****
  		
  	      * -- buff = 0;
  	      
! 	      (void) HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer);
  #endif /* HANDLE_PRAGMA */
  	      goto skipline;
  	    }
  	}
--- 1631,1645 ----
  		
  	      * -- buff = 0;
  	      
! 	      if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer))
! 		goto skipline;
  #endif /* HANDLE_PRAGMA */
+ 	      
+ #ifdef HANDLE_GENERIC_PRAGMAS
+ 	      if (handle_generic_pragma (buffer))
+ 		goto skipline;
+ #endif /* HANDLE_GENERIC_PRAGMAS */
+ 	      
  	      goto skipline;
  	    }
  	}


Index: ch/Makefile.in
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/ch/Makefile.in,v
retrieving revision 1.4
diff -p -w -r1.4 Makefile.in
*** Makefile.in	1998/09/05 22:51:21	1.4
--- Makefile.in	1998/09/15 16:58:01
*************** CHILL_OBJS = parse.o actions.o except.o 
*** 199,206 ****
     tasking.o timing.o inout.o satisfy.o ch-version.o
  
  # Language-independent object files.
! OBJS = `cat ../stamp-objlist`
! OBJDEPS = ../stamp-objlist
  
  ../cc1chill: $(P) $(CHILL_OBJS) $(OBJDEPS) $(LIBDEPS)
  	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(CHILL_OBJS) \
--- 199,206 ----
     tasking.o timing.o inout.o satisfy.o ch-version.o
  
  # Language-independent object files.
! OBJS = `cat ../stamp-objlist` ../c-pragma.o
! OBJDEPS = ../stamp-objlist ../c-pragma.o
  
  ../cc1chill: $(P) $(CHILL_OBJS) $(OBJDEPS) $(LIBDEPS)
  	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(CHILL_OBJS) \


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]