OSDN Git Service

* lto-cgraph.c (lto_output_varpool_node): Always output constant pool
[pf3gnuchains/gcc-fork.git] / gcc / stor-layout.c
index 47ce848..151092c 100644 (file)
@@ -1,6 +1,6 @@
 /* C-compiler utilities for types and variables storage layout
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1996, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -52,9 +52,9 @@ unsigned int maximum_field_alignment = TARGET_DEFAULT_PACK_STRUCT * BITS_PER_UNI
 /* ... and its original value in bytes, specified via -fpack-struct=<value>.  */
 unsigned int initial_max_fld_align = TARGET_DEFAULT_PACK_STRUCT;
 
-/* Nonzero if all REFERENCE_TYPEs are internal and hence should be
-   allocated in Pmode, not ptr_mode.   Set only by internal_reference_types
-   called only by a front end.  */
+/* Nonzero if all REFERENCE_TYPEs are internal and hence should be allocated
+   in the address spaces' address_mode, not pointer_mode.   Set only by
+   internal_reference_types called only by a front end.  */
 static int reference_types_internal = 0;
 
 static tree self_referential_size (tree);
@@ -71,8 +71,8 @@ extern void debug_rli (record_layout_info);
 
 static GTY(()) tree pending_sizes;
 
-/* Show that REFERENCE_TYPES are internal and should be Pmode.  Called only
-   by front end.  */
+/* Show that REFERENCE_TYPES are internal and should use address_mode.
+   Called only by front end.  */
 
 void
 internal_reference_types (void)
@@ -1100,7 +1100,8 @@ place_field (record_layout_info rli, tree field)
              if (STRICT_ALIGNMENT)
                warning (OPT_Wattributes, "packed attribute causes "
                          "inefficient alignment for %q+D", field);
-             else
+             /* Don't warn if DECL_PACKED was set by the type.  */
+             else if (!TYPE_PACKED (rli->t))
                warning (OPT_Wattributes, "packed attribute is "
                         "unnecessary for %q+D", field);
            }
@@ -1118,7 +1119,8 @@ place_field (record_layout_info rli, tree field)
       /* No, we need to skip space before this field.
         Bump the cumulative size to multiple of field alignment.  */
 
-      warning (OPT_Wpadded, "padding struct to align %q+D", field);
+      if (DECL_SOURCE_LOCATION (field) != BUILTINS_LOCATION)
+       warning (OPT_Wpadded, "padding struct to align %q+D", field);
 
       /* If the alignment is still within offset_align, just align
         the bit position.  */
@@ -1344,11 +1346,12 @@ place_field (record_layout_info rli, tree field)
             until we see a bitfield (and come by here again) we just skip
             calculating it.  */
          if (DECL_SIZE (field) != NULL
-             && host_integerp (TYPE_SIZE (TREE_TYPE (field)), 0)
-             && host_integerp (DECL_SIZE (field), 0))
+             && host_integerp (TYPE_SIZE (TREE_TYPE (field)), 1)
+             && host_integerp (DECL_SIZE (field), 1))
            {
-             HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 1);
-             HOST_WIDE_INT typesize
+             unsigned HOST_WIDE_INT bitsize
+               = tree_low_cst (DECL_SIZE (field), 1);
+             unsigned HOST_WIDE_INT typesize
                = tree_low_cst (TYPE_SIZE (TREE_TYPE (field)), 1);
 
              if (typesize < bitsize)
@@ -1483,7 +1486,8 @@ finalize_record_size (record_layout_info rli)
     = round_up_loc (input_location, unpadded_size_unit, TYPE_ALIGN_UNIT (rli->t));
 
   if (TREE_CONSTANT (unpadded_size)
-      && simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0)
+      && simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0
+      && input_location != BUILTINS_LOCATION)
     warning (OPT_Wpadded, "padding struct size to alignment boundary");
 
   if (warn_packed && TREE_CODE (rli->t) == RECORD_TYPE
@@ -1502,8 +1506,6 @@ finalize_record_size (record_layout_info rli)
       unpacked_size = round_up_loc (input_location, TYPE_SIZE (rli->t), rli->unpacked_align);
       if (simple_cst_equal (unpacked_size, TYPE_SIZE (rli->t)))
        {
-         TYPE_PACKED (rli->t) = 0;
-
          if (TYPE_NAME (rli->t))
            {
              tree name;
@@ -1915,6 +1917,7 @@ layout_type (tree type)
       /* A pointer might be MODE_PARTIAL_INT,
         but ptrdiff_t must be integral.  */
       SET_TYPE_MODE (type, mode_for_size (POINTER_SIZE, MODE_INT, 0));
+      TYPE_PRECISION (type) = POINTER_SIZE;
       break;
 
     case FUNCTION_TYPE:
@@ -1930,16 +1933,17 @@ layout_type (tree type)
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       {
-       enum machine_mode mode = ((TREE_CODE (type) == REFERENCE_TYPE
-                                  && reference_types_internal)
-                                 ? Pmode : TYPE_MODE (type));
-
-       int nbits = GET_MODE_BITSIZE (mode);
+       enum machine_mode mode = TYPE_MODE (type);
+       if (TREE_CODE (type) == REFERENCE_TYPE && reference_types_internal)
+         {
+           addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
+           mode = targetm.addr_space.address_mode (as);
+         }
 
-       TYPE_SIZE (type) = bitsize_int (nbits);
+       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
        TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
        TYPE_UNSIGNED (type) = 1;
-       TYPE_PRECISION (type) = nbits;
+       TYPE_PRECISION (type) = GET_MODE_BITSIZE (mode);
       }
       break;
 
@@ -1956,57 +1960,34 @@ layout_type (tree type)
          {
            tree ub = TYPE_MAX_VALUE (index);
            tree lb = TYPE_MIN_VALUE (index);
+           tree element_size = TYPE_SIZE (element);
            tree length;
-           tree element_size;
+
+           /* Make sure that an array of zero-sized element is zero-sized
+              regardless of its extent.  */
+           if (integer_zerop (element_size))
+             length = size_zero_node;
 
            /* The initial subtraction should happen in the original type so
               that (possible) negative values are handled appropriately.  */
-           length = size_binop (PLUS_EXPR, size_one_node,
-                                fold_convert (sizetype,
-                                              fold_build2_loc (input_location,
-                                                           MINUS_EXPR,
-                                                           TREE_TYPE (lb),
-                                                           ub, lb)));
-
-           /* Special handling for arrays of bits (for Chill).  */
-           element_size = TYPE_SIZE (element);
-           if (TYPE_PACKED (type) && INTEGRAL_TYPE_P (element)
-               && (integer_zerop (TYPE_MAX_VALUE (element))
-                   || integer_onep (TYPE_MAX_VALUE (element)))
-               && host_integerp (TYPE_MIN_VALUE (element), 1))
-             {
-               HOST_WIDE_INT maxvalue
-                 = tree_low_cst (TYPE_MAX_VALUE (element), 1);
-               HOST_WIDE_INT minvalue
-                 = tree_low_cst (TYPE_MIN_VALUE (element), 1);
-
-               if (maxvalue - minvalue == 1
-                   && (maxvalue == 1 || maxvalue == 0))
-                 element_size = integer_one_node;
-             }
-
-           /* If neither bound is a constant and sizetype is signed, make
-              sure the size is never negative.  We should really do this
-              if *either* bound is non-constant, but this is the best
-              compromise between C and Ada.  */
-           if (!TYPE_UNSIGNED (sizetype)
-               && TREE_CODE (TYPE_MIN_VALUE (index)) != INTEGER_CST
-               && TREE_CODE (TYPE_MAX_VALUE (index)) != INTEGER_CST)
-             length = size_binop (MAX_EXPR, length, size_zero_node);
+           else
+             length
+               = size_binop (PLUS_EXPR, size_one_node,
+                             fold_convert (sizetype,
+                                           fold_build2_loc (input_location,
+                                                            MINUS_EXPR,
+                                                            TREE_TYPE (lb),
+                                                            ub, lb)));
 
            TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
                                           fold_convert (bitsizetype,
                                                         length));
 
-           /* If we know the size of the element, calculate the total
-              size directly, rather than do some division thing below.
-              This optimization helps Fortran assumed-size arrays
-              (where the size of the array is determined at runtime)
-              substantially.
-              Note that we can't do this in the case where the size of
-              the elements is one bit since TYPE_SIZE_UNIT cannot be
-              set correctly in that case.  */
-           if (TYPE_SIZE_UNIT (element) != 0 && ! integer_onep (element_size))
+           /* If we know the size of the element, calculate the total size
+              directly, rather than do some division thing below.  This
+              optimization helps Fortran assumed-size arrays (where the
+              size of the array is determined at runtime) substantially.  */
+           if (TYPE_SIZE_UNIT (element))
              TYPE_SIZE_UNIT (type)
                = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (element), length);
          }
@@ -2117,7 +2098,7 @@ layout_type (tree type)
    change the result of vector_mode_supported_p and have_regs_of_mode
    on a per-function basis.  Thus the TYPE_MODE of a VECTOR_TYPE can
    change on a per-function basis.  */
-/* ??? Possibly a better solution is to run through all the types 
+/* ??? Possibly a better solution is to run through all the types
    referenced by a function and re-compute the TYPE_MODE once, rather
    than make the TYPE_MODE macro call a function.  */
 
@@ -2233,37 +2214,35 @@ make_accum_type (int precision, int unsignedp, int satp)
    value to enable integer types to be created.  */
 
 void
-initialize_sizetypes (bool signed_p)
+initialize_sizetypes (void)
 {
   tree t = make_node (INTEGER_TYPE);
   int precision = GET_MODE_BITSIZE (SImode);
 
   SET_TYPE_MODE (t, SImode);
   TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode);
-  TYPE_USER_ALIGN (t) = 0;
   TYPE_IS_SIZETYPE (t) = 1;
-  TYPE_UNSIGNED (t) = !signed_p;
+  TYPE_UNSIGNED (t) = 1;
   TYPE_SIZE (t) = build_int_cst (t, precision);
   TYPE_SIZE_UNIT (t) = build_int_cst (t, GET_MODE_SIZE (SImode));
   TYPE_PRECISION (t) = precision;
 
-  /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE.  */
-  set_min_and_max_values_for_integral_type (t, precision, !signed_p);
+  set_min_and_max_values_for_integral_type (t, precision, true);
 
   sizetype = t;
   bitsizetype = build_distinct_type_copy (t);
 }
 
-/* Make sizetype a version of TYPE, and initialize *sizetype
-   accordingly.  We do this by overwriting the stub sizetype and
-   bitsizetype nodes created by initialize_sizetypes.  This makes sure
-   that (a) anything stubby about them no longer exists, (b) any
-   INTEGER_CSTs created with such a type, remain valid.  */
+/* Make sizetype a version of TYPE, and initialize *sizetype accordingly.
+   We do this by overwriting the stub sizetype and bitsizetype nodes created
+   by initialize_sizetypes.  This makes sure that (a) anything stubby about
+   them no longer exists and (b) any INTEGER_CSTs created with such a type,
+   remain valid.  */
 
 void
 set_sizetype (tree type)
 {
-  tree t;
+  tree t, max;
   int oprecision = TYPE_PRECISION (type);
   /* The *bitsizetype types use a precision that avoids overflows when
      calculating signed sizes / offsets in bits.  However, when
@@ -2276,11 +2255,11 @@ set_sizetype (tree type)
   if (precision > HOST_BITS_PER_WIDE_INT * 2)
     precision = HOST_BITS_PER_WIDE_INT * 2;
 
-  gcc_assert (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (sizetype));
+  /* sizetype must be an unsigned type.  */
+  gcc_assert (TYPE_UNSIGNED (type));
 
   t = build_distinct_type_copy (type);
-  /* We do want to use sizetype's cache, as we will be replacing that
-     type.  */
+  /* We want to use sizetype's cache, as we will be replacing that type.  */
   TYPE_CACHED_VALUES (t) = TYPE_CACHED_VALUES (sizetype);
   TYPE_CACHED_VALUES_P (t) = TYPE_CACHED_VALUES_P (sizetype);
   TREE_TYPE (TYPE_CACHED_VALUES (t)) = type;
@@ -2292,10 +2271,17 @@ set_sizetype (tree type)
   TYPE_MAIN_VARIANT (sizetype) = sizetype;
   TYPE_CANONICAL (sizetype) = sizetype;
 
+  /* sizetype is unsigned but we need to fix TYPE_MAX_VALUE so that it is
+     sign-extended in a way consistent with force_fit_type.  */
+  max = TYPE_MAX_VALUE (sizetype);
+  TYPE_MAX_VALUE (sizetype)
+    = build_int_cst_wide_type (sizetype,
+                              TREE_INT_CST_LOW (max),
+                              TREE_INT_CST_HIGH (max));
+
   t = make_node (INTEGER_TYPE);
   TYPE_NAME (t) = get_identifier ("bit_size_type");
-  /* We do want to use bitsizetype's cache, as we will be replacing that
-     type.  */
+  /* We want to use bitsizetype's cache, as we will be replacing that type.  */
   TYPE_CACHED_VALUES (t) = TYPE_CACHED_VALUES (bitsizetype);
   TYPE_CACHED_VALUES_P (t) = TYPE_CACHED_VALUES_P (bitsizetype);
   TYPE_PRECISION (t) = precision;
@@ -2307,36 +2293,13 @@ set_sizetype (tree type)
   TYPE_MAIN_VARIANT (bitsizetype) = bitsizetype;
   TYPE_CANONICAL (bitsizetype) = bitsizetype;
 
-  if (TYPE_UNSIGNED (type))
-    {
-      fixup_unsigned_type (bitsizetype);
-      ssizetype = build_distinct_type_copy (make_signed_type (oprecision));
-      TYPE_IS_SIZETYPE (ssizetype) = 1;
-      sbitsizetype = build_distinct_type_copy (make_signed_type (precision));
-      TYPE_IS_SIZETYPE (sbitsizetype) = 1;
-    }
-  else
-    {
-      fixup_signed_type (bitsizetype);
-      ssizetype = sizetype;
-      sbitsizetype = bitsizetype;
-    }
-
-  /* If SIZETYPE is unsigned, we need to fix TYPE_MAX_VALUE so that
-     it is sign extended in a way consistent with force_fit_type.  */
-  if (TYPE_UNSIGNED (type))
-    {
-      tree orig_max, new_max;
+  fixup_unsigned_type (bitsizetype);
 
-      orig_max = TYPE_MAX_VALUE (sizetype);
-
-      /* Build a new node with the same values, but a different type.
-        Sign extend it to ensure consistency.  */
-      new_max = build_int_cst_wide_type (sizetype,
-                                        TREE_INT_CST_LOW (orig_max),
-                                        TREE_INT_CST_HIGH (orig_max));
-      TYPE_MAX_VALUE (sizetype) = new_max;
-    }
+  /* Create the signed variants of *sizetype.  */
+  ssizetype = make_signed_type (oprecision);
+  TYPE_IS_SIZETYPE (ssizetype) = 1;
+  sbitsizetype = make_signed_type (precision);
+  TYPE_IS_SIZETYPE (sbitsizetype) = 1;
 }
 \f
 /* TYPE is an integral type, i.e., an INTEGRAL_TYPE, ENUMERAL_TYPE