OSDN Git Service

* gcj.texi (Linking): New node. Document -lgij usage.
[pf3gnuchains/gcc-fork.git] / gcc / stor-layout.c
index d19fc9f..cf97159 100644 (file)
@@ -66,20 +66,12 @@ static void place_union_field (record_layout_info, tree);
 static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT,
                             HOST_WIDE_INT, tree);
 #endif
-static void force_type_save_exprs_1 (tree);
-static unsigned int update_alignment_for_field (record_layout_info, tree,
-                                               unsigned int);
 extern void debug_rli (record_layout_info);
 \f
 /* SAVE_EXPRs for sizes of types and decls, waiting to be expanded.  */
 
 static GTY(()) tree pending_sizes;
 
-/* Nonzero means cannot safely call expand_expr now,
-   so put variable sizes onto `pending_sizes' instead.  */
-
-int immediate_size_expand;
-
 /* Show that REFERENCE_TYPES are internal and should be Pmode.  Called only
    by front end.  */
 
@@ -95,11 +87,6 @@ tree
 get_pending_sizes (void)
 {
   tree chain = pending_sizes;
-  tree t;
-
-  /* Put each SAVE_EXPR into the current function.  */
-  for (t = chain; t; t = TREE_CHAIN (t))
-    SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = current_function_decl;
 
   pending_sizes = 0;
   return chain;
@@ -158,8 +145,11 @@ variable_size (tree size)
      not wish to do that here; the array-size is the same in both
      places.  */
   save = skip_simple_arithmetic (size);
-  if (TREE_CODE (save) == SAVE_EXPR)
-    SAVE_EXPR_PERSISTENT_P (save) = 1;
+
+  if (cfun && cfun->x_dont_save_pending_sizes_p)
+    /* The front-end doesn't want us to keep a list of the expressions
+       that determine sizes for variable size objects.  Trust it.  */
+    return size;
 
   if (lang_hooks.decls.global_bindings_p ())
     {
@@ -171,71 +161,10 @@ variable_size (tree size)
       return size_one_node;
     }
 
-  if (immediate_size_expand)
-    expand_expr (save, const0_rtx, VOIDmode, 0);
-  else if (cfun != 0 && cfun->x_dont_save_pending_sizes_p)
-    /* The front-end doesn't want us to keep a list of the expressions
-       that determine sizes for variable size objects.  */
-    ;
-  else
-    put_pending_size (save);
+  put_pending_size (save);
 
   return size;
 }
-
-/* Given a type T, force elaboration of any SAVE_EXPRs used in the definition
-   of that type.  */
-
-void
-force_type_save_exprs (tree t)
-{
-  tree field;
-
-  switch (TREE_CODE (t))
-    {
-    case ERROR_MARK:
-      return;
-
-    case ARRAY_TYPE:
-    case SET_TYPE:
-    case VECTOR_TYPE:
-      /* It's probably overly-conservative to force elaboration of bounds and
-        also the sizes, but it's better to be safe than sorry.  */
-      force_type_save_exprs_1 (TYPE_MIN_VALUE (TYPE_DOMAIN (t)));
-      force_type_save_exprs_1 (TYPE_MAX_VALUE (TYPE_DOMAIN (t)));
-      break;
-
-    case RECORD_TYPE:
-    case UNION_TYPE:
-    case QUAL_UNION_TYPE:
-      for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
-       if (TREE_CODE (field) == FIELD_DECL)
-         {
-           force_type_save_exprs (TREE_TYPE (field));
-           force_type_save_exprs_1 (DECL_FIELD_OFFSET (field));
-         }
-      break;
-
-    default:
-      break;
-    }
-
-  force_type_save_exprs_1 (TYPE_SIZE (t));
-  force_type_save_exprs_1 (TYPE_SIZE_UNIT (t));
-}
-
-/* Utility routine of above, to verify that SIZE has been elaborated and
-   do so it it is a SAVE_EXPR and has not been.  */
-
-static void
-force_type_save_exprs_1 (tree size)
-{
-  if (size
-      && (size = skip_simple_arithmetic (size))
-      && TREE_CODE (size) == SAVE_EXPR
-      && !SAVE_EXPR_RTL (size))
-    expand_expr (size, NULL_RTX, VOIDmode, 0);
-}
 \f
 #ifndef MAX_FIXED_MODE_SIZE
 #define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode)
@@ -512,10 +441,7 @@ layout_decl (tree decl, unsigned int known_align)
              || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
        DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
 
-      /* Should this be controlled by DECL_USER_ALIGN, too?  */
-      if (maximum_field_alignment != 0)
-       DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
-      if (! DECL_USER_ALIGN (decl))
+      if (! DECL_USER_ALIGN (decl) && ! DECL_PACKED (decl))
        {
          /* Some targets (i.e. i386, VMS) limit struct field alignment
             to a lower boundary than alignment of variables unless
@@ -528,6 +454,10 @@ layout_decl (tree decl, unsigned int known_align)
          DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl));
 #endif
        }
+
+      /* Should this be controlled by DECL_USER_ALIGN, too?  */
+      if (maximum_field_alignment != 0)
+       DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
     }
 
   /* Evaluate nonconstant size only once, either now or as soon as safe.  */
@@ -721,7 +651,7 @@ rli_size_so_far (record_layout_info rli)
    variable alignment fields in RLI, and return the alignment to give
    the FIELD.  */
 
-static unsigned int
+unsigned int
 update_alignment_for_field (record_layout_info rli, tree field,
                            unsigned int known_align)
 {
@@ -771,8 +701,10 @@ update_alignment_for_field (record_layout_info rli, tree field,
   else if (is_bitfield && PCC_BITFIELD_TYPE_MATTERS)
     {
       /* Named bit-fields cause the entire structure to have the
-        alignment implied by their type.  */
-      if (DECL_NAME (field) != 0)
+        alignment implied by their type.  Some targets also apply the same
+        rules to unnamed bitfields.  */
+      if (DECL_NAME (field) != 0
+         || targetm.align_anon_bitfield ())
        {
          unsigned int type_align = TYPE_ALIGN (type);
 
@@ -1125,7 +1057,6 @@ place_field (record_layout_info rli, tree field)
                rli->prev_field = NULL;
            }
 
-         rli->offset_align = tree_low_cst (TYPE_SIZE (type), 0);
          normalize_rli (rli);
         }
 
@@ -1558,6 +1489,9 @@ layout_type (tree type)
   if (type == 0)
     abort ();
 
+  if (type == error_mark_node)
+    return;
+
   /* Do nothing if type has been laid out before.  */
   if (TYPE_SIZE (type))
     return;
@@ -2155,26 +2089,32 @@ get_best_mode (int bitsize, int bitpos, unsigned int align,
 }
 
 /* Gets minimal and maximal values for MODE (signed or unsigned depending on
-   SIGN).  */
+   SIGN).  The returned constants are made to be usable in TARGET_MODE.  */
 
 void
-get_mode_bounds (enum machine_mode mode, int sign, rtx *mmin, rtx *mmax)
+get_mode_bounds (enum machine_mode mode, int sign,
+                enum machine_mode target_mode,
+                rtx *mmin, rtx *mmax)
 {
-  int size = GET_MODE_BITSIZE (mode);
+  unsigned size = GET_MODE_BITSIZE (mode);
+  unsigned HOST_WIDE_INT min_val, max_val;
 
   if (size > HOST_BITS_PER_WIDE_INT)
     abort ();
 
   if (sign)
     {
-      *mmin = GEN_INT (-((unsigned HOST_WIDE_INT) 1 << (size - 1)));
-      *mmax = GEN_INT (((unsigned HOST_WIDE_INT) 1 << (size - 1)) - 1);
+      min_val = -((unsigned HOST_WIDE_INT) 1 << (size - 1));
+      max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1)) - 1;
     }
   else
     {
-      *mmin = const0_rtx;
-      *mmax = GEN_INT (((unsigned HOST_WIDE_INT) 1 << (size - 1) << 1) - 1);
+      min_val = 0;
+      max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1) << 1) - 1;
     }
+
+  *mmin = GEN_INT (trunc_int_for_mode (min_val, target_mode));
+  *mmax = GEN_INT (trunc_int_for_mode (max_val, target_mode));
 }
 
 #include "gt-stor-layout.h"