]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c-pragma.c (push_alignment): Don't ignore alignments greater than 4 bytes.
authorJason Merrill <jason@yorick.cygnus.com>
Mon, 26 Apr 1999 21:18:08 +0000 (21:18 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 26 Apr 1999 21:18:08 +0000 (17:18 -0400)
* c-pragma.c (push_alignment): Don't ignore alignments greater than
4 bytes.
(handle_pragma_token): Likewise.
* c-pragma.c: Support for #pragma pack (push, <id>, <n>).
(struct align_stack): Add id field.
(push_alignment, pop_alignment): Take id parameter.
(handle_pragma_token): Add necessary states.
* c-pragma.h (enum pragma_state): Add necessary states.

From-SVN: r26662

gcc/ChangeLog
gcc/c-pragma.c
gcc/c-pragma.h

index ccb0196c2d8c122ca949044b8da77507233adaa8..ae7d4d0650b08902faa88e741819ad395056f250 100644 (file)
@@ -1,3 +1,15 @@
+Mon Apr 26 21:17:41 1999  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * c-pragma.c (push_alignment): Don't ignore alignments greater than
+       4 bytes.
+       (handle_pragma_token): Likewise.
+
+       * c-pragma.c: Support for #pragma pack (push, <id>, <n>).
+       (struct align_stack): Add id field.
+       (push_alignment, pop_alignment): Take id parameter.
+       (handle_pragma_token): Add necessary states.
+       * c-pragma.h (enum pragma_state): Add necessary states.
+
 Tue Apr 27 13:58:23 1999  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
 
        * config/c4x/c4x.md (*cmpqf, *cmpqf_noov, *cmpqi_test, 
index 09fac1feaabd0e4b9cb8a8fa755724bc1cc73f4f..eedd0a13f0d6c28e4aef1a8d692f12ba75b15d85 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
-   Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1997, 1998, 1999 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -45,18 +45,20 @@ typedef struct align_stack
 {
   int                  alignment;
   unsigned int         num_pushes;
+  tree                 id;
   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));
+static int  push_alignment PROTO((int, tree));
+static int  pop_alignment  PROTO((tree));
 
 /* Push an alignment value onto the stack.  */
 static int
-push_alignment (alignment)
+push_alignment (alignment, id)
      int alignment;
+     tree id;
 {
   switch (alignment)
     {
@@ -75,7 +77,8 @@ Alignment must be a small power of two, not %d, in #pragma pack",
     }
   
   if (alignment_stack == NULL
-      || alignment_stack->alignment != alignment)
+      || alignment_stack->alignment != alignment
+      || id != NULL_TREE)
     {
       align_stack * entry;
 
@@ -89,15 +92,12 @@ Alignment must be a small power of two, not %d, in #pragma pack",
 
       entry->alignment  = alignment;
       entry->num_pushes = 1;
+      entry->id         = id;
       entry->prev       = alignment_stack;
       
       alignment_stack = entry;
 
-      if (alignment < 8)
-       maximum_field_alignment = alignment * 8;
-      else
-       /* MSVC ignores alignments > 4.  */
-       maximum_field_alignment = 0;
+      maximum_field_alignment = alignment * 8;
     }
   else
     alignment_stack->num_pushes ++;
@@ -107,19 +107,38 @@ Alignment must be a small power of two, not %d, in #pragma pack",
 
 /* Undo a push of an alignment onto the stack.  */
 static int
-pop_alignment ()
+pop_alignment (id)
+     tree id;
 {
+  align_stack * entry;
+      
   if (alignment_stack == NULL)
     {
       warning ("\
-#pragma pack(pop) encountered without corresponding #pragma pack(push,<n>)");
+#pragma pack (pop) encountered without matching #pragma pack (push, <n>)"
+              );
       return 0;
     }
 
+  /* If we got an identifier, strip away everything above the target
+     entry so that the next step will restore the state just below it.  */
+  if (id)
+    {
+      for (entry = alignment_stack; entry; entry = entry->prev)
+       if (entry->id == id)
+         {
+           entry->num_pushes = 1;
+           alignment_stack = entry;
+           break;
+         }
+      if (entry == NULL)
+       warning ("\
+#pragma pack(pop, %s) encountered without matching #pragma pack(push, %s, <n>)"
+                , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
+    }
+
   if (-- alignment_stack->num_pushes == 0)
     {
-      align_stack * entry;
-      
       entry = alignment_stack->prev;
 
       if (entry == NULL || entry->alignment > 4)
@@ -215,6 +234,7 @@ handle_pragma_token (string, token)
   static char * name;
   static char * value;
   static int align;
+  static tree id;
 
   /* If we have reached the end of the #pragma directive then
      determine what value we should return.  */
@@ -248,16 +268,16 @@ handle_pragma_token (string, token)
 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
        case ps_push:
          if (state == ps_right)
-           ret_val = push_alignment (align);
+           ret_val = push_alignment (align, id);
          else
-           warning ("incomplete '#pragma pack(push,<n>)'");
+           warning ("malformed '#pragma pack(push[,id],<n>)'");
          break;
          
        case ps_pop:
          if (state == ps_right)
-           ret_val = pop_alignment ();
+           ret_val = pop_alignment (id);
          else
-           warning ("missing closing parenthesis in '#pragma pack(pop)'");
+           warning ("malformed '#pragma pack(pop[,id])'");
          break;
 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
          
@@ -279,6 +299,7 @@ handle_pragma_token (string, token)
        }
 
       type = state = ps_start;
+      id = NULL_TREE;
       
       return ret_val;
     }
@@ -361,40 +382,45 @@ handle_pragma_token (string, token)
 
     case ps_left:
 
-      if (token && TREE_CODE(token) == INTEGER_CST) 
-       align = TREE_INT_CST_LOW(token);
+      if (token == NULL_TREE)
+       state = (strcmp (string, ")") ? ps_bad : ps_right);
+
+      else if (TREE_CODE (token) == INTEGER_CST)
+       goto handle_align;
+
+#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
+      else if (TREE_CODE (token) == IDENTIFIER_NODE)
+       {
+         if (strcmp (string, "push") == 0)
+           type = state = ps_push;
+         else if (strcmp (string, "pop") == 0)
+           type = state = ps_pop;
+         else
+           state = ps_bad;
+       }
+#endif
       else
-       align = atoi (string);
+       state = ps_bad;
+      break;
+
+    handle_align:
+      align = TREE_INT_CST_LOW (token);
       switch (align)
        {
        case 1:
        case 2:
        case 4:
+       case 8:
+       case 16:
          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;
@@ -406,12 +432,44 @@ handle_pragma_token (string, token)
 
 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
     case ps_push:
-      state = (strcmp (string, ",") ? ps_bad : ps_comma);
+      state = (strcmp (string, ",") ? ps_bad : ps_pushcomma);
       break;
 
-    case ps_comma:
-      align = atoi (string);
-      state = ps_align;
+    case ps_pushid:
+      state = (strcmp (string, ",") ? ps_bad : ps_pushcomma2);
+      break;
+
+    case ps_pushcomma:
+      if (token && TREE_CODE (token) == IDENTIFIER_NODE)
+       {
+         id = token;
+         state = ps_pushid;
+         break;
+       }
+
+      /* else fall through */
+    case ps_pushcomma2:
+      if (token && TREE_CODE (token) == INTEGER_CST)
+       goto handle_align;
+      else
+       state = ps_bad;
+      break;
+
+    case ps_pop:
+      if (strcmp (string, ",") == 0)
+       state = ps_popcomma;
+      else
+       state = (strcmp (string, ")") ? ps_bad : ps_right);
+      break;
+
+    case ps_popcomma:
+      if (token && TREE_CODE (token) == IDENTIFIER_NODE)
+       {
+         id = token;
+         state = ps_align;
+       }
+      else
+       state = ps_bad;
       break;
 #endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
       
index ddc74d1076e201516813bb23f8fcc74c3edca733..f94ee9fe6c500555aa165306357de6c64b11b1c1 100644 (file)
@@ -1,5 +1,5 @@
 /* Pragma related interfaces.
-   Copyright (C) 1995, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1998, 1999 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -88,9 +88,8 @@ enum pragma_state
   ps_right,
 #endif
 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
-  ps_push,
-  ps_pop,
-  ps_comma,
+  ps_push, ps_pushcomma, ps_pushid, ps_pushcomma2,
+  ps_pop, ps_popcomma,
 #endif
   ps_bad
 };