Add prototypes for layout_record and layout_union.
authorRichard Kenner <kenner@gcc.gnu.org>
Mon, 28 Jun 1993 01:14:04 +0000 (21:14 -0400)
committerRichard Kenner <kenner@gcc.gnu.org>
Mon, 28 Jun 1993 01:14:04 +0000 (21:14 -0400)
(smallest_mode_for_size): New function.
(variable_size): Allow variable sizes if global_bindings_p returns a negative
value.
(mode_for_size): Fix incorrect comment.
(layout_decl): If DECL has a size already, don't copy from type.
(layout_type, case INTEGER_TYPE, ENUMERAL_TYPE): Use smallest integer mode
that fits, whether or not it fits exactly.

From-SVN: r4776

gcc/stor-layout.c

index c0efe3dab89920781c702561bb8e327ad11c024f..620c0bb2b91a653edd20ae5f3bca3c8582010840 100644 (file)
@@ -1,5 +1,5 @@
 /* C-compiler utilities for types and variables storage layout
-   Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1992, 1993 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -47,6 +47,11 @@ int maximum_field_alignment;
 #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));
+static void layout_union       PROTO((tree));
 \f
 /* SAVE_EXPRs for sizes of types and decls, waiting to be expanded.  */
 
@@ -79,7 +84,13 @@ variable_size (size)
 {
   size = save_expr (size);
 
-  if (global_bindings_p ())
+  /* If the language-processor is to take responsibility for variable-sized
+     items (e.g., languages which have elaboration procedures like Ada),
+     just return SIZE unchanged.  */
+  if (global_bindings_p () < 0)
+    return size;
+
+  else if (global_bindings_p ())
     {
       if (TREE_CONSTANT (size))
        error ("type size can't be explicitly evaluated");
@@ -120,7 +131,7 @@ mode_for_size (size, class, limit)
   if (limit && size > MAX_FIXED_MODE_SIZE)
     return BLKmode;
 
-  /* Get the last mode which has this size, in the specified class.  */
+  /* Get the first mode which has this size, in the specified class.  */
   for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
        mode = GET_MODE_WIDER_MODE (mode))
     if (GET_MODE_BITSIZE (mode) == size)
@@ -129,6 +140,26 @@ mode_for_size (size, class, limit)
   return BLKmode;
 }
 
+/* Similar, but never return BLKmode; return the narrowest mode that
+   contains at least the requested number of bits.  */
+
+static enum machine_mode
+smallest_mode_for_size (size, class)
+     unsigned int size;
+     enum mode_class class;
+{
+  register enum machine_mode mode;
+
+  /* Get the first mode which has at least this size, in the
+     specified class.  */
+  for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
+       mode = GET_MODE_WIDER_MODE (mode))
+    if (GET_MODE_BITSIZE (mode) >= size)
+      return mode;
+
+  abort ();
+}
+
 /* Return the value of VALUE, rounded up to a multiple of DIVISOR.  */
 
 tree
@@ -179,8 +210,9 @@ layout_decl (decl, known_align)
   /* Usually the size and mode come from the data type without change.  */
 
   DECL_MODE (decl) = TYPE_MODE (type);
-  DECL_SIZE (decl) = TYPE_SIZE (type);
   TREE_UNSIGNED (decl) = TREE_UNSIGNED (type);
+  if (DECL_SIZE (decl) == 0)
+    DECL_SIZE (decl) = TYPE_SIZE (type);
 
   if (code == FIELD_DECL && DECL_BIT_FIELD (decl))
     {
@@ -669,11 +701,8 @@ layout_type (type)
       if (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) >= 0)
        TREE_UNSIGNED (type) = 1;
 
-      /* We pass 0 for the last arg of mode_for_size because otherwise
-        on the Apollo using long long causes a crash.
-        It seems better to use integer modes than to try to support
-        integer types with BLKmode.  */
-      TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_INT, 0);
+      TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type),
+                                                MODE_INT);
       TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
       break;