/* 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 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */


#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "flags.h"
#include "function.h"
#include "expr.h"
#include "toplev.h"
#include "ggc.h"
#include "target.h"
#include "langhooks.h"

/* Set to one when set_sizetype has been called.  */
static int sizetype_set;

/* List of types created before set_sizetype has been called.  We do not
   make this a GGC root since we want these nodes to be reclaimed.  */
static tree early_type_list;

/* Data type for the expressions representing sizes of data types.
   It is the first integer type laid out.  */
tree sizetype_tab[(int) TYPE_KIND_LAST];

/* If nonzero, this is an upper limit on alignment of structure fields.
   The value is measured in bits.  */
unsigned int maximum_field_alignment;

/* If nonzero, the alignment of a bitstring or (power-)set value, in bits.
   May be overridden by front-ends.  */
unsigned int set_alignment = 0;

/* 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.  */
static int reference_types_internal = 0;

static void finalize_record_size (record_layout_info);
static void finalize_type_size (tree);
static void place_union_field (record_layout_info, tree);
#if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT,
			     HOST_WIDE_INT, tree);
#endif
static unsigned int update_alignment_for_field (record_layout_info, tree,
						unsigned int);
extern void debug_rli (record_layout_info);

/* 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.  */

void
internal_reference_types (void)
{
  reference_types_internal = 1;
}

/* Get a list of all the objects put on the pending sizes list.  */

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;
}

/* Return nonzero if EXPR is present on the pending sizes list.  */

int
is_pending_size (tree expr)
{
  tree t;

  for (t = pending_sizes; t; t = TREE_CHAIN (t))
    if (TREE_VALUE (t) == expr)
      return 1;
  return 0;
}

/* Add EXPR to the pending sizes list.  */

void
put_pending_size (tree expr)
{
  /* Strip any simple arithmetic from EXPR to see if it has an underlying
     SAVE_EXPR.  */
  expr = skip_simple_arithmetic (expr);

  if (TREE_CODE (expr) == SAVE_EXPR)
    pending_sizes = tree_cons (NULL_TREE, expr, pending_sizes);
}

/* Put a chain of objects into the pending sizes list, which must be
   empty.  */

void
put_pending_sizes (tree chain)
{
  if (pending_sizes)
    abort ();

  pending_sizes = chain;
}

/* Given a size SIZE that may not be a constant, return a SAVE_EXPR
   to serve as the actual size-expression for a type or decl.  */

tree
variable_size (tree size)
{
  tree save;

  /* 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.  Likewise for self-referential sizes and
     constant sizes.  */
  if (TREE_CONSTANT (size)
      || (*lang_hooks.decls.global_bindings_p) () < 0
      || CONTAINS_PLACEHOLDER_P (size))
    return size;

  if (TREE_CODE (size) == MINUS_EXPR && integer_onep (TREE_OPERAND (size, 1)))
    /* If this is the upper bound of a C array, leave the minus 1 outside
       the SAVE_EXPR so it can be folded away.  */
    TREE_OPERAND (size, 0) = save = save_expr (TREE_OPERAND (size, 0));
  else
    size = save = save_expr (size);

  /* If an array with a variable number of elements is declared, and
     the elements require destruction, we will emit a cleanup for the
     array.  That cleanup is run both on normal exit from the block
     and in the exception-handler for the block.  Normally, when code
     is used in both ordinary code and in an exception handler it is
     `unsaved', i.e., all SAVE_EXPRs are recalculated.  However, we do
     not wish to do that here; the array-size is the same in both
     places.  */
  if (TREE_CODE (save) == SAVE_EXPR)
    SAVE_EXPR_PERSISTENT_P (save) = 1;

  if ((*lang_hooks.decls.global_bindings_p) ())
    {
      if (TREE_CONSTANT (size))
	error ("type size can't be explicitly evaluated");
      else
	error ("variable-size type declared outside of any function");

      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);

  return size;
}

#ifndef MAX_FIXED_MODE_SIZE
#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode)
#endif

/* Return the machine mode to use for a nonscalar of SIZE bits.  The
   mode must be in class CLASS, and have exactly that many value bits;
   it may have padding as well.  If LIMIT is nonzero, modes of wider
   than MAX_FIXED_MODE_SIZE will not be used.  */

enum machine_mode
mode_for_size (unsigned int size, enum mode_class class, int limit)
{
  enum machine_mode mode;

  if (limit && size > MAX_FIXED_MODE_SIZE)
    return BLKmode;

  /* 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_PRECISION (mode) == size)
      return mode;

  return BLKmode;
}

/* Similar, except passed a tree node.  */

enum machine_mode
mode_for_size_tree (tree size, enum mode_class class, int limit)
{
  if (TREE_CODE (size) != INTEGER_CST
      || TREE_OVERFLOW (size)
      /* What we really want to say here is that the size can fit in a
	 host integer, but we know there's no way we'd find a mode for
	 this many bits, so there's no point in doing the precise test.  */
      || compare_tree_int (size, 1000) > 0)
    return BLKmode;
  else
    return mode_for_size (tree_low_cst (size, 1), class, limit);
}

/* Similar, but never return BLKmode; return the narrowest mode that
   contains at least the requested number of value bits.  */

enum machine_mode
smallest_mode_for_size (unsigned int size, enum mode_class class)
{
  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_PRECISION (mode) >= size)
      return mode;

  abort ();
}

/* Find an integer mode of the exact same size, or BLKmode on failure.  */

enum machine_mode
int_mode_for_mode (enum machine_mode mode)
{
  switch (GET_MODE_CLASS (mode))
    {
    case MODE_INT:
    case MODE_PARTIAL_INT:
      break;

    case MODE_COMPLEX_INT:
    case MODE_COMPLEX_FLOAT:
    case MODE_FLOAT:
    case MODE_VECTOR_INT:
    case MODE_VECTOR_FLOAT:
      mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
      break;

    case MODE_RANDOM:
      if (mode == BLKmode)
	break;

      /* ... fall through ...  */

    case MODE_CC:
    default:
      abort ();
    }

  return mode;
}

/* Return the alignment of MODE. This will be bounded by 1 and
   BIGGEST_ALIGNMENT.  */

unsigned int
get_mode_alignment (enum machine_mode mode)
{
  return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT));
}

/* Return the value of VALUE, rounded up to a multiple of DIVISOR.
   This can only be applied to objects of a sizetype.  */

tree
round_up (tree value, int divisor)
{
  tree arg = size_int_type (divisor, TREE_TYPE (value));

  return size_binop (MULT_EXPR, size_binop (CEIL_DIV_EXPR, value, arg), arg);
}

/* Likewise, but round down.  */

tree
round_down (tree value, int divisor)
{
  tree arg = size_int_type (divisor, TREE_TYPE (value));

  return size_binop (MULT_EXPR, size_binop (FLOOR_DIV_EXPR, value, arg), arg);
}

/* Subroutine of layout_decl: Force alignment required for the data type.
   But if the decl itself wants greater alignment, don't override that.  */

static inline void
do_type_align (tree type, tree decl)
{
  if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
    {
      DECL_ALIGN (decl) = TYPE_ALIGN (type);
      if (TREE_CODE (decl) == FIELD_DECL)
	DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
    }
}

/* Set the size, mode and alignment of a ..._DECL node.
   TYPE_DECL does need this for C++.
   Note that LABEL_DECL and CONST_DECL nodes do not need this,
   and FUNCTION_DECL nodes have them set up in a special (and simple) way.
   Don't call layout_decl for them.

   KNOWN_ALIGN is the amount of alignment we can assume this
   decl has with no special effort.  It is relevant only for FIELD_DECLs
   and depends on the previous fields.
   All that matters about KNOWN_ALIGN is which powers of 2 divide it.
   If KNOWN_ALIGN is 0, it means, "as much alignment as you like":
   the record will be aligned to suit.  */

void
layout_decl (tree decl, unsigned int known_align)
{
  tree type = TREE_TYPE (decl);
  enum tree_code code = TREE_CODE (decl);
  rtx rtl = NULL_RTX;

  if (code == CONST_DECL)
    return;
  else if (code != VAR_DECL && code != PARM_DECL && code != RESULT_DECL
	   && code != TYPE_DECL && code != FIELD_DECL)
    abort ();

  rtl = DECL_RTL_IF_SET (decl);

  if (type == error_mark_node)
    type = void_type_node;

  /* Usually the size and mode come from the data type without change,
     however, the front-end may set the explicit width of the field, so its
     size may not be the same as the size of its type.  This happens with
     bitfields, of course (an `int' bitfield may be only 2 bits, say), but it
     also happens with other fields.  For example, the C++ front-end creates
     zero-sized fields corresponding to empty base classes, and depends on
     layout_type setting DECL_FIELD_BITPOS correctly for the field.  Set the
     size in bytes from the size in bits.  If we have already set the mode,
     don't set it again since we can be called twice for FIELD_DECLs.  */

  TREE_UNSIGNED (decl) = TREE_UNSIGNED (type);
  if (DECL_MODE (decl) == VOIDmode)
    DECL_MODE (decl) = TYPE_MODE (type);

  if (DECL_SIZE (decl) == 0)
    {
      DECL_SIZE (decl) = TYPE_SIZE (type);
      DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
    }
  else if (DECL_SIZE_UNIT (decl) == 0)
    DECL_SIZE_UNIT (decl)
      = convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
				       bitsize_unit_node));

  if (code != FIELD_DECL)
    /* For non-fields, update the alignment from the type.  */
    do_type_align (type, decl);
  else
    /* For fields, it's a bit more complicated...  */
    {
      bool old_user_align = DECL_USER_ALIGN (decl);

      if (DECL_BIT_FIELD (decl))
	{
	  DECL_BIT_FIELD_TYPE (decl) = type;

	  /* A zero-length bit-field affects the alignment of the next
	     field.  */
	  if (integer_zerop (DECL_SIZE (decl))
	      && ! DECL_PACKED (decl)
	      && ! (*targetm.ms_bitfield_layout_p) (DECL_FIELD_CONTEXT (decl)))
	    {
#ifdef PCC_BITFIELD_TYPE_MATTERS
	      if (PCC_BITFIELD_TYPE_MATTERS)
		do_type_align (type, decl);
	      else
#endif
		{
#ifdef EMPTY_FIELD_BOUNDARY
		  if (EMPTY_FIELD_BOUNDARY > DECL_ALIGN (decl))
		    {
		      DECL_ALIGN (decl) = EMPTY_FIELD_BOUNDARY;
		      DECL_USER_ALIGN (decl) = 0;
		    }
#endif
		}
	    }

	  /* See if we can use an ordinary integer mode for a bit-field.
	     Conditions are: a fixed size that is correct for another mode
	     and occupying a complete byte or bytes on proper boundary.  */
	  if (TYPE_SIZE (type) != 0
	      && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
	      && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
	    {
	      enum machine_mode xmode
		= mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);

	      if (xmode != BLKmode 
		  && (known_align == 0
		      || known_align >= GET_MODE_ALIGNMENT (xmode)))
		{
		  DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
					   DECL_ALIGN (decl));
		  DECL_MODE (decl) = xmode;
		  DECL_BIT_FIELD (decl) = 0;
		}
	    }

	  /* Turn off DECL_BIT_FIELD if we won't need it set.  */
	  if (TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
	      && known_align >= TYPE_ALIGN (type)
	      && DECL_ALIGN (decl) >= TYPE_ALIGN (type))
	    DECL_BIT_FIELD (decl) = 0;
	}
      else if (DECL_PACKED (decl) && DECL_USER_ALIGN (decl))
	/* Don't touch DECL_ALIGN.  For other packed fields, go ahead and
	   round up; we'll reduce it again below.  We want packing to
	   supersede USER_ALIGN inherited from the type, but defer to
	   alignment explicitly specified on the field decl.  */;
      else
	do_type_align (type, decl);

      /* If the field is of variable size, we can't misalign it since we
	 have no way to make a temporary to align the result.  But this
	 isn't an issue if the decl is not addressable.  Likewise if it
	 is of unknown size.

	 Note that do_type_align may set DECL_USER_ALIGN, so we need to
	 check old_user_align instead.  */
      if (DECL_PACKED (decl)
	  && !old_user_align
	  && (DECL_NONADDRESSABLE_P (decl)
	      || DECL_SIZE_UNIT (decl) == 0
	      || 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))
	{
	  /* Some targets (i.e. i386, VMS) limit struct field alignment
	     to a lower boundary than alignment of variables unless
	     it was overridden by attribute aligned.  */
#ifdef BIGGEST_FIELD_ALIGNMENT
	  DECL_ALIGN (decl)
	    = MIN (DECL_ALIGN (decl), (unsigned) BIGGEST_FIELD_ALIGNMENT);
#endif
#ifdef ADJUST_FIELD_ALIGN
	  DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl));
#endif
	}
    }

  /* Evaluate nonconstant size only once, either now or as soon as safe.  */
  if (DECL_SIZE (decl) != 0 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
    DECL_SIZE (decl) = variable_size (DECL_SIZE (decl));
  if (DECL_SIZE_UNIT (decl) != 0
      && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST)
    DECL_SIZE_UNIT (decl) = variable_size (DECL_SIZE_UNIT (decl));

  /* If requested, warn about definitions of large data objects.  */
  if (warn_larger_than
      && (code == VAR_DECL || code == PARM_DECL)
      && ! DECL_EXTERNAL (decl))
    {
      tree size = DECL_SIZE_UNIT (decl);

      if (size != 0 && TREE_CODE (size) == INTEGER_CST
	  && compare_tree_int (size, larger_than_size) > 0)
	{
	  int size_as_int = TREE_INT_CST_LOW (size);

	  if (compare_tree_int (size, size_as_int) == 0)
	    warning ("%Jsize of '%D' is %d bytes", decl, decl, size_as_int);
	  else
	    warning ("%Jsize of '%D' is larger than %d bytes",
                     decl, decl, larger_than_size);
	}
    }

  /* If the RTL was already set, update its mode and mem attributes.  */
  if (rtl)
    {
      PUT_MODE (rtl, DECL_MODE (decl));
      SET_DECL_RTL (decl, 0);
      set_mem_attributes (rtl, decl, 1);
      SET_DECL_RTL (decl, rtl);
    }
}

/* Hook for a front-end function that can modify the record layout as needed
   immediately before it is finalized.  */

void (*lang_adjust_rli) (record_layout_info) = 0;

void
set_lang_adjust_rli (void (*f) (record_layout_info))
{
  lang_adjust_rli = f;
}

/* Begin laying out type T, which may be a RECORD_TYPE, UNION_TYPE, or
   QUAL_UNION_TYPE.  Return a pointer to a struct record_layout_info which
   is to be passed to all other layout functions for this record.  It is the
   responsibility of the caller to call `free' for the storage returned.
   Note that garbage collection is not permitted until we finish laying
   out the record.  */

record_layout_info
start_record_layout (tree t)
{
  record_layout_info rli = xmalloc (sizeof (struct record_layout_info_s));

  rli->t = t;

  /* If the type has a minimum specified alignment (via an attribute
     declaration, for example) use it -- otherwise, start with a
     one-byte alignment.  */
  rli->record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (t));
  rli->unpacked_align = rli->record_align;
  rli->offset_align = MAX (rli->record_align, BIGGEST_ALIGNMENT);

#ifdef STRUCTURE_SIZE_BOUNDARY
  /* Packed structures don't need to have minimum size.  */
  if (! TYPE_PACKED (t))
    rli->record_align = MAX (rli->record_align, (unsigned) STRUCTURE_SIZE_BOUNDARY);
#endif

  rli->offset = size_zero_node;
  rli->bitpos = bitsize_zero_node;
  rli->prev_field = 0;
  rli->pending_statics = 0;
  rli->packed_maybe_necessary = 0;

  return rli;
}

/* These four routines perform computations that convert between
   the offset/bitpos forms and byte and bit offsets.  */

tree
bit_from_pos (tree offset, tree bitpos)
{
  return size_binop (PLUS_EXPR, bitpos,
		     size_binop (MULT_EXPR, convert (bitsizetype, offset),
				 bitsize_unit_node));
}

tree
byte_from_pos (tree offset, tree bitpos)
{
  return size_binop (PLUS_EXPR, offset,
		     convert (sizetype,
			      size_binop (TRUNC_DIV_EXPR, bitpos,
					  bitsize_unit_node)));
}

void
pos_from_bit (tree *poffset, tree *pbitpos, unsigned int off_align,
	      tree pos)
{
  *poffset = size_binop (MULT_EXPR,
			 convert (sizetype,
				  size_binop (FLOOR_DIV_EXPR, pos,
					      bitsize_int (off_align))),
			 size_int (off_align / BITS_PER_UNIT));
  *pbitpos = size_binop (FLOOR_MOD_EXPR, pos, bitsize_int (off_align));
}

/* Given a pointer to bit and byte offsets and an offset alignment,
   normalize the offsets so they are within the alignment.  */

void
normalize_offset (tree *poffset, tree *pbitpos, unsigned int off_align)
{
  /* If the bit position is now larger than it should be, adjust it
     downwards.  */
  if (compare_tree_int (*pbitpos, off_align) >= 0)
    {
      tree extra_aligns = size_binop (FLOOR_DIV_EXPR, *pbitpos,
				      bitsize_int (off_align));

      *poffset
	= size_binop (PLUS_EXPR, *poffset,
		      size_binop (MULT_EXPR, convert (sizetype, extra_aligns),
				  size_int (off_align / BITS_PER_UNIT)));

      *pbitpos
	= size_binop (FLOOR_MOD_EXPR, *pbitpos, bitsize_int (off_align));
    }
}

/* Print debugging information about the information in RLI.  */

void
debug_rli (record_layout_info rli)
{
  print_node_brief (stderr, "type", rli->t, 0);
  print_node_brief (stderr, "\noffset", rli->offset, 0);
  print_node_brief (stderr, " bitpos", rli->bitpos, 0);

  fprintf (stderr, "\naligns: rec = %u, unpack = %u, off = %u\n",
	   rli->record_align, rli->unpacked_align,
	   rli->offset_align);
  if (rli->packed_maybe_necessary)
    fprintf (stderr, "packed may be necessary\n");

  if (rli->pending_statics)
    {
      fprintf (stderr, "pending statics:\n");
      debug_tree (rli->pending_statics);
    }
}

/* Given an RLI with a possibly-incremented BITPOS, adjust OFFSET and
   BITPOS if necessary to keep BITPOS below OFFSET_ALIGN.  */

void
normalize_rli (record_layout_info rli)
{
  normalize_offset (&rli->offset, &rli->bitpos, rli->offset_align);
}

/* Returns the size in bytes allocated so far.  */

tree
rli_size_unit_so_far (record_layout_info rli)
{
  return byte_from_pos (rli->offset, rli->bitpos);
}

/* Returns the size in bits allocated so far.  */

tree
rli_size_so_far (record_layout_info rli)
{
  return bit_from_pos (rli->offset, rli->bitpos);
}

/* FIELD is about to be added to RLI->T.  The alignment (in bits) of
   the next available location is given by KNOWN_ALIGN.  Update the
   variable alignment fields in RLI, and return the alignment to give
   the FIELD.  */

static unsigned int
update_alignment_for_field (record_layout_info rli, tree field,
			    unsigned int known_align)
{
  /* The alignment required for FIELD.  */
  unsigned int desired_align;
  /* The type of this field.  */
  tree type = TREE_TYPE (field);
  /* True if the field was explicitly aligned by the user.  */
  bool user_align;
  bool is_bitfield;

  /* Lay out the field so we know what alignment it needs.  */
  layout_decl (field, known_align);
  desired_align = DECL_ALIGN (field);
  user_align = DECL_USER_ALIGN (field);

  is_bitfield = (type != error_mark_node
		 && DECL_BIT_FIELD_TYPE (field)
		 && ! integer_zerop (TYPE_SIZE (type)));

  /* Record must have at least as much alignment as any field.
     Otherwise, the alignment of the field within the record is
     meaningless.  */
  if (is_bitfield && (* targetm.ms_bitfield_layout_p) (rli->t))
    {
      /* Here, the alignment of the underlying type of a bitfield can
	 affect the alignment of a record; even a zero-sized field
	 can do this.  The alignment should be to the alignment of
	 the type, except that for zero-size bitfields this only
	 applies if there was an immediately prior, nonzero-size
	 bitfield.  (That's the way it is, experimentally.) */
      if (! integer_zerop (DECL_SIZE (field))
	  ? ! DECL_PACKED (field)
	  : (rli->prev_field
	     && DECL_BIT_FIELD_TYPE (rli->prev_field)
	     && ! integer_zerop (DECL_SIZE (rli->prev_field))))
	{
	  unsigned int type_align = TYPE_ALIGN (type);
	  type_align = MAX (type_align, desired_align);
	  if (maximum_field_alignment != 0)
	    type_align = MIN (type_align, maximum_field_alignment);
	  rli->record_align = MAX (rli->record_align, type_align);
	  rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
	}
    }
#ifdef PCC_BITFIELD_TYPE_MATTERS
  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)
	{
	  unsigned int type_align = TYPE_ALIGN (type);

#ifdef ADJUST_FIELD_ALIGN
	  if (! TYPE_USER_ALIGN (type))
	    type_align = ADJUST_FIELD_ALIGN (field, type_align);
#endif

	  if (maximum_field_alignment != 0)
	    type_align = MIN (type_align, maximum_field_alignment);
	  else if (DECL_PACKED (field))
	    type_align = MIN (type_align, BITS_PER_UNIT);

	  /* The alignment of the record is increased to the maximum
	     of the current alignment, the alignment indicated on the
	     field (i.e., the alignment specified by an __aligned__
	     attribute), and the alignment indicated by the type of
	     the field.  */
	  rli->record_align = MAX (rli->record_align, desired_align);
	  rli->record_align = MAX (rli->record_align, type_align);

	  if (warn_packed)
	    rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
	  user_align |= TYPE_USER_ALIGN (type);
	}
    }
#endif
  else
    {
      rli->record_align = MAX (rli->record_align, desired_align);
      rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
    }

  TYPE_USER_ALIGN (rli->t) |= user_align;

  return desired_align;
}

/* Called from place_field to handle unions.  */

static void
place_union_field (record_layout_info rli, tree field)
{
  update_alignment_for_field (rli, field, /*known_align=*/0);

  DECL_FIELD_OFFSET (field) = size_zero_node;
  DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
  SET_DECL_OFFSET_ALIGN (field, BIGGEST_ALIGNMENT);

  /* We assume the union's size will be a multiple of a byte so we don't
     bother with BITPOS.  */
  if (TREE_CODE (rli->t) == UNION_TYPE)
    rli->offset = size_binop (MAX_EXPR, rli->offset, DECL_SIZE_UNIT (field));
  else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE)
    rli->offset = fold (build (COND_EXPR, sizetype,
			       DECL_QUALIFIER (field),
			       DECL_SIZE_UNIT (field), rli->offset));
}

#if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
/* A bitfield of SIZE with a required access alignment of ALIGN is allocated
   at BYTE_OFFSET / BIT_OFFSET.  Return nonzero if the field would span more
   units of alignment than the underlying TYPE.  */
static int
excess_unit_span (HOST_WIDE_INT byte_offset, HOST_WIDE_INT bit_offset,
		  HOST_WIDE_INT size, HOST_WIDE_INT align, tree type)
{
  /* Note that the calculation of OFFSET might overflow; we calculate it so
     that we still get the right result as long as ALIGN is a power of two.  */
  unsigned HOST_WIDE_INT offset = byte_offset * BITS_PER_UNIT + bit_offset;

  offset = offset % align;
  return ((offset + size + align - 1) / align
	  > ((unsigned HOST_WIDE_INT) tree_low_cst (TYPE_SIZE (type), 1)
	     / align));
}
#endif

/* RLI contains information about the layout of a RECORD_TYPE.  FIELD
   is a FIELD_DECL to be added after those fields already present in
   T.  (FIELD is not actually added to the TYPE_FIELDS list here;
   callers that desire that behavior must manually perform that step.)  */

void
place_field (record_layout_info rli, tree field)
{
  /* The alignment required for FIELD.  */
  unsigned int desired_align;
  /* The alignment FIELD would have if we just dropped it into the
     record as it presently stands.  */
  unsigned int known_align;
  unsigned int actual_align;
  /* The type of this field.  */
  tree type = TREE_TYPE (field);

  if (TREE_CODE (field) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)
      return;

  /* If FIELD is static, then treat it like a separate variable, not
     really like a structure field.  If it is a FUNCTION_DECL, it's a
     method.  In both cases, all we do is lay out the decl, and we do
     it *after* the record is laid out.  */
  if (TREE_CODE (field) == VAR_DECL)
    {
      rli->pending_statics = tree_cons (NULL_TREE, field,
					rli->pending_statics);
      return;
    }

  /* Enumerators and enum types which are local to this class need not
     be laid out.  Likewise for initialized constant fields.  */
  else if (TREE_CODE (field) != FIELD_DECL)
    return;

  /* Unions are laid out very differently than records, so split
     that code off to another function.  */
  else if (TREE_CODE (rli->t) != RECORD_TYPE)
    {
      place_union_field (rli, field);
      return;
    }

  /* Work out the known alignment so far.  Note that A & (-A) is the
     value of the least-significant bit in A that is one.  */
  if (! integer_zerop (rli->bitpos))
    known_align = (tree_low_cst (rli->bitpos, 1)
		   & - tree_low_cst (rli->bitpos, 1));
  else if (integer_zerop (rli->offset))
    known_align = BIGGEST_ALIGNMENT;
  else if (host_integerp (rli->offset, 1))
    known_align = (BITS_PER_UNIT
		   * (tree_low_cst (rli->offset, 1)
		      & - tree_low_cst (rli->offset, 1)));
  else
    known_align = rli->offset_align;

  desired_align = update_alignment_for_field (rli, field, known_align);

  if (warn_packed && DECL_PACKED (field))
    {
      if (known_align >= TYPE_ALIGN (type))
	{
	  if (TYPE_ALIGN (type) > desired_align)
	    {
	      if (STRICT_ALIGNMENT)
		warning ("%Jpacked attribute causes inefficient alignment "
                         "for '%D'", field, field);
	      else
		warning ("%Jpacked attribute is unnecessary for '%D'",
			 field, field);
	    }
	}
      else
	rli->packed_maybe_necessary = 1;
    }

  /* Does this field automatically have alignment it needs by virtue
     of the fields that precede it and the record's own alignment?  */
  if (known_align < desired_align)
    {
      /* No, we need to skip space before this field.
	 Bump the cumulative size to multiple of field alignment.  */

      if (warn_padded)
	warning ("%Jpadding struct to align '%D'", field, field);

      /* If the alignment is still within offset_align, just align
	 the bit position.  */
      if (desired_align < rli->offset_align)
	rli->bitpos = round_up (rli->bitpos, desired_align);
      else
	{
	  /* First adjust OFFSET by the partial bits, then align.  */
	  rli->offset
	    = size_binop (PLUS_EXPR, rli->offset,
			  convert (sizetype,
				   size_binop (CEIL_DIV_EXPR, rli->bitpos,
					       bitsize_unit_node)));
	  rli->bitpos = bitsize_zero_node;

	  rli->offset = round_up (rli->offset, desired_align / BITS_PER_UNIT);
	}

      if (! TREE_CONSTANT (rli->offset))
	rli->offset_align = desired_align;

    }

  /* Handle compatibility with PCC.  Note that if the record has any
     variable-sized fields, we need not worry about compatibility.  */
#ifdef PCC_BITFIELD_TYPE_MATTERS
  if (PCC_BITFIELD_TYPE_MATTERS
      && ! (* targetm.ms_bitfield_layout_p) (rli->t)
      && TREE_CODE (field) == FIELD_DECL
      && type != error_mark_node
      && DECL_BIT_FIELD (field)
      && ! DECL_PACKED (field)
      && maximum_field_alignment == 0
      && ! integer_zerop (DECL_SIZE (field))
      && host_integerp (DECL_SIZE (field), 1)
      && host_integerp (rli->offset, 1)
      && host_integerp (TYPE_SIZE (type), 1))
    {
      unsigned int type_align = TYPE_ALIGN (type);
      tree dsize = DECL_SIZE (field);
      HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
      HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
      HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);

#ifdef ADJUST_FIELD_ALIGN
      if (! TYPE_USER_ALIGN (type))
	type_align = ADJUST_FIELD_ALIGN (field, type_align);
#endif

      /* A bit field may not span more units of alignment of its type
	 than its type itself.  Advance to next boundary if necessary.  */
      if (excess_unit_span (offset, bit_offset, field_size, type_align, type))
	rli->bitpos = round_up (rli->bitpos, type_align);

      TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
    }
#endif

#ifdef BITFIELD_NBYTES_LIMITED
  if (BITFIELD_NBYTES_LIMITED
      && ! (* targetm.ms_bitfield_layout_p) (rli->t)
      && TREE_CODE (field) == FIELD_DECL
      && type != error_mark_node
      && DECL_BIT_FIELD_TYPE (field)
      && ! DECL_PACKED (field)
      && ! integer_zerop (DECL_SIZE (field))
      && host_integerp (DECL_SIZE (field), 1)
      && host_integerp (rli->offset, 1)
      && host_integerp (TYPE_SIZE (type), 1))
    {
      unsigned int type_align = TYPE_ALIGN (type);
      tree dsize = DECL_SIZE (field);
      HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
      HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
      HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);

#ifdef ADJUST_FIELD_ALIGN
      if (! TYPE_USER_ALIGN (type))
	type_align = ADJUST_FIELD_ALIGN (field, type_align);
#endif

      if (maximum_field_alignment != 0)
	type_align = MIN (type_align, maximum_field_alignment);
      /* ??? This test is opposite the test in the containing if
	 statement, so this code is unreachable currently.  */
      else if (DECL_PACKED (field))
	type_align = MIN (type_align, BITS_PER_UNIT);

      /* A bit field may not span the unit of alignment of its type.
	 Advance to next boundary if necessary.  */
      if (excess_unit_span (offset, bit_offset, field_size, type_align, type))
	rli->bitpos = round_up (rli->bitpos, type_align);

      TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
    }
#endif

  /* See the docs for TARGET_MS_BITFIELD_LAYOUT_P for details.
     A subtlety:
	When a bit field is inserted into a packed record, the whole
	size of the underlying type is used by one or more same-size
	adjacent bitfields.  (That is, if its long:3, 32 bits is
	used in the record, and any additional adjacent long bitfields are
	packed into the same chunk of 32 bits. However, if the size
	changes, a new field of that size is allocated.)  In an unpacked
	record, this is the same as using alignment, but not equivalent
	when packing.

     Note: for compatibility, we use the type size, not the type alignment
     to determine alignment, since that matches the documentation */

  if ((* targetm.ms_bitfield_layout_p) (rli->t)
       && ((DECL_BIT_FIELD_TYPE (field) && ! DECL_PACKED (field))
	  || (rli->prev_field && ! DECL_PACKED (rli->prev_field))))
    {
      /* At this point, either the prior or current are bitfields,
	 (possibly both), and we're dealing with MS packing.  */
      tree prev_saved = rli->prev_field;

      /* Is the prior field a bitfield?  If so, handle "runs" of same
	 type size fields.  */
      if (rli->prev_field /* necessarily a bitfield if it exists.  */)
	{
	  /* If both are bitfields, nonzero, and the same size, this is
	     the middle of a run.  Zero declared size fields are special
	     and handled as "end of run". (Note: it's nonzero declared
	     size, but equal type sizes!) (Since we know that both
	     the current and previous fields are bitfields by the
	     time we check it, DECL_SIZE must be present for both.) */
	  if (DECL_BIT_FIELD_TYPE (field)
	      && !integer_zerop (DECL_SIZE (field))
	      && !integer_zerop (DECL_SIZE (rli->prev_field))
	      && host_integerp (DECL_SIZE (rli->prev_field), 0)
	      && host_integerp (TYPE_SIZE (type), 0)
	      && simple_cst_equal (TYPE_SIZE (type),
				   TYPE_SIZE (TREE_TYPE (rli->prev_field))))
	    {
	      /* We're in the middle of a run of equal type size fields; make
		 sure we realign if we run out of bits.  (Not decl size,
		 type size!) */
	      HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 0);

	      if (rli->remaining_in_alignment < bitsize)
		{
		  /* out of bits; bump up to next 'word'.  */
		  rli->offset = DECL_FIELD_OFFSET (rli->prev_field);
		  rli->bitpos
		    = size_binop (PLUS_EXPR, TYPE_SIZE (type),
				  DECL_FIELD_BIT_OFFSET (rli->prev_field));
		  rli->prev_field = field;
		  rli->remaining_in_alignment
		    = tree_low_cst (TYPE_SIZE (type), 0);
		}

	      rli->remaining_in_alignment -= bitsize;
	    }
	  else
	    {
	      /* End of a run: if leaving a run of bitfields of the same type
		 size, we have to "use up" the rest of the bits of the type
		 size.

		 Compute the new position as the sum of the size for the prior
		 type and where we first started working on that type.
		 Note: since the beginning of the field was aligned then
		 of course the end will be too.  No round needed.  */

	      if (!integer_zerop (DECL_SIZE (rli->prev_field)))
		{
		  tree type_size = TYPE_SIZE (TREE_TYPE (rli->prev_field));

		  rli->bitpos
		    = size_binop (PLUS_EXPR, type_size,
				  DECL_FIELD_BIT_OFFSET (rli->prev_field));
		}
	      else
		/* We "use up" size zero fields; the code below should behave
		   as if the prior field was not a bitfield.  */
		prev_saved = NULL;

	      /* Cause a new bitfield to be captured, either this time (if
		 currently a bitfield) or next time we see one.  */
	      if (!DECL_BIT_FIELD_TYPE(field)
		 || integer_zerop (DECL_SIZE (field)))
		rli->prev_field = NULL;
	    }

	  normalize_rli (rli);
        }

      /* If we're starting a new run of same size type bitfields
	 (or a run of non-bitfields), set up the "first of the run"
	 fields.

	 That is, if the current field is not a bitfield, or if there
	 was a prior bitfield the type sizes differ, or if there wasn't
	 a prior bitfield the size of the current field is nonzero.

	 Note: we must be sure to test ONLY the type size if there was
	 a prior bitfield and ONLY for the current field being zero if
	 there wasn't.  */

      if (!DECL_BIT_FIELD_TYPE (field)
	  || ( prev_saved != NULL
	       ? !simple_cst_equal (TYPE_SIZE (type),
				    TYPE_SIZE (TREE_TYPE (prev_saved)))
	      : !integer_zerop (DECL_SIZE (field)) ))
	{
	  /* Never smaller than a byte for compatibility.  */
	  unsigned int type_align = BITS_PER_UNIT;

	  /* (When not a bitfield), we could be seeing a flex array (with
	     no DECL_SIZE).  Since we won't be using remaining_in_alignment
	     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))
	    rli->remaining_in_alignment
	      = tree_low_cst (TYPE_SIZE (TREE_TYPE(field)), 0)
		- tree_low_cst (DECL_SIZE (field), 0);

	  /* Now align (conventionally) for the new type.  */
	  if (!DECL_PACKED(field))
	    type_align = MAX(TYPE_ALIGN (type), type_align);

	  if (prev_saved
	      && DECL_BIT_FIELD_TYPE (prev_saved)
	      /* If the previous bit-field is zero-sized, we've already
		 accounted for its alignment needs (or ignored it, if
		 appropriate) while placing it.  */
	      && ! integer_zerop (DECL_SIZE (prev_saved)))
	    type_align = MAX (type_align,
			      TYPE_ALIGN (TREE_TYPE (prev_saved)));

	  if (maximum_field_alignment != 0)
	    type_align = MIN (type_align, maximum_field_alignment);

	  rli->bitpos = round_up (rli->bitpos, type_align);

          /* If we really aligned, don't allow subsequent bitfields
	     to undo that.  */
	  rli->prev_field = NULL;
	}
    }

  /* Offset so far becomes the position of this field after normalizing.  */
  normalize_rli (rli);
  DECL_FIELD_OFFSET (field) = rli->offset;
  DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
  SET_DECL_OFFSET_ALIGN (field, rli->offset_align);

  /* If this field ended up more aligned than we thought it would be (we
     approximate this by seeing if its position changed), lay out the field
     again; perhaps we can use an integral mode for it now.  */
  if (! integer_zerop (DECL_FIELD_BIT_OFFSET (field)))
    actual_align = (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
		    & - tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1));
  else if (integer_zerop (DECL_FIELD_OFFSET (field)))
    actual_align = BIGGEST_ALIGNMENT;
  else if (host_integerp (DECL_FIELD_OFFSET (field), 1))
    actual_align = (BITS_PER_UNIT
		   * (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
		      & - tree_low_cst (DECL_FIELD_OFFSET (field), 1)));
  else
    actual_align = DECL_OFFSET_ALIGN (field);

  if (known_align != actual_align)
    layout_decl (field, actual_align);

  /* Only the MS bitfields use this.  */
  if (rli->prev_field == NULL && DECL_BIT_FIELD_TYPE(field))
      rli->prev_field = field;

  /* Now add size of this field to the size of the record.  If the size is
     not constant, treat the field as being a multiple of bytes and just
     adjust the offset, resetting the bit position.  Otherwise, apportion the
     size amongst the bit position and offset.  First handle the case of an
     unspecified size, which can happen when we have an invalid nested struct
     definition, such as struct j { struct j { int i; } }.  The error message
     is printed in finish_struct.  */
  if (DECL_SIZE (field) == 0)
    /* Do nothing.  */;
  else if (TREE_CODE (DECL_SIZE_UNIT (field)) != INTEGER_CST
	   || TREE_CONSTANT_OVERFLOW (DECL_SIZE_UNIT (field)))
    {
      rli->offset
	= size_binop (PLUS_EXPR, rli->offset,
		      convert (sizetype,
			       size_binop (CEIL_DIV_EXPR, rli->bitpos,
					   bitsize_unit_node)));
      rli->offset
	= size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field));
      rli->bitpos = bitsize_zero_node;
      rli->offset_align = MIN (rli->offset_align, desired_align);
    }
  else
    {
      rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field));
      normalize_rli (rli);
    }
}

/* Assuming that all the fields have been laid out, this function uses
   RLI to compute the final TYPE_SIZE, TYPE_ALIGN, etc. for the type
   indicated by RLI.  */

static void
finalize_record_size (record_layout_info rli)
{
  tree unpadded_size, unpadded_size_unit;

  /* Now we want just byte and bit offsets, so set the offset alignment
     to be a byte and then normalize.  */
  rli->offset_align = BITS_PER_UNIT;
  normalize_rli (rli);

  /* Determine the desired alignment.  */
#ifdef ROUND_TYPE_ALIGN
  TYPE_ALIGN (rli->t) = ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t),
					  rli->record_align);
#else
  TYPE_ALIGN (rli->t) = MAX (TYPE_ALIGN (rli->t), rli->record_align);
#endif

  /* Compute the size so far.  Be sure to allow for extra bits in the
     size in bytes.  We have guaranteed above that it will be no more
     than a single byte.  */
  unpadded_size = rli_size_so_far (rli);
  unpadded_size_unit = rli_size_unit_so_far (rli);
  if (! integer_zerop (rli->bitpos))
    unpadded_size_unit
      = size_binop (PLUS_EXPR, unpadded_size_unit, size_one_node);

  /* Round the size up to be a multiple of the required alignment.  */
  TYPE_SIZE (rli->t) = round_up (unpadded_size, TYPE_ALIGN (rli->t));
  TYPE_SIZE_UNIT (rli->t) = round_up (unpadded_size_unit,
				      TYPE_ALIGN (rli->t) / BITS_PER_UNIT);

  if (warn_padded && TREE_CONSTANT (unpadded_size)
      && simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0)
    warning ("padding struct size to alignment boundary");

  if (warn_packed && TREE_CODE (rli->t) == RECORD_TYPE
      && TYPE_PACKED (rli->t) && ! rli->packed_maybe_necessary
      && TREE_CONSTANT (unpadded_size))
    {
      tree unpacked_size;

#ifdef ROUND_TYPE_ALIGN
      rli->unpacked_align
	= ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t), rli->unpacked_align);
#else
      rli->unpacked_align = MAX (TYPE_ALIGN (rli->t), rli->unpacked_align);
#endif

      unpacked_size = round_up (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))
	    {
	      const char *name;

	      if (TREE_CODE (TYPE_NAME (rli->t)) == IDENTIFIER_NODE)
		name = IDENTIFIER_POINTER (TYPE_NAME (rli->t));
	      else
		name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (rli->t)));

	      if (STRICT_ALIGNMENT)
		warning ("packed attribute causes inefficient alignment for `%s'", name);
	      else
		warning ("packed attribute is unnecessary for `%s'", name);
	    }
	  else
	    {
	      if (STRICT_ALIGNMENT)
		warning ("packed attribute causes inefficient alignment");
	      else
		warning ("packed attribute is unnecessary");
	    }
	}
    }
}

/* Compute the TYPE_MODE for the TYPE (which is a RECORD_TYPE).  */

void
compute_record_mode (tree type)
{
  tree field;
  enum machine_mode mode = VOIDmode;

  /* Most RECORD_TYPEs have BLKmode, so we start off assuming that.
     However, if possible, we use a mode that fits in a register
     instead, in order to allow for better optimization down the
     line.  */
  TYPE_MODE (type) = BLKmode;

  if (! host_integerp (TYPE_SIZE (type), 1))
    return;

  /* A record which has any BLKmode members must itself be
     BLKmode; it can't go in a register.  Unless the member is
     BLKmode only because it isn't aligned.  */
  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
    {
      if (TREE_CODE (field) != FIELD_DECL)
	continue;

      if (TREE_CODE (TREE_TYPE (field)) == ERROR_MARK
	  || (TYPE_MODE (TREE_TYPE (field)) == BLKmode
	      && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field))
	      && !(TYPE_SIZE (TREE_TYPE (field)) != 0
		   && integer_zerop (TYPE_SIZE (TREE_TYPE (field)))))
	  || ! host_integerp (bit_position (field), 1)
	  || DECL_SIZE (field) == 0
	  || ! host_integerp (DECL_SIZE (field), 1))
	return;

      /* If this field is the whole struct, remember its mode so
	 that, say, we can put a double in a class into a DF
	 register instead of forcing it to live in the stack.  */
      if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field)))
	mode = DECL_MODE (field);

#ifdef MEMBER_TYPE_FORCES_BLK
      /* With some targets, eg. c4x, it is sub-optimal
	 to access an aligned BLKmode structure as a scalar.  */

      if (MEMBER_TYPE_FORCES_BLK (field, mode))
	return;
#endif /* MEMBER_TYPE_FORCES_BLK  */
    }

  /* If we only have one real field; use its mode.  This only applies to
     RECORD_TYPE.  This does not apply to unions.  */
  if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode)
    TYPE_MODE (type) = mode;
  else
    TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);

  /* If structure's known alignment is less than what the scalar
     mode would need, and it matters, then stick with BLKmode.  */
  if (TYPE_MODE (type) != BLKmode
      && STRICT_ALIGNMENT
      && ! (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
	    || TYPE_ALIGN (type) >= GET_MODE_ALIGNMENT (TYPE_MODE (type))))
    {
      /* If this is the only reason this type is BLKmode, then
	 don't force containing types to be BLKmode.  */
      TYPE_NO_FORCE_BLK (type) = 1;
      TYPE_MODE (type) = BLKmode;
    }
}

/* Compute TYPE_SIZE and TYPE_ALIGN for TYPE, once it has been laid
   out.  */

static void
finalize_type_size (tree type)
{
  /* Normally, use the alignment corresponding to the mode chosen.
     However, where strict alignment is not required, avoid
     over-aligning structures, since most compilers do not do this
     alignment.  */

  if (TYPE_MODE (type) != BLKmode && TYPE_MODE (type) != VOIDmode
      && (STRICT_ALIGNMENT
	  || (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE
	      && TREE_CODE (type) != QUAL_UNION_TYPE
	      && TREE_CODE (type) != ARRAY_TYPE)))
    {
      TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type));
      TYPE_USER_ALIGN (type) = 0;
    }

  /* Do machine-dependent extra alignment.  */
#ifdef ROUND_TYPE_ALIGN
  TYPE_ALIGN (type)
    = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (type), BITS_PER_UNIT);
#endif

  /* If we failed to find a simple way to calculate the unit size
     of the type, find it by division.  */
  if (TYPE_SIZE_UNIT (type) == 0 && TYPE_SIZE (type) != 0)
    /* TYPE_SIZE (type) is computed in bitsizetype.  After the division, the
       result will fit in sizetype.  We will get more efficient code using
       sizetype, so we force a conversion.  */
    TYPE_SIZE_UNIT (type)
      = convert (sizetype,
		 size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (type),
			     bitsize_unit_node));

  if (TYPE_SIZE (type) != 0)
    {
      TYPE_SIZE (type) = round_up (TYPE_SIZE (type), TYPE_ALIGN (type));
      TYPE_SIZE_UNIT (type)
	= round_up (TYPE_SIZE_UNIT (type), TYPE_ALIGN (type) / BITS_PER_UNIT);
    }

  /* Evaluate nonconstant sizes only once, either now or as soon as safe.  */
  if (TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
    TYPE_SIZE (type) = variable_size (TYPE_SIZE (type));
  if (TYPE_SIZE_UNIT (type) != 0
      && TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
    TYPE_SIZE_UNIT (type) = variable_size (TYPE_SIZE_UNIT (type));

  /* Also layout any other variants of the type.  */
  if (TYPE_NEXT_VARIANT (type)
      || type != TYPE_MAIN_VARIANT (type))
    {
      tree variant;
      /* Record layout info of this variant.  */
      tree size = TYPE_SIZE (type);
      tree size_unit = TYPE_SIZE_UNIT (type);
      unsigned int align = TYPE_ALIGN (type);
      unsigned int user_align = TYPE_USER_ALIGN (type);
      enum machine_mode mode = TYPE_MODE (type);

      /* Copy it into all variants.  */
      for (variant = TYPE_MAIN_VARIANT (type);
	   variant != 0;
	   variant = TYPE_NEXT_VARIANT (variant))
	{
	  TYPE_SIZE (variant) = size;
	  TYPE_SIZE_UNIT (variant) = size_unit;
	  TYPE_ALIGN (variant) = align;
	  TYPE_USER_ALIGN (variant) = user_align;
	  TYPE_MODE (variant) = mode;
	}
    }
}

/* Do all of the work required to layout the type indicated by RLI,
   once the fields have been laid out.  This function will call `free'
   for RLI, unless FREE_P is false.  Passing a value other than false
   for FREE_P is bad practice; this option only exists to support the
   G++ 3.2 ABI.  */

void
finish_record_layout (record_layout_info rli, int free_p)
{
  /* Compute the final size.  */
  finalize_record_size (rli);

  /* Compute the TYPE_MODE for the record.  */
  compute_record_mode (rli->t);

  /* Perform any last tweaks to the TYPE_SIZE, etc.  */
  finalize_type_size (rli->t);

  /* Lay out any static members.  This is done now because their type
     may use the record's type.  */
  while (rli->pending_statics)
    {
      layout_decl (TREE_VALUE (rli->pending_statics), 0);
      rli->pending_statics = TREE_CHAIN (rli->pending_statics);
    }

  /* Clean up.  */
  if (free_p)
    free (rli);
}


/* Finish processing a builtin RECORD_TYPE type TYPE.  It's name is
   NAME, its fields are chained in reverse on FIELDS.

   If ALIGN_TYPE is non-null, it is given the same alignment as
   ALIGN_TYPE.  */

void
finish_builtin_struct (tree type, const char *name, tree fields,
		       tree align_type)
{
  tree tail, next;

  for (tail = NULL_TREE; fields; tail = fields, fields = next)
    {
      DECL_FIELD_CONTEXT (fields) = type;
      next = TREE_CHAIN (fields);
      TREE_CHAIN (fields) = tail;
    }
  TYPE_FIELDS (type) = tail;

  if (align_type)
    {
      TYPE_ALIGN (type) = TYPE_ALIGN (align_type);
      TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (align_type);
    }

  layout_type (type);
#if 0 /* not yet, should get fixed properly later */
  TYPE_NAME (type) = make_type_decl (get_identifier (name), type);
#else
  TYPE_NAME (type) = build_decl (TYPE_DECL, get_identifier (name), type);
#endif
  TYPE_STUB_DECL (type) = TYPE_NAME (type);
  layout_decl (TYPE_NAME (type), 0);
}

/* Calculate the mode, size, and alignment for TYPE.
   For an array type, calculate the element separation as well.
   Record TYPE on the chain of permanent or temporary types
   so that dbxout will find out about it.

   TYPE_SIZE of a type is nonzero if the type has been laid out already.
   layout_type does nothing on such a type.

   If the type is incomplete, its TYPE_SIZE remains zero.  */

void
layout_type (tree type)
{
  if (type == 0)
    abort ();

  /* Do nothing if type has been laid out before.  */
  if (TYPE_SIZE (type))
    return;

  switch (TREE_CODE (type))
    {
    case LANG_TYPE:
      /* This kind of type is the responsibility
	 of the language-specific code.  */
      abort ();

    case BOOLEAN_TYPE:  /* Used for Java, Pascal, and Chill.  */
      if (TYPE_PRECISION (type) == 0)
	TYPE_PRECISION (type) = 1; /* default to one byte/boolean.  */

      /* ... fall through ...  */

    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
    case CHAR_TYPE:
      if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
	  && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0)
	TREE_UNSIGNED (type) = 1;

      TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type),
						 MODE_INT);
      TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
      TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
      break;

    case REAL_TYPE:
      TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0);
      TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
      TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
      break;

    case COMPLEX_TYPE:
      TREE_UNSIGNED (type) = TREE_UNSIGNED (TREE_TYPE (type));
      TYPE_MODE (type)
	= mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)),
			 (TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
			  ? MODE_COMPLEX_INT : MODE_COMPLEX_FLOAT),
			 0);
      TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
      TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
      break;

    case VECTOR_TYPE:
      {
	tree subtype;

	subtype = TREE_TYPE (type);
	TREE_UNSIGNED (type) = TREE_UNSIGNED (subtype);
	TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
	TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
      }
      break;

    case VOID_TYPE:
      /* This is an incomplete type and so doesn't have a size.  */
      TYPE_ALIGN (type) = 1;
      TYPE_USER_ALIGN (type) = 0;
      TYPE_MODE (type) = VOIDmode;
      break;

    case OFFSET_TYPE:
      TYPE_SIZE (type) = bitsize_int (POINTER_SIZE);
      TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
      /* A pointer might be MODE_PARTIAL_INT,
	 but ptrdiff_t must be integral.  */
      TYPE_MODE (type) = mode_for_size (POINTER_SIZE, MODE_INT, 0);
      break;

    case FUNCTION_TYPE:
    case METHOD_TYPE:
      TYPE_MODE (type) = mode_for_size (2 * POINTER_SIZE, MODE_INT, 0);
      TYPE_SIZE (type) = bitsize_int (2 * POINTER_SIZE);
      TYPE_SIZE_UNIT (type) = size_int ((2 * POINTER_SIZE) / BITS_PER_UNIT);
      break;

    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);

	TYPE_SIZE (type) = bitsize_int (nbits);
	TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
	TREE_UNSIGNED (type) = 1;
	TYPE_PRECISION (type) = nbits;
      }
      break;

    case ARRAY_TYPE:
      {
	tree index = TYPE_DOMAIN (type);
	tree element = TREE_TYPE (type);

	build_pointer_type (element);

	/* We need to know both bounds in order to compute the size.  */
	if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
	    && TYPE_SIZE (element))
	  {
	    tree ub = TYPE_MAX_VALUE (index);
	    tree lb = TYPE_MIN_VALUE (index);
	    tree length;
	    tree element_size;

	    /* 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,
				 convert (sizetype,
					  fold (build (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 (! TREE_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);

	    TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
					   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))
	      TYPE_SIZE_UNIT (type)
		= size_binop (MULT_EXPR, TYPE_SIZE_UNIT (element), length);
	  }

	/* Now round the alignment and size,
	   using machine-dependent criteria if any.  */

#ifdef ROUND_TYPE_ALIGN
	TYPE_ALIGN (type)
	  = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (element), BITS_PER_UNIT);
#else
	TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);
#endif
	TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
	TYPE_MODE (type) = BLKmode;
	if (TYPE_SIZE (type) != 0
#ifdef MEMBER_TYPE_FORCES_BLK
	    && ! MEMBER_TYPE_FORCES_BLK (type, VOIDmode)
#endif
	    /* BLKmode elements force BLKmode aggregate;
	       else extract/store fields may lose.  */
	    && (TYPE_MODE (TREE_TYPE (type)) != BLKmode
		|| TYPE_NO_FORCE_BLK (TREE_TYPE (type))))
	  {
	    /* One-element arrays get the component type's mode.  */
	    if (simple_cst_equal (TYPE_SIZE (type),
				  TYPE_SIZE (TREE_TYPE (type))))
	      TYPE_MODE (type) = TYPE_MODE (TREE_TYPE (type));
	    else
	      TYPE_MODE (type)
		= mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);

	    if (TYPE_MODE (type) != BLKmode
		&& STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
		&& TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type))
		&& TYPE_MODE (type) != BLKmode)
	      {
		TYPE_NO_FORCE_BLK (type) = 1;
		TYPE_MODE (type) = BLKmode;
	      }
	  }
	break;
      }

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      {
	tree field;
	record_layout_info rli;

	/* Initialize the layout information.  */
	rli = start_record_layout (type);

	/* If this is a QUAL_UNION_TYPE, we want to process the fields
	   in the reverse order in building the COND_EXPR that denotes
	   its size.  We reverse them again later.  */
	if (TREE_CODE (type) == QUAL_UNION_TYPE)
	  TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));

	/* Place all the fields.  */
	for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
	  place_field (rli, field);

	if (TREE_CODE (type) == QUAL_UNION_TYPE)
	  TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));

	if (lang_adjust_rli)
	  (*lang_adjust_rli) (rli);

	/* Finish laying out the record.  */
	finish_record_layout (rli, /*free_p=*/true);
      }
      break;

    case SET_TYPE:  /* Used by Chill and Pascal.  */
      if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) != INTEGER_CST
	  || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) != INTEGER_CST)
	abort ();
      else
	{
#ifndef SET_WORD_SIZE
#define SET_WORD_SIZE BITS_PER_WORD
#endif
	  unsigned int alignment
	    = set_alignment ? set_alignment : SET_WORD_SIZE;
	  HOST_WIDE_INT size_in_bits
	    = (tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
	       - tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0) + 1);
	  HOST_WIDE_INT rounded_size
	    = ((size_in_bits + alignment - 1) / alignment) * alignment;

	  if (rounded_size > (int) alignment)
	    TYPE_MODE (type) = BLKmode;
	  else
	    TYPE_MODE (type) = mode_for_size (alignment, MODE_INT, 1);

	  TYPE_SIZE (type) = bitsize_int (rounded_size);
	  TYPE_SIZE_UNIT (type) = size_int (rounded_size / BITS_PER_UNIT);
	  TYPE_ALIGN (type) = alignment;
	  TYPE_USER_ALIGN (type) = 0;
	  TYPE_PRECISION (type) = size_in_bits;
	}
      break;

    case FILE_TYPE:
      /* The size may vary in different languages, so the language front end
	 should fill in the size.  */
      TYPE_ALIGN (type) = BIGGEST_ALIGNMENT;
      TYPE_USER_ALIGN (type) = 0;
      TYPE_MODE  (type) = BLKmode;
      break;

    default:
      abort ();
    }

  /* Compute the final TYPE_SIZE, TYPE_ALIGN, etc. for TYPE.  For
     records and unions, finish_record_layout already called this
     function.  */
  if (TREE_CODE (type) != RECORD_TYPE
      && TREE_CODE (type) != UNION_TYPE
      && TREE_CODE (type) != QUAL_UNION_TYPE)
    finalize_type_size (type);

  /* If this type is created before sizetype has been permanently set,
     record it so set_sizetype can fix it up.  */
  if (! sizetype_set)
    early_type_list = tree_cons (NULL_TREE, type, early_type_list);

  /* If an alias set has been set for this aggregate when it was incomplete,
     force it into alias set 0.
     This is too conservative, but we cannot call record_component_aliases
     here because some frontends still change the aggregates after
     layout_type.  */
  if (AGGREGATE_TYPE_P (type) && TYPE_ALIAS_SET_KNOWN_P (type))
    TYPE_ALIAS_SET (type) = 0;
}

/* Create and return a type for signed integers of PRECISION bits.  */

tree
make_signed_type (int precision)
{
  tree type = make_node (INTEGER_TYPE);

  TYPE_PRECISION (type) = precision;

  fixup_signed_type (type);
  return type;
}

/* Create and return a type for unsigned integers of PRECISION bits.  */

tree
make_unsigned_type (int precision)
{
  tree type = make_node (INTEGER_TYPE);

  TYPE_PRECISION (type) = precision;

  fixup_unsigned_type (type);
  return type;
}

/* Initialize sizetype and bitsizetype to a reasonable and temporary
   value to enable integer types to be created.  */

void
initialize_sizetypes (void)
{
  tree t = make_node (INTEGER_TYPE);

  /* Set this so we do something reasonable for the build_int_2 calls
     below.  */
  integer_type_node = t;

  TYPE_MODE (t) = SImode;
  TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode);
  TYPE_USER_ALIGN (t) = 0;
  TYPE_SIZE (t) = build_int_2 (GET_MODE_BITSIZE (SImode), 0);
  TYPE_SIZE_UNIT (t) = build_int_2 (GET_MODE_SIZE (SImode), 0);
  TREE_UNSIGNED (t) = 1;
  TYPE_PRECISION (t) = GET_MODE_BITSIZE (SImode);
  TYPE_MIN_VALUE (t) = build_int_2 (0, 0);
  TYPE_IS_SIZETYPE (t) = 1;

  /* 1000 avoids problems with possible overflow and is certainly
     larger than any size value we'd want to be storing.  */
  TYPE_MAX_VALUE (t) = build_int_2 (1000, 0);

  /* These two must be different nodes because of the caching done in
     size_int_wide.  */
  sizetype = t;
  bitsizetype = copy_node (t);
  integer_type_node = 0;
}

/* Set sizetype to TYPE, and initialize *sizetype accordingly.
   Also update the type of any standard type's sizes made so far.  */

void
set_sizetype (tree type)
{
  int oprecision = TYPE_PRECISION (type);
  /* The *bitsizetype types use a precision that avoids overflows when
     calculating signed sizes / offsets in bits.  However, when
     cross-compiling from a 32 bit to a 64 bit host, we are limited to 64 bit
     precision.  */
  int precision = MIN (oprecision + BITS_PER_UNIT_LOG + 1,
		       2 * HOST_BITS_PER_WIDE_INT);
  unsigned int i;
  tree t;

  if (sizetype_set)
    abort ();

  /* Make copies of nodes since we'll be setting TYPE_IS_SIZETYPE.  */
  sizetype = copy_node (type);
  TYPE_DOMAIN (sizetype) = type;
  TYPE_IS_SIZETYPE (sizetype) = 1;
  bitsizetype = make_node (INTEGER_TYPE);
  TYPE_NAME (bitsizetype) = TYPE_NAME (type);
  TYPE_PRECISION (bitsizetype) = precision;
  TYPE_IS_SIZETYPE (bitsizetype) = 1;

  if (TREE_UNSIGNED (type))
    fixup_unsigned_type (bitsizetype);
  else
    fixup_signed_type (bitsizetype);

  layout_type (bitsizetype);

  if (TREE_UNSIGNED (type))
    {
      usizetype = sizetype;
      ubitsizetype = bitsizetype;
      ssizetype = copy_node (make_signed_type (oprecision));
      sbitsizetype = copy_node (make_signed_type (precision));
    }
  else
    {
      ssizetype = sizetype;
      sbitsizetype = bitsizetype;
      usizetype = copy_node (make_unsigned_type (oprecision));
      ubitsizetype = copy_node (make_unsigned_type (precision));
    }

  TYPE_NAME (bitsizetype) = get_identifier ("bit_size_type");

  /* Show is a sizetype, is a main type, and has no pointers to it.  */
  for (i = 0; i < ARRAY_SIZE (sizetype_tab); i++)
    {
      TYPE_IS_SIZETYPE (sizetype_tab[i]) = 1;
      TYPE_MAIN_VARIANT (sizetype_tab[i]) = sizetype_tab[i];
      TYPE_NEXT_VARIANT (sizetype_tab[i]) = 0;
      TYPE_POINTER_TO (sizetype_tab[i]) = 0;
      TYPE_REFERENCE_TO (sizetype_tab[i]) = 0;
    }

  /* Go down each of the types we already made and set the proper type
     for the sizes in them.  */
  for (t = early_type_list; t != 0; t = TREE_CHAIN (t))
    {
      if (TREE_CODE (TREE_VALUE (t)) != INTEGER_TYPE
	  && TREE_CODE (TREE_VALUE (t)) != BOOLEAN_TYPE)
	abort ();

      TREE_TYPE (TYPE_SIZE (TREE_VALUE (t))) = bitsizetype;
      TREE_TYPE (TYPE_SIZE_UNIT (TREE_VALUE (t))) = sizetype;
    }

  early_type_list = 0;
  sizetype_set = 1;
}

/* TYPE is an integral type, i.e., an INTEGRAL_TYPE, ENUMERAL_TYPE,
   BOOLEAN_TYPE, or CHAR_TYPE.  Set TYPE_MIN_VALUE and TYPE_MAX_VALUE
   for TYPE, based on the PRECISION and whether or not the TYPE
   IS_UNSIGNED.  PRECISION need not correspond to a width supported
   natively by the hardware; for example, on a machine with 8-bit,
   16-bit, and 32-bit register modes, PRECISION might be 7, 23, or
   61.  */

void
set_min_and_max_values_for_integral_type (tree type,
					  int precision,
					  bool is_unsigned)
{
  tree min_value;
  tree max_value;

  if (is_unsigned)
    {
      min_value = build_int_2 (0, 0);
      max_value 
	= build_int_2 (precision - HOST_BITS_PER_WIDE_INT >= 0
		       ? -1 : ((HOST_WIDE_INT) 1 << precision) - 1,
		       precision - HOST_BITS_PER_WIDE_INT > 0
		       ? ((unsigned HOST_WIDE_INT) ~0
			  >> (HOST_BITS_PER_WIDE_INT
			      - (precision - HOST_BITS_PER_WIDE_INT)))
		       : 0);
    }
  else
    {
      min_value 
	= build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
			? 0 : (HOST_WIDE_INT) (-1) << (precision - 1)),
		       (((HOST_WIDE_INT) (-1)
			 << (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
			     ? precision - HOST_BITS_PER_WIDE_INT - 1
			     : 0))));    
      max_value
	= build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
			? -1 : ((HOST_WIDE_INT) 1 << (precision - 1)) - 1),
		       (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
			? (((HOST_WIDE_INT) 1
			    << (precision - HOST_BITS_PER_WIDE_INT - 1))) - 1
			: 0));
    }

  TREE_TYPE (min_value) = type;
  TREE_TYPE (max_value) = type;
  TYPE_MIN_VALUE (type) = min_value;
  TYPE_MAX_VALUE (type) = max_value;
}

/* Set the extreme values of TYPE based on its precision in bits,
   then lay it out.  Used when make_signed_type won't do
   because the tree code is not INTEGER_TYPE.
   E.g. for Pascal, when the -fsigned-char option is given.  */

void
fixup_signed_type (tree type)
{
  int precision = TYPE_PRECISION (type);

  /* We can not represent properly constants greater then
     2 * HOST_BITS_PER_WIDE_INT, still we need the types
     as they are used by i386 vector extensions and friends.  */
  if (precision > HOST_BITS_PER_WIDE_INT * 2)
    precision = HOST_BITS_PER_WIDE_INT * 2;

  set_min_and_max_values_for_integral_type (type, precision, 
					    /*is_unsigned=*/false);

  /* Lay out the type: set its alignment, size, etc.  */
  layout_type (type);
}

/* Set the extreme values of TYPE based on its precision in bits,
   then lay it out.  This is used both in `make_unsigned_type'
   and for enumeral types.  */

void
fixup_unsigned_type (tree type)
{
  int precision = TYPE_PRECISION (type);

  /* We can not represent properly constants greater then
     2 * HOST_BITS_PER_WIDE_INT, still we need the types
     as they are used by i386 vector extensions and friends.  */
  if (precision > HOST_BITS_PER_WIDE_INT * 2)
    precision = HOST_BITS_PER_WIDE_INT * 2;

  set_min_and_max_values_for_integral_type (type, precision, 
					    /*is_unsigned=*/true);

  /* Lay out the type: set its alignment, size, etc.  */
  layout_type (type);
}

/* Find the best machine mode to use when referencing a bit field of length
   BITSIZE bits starting at BITPOS.

   The underlying object is known to be aligned to a boundary of ALIGN bits.
   If LARGEST_MODE is not VOIDmode, it means that we should not use a mode
   larger than LARGEST_MODE (usually SImode).

   If no mode meets all these conditions, we return VOIDmode.  Otherwise, if
   VOLATILEP is true or SLOW_BYTE_ACCESS is false, we return the smallest
   mode meeting these conditions.

   Otherwise (VOLATILEP is false and SLOW_BYTE_ACCESS is true), we return
   the largest mode (but a mode no wider than UNITS_PER_WORD) that meets
   all the conditions.  */

enum machine_mode
get_best_mode (int bitsize, int bitpos, unsigned int align,
	       enum machine_mode largest_mode, int volatilep)
{
  enum machine_mode mode;
  unsigned int unit = 0;

  /* Find the narrowest integer mode that contains the bit field.  */
  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
       mode = GET_MODE_WIDER_MODE (mode))
    {
      unit = GET_MODE_BITSIZE (mode);
      if ((bitpos % unit) + bitsize <= unit)
	break;
    }

  if (mode == VOIDmode
      /* It is tempting to omit the following line
	 if STRICT_ALIGNMENT is true.
	 But that is incorrect, since if the bitfield uses part of 3 bytes
	 and we use a 4-byte mode, we could get a spurious segv
	 if the extra 4th byte is past the end of memory.
	 (Though at least one Unix compiler ignores this problem:
	 that on the Sequent 386 machine.  */
      || MIN (unit, BIGGEST_ALIGNMENT) > align
      || (largest_mode != VOIDmode && unit > GET_MODE_BITSIZE (largest_mode)))
    return VOIDmode;

  if (SLOW_BYTE_ACCESS && ! volatilep)
    {
      enum machine_mode wide_mode = VOIDmode, tmode;

      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); tmode != VOIDmode;
	   tmode = GET_MODE_WIDER_MODE (tmode))
	{
	  unit = GET_MODE_BITSIZE (tmode);
	  if (bitpos / unit == (bitpos + bitsize - 1) / unit
	      && unit <= BITS_PER_WORD
	      && unit <= MIN (align, BIGGEST_ALIGNMENT)
	      && (largest_mode == VOIDmode
		  || unit <= GET_MODE_BITSIZE (largest_mode)))
	    wide_mode = tmode;
	}

      if (wide_mode != VOIDmode)
	return wide_mode;
    }

  return mode;
}

#include "gt-stor-layout.h"
