OSDN Git Service

* config/alpha/vms.h (INCLUDE_DEFAULTS): Add /gnu/lib/gcc-lib/include.
[pf3gnuchains/gcc-fork.git] / gcc / ch / typeck.c
index 2fe1af4..84ee56e 100644 (file)
@@ -46,6 +46,7 @@ static tree extract_constant_from_buffer PARAMS ((tree, const unsigned char *, i
 static int expand_constant_to_buffer PARAMS ((tree, unsigned char *, int));
 static tree build_empty_string PARAMS ((tree));
 static tree make_chill_pointer_type PARAMS ((tree, enum tree_code));
+static unsigned int min_precision PARAMS ((tree, int));
 static tree make_chill_range_type PARAMS ((tree, tree, tree));
 static void apply_chill_array_layout PARAMS ((tree));
 static int field_decl_cmp PARAMS ((tree *, tree*));
@@ -243,14 +244,16 @@ build_chill_slice (array, min_value, length)
 
       SET_CH_NOVELTY (slice_type, CH_NOVELTY (array_type));
 
-      if (TREE_CONSTANT (array) && TREE_CODE (min_value) == INTEGER_CST
-         && TREE_CODE (length) == INTEGER_CST)
+      if (TREE_CONSTANT (array) && host_integerp (min_value, 0)
+         && host_integerp (length, 0))
        {
-         int type_size = int_size_in_bytes (array_type);
-         unsigned char *buffer = (unsigned char*) alloca (type_size);
-         int delta = int_size_in_bytes (element_type)
-           * (TREE_INT_CST_LOW (min_value) - TREE_INT_CST_LOW (domain_min));
-         bzero (buffer, type_size);
+         unsigned HOST_WIDE_INT type_size = int_size_in_bytes (array_type);
+         unsigned char *buffer = (unsigned char *) alloca (type_size);
+         int delta = (int_size_in_bytes (element_type)
+                      * (tree_low_cst (min_value, 0)
+                         - tree_low_cst (domain_min, 0)));
+
+         memset (buffer, 0, type_size);
          if (expand_constant_to_buffer (array, buffer, type_size))
            {
              result = extract_constant_from_buffer (slice_type,
@@ -567,7 +570,7 @@ build_chill_array_ref_1 (array, idx)
   if (! integer_zerop (TYPE_MIN_VALUE (domain)))
     {
       /* The C part of the compiler doesn't understand how to do
-        arithmetic with dissimilar enum types.  So we check compatability
+        arithmetic with dissimilar enum types.  So we check compatibility
         here, and perform the math in INTEGER_TYPE.  */
       if (TREE_CODE (TREE_TYPE (idx)) == ENUMERAL_TYPE
          && chill_comptypes (TREE_TYPE (idx), domain, 0))
@@ -626,13 +629,14 @@ build_chill_array_ref_1 (array, idx)
       else if (TREE_CODE (array) == STRING_CST
               && CH_CHARS_TYPE_P (TREE_TYPE (array)))
        {
-         HOST_WIDE_INT i = TREE_INT_CST_LOW (idx);
+         HOST_WIDE_INT i = tree_low_cst (idx, 0);
+
          if (i >= 0 && i < TREE_STRING_LENGTH (array))
-           {
-             char ch = TREE_STRING_POINTER (array) [i];
-             return convert_to_class (class,
-                                      build_int_2 ((unsigned char)ch, 0));
-           }
+           return
+             convert_to_class
+               (class,
+                build_int_2
+                ((unsigned char) TREE_STRING_POINTER (array) [i], 0));
        }
     }
 
@@ -731,16 +735,18 @@ expand_constant_to_buffer (value, buffer, buf_size)
     {
     case INTEGER_CST:
       {
-       HOST_WIDE_INT lo = TREE_INT_CST_LOW (value);
+       unsigned HOST_WIDE_INT lo = TREE_INT_CST_LOW (value);
        HOST_WIDE_INT hi = TREE_INT_CST_HIGH (value);
        for (i = 0; i < size; i++)
          {
            /* Doesn't work if host and target BITS_PER_UNIT differ. */
            unsigned char byte = lo & ((1 << BITS_PER_UNIT) - 1);
+
            if (BYTES_BIG_ENDIAN)
              buffer[size - i - 1] = byte;
            else
              buffer[i] = byte;
+
            rshift_double (lo, hi, BITS_PER_UNIT, BITS_PER_UNIT * size,
                           &lo, &hi, 0);
          }
@@ -770,10 +776,10 @@ expand_constant_to_buffer (value, buffer, buf_size)
              tree min_val = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
              if (min_val)
                {
-                 if (TREE_CODE (min_val) != INTEGER_CST)
+                 if (! host_integerp (min_val, 0))
                    return 0;
                  else
-                   min_index = TREE_INT_CST_LOW (min_val);
+                   min_index = tree_low_cst (min_val, 0);
                }
            }
 
@@ -784,14 +790,15 @@ expand_constant_to_buffer (value, buffer, buf_size)
              HOST_WIDE_INT offset;
              HOST_WIDE_INT last_index;
              tree purpose = TREE_PURPOSE (list);
+
              if (purpose)
                {
-                 if (TREE_CODE (purpose) == INTEGER_CST)
-                   last_index = next_index = TREE_INT_CST_LOW (purpose);
+                 if (host_integerp (purpose, 0))
+                   last_index = next_index = tree_low_cst (purpose, 0);
                  else if (TREE_CODE (purpose) == RANGE_EXPR)
                    {
-                     next_index = TREE_INT_CST_LOW (TREE_OPERAND(purpose, 0));
-                     last_index = TREE_INT_CST_LOW (TREE_OPERAND(purpose, 1));
+                     next_index = tree_low_cst (TREE_OPERAND (purpose, 0), 0);
+                     last_index = tree_low_cst (TREE_OPERAND (purpose, 1), 0);
                    }
                  else
                    return 0;
@@ -816,12 +823,14 @@ expand_constant_to_buffer (value, buffer, buf_size)
            {
              tree field = TREE_PURPOSE (list);
              HOST_WIDE_INT offset;
+
              if (field == NULL_TREE || TREE_CODE (field) != FIELD_DECL)
                return 0;
+
              if (DECL_BIT_FIELD (field))
                return 0;
-             offset = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
-               / BITS_PER_UNIT;
+
+             offset = int_byte_position (field);
              if (!expand_constant_to_buffer (TREE_VALUE (list),
                                              buffer + offset,
                                              buf_size - offset))
@@ -854,10 +863,12 @@ extract_constant_from_buffer (type, buffer, buf_size)
      int buf_size;
 {
   tree value;
-  int size = int_size_in_bytes (type);
-  int i;
+  HOST_WIDE_INT size = int_size_in_bytes (type);
+  HOST_WIDE_INT i;
+
   if (size < 0 || size > buf_size)
     return 0;
+
   switch (TREE_CODE (type))
     {
     case INTEGER_TYPE:
@@ -902,16 +913,18 @@ extract_constant_from_buffer (type, buffer, buf_size)
        value = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
        if (value)
          {
-           if (TREE_CODE (value) != INTEGER_CST)
+           if (! host_integerp (value, 0))
              return 0;
            else
-             min_index = TREE_INT_CST_LOW (value);
+             min_index = tree_low_cst (value, 0);
          }
+
        value = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
-       if (value == NULL_TREE || TREE_CODE (value) != INTEGER_CST)
+       if (value == NULL_TREE || ! host_integerp (value, 0))
          return 0;
        else
-         max_index = TREE_INT_CST_LOW (value);
+         max_index = tree_low_cst (value, 0);
+
        for (cur_index = max_index; cur_index >= min_index; cur_index--)
          {
            HOST_WIDE_INT offset = (cur_index - min_index) * element_size;
@@ -933,8 +946,8 @@ extract_constant_from_buffer (type, buffer, buf_size)
        tree field = TYPE_FIELDS (type);
        for (; field != NULL_TREE; field = TREE_CHAIN (field))
          {
-           HOST_WIDE_INT offset
-             = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)) / BITS_PER_UNIT;
+           HOST_WIDE_INT offset = int_byte_position (field);
+
            if (DECL_BIT_FIELD (field))
              return 0;
            value = extract_constant_from_buffer (TREE_TYPE (field),
@@ -953,7 +966,7 @@ extract_constant_from_buffer (type, buffer, buf_size)
     case UNION_TYPE:
       {
        tree longest_variant = NULL_TREE;
-       int longest_size = 0;
+       unsigned HOST_WIDE_INT longest_size = 0;
        tree field = TYPE_FIELDS (type);
        
        /* This is a kludge.  We assume that converting the data to te
@@ -966,7 +979,8 @@ extract_constant_from_buffer (type, buffer, buf_size)
 
        for (; field != NULL_TREE; field = TREE_CHAIN (field))
          {
-           int size = TREE_INT_CST_LOW (size_in_bytes (TREE_TYPE (field)));
+           unsigned HOST_WIDE_INT size
+             = int_size_in_bytes (TREE_TYPE (field));
            
            if (size > longest_size)
              {
@@ -974,9 +988,13 @@ extract_constant_from_buffer (type, buffer, buf_size)
                longest_variant = field;
              }
          }
+
        if (longest_variant == NULL_TREE)
          return NULL_TREE;
-       return extract_constant_from_buffer (TREE_TYPE (longest_variant), buffer, buf_size);
+
+       return
+         extract_constant_from_buffer (TREE_TYPE (longest_variant),
+                                       buffer, buf_size);
       }
 
     case SET_TYPE:
@@ -984,26 +1002,32 @@ extract_constant_from_buffer (type, buffer, buf_size)
        tree list = NULL_TREE;
        int i;
        HOST_WIDE_INT min_index, max_index;
+
        if (TYPE_DOMAIN (type) == 0)
          return 0;
+
        value = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
        if (value == NULL_TREE)
          min_index = 0;
-       else if (TREE_CODE (value) != INTEGER_CST)
+
+       else if (! host_integerp (value, 0))
          return 0;
        else
-         min_index = TREE_INT_CST_LOW (value);
+         min_index = tree_low_cst (value, 0);
+
        value = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
        if (value == NULL_TREE)
          max_index = 0;
-       else if (TREE_CODE (value) != INTEGER_CST)
+       else if (! host_integerp (value, 0))
          return 0;
        else
-         max_index = TREE_INT_CST_LOW (value);
+         max_index = tree_low_cst (value, 0);
+
        for (i = max_index + 1 - min_index; --i >= 0; )
          {
-           unsigned char byte = (unsigned char)buffer[i / BITS_PER_UNIT];
-           unsigned bit_pos = (unsigned)i % (unsigned)BITS_PER_UNIT;
+           unsigned char byte = (unsigned char) buffer[i / BITS_PER_UNIT];
+           unsigned bit_pos = (unsigned) i % (unsigned) BITS_PER_UNIT;
+
            if (BYTES_BIG_ENDIAN
                ? (byte & (1 << (BITS_PER_UNIT - 1 - bit_pos)))
                : (byte & (1 << bit_pos)))
@@ -1090,7 +1114,7 @@ build_chill_cast (type, expr)
   if (expr_type_is_discrete && type_is_discrete)
     {
       /* do an overflow check
-        FIXME: is this always neccessary ??? */
+        FIXME: is this always necessary ??? */
       /* FIXME: don't do range chacking when target type is PTR.
         PTR doesn't have MIN and MAXVALUE. result is sigsegv. */
       if (range_checking && type != ptr_type_node)
@@ -1169,7 +1193,7 @@ build_chill_cast (type, expr)
     {
       unsigned char *buffer = (unsigned char*) alloca (type_size);
       tree value;
-      bzero (buffer, type_size);
+      memset (buffer, 0, type_size);
       if (!expand_constant_to_buffer (expr, buffer, type_size))
        {
          error ("not implemented: constant conversion from that kind of expression");
@@ -1241,14 +1265,16 @@ build_chill_bin_type (size)
      tree size;
 {
 #if 0
-  int isize;
+  HOST_WIDE_INT isize;
 
-  if (TREE_CODE (size) != INTEGER_CST
-      || (isize = TREE_INT_CST_LOW (size), isize <= 0))
+  if (! host_integerp (size, 1))
     {
       error ("operand to bin must be a non-negative integer literal");
       return error_mark_node;
     }
+
+  isize = tree_low_cst (size, 1);
+
   if (isize <= TYPE_PRECISION (unsigned_char_type_node))
     return unsigned_char_type_node;
   if (isize <= TYPE_PRECISION (short_unsigned_type_node))
@@ -1696,12 +1722,10 @@ chill_similar (mode1, mode2, chain)
 
     default:
       ;
-#if 0
       /* Need to handle row modes, instance modes,
         association modes, access modes, text modes,
         duration modes, absolute time modes, structure modes,
         parameterized structure modes */
-#endif
     }
   return 1;
 }
@@ -1783,9 +1807,9 @@ chill_l_equivalent (mode1, mode2, chain)
     return 0;
   if (TYPE_READONLY (mode1) != TYPE_READONLY (mode2))
     return 0;
-#if 0
+/*
   ... other conditions ...;
-#endif
+ */
   return 1;
 }
 
@@ -1811,9 +1835,9 @@ chill_read_compatible (modeM, modeN)
        {
          return chill_l_equivalent (TREE_TYPE (modeM), TREE_TYPE (modeN), 0);
        }
-#if 0
+/*
       ...;
-#endif
+*/
     }
   return 1;
 }
@@ -1863,13 +1887,12 @@ chill_compatible (expr, mode)
     case CH_REFERENCE_CLASS:
       if (!CH_IS_REFERENCE_MODE (mode))
        return 0;
-#if 0
-      /* FIXME! */
+/* FIXME!
       if (class.mode is a row mode)
        ...;
       else if (class.mode is not a static mode)
-       return 0; /* is this possible? FIXME */
-#endif
+       return 0; is this possible?
+*/
       return !CH_IS_BOUND_REFERENCE_MODE(mode)
        || CH_READ_COMPATIBLE (TREE_TYPE (mode), class.mode);
     }
@@ -2500,6 +2523,36 @@ make_chill_range_type (type, lowval, highval)
   return itype;
 }
 
+\f
+/* Return the minimum number of bits needed to represent VALUE in a
+   signed or unsigned type, UNSIGNEDP says which.  */
+
+static unsigned int
+min_precision (value, unsignedp)
+     tree value;
+     int unsignedp;
+{
+  int log;
+
+  /* If the value is negative, compute its negative minus 1.  The latter
+     adjustment is because the absolute value of the largest negative value
+     is one larger than the largest positive value.  This is equivalent to
+     a bit-wise negation, so use that operation instead.  */
+
+  if (tree_int_cst_sgn (value) < 0)
+    value = fold (build1 (BIT_NOT_EXPR, TREE_TYPE (value), value));
+
+  /* Return the number of bits needed, taking into account the fact
+     that we need one more bit for a signed than unsigned type.  */
+
+  if (integer_zerop (value))
+    log = 0;
+  else
+    log = tree_floor_log2 (value);
+
+  return log + 1 + ! unsignedp;
+}
+
 tree
 layout_chill_range_type (rangetype, must_be_const)
      tree rangetype;
@@ -2518,30 +2571,31 @@ layout_chill_range_type (rangetype, must_be_const)
     {
       int binsize;
       
-      /* make a range out of it */
+      /* Make a range out of it */
       if (TREE_CODE (highval) != INTEGER_CST)
        {
          error ("non-constant expression for BIN");
          return error_mark_node;
        }
-      binsize = TREE_INT_CST_LOW (highval);
-      if (binsize < 0)
+      else if (tree_int_cst_sgn (highval) < 0)
        {
          error ("expression for BIN must not be negative");
          return error_mark_node;
        }
-      if (binsize > 32)
+      else if (compare_tree_int (highval, 32) > 0)
        {
          error ("cannot process BIN (>32)");
          return error_mark_node;
        }
+
+      binsize = tree_low_cst (highval, 1);
       type = ridpointers [(int) RID_RANGE];
       lowval = integer_zero_node;
       highval = build_int_2 ((1 << binsize) - 1, 0);
     }
  
-  if (TREE_CODE (lowval) == ERROR_MARK ||
-      TREE_CODE (highval) == ERROR_MARK)
+  if (TREE_CODE (lowval) == ERROR_MARK
+      || TREE_CODE (highval) == ERROR_MARK)
     return error_mark_node;
 
   if (!CH_COMPATIBLE_CLASSES (lowval, highval))
@@ -2578,37 +2632,14 @@ layout_chill_range_type (rangetype, must_be_const)
          && TREE_CODE (lowval) == INTEGER_CST
          && TREE_CODE (highval) == INTEGER_CST)
        {
-         /* The logic of this code has been copied from finish_enum
-            in c-decl.c.  FIXME duplication! */
-         int precision = 0;
-         HOST_WIDE_INT maxvalue = TREE_INT_CST_LOW (highval);
-         HOST_WIDE_INT minvalue = TREE_INT_CST_LOW (lowval);
-         if (TREE_INT_CST_HIGH (lowval) >= 0
-             ? tree_int_cst_lt (TYPE_MAX_VALUE (unsigned_type_node), highval)
-             : (tree_int_cst_lt (lowval, TYPE_MIN_VALUE (integer_type_node))
-                || tree_int_cst_lt (TYPE_MAX_VALUE (integer_type_node), highval)))
-           precision = TYPE_PRECISION (long_long_integer_type_node);
-         else
-           {
-             if (maxvalue > 0)
-               precision = floor_log2 (maxvalue) + 1;
-             if (minvalue < 0)
-               {
-                 /* Compute number of bits to represent magnitude of a
-                    negative value.  Add one to MINVALUE since range of
-                    negative numbers includes the power of two.  */
-                 int negprecision = floor_log2 (-minvalue - 1) + 1;
-                 if (negprecision > precision)
-                   precision = negprecision;
-                 precision += 1;       /* room for sign bit */
-               }
+         int unsignedp = tree_int_cst_sgn (lowval) >= 0;
+         unsigned int precision = MAX (min_precision (highval, unsignedp),
+                                       min_precision (lowval, unsignedp));
 
-             if (!precision)
-               precision = 1;
-           }
-         type = type_for_size (precision, minvalue >= 0);
+         type = type_for_size (precision, unsignedp);
 
        }
+
       TREE_TYPE (rangetype) = type;
     }
   else
@@ -2691,6 +2722,7 @@ layout_chill_range_type (rangetype, must_be_const)
   TYPE_SIZE (rangetype) = TYPE_SIZE (type);
   TYPE_SIZE_UNIT (rangetype) = TYPE_SIZE_UNIT (type);
   TYPE_ALIGN (rangetype) = TYPE_ALIGN (type);
+  TYPE_USER_ALIGN (rangetype) = TYPE_USER_ALIGN (type);
   TREE_UNSIGNED (rangetype) = TREE_UNSIGNED (type);
   CH_NOVELTY (rangetype) = CH_NOVELTY (type);
   return rangetype;
@@ -2736,7 +2768,9 @@ apply_chill_array_layout (array_type)
      tree array_type;
 {
   tree layout, temp, what, element_type;
-  int stepsize=0, word, start_bit=0, length, natural_length;
+  HOST_WIDE_INT stepsize = 0;
+  HOST_WIDE_INT word, start_bit = 0, length;
+  HOST_WIDE_INT natural_length;
   int stepsize_specified;
   int start_bit_error = 0;
   int length_error = 0;
@@ -2757,8 +2791,10 @@ apply_chill_array_layout (array_type)
       && get_type_precision (TYPE_MIN_VALUE (element_type),
                             TYPE_MAX_VALUE (element_type)) == 1)
     natural_length = 1;
+  else if (host_integerp (TYPE_SIZE (element_type), 1))
+    natural_length = tree_low_cst (TYPE_SIZE (element_type), 1);
   else
-    natural_length = TREE_INT_CST_LOW (TYPE_SIZE (element_type));
+    natural_length = -1;
 
   if (layout == integer_one_node) /* PACK */
     {
@@ -2774,31 +2810,32 @@ apply_chill_array_layout (array_type)
   temp = TREE_VALUE (layout);
   if (TREE_VALUE (temp) != NULL_TREE)
     {
-      if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
-       error ("Stepsize in STEP must be an integer constant");
+      if (! host_integerp (TREE_VALUE (temp), 0))
+       error ("stepsize in STEP must be an integer constant");
       else
        {
-         stepsize = TREE_INT_CST_LOW (TREE_VALUE (temp));
-         if (stepsize <= 0)
-           error ("Stepsize in STEP must be > 0");
+         if (tree_int_cst_sgn (TREE_VALUE (temp)) <= 0)
+           error ("stepsize in STEP must be > 0");
          else
            stepsize_specified = 1;
 
+         stepsize = tree_low_cst (TREE_VALUE (temp), 1);
          if (stepsize != natural_length)
-           sorry ("Stepsize in STEP must be the natural width of the array element mode");
+           sorry ("stepsize in STEP must be the natural width of the array element mode");
        }
     }
 
   temp = TREE_PURPOSE (temp);
-  if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
-    error ("Starting word in POS must be an integer constant");
+  if (! host_integerp (TREE_PURPOSE (temp), 0))
+    error ("starting word in POS must be an integer constant");
   else
     {
-      word = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
-      if (word < 0)
-       error ("Starting word in POS must be >= 0");
-      if (word != 0)
-       sorry ("Starting word in POS within STEP must be 0");
+      if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
+       error ("starting word in POS must be >= 0");
+      if (! integer_zerop (TREE_PURPOSE (temp)))
+       sorry ("starting word in POS within STEP must be 0");
+
+      word = tree_low_cst (TREE_PURPOSE (temp), 0);
     }
 
   length = natural_length;
@@ -2806,25 +2843,27 @@ apply_chill_array_layout (array_type)
   if (temp != NULL_TREE)
     {
       int wordsize = TYPE_PRECISION (chill_integer_type_node);
-      if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
+      if (! host_integerp (TREE_PURPOSE (temp), 0))
        {
-         error ("Starting bit in POS must be an integer constant");
+         error ("starting bit in POS must be an integer constant");
          start_bit_error = 1;
        }
       else
        {
-         start_bit = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
-         if (start_bit != 0)
-           sorry ("Starting bit in POS within STEP must be 0");
-         if (start_bit < 0)
+         if (! integer_zerop (TREE_PURPOSE (temp)))
+           sorry ("starting bit in POS within STEP must be 0");
+
+         if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
            {
-             error ("Starting bit in POS must be >= 0");
+             error ("starting bit in POS must be >= 0");
              start_bit = 0;
              start_bit_error = 1;
            }
-         else if (start_bit >= wordsize)
+         
+         start_bit = tree_low_cst (TREE_PURPOSE (temp), 0);
+         if (start_bit >= wordsize)
            {
-             error ("Starting bit in POS must be < the width of a word");
+             error ("starting bit in POS must be < the width of a word");
              start_bit = 0;
              start_bit_error = 1;
            }
@@ -2836,37 +2875,38 @@ apply_chill_array_layout (array_type)
          what = TREE_PURPOSE (temp);
          if (what == integer_zero_node)
            {
-             if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+             if (! host_integerp (TREE_VALUE (temp), 0))
                {
-                 error ("Length in POS must be an integer constant");
+                 error ("length in POS must be an integer constant");
                  length_error = 1;
                }
              else
                {
-                 length = TREE_INT_CST_LOW (TREE_VALUE (temp));
+                 length = tree_low_cst (TREE_VALUE (temp), 0);
                  if (length <= 0)
-                   error ("Length in POS must be > 0");
+                   error ("length in POS must be > 0");
                }
            }
          else
            {
-             if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+             if (! host_integerp (TREE_VALUE (temp), 0))
                {
-                 error ("End bit in POS must be an integer constant");
+                 error ("end bit in POS must be an integer constant");
                  length_error = 1;
                }
              else
                {
-                 int end_bit = TREE_INT_CST_LOW (TREE_VALUE (temp));
+                 HOST_WIDE_INT end_bit = tree_low_cst (TREE_VALUE (temp), 0);
+
                  if (end_bit < start_bit)
                    {
-                     error ("End bit in POS must be >= the start bit");
+                     error ("end bit in POS must be >= the start bit");
                      end_bit = wordsize - 1;
                      length_error = 1;
                    }
                  else if (end_bit >= wordsize)
                    {
-                     error ("End bit in POS must be < the width of a word");
+                     error ("end bit in POS must be < the width of a word");
                      end_bit = wordsize - 1;
                      length_error = 1;
                    }
@@ -2876,15 +2916,14 @@ apply_chill_array_layout (array_type)
                    length = end_bit - start_bit + 1;
                }
            }
+
          if (! length_error && length != natural_length)
-           {
-             sorry ("The length specified on POS within STEP must be the natural length of the array element type");
-           }
+           sorry ("the length specified on POS within STEP must be the natural length of the array element type");
        }
     }
 
   if (! length_error && stepsize_specified && stepsize < length)
-    error ("Step size in STEP must be >= the length in POS");
+    error ("step size in STEP must be >= the length in POS");
 
   if (length == 1)
     TYPE_PACKED (array_type) = 1;
@@ -3053,8 +3092,10 @@ apply_chill_field_layout (decl, next_struct_offset)
   if (is_discrete)
     natural_length
       = get_type_precision (TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type));
+  else if (host_integerp (TYPE_SIZE (type), 1))
+    natural_length = tree_low_cst (TYPE_SIZE (type), 1);
   else
-    natural_length = TREE_INT_CST_LOW (TYPE_SIZE (type));
+    natural_length = -1;
 
   if (layout == integer_zero_node) /* NOPACK */
     {
@@ -3070,7 +3111,10 @@ apply_chill_field_layout (decl, next_struct_offset)
          DECL_SIZE (decl) = bitsize_int (natural_length);
        }
       else
-       DECL_ALIGN (decl) = BITS_PER_UNIT;
+       {
+         DECL_ALIGN (decl) = BITS_PER_UNIT;
+         DECL_USER_ALIGN (decl) = 0;
+       }
 
       DECL_PACKED (decl) = 1;
       *next_struct_offset += natural_length;
@@ -3082,20 +3126,21 @@ apply_chill_field_layout (decl, next_struct_offset)
      natural width of the underlying type. */
   temp = TREE_PURPOSE (layout);
 
-  if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
+  if (! host_integerp (TREE_PURPOSE (temp), 0))
     {
-      error ("Starting word in POS must be an integer constant");
+      error ("starting word in POS must be an integer constant");
       pos_error = 1;
     }
   else
     {
-      word = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
       if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
        {
-         error ("Starting word in POS must be >= 0");
+         error ("starting word in POS must be >= 0");
          word = 0;
          pos_error = 1;
        }
+      else
+       word = tree_low_cst (TREE_PURPOSE (temp), 0);
     }
 
   wordsize = TYPE_PRECISION (chill_integer_type_node);
@@ -3105,24 +3150,25 @@ apply_chill_field_layout (decl, next_struct_offset)
   temp = TREE_VALUE (temp);
   if (temp != NULL_TREE)
     {
-      if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
+      if (! host_integerp (TREE_PURPOSE (temp), 0))
        {
-         error ("Starting bit in POS must be an integer constant");
+         error ("starting bit in POS must be an integer constant");
          start_bit = *next_struct_offset - offset;
          pos_error = 1;
        }
       else
        {
-         start_bit = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
          if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
            {
-             error ("Starting bit in POS must be >= 0");
+             error ("starting bit in POS must be >= 0");
              start_bit = *next_struct_offset - offset;
              pos_error = 1;
            }
-         else if (start_bit >= wordsize)
+
+         start_bit = tree_low_cst (TREE_PURPOSE (temp), 0);
+         if (start_bit >= wordsize)
            {
-             error ("Starting bit in POS must be < the width of a word");
+             error ("starting bit in POS must be < the width of a word");
              start_bit = *next_struct_offset - offset;
              pos_error = 1;
            }
@@ -3134,41 +3180,43 @@ apply_chill_field_layout (decl, next_struct_offset)
          what = TREE_PURPOSE (temp);
          if (what == integer_zero_node)
            {
-             if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+             if (! host_integerp (TREE_VALUE (temp), 0))
                {
-                 error ("Length in POS must be an integer constant");
+                 error ("length in POS must be an integer constant");
                  pos_error = 1;
                }
              else
                {
-                 length = TREE_INT_CST_LOW (TREE_VALUE (temp));
                  if (tree_int_cst_sgn (TREE_VALUE (temp)) < 0)
                    {
-                     error ("Length in POS must be > 0");
+                     error ("length in POS must be > 0");
                      length = natural_length;
                      pos_error = 1;
                    }
+                 else
+                   length = tree_low_cst (TREE_VALUE (temp), 0);
+
                }
            }
          else
            {
-             if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+             if (! host_integerp (TREE_VALUE (temp), 0))
                {
-                 error ("End bit in POS must be an integer constant");
+                 error ("end bit in POS must be an integer constant");
                  pos_error = 1;
                }
              else
                {
-                 HOST_WIDE_INT end_bit = TREE_INT_CST_LOW (TREE_VALUE (temp));
+                 HOST_WIDE_INT end_bit = tree_low_cst (TREE_VALUE (temp), 0);
 
                  if (end_bit < start_bit)
                    {
-                     error ("End bit in POS must be >= the start bit");
+                     error ("end bit in POS must be >= the start bit");
                      pos_error = 1;
                    }
                  else if (end_bit >= wordsize)
                    {
-                     error ("End bit in POS must be < the width of a word");
+                     error ("end bit in POS must be < the width of a word");
                      pos_error = 1;
                    }
                  else
@@ -3178,7 +3226,7 @@ apply_chill_field_layout (decl, next_struct_offset)
 
          if (length != natural_length && ! pos_error)
            {
-             sorry ("The length specified on POS must be the natural length of the field type");
+             sorry ("the length specified on POS must be the natural length of the field type");
              length = natural_length;
            }
        }
@@ -3250,7 +3298,7 @@ layout_chill_struct_type (t)
     }
 
   if (pos_error)
-    error ("If one field has a POS layout, then all fields must have a POS layout");
+    error ("if one field has a POS layout, then all fields must have a POS layout");
 
   /* Now DECL_INITIAL is null on all fields.  */
 
@@ -3304,6 +3352,7 @@ layout_chill_struct_type (t)
       TYPE_FIELDS (x) = TYPE_FIELDS (t);
       TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
       TYPE_ALIGN (x) = TYPE_ALIGN (t);
+      TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t);
     }
 
   resume_momentary (old_momentary);
@@ -3392,12 +3441,12 @@ smash_dummy_type (type)
            }
          else if (TREE_CODE (origin) == RECORD_TYPE)
            {
-             error ("parameterised structures not implemented");
+             error ("parameterized structures not implemented");
              return error_mark_node;
            }
          else
            {
-             error ("invalid parameterised type");
+             error ("invalid parameterized type");
              return error_mark_node;
            }