Add support for #pragma pack(push,<n>) and #pragma pack(pop).
authorNick Clifton <nickc@cygnus.com>
Thu, 1 Oct 1998 10:50:15 +0000 (10:50 +0000)
committerNick Clifton <nickc@gcc.gnu.org>
Thu, 1 Oct 1998 10:50:15 +0000 (10:50 +0000)
From-SVN: r22710

gcc/ChangeLog
gcc/c-common.c
gcc/c-lex.c
gcc/c-pragma.c
gcc/c-pragma.h
gcc/config/i386/i386.h
gcc/config/winnt/win-nt.h
gcc/tm.texi
gcc/varasm.c

index ebd5b50a3726808a0a7f5c8322bb3ef0d3f77dc2..ce607e1509e462d9929b06c9a3e6981c7923b238 100644 (file)
@@ -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>
 
index 4d2e7a090a8b0b42098990360e0f84e2159362a6..5fcf1bc9a50734b0207b59c2e586b26396035698 100644 (file)
@@ -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
index e361f5bbe09ba2ff94bb79cb3f24a7b4c825387c..af627cd5315904bc385d82442cccfb7ae9b35a34 100644 (file)
@@ -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;
 }
 \f
-#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 */
 \f
 #define ENDFILE -1  /* token that represents end-of-file */
 
index cb215700c6c2263c93602d06b01880a91dde95a5..90edeb744a116593532bd0ffd0037f9f3d900d12 100644 (file)
@@ -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
+
+
+#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 */
+\f
+#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
-   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.  */
+  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 */
+\f
+/* 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 */
index 5478977608e1a0fe2a97761d91285009e478d9b3..d7a383df4a49cd703d1d8582fb1695f7f03a8dff 100644 (file)
@@ -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 */
index 0bb72415367bf0b03a30539575021df6e6ac3e09..12f5503322f74c67a7c1d4938900a38a3e487b82 100644 (file)
@@ -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
+
 \f
 /* Functions in i386.c */
 extern void override_options ();
index 4b93f8c118d9c48f8eff74568af5bc5f4fbc7391..f123b0497fc9d19ab218442b3550073323f90cf4 100644 (file)
@@ -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
index 0378bc8f233c08492fd846bf6ea70cf20413068a..d0dee150668b8b0f781ba4b1c639e168a157e3e7 100644 (file)
@@ -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
index d3e12b9cb86b1cd9b9ba12a06ab49fd9ac2faed2..d9e526132815e8b844609c7bb32b11678beb4ece 100644 (file)
@@ -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 ()
 {