/****************************************************************************
 *                                                                          *
 *                         GNAT COMPILER COMPONENTS                         *
 *                                                                          *
 *                                U T I L S                                 *
 *                                                                          *
 *                          C Implementation File                           *
 *                                                                          *
 *                            $Revision: 1.8 $
 *                                                                          *
 *          Copyright (C) 1992-2001, Free Software Foundation, Inc.         *
 *                                                                          *
 * GNAT is free software;  you can  redistribute it  and/or modify it under *
 * terms of the  GNU General Public License as published  by the Free Soft- *
 * ware  Foundation;  either version 2,  or (at your option) any later ver- *
 * sion.  GNAT is distributed in the hope that it will be useful, but WITH- *
 * OUT 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  distributed with GNAT;  see file COPYING.  If not, write *
 * to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, *
 * MA 02111-1307, USA.                                                      *
 *                                                                          *
 * GNAT was originally developed  by the GNAT team at  New York University. *
 * It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). *
 *                                                                          *
 ****************************************************************************/

#include "config.h"
#include "system.h"
#include "tree.h"
#include "flags.h"
#include "defaults.h"
#include "toplev.h"
#include "output.h"
#include "ggc.h"
#include "convert.h"

#include "ada.h"
#include "types.h"
#include "atree.h"
#include "elists.h"
#include "namet.h"
#include "nlists.h"
#include "stringt.h"
#include "uintp.h"
#include "fe.h"
#include "sinfo.h"
#include "einfo.h"
#include "ada-tree.h"
#include "gigi.h"

#ifndef MAX_FIXED_MODE_SIZE
#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode)
#endif

#ifndef MAX_BITS_PER_WORD
#define MAX_BITS_PER_WORD  BITS_PER_WORD
#endif

/* If nonzero, pretend we are allocating at global level.  */
int force_global;

/* Global Variables for the various types we create.  */ 
tree gnat_std_decls[(int) ADT_LAST];

/* Associates a GNAT tree node to a GCC tree node. It is used in
   `save_gnu_tree', `get_gnu_tree' and `present_gnu_tree'. See documentation
   of `save_gnu_tree' for more info.  */
static tree *associate_gnat_to_gnu;

/* This listhead is used to record any global objects that need elaboration.
   TREE_PURPOSE is the variable to be elaborated and TREE_VALUE is the
   initial value to assign.  */

static tree pending_elaborations;

/* This stack allows us to momentarily switch to generating elaboration
   lists for an inner context.  */

static struct e_stack {struct e_stack *next; tree elab_list; } *elist_stack;

/* This variable keeps a table for types for each precision so that we only 
   allocate each of them once. Signed and unsigned types are kept separate.

   Note that these types are only used when fold-const requests something
   special.  Perhaps we should NOT share these types; we'll see how it
   goes later.  */
static tree signed_and_unsigned_types[2 * MAX_BITS_PER_WORD + 1][2];

/* Likewise for float types, but record these by mode.  */
static tree float_types[NUM_MACHINE_MODES];

/* For each binding contour we allocate a binding_level structure which records
   the entities defined or declared in that contour. Contours include:

	the global one
	one for each subprogram definition
	one for each compound statement (declare block)

   Binding contours are used to create GCC tree BLOCK nodes.  */

struct binding_level
{
  /* A chain of ..._DECL nodes for all variables, constants, functions,
     parameters and type declarations.  These ..._DECL nodes are chained
     through the TREE_CHAIN field. Note that these ..._DECL nodes are stored
     in the reverse of the order supplied to be compatible with the
     back-end.  */
  tree names;
  /* For each level (except the global one), a chain of BLOCK nodes for all
     the levels that were entered and exited one level down from this one.  */
  tree blocks;
  /* The BLOCK node for this level, if one has been preallocated.
     If 0, the BLOCK is allocated (if needed) when the level is popped.  */
  tree this_block;
  /* The binding level containing this one (the enclosing binding level). */
  struct binding_level *level_chain;
};

/* The binding level currently in effect.  */
static struct binding_level *current_binding_level = NULL;

/* A chain of binding_level structures awaiting reuse.  */
static struct binding_level *free_binding_level = NULL;

/* The outermost binding level. This binding level is created when the
   compiler is started and it will exist through the entire compilation.  */
static struct binding_level *global_binding_level;

/* Binding level structures are initialized by copying this one.  */
static struct binding_level clear_binding_level = {NULL, NULL, NULL, NULL};


static tree merge_sizes			PARAMS ((tree, tree, tree, int, int));
static tree compute_related_constant	PARAMS ((tree, tree));
static tree split_plus			PARAMS ((tree, tree *));
static int value_zerop			PARAMS ((tree));
static tree float_type_for_size		PARAMS ((int, enum machine_mode));
static tree convert_to_fat_pointer	PARAMS ((tree, tree));
static tree convert_to_thin_pointer	PARAMS ((tree, tree));
static tree make_descriptor_field	PARAMS ((const char *,tree, tree,
						 tree));
static void mark_binding_level		PARAMS((PTR));
static void mark_e_stack	  	PARAMS((PTR));

/* Initialize the association of GNAT nodes to GCC trees.  */

void
init_gnat_to_gnu ()
{
  Node_Id gnat_node;

  associate_gnat_to_gnu = (tree *) xmalloc (max_gnat_nodes * sizeof (tree));
  ggc_add_tree_root (associate_gnat_to_gnu, max_gnat_nodes);

  for (gnat_node = 0; gnat_node < max_gnat_nodes; gnat_node++)
    associate_gnat_to_gnu [gnat_node] = NULL_TREE;

  associate_gnat_to_gnu -= First_Node_Id;

  pending_elaborations = build_tree_list (NULL_TREE, NULL_TREE);
  ggc_add_tree_root (&pending_elaborations, 1);
  ggc_add_root ((PTR) &elist_stack, 1, sizeof (struct e_stack), mark_e_stack);
  ggc_add_tree_root (&signed_and_unsigned_types[0][0],
		     (sizeof signed_and_unsigned_types
		      / sizeof signed_and_unsigned_types[0][0]));
  ggc_add_tree_root (float_types, ARRAY_SIZE (float_types));

  ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
		mark_binding_level);
}

/* GNAT_ENTITY is a GNAT tree node for an entity.   GNU_DECL is the GCC tree
   which is to be associated with GNAT_ENTITY. Such GCC tree node is always
   a ..._DECL node.  If NO_CHECK is nonzero, the latter check is suppressed.

   If GNU_DECL is zero, a previous association is to be reset.  */

void
save_gnu_tree (gnat_entity, gnu_decl, no_check)
     Entity_Id gnat_entity;
     tree gnu_decl;
     int no_check;
{
  if (gnu_decl
      && (associate_gnat_to_gnu [gnat_entity]
	  || (! no_check && ! DECL_P (gnu_decl))))
    gigi_abort (401);

  associate_gnat_to_gnu [gnat_entity] = gnu_decl;
}

/* GNAT_ENTITY is a GNAT tree node for a defining identifier.
   Return the ..._DECL node that was associated with it.  If there is no tree
   node associated with GNAT_ENTITY, abort.

   In some cases, such as delayed elaboration or expressions that need to
   be elaborated only once, GNAT_ENTITY is really not an entity.  */

tree
get_gnu_tree (gnat_entity)
     Entity_Id gnat_entity;
{
  if (! associate_gnat_to_gnu [gnat_entity])
    gigi_abort (402);

  return associate_gnat_to_gnu [gnat_entity];
}

/* Return nonzero if a GCC tree has been associated with GNAT_ENTITY.  */

int
present_gnu_tree (gnat_entity)
     Entity_Id gnat_entity;
{
  return (associate_gnat_to_gnu [gnat_entity] != NULL_TREE);
}


/* Return non-zero if we are currently in the global binding level.  */

int
global_bindings_p ()
{
  return (force_global != 0 || current_binding_level == global_binding_level
	  ? -1 : 0);
}

/* Return the list of declarations in the current level. Note that this list
   is in reverse order (it has to be so for back-end compatibility).  */

tree
getdecls ()
{
  return current_binding_level->names;
}

/* Nonzero if the current level needs to have a BLOCK made.  */

int
kept_level_p ()
{
  return (current_binding_level->names != 0);
}

/* Enter a new binding level. The input parameter is ignored, but has to be
   specified for back-end compatibility.  */

void
pushlevel (ignore)
     int ignore ATTRIBUTE_UNUSED;
{
  struct binding_level *newlevel = NULL;

  /* Reuse a struct for this binding level, if there is one.  */
  if (free_binding_level)
    {
      newlevel = free_binding_level;
      free_binding_level = free_binding_level->level_chain;
    }
  else
    newlevel
      = (struct binding_level *) xmalloc (sizeof (struct binding_level));

  *newlevel = clear_binding_level;

  /* Add this level to the front of the chain (stack) of levels that are
     active.  */
  newlevel->level_chain = current_binding_level;
  current_binding_level = newlevel;
}

/* Exit a binding level.
   Pop the level off, and restore the state of the identifier-decl mappings
   that were in effect when this level was entered.

   If KEEP is nonzero, this level had explicit declarations, so
   and create a "block" (a BLOCK node) for the level
   to record its declarations and subblocks for symbol table output.

   If FUNCTIONBODY is nonzero, this level is the body of a function,
   so create a block as if KEEP were set and also clear out all
   label names.

   If REVERSE is nonzero, reverse the order of decls before putting
   them into the BLOCK.  */

tree
poplevel (keep, reverse, functionbody)
     int keep;
     int reverse;
     int functionbody;
{
  /* Points to a GCC BLOCK tree node. This is the BLOCK node construted for the
     binding level that we are about to exit and which is returned by this
     routine.  */
  tree block = NULL_TREE;
  tree decl_chain;
  tree decl_node;
  tree subblock_chain = current_binding_level->blocks;
  tree subblock_node;
  int block_previously_created;

  /* Reverse the list of XXXX_DECL nodes if desired.  Note that the ..._DECL
     nodes chained through the `names' field of current_binding_level are in
     reverse order except for PARM_DECL node, which are explicitly stored in
     the right order.  */
  current_binding_level->names
    = decl_chain = (reverse) ? nreverse (current_binding_level->names)
      : current_binding_level->names;

  /* Output any nested inline functions within this block which must be
     compiled because their address is needed. */
  for (decl_node = decl_chain; decl_node; decl_node = TREE_CHAIN (decl_node))
    if (TREE_CODE (decl_node) == FUNCTION_DECL
	&& ! TREE_ASM_WRITTEN (decl_node) && TREE_ADDRESSABLE (decl_node)
	&& DECL_INITIAL (decl_node) != 0)
      {
	push_function_context ();
	output_inline_function (decl_node);
	pop_function_context ();
      }

  block = 0;
  block_previously_created = (current_binding_level->this_block != 0);
  if (block_previously_created)
    block = current_binding_level->this_block;
  else if (keep || functionbody)
    block = make_node (BLOCK);
  if (block != 0)
    {
      BLOCK_VARS (block) = keep ? decl_chain : 0;
      BLOCK_SUBBLOCKS (block) = subblock_chain;
    }

  /* Record the BLOCK node just built as the subblock its enclosing scope.  */
  for (subblock_node = subblock_chain; subblock_node;
       subblock_node = TREE_CHAIN (subblock_node))
    BLOCK_SUPERCONTEXT (subblock_node) = block;

  /* Clear out the meanings of the local variables of this level.  */

  for (subblock_node = decl_chain; subblock_node;
       subblock_node = TREE_CHAIN (subblock_node))
    if (DECL_NAME (subblock_node) != 0)
      /* If the identifier was used or addressed via a local extern decl,  
	 don't forget that fact.   */
      if (DECL_EXTERNAL (subblock_node))
	{
	  if (TREE_USED (subblock_node))
	    TREE_USED (DECL_NAME (subblock_node)) = 1;
	  if (TREE_ADDRESSABLE (subblock_node))
	    TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (subblock_node)) = 1;
	}

  {
    /* Pop the current level, and free the structure for reuse.  */
    struct binding_level *level = current_binding_level;
    current_binding_level = current_binding_level->level_chain;
    level->level_chain = free_binding_level;
    free_binding_level = level;
  }

  if (functionbody)
    {
      /* This is the top level block of a function. The ..._DECL chain stored
	 in BLOCK_VARS are the function's parameters (PARM_DECL nodes). Don't
	 leave them in the BLOCK because they are found in the FUNCTION_DECL
	 instead.  */
      DECL_INITIAL (current_function_decl) = block;
      BLOCK_VARS (block) = 0;
    }
  else if (block)
    {
      if (!block_previously_created)
	current_binding_level->blocks
	  = chainon (current_binding_level->blocks, block);
    }

  /* If we did not make a block for the level just exited, any blocks made for
     inner levels (since they cannot be recorded as subblocks in that level)
     must be carried forward so they will later become subblocks of something
     else.  */
  else if (subblock_chain)
    current_binding_level->blocks
      = chainon (current_binding_level->blocks, subblock_chain);
  if (block)
    TREE_USED (block) = 1;

  return block;
}

/* Insert BLOCK at the end of the list of subblocks of the
   current binding level.  This is used when a BIND_EXPR is expanded,
   to handle the BLOCK node inside the BIND_EXPR.  */

void
insert_block (block)
     tree block;
{
  TREE_USED (block) = 1;
  current_binding_level->blocks
    = chainon (current_binding_level->blocks, block);
}

/* Set the BLOCK node for the innermost scope
   (the one we are currently in).  */

void
set_block (block)
     tree block;
{
  current_binding_level->this_block = block;
  current_binding_level->names = chainon (current_binding_level->names,
					  BLOCK_VARS (block));
  current_binding_level->blocks = chainon (current_binding_level->blocks,
					   BLOCK_SUBBLOCKS (block));
}

/* Records a ..._DECL node DECL as belonging to the current lexical scope.
   Returns the ..._DECL node. */

tree
pushdecl (decl)
     tree decl;
{
  struct binding_level *b;

  /* If at top level, there is no context. But PARM_DECLs always go in the
     level of its function. */
  if (global_bindings_p () && TREE_CODE (decl) != PARM_DECL)
    {
      b = global_binding_level;
      DECL_CONTEXT (decl) = 0;
    }
  else
    {
      b = current_binding_level;
      DECL_CONTEXT (decl) = current_function_decl;
    }

  /* Put the declaration on the list.  The list of declarations is in reverse
     order. The list will be reversed later if necessary.  This needs to be
     this way for compatibility with the back-end.

     Don't put TYPE_DECLs for UNCONSTRAINED_ARRAY_TYPE into the list.  They
     will cause trouble with the debugger and aren't needed anyway.  */
  if (TREE_CODE (decl) != TYPE_DECL
      || TREE_CODE (TREE_TYPE (decl)) != UNCONSTRAINED_ARRAY_TYPE)
    {
      TREE_CHAIN (decl) = b->names;
      b->names = decl;
    }

  /* For the declaration of a type, set its name if it either is not already
     set, was set to an IDENTIFIER_NODE, indicating an internal name,
     or if the previous type name was not derived from a source name.
     We'd rather have the type named with a real name and all the pointer
     types to the same object have the same POINTER_TYPE node.  Code in this
     function in c-decl.c makes a copy of the type node here, but that may
     cause us trouble with incomplete types, so let's not try it (at least
     for now).  */

  if (TREE_CODE (decl) == TYPE_DECL
      && DECL_NAME (decl) != 0
      && (TYPE_NAME (TREE_TYPE (decl)) == 0
	  || TREE_CODE (TYPE_NAME (TREE_TYPE (decl))) == IDENTIFIER_NODE
	  || (TREE_CODE (TYPE_NAME (TREE_TYPE (decl))) == TYPE_DECL
	      && DECL_ARTIFICIAL (TYPE_NAME (TREE_TYPE (decl)))
	      && ! DECL_ARTIFICIAL (decl))))
    TYPE_NAME (TREE_TYPE (decl)) = decl;

  return decl;
}

/* Do little here.  Set up the standard declarations later after the
   front end has been run.  */

void
gnat_init_decl_processing ()
{
  lineno = 0;

  /* incomplete_decl_finalize_hook is defined in toplev.c. It needs to be set
     by each front end to the appropriate routine that handles incomplete 
     VAR_DECL nodes. This routine will be invoked by compile_file when a  
     VAR_DECL node of DECL_SIZE zero is encountered.  */
  incomplete_decl_finalize_hook = finish_incomplete_decl;

  /* Make the binding_level structure for global names.  */
  current_function_decl = 0;
  current_binding_level = 0;
  free_binding_level = 0;
  pushlevel (0);
  global_binding_level = current_binding_level;

  build_common_tree_nodes (0);

  /* In Ada, we use a signed type for SIZETYPE.  Use the signed type
     corresponding to the size of ptr_mode.  Make this here since we need
     this before we can expand the GNAT types.  */
  set_sizetype (type_for_size (GET_MODE_BITSIZE (ptr_mode), 0));
  build_common_tree_nodes_2 (0);

  pushdecl (build_decl (TYPE_DECL, get_identifier (SIZE_TYPE), sizetype));

  /* We need to make the integer type before doing anything else.
     We stitch this in to the appropriate GNAT type later.  */
  pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
			integer_type_node));
  pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
			char_type_node));

  ptr_void_type_node = build_pointer_type (void_type_node);

}

/* Create the predefined scalar types such as `integer_type_node' needed 
   in the gcc back-end and initialize the global binding level.  */

void
init_gigi_decls (long_long_float_type, exception_type)
     tree long_long_float_type, exception_type;
{
  tree endlink;

  /* Set the types that GCC and Gigi use from the front end.  We would like
     to do this for char_type_node, but it needs to correspond to the C
     char type.  */
  if (TREE_CODE (TREE_TYPE (long_long_float_type)) == INTEGER_TYPE)
    {
      /* In this case, the builtin floating point types are VAX float,
	 so make up a type for use.  */
      longest_float_type_node = make_node (REAL_TYPE);
      TYPE_PRECISION (longest_float_type_node) = LONG_DOUBLE_TYPE_SIZE;
      layout_type (longest_float_type_node);
      pushdecl (build_decl (TYPE_DECL, get_identifier ("longest float type"),
			    longest_float_type_node));
    }
  else
    longest_float_type_node = TREE_TYPE (long_long_float_type);

  except_type_node = TREE_TYPE (exception_type);

  unsigned_type_node = type_for_size (INT_TYPE_SIZE, 1);
  pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
			unsigned_type_node));

  void_type_decl_node
    = pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
			    void_type_node));

  void_ftype = build_function_type (void_type_node, NULL_TREE);
  ptr_void_ftype = build_pointer_type (void_ftype);

  /* Now declare runtime functions. */
  endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);

  /* malloc is a function declaration tree for a function to allocate
     memory.  */
  malloc_decl = create_subprog_decl (get_identifier ("__gnat_malloc"),
				     NULL_TREE,
				     build_function_type (ptr_void_type_node,
							  tree_cons (NULL_TREE,
								     sizetype,
								     endlink)),
				     NULL_TREE, 0, 1, 1, 0);

  /* free is a function declaration tree for a function to free memory.  */

  free_decl
    = create_subprog_decl (get_identifier ("__gnat_free"), NULL_TREE,
			   build_function_type (void_type_node,
						tree_cons (NULL_TREE,
							   ptr_void_type_node,
							   endlink)),
			   NULL_TREE, 0, 1, 1, 0);

  /* Make the types and functions used for exception processing.    */
  jmpbuf_type
    = build_array_type (type_for_mode (Pmode, 0),
			build_index_type (build_int_2 (5, 0)));
  pushdecl (build_decl (TYPE_DECL, get_identifier ("JMPBUF_T"), jmpbuf_type));
  jmpbuf_ptr_type = build_pointer_type (jmpbuf_type);

  /* Functions to get and set the jumpbuf pointer for the current thread.  */
  get_jmpbuf_decl
    = create_subprog_decl
    (get_identifier ("system__soft_links__get_jmpbuf_address_soft"),
     NULL_TREE, build_function_type (jmpbuf_ptr_type, NULL_TREE),
     NULL_TREE, 0, 1, 1, 0);

  set_jmpbuf_decl
    = create_subprog_decl
    (get_identifier ("system__soft_links__set_jmpbuf_address_soft"),
     NULL_TREE,
     build_function_type (void_type_node, 
			  tree_cons (NULL_TREE, jmpbuf_ptr_type, endlink)),
     NULL_TREE, 0, 1, 1, 0);

  /* Function to get the current exception.  */
  get_excptr_decl
    = create_subprog_decl
    (get_identifier ("system__soft_links__get_gnat_exception"),
     NULL_TREE,
     build_function_type (build_pointer_type (except_type_node), NULL_TREE),
     NULL_TREE, 0, 1, 1, 0);

  /* Function that raise exceptions. */
  raise_nodefer_decl
    = create_subprog_decl
      (get_identifier ("__gnat_raise_nodefer_with_msg"), NULL_TREE,
       build_function_type (void_type_node,
			    tree_cons (NULL_TREE,
				       build_pointer_type (except_type_node),
				       endlink)),
       NULL_TREE, 0, 1, 1, 0);


  /* __gnat_raise_constraint_error takes a string, an integer and never
     returns.  */
  raise_constraint_error_decl
    = create_subprog_decl
      (get_identifier ("__gnat_raise_constraint_error"), NULL_TREE,
       build_function_type (void_type_node,
			    tree_cons (NULL_TREE,
				       build_pointer_type (char_type_node),
				       tree_cons (NULL_TREE,
						  integer_type_node,
						  endlink))),
       NULL_TREE, 0, 1, 1, 0);

  /* Likewise for __gnat_raise_program_error.  */
  raise_program_error_decl
    = create_subprog_decl
      (get_identifier ("__gnat_raise_program_error"), NULL_TREE,
       build_function_type (void_type_node,
			    tree_cons (NULL_TREE,
				       build_pointer_type (char_type_node),
				       tree_cons (NULL_TREE,
						  integer_type_node,
						  endlink))),
       NULL_TREE, 0, 1, 1, 0);

  /* Likewise for __gnat_raise_storage_error.  */
  raise_storage_error_decl
    = create_subprog_decl
      (get_identifier ("__gnat_raise_storage_error"), NULL_TREE,
       build_function_type (void_type_node,
			    tree_cons (NULL_TREE,
				       build_pointer_type (char_type_node),
				       tree_cons (NULL_TREE,
						  integer_type_node,
						  endlink))),
       NULL_TREE, 0, 1, 1, 0);

  /* Indicate that these never return.  */

  TREE_THIS_VOLATILE (raise_nodefer_decl) = 1;
  TREE_THIS_VOLATILE (raise_constraint_error_decl) = 1;
  TREE_THIS_VOLATILE (raise_program_error_decl) = 1;
  TREE_THIS_VOLATILE (raise_storage_error_decl) = 1;

  TREE_SIDE_EFFECTS (raise_nodefer_decl) = 1;
  TREE_SIDE_EFFECTS (raise_constraint_error_decl) = 1;
  TREE_SIDE_EFFECTS (raise_program_error_decl) = 1;
  TREE_SIDE_EFFECTS (raise_storage_error_decl) = 1;

  TREE_TYPE (raise_nodefer_decl)
    = build_qualified_type (TREE_TYPE (raise_nodefer_decl),
			    TYPE_QUAL_VOLATILE);
  TREE_TYPE (raise_constraint_error_decl)
    = build_qualified_type (TREE_TYPE (raise_constraint_error_decl),
			    TYPE_QUAL_VOLATILE);
  TREE_TYPE (raise_program_error_decl)
    = build_qualified_type (TREE_TYPE (raise_program_error_decl),
			    TYPE_QUAL_VOLATILE);
  TREE_TYPE (raise_storage_error_decl)
    = build_qualified_type (TREE_TYPE (raise_storage_error_decl),
			    TYPE_QUAL_VOLATILE);

  /* setjmp returns an integer and has one operand, which is a pointer to
     a jmpbuf.  */
  setjmp_decl
    = create_subprog_decl
      (get_identifier ("setjmp"), NULL_TREE,
       build_function_type (integer_type_node,
			    tree_cons (NULL_TREE,  jmpbuf_ptr_type, endlink)),
       NULL_TREE, 0, 1, 1, 0);

  DECL_BUILT_IN_CLASS (setjmp_decl) = BUILT_IN_NORMAL;
  DECL_FUNCTION_CODE (setjmp_decl) = BUILT_IN_SETJMP;

  ggc_add_tree_root (gnat_std_decls, ARRAY_SIZE (gnat_std_decls));
}

/* This routine is called in tree.c to print an error message for invalid use
   of an incomplete type.  */

void
incomplete_type_error (dont_care_1, dont_care_2)
     tree dont_care_1 ATTRIBUTE_UNUSED;
     tree dont_care_2 ATTRIBUTE_UNUSED;
{
  gigi_abort (404);
}

/* This function is called indirectly from toplev.c to handle incomplete 
   declarations, i.e. VAR_DECL nodes whose DECL_SIZE is zero.  To be precise,
   compile_file in toplev.c makes an indirect call through the function pointer
   incomplete_decl_finalize_hook which is initialized to this routine in
   init_decl_processing.  */

void
finish_incomplete_decl (dont_care)
     tree dont_care ATTRIBUTE_UNUSED;
{
  gigi_abort (405);
}

/* Given a record type (RECORD_TYPE) and a chain of FIELD_DECL
   nodes (FIELDLIST), finish constructing the record or union type. 
   If HAS_REP is nonzero, this record has a rep clause; don't call
   layout_type but merely set the size and alignment ourselves. 
   If DEFER_DEBUG is nonzero, do not call the debugging routines
   on this type; it will be done later. */

void
finish_record_type (record_type, fieldlist, has_rep, defer_debug)
     tree record_type;
     tree fieldlist;
     int has_rep;
     int defer_debug;
{
  enum tree_code code = TREE_CODE (record_type);
  tree ada_size = bitsize_zero_node;
  tree size = bitsize_zero_node;
  tree size_unit = size_zero_node;
  tree field;

  TYPE_FIELDS (record_type) = fieldlist;

  if (TYPE_NAME (record_type) != 0
      && TREE_CODE (TYPE_NAME (record_type)) == TYPE_DECL)
    TYPE_STUB_DECL (record_type) = TYPE_NAME (record_type);
  else
    TYPE_STUB_DECL (record_type)
      = pushdecl (build_decl (TYPE_DECL, TYPE_NAME (record_type),
			      record_type));

  /* We don't need both the typedef name and the record name output in
     the debugging information, since they are the same.  */
  DECL_ARTIFICIAL (TYPE_STUB_DECL (record_type)) = 1;

  /* Globally initialize the record first.  If this is a rep'ed record,
     that just means some initializations; otherwise, layout the record.  */

  if (has_rep)
    {
      TYPE_ALIGN (record_type) = MAX (BITS_PER_UNIT, TYPE_ALIGN (record_type));
      TYPE_MODE (record_type) = BLKmode;
      if (TYPE_SIZE (record_type) == 0)
	{
	  TYPE_SIZE (record_type) = bitsize_zero_node;
	  TYPE_SIZE_UNIT (record_type) = size_zero_node;
	}
    }
  else
    {
      /* Ensure there isn't a size already set.  There can be in an error
	 case where there is a rep clause but all fields have errors and
	 no longer have a position.  */
      TYPE_SIZE (record_type) = 0;
      layout_type (record_type);
    }

  /* At this point, the position and size of each field is known.  It was
     either set before entry by a rep clause, or by laying out the type
     above.  We now make a pass through the fields (in reverse order for
     QUAL_UNION_TYPEs) to compute the Ada size; the GCC size and alignment
     (for rep'ed records that are not padding types); and the mode (for
     rep'ed records).  */

  if (code == QUAL_UNION_TYPE)
    fieldlist = nreverse (fieldlist);

  for (field = fieldlist; field; field = TREE_CHAIN (field))
    {
      tree type = TREE_TYPE (field);
      tree this_size = DECL_SIZE (field);
      tree this_size_unit = DECL_SIZE_UNIT (field);
      tree this_ada_size = DECL_SIZE (field);

      if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
	  || TREE_CODE (type) == QUAL_UNION_TYPE)
	  && ! TYPE_IS_FAT_POINTER_P (type)
	  && ! TYPE_CONTAINS_TEMPLATE_P (type)
	  && TYPE_ADA_SIZE (type) != 0)
	this_ada_size = TYPE_ADA_SIZE (type);

      if (has_rep && ! DECL_BIT_FIELD (field))
	TYPE_ALIGN (record_type)
	  = MAX (TYPE_ALIGN (record_type), DECL_ALIGN (field));

      switch (code)
	{
	case UNION_TYPE:
	  ada_size = size_binop (MAX_EXPR, ada_size, this_ada_size);
	  size = size_binop (MAX_EXPR, size, this_size);
	  size_unit = size_binop (MAX_EXPR, size_unit, this_size_unit);
	  break;

	case QUAL_UNION_TYPE:
	  ada_size
	    = fold (build (COND_EXPR, bitsizetype, DECL_QUALIFIER (field),
			   this_ada_size, ada_size));
	  size = fold (build (COND_EXPR, bitsizetype, DECL_QUALIFIER (field),
			      this_size, size));
	  size_unit = fold (build (COND_EXPR, sizetype, DECL_QUALIFIER (field),
				   this_size_unit, size_unit));
	  break;

	case RECORD_TYPE:
	  /* Since we know here that all fields are sorted in order of
	     increasing bit position, the size of the record is one
	     higher than the ending bit of the last field processed
	     unless we have a rep clause, since in that case we might
	     have a field outside a QUAL_UNION_TYPE that has a higher ending
	     position.  So use a MAX in that case.  Also, if this field is a
	     QUAL_UNION_TYPE, we need to take into account the previous size in
	     the case of empty variants.  */
	  ada_size
	    = merge_sizes (ada_size, bit_position (field), this_ada_size,
			   TREE_CODE (type) == QUAL_UNION_TYPE, has_rep);
	  size = merge_sizes (size, bit_position (field), this_size,
			      TREE_CODE (type) == QUAL_UNION_TYPE, has_rep);
	  size_unit
	    = merge_sizes (size_unit, byte_position (field), this_size_unit,
			   TREE_CODE (type) == QUAL_UNION_TYPE, has_rep);
	  break;

	default:
	  abort ();
	}
    }

  if (code == QUAL_UNION_TYPE)
    nreverse (fieldlist);

  /* If this is a padding record, we never want to make the size smaller than
     what was specified in it, if any.  */
  if (TREE_CODE (record_type) == RECORD_TYPE
      && TYPE_IS_PADDING_P (record_type) && TYPE_SIZE (record_type) != 0)
    {
      size = TYPE_SIZE (record_type);
      size_unit = TYPE_SIZE_UNIT (record_type);
    }

  /* Now set any of the values we've just computed that apply.  */
  if (! TYPE_IS_FAT_POINTER_P (record_type)
      && ! TYPE_CONTAINS_TEMPLATE_P (record_type))
    TYPE_ADA_SIZE (record_type) = ada_size;

#ifdef ROUND_TYPE_SIZE
  size = ROUND_TYPE_SIZE (record_type, size, TYPE_ALIGN (record_type));
  size_unit = ROUND_TYPE_SIZE_UNIT (record_size, size_unit,
				    TYPE_ALIGN (record_type) / BITS_PER_UNIT);
#else
  size = round_up (size, TYPE_ALIGN (record_type));
  size_unit = round_up (size_unit, TYPE_ALIGN (record_type) / BITS_PER_UNIT);
#endif

  if (has_rep
      && ! (TREE_CODE (record_type) == RECORD_TYPE
	    && TYPE_IS_PADDING_P (record_type)
	    && TREE_CODE (size) != INTEGER_CST
	    && contains_placeholder_p (size)))
    {
      TYPE_SIZE (record_type) = size;
      TYPE_SIZE_UNIT (record_type) = size_unit;
    }

  if (has_rep)
    compute_record_mode (record_type);

  if (! defer_debug)
    {
      /* If this record is of variable size, rename it so that the
	 debugger knows it is and make a new, parallel, record
	 that tells the debugger how the record is laid out.  See
	 exp_dbug.ads.  */
      if (TREE_CODE (TYPE_SIZE (record_type)) != INTEGER_CST)
	{
	  tree new_record_type
	    = make_node (TREE_CODE (record_type) == QUAL_UNION_TYPE
			 ? UNION_TYPE : TREE_CODE (record_type));
	  tree orig_id = DECL_NAME (TYPE_STUB_DECL (record_type));
	  tree new_id
	    = concat_id_with_name (orig_id,
				   TREE_CODE (record_type) == QUAL_UNION_TYPE
				   ? "XVU" : "XVE");
	  tree last_pos = bitsize_zero_node;
	  tree old_field;

	  TYPE_NAME (new_record_type) = new_id;
	  TYPE_ALIGN (new_record_type) = BIGGEST_ALIGNMENT;
	  TYPE_STUB_DECL (new_record_type)
	    = pushdecl (build_decl (TYPE_DECL, new_id, new_record_type));
	  DECL_ARTIFICIAL (TYPE_STUB_DECL (new_record_type)) = 1;
	  DECL_IGNORED_P (TYPE_STUB_DECL (new_record_type))
	    = DECL_IGNORED_P (TYPE_STUB_DECL (record_type));
	  TYPE_SIZE (new_record_type) = size_int (TYPE_ALIGN (record_type));

	  /* Now scan all the fields, replacing each field with a new
	     field corresponding to the new encoding.  */
	  for (old_field = TYPE_FIELDS (record_type); old_field != 0;
	       old_field = TREE_CHAIN (old_field))
	    {
	      tree field_type = TREE_TYPE (old_field);
	      tree field_name = DECL_NAME (old_field);
	      tree new_field;
	      tree curpos = bit_position (old_field);
	      int var = 0;
	      unsigned int align = 0;
	      tree pos;

	      /* See how the position was modified from the last position.

		 There are two basic cases we support: a value was added
		 to the last position or the last position was rounded to
		 a boundary and they something was added.  Check for the
		 first case first.  If not, see if there is any evidence
		 of rounding.  If so, round the last position and try
		 again. 

		 If this is a union, the position can be taken as zero. */

	      if (TREE_CODE (new_record_type) == UNION_TYPE)
		pos = bitsize_zero_node, align = 0;
	      else
		pos = compute_related_constant (curpos, last_pos);

	      if (pos == 0 && TREE_CODE (curpos) == MULT_EXPR
		  && TREE_CODE (TREE_OPERAND (curpos, 1)) == INTEGER_CST)
		{
		  align = TREE_INT_CST_LOW (TREE_OPERAND (curpos, 1));
		  pos = compute_related_constant (curpos,
						  round_up (last_pos, align));
		}
	      else if (pos == 0 && TREE_CODE (curpos) == PLUS_EXPR
		       && TREE_CODE (TREE_OPERAND (curpos, 1)) == INTEGER_CST
		       && TREE_CODE (TREE_OPERAND (curpos, 0)) == MULT_EXPR
		       && host_integerp (TREE_OPERAND
					 (TREE_OPERAND (curpos, 0), 1),
					 1))
		{
		  align
		    = tree_low_cst
		      (TREE_OPERAND (TREE_OPERAND (curpos, 0), 1), 1);
		  pos = compute_related_constant (curpos,
						  round_up (last_pos, align));
		}

	      /* If we can't compute a position, set it to zero.

		 ??? We really should abort here, but it's too much work
		 to get this correct for all cases.  */

	      if (pos == 0)
		pos = bitsize_zero_node;

	      /* See if this type is variable-size and make a new type
		 and indicate the indirection if so.  */
	      if (TREE_CODE (TYPE_SIZE (field_type)) != INTEGER_CST)
		{
		  field_type = build_pointer_type (field_type);
		  var = 1;
		}

	      /* Make a new field name, if necessary.  */
	      if (var || align != 0)
		{
		  char suffix[6];

		  if (align != 0)
		    sprintf (suffix, "XV%c%u", var ? 'L' : 'A',
			     align / BITS_PER_UNIT);
		  else
		    strcpy (suffix, "XVL");

		  field_name = concat_id_with_name (field_name, suffix);
		}

	      new_field = create_field_decl (field_name, field_type,
					     new_record_type, 0,
					     TYPE_SIZE (field_type), pos, 0);
	      TREE_CHAIN (new_field) = TYPE_FIELDS (new_record_type);
	      TYPE_FIELDS (new_record_type) = new_field;

	      /* If old_field is a QUAL_UNION_TYPE, take its size as being
		 zero.  The only time it's not the last field of the record
		 is when there are other components at fixed positions after
		 it (meaning there was a rep clause for every field) and we
		 want to be able to encode them.  */
	      last_pos = size_binop (PLUS_EXPR, bit_position (old_field),
				     (TREE_CODE (TREE_TYPE (old_field))
				      == QUAL_UNION_TYPE)
				     ? bitsize_zero_node
				     : TYPE_SIZE (TREE_TYPE (old_field)));
	    }

	  TYPE_FIELDS (new_record_type)
	    = nreverse (TYPE_FIELDS (new_record_type));

	  rest_of_type_compilation (new_record_type, global_bindings_p ());
	}

      rest_of_type_compilation (record_type, global_bindings_p ());
    }
}

/* Utility function of above to merge LAST_SIZE, the previous size of a record
   with FIRST_BIT and SIZE that describe a field.  SPECIAL is nonzero
   if this represents a QUAL_UNION_TYPE in which case we must look for
   COND_EXPRs and replace a value of zero with the old size.  If HAS_REP
   is nonzero, we must take the MAX of the end position of this field
   with LAST_SIZE.  In all other cases, we use FIRST_BIT plus SIZE.

   We return an expression for the size.  */

static tree
merge_sizes (last_size, first_bit, size, special, has_rep)
     tree last_size;
     tree first_bit, size;
     int special;
     int has_rep;
{
  tree type = TREE_TYPE (last_size);

  if (! special || TREE_CODE (size) != COND_EXPR)
    {
      tree new = size_binop (PLUS_EXPR, first_bit, size);

      if (has_rep)
	new = size_binop (MAX_EXPR, last_size, new);

      return new;
    }

  return fold (build (COND_EXPR, type, TREE_OPERAND (size, 0),
		      integer_zerop (TREE_OPERAND (size, 1))
		      ? last_size : merge_sizes (last_size, first_bit,
						 TREE_OPERAND (size, 1),
						 1, has_rep),
		      integer_zerop (TREE_OPERAND (size, 2))
		      ? last_size : merge_sizes (last_size, first_bit,
						 TREE_OPERAND (size, 2),
						 1, has_rep)));
}

/* Utility function of above to see if OP0 and OP1, both of SIZETYPE, are
   related by the addition of a constant.  Return that constant if so.  */

static tree
compute_related_constant (op0, op1)
     tree op0, op1;
{
  tree op0_var, op1_var;
  tree op0_con = split_plus (op0, &op0_var);
  tree op1_con = split_plus (op1, &op1_var);
  tree result = size_binop (MINUS_EXPR, op0_con, op1_con);

  if (operand_equal_p (op0_var, op1_var, 0))
    return result;
  else if (operand_equal_p (op0, size_binop (PLUS_EXPR, op1_var, result), 0))
    return result;
  else
    return 0;
}

/* Utility function of above to split a tree OP which may be a sum, into a
   constant part, which is returned, and a variable part, which is stored
   in *PVAR.  *PVAR may be size_zero_node.  All operations must be of
   sizetype.  */

static tree
split_plus (in, pvar)
     tree in;
     tree *pvar;
{
  tree result = bitsize_zero_node;

  while (TREE_CODE (in) == NON_LVALUE_EXPR)
    in = TREE_OPERAND (in, 0);

  *pvar = in;
  if (TREE_CODE (in) == INTEGER_CST)
    {
      *pvar = bitsize_zero_node;
      return in;
    }
  else if (TREE_CODE (in) == PLUS_EXPR || TREE_CODE (in) == MINUS_EXPR)
    {
      tree lhs_var, rhs_var;
      tree lhs_con = split_plus (TREE_OPERAND (in, 0), &lhs_var);
      tree rhs_con = split_plus (TREE_OPERAND (in, 1), &rhs_var);

      result = size_binop (PLUS_EXPR, result, lhs_con);
      result = size_binop (TREE_CODE (in), result, rhs_con);

      if (lhs_var == TREE_OPERAND (in, 0)
	  && rhs_var == TREE_OPERAND (in, 1))
	return bitsize_zero_node;

      *pvar = size_binop (TREE_CODE (in), lhs_var, rhs_var);
      return result;
    }
  else
    return bitsize_zero_node;
}

/* Return a FUNCTION_TYPE node. RETURN_TYPE is the type returned by the
   subprogram. If it is void_type_node, then we are dealing with a procedure,
   otherwise we are dealing with a function. PARAM_DECL_LIST is a list of
   PARM_DECL nodes that are the subprogram arguments.  CICO_LIST is the
   copy-in/copy-out list to be stored into TYPE_CICO_LIST.
   RETURNS_UNCONSTRAINED is nonzero if the function returns an unconstrained
   object.  RETURNS_BY_REF is nonzero if the function returns by reference. 
   RETURNS_WITH_DSP is nonzero if the function is to return with a
   depressed stack pointer.  */

tree
create_subprog_type (return_type, param_decl_list, cico_list,
		     returns_unconstrained, returns_by_ref, returns_with_dsp)
     tree return_type;
     tree param_decl_list;
     tree cico_list;
     int returns_unconstrained, returns_by_ref, returns_with_dsp;
{
  /* A chain of TREE_LIST nodes whose TREE_VALUEs are the data type nodes of
     the subprogram formal parameters. This list is generated by traversing the
     input list of PARM_DECL nodes.  */
  tree param_type_list = NULL;
  tree param_decl;
  tree type;

  for (param_decl = param_decl_list; param_decl;
       param_decl = TREE_CHAIN (param_decl))
    param_type_list = tree_cons (NULL_TREE, TREE_TYPE (param_decl),
					  param_type_list);

  /* The list of the function parameter types has to be terminated by the void
     type to signal to the back-end that we are not dealing with a variable
     parameter subprogram, but that the subprogram has a fixed number of
     parameters.  */
  param_type_list = tree_cons (NULL_TREE, void_type_node, param_type_list);

  /* The list of argument types has been created in reverse
     so nreverse it.   */
  param_type_list = nreverse (param_type_list);

  type = build_function_type (return_type, param_type_list);

  /* TYPE may have been shared since GCC hashes types.  If it has a CICO_LIST
     or the new type should, make a copy of TYPE.  Likewise for
     RETURNS_UNCONSTRAINED and RETURNS_BY_REF.  */
  if (TYPE_CI_CO_LIST (type) != 0 || cico_list != 0
      || TYPE_RETURNS_UNCONSTRAINED_P (type) != returns_unconstrained
      || TYPE_RETURNS_BY_REF_P (type) != returns_by_ref)
    type = copy_type (type);

  TYPE_CI_CO_LIST (type) = cico_list;
  TYPE_RETURNS_UNCONSTRAINED_P (type) = returns_unconstrained;
  TYPE_RETURNS_STACK_DEPRESSED (type) = returns_with_dsp;
  TYPE_RETURNS_BY_REF_P (type) = returns_by_ref;
  return type;
}

/* Return a copy of TYPE but safe to modify in any way.  */

tree
copy_type (type)
     tree type;
{
  tree new = copy_node (type);

  /* copy_node clears this field instead of copying it, because it is
     aliased with TREE_CHAIN.  */
  TYPE_STUB_DECL (new) = TYPE_STUB_DECL (type);

  TYPE_POINTER_TO (new) = 0;
  TYPE_REFERENCE_TO (new) = 0;
  TYPE_MAIN_VARIANT (new) = new;
  TYPE_NEXT_VARIANT (new) = 0;

  return new;
}

/* Return an INTEGER_TYPE of SIZETYPE with range MIN to MAX and whose
   TYPE_INDEX_TYPE is INDEX.  */

tree
create_index_type (min, max, index)
     tree min, max;
     tree index;
{
  /* First build a type for the desired range.  */
  tree type = build_index_2_type (min, max);

  /* If this type has the TYPE_INDEX_TYPE we want, return it.  Otherwise, if it
     doesn't have TYPE_INDEX_TYPE set, set it to INDEX.  If TYPE_INDEX_TYPE
     is set, but not to INDEX, make a copy of this type with the requested
     index type.  Note that we have no way of sharing these types, but that's
     only a small hole.  */
  if (TYPE_INDEX_TYPE (type) == index)
    return type;
  else if (TYPE_INDEX_TYPE (type) != 0)
    type = copy_type (type);

  TYPE_INDEX_TYPE (type) = index;
  return type;
}

/* Return a TYPE_DECL node. TYPE_NAME gives the name of the type (a character
   string) and TYPE is a ..._TYPE node giving its data type. 
   ARTIFICIAL_P is nonzero if this is a declaration that was generated
   by the compiler.  DEBUG_INFO_P is nonzero if we need to write debugging
   information about this type.  */

tree
create_type_decl (type_name, type, attr_list, artificial_p, debug_info_p)
     tree type_name;
     tree type;
     struct attrib *attr_list;
     int artificial_p;
     int debug_info_p;
{
  tree type_decl = build_decl (TYPE_DECL, type_name, type);
  enum tree_code code = TREE_CODE (type);

  DECL_ARTIFICIAL (type_decl) = artificial_p;
  pushdecl (type_decl);
  process_attributes (type_decl, attr_list);

  /* Pass type declaration information to the debugger unless this is an
     UNCONSTRAINED_ARRAY_TYPE, which the debugger does not support,
     and ENUMERAL_TYPE or RECORD_TYPE which is handled separately,
     a dummy type, which will be completed later, or a type for which
     debugging information was not requested.  */
  if (code == UNCONSTRAINED_ARRAY_TYPE || TYPE_IS_DUMMY_P (type)
      || ! debug_info_p)
    DECL_IGNORED_P (type_decl) = 1;
  else if (code != ENUMERAL_TYPE && code != RECORD_TYPE
      && ! ((code == POINTER_TYPE || code == REFERENCE_TYPE)
	    && TYPE_IS_DUMMY_P (TREE_TYPE (type))))
    rest_of_decl_compilation (type_decl, NULL, global_bindings_p (), 0);

  return type_decl;
}

/* Returns a GCC VAR_DECL node. VAR_NAME gives the name of the variable.
   ASM_NAME is its assembler name (if provided).  TYPE is its data type
   (a GCC ..._TYPE node).  VAR_INIT is the GCC tree for an optional initial
   expression; NULL_TREE if none.

   CONST_FLAG is nonzero if this variable is constant.

   PUBLIC_FLAG is nonzero if this definition is to be made visible outside of
   the current compilation unit. This flag should be set when processing the
   variable definitions in a package specification.  EXTERN_FLAG is nonzero 
   when processing an external variable declaration (as opposed to a
   definition: no storage is to be allocated for the variable here). 

   STATIC_FLAG is only relevant when not at top level.  In that case
   it indicates whether to always allocate storage to the variable.   */

tree
create_var_decl (var_name, asm_name, type, var_init, const_flag, public_flag,
		 extern_flag, static_flag, attr_list)
     tree var_name;
     tree asm_name;
     tree type;
     tree var_init;
     int const_flag;
     int public_flag;
     int extern_flag;
     int static_flag;
     struct attrib *attr_list;
{
  int init_const
    = (var_init == 0
       ? 0
       : (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (var_init))
	  && (global_bindings_p () || static_flag
	      ? 0 != initializer_constant_valid_p (var_init,
						   TREE_TYPE (var_init))
	      : TREE_CONSTANT (var_init))));
  tree var_decl
    = build_decl ((const_flag && init_const
		   /* Only make a CONST_DECL for sufficiently-small objects.
		      We consider complex double "sufficiently-small"  */
		   && TYPE_SIZE (type) != 0
		   && host_integerp (TYPE_SIZE_UNIT (type), 1)
		   && 0 >= compare_tree_int (TYPE_SIZE_UNIT (type),
					     GET_MODE_SIZE (DCmode)))
		  ? CONST_DECL : VAR_DECL, var_name, type);
  tree assign_init = 0;

  /* If this is external, throw away any initializations unless this is a
     CONST_DECL (meaning we have a constant); they will be done elsewhere.  If
     we are defining a global here, leave a constant initialization and save
     any variable elaborations for the elaboration routine.  Otherwise, if
     the initializing expression is not the same as TYPE, generate the
     initialization with an assignment statement, since it knows how
     to do the required adjustents.  If we are just annotating types,
     throw away the initialization if it isn't a constant.  */

  if ((extern_flag && TREE_CODE (var_decl) != CONST_DECL)
      || (type_annotate_only && var_init != 0 && ! TREE_CONSTANT (var_init)))
    var_init = 0;

  if (global_bindings_p () && var_init != 0 && ! init_const)
    {
      add_pending_elaborations (var_decl, var_init);
      var_init = 0;
    }

  else if (var_init != 0
	   && ((TYPE_MAIN_VARIANT (TREE_TYPE (var_init))
		!= TYPE_MAIN_VARIANT (type))
	       || (static_flag && ! init_const)))
    assign_init = var_init, var_init = 0;

  DECL_COMMON   (var_decl) = !flag_no_common;
  DECL_INITIAL  (var_decl) = var_init;
  TREE_READONLY (var_decl) = const_flag;
  DECL_EXTERNAL (var_decl) = extern_flag;
  TREE_PUBLIC   (var_decl) = public_flag || extern_flag;
  TREE_CONSTANT (var_decl) = TREE_CODE (var_decl) == CONST_DECL;
  TREE_THIS_VOLATILE (var_decl) = TREE_SIDE_EFFECTS (var_decl)
    = TYPE_VOLATILE (type);

  /* At the global binding level we need to allocate static storage for the
     variable if and only if its not external. If we are not at the top level
     we allocate automatic storage unless requested not to.  */
  TREE_STATIC (var_decl) = global_bindings_p () ? !extern_flag : static_flag;

  if (asm_name != 0)
    SET_DECL_ASSEMBLER_NAME (var_decl, asm_name);

  process_attributes (var_decl, attr_list);

  /* Add this decl to the current binding level and generate any
     needed code and RTL. */
  var_decl = pushdecl (var_decl);
  expand_decl (var_decl);

  if (DECL_CONTEXT (var_decl) != 0)
    expand_decl_init (var_decl);

  /* If this is volatile, force it into memory.  */
  if (TREE_SIDE_EFFECTS (var_decl))
    mark_addressable (var_decl);

  if (TREE_CODE (var_decl) != CONST_DECL)
    rest_of_decl_compilation (var_decl, 0, global_bindings_p (), 0);

  if (assign_init != 0)
    {
      /* If VAR_DECL has a padded type, convert it to the unpadded
	 type so the assignment is done properly.  */
      tree lhs = var_decl;

      if (TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
	  && TYPE_IS_PADDING_P (TREE_TYPE (lhs)))
	lhs = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (lhs))), lhs);

      expand_expr_stmt (build_binary_op (MODIFY_EXPR, NULL_TREE, lhs,
					 assign_init));
    }

  return var_decl;
}

/* Returns a FIELD_DECL node. FIELD_NAME the field name, FIELD_TYPE is its
   type, and RECORD_TYPE is the type of the parent.  PACKED is nonzero if
   this field is in a record type with a "pragma pack".  If SIZE is nonzero
   it is the specified size for this field.  If POS is nonzero, it is the bit
   position.  If ADDRESSABLE is nonzero, it means we are allowed to take
   the address of this field for aliasing purposes.  */

tree
create_field_decl (field_name, field_type, record_type, packed, size, pos,
		   addressable)
     tree field_name;
     tree field_type;
     tree record_type;
     int packed;
     tree size, pos;
     int addressable;
{
  tree field_decl = build_decl (FIELD_DECL, field_name, field_type);

  DECL_CONTEXT (field_decl) = record_type;
  TREE_READONLY (field_decl) = TREE_READONLY (field_type);

  /* If FIELD_TYPE is BLKmode, we must ensure this is aligned to at least a
     byte boundary since GCC cannot handle less-aligned BLKmode bitfields.
     If it is a padding type where the inner field is of variable size, it
     must be at its natural alignment.  Just handle the packed case here; we
     will disallow non-aligned rep clauses elsewhere.  */
  if (packed && TYPE_MODE (field_type) == BLKmode)
    DECL_ALIGN (field_decl)
      = ((TREE_CODE (field_type) == RECORD_TYPE
	  && TYPE_IS_PADDING_P (field_type)
	  && ! TREE_CONSTANT (DECL_SIZE (TYPE_FIELDS (field_type))))
	 ?  TYPE_ALIGN (field_type) : BITS_PER_UNIT);

  /* If a size is specified, use it.  Otherwise, see if we have a size
     to use that may differ from the natural size of the object.  */
  if (size != 0)
    size = convert (bitsizetype, size);
  else if (packed)
    {
      if (packed == 1 && ! operand_equal_p (rm_size (field_type),
					    TYPE_SIZE (field_type), 0))
	size = rm_size (field_type);

      /* For a constant size larger than MAX_FIXED_MODE_SIZE, round up to
	 byte.  */
      if (size != 0 && TREE_CODE (size) == INTEGER_CST
	  && compare_tree_int (size, MAX_FIXED_MODE_SIZE) > 0)
	size = round_up (size, BITS_PER_UNIT);
    }

  /* Make a bitfield if a size is specified for two reasons: first if the size
     differs from the natural size.  Second, if the alignment is insufficient.
     There are a number of ways the latter can be true.  But never make a
     bitfield if the type of the field has a nonconstant size.  */

  if (size != 0 && TREE_CODE (size) == INTEGER_CST
      && TREE_CODE (TYPE_SIZE (field_type)) == INTEGER_CST
      && (! operand_equal_p (TYPE_SIZE (field_type), size, 0)
	  || (pos != 0
	      && ! value_zerop (size_binop (TRUNC_MOD_EXPR, pos,
					    bitsize_int (TYPE_ALIGN
							 (field_type)))))
	  || packed
	  || (TYPE_ALIGN (record_type) != 0
	      && TYPE_ALIGN (record_type) < TYPE_ALIGN (field_type))))
    {
      DECL_BIT_FIELD (field_decl) = 1;
      DECL_SIZE (field_decl) = size;
      if (! packed && pos == 0)
	DECL_ALIGN (field_decl)
	  = (TYPE_ALIGN (record_type) != 0
	     ? MIN (TYPE_ALIGN (record_type), TYPE_ALIGN (field_type))
	     : TYPE_ALIGN (field_type));
    }

  DECL_PACKED (field_decl) = pos != 0 ? DECL_BIT_FIELD (field_decl) : packed;
  DECL_ALIGN (field_decl)
    = MAX (DECL_ALIGN (field_decl),
	   DECL_BIT_FIELD (field_decl) ? 1
	   : packed && TYPE_MODE (field_type) != BLKmode ? BITS_PER_UNIT
	   : TYPE_ALIGN (field_type));

  if (pos != 0)
    {
      /* We need to pass in the alignment the DECL is known to have.
	 This is the lowest-order bit set in POS, but no more than
	 the alignment of the record, if one is specified.  Note
	 that an alignment of 0 is taken as infinite.  */
      unsigned int known_align;

      if (host_integerp (pos, 1))
	known_align = tree_low_cst (pos, 1) & - tree_low_cst (pos, 1);
      else
	known_align = BITS_PER_UNIT;

      if (TYPE_ALIGN (record_type)
	  && (known_align == 0 || known_align > TYPE_ALIGN (record_type)))
	known_align = TYPE_ALIGN (record_type);

      layout_decl (field_decl, known_align);
      SET_DECL_OFFSET_ALIGN (field_decl, BIGGEST_ALIGNMENT);
      pos_from_bit (&DECL_FIELD_OFFSET (field_decl),
		    &DECL_FIELD_BIT_OFFSET (field_decl),
		    BIGGEST_ALIGNMENT, pos);

      DECL_HAS_REP_P (field_decl) = 1;
    }

  /* Mark the decl as nonaddressable if it either is indicated so semantically
     or if it is a bit field.  */
  DECL_NONADDRESSABLE_P (field_decl)
    = ! addressable || DECL_BIT_FIELD (field_decl);

  return field_decl;
}

/* Subroutine of previous function: return nonzero if EXP, ignoring any side
   effects, has the value of zero.  */

static int
value_zerop (exp)
     tree exp;
{
  if (TREE_CODE (exp) == COMPOUND_EXPR)
    return value_zerop (TREE_OPERAND (exp, 1));

  return integer_zerop (exp);
}

/* Returns a PARM_DECL node. PARAM_NAME is the name of the parameter,
   PARAM_TYPE is its type.  READONLY is nonzero if the parameter is
   readonly (either an IN parameter or an address of a pass-by-ref
   parameter). */

tree
create_param_decl (param_name, param_type, readonly)
     tree param_name;
     tree param_type;
     int readonly;
{
  tree param_decl = build_decl (PARM_DECL, param_name, param_type);

  DECL_ARG_TYPE (param_decl) = param_type;
  DECL_ARG_TYPE_AS_WRITTEN (param_decl) = param_type;
  TREE_READONLY (param_decl) = readonly;
  return param_decl;
}

/* Given a DECL and ATTR_LIST, process the listed attributes.  */

void
process_attributes (decl, attr_list)
     tree decl;
     struct attrib *attr_list;
{
  for (; attr_list; attr_list = attr_list->next)
    switch (attr_list->type)
      {
      case ATTR_MACHINE_ATTRIBUTE:
	decl_attributes (&decl, tree_cons (attr_list->name, attr_list->arg,
					   NULL_TREE),
			 ATTR_FLAG_TYPE_IN_PLACE);
	break;

      case ATTR_LINK_ALIAS:
	TREE_STATIC (decl) = 1;
	assemble_alias (decl, attr_list->name);
	break;

      case ATTR_WEAK_EXTERNAL:
	if (SUPPORTS_WEAK)
	  declare_weak (decl);
	else
	  post_error ("?weak declarations not supported on this target",
		      attr_list->error_point);
	break;

      case ATTR_LINK_SECTION:
#ifdef ASM_OUTPUT_SECTION_NAME
	DECL_SECTION_NAME (decl)
	  = build_string (IDENTIFIER_LENGTH (attr_list->name),
			  IDENTIFIER_POINTER (attr_list->name));
	DECL_COMMON (decl) = 0;
#else
	post_error ("?section attributes are not supported for this target",
		    attr_list->error_point);
#endif
	break;
      }
}

/* Add some pending elaborations on the list.  */

void 
add_pending_elaborations (var_decl, var_init)
     tree var_decl;
     tree var_init;
{
  if (var_init != 0)
    Check_Elaboration_Code_Allowed (error_gnat_node);

  pending_elaborations
    = chainon (pending_elaborations, build_tree_list (var_decl, var_init));
}

/* Obtain any pending elaborations and clear the old list.  */

tree
get_pending_elaborations ()
{
  /* Each thing added to the list went on the end; we want it on the
     beginning.  */
  tree result = TREE_CHAIN (pending_elaborations);

  TREE_CHAIN (pending_elaborations) = 0;
  return result;
}

/* Mark the binding level stack.  */

static void
mark_binding_level (arg)
     PTR arg;
{
  struct binding_level *level = *(struct binding_level **) arg;

  for (; level != 0; level = level->level_chain)
    {
      ggc_mark_tree (level->names);
      ggc_mark_tree (level->blocks);
      ggc_mark_tree (level->this_block);
    }
}

/* Mark the pending elaboration list.  */

static void
mark_e_stack (data)
     PTR data;
{
  struct e_stack *p = *((struct e_stack **) data);

  if (p != 0)
    {
      ggc_mark_tree (p->elab_list);
      mark_e_stack (&p->next);
    }
}

/* Return nonzero if there are pending elaborations.  */

int
pending_elaborations_p ()
{
  return TREE_CHAIN (pending_elaborations) != 0;
}

/* Save a copy of the current pending elaboration list and make a new
   one.  */

void
push_pending_elaborations ()
{
  struct e_stack *p = (struct e_stack *) xmalloc (sizeof (struct e_stack));

  p->next = elist_stack;
  p->elab_list = pending_elaborations;
  elist_stack = p;
  pending_elaborations = build_tree_list (NULL_TREE, NULL_TREE);
}

/* Pop the stack of pending elaborations.  */

void
pop_pending_elaborations ()
{
  struct e_stack *p = elist_stack;

  pending_elaborations = p->elab_list;
  elist_stack = p->next;
  free (p);
}

/* Return the current position in pending_elaborations so we can insert
   elaborations after that point.  */

tree
get_elaboration_location ()
{
  return tree_last (pending_elaborations);
}

/* Insert the current elaborations after ELAB, which is in some elaboration
   list.  */

void
insert_elaboration_list (elab)
     tree elab;
{
  tree next = TREE_CHAIN (elab);

  if (TREE_CHAIN (pending_elaborations))
    {
      TREE_CHAIN (elab) = TREE_CHAIN (pending_elaborations);
      TREE_CHAIN (tree_last (pending_elaborations)) = next;
      TREE_CHAIN (pending_elaborations) = 0;
    }
}

/* Returns a LABEL_DECL node for LABEL_NAME.  */

tree
create_label_decl (label_name)
     tree label_name;
{
  tree label_decl = build_decl (LABEL_DECL, label_name, void_type_node);

  DECL_CONTEXT (label_decl)     = current_function_decl;
  DECL_MODE (label_decl)        = VOIDmode;
  DECL_SOURCE_LINE (label_decl) = lineno;
  DECL_SOURCE_FILE (label_decl) = input_filename;

  return label_decl;
}

/* Returns a FUNCTION_DECL node.  SUBPROG_NAME is the name of the subprogram,
   ASM_NAME is its assembler name, SUBPROG_TYPE is its type (a FUNCTION_TYPE
   node), PARAM_DECL_LIST is the list of the subprogram arguments (a list of
   PARM_DECL nodes chained through the TREE_CHAIN field).

   INLINE_FLAG, PUBLIC_FLAG, and EXTERN_FLAG are used to set the appropriate
   fields in the FUNCTION_DECL.  */

tree
create_subprog_decl (subprog_name, asm_name, subprog_type, param_decl_list,
		     inline_flag, public_flag, extern_flag, attr_list)
     tree subprog_name;
     tree asm_name;
     tree subprog_type;
     tree param_decl_list;
     int inline_flag;
     int public_flag;
     int extern_flag;
     struct attrib *attr_list;
{
  tree return_type  = TREE_TYPE (subprog_type);
  tree subprog_decl = build_decl (FUNCTION_DECL, subprog_name, subprog_type);

  /* If this is a function nested inside an inlined external function, it
     means we aren't going to compile the outer function unless it is
     actually inlined, so do the same for us.  */
  if (current_function_decl != 0 && DECL_INLINE (current_function_decl)
      && DECL_EXTERNAL (current_function_decl))
    extern_flag = 1;

  DECL_EXTERNAL (subprog_decl)  = extern_flag;
  TREE_PUBLIC (subprog_decl)    = public_flag;
  DECL_INLINE (subprog_decl)    = inline_flag;
  TREE_READONLY (subprog_decl)  = TYPE_READONLY (subprog_type);
  TREE_THIS_VOLATILE (subprog_decl) = TYPE_VOLATILE (subprog_type);
  TREE_SIDE_EFFECTS (subprog_decl) = TYPE_VOLATILE (subprog_type);
  DECL_ARGUMENTS (subprog_decl) = param_decl_list;
  DECL_RESULT (subprog_decl)    = build_decl (RESULT_DECL, 0, return_type);

  if (asm_name != 0)
    DECL_ASSEMBLER_NAME (subprog_decl) = asm_name;

  process_attributes (subprog_decl, attr_list);

  /* Add this decl to the current binding level.  */
  subprog_decl = pushdecl (subprog_decl);

  /* Output the assembler code and/or RTL for the declaration.  */
  rest_of_decl_compilation (subprog_decl, 0, global_bindings_p (), 0);

  return subprog_decl;
}

/* Count how deep we are into nested functions.  This is because
   we shouldn't call the backend function context routines unless we
   are in a nested function.  */

static int function_nesting_depth;

/* Set up the framework for generating code for SUBPROG_DECL, a subprogram
   body. This routine needs to be invoked before processing the declarations
   appearing in the subprogram.  */

void
begin_subprog_body (subprog_decl)
     tree subprog_decl;
{
  tree param_decl_list;
  tree param_decl;
  tree next_param;

  if (function_nesting_depth++ != 0)
    push_function_context ();

  announce_function (subprog_decl);

  /* Make this field nonzero so further routines know that this is not
     tentative. error_mark_node is replaced below (in poplevel) with the
     adequate BLOCK.  */
  DECL_INITIAL (subprog_decl)  = error_mark_node;

  /* This function exists in static storage. This does not mean `static' in
     the C sense!  */
  TREE_STATIC (subprog_decl)   = 1;

  /* Enter a new binding level.  */
  current_function_decl = subprog_decl;
  pushlevel (0);

  /* Push all the PARM_DECL nodes onto the current scope (i.e. the scope of the
     subprogram body) so that they can be recognized as local variables in the
     subprogram. 

     The list of PARM_DECL nodes is stored in the right order in
     DECL_ARGUMENTS.  Since ..._DECL nodes get stored in the reverse order in
     which they are transmitted to `pushdecl' we need to reverse the list of
     PARM_DECLs if we want it to be stored in the right order. The reason why
     we want to make sure the PARM_DECLs are stored in the correct order is
     that this list will be retrieved in a few lines with a call to `getdecl'
     to store it back into the DECL_ARGUMENTS field.  */
    param_decl_list = nreverse (DECL_ARGUMENTS (subprog_decl));

    for (param_decl = param_decl_list; param_decl; param_decl = next_param)
      {
	next_param = TREE_CHAIN (param_decl);
	TREE_CHAIN (param_decl) = NULL;
	pushdecl (param_decl);
      }

  /* Store back the PARM_DECL nodes. They appear in the right order. */
  DECL_ARGUMENTS (subprog_decl) = getdecls ();

  init_function_start   (subprog_decl, input_filename, lineno);
  expand_function_start (subprog_decl, 0);
}


/* Finish the definition of the current subprogram and compile it all the way
   to assembler language output.  */

void
end_subprog_body ()
{
  tree decl;
  tree cico_list;

  poplevel (1, 0, 1);
  BLOCK_SUPERCONTEXT (DECL_INITIAL (current_function_decl))
    = current_function_decl;

  /* Mark the RESULT_DECL as being in this subprogram. */
  DECL_CONTEXT (DECL_RESULT (current_function_decl)) = current_function_decl;

  expand_function_end (input_filename, lineno, 0);

  /* If this is a nested function, push a new GC context.  That will keep
     local variables on the stack from being collected while we're doing
     the compilation of this function.  */
  if (function_nesting_depth > 1)
    ggc_push_context ();

  rest_of_compilation (current_function_decl);

  if (function_nesting_depth > 1)
    ggc_pop_context ();

#if 0
  /* If we're sure this function is defined in this file then mark it
     as such */
  if (TREE_ASM_WRITTEN (current_function_decl))
    mark_fn_defined_in_this_file (current_function_decl);
#endif

  /* Throw away any VAR_DECLs we made for OUT parameters; they must
     not be seen when we call this function and will be in
     unallocated memory anyway.  */
  for (cico_list = TYPE_CI_CO_LIST (TREE_TYPE (current_function_decl));
       cico_list != 0; cico_list = TREE_CHAIN (cico_list))
    TREE_VALUE (cico_list) = 0;

  if (DECL_SAVED_INSNS (current_function_decl) == 0)
    {
      /* Throw away DECL_RTL in any PARM_DECLs unless this function
	 was saved for inline, in which case the DECL_RTLs are in
	 preserved memory.  */
      for (decl = DECL_ARGUMENTS (current_function_decl);
	   decl != 0; decl = TREE_CHAIN (decl))
	{
	  SET_DECL_RTL (decl, 0);
	  DECL_INCOMING_RTL (decl) = 0;
	}

      /* Similarly, discard DECL_RTL of the return value.  */
      SET_DECL_RTL (DECL_RESULT (current_function_decl), 0);

      /* But DECL_INITIAL must remain nonzero so we know this
	 was an actual function definition unless toplev.c decided not
	 to inline it.  */
      if (DECL_INITIAL (current_function_decl) != 0)
	DECL_INITIAL (current_function_decl) = error_mark_node;

      DECL_ARGUMENTS (current_function_decl) = 0;
    }

  /* If we are not at the bottom of the function nesting stack, pop up to
     the containing function.  Otherwise show we aren't in any function.  */
  if (--function_nesting_depth != 0)
    pop_function_context ();
  else
    current_function_decl = 0;
}

/* Return a definition for a builtin function named NAME and whose data type
   is TYPE.  TYPE should be a function type with argument types.
   FUNCTION_CODE tells later passes how to compile calls to this function.
   See tree.h for its possible values.

   If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
   the name to be called if we can't opencode the function.  */

tree
builtin_function (name, type, function_code, class, library_name)
     const char *name;
     tree type;
     int function_code;
     enum built_in_class class;
     const char *library_name;
{
  tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);

  DECL_EXTERNAL (decl) = 1;
  TREE_PUBLIC (decl) = 1;
  if (library_name)
    DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);

  pushdecl (decl);
  DECL_BUILT_IN_CLASS (decl) = class;
  DECL_FUNCTION_CODE (decl) = function_code;
  return decl;
}

/* Return an integer type with the number of bits of precision given by  
   PRECISION.  UNSIGNEDP is nonzero if the type is unsigned; otherwise
   it is a signed type.  */

tree
type_for_size (precision, unsignedp)
     unsigned precision;
     int unsignedp;
{
  tree t;
  char type_name[20];

  if (precision <= 2 * MAX_BITS_PER_WORD
      && signed_and_unsigned_types[precision][unsignedp] != 0)
    return signed_and_unsigned_types[precision][unsignedp];

 if (unsignedp)
    t = make_unsigned_type (precision);
  else
    t = make_signed_type (precision);

  if (precision <= 2 * MAX_BITS_PER_WORD)
    signed_and_unsigned_types[precision][unsignedp] = t;

  if (TYPE_NAME (t) == 0)
    {
      sprintf (type_name, "%sSIGNED_%d", unsignedp ? "UN" : "", precision);
      TYPE_NAME (t) = get_identifier (type_name);
    }

  return t;
}

/* Likewise for floating-point types.  */

static tree
float_type_for_size (precision, mode)
     int precision;
     enum machine_mode mode;
{
  tree t;
  char type_name[20];

  if (float_types[(int) mode] != 0)
    return float_types[(int) mode];

  float_types[(int) mode] = t = make_node (REAL_TYPE);
  TYPE_PRECISION (t) = precision;
  layout_type (t);

  if (TYPE_MODE (t) != mode)
    gigi_abort (414);

  if (TYPE_NAME (t) == 0)
    {
      sprintf (type_name, "FLOAT_%d", precision);
      TYPE_NAME (t) = get_identifier (type_name);
    }

  return t;
}

/* Return a data type that has machine mode MODE.  UNSIGNEDP selects
   an unsigned type; otherwise a signed type is returned.  */

tree
type_for_mode (mode, unsignedp)
     enum machine_mode mode;
     int unsignedp;
{
  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
    return float_type_for_size (GET_MODE_BITSIZE (mode), mode);
  else
    return type_for_size (GET_MODE_BITSIZE (mode), unsignedp);
}

/* Return the unsigned version of a TYPE_NODE, a scalar type.  */

tree
unsigned_type (type_node)
     tree type_node;
{
  tree type = type_for_size (TYPE_PRECISION (type_node), 1);

  if (TREE_CODE (type_node) == INTEGER_TYPE && TYPE_MODULAR_P (type_node))
    {
      type = copy_node (type);
      TREE_TYPE (type) = type_node;
    }
  else if (TREE_TYPE (type_node) != 0
	   && TREE_CODE (TREE_TYPE (type_node)) == INTEGER_TYPE
	   && TYPE_MODULAR_P (TREE_TYPE (type_node)))
    {
      type = copy_node (type);
      TREE_TYPE (type) = TREE_TYPE (type_node);
    }

  return type;
}

/* Return the signed version of a TYPE_NODE, a scalar type.  */

tree
signed_type (type_node)
     tree type_node;
{
  tree type = type_for_size (TYPE_PRECISION (type_node), 0);

  if (TREE_CODE (type_node) == INTEGER_TYPE && TYPE_MODULAR_P (type_node))
    {
      type = copy_node (type);
      TREE_TYPE (type) = type_node;
    }
  else if (TREE_TYPE (type_node) != 0
	   && TREE_CODE (TREE_TYPE (type_node)) == INTEGER_TYPE
	   && TYPE_MODULAR_P (TREE_TYPE (type_node)))
    {
      type = copy_node (type);
      TREE_TYPE (type) = TREE_TYPE (type_node);
    }

  return type;
}

/* Return a type the same as TYPE except unsigned or signed according to
   UNSIGNEDP.  */

tree
signed_or_unsigned_type (unsignedp, type)
     int unsignedp;
     tree type;
{
  if (! INTEGRAL_TYPE_P (type) || TREE_UNSIGNED (type) == unsignedp)
    return type;
  else
    return type_for_size (TYPE_PRECISION (type), unsignedp);
}

/* EXP is an expression for the size of an object.  If this size contains
   discriminant references, replace them with the maximum (if MAX_P) or
   minimum (if ! MAX_P) possible value of the discriminant.  */

tree
max_size (exp, max_p)
     tree exp;
     int max_p;
{
  enum tree_code code = TREE_CODE (exp);
  tree type = TREE_TYPE (exp);

  switch (TREE_CODE_CLASS (code))
    {
    case 'd':
    case 'c':
      return exp;

    case 'x':
      if (code == TREE_LIST)
	return tree_cons (TREE_PURPOSE (exp),
			  max_size (TREE_VALUE (exp), max_p),
			  TREE_CHAIN (exp) != 0
			  ? max_size (TREE_CHAIN (exp), max_p) : 0);
      break;

    case 'r':
      /* If this contains a PLACEHOLDER_EXPR, it is the thing we want to
	 modify.  Otherwise, we abort since it is something we can't
	 handle.  */
      if (! contains_placeholder_p (exp))
	gigi_abort (406);

      type = TREE_TYPE (TREE_OPERAND (exp, 1));
      return
	max_size (max_p ? TYPE_MAX_VALUE (type) : TYPE_MIN_VALUE (type), 1);

    case '<':
      return max_p ? size_one_node : size_zero_node;

    case '1':
    case '2':
    case 'e':
      switch (TREE_CODE_LENGTH (code))
	{
	case 1:
	  if (code == NON_LVALUE_EXPR)
	    return max_size (TREE_OPERAND (exp, 0), max_p);
	  else
	    return
	      fold (build1 (code, type,
			    max_size (TREE_OPERAND (exp, 0),
				      code == NEGATE_EXPR ? ! max_p : max_p)));

	case 2:
	  if (code == RTL_EXPR)
	    gigi_abort (407);
	  else if (code == COMPOUND_EXPR)
	    return max_size (TREE_OPERAND (exp, 1), max_p);
	  else if (code == WITH_RECORD_EXPR)
	    return exp;

	  {
	    tree lhs = max_size (TREE_OPERAND (exp, 0), max_p);
	    tree rhs = max_size (TREE_OPERAND (exp, 1),
				 code == MINUS_EXPR ? ! max_p : max_p);

	    /* Special-case wanting the maximum value of a MIN_EXPR.
	       In that case, if one side overflows, return the other.
	       sizetype is signed, but we know sizes are non-negative.
	       Likewise, handle a MINUS_EXPR or PLUS_EXPR with the LHS
	       overflowing or the maximum possible value and the RHS
	       a variable.  */
	    if (max_p && code == MIN_EXPR && TREE_OVERFLOW (rhs))
	      return lhs;
	    else if (max_p && code == MIN_EXPR && TREE_OVERFLOW (lhs))
	      return rhs;
	    else if ((code == MINUS_EXPR || code == PLUS_EXPR)
		     && (TREE_OVERFLOW (lhs)
			 || operand_equal_p (lhs, TYPE_MAX_VALUE (type), 0))
		     && ! TREE_CONSTANT (rhs))
	      return lhs;
	    else
	      return fold (build (code, type, lhs, rhs));
	  }

	case 3:
	  if (code == SAVE_EXPR)
	    return exp;
	  else if (code == COND_EXPR)
	    return fold (build (MAX_EXPR, type,
				max_size (TREE_OPERAND (exp, 1), max_p),
				max_size (TREE_OPERAND (exp, 2), max_p)));
	  else if (code == CALL_EXPR && TREE_OPERAND (exp, 1) != 0)
	    return build (CALL_EXPR, type, TREE_OPERAND (exp, 0),
			  max_size (TREE_OPERAND (exp, 1), max_p));
	}
    }

  gigi_abort (408);
}

/* Build a template of type TEMPLATE_TYPE from the array bounds of ARRAY_TYPE.
   EXPR is an expression that we can use to locate any PLACEHOLDER_EXPRs.
   Return a constructor for the template.  */

tree
build_template (template_type, array_type, expr)
     tree template_type;
     tree array_type;
     tree expr;
{
  tree template_elts = NULL_TREE;
  tree bound_list = NULL_TREE;
  tree field;

  if (TREE_CODE (array_type) == RECORD_TYPE
      && (TYPE_IS_PADDING_P (array_type)
	  || TYPE_LEFT_JUSTIFIED_MODULAR_P (array_type)))
    array_type = TREE_TYPE (TYPE_FIELDS (array_type));

  if (TREE_CODE (array_type) == ARRAY_TYPE
      || (TREE_CODE (array_type) == INTEGER_TYPE
	  && TYPE_HAS_ACTUAL_BOUNDS_P (array_type)))
    bound_list = TYPE_ACTUAL_BOUNDS (array_type);

  /* First make the list for a CONSTRUCTOR for the template.   Go down the
     field list of the template instead of the type chain because this
     array might be an Ada array of arrays and we can't tell where the
     nested arrays stop being the underlying object.  */

  for (field = TYPE_FIELDS (template_type); field;
       (bound_list != 0
	? (bound_list = TREE_CHAIN (bound_list))
	: (array_type = TREE_TYPE (array_type))),
       field = TREE_CHAIN (TREE_CHAIN (field)))
    {
      tree bounds, min, max;

      /* If we have a bound list, get the bounds from there.  Likewise
	 for an ARRAY_TYPE.  Otherwise, if expr is a PARM_DECL with
	 DECL_BY_COMPONENT_PTR_P, use the bounds of the field in the template.
	 This will give us a maximum range.  */
      if (bound_list != 0)
	bounds = TREE_VALUE (bound_list);
      else if (TREE_CODE (array_type) == ARRAY_TYPE)
	bounds = TYPE_INDEX_TYPE (TYPE_DOMAIN (array_type));
      else if (expr != 0 && TREE_CODE (expr) == PARM_DECL
	       && DECL_BY_COMPONENT_PTR_P (expr))
	bounds = TREE_TYPE (field);
      else
	gigi_abort (411);

      min = convert (TREE_TYPE (TREE_CHAIN (field)), TYPE_MIN_VALUE (bounds));
      max = convert (TREE_TYPE (field), TYPE_MAX_VALUE (bounds));

      /* If either MIN or MAX involve a PLACEHOLDER_EXPR, we must
	 surround them with a WITH_RECORD_EXPR giving EXPR as the
	 OBJECT.  */
      if (! TREE_CONSTANT (min) && contains_placeholder_p (min))
	min = build (WITH_RECORD_EXPR, TREE_TYPE (min), min, expr);
      if (! TREE_CONSTANT (max) && contains_placeholder_p (max))
	max = build (WITH_RECORD_EXPR, TREE_TYPE (max), max, expr);

      template_elts = tree_cons (TREE_CHAIN (field), max,
				 tree_cons (field, min, template_elts));
    }

  return build_constructor (template_type, nreverse (template_elts));
}

/* Build a VMS descriptor from a Mechanism_Type, which must specify
   a descriptor type, and the GCC type of an object.  Each FIELD_DECL
   in the type contains in its DECL_INITIAL the expression to use when
   a constructor is made for the type.  GNAT_ENTITY is a gnat node used
   to print out an error message if the mechanism cannot be applied to
   an object of that type and also for the name.  */

tree
build_vms_descriptor (type, mech, gnat_entity)
     tree type;
     Mechanism_Type mech;
     Entity_Id gnat_entity;
{
  tree record_type = make_node (RECORD_TYPE);
  tree field_list = 0;
  int class;
  int dtype = 0;
  tree inner_type;
  int ndim;
  int i;
  tree *idx_arr;
  tree tem;

  /* If TYPE is an unconstrained array, use the underlying array type.  */
  if (TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
    type = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (type))));

  /* If this is an array, compute the number of dimensions in the array,
     get the index types, and point to the inner type.  */
  if (TREE_CODE (type) != ARRAY_TYPE)
    ndim = 0;
  else
    for (ndim = 1, inner_type = type;
	 TREE_CODE (TREE_TYPE (inner_type)) == ARRAY_TYPE
	 && TYPE_MULTI_ARRAY_P (TREE_TYPE (inner_type));
	 ndim++, inner_type = TREE_TYPE (inner_type))
      ;

  idx_arr = (tree *) alloca (ndim * sizeof (tree));

  if (mech != By_Descriptor_NCA
      && TREE_CODE (type) == ARRAY_TYPE && TYPE_CONVENTION_FORTRAN_P (type))
    for (i = ndim - 1, inner_type = type;
	 i >= 0;
	 i--, inner_type = TREE_TYPE (inner_type))
      idx_arr[i] = TYPE_DOMAIN (inner_type);
  else
    for (i = 0, inner_type = type;
	 i < ndim;
	 i++, inner_type = TREE_TYPE (inner_type))
      idx_arr[i] = TYPE_DOMAIN (inner_type);

  /* Now get the DTYPE value.  */
  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
      if (TYPE_VAX_FLOATING_POINT_P (type))
	switch ((int) TYPE_DIGITS_VALUE (type))
	  {
	  case 6:
	    dtype = 10;
	    break;
	  case 9:
	    dtype = 11;
	    break;
	  case 15:
	    dtype = 27;
	    break;
	  }
      else
	switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
	  {
	  case 8:
	    dtype = TREE_UNSIGNED (type) ? 2 : 6;
	    break;
	  case 16:
	    dtype = TREE_UNSIGNED (type) ? 3 : 7;
	    break;
	  case 32:
	    dtype = TREE_UNSIGNED (type) ? 4 : 8;
	    break;
	  case 64:
	    dtype = TREE_UNSIGNED (type) ? 5 : 9;
	    break;
	  case 128:
	    dtype = TREE_UNSIGNED (type) ? 25 : 26;
	    break;
	  }
      break;

    case REAL_TYPE:
      dtype = GET_MODE_BITSIZE (TYPE_MODE (type)) == 32 ? 52 : 53;
      break;

    case COMPLEX_TYPE:
      if (TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
	  && TYPE_VAX_FLOATING_POINT_P (type))
	switch ((int) TYPE_DIGITS_VALUE (type))
	  {
	  case 6:
	    dtype = 12;
	    break;
	  case 9:
	    dtype = 13;
	    break;
	  case 15:
	    dtype = 29;
	  }
      else
	dtype = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type))) == 32 ? 54: 55;
      break;

    case ARRAY_TYPE:
      dtype = 14;
      break;

    default:
      break;
    }

  /* Get the CLASS value.  */
  switch (mech)
    {
    case By_Descriptor_A:
      class = 4;
      break;
    case By_Descriptor_NCA:
      class = 10;
      break;
    case By_Descriptor_SB:
      class = 15;
      break;
    default:
      class = 1;
    }

  /* Make the type for a descriptor for VMS.  The first four fields
     are the same for all types.  */

  field_list
    = chainon (field_list,
	       make_descriptor_field
	       ("LENGTH", type_for_size (16, 1), record_type,
		size_in_bytes (mech == By_Descriptor_A ? inner_type : type)));

  field_list = chainon (field_list,
			make_descriptor_field ("DTYPE", type_for_size (8, 1),
					       record_type, size_int (dtype)));
  field_list = chainon (field_list,
			make_descriptor_field ("CLASS", type_for_size (8, 1),
					       record_type, size_int (class)));

  field_list
    = chainon (field_list,
	       make_descriptor_field ("POINTER",
				      build_pointer_type (type),
				      record_type,
				      build1 (ADDR_EXPR,
					      build_pointer_type (type),
					      build (PLACEHOLDER_EXPR,
						     type))));

  switch (mech)
    {
    case By_Descriptor:
    case By_Descriptor_S:
      break;

    case By_Descriptor_SB:
      field_list
	= chainon (field_list,
		   make_descriptor_field 
		   ("SB_L1", type_for_size (32, 1), record_type,
		    TREE_CODE (type) == ARRAY_TYPE
		    ? TYPE_MIN_VALUE (TYPE_DOMAIN (type)) : size_zero_node));
      field_list
	= chainon (field_list,
		   make_descriptor_field
		   ("SB_L2", type_for_size (32, 1), record_type,
		    TREE_CODE (type) == ARRAY_TYPE
		    ? TYPE_MAX_VALUE (TYPE_DOMAIN (type)) : size_zero_node));
      break;

    case By_Descriptor_A:
    case By_Descriptor_NCA:
      field_list = chainon (field_list,
			    make_descriptor_field ("SCALE",
						   type_for_size (8, 1),
						   record_type,
						   size_zero_node));

      field_list = chainon (field_list,
			    make_descriptor_field ("DIGITS",
						   type_for_size (8, 1),
						   record_type,
						   size_zero_node));

      field_list
	= chainon (field_list,
		   make_descriptor_field
		   ("AFLAGS", type_for_size (8, 1), record_type,
		    size_int (mech == By_Descriptor_NCA
			      ? 0
			      /* Set FL_COLUMN, FL_COEFF, and FL_BOUNDS.  */
			      : (TREE_CODE (type) == ARRAY_TYPE
				 && TYPE_CONVENTION_FORTRAN_P (type)
				 ? 224 : 192))));

      field_list = chainon (field_list,
			    make_descriptor_field ("DIMCT",
						   type_for_size (8, 1),
						   record_type,
						   size_int (ndim)));

      field_list = chainon (field_list,
			    make_descriptor_field ("ARSIZE",
						   type_for_size (32, 1),
						   record_type,
						   size_in_bytes (type)));

      /* Now build a pointer to the 0,0,0... element.  */
      tem = build (PLACEHOLDER_EXPR, type);
      for (i = 0, inner_type = type; i < ndim;
	   i++, inner_type = TREE_TYPE (inner_type))
	tem = build (ARRAY_REF, TREE_TYPE (inner_type), tem,
		     convert (TYPE_DOMAIN (inner_type), size_zero_node));

      field_list
	= chainon (field_list,
		   make_descriptor_field
		   ("A0", build_pointer_type (inner_type), record_type,
		    build1 (ADDR_EXPR, build_pointer_type (inner_type), tem)));

      /* Next come the addressing coefficients.  */
      tem = size_int (1);
      for (i = 0; i < ndim; i++)
	{
	  char fname[3];
	  tree idx_length
	    = size_binop (MULT_EXPR, tem,
			  size_binop (PLUS_EXPR,
				      size_binop (MINUS_EXPR,
						  TYPE_MAX_VALUE (idx_arr[i]),
						  TYPE_MIN_VALUE (idx_arr[i])),
				      size_int (1)));

	  fname[0] = (mech == By_Descriptor_NCA ? 'S' : 'M');
	  fname[1] = '0' + i, fname[2] = 0;
	  field_list = chainon (field_list,
				make_descriptor_field (fname,
						       type_for_size (32, 1),
						       record_type,
						       idx_length));

	  if (mech == By_Descriptor_NCA)
	    tem = idx_length;
	}

      /* Finally here are the bounds.  */
      for (i = 0; i < ndim; i++)
	{
	  char fname[3];

	  fname[0] = 'L', fname[1] = '0' + i, fname[2] = 0;
	  field_list
	    = chainon (field_list,
		       make_descriptor_field
		       (fname, type_for_size (32, 1), record_type,
			TYPE_MIN_VALUE (idx_arr[i])));

	  fname[0] = 'U';
	  field_list
	    = chainon (field_list,
		       make_descriptor_field
		       (fname, type_for_size (32, 1), record_type,
			TYPE_MAX_VALUE (idx_arr[i])));
	}
      break;

    default:
      post_error ("unsupported descriptor type for &", gnat_entity);
    }

  finish_record_type (record_type, field_list, 0, 1);
  pushdecl (build_decl (TYPE_DECL, create_concat_name (gnat_entity, "DESC"),
			record_type));

  return record_type;
}

/* Utility routine for above code to make a field.  */

static tree
make_descriptor_field (name, type, rec_type, initial)
     const char *name;
     tree type;
     tree rec_type;
     tree initial;
{
  tree field
    = create_field_decl (get_identifier (name), type, rec_type, 0, 0, 0, 0);

  DECL_INITIAL (field) = initial;
  return field;
}

/* Build a type to be used to represent an aliased object whose nominal
   type is an unconstrained array.  This consists of a RECORD_TYPE containing
   a field of TEMPLATE_TYPE and a field of OBJECT_TYPE, which is an
   ARRAY_TYPE.  If ARRAY_TYPE is that of the unconstrained array, this
   is used to represent an arbitrary unconstrained object.  Use NAME
   as the name of the record.  */

tree
build_unc_object_type (template_type, object_type, name)
     tree template_type;
     tree object_type;
     tree name;
{
  tree type = make_node (RECORD_TYPE);
  tree template_field = create_field_decl (get_identifier ("BOUNDS"),
					   template_type, type, 0, 0, 0, 1);
  tree array_field = create_field_decl (get_identifier ("ARRAY"), object_type,
					type, 0, 0, 0, 1);

  TYPE_NAME (type) = name;
  TYPE_CONTAINS_TEMPLATE_P (type) = 1;
  finish_record_type (type,
		      chainon (chainon (NULL_TREE, template_field),
			       array_field),
		      0, 0);

  return type;
}

/* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE.  In
   the normal case this is just two adjustments, but we have more to do
   if NEW is an UNCONSTRAINED_ARRAY_TYPE.  */

void
update_pointer_to (old_type, new_type)
     tree old_type;
     tree new_type;
{
  tree ptr = TYPE_POINTER_TO (old_type);
  tree ref = TYPE_REFERENCE_TO (old_type);
  tree type;

  /* If this is the main variant, process all the other variants first.  */
  if (TYPE_MAIN_VARIANT (old_type) == old_type)
    for (type = TYPE_NEXT_VARIANT (old_type); type != 0;
	 type = TYPE_NEXT_VARIANT (type))
      update_pointer_to (type, new_type);

  /* If no pointer or reference, we are done.  Otherwise, get the new type with
     the same qualifiers as the old type and see if it is the same as the old
     type.  */
  if (ptr == 0 && ref == 0)
    return;

  new_type = build_qualified_type (new_type, TYPE_QUALS (old_type));
  if (old_type == new_type)
    return;

  /* First handle the simple case.  */
  if (TREE_CODE (new_type) != UNCONSTRAINED_ARRAY_TYPE)
    {
      if (ptr != 0)
	TREE_TYPE (ptr) = new_type;
      TYPE_POINTER_TO (new_type) = ptr;

      if (ref != 0)
	TREE_TYPE (ref) = new_type;
      TYPE_REFERENCE_TO (new_type) = ref;

      if (ptr != 0 && TYPE_NAME (ptr) != 0
	  && TREE_CODE (TYPE_NAME (ptr)) == TYPE_DECL
	  && TREE_CODE (new_type) != ENUMERAL_TYPE)
	rest_of_decl_compilation (TYPE_NAME (ptr), NULL,
				  global_bindings_p (), 0);
      if (ref != 0 && TYPE_NAME (ref) != 0
	  && TREE_CODE (TYPE_NAME (ref)) == TYPE_DECL
	  && TREE_CODE (new_type) != ENUMERAL_TYPE)
	rest_of_decl_compilation (TYPE_NAME (ref), NULL,
				  global_bindings_p (), 0);
    }

  /* Now deal with the unconstrained array case. In this case the "pointer"
     is actually a RECORD_TYPE where the types of both fields are
     pointers to void.  In that case, copy the field list from the
     old type to the new one and update the fields' context. */
  else if (TREE_CODE (ptr) != RECORD_TYPE || ! TYPE_IS_FAT_POINTER_P (ptr))
    gigi_abort (412);

  else
    {
      tree new_obj_rec = TYPE_OBJECT_RECORD_TYPE (new_type);
      tree ptr_temp_type;
      tree new_ref;
      tree var;

      TYPE_FIELDS (ptr) = TYPE_FIELDS (TYPE_POINTER_TO (new_type));
      DECL_CONTEXT (TYPE_FIELDS (ptr)) = ptr;
      DECL_CONTEXT (TREE_CHAIN (TYPE_FIELDS (ptr))) = ptr;

      /* Rework the PLACEHOLDER_EXPR inside the reference to the
	 template bounds.

	 ??? This is now the only use of gnat_substitute_in_type, which
	 is now a very "heavy" routine to do this, so it should be replaced
	 at some point.  */
      ptr_temp_type = TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (ptr)));
      new_ref = build (COMPONENT_REF, ptr_temp_type,
		       build (PLACEHOLDER_EXPR, ptr),
		       TREE_CHAIN (TYPE_FIELDS (ptr)));

      update_pointer_to 
	(TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr))),
	 gnat_substitute_in_type (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr))),
				  TREE_CHAIN (TYPE_FIELDS (ptr)), new_ref));

      for (var = TYPE_MAIN_VARIANT (ptr); var; var = TYPE_NEXT_VARIANT (var))
	TYPE_UNCONSTRAINED_ARRAY (var) = new_type;

      TYPE_POINTER_TO (new_type) = TYPE_REFERENCE_TO (new_type)
	= TREE_TYPE (new_type) = ptr;

      /* Now handle updating the allocation record, what the thin pointer
	 points to.  Update all pointers from the old record into the new
	 one, update the types of the fields, and recompute the size.  */

      update_pointer_to (TYPE_OBJECT_RECORD_TYPE (old_type), new_obj_rec);

      TREE_TYPE (TYPE_FIELDS (new_obj_rec)) = TREE_TYPE (ptr_temp_type);
      TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (new_obj_rec)))
	= TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr)));
      DECL_SIZE (TREE_CHAIN (TYPE_FIELDS (new_obj_rec)))
	= TYPE_SIZE (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr))));
      DECL_SIZE_UNIT (TREE_CHAIN (TYPE_FIELDS (new_obj_rec)))
	= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr))));

      TYPE_SIZE (new_obj_rec)
	= size_binop (PLUS_EXPR,
		      DECL_SIZE (TYPE_FIELDS (new_obj_rec)),
		      DECL_SIZE (TREE_CHAIN (TYPE_FIELDS (new_obj_rec))));
      TYPE_SIZE_UNIT (new_obj_rec)
	= size_binop (PLUS_EXPR,
		      DECL_SIZE_UNIT (TYPE_FIELDS (new_obj_rec)),
		      DECL_SIZE_UNIT (TREE_CHAIN (TYPE_FIELDS (new_obj_rec))));
      rest_of_type_compilation (ptr, global_bindings_p ());
    }
}

/* Convert a pointer to a constrained array into a pointer to a fat
   pointer.  This involves making or finding a template.  */

static tree
convert_to_fat_pointer (type, expr)
     tree type;
     tree expr;
{
  tree template_type = TREE_TYPE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (type))));
  tree template, template_addr;
  tree etype = TREE_TYPE (expr);

  /* If EXPR is a constant of zero, we make a fat pointer that has a null
     pointer to the template and array.  */
  if (integer_zerop (expr))
    return
      build_constructor
	(type,
	 tree_cons (TYPE_FIELDS (type),
		    convert (TREE_TYPE (TYPE_FIELDS (type)), expr),
		    tree_cons (TREE_CHAIN (TYPE_FIELDS (type)),
			       convert (build_pointer_type (template_type),
					expr),
			       NULL_TREE)));

  /* If EXPR is a thin pointer, make the template and data from the record.  */

  else if (TYPE_THIN_POINTER_P (etype))
    {
      tree fields = TYPE_FIELDS (TREE_TYPE (etype));

      expr = save_expr (expr);
      if (TREE_CODE (expr) == ADDR_EXPR)
	expr = TREE_OPERAND (expr, 0);
      else
	expr = build1 (INDIRECT_REF, TREE_TYPE (etype), expr);

      template = build_component_ref (expr, NULL_TREE, fields);
      expr = build_unary_op (ADDR_EXPR, NULL_TREE,
			     build_component_ref (expr, NULL_TREE,
						  TREE_CHAIN (fields)));
    }
  else
    /* Otherwise, build the constructor for the template.  */
    template = build_template (template_type, TREE_TYPE (etype), expr);

  template_addr = build_unary_op (ADDR_EXPR, NULL_TREE, template);

  /* The result is a CONSTRUCTOR for the fat pointer.  */
  return
    build_constructor (type,
		       tree_cons (TYPE_FIELDS (type), expr,
				  tree_cons (TREE_CHAIN (TYPE_FIELDS (type)),
					     template_addr, NULL_TREE)));
}

/* Convert to a thin pointer type, TYPE.  The only thing we know how to convert
   is something that is a fat pointer, so convert to it first if it EXPR
   is not already a fat pointer.  */

static tree
convert_to_thin_pointer (type, expr)
     tree type;
     tree expr;
{
  if (! TYPE_FAT_POINTER_P (TREE_TYPE (expr)))
    expr
      = convert_to_fat_pointer
	(TREE_TYPE (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type))), expr);

  /* We get the pointer to the data and use a NOP_EXPR to make it the
     proper GCC type.  */
  expr = build_component_ref (expr, NULL_TREE, TYPE_FIELDS (TREE_TYPE (expr)));
  expr = build1 (NOP_EXPR, type, expr);

  return expr;
}

/* Create an expression whose value is that of EXPR,
   converted to type TYPE.  The TREE_TYPE of the value
   is always TYPE.  This function implements all reasonable
   conversions; callers should filter out those that are
   not permitted by the language being compiled.  */

tree
convert (type, expr)
     tree type, expr;
{
  enum tree_code code = TREE_CODE (type);
  tree etype = TREE_TYPE (expr);
  enum tree_code ecode = TREE_CODE (etype);
  tree tem;

  /* If EXPR is already the right type, we are done.  */
  if (type == etype)
    return expr;

  /* If EXPR is a WITH_RECORD_EXPR, do the conversion inside and then make a
     new one.  */
  if (TREE_CODE (expr) == WITH_RECORD_EXPR)
    return build (WITH_RECORD_EXPR, type,
		  convert (type, TREE_OPERAND (expr, 0)),
		  TREE_OPERAND (expr, 1));

  /* If the input type has padding, remove it by doing a component reference
     to the field.  If the output type has padding, make a constructor
     to build the record.  If both input and output have padding and are
     of variable size, do this as an unchecked conversion.  */
  if (ecode == RECORD_TYPE && code == RECORD_TYPE
      && TYPE_IS_PADDING_P (type) && TYPE_IS_PADDING_P (etype)
      && (! TREE_CONSTANT (TYPE_SIZE (type))
	  || ! TREE_CONSTANT (TYPE_SIZE (etype))))
    ;
  else if (ecode == RECORD_TYPE && TYPE_IS_PADDING_P (etype))
    {
      /* If we have just converted to this padded type, just get
	 the inner expression.  */
      if (TREE_CODE (expr) == CONSTRUCTOR
	  && CONSTRUCTOR_ELTS (expr) != 0
	  && TREE_PURPOSE (CONSTRUCTOR_ELTS (expr)) == TYPE_FIELDS (etype))
	return TREE_VALUE (CONSTRUCTOR_ELTS (expr));
      else
	return convert (type, build_component_ref (expr, NULL_TREE,
						   TYPE_FIELDS (etype)));
    }
  else if (code == RECORD_TYPE && TYPE_IS_PADDING_P (type))
    {
      /* If we previously converted from another type and our type is
	 of variable size, remove the conversion to avoid the need for
	 variable-size temporaries.  */
      if (TREE_CODE (expr) == UNCHECKED_CONVERT_EXPR
	  && ! TREE_CONSTANT (TYPE_SIZE (type)))
	expr = TREE_OPERAND (expr, 0);

      /* If we are just removing the padding from expr, convert the original
	 object if we have variable size.  That will avoid the need
	 for some variable-size temporaries.  */
      if (TREE_CODE (expr) == COMPONENT_REF
	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE
	  && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
	  && ! TREE_CONSTANT (TYPE_SIZE (type)))
	return convert (type, TREE_OPERAND (expr, 0));

      /* If the result type is a padded type with a self-referentially-sized
	 field and the expression type is a record, do this as an
	 unchecked converstion.  */
      else if (TREE_CODE (DECL_SIZE (TYPE_FIELDS (type))) != INTEGER_CST
	       && contains_placeholder_p (DECL_SIZE (TYPE_FIELDS (type)))
	       && TREE_CODE (etype) == RECORD_TYPE)
	return unchecked_convert (type, expr);

      else
	return
	  build_constructor (type,
			     tree_cons (TYPE_FIELDS (type),
					convert (TREE_TYPE
						 (TYPE_FIELDS (type)),
						 expr),
					NULL_TREE));
    }

  /* If the input is a biased type, adjust first.  */
  if (ecode == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (etype))
    return convert (type, fold (build (PLUS_EXPR, TREE_TYPE (etype),
				       fold (build1 (GNAT_NOP_EXPR,
						     TREE_TYPE (etype), expr)),
				       TYPE_MIN_VALUE (etype))));

  /* If the input is a left-justified modular type, we need to extract
     the actual object before converting it to any other type with the
     exception of an unconstrained array.  */
  if (ecode == RECORD_TYPE && TYPE_LEFT_JUSTIFIED_MODULAR_P (etype)
      && code != UNCONSTRAINED_ARRAY_TYPE)
    return convert (type, build_component_ref (expr, NULL_TREE,
					       TYPE_FIELDS (etype)));

  /* If converting a type that does not contain a template into one
     that does, convert to the data type and then build the template. */
  if (code == RECORD_TYPE && TYPE_CONTAINS_TEMPLATE_P (type)
      && ! (ecode == RECORD_TYPE && TYPE_CONTAINS_TEMPLATE_P (etype)))
    {
      tree obj_type = TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (type)));

      return
	build_constructor
	  (type,
	   tree_cons (TYPE_FIELDS (type),
		      build_template (TREE_TYPE (TYPE_FIELDS (type)),
				      obj_type, NULL_TREE),
		      tree_cons (TREE_CHAIN (TYPE_FIELDS (type)),
				 convert (obj_type, expr), NULL_TREE)));
    }

  /* There are some special cases of expressions that we process
     specially.  */
  switch (TREE_CODE (expr))
    {
    case ERROR_MARK:
      return expr;

    case TRANSFORM_EXPR:
    case NULL_EXPR:
      /* Just set its type here.  For TRANSFORM_EXPR, we will do the actual
	 conversion in gnat_expand_expr.  NULL_EXPR does not represent
	 and actual value, so no conversion is needed.  */
      TREE_TYPE (expr) = type;
      return expr;

    case STRING_CST:
    case CONSTRUCTOR:
      /* If we are converting a STRING_CST to another constrained array type,
	 just make a new one in the proper type.  Likewise for a
	 CONSTRUCTOR.  But if the mode of the type is different, we must
	 ensure a new RTL is made for the constant.  */
      if (code == ecode && AGGREGATE_TYPE_P (etype)
	  && ! (TREE_CODE (TYPE_SIZE (etype)) == INTEGER_CST
		&& TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST))
	{
	  expr = copy_node (expr);
	  TREE_TYPE (expr) = type;

	  if (TYPE_MODE (type) != TYPE_MODE (etype))
	    TREE_CST_RTL (expr) = 0;

	  return expr;
	}
      break;

    case COMPONENT_REF:
      /* If we are converting between two aggregate types of the same
	 kind, size, mode, and alignment, just make a new COMPONENT_REF.
	 This avoid unneeded conversions which makes reference computations
	 more complex.  */
      if (code == ecode && TYPE_MODE (type) == TYPE_MODE (etype)
	  && AGGREGATE_TYPE_P (type) && AGGREGATE_TYPE_P (etype)
	  && TYPE_ALIGN (type) == TYPE_ALIGN (etype)
	  && operand_equal_p (TYPE_SIZE (type), TYPE_SIZE (etype), 0))
	return build (COMPONENT_REF, type, TREE_OPERAND (expr, 0),
		      TREE_OPERAND (expr, 1));

      break;

    case UNCONSTRAINED_ARRAY_REF:
      /* Convert this to the type of the inner array by getting the address of
	 the array from the template.  */
      expr = build_unary_op (INDIRECT_REF, NULL_TREE,
			     build_component_ref (TREE_OPERAND (expr, 0),
						  get_identifier ("P_ARRAY"),
						  NULL_TREE));
      etype = TREE_TYPE (expr);
      ecode = TREE_CODE (etype);
      break;

    case UNCHECKED_CONVERT_EXPR:
      if (AGGREGATE_TYPE_P (type) && AGGREGATE_TYPE_P (etype)
	  && ! TYPE_FAT_POINTER_P (type) && ! TYPE_FAT_POINTER_P (etype))
	return convert (type, TREE_OPERAND (expr, 0));
      break;

    case INDIRECT_REF:
      /* If both types are record types, just convert the pointer and
	 make a new INDIRECT_REF. 

	 ??? Disable this for now since it causes problems with the
	 code in build_binary_op for MODIFY_EXPR which wants to
	 strip off conversions.  But that code really is a mess and
	 we need to do this a much better way some time.  */
      if (0
	  && (TREE_CODE (type) == RECORD_TYPE
	      || TREE_CODE (type) == UNION_TYPE)
	  && (TREE_CODE (etype) == RECORD_TYPE
	      || TREE_CODE (etype) == UNION_TYPE)
	  && ! TYPE_FAT_POINTER_P (type) && ! TYPE_FAT_POINTER_P (etype))
	return build_unary_op (INDIRECT_REF, NULL_TREE,
			       convert (build_pointer_type (type),
					TREE_OPERAND (expr, 0)));
      break;

    default:
      break;
    }

  /* Check for converting to a pointer to an unconstrained array.  */
  if (TYPE_FAT_POINTER_P (type) && ! TYPE_FAT_POINTER_P (etype))
    return convert_to_fat_pointer (type, expr);

  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (etype)
      || (code == INTEGER_CST && ecode == INTEGER_CST
	  && (type == TREE_TYPE (etype) || etype == TREE_TYPE (type))))
    return fold (build1 (NOP_EXPR, type, expr));

  switch (code)
    {
    case VOID_TYPE:
      return build1 (CONVERT_EXPR, type, expr);

    case INTEGER_TYPE:
      if (TYPE_HAS_ACTUAL_BOUNDS_P (type)
	  && (ecode == ARRAY_TYPE || ecode == UNCONSTRAINED_ARRAY_TYPE))
	return unchecked_convert (type, expr);
      else if (TYPE_BIASED_REPRESENTATION_P (type))
	return fold (build1 (CONVERT_EXPR, type,
			     fold (build (MINUS_EXPR, TREE_TYPE (type),
					  convert (TREE_TYPE (type), expr),
					  TYPE_MIN_VALUE (type)))));

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

    case ENUMERAL_TYPE:
      return fold (convert_to_integer (type, expr));

    case POINTER_TYPE:
    case REFERENCE_TYPE:
      /* If converting between two pointers to records denoting
	 both a template and type, adjust if needed to account
	 for any differing offsets, since one might be negative.  */
      if (TYPE_THIN_POINTER_P (etype) && TYPE_THIN_POINTER_P (type))
	{
	  tree bit_diff
	    = size_diffop (bit_position (TYPE_FIELDS (TREE_TYPE (etype))),
			   bit_position (TYPE_FIELDS (TREE_TYPE (type))));
	  tree byte_diff = size_binop (CEIL_DIV_EXPR, bit_diff,
				       sbitsize_int (BITS_PER_UNIT));

	  expr = build1 (NOP_EXPR, type, expr);
	  TREE_CONSTANT (expr) = TREE_CONSTANT (TREE_OPERAND (expr, 0));
	  if (integer_zerop (byte_diff))
	    return expr;

	  return build_binary_op (PLUS_EXPR, type, expr,
				  fold (convert_to_pointer (type, byte_diff)));
	}

      /* If converting to a thin pointer, handle specially.  */
      if (TYPE_THIN_POINTER_P (type)
	  && TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type)) != 0)
	return convert_to_thin_pointer (type, expr);

      /* If converting fat pointer to normal pointer, get the pointer to the
	 array and then convert it.  */
      else if (TYPE_FAT_POINTER_P (etype))
	expr = build_component_ref (expr, get_identifier ("P_ARRAY"),
				    NULL_TREE);

      return fold (convert_to_pointer (type, expr));

    case REAL_TYPE:
      return fold (convert_to_real (type, expr));

    case RECORD_TYPE:
      if (TYPE_LEFT_JUSTIFIED_MODULAR_P (type) && ! AGGREGATE_TYPE_P (etype))
	return
	  build_constructor
	    (type, tree_cons (TYPE_FIELDS (type),
			      convert (TREE_TYPE (TYPE_FIELDS (type)), expr),
			      NULL_TREE));

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

    case ARRAY_TYPE:
      /* In these cases, assume the front-end has validated the conversion.
	 If the conversion is valid, it will be a bit-wise conversion, so
	 it can be viewed as an unchecked conversion.  */
      return unchecked_convert (type, expr);

    case UNION_TYPE:
      /* Just validate that the type is indeed that of a field
	 of the type.  Then make the simple conversion.  */
      for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
	if (TREE_TYPE (tem) == etype)
	  return build1 (CONVERT_EXPR, type, expr);

      gigi_abort (413);

    case UNCONSTRAINED_ARRAY_TYPE:
      /* If EXPR is a constrained array, take its address, convert it to a
	 fat pointer, and then dereference it.  Likewise if EXPR is a
	 record containing both a template and a constrained array.
	 Note that a record representing a left justified modular type
	 always represents a packed constrained array.  */
      if (ecode == ARRAY_TYPE
	  || (ecode == INTEGER_TYPE && TYPE_HAS_ACTUAL_BOUNDS_P (etype))
	  || (ecode == RECORD_TYPE && TYPE_CONTAINS_TEMPLATE_P (etype))
	  || (ecode == RECORD_TYPE && TYPE_LEFT_JUSTIFIED_MODULAR_P (etype)))
	return
	  build_unary_op
	    (INDIRECT_REF, NULL_TREE,
	     convert_to_fat_pointer (TREE_TYPE (type),
				     build_unary_op (ADDR_EXPR,
						     NULL_TREE, expr)));

      /* Do something very similar for converting one unconstrained
	 array to another.  */
      else if (ecode == UNCONSTRAINED_ARRAY_TYPE)
	return
	  build_unary_op (INDIRECT_REF, NULL_TREE,
			  convert (TREE_TYPE (type),
				   build_unary_op (ADDR_EXPR,
						   NULL_TREE, expr)));
      else
	gigi_abort (409);

    case COMPLEX_TYPE:
      return fold (convert_to_complex (type, expr));

    default:
      gigi_abort (410);
    }
}

/* Remove all conversions that are done in EXP.  This includes converting
   from a padded type or converting to a left-justified modular type.  */

tree
remove_conversions (exp)
     tree exp;
{
  switch (TREE_CODE (exp))
    {
    case CONSTRUCTOR:
      if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
	  && TYPE_LEFT_JUSTIFIED_MODULAR_P (TREE_TYPE (exp)))
	return remove_conversions (TREE_VALUE (CONSTRUCTOR_ELTS (exp)));
      break;

    case COMPONENT_REF:
      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == RECORD_TYPE
	  && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
	return remove_conversions (TREE_OPERAND (exp, 0));
      break;

    case UNCHECKED_CONVERT_EXPR:
    case NOP_EXPR:  case CONVERT_EXPR:
      return remove_conversions (TREE_OPERAND (exp, 0));

    default:
      break;
    }

  return exp;
}

/* If EXP's type is an UNCONSTRAINED_ARRAY_TYPE, return an expression that
   refers to the underlying array.  If its type has TYPE_CONTAINS_TEMPLATE_P,
   likewise return an expression pointing to the underlying array.  */

tree
maybe_unconstrained_array (exp)
     tree exp;
{
  enum tree_code code = TREE_CODE (exp);
  tree new;

  switch (TREE_CODE (TREE_TYPE (exp)))
    {
    case UNCONSTRAINED_ARRAY_TYPE:
      if (code == UNCONSTRAINED_ARRAY_REF)
	{
	  new
	    = build_unary_op (INDIRECT_REF, NULL_TREE,
			      build_component_ref (TREE_OPERAND (exp, 0),
						   get_identifier ("P_ARRAY"),
						   NULL_TREE));
	  TREE_READONLY (new) = TREE_STATIC (new) = TREE_READONLY (exp);
	  return new;
	}

      else if (code == NULL_EXPR)
	return build1 (NULL_EXPR,
		       TREE_TYPE (TREE_TYPE (TYPE_FIELDS
					     (TREE_TYPE (TREE_TYPE (exp))))),
		       TREE_OPERAND (exp, 0));

      else if (code == WITH_RECORD_EXPR
	       && (TREE_OPERAND (exp, 0)
		   != (new = maybe_unconstrained_array
		       (TREE_OPERAND (exp, 0)))))
	return build (WITH_RECORD_EXPR, TREE_TYPE (new), new,
		      TREE_OPERAND (exp, 1));

    case RECORD_TYPE:
      if (TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (exp)))
	{
	  new
	    = build_component_ref (exp, NULL_TREE,
				   TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (exp))));
	  if (TREE_CODE (TREE_TYPE (new)) == RECORD_TYPE
	      && TYPE_IS_PADDING_P (TREE_TYPE (new)))
	    new = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (new))), new);

	  return new;
	}
      break;

    default:
      break;
    }

  return exp;
}

/* Return an expression that does an unchecked converstion of EXPR to TYPE.  */

tree
unchecked_convert (type, expr)
     tree type;
     tree expr;
{
  tree etype = TREE_TYPE (expr);

  /* If the expression is already the right type, we are done.  */
  if (etype == type)
    return expr;

  /* If EXPR is a WITH_RECORD_EXPR, do the conversion inside and then make a
     new one.  */
  if (TREE_CODE (expr) == WITH_RECORD_EXPR)
    return build (WITH_RECORD_EXPR, type,
		  unchecked_convert (type, TREE_OPERAND (expr, 0)),
		  TREE_OPERAND (expr, 1));

  /* If both types types are integral just do a normal conversion.
     Likewise for a conversion to an unconstrained array.  */
  if ((((INTEGRAL_TYPE_P (type)
	 && ! (TREE_CODE (type) == INTEGER_TYPE
	       && TYPE_VAX_FLOATING_POINT_P (type)))
	|| (POINTER_TYPE_P (type) && ! TYPE_THIN_POINTER_P (type))
	|| (TREE_CODE (type) == RECORD_TYPE
	    && TYPE_LEFT_JUSTIFIED_MODULAR_P (type)))
       && ((INTEGRAL_TYPE_P (etype)
	    && ! (TREE_CODE (etype) == INTEGER_TYPE
		  && TYPE_VAX_FLOATING_POINT_P (etype)))
	   || (POINTER_TYPE_P (etype) && ! TYPE_THIN_POINTER_P (etype))
	   || (TREE_CODE (etype) == RECORD_TYPE
	       && TYPE_LEFT_JUSTIFIED_MODULAR_P (etype))))
      || TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
    {
      tree rtype = type;

      if (TREE_CODE (etype) == INTEGER_TYPE
	  && TYPE_BIASED_REPRESENTATION_P (etype))
	{
	  tree ntype = copy_type (etype);

	  TYPE_BIASED_REPRESENTATION_P (ntype) = 0;
	  TYPE_MAIN_VARIANT (ntype) = ntype;
	  expr = build1 (GNAT_NOP_EXPR, ntype, expr);
	}

      if (TREE_CODE (type) == INTEGER_TYPE
	  && TYPE_BIASED_REPRESENTATION_P (type))
	{
	  rtype = copy_type (type);
	  TYPE_BIASED_REPRESENTATION_P (rtype) = 0;
	  TYPE_MAIN_VARIANT (rtype) = rtype;
	}

      expr = convert (rtype, expr);
      if (type != rtype)
	expr = build1 (GNAT_NOP_EXPR, type, expr);
    }

  /* If we are converting TO an integral type whose precision is not the
     same as its size, first unchecked convert to a record that contains
     an object of the output type.  Then extract the field. */
  else if (INTEGRAL_TYPE_P (type) && TYPE_RM_SIZE (type) != 0
	   && 0 != compare_tree_int (TYPE_RM_SIZE (type),
				     GET_MODE_BITSIZE (TYPE_MODE (type))))
    {
      tree rec_type = make_node (RECORD_TYPE);
      tree field = create_field_decl (get_identifier ("OBJ"), type, 
				      rec_type, 1, 0, 0, 0);

      TYPE_FIELDS (rec_type) = field;
      layout_type (rec_type);

      expr = unchecked_convert (rec_type, expr);
      expr = build_component_ref (expr, NULL_TREE, field);
    }

  /* Similarly for integral input type whose precision is not equal to its
     size.  */
  else if (INTEGRAL_TYPE_P (etype) && TYPE_RM_SIZE (etype) != 0
      && 0 != compare_tree_int (TYPE_RM_SIZE (etype),
				GET_MODE_BITSIZE (TYPE_MODE (etype))))
    {
      tree rec_type = make_node (RECORD_TYPE);
      tree field
	= create_field_decl (get_identifier ("OBJ"), etype, rec_type,
			     1, 0, 0, 0);

      TYPE_FIELDS (rec_type) = field;
      layout_type (rec_type);

      expr = build_constructor (rec_type, build_tree_list (field, expr));
      expr = unchecked_convert (type, expr);
    }

  /* We have a special case when we are converting between two
     unconstrained array types.  In that case, take the address,
     convert the fat pointer types, and dereference.  */
  else if (TREE_CODE (etype) == UNCONSTRAINED_ARRAY_TYPE
	   && TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
    expr = build_unary_op (INDIRECT_REF, NULL_TREE,
			   build1 (UNCHECKED_CONVERT_EXPR, TREE_TYPE (type),
				   build_unary_op (ADDR_EXPR, NULL_TREE,
						   expr)));

  /* If both types are aggregates with the same mode and alignment (except
     if the result is a UNION_TYPE), we can do this as a normal conversion.  */
  else if (AGGREGATE_TYPE_P (type) && AGGREGATE_TYPE_P (etype)
	   && TREE_CODE (type) != UNION_TYPE
	   && TYPE_ALIGN (type) == TYPE_ALIGN (etype)
	   && TYPE_MODE (type) == TYPE_MODE (etype))
    expr = build1 (CONVERT_EXPR, type, expr);

  else
    {
      expr = maybe_unconstrained_array (expr);
      etype = TREE_TYPE (expr);
      expr = build1 (UNCHECKED_CONVERT_EXPR, type, expr);
    }


  /* If the result is an integral type whose size is not equal to
     the size of the underlying machine type, sign- or zero-extend
     the result.  We need not do this in the case where the input is
     an integral type of the same precision and signedness or if the output
     is a biased type or if both the input and output are unsigned.  */
  if (INTEGRAL_TYPE_P (type) && TYPE_RM_SIZE (type) != 0
      && ! (TREE_CODE (type) == INTEGER_TYPE
	    && TYPE_BIASED_REPRESENTATION_P (type))
      && 0 != compare_tree_int (TYPE_RM_SIZE (type),
				GET_MODE_BITSIZE (TYPE_MODE (type)))
      && ! (INTEGRAL_TYPE_P (etype)
	    && TREE_UNSIGNED (type) == TREE_UNSIGNED (etype)
	    && operand_equal_p (TYPE_RM_SIZE (type),
				(TYPE_RM_SIZE (etype) != 0
				 ? TYPE_RM_SIZE (etype) : TYPE_SIZE (etype)),
				0))
      && ! (TREE_UNSIGNED (type) && TREE_UNSIGNED (etype)))
    {
      tree base_type = type_for_mode (TYPE_MODE (type), TREE_UNSIGNED (type));
      tree shift_expr
	= convert (base_type,
		   size_binop (MINUS_EXPR,
			       bitsize_int
			       (GET_MODE_BITSIZE (TYPE_MODE (type))),
			       TYPE_RM_SIZE (type)));
      expr
	= convert (type,
		   build_binary_op (RSHIFT_EXPR, base_type,
				    build_binary_op (LSHIFT_EXPR, base_type,
						     convert (base_type, expr),
						     shift_expr),
				    shift_expr));
    }

  /* An unchecked conversion should never raise Constraint_Error.  The code
     below assumes that GCC's conversion routines overflow the same
     way that the underlying hardware does.  This is probably true.  In
     the rare case when it isn't, we can rely on the fact that such
     conversions are erroneous anyway.  */
  if (TREE_CODE (expr) == INTEGER_CST)
    TREE_OVERFLOW (expr) = TREE_CONSTANT_OVERFLOW (expr) = 0;

  /* If the sizes of the types differ and this is an UNCHECKED_CONVERT_EXPR,
     show no longer constant.  */
  if (TREE_CODE (expr) == UNCHECKED_CONVERT_EXPR
      && ! operand_equal_p (TYPE_SIZE_UNIT (type), TYPE_SIZE_UNIT (etype), 1))
    TREE_CONSTANT (expr) = 0;

  return expr;
}
