OSDN Git Service

x
[pf3gnuchains/gcc-fork.git] / gcc / stor-layout.c
index 0a152d7..e55961a 100644 (file)
@@ -1,5 +1,5 @@
 /* C-compiler utilities for types and variables storage layout
-   Copyright (C) 1987, 88, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 92-96, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include "tree.h"
 #include "flags.h"
+#include "except.h"
 #include "function.h"
 
 #define CEIL(x,y) (((x) + (y) - 1) / (y))
@@ -50,10 +51,6 @@ int maximum_field_alignment;
    May be overridden by front-ends.  */
 int set_alignment = 0;
 
-#define GET_MODE_ALIGNMENT(MODE)   \
-  MIN (BIGGEST_ALIGNMENT,         \
-       MAX (1, (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT)))
-
 static enum machine_mode smallest_mode_for_size  PROTO((unsigned int,
                                                        enum mode_class));
 static tree layout_record      PROTO((tree));
@@ -283,7 +280,8 @@ layout_decl (decl, known_align)
       && known_align % TYPE_ALIGN (type) == 0
       && DECL_SIZE (decl) != 0
       && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
-         || (TREE_INT_CST_LOW (DECL_SIZE (decl)) % BITS_PER_UNIT) == 0))
+         || (TREE_INT_CST_LOW (DECL_SIZE (decl)) % BITS_PER_UNIT) == 0)
+      && DECL_ALIGN (decl) >= TYPE_ALIGN (type))
     DECL_BIT_FIELD (decl) = 0;
 
   /* Evaluate nonconstant size only once, either now or as soon as safe.  */
@@ -320,7 +318,7 @@ layout_record (rec)
      and VAR_SIZE is a tree expression.
      If VAR_SIZE is null, the size is just CONST_SIZE.
      Naturally we try to avoid using VAR_SIZE.  */
 register int const_size = 0;
register HOST_WIDE_INT const_size = 0;
   register tree var_size = 0;
   /* Once we start using VAR_SIZE, this is the maximum alignment
      that we know VAR_SIZE has.  */
@@ -338,7 +336,7 @@ layout_record (rec)
         In both cases, all we do is lay out the decl,
         and we do it *after* the record is laid out.  */
 
-      if (TREE_STATIC (field))
+      if (TREE_CODE (field) == VAR_DECL)
        {
          pending_statics = tree_cons (NULL_TREE, field, pending_statics);
          continue;
@@ -440,14 +438,10 @@ layout_record (rec)
          register tree dsize = DECL_SIZE (field);
          int field_size = TREE_INT_CST_LOW (dsize);
 
-         /* A bit field may not span the unit of alignment of its type.
-            Advance to next boundary if necessary.  */
-         /* ??? There is some uncertainty here as to what
-            should be done if type_align is less than the width of the type.
-            That can happen because the width exceeds BIGGEST_ALIGNMENT
-            or because it exceeds maximum_field_alignment.  */
-         if (const_size / type_align
-             != (const_size + (field_size % type_align) - 1) / type_align)
+         /* A bit field may not span more units of alignment of its type
+            than its type itself.  Advance to next boundary if necessary.  */
+         if (((const_size + field_size) / type_align - const_size / type_align)
+             > TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (field))) / type_align)
            const_size = CEIL (const_size, type_align) * type_align;
        }
 #endif
@@ -509,8 +503,9 @@ layout_record (rec)
        if (dsize == 0)
          /* Do nothing.  */;
        else if (TREE_CODE (dsize) == INTEGER_CST
+                && ! TREE_CONSTANT_OVERFLOW (dsize)
                 && TREE_INT_CST_HIGH (dsize) == 0
-                && TREE_INT_CST_LOW (dsize) + const_size > const_size)
+                && TREE_INT_CST_LOW (dsize) + const_size >= const_size)
          /* Use const_size if there's no overflow.  */
          const_size += TREE_INT_CST_LOW (dsize);
        else
@@ -934,7 +929,7 @@ layout_type (type)
       break;
 
     /* Pascal and Chill types */
-    case BOOLEAN_TYPE:          /* store one byte/boolean for now. */
+    case BOOLEAN_TYPE:          /* store one byte/boolean for now.  */
       TYPE_MODE (type) = QImode;
       TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
       TYPE_PRECISION (type) = 1;