/****************************************************************************
 *                                                                          *
 *                         GNAT COMPILER COMPONENTS                         *
 *                                                                          *
 *                                 D E C L                                  *
 *                                                                          *
 *                          C Implementation File                           *
 *                                                                          *
 *          Copyright (C) 1992-2013, 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 3,  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 along with GCC; see the file COPYING3.  If not see        *
 * <http://www.gnu.org/licenses/>.                                          *
 *                                                                          *
 * GNAT was originally developed  by the GNAT team at  New York University. *
 * Extensive contributions were provided by Ada Core Technologies Inc.      *
 *                                                                          *
 ****************************************************************************/

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "toplev.h"
#include "ggc.h"
#include "target.h"
#include "tree-inline.h"
#include "diagnostic-core.h"

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

/* "stdcall" and "thiscall" conventions should be processed in a specific way
   on 32-bit x86/Windows only.  The macros below are helpers to avoid having
   to check for a Windows specific attribute throughout this unit.  */

#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
#ifdef TARGET_64BIT
#define Has_Stdcall_Convention(E) \
  (!TARGET_64BIT && Convention (E) == Convention_Stdcall)
#define Has_Thiscall_Convention(E) \
  (!TARGET_64BIT && is_cplusplus_method (E))
#else
#define Has_Stdcall_Convention(E) (Convention (E) == Convention_Stdcall)
#define Has_Thiscall_Convention(E) (is_cplusplus_method (E))
#endif
#else
#define Has_Stdcall_Convention(E) 0
#define Has_Thiscall_Convention(E) 0
#endif

/* Stack realignment is necessary for functions with foreign conventions when
   the ABI doesn't mandate as much as what the compiler assumes - that is, up
   to PREFERRED_STACK_BOUNDARY.

   Such realignment can be requested with a dedicated function type attribute
   on the targets that support it.  We define FOREIGN_FORCE_REALIGN_STACK to
   characterize the situations where the attribute should be set.  We rely on
   compiler configuration settings for 'main' to decide.  */

#ifdef MAIN_STACK_BOUNDARY
#define FOREIGN_FORCE_REALIGN_STACK \
  (MAIN_STACK_BOUNDARY < PREFERRED_STACK_BOUNDARY)
#else
#define FOREIGN_FORCE_REALIGN_STACK 0
#endif

struct incomplete
{
  struct incomplete *next;
  tree old_type;
  Entity_Id full_type;
};

/* These variables are used to defer recursively expanding incomplete types
   while we are processing an array, a record or a subprogram type.  */
static int defer_incomplete_level = 0;
static struct incomplete *defer_incomplete_list;

/* This variable is used to delay expanding From_With_Type types until the
   end of the spec.  */
static struct incomplete *defer_limited_with;

typedef struct subst_pair_d {
  tree discriminant;
  tree replacement;
} subst_pair;


typedef struct variant_desc_d {
  /* The type of the variant.  */
  tree type;

  /* The associated field.  */
  tree field;

  /* The value of the qualifier.  */
  tree qual;

  /* The type of the variant after transformation.  */
  tree new_type;
} variant_desc;


/* A hash table used to cache the result of annotate_value.  */
static GTY ((if_marked ("tree_int_map_marked_p"),
	     param_is (struct tree_int_map))) htab_t annotate_value_cache;

static bool allocatable_size_p (tree, bool);
static void prepend_one_attribute_to (struct attrib **,
				      enum attr_type, tree, tree, Node_Id);
static void prepend_attributes (Entity_Id, struct attrib **);
static tree elaborate_expression (Node_Id, Entity_Id, tree, bool, bool, bool);
static bool type_has_variable_size (tree);
static tree elaborate_expression_1 (tree, Entity_Id, tree, bool, bool);
static tree elaborate_expression_2 (tree, Entity_Id, tree, bool, bool,
				    unsigned int);
static tree gnat_to_gnu_component_type (Entity_Id, bool, bool);
static tree gnat_to_gnu_param (Entity_Id, Mechanism_Type, Entity_Id, bool,
			       bool *);
static tree gnat_to_gnu_field (Entity_Id, tree, int, bool, bool);
static bool same_discriminant_p (Entity_Id, Entity_Id);
static bool array_type_has_nonaliased_component (tree, Entity_Id);
static bool compile_time_known_address_p (Node_Id);
static bool cannot_be_superflat_p (Node_Id);
static bool constructor_address_p (tree);
static void components_to_record (tree, Node_Id, tree, int, bool, bool, bool,
				  bool, bool, bool, bool, bool, tree, tree *);
static Uint annotate_value (tree);
static void annotate_rep (Entity_Id, tree);
static tree build_position_list (tree, bool, tree, tree, unsigned int, tree);
static vec<subst_pair> build_subst_list (Entity_Id, Entity_Id, bool);
static vec<variant_desc> build_variant_list (tree,
						   vec<subst_pair> ,
						   vec<variant_desc> );
static tree validate_size (Uint, tree, Entity_Id, enum tree_code, bool, bool);
static void set_rm_size (Uint, tree, Entity_Id);
static unsigned int validate_alignment (Uint, Entity_Id, unsigned int);
static void check_ok_for_atomic (tree, Entity_Id, bool);
static tree create_field_decl_from (tree, tree, tree, tree, tree,
				    vec<subst_pair> );
static tree create_rep_part (tree, tree, tree);
static tree get_rep_part (tree);
static tree create_variant_part_from (tree, vec<variant_desc> , tree,
				      tree, vec<subst_pair> );
static void copy_and_substitute_in_size (tree, tree, vec<subst_pair> );

/* The relevant constituents of a subprogram binding to a GCC builtin.  Used
   to pass around calls performing profile compatibility checks.  */

typedef struct {
  Entity_Id gnat_entity;  /* The Ada subprogram entity.  */
  tree ada_fntype;        /* The corresponding GCC type node.  */
  tree btin_fntype;       /* The GCC builtin function type node.  */
} intrin_binding_t;

static bool intrin_profiles_compatible_p (intrin_binding_t *);

/* Given GNAT_ENTITY, a GNAT defining identifier node, which denotes some Ada
   entity, return the equivalent GCC tree for that entity (a ..._DECL node)
   and associate the ..._DECL node with the input GNAT defining identifier.

   If GNAT_ENTITY is a variable or a constant declaration, GNU_EXPR gives its
   initial value (in GCC tree form).  This is optional for a variable.  For
   a renamed entity, GNU_EXPR gives the object being renamed.

   DEFINITION is nonzero if this call is intended for a definition.  This is
   used for separate compilation where it is necessary to know whether an
   external declaration or a definition must be created if the GCC equivalent
   was not created previously.  The value of 1 is normally used for a nonzero
   DEFINITION, but a value of 2 is used in special circumstances, defined in
   the code.  */

tree
gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
{
  /* Contains the kind of the input GNAT node.  */
  const Entity_Kind kind = Ekind (gnat_entity);
  /* True if this is a type.  */
  const bool is_type = IN (kind, Type_Kind);
  /* True if debug info is requested for this entity.  */
  const bool debug_info_p = Needs_Debug_Info (gnat_entity);
  /* True if this entity is to be considered as imported.  */
  const bool imported_p
    = (Is_Imported (gnat_entity) && No (Address_Clause (gnat_entity)));
  /* For a type, contains the equivalent GNAT node to be used in gigi.  */
  Entity_Id gnat_equiv_type = Empty;
  /* Temporary used to walk the GNAT tree.  */
  Entity_Id gnat_temp;
  /* Contains the GCC DECL node which is equivalent to the input GNAT node.
     This node will be associated with the GNAT node by calling at the end
     of the `switch' statement.  */
  tree gnu_decl = NULL_TREE;
  /* Contains the GCC type to be used for the GCC node.  */
  tree gnu_type = NULL_TREE;
  /* Contains the GCC size tree to be used for the GCC node.  */
  tree gnu_size = NULL_TREE;
  /* Contains the GCC name to be used for the GCC node.  */
  tree gnu_entity_name;
  /* True if we have already saved gnu_decl as a GNAT association.  */
  bool saved = false;
  /* True if we incremented defer_incomplete_level.  */
  bool this_deferred = false;
  /* True if we incremented force_global.  */
  bool this_global = false;
  /* True if we should check to see if elaborated during processing.  */
  bool maybe_present = false;
  /* True if we made GNU_DECL and its type here.  */
  bool this_made_decl = false;
  /* Size and alignment of the GCC node, if meaningful.  */
  unsigned int esize = 0, align = 0;
  /* Contains the list of attributes directly attached to the entity.  */
  struct attrib *attr_list = NULL;

  /* Since a use of an Itype is a definition, process it as such if it
     is not in a with'ed unit.  */
  if (!definition
      && is_type
      && Is_Itype (gnat_entity)
      && !present_gnu_tree (gnat_entity)
      && In_Extended_Main_Code_Unit (gnat_entity))
    {
      /* Ensure that we are in a subprogram mentioned in the Scope chain of
	 this entity, our current scope is global, or we encountered a task
	 or entry (where we can't currently accurately check scoping).  */
      if (!current_function_decl
	  || DECL_ELABORATION_PROC_P (current_function_decl))
	{
	  process_type (gnat_entity);
	  return get_gnu_tree (gnat_entity);
	}

      for (gnat_temp = Scope (gnat_entity);
	   Present (gnat_temp);
	   gnat_temp = Scope (gnat_temp))
	{
	  if (Is_Type (gnat_temp))
	    gnat_temp = Underlying_Type (gnat_temp);

	  if (Ekind (gnat_temp) == E_Subprogram_Body)
	    gnat_temp
	      = Corresponding_Spec (Parent (Declaration_Node (gnat_temp)));

	  if (IN (Ekind (gnat_temp), Subprogram_Kind)
	      && Present (Protected_Body_Subprogram (gnat_temp)))
	    gnat_temp = Protected_Body_Subprogram (gnat_temp);

	  if (Ekind (gnat_temp) == E_Entry
	      || Ekind (gnat_temp) == E_Entry_Family
	      || Ekind (gnat_temp) == E_Task_Type
	      || (IN (Ekind (gnat_temp), Subprogram_Kind)
		  && present_gnu_tree (gnat_temp)
		  && (current_function_decl
		      == gnat_to_gnu_entity (gnat_temp, NULL_TREE, 0))))
	    {
	      process_type (gnat_entity);
	      return get_gnu_tree (gnat_entity);
	    }
	}

      /* This abort means the Itype has an incorrect scope, i.e. that its
	 scope does not correspond to the subprogram it is declared in.  */
      gcc_unreachable ();
    }

  /* If we've already processed this entity, return what we got last time.
     If we are defining the node, we should not have already processed it.
     In that case, we will abort below when we try to save a new GCC tree
     for this object.  We also need to handle the case of getting a dummy
     type when a Full_View exists.  */
  if ((!definition || (is_type && imported_p))
      && present_gnu_tree (gnat_entity))
    {
      gnu_decl = get_gnu_tree (gnat_entity);

      if (TREE_CODE (gnu_decl) == TYPE_DECL
	  && TYPE_IS_DUMMY_P (TREE_TYPE (gnu_decl))
	  && IN (kind, Incomplete_Or_Private_Kind)
	  && Present (Full_View (gnat_entity)))
	{
	  gnu_decl
	    = gnat_to_gnu_entity (Full_View (gnat_entity), NULL_TREE, 0);
	  save_gnu_tree (gnat_entity, NULL_TREE, false);
	  save_gnu_tree (gnat_entity, gnu_decl, false);
	}

      return gnu_decl;
    }

  /* If this is a numeric or enumeral type, or an access type, a nonzero
     Esize must be specified unless it was specified by the programmer.  */
  gcc_assert (!Unknown_Esize (gnat_entity)
	      || Has_Size_Clause (gnat_entity)
	      || (!IN (kind, Numeric_Kind)
		  && !IN (kind, Enumeration_Kind)
		  && (!IN (kind, Access_Kind)
		      || kind == E_Access_Protected_Subprogram_Type
		      || kind == E_Anonymous_Access_Protected_Subprogram_Type
		      || kind == E_Access_Subtype)));

  /* The RM size must be specified for all discrete and fixed-point types.  */
  gcc_assert (!(IN (kind, Discrete_Or_Fixed_Point_Kind)
		&& Unknown_RM_Size (gnat_entity)));

  /* If we get here, it means we have not yet done anything with this entity.
     If we are not defining it, it must be a type or an entity that is defined
     elsewhere or externally, otherwise we should have defined it already.  */
  gcc_assert (definition
	      || type_annotate_only
	      || is_type
	      || kind == E_Discriminant
	      || kind == E_Component
	      || kind == E_Label
	      || (kind == E_Constant && Present (Full_View (gnat_entity)))
	      || Is_Public (gnat_entity));

  /* Get the name of the entity and set up the line number and filename of
     the original definition for use in any decl we make.  */
  gnu_entity_name = get_entity_name (gnat_entity);
  Sloc_to_locus (Sloc (gnat_entity), &input_location);

  /* For cases when we are not defining (i.e., we are referencing from
     another compilation unit) public entities, show we are at global level
     for the purpose of computing scopes.  Don't do this for components or
     discriminants since the relevant test is whether or not the record is
     being defined.  */
  if (!definition
      && kind != E_Component
      && kind != E_Discriminant
      && Is_Public (gnat_entity)
      && !Is_Statically_Allocated (gnat_entity))
    force_global++, this_global = true;

  /* Handle any attributes directly attached to the entity.  */
  if (Has_Gigi_Rep_Item (gnat_entity))
    prepend_attributes (gnat_entity, &attr_list);

  /* Do some common processing for types.  */
  if (is_type)
    {
      /* Compute the equivalent type to be used in gigi.  */
      gnat_equiv_type = Gigi_Equivalent_Type (gnat_entity);

      /* Machine_Attributes on types are expected to be propagated to
	 subtypes.  The corresponding Gigi_Rep_Items are only attached
	 to the first subtype though, so we handle the propagation here.  */
      if (Base_Type (gnat_entity) != gnat_entity
	  && !Is_First_Subtype (gnat_entity)
	  && Has_Gigi_Rep_Item (First_Subtype (Base_Type (gnat_entity))))
	prepend_attributes (First_Subtype (Base_Type (gnat_entity)),
			    &attr_list);

      /* Compute a default value for the size of an elementary type.  */
      if (Known_Esize (gnat_entity) && Is_Elementary_Type (gnat_entity))
	{
	  unsigned int max_esize;

	  gcc_assert (UI_Is_In_Int_Range (Esize (gnat_entity)));
	  esize = UI_To_Int (Esize (gnat_entity));

	  if (IN (kind, Float_Kind))
	    max_esize = fp_prec_to_size (LONG_DOUBLE_TYPE_SIZE);
	  else if (IN (kind, Access_Kind))
	    max_esize = POINTER_SIZE * 2;
	  else
	    max_esize = LONG_LONG_TYPE_SIZE;

	  if (esize > max_esize)
	   esize = max_esize;
	}
    }

  switch (kind)
    {
    case E_Constant:
      /* If this is a use of a deferred constant without address clause,
	 get its full definition.  */
      if (!definition
	  && No (Address_Clause (gnat_entity))
	  && Present (Full_View (gnat_entity)))
	{
	  gnu_decl
	    = gnat_to_gnu_entity (Full_View (gnat_entity), gnu_expr, 0);
	  saved = true;
	  break;
	}

      /* If we have an external constant that we are not defining, get the
	 expression that is was defined to represent.  We may throw it away
	 later if it is not a constant.  But do not retrieve the expression
	 if it is an allocator because the designated type might be dummy
	 at this point.  */
      if (!definition
	  && !No_Initialization (Declaration_Node (gnat_entity))
	  && Present (Expression (Declaration_Node (gnat_entity)))
	  && Nkind (Expression (Declaration_Node (gnat_entity)))
	     != N_Allocator)
	{
	  bool went_into_elab_proc = false;
	  int save_force_global = force_global;

	  /* The expression may contain N_Expression_With_Actions nodes and
	     thus object declarations from other units.  In this case, even
	     though the expression will eventually be discarded since not a
	     constant, the declarations would be stuck either in the global
	     varpool or in the current scope.  Therefore we force the local
	     context and create a fake scope that we'll zap at the end.  */
	  if (!current_function_decl)
	    {
	      current_function_decl = get_elaboration_procedure ();
	      went_into_elab_proc = true;
	    }
	  force_global = 0;
	  gnat_pushlevel ();

	  gnu_expr = gnat_to_gnu (Expression (Declaration_Node (gnat_entity)));

	  gnat_zaplevel ();
	  force_global = save_force_global;
	  if (went_into_elab_proc)
	    current_function_decl = NULL_TREE;
	}

      /* Ignore deferred constant definitions without address clause since
	 they are processed fully in the front-end.  If No_Initialization
	 is set, this is not a deferred constant but a constant whose value
	 is built manually.  And constants that are renamings are handled
	 like variables.  */
      if (definition
	  && !gnu_expr
	  && No (Address_Clause (gnat_entity))
	  && !No_Initialization (Declaration_Node (gnat_entity))
	  && No (Renamed_Object (gnat_entity)))
	{
	  gnu_decl = error_mark_node;
	  saved = true;
	  break;
	}

      /* Ignore constant definitions already marked with the error node.  See
	 the N_Object_Declaration case of gnat_to_gnu for the rationale.  */
      if (definition
	  && gnu_expr
	  && present_gnu_tree (gnat_entity)
	  && get_gnu_tree (gnat_entity) == error_mark_node)
	{
	  maybe_present = true;
	  break;
	}

      goto object;

    case E_Exception:
      /* We used to special case VMS exceptions here to directly map them to
	 their associated condition code.  Since this code had to be masked
	 dynamically to strip off the severity bits, this caused trouble in
	 the GCC/ZCX case because the "type" pointers we store in the tables
	 have to be static.  We now don't special case here anymore, and let
	 the regular processing take place, which leaves us with a regular
	 exception data object for VMS exceptions too.  The condition code
	 mapping is taken care of by the front end and the bitmasking by the
	 run-time library.  */
      goto object;

    case E_Discriminant:
    case E_Component:
      {
	/* The GNAT record where the component was defined.  */
	Entity_Id gnat_record = Underlying_Type (Scope (gnat_entity));

	/* If the variable is an inherited record component (in the case of
	   extended record types), just return the inherited entity, which
	   must be a FIELD_DECL.  Likewise for discriminants.
	   For discriminants of untagged records which have explicit
	   stored discriminants, return the entity for the corresponding
	   stored discriminant.  Also use Original_Record_Component
	   if the record has a private extension.  */
	if (Present (Original_Record_Component (gnat_entity))
	    && Original_Record_Component (gnat_entity) != gnat_entity)
	  {
	    gnu_decl
	      = gnat_to_gnu_entity (Original_Record_Component (gnat_entity),
				    gnu_expr, definition);
	    saved = true;
	    break;
	  }

	/* If the enclosing record has explicit stored discriminants,
	   then it is an untagged record.  If the Corresponding_Discriminant
	   is not empty then this must be a renamed discriminant and its
	   Original_Record_Component must point to the corresponding explicit
	   stored discriminant (i.e. we should have taken the previous
	   branch).  */
	else if (Present (Corresponding_Discriminant (gnat_entity))
		 && Is_Tagged_Type (gnat_record))
	  {
	    /* A tagged record has no explicit stored discriminants.  */
	    gcc_assert (First_Discriminant (gnat_record)
		       == First_Stored_Discriminant (gnat_record));
	    gnu_decl
	      = gnat_to_gnu_entity (Corresponding_Discriminant (gnat_entity),
				    gnu_expr, definition);
	    saved = true;
	    break;
	  }

	else if (Present (CR_Discriminant (gnat_entity))
		 && type_annotate_only)
	  {
	    gnu_decl = gnat_to_gnu_entity (CR_Discriminant (gnat_entity),
					   gnu_expr, definition);
	    saved = true;
	    break;
	  }

	/* If the enclosing record has explicit stored discriminants, then
	   it is an untagged record.  If the Corresponding_Discriminant
	   is not empty then this must be a renamed discriminant and its
	   Original_Record_Component must point to the corresponding explicit
	   stored discriminant (i.e. we should have taken the first
	   branch).  */
	else if (Present (Corresponding_Discriminant (gnat_entity))
		 && (First_Discriminant (gnat_record)
		     != First_Stored_Discriminant (gnat_record)))
	  gcc_unreachable ();

	/* Otherwise, if we are not defining this and we have no GCC type
	   for the containing record, make one for it.  Then we should
	   have made our own equivalent.  */
	else if (!definition && !present_gnu_tree (gnat_record))
	  {
	    /* ??? If this is in a record whose scope is a protected
	       type and we have an Original_Record_Component, use it.
	       This is a workaround for major problems in protected type
	       handling.  */
	    Entity_Id Scop = Scope (Scope (gnat_entity));
	    if ((Is_Protected_Type (Scop)
		 || (Is_Private_Type (Scop)
		     && Present (Full_View (Scop))
		     && Is_Protected_Type (Full_View (Scop))))
		&& Present (Original_Record_Component (gnat_entity)))
	      {
		gnu_decl
		  = gnat_to_gnu_entity (Original_Record_Component
					(gnat_entity),
					gnu_expr, 0);
		saved = true;
		break;
	      }

	    gnat_to_gnu_entity (Scope (gnat_entity), NULL_TREE, 0);
	    gnu_decl = get_gnu_tree (gnat_entity);
	    saved = true;
	    break;
	  }

	else
	  /* Here we have no GCC type and this is a reference rather than a
	     definition.  This should never happen.  Most likely the cause is
	     reference before declaration in the gnat tree for gnat_entity.  */
	  gcc_unreachable ();
      }

    case E_Loop_Parameter:
    case E_Out_Parameter:
    case E_Variable:

      /* Simple variables, loop variables, Out parameters and exceptions.  */
    object:
      {
	bool const_flag
	  = ((kind == E_Constant || kind == E_Variable)
	     && Is_True_Constant (gnat_entity)
	     && !Treat_As_Volatile (gnat_entity)
	     && (((Nkind (Declaration_Node (gnat_entity))
		   == N_Object_Declaration)
		  && Present (Expression (Declaration_Node (gnat_entity))))
		 || Present (Renamed_Object (gnat_entity))
		 || imported_p));
	bool inner_const_flag = const_flag;
	bool static_p = Is_Statically_Allocated (gnat_entity);
	bool mutable_p = false;
	bool used_by_ref = false;
	tree gnu_ext_name = NULL_TREE;
	tree renamed_obj = NULL_TREE;
	tree gnu_object_size;

	if (Present (Renamed_Object (gnat_entity)) && !definition)
	  {
	    if (kind == E_Exception)
	      gnu_expr = gnat_to_gnu_entity (Renamed_Entity (gnat_entity),
					     NULL_TREE, 0);
	    else
	      gnu_expr = gnat_to_gnu (Renamed_Object (gnat_entity));
	  }

	/* Get the type after elaborating the renamed object.  */
	gnu_type = gnat_to_gnu_type (Etype (gnat_entity));

	/* If this is a standard exception definition, then use the standard
	   exception type.  This is necessary to make sure that imported and
	   exported views of exceptions are properly merged in LTO mode.  */
	if (TREE_CODE (TYPE_NAME (gnu_type)) == TYPE_DECL
	    && DECL_NAME (TYPE_NAME (gnu_type)) == exception_data_name_id)
	  gnu_type = except_type_node;

	/* For a debug renaming declaration, build a debug-only entity.  */
	if (Present (Debug_Renaming_Link (gnat_entity)))
	  {
	    /* Force a non-null value to make sure the symbol is retained.  */
	    tree value = build1 (INDIRECT_REF, gnu_type,
				 build1 (NOP_EXPR,
					 build_pointer_type (gnu_type),
					 integer_minus_one_node));
	    gnu_decl = build_decl (input_location,
				   VAR_DECL, gnu_entity_name, gnu_type);
	    SET_DECL_VALUE_EXPR (gnu_decl, value);
	    DECL_HAS_VALUE_EXPR_P (gnu_decl) = 1;
	    gnat_pushdecl (gnu_decl, gnat_entity);
	    break;
	  }

	/* If this is a loop variable, its type should be the base type.
	   This is because the code for processing a loop determines whether
	   a normal loop end test can be done by comparing the bounds of the
	   loop against those of the base type, which is presumed to be the
	   size used for computation.  But this is not correct when the size
	   of the subtype is smaller than the type.  */
	if (kind == E_Loop_Parameter)
	  gnu_type = get_base_type (gnu_type);

	/* Reject non-renamed objects whose type is an unconstrained array or
	   any object whose type is a dummy type or void.  */
	if ((TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE
	     && No (Renamed_Object (gnat_entity)))
	    || TYPE_IS_DUMMY_P (gnu_type)
	    || TREE_CODE (gnu_type) == VOID_TYPE)
	  {
	    gcc_assert (type_annotate_only);
	    if (this_global)
	      force_global--;
	    return error_mark_node;
	  }

	/* If an alignment is specified, use it if valid.  Note that exceptions
	   are objects but don't have an alignment.  We must do this before we
	   validate the size, since the alignment can affect the size.  */
	if (kind != E_Exception && Known_Alignment (gnat_entity))
	  {
	    gcc_assert (Present (Alignment (gnat_entity)));

	    align = validate_alignment (Alignment (gnat_entity), gnat_entity,
					TYPE_ALIGN (gnu_type));

	    /* No point in changing the type if there is an address clause
	       as the final type of the object will be a reference type.  */
	    if (Present (Address_Clause (gnat_entity)))
	      align = 0;
	    else
	      {
		tree orig_type = gnu_type;

		gnu_type
		  = maybe_pad_type (gnu_type, NULL_TREE, align, gnat_entity,
				    false, false, definition, true);

		/* If a padding record was made, declare it now since it will
		   never be declared otherwise.  This is necessary to ensure
		   that its subtrees are properly marked.  */
		if (gnu_type != orig_type && !DECL_P (TYPE_NAME (gnu_type)))
		  create_type_decl (TYPE_NAME (gnu_type), gnu_type, NULL, true,
				    debug_info_p, gnat_entity);
	      }
	  }

	/* If we are defining the object, see if it has a Size and validate it
	   if so.  If we are not defining the object and a Size clause applies,
	   simply retrieve the value.  We don't want to ignore the clause and
	   it is expected to have been validated already.  Then get the new
	   type, if any.  */
	if (definition)
	  gnu_size = validate_size (Esize (gnat_entity), gnu_type,
				    gnat_entity, VAR_DECL, false,
				    Has_Size_Clause (gnat_entity));
	else if (Has_Size_Clause (gnat_entity))
	  gnu_size = UI_To_gnu (Esize (gnat_entity), bitsizetype);

	if (gnu_size)
	  {
	    gnu_type
	      = make_type_from_size (gnu_type, gnu_size,
				     Has_Biased_Representation (gnat_entity));

	    if (operand_equal_p (TYPE_SIZE (gnu_type), gnu_size, 0))
	      gnu_size = NULL_TREE;
	  }

	/* If this object has self-referential size, it must be a record with
	   a default discriminant.  We are supposed to allocate an object of
	   the maximum size in this case, unless it is a constant with an
	   initializing expression, in which case we can get the size from
	   that.  Note that the resulting size may still be a variable, so
	   this may end up with an indirect allocation.  */
	if (No (Renamed_Object (gnat_entity))
	    && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type)))
	  {
	    if (gnu_expr && kind == E_Constant)
	      {
		tree size = TYPE_SIZE (TREE_TYPE (gnu_expr));
		if (CONTAINS_PLACEHOLDER_P (size))
		  {
		    /* If the initializing expression is itself a constant,
		       despite having a nominal type with self-referential
		       size, we can get the size directly from it.  */
		    if (TREE_CODE (gnu_expr) == COMPONENT_REF
			&& TYPE_IS_PADDING_P
			   (TREE_TYPE (TREE_OPERAND (gnu_expr, 0)))
			&& TREE_CODE (TREE_OPERAND (gnu_expr, 0)) == VAR_DECL
			&& (TREE_READONLY (TREE_OPERAND (gnu_expr, 0))
			    || DECL_READONLY_ONCE_ELAB
			       (TREE_OPERAND (gnu_expr, 0))))
		      gnu_size = DECL_SIZE (TREE_OPERAND (gnu_expr, 0));
		    else
		      gnu_size
			= SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, gnu_expr);
		  }
		else
		  gnu_size = size;
	      }
	    /* We may have no GNU_EXPR because No_Initialization is
	       set even though there's an Expression.  */
	    else if (kind == E_Constant
		     && (Nkind (Declaration_Node (gnat_entity))
			 == N_Object_Declaration)
		     && Present (Expression (Declaration_Node (gnat_entity))))
	      gnu_size
		= TYPE_SIZE (gnat_to_gnu_type
			     (Etype
			      (Expression (Declaration_Node (gnat_entity)))));
	    else
	      {
		gnu_size = max_size (TYPE_SIZE (gnu_type), true);
		mutable_p = true;
	      }

	    /* If we are at global level and the size isn't constant, call
	       elaborate_expression_1 to make a variable for it rather than
	       calculating it each time.  */
	    if (global_bindings_p () && !TREE_CONSTANT (gnu_size))
	      gnu_size = elaborate_expression_1 (gnu_size, gnat_entity,
						 get_identifier ("SIZE"),
						 definition, false);
	  }

	/* If the size is zero byte, make it one byte since some linkers have
	   troubles with zero-sized objects.  If the object will have a
	   template, that will make it nonzero so don't bother.  Also avoid
	   doing that for an object renaming or an object with an address
	   clause, as we would lose useful information on the view size
	   (e.g. for null array slices) and we are not allocating the object
	   here anyway.  */
	if (((gnu_size
	      && integer_zerop (gnu_size)
	      && !TREE_OVERFLOW (gnu_size))
	     || (TYPE_SIZE (gnu_type)
		 && integer_zerop (TYPE_SIZE (gnu_type))
		 && !TREE_OVERFLOW (TYPE_SIZE (gnu_type))))
	    && (!Is_Constr_Subt_For_UN_Aliased (Etype (gnat_entity))
		|| !Is_Array_Type (Etype (gnat_entity)))
	    && No (Renamed_Object (gnat_entity))
	    && No (Address_Clause (gnat_entity)))
	  gnu_size = bitsize_unit_node;

	/* If this is an object with no specified size and alignment, and
	   if either it is atomic or we are not optimizing alignment for
	   space and it is composite and not an exception, an Out parameter
	   or a reference to another object, and the size of its type is a
	   constant, set the alignment to the smallest one which is not
	   smaller than the size, with an appropriate cap.  */
	if (!gnu_size && align == 0
	    && (Is_Atomic (gnat_entity)
		|| (!Optimize_Alignment_Space (gnat_entity)
		    && kind != E_Exception
		    && kind != E_Out_Parameter
		    && Is_Composite_Type (Etype (gnat_entity))
		    && !Is_Constr_Subt_For_UN_Aliased (Etype (gnat_entity))
		    && !Is_Exported (gnat_entity)
		    && !imported_p
		    && No (Renamed_Object (gnat_entity))
		    && No (Address_Clause (gnat_entity))))
	    && TREE_CODE (TYPE_SIZE (gnu_type)) == INTEGER_CST)
	  {
	    unsigned int size_cap, align_cap;

	    /* No point in promoting the alignment if this doesn't prevent
	       BLKmode access to the object, in particular block copy, as
	       this will for example disable the NRV optimization for it.
	       No point in jumping through all the hoops needed in order
	       to support BIGGEST_ALIGNMENT if we don't really have to.
	       So we cap to the smallest alignment that corresponds to
	       a known efficient memory access pattern of the target.  */
	    if (Is_Atomic (gnat_entity))
	      {
		size_cap = UINT_MAX;
		align_cap = BIGGEST_ALIGNMENT;
	      }
	    else
	      {
		size_cap = MAX_FIXED_MODE_SIZE;
		align_cap = get_mode_alignment (ptr_mode);
	      }

	    if (!host_integerp (TYPE_SIZE (gnu_type), 1)
		|| compare_tree_int (TYPE_SIZE (gnu_type), size_cap) > 0)
	      align = 0;
	    else if (compare_tree_int (TYPE_SIZE (gnu_type), align_cap) > 0)
	      align = align_cap;
	    else
	      align = ceil_pow2 (tree_low_cst (TYPE_SIZE (gnu_type), 1));

	    /* But make sure not to under-align the object.  */
	    if (align <= TYPE_ALIGN (gnu_type))
	      align = 0;

	    /* And honor the minimum valid atomic alignment, if any.  */
#ifdef MINIMUM_ATOMIC_ALIGNMENT
	    else if (align < MINIMUM_ATOMIC_ALIGNMENT)
	      align = MINIMUM_ATOMIC_ALIGNMENT;
#endif
	  }

	/* If the object is set to have atomic components, find the component
	   type and validate it.

	   ??? Note that we ignore Has_Volatile_Components on objects; it's
	   not at all clear what to do in that case.  */
	if (Has_Atomic_Components (gnat_entity))
	  {
	    tree gnu_inner = (TREE_CODE (gnu_type) == ARRAY_TYPE
			      ? TREE_TYPE (gnu_type) : gnu_type);

	    while (TREE_CODE (gnu_inner) == ARRAY_TYPE
		   && TYPE_MULTI_ARRAY_P (gnu_inner))
	      gnu_inner = TREE_TYPE (gnu_inner);

	    check_ok_for_atomic (gnu_inner, gnat_entity, true);
	  }

	/* Now check if the type of the object allows atomic access.  Note
	   that we must test the type, even if this object has size and
	   alignment to allow such access, because we will be going inside
	   the padded record to assign to the object.  We could fix this by
	   always copying via an intermediate value, but it's not clear it's
	   worth the effort.  */
	if (Is_Atomic (gnat_entity))
	  check_ok_for_atomic (gnu_type, gnat_entity, false);

	/* If this is an aliased object with an unconstrained nominal subtype,
	   make a type that includes the template.  */
	if (Is_Constr_Subt_For_UN_Aliased (Etype (gnat_entity))
	    && Is_Array_Type (Etype (gnat_entity))
	    && !type_annotate_only)
	  {
	    tree gnu_array
	      = gnat_to_gnu_type (Base_Type (Etype (gnat_entity)));
	    gnu_type
	      = build_unc_object_type_from_ptr (TREE_TYPE (gnu_array),
						gnu_type,
						concat_name (gnu_entity_name,
							     "UNC"),
						debug_info_p);
	  }

	/* ??? If this is an object of CW type initialized to a value, try to
	   ensure that the object is sufficient aligned for this value, but
	   without pessimizing the allocation.  This is a kludge necessary
	   because we don't support dynamic alignment.  */
	if (align == 0
	    && Ekind (Etype (gnat_entity)) == E_Class_Wide_Subtype
	    && No (Renamed_Object (gnat_entity))
	    && No (Address_Clause (gnat_entity)))
	  align = get_target_system_allocator_alignment () * BITS_PER_UNIT;

#ifdef MINIMUM_ATOMIC_ALIGNMENT
	/* If the size is a constant and no alignment is specified, force
	   the alignment to be the minimum valid atomic alignment.  The
	   restriction on constant size avoids problems with variable-size
	   temporaries; if the size is variable, there's no issue with
	   atomic access.  Also don't do this for a constant, since it isn't
	   necessary and can interfere with constant replacement.  Finally,
	   do not do it for Out parameters since that creates an
	   size inconsistency with In parameters.  */
	if (align == 0
	    && MINIMUM_ATOMIC_ALIGNMENT > TYPE_ALIGN (gnu_type)
	    && !FLOAT_TYPE_P (gnu_type)
	    && !const_flag && No (Renamed_Object (gnat_entity))
	    && !imported_p && No (Address_Clause (gnat_entity))
	    && kind != E_Out_Parameter
	    && (gnu_size ? TREE_CODE (gnu_size) == INTEGER_CST
		: TREE_CODE (TYPE_SIZE (gnu_type)) == INTEGER_CST))
	  align = MINIMUM_ATOMIC_ALIGNMENT;
#endif

	/* Make a new type with the desired size and alignment, if needed.
	   But do not take into account alignment promotions to compute the
	   size of the object.  */
	gnu_object_size = gnu_size ? gnu_size : TYPE_SIZE (gnu_type);
	if (gnu_size || align > 0)
	  {
	    tree orig_type = gnu_type;

	    gnu_type = maybe_pad_type (gnu_type, gnu_size, align, gnat_entity,
				       false, false, definition, true);

	    /* If a padding record was made, declare it now since it will
	       never be declared otherwise.  This is necessary to ensure
	       that its subtrees are properly marked.  */
	    if (gnu_type != orig_type && !DECL_P (TYPE_NAME (gnu_type)))
	      create_type_decl (TYPE_NAME (gnu_type), gnu_type, NULL, true,
				debug_info_p, gnat_entity);
	  }

	/* If this is a renaming, avoid as much as possible to create a new
	   object.  However, in several cases, creating it is required.
	   This processing needs to be applied to the raw expression so
	   as to make it more likely to rename the underlying object.  */
	if (Present (Renamed_Object (gnat_entity)))
	  {
	    bool create_normal_object = false;

	    /* If the renamed object had padding, strip off the reference
	       to the inner object and reset our type.  */
	    if ((TREE_CODE (gnu_expr) == COMPONENT_REF
		 && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_expr, 0))))
		/* Strip useless conversions around the object.  */
		|| gnat_useless_type_conversion (gnu_expr))
	      {
		gnu_expr = TREE_OPERAND (gnu_expr, 0);
		gnu_type = TREE_TYPE (gnu_expr);
	      }

	    /* Or else, if the renamed object has an unconstrained type with
	       default discriminant, use the padded type.  */
	    else if (TYPE_IS_PADDING_P (TREE_TYPE (gnu_expr))
		     && TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_expr)))
			== gnu_type
		     && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type)))
	      gnu_type = TREE_TYPE (gnu_expr);

	    /* Case 1: If this is a constant renaming stemming from a function
	       call, treat it as a normal object whose initial value is what
	       is being renamed.  RM 3.3 says that the result of evaluating a
	       function call is a constant object.  As a consequence, it can
	       be the inner object of a constant renaming.  In this case, the
	       renaming must be fully instantiated, i.e. it cannot be a mere
	       reference to (part of) an existing object.  */
	    if (const_flag)
	      {
	        tree inner_object = gnu_expr;
		while (handled_component_p (inner_object))
		  inner_object = TREE_OPERAND (inner_object, 0);
		if (TREE_CODE (inner_object) == CALL_EXPR)
		  create_normal_object = true;
	      }

	    /* Otherwise, see if we can proceed with a stabilized version of
	       the renamed entity or if we need to make a new object.  */
	    if (!create_normal_object)
	      {
		tree maybe_stable_expr = NULL_TREE;
		bool stable = false;

		/* Case 2: If the renaming entity need not be materialized and
		   the renamed expression is something we can stabilize, use
		   that for the renaming.  At the global level, we can only do
		   this if we know no SAVE_EXPRs need be made, because the
		   expression we return might be used in arbitrary conditional
		   branches so we must force the evaluation of the SAVE_EXPRs
		   immediately and this requires a proper function context.
		   Note that an external constant is at the global level.  */
		if (!Materialize_Entity (gnat_entity)
		    && (!((!definition && kind == E_Constant)
			  || global_bindings_p ())
			|| (staticp (gnu_expr)
			    && !TREE_SIDE_EFFECTS (gnu_expr))))
		  {
		    maybe_stable_expr
		      = gnat_stabilize_reference (gnu_expr, true, &stable);

		    if (stable)
		      {
			/* ??? No DECL_EXPR is created so we need to mark
			   the expression manually lest it is shared.  */
			if ((!definition && kind == E_Constant)
			    || global_bindings_p ())
			  MARK_VISITED (maybe_stable_expr);
			gnu_decl = maybe_stable_expr;
			save_gnu_tree (gnat_entity, gnu_decl, true);
			saved = true;
			annotate_object (gnat_entity, gnu_type, NULL_TREE,
					 false);
			/* This assertion will fail if the renamed object
			   isn't aligned enough as to make it possible to
			   honor the alignment set on the renaming.  */
			if (align)
			  {
			    unsigned int renamed_align
			      = DECL_P (gnu_decl)
				? DECL_ALIGN (gnu_decl)
				: TYPE_ALIGN (TREE_TYPE (gnu_decl));
			    gcc_assert (renamed_align >= align);
			  }
			break;
		      }

		    /* The stabilization failed.  Keep maybe_stable_expr
		       untouched here to let the pointer case below know
		       about that failure.  */
		  }

		/* Case 3: If this is a constant renaming and creating a
		   new object is allowed and cheap, treat it as a normal
		   object whose initial value is what is being renamed.  */
		if (const_flag
		    && !Is_Composite_Type
		        (Underlying_Type (Etype (gnat_entity))))
		  ;

		/* Case 4: Make this into a constant pointer to the object we
		   are to rename and attach the object to the pointer if it is
		   something we can stabilize.

		   From the proper scope, attached objects will be referenced
		   directly instead of indirectly via the pointer to avoid
		   subtle aliasing problems with non-addressable entities.
		   They have to be stable because we must not evaluate the
		   variables in the expression every time the renaming is used.
		   The pointer is called a "renaming" pointer in this case.

		   In the rare cases where we cannot stabilize the renamed
		   object, we just make a "bare" pointer, and the renamed
		   entity is always accessed indirectly through it.  */
		else
		  {
		    /* We need to preserve the volatileness of the renamed
		       object through the indirection.  */
		    if (TREE_THIS_VOLATILE (gnu_expr)
			&& !TYPE_VOLATILE (gnu_type))
		      gnu_type
			= build_qualified_type (gnu_type,
						(TYPE_QUALS (gnu_type)
						 | TYPE_QUAL_VOLATILE));
		    gnu_type = build_reference_type (gnu_type);
		    inner_const_flag = TREE_READONLY (gnu_expr);
		    const_flag = true;

		    /* If the previous attempt at stabilizing failed, there
		       is no point in trying again and we reuse the result
		       without attaching it to the pointer.  In this case it
		       will only be used as the initializing expression of
		       the pointer and thus needs no special treatment with
		       regard to multiple evaluations.  */
		    if (maybe_stable_expr)
		      ;

		    /* Otherwise, try to stabilize and attach the expression
		       to the pointer if the stabilization succeeds.

		       Note that this might introduce SAVE_EXPRs and we don't
		       check whether we're at the global level or not.  This
		       is fine since we are building a pointer initializer and
		       neither the pointer nor the initializing expression can
		       be accessed before the pointer elaboration has taken
		       place in a correct program.

		       These SAVE_EXPRs will be evaluated at the right place
		       by either the evaluation of the initializer for the
		       non-global case or the elaboration code for the global
		       case, and will be attached to the elaboration procedure
		       in the latter case.  */
		    else
	 	     {
			maybe_stable_expr
			  = gnat_stabilize_reference (gnu_expr, true, &stable);

			if (stable)
			  renamed_obj = maybe_stable_expr;

			/* Attaching is actually performed downstream, as soon
			   as we have a VAR_DECL for the pointer we make.  */
		      }

		    gnu_expr = build_unary_op (ADDR_EXPR, gnu_type,
					       maybe_stable_expr);

		    gnu_size = NULL_TREE;
		    used_by_ref = true;
		  }
	      }
	  }

	/* Make a volatile version of this object's type if we are to make
	   the object volatile.  We also interpret 13.3(19) conservatively
	   and disallow any optimizations for such a non-constant object.  */
	if ((Treat_As_Volatile (gnat_entity)
	     || (!const_flag
		 && gnu_type != except_type_node
		 && (Is_Exported (gnat_entity)
		     || imported_p
		     || Present (Address_Clause (gnat_entity)))))
	    && !TYPE_VOLATILE (gnu_type))
	  gnu_type = build_qualified_type (gnu_type,
					   (TYPE_QUALS (gnu_type)
					    | TYPE_QUAL_VOLATILE));

	/* If we are defining an aliased object whose nominal subtype is
	   unconstrained, the object is a record that contains both the
	   template and the object.  If there is an initializer, it will
	   have already been converted to the right type, but we need to
	   create the template if there is no initializer.  */
	if (definition
	    && !gnu_expr
	    && TREE_CODE (gnu_type) == RECORD_TYPE
	    && (TYPE_CONTAINS_TEMPLATE_P (gnu_type)
	        /* Beware that padding might have been introduced above.  */
		|| (TYPE_PADDING_P (gnu_type)
		    && TREE_CODE (TREE_TYPE (TYPE_FIELDS (gnu_type)))
		       == RECORD_TYPE
		    && TYPE_CONTAINS_TEMPLATE_P
		       (TREE_TYPE (TYPE_FIELDS (gnu_type))))))
	  {
	    tree template_field
	      = TYPE_PADDING_P (gnu_type)
		? TYPE_FIELDS (TREE_TYPE (TYPE_FIELDS (gnu_type)))
		: TYPE_FIELDS (gnu_type);
	    vec<constructor_elt, va_gc> *v;
	    vec_alloc (v, 1);
	    tree t = build_template (TREE_TYPE (template_field),
				     TREE_TYPE (DECL_CHAIN (template_field)),
				     NULL_TREE);
	    CONSTRUCTOR_APPEND_ELT (v, template_field, t);
	    gnu_expr = gnat_build_constructor (gnu_type, v);
	  }

	/* Convert the expression to the type of the object except in the
	   case where the object's type is unconstrained or the object's type
	   is a padded record whose field is of self-referential size.  In
	   the former case, converting will generate unnecessary evaluations
	   of the CONSTRUCTOR to compute the size and in the latter case, we
	   want to only copy the actual data.  Also don't convert to a record
	   type with a variant part from a record type without one, to keep
	   the object simpler.  */
	if (gnu_expr
	    && TREE_CODE (gnu_type) != UNCONSTRAINED_ARRAY_TYPE
	    && !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type))
	    && !(TYPE_IS_PADDING_P (gnu_type)
		 && CONTAINS_PLACEHOLDER_P
		    (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (gnu_type)))))
	    && !(TREE_CODE (gnu_type) == RECORD_TYPE
		 && TREE_CODE (TREE_TYPE (gnu_expr)) == RECORD_TYPE
		 && get_variant_part (gnu_type) != NULL_TREE
		 && get_variant_part (TREE_TYPE (gnu_expr)) == NULL_TREE))
	  gnu_expr = convert (gnu_type, gnu_expr);

	/* If this is a pointer that doesn't have an initializing expression,
	   initialize it to NULL, unless the object is imported.  */
	if (definition
	    && (POINTER_TYPE_P (gnu_type) || TYPE_IS_FAT_POINTER_P (gnu_type))
	    && !gnu_expr
	    && !Is_Imported (gnat_entity))
	  gnu_expr = integer_zero_node;

	/* If we are defining the object and it has an Address clause, we must
	   either get the address expression from the saved GCC tree for the
	   object if it has a Freeze node, or elaborate the address expression
	   here since the front-end has guaranteed that the elaboration has no
	   effects in this case.  */
	if (definition && Present (Address_Clause (gnat_entity)))
	  {
	    Node_Id gnat_expr = Expression (Address_Clause (gnat_entity));
	    tree gnu_address
	      = present_gnu_tree (gnat_entity)
		? get_gnu_tree (gnat_entity) : gnat_to_gnu (gnat_expr);

	    save_gnu_tree (gnat_entity, NULL_TREE, false);

	    /* Ignore the size.  It's either meaningless or was handled
	       above.  */
	    gnu_size = NULL_TREE;
	    /* Convert the type of the object to a reference type that can
	       alias everything as per 13.3(19).  */
	    gnu_type
	      = build_reference_type_for_mode (gnu_type, ptr_mode, true);
	    gnu_address = convert (gnu_type, gnu_address);
	    used_by_ref = true;
	    const_flag
	      = !Is_Public (gnat_entity)
		|| compile_time_known_address_p (gnat_expr);

	    /* If this is a deferred constant, the initializer is attached to
	       the full view.  */
	    if (kind == E_Constant && Present (Full_View (gnat_entity)))
	      gnu_expr
		= gnat_to_gnu
		    (Expression (Declaration_Node (Full_View (gnat_entity))));

	    /* If we don't have an initializing expression for the underlying
	       variable, the initializing expression for the pointer is the
	       specified address.  Otherwise, we have to make a COMPOUND_EXPR
	       to assign both the address and the initial value.  */
	    if (!gnu_expr)
	      gnu_expr = gnu_address;
	    else
	      gnu_expr
		= build2 (COMPOUND_EXPR, gnu_type,
			  build_binary_op
			  (MODIFY_EXPR, NULL_TREE,
			   build_unary_op (INDIRECT_REF, NULL_TREE,
					   gnu_address),
			   gnu_expr),
			  gnu_address);
	  }

	/* If it has an address clause and we are not defining it, mark it
	   as an indirect object.  Likewise for Stdcall objects that are
	   imported.  */
	if ((!definition && Present (Address_Clause (gnat_entity)))
	    || (Is_Imported (gnat_entity)
		&& Has_Stdcall_Convention (gnat_entity)))
	  {
	    /* Convert the type of the object to a reference type that can
	       alias everything as per 13.3(19).  */
	    gnu_type
	      = build_reference_type_for_mode (gnu_type, ptr_mode, true);
	    gnu_size = NULL_TREE;

	    /* No point in taking the address of an initializing expression
	       that isn't going to be used.  */
	    gnu_expr = NULL_TREE;

	    /* If it has an address clause whose value is known at compile
	       time, make the object a CONST_DECL.  This will avoid a
	       useless dereference.  */
	    if (Present (Address_Clause (gnat_entity)))
	      {
		Node_Id gnat_address
		  = Expression (Address_Clause (gnat_entity));

		if (compile_time_known_address_p (gnat_address))
		  {
		    gnu_expr = gnat_to_gnu (gnat_address);
		    const_flag = true;
		  }
	      }

	    used_by_ref = true;
	  }

	/* If we are at top level and this object is of variable size,
	   make the actual type a hidden pointer to the real type and
	   make the initializer be a memory allocation and initialization.
	   Likewise for objects we aren't defining (presumed to be
	   external references from other packages), but there we do
	   not set up an initialization.

	   If the object's size overflows, make an allocator too, so that
	   Storage_Error gets raised.  Note that we will never free
	   such memory, so we presume it never will get allocated.  */
	if (!allocatable_size_p (TYPE_SIZE_UNIT (gnu_type),
				 global_bindings_p ()
				 || !definition
				 || static_p)
	    || (gnu_size
		&& !allocatable_size_p (convert (sizetype,
						 size_binop
						 (CEIL_DIV_EXPR, gnu_size,
						  bitsize_unit_node)),
					global_bindings_p ()
					|| !definition
					|| static_p)))
	  {
	    gnu_type = build_reference_type (gnu_type);
	    gnu_size = NULL_TREE;
	    used_by_ref = true;

	    /* In case this was a aliased object whose nominal subtype is
	       unconstrained, the pointer above will be a thin pointer and
	       build_allocator will automatically make the template.

	       If we have a template initializer only (that we made above),
	       pretend there is none and rely on what build_allocator creates
	       again anyway.  Otherwise (if we have a full initializer), get
	       the data part and feed that to build_allocator.

	       If we are elaborating a mutable object, tell build_allocator to
	       ignore a possibly simpler size from the initializer, if any, as
	       we must allocate the maximum possible size in this case.  */
	    if (definition && !imported_p)
	      {
		tree gnu_alloc_type = TREE_TYPE (gnu_type);

		if (TREE_CODE (gnu_alloc_type) == RECORD_TYPE
		    && TYPE_CONTAINS_TEMPLATE_P (gnu_alloc_type))
		  {
		    gnu_alloc_type
		      = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_alloc_type)));

		    if (TREE_CODE (gnu_expr) == CONSTRUCTOR
			&& 1 == vec_safe_length (CONSTRUCTOR_ELTS (gnu_expr)))
		      gnu_expr = 0;
		    else
		      gnu_expr
			= build_component_ref
			    (gnu_expr, NULL_TREE,
			     DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (gnu_expr))),
			     false);
		  }

		if (TREE_CODE (TYPE_SIZE_UNIT (gnu_alloc_type)) == INTEGER_CST
		    && !valid_constant_size_p (TYPE_SIZE_UNIT (gnu_alloc_type)))
		  post_error ("?`Storage_Error` will be raised at run time!",
			      gnat_entity);

		gnu_expr
		  = build_allocator (gnu_alloc_type, gnu_expr, gnu_type,
				     Empty, Empty, gnat_entity, mutable_p);
		const_flag = true;
	      }
	    else
	      {
		gnu_expr = NULL_TREE;
		const_flag = false;
	      }
	  }

	/* If this object would go into the stack and has an alignment larger
	   than the largest stack alignment the back-end can honor, resort to
	   a variable of "aligning type".  */
	if (!global_bindings_p () && !static_p && definition
	    && !imported_p && TYPE_ALIGN (gnu_type) > BIGGEST_ALIGNMENT)
	  {
	    /* Create the new variable.  No need for extra room before the
	       aligned field as this is in automatic storage.  */
	    tree gnu_new_type
	      = make_aligning_type (gnu_type, TYPE_ALIGN (gnu_type),
				    TYPE_SIZE_UNIT (gnu_type),
				    BIGGEST_ALIGNMENT, 0);
	    tree gnu_new_var
	      = create_var_decl (create_concat_name (gnat_entity, "ALIGN"),
				 NULL_TREE, gnu_new_type, NULL_TREE, false,
				 false, false, false, NULL, gnat_entity);

	    /* Initialize the aligned field if we have an initializer.  */
	    if (gnu_expr)
	      add_stmt_with_node
		(build_binary_op (MODIFY_EXPR, NULL_TREE,
				  build_component_ref
				  (gnu_new_var, NULL_TREE,
				   TYPE_FIELDS (gnu_new_type), false),
				  gnu_expr),
		 gnat_entity);

	    /* And setup this entity as a reference to the aligned field.  */
	    gnu_type = build_reference_type (gnu_type);
	    gnu_expr
	      = build_unary_op
		(ADDR_EXPR, gnu_type,
		 build_component_ref (gnu_new_var, NULL_TREE,
				      TYPE_FIELDS (gnu_new_type), false));

	    gnu_size = NULL_TREE;
	    used_by_ref = true;
	    const_flag = true;
	  }

	/* If this is an aliased object with an unconstrained nominal subtype,
	   we make its type a thin reference, i.e. the reference counterpart
	   of a thin pointer, so that it points to the array part.  This is
	   aimed at making it easier for the debugger to decode the object.
	   Note that we have to do that this late because of the couple of
	   allocation adjustments that might be made just above.  */
	if (Is_Constr_Subt_For_UN_Aliased (Etype (gnat_entity))
	    && Is_Array_Type (Etype (gnat_entity))
	    && !type_annotate_only)
	  {
	    tree gnu_array
	      = gnat_to_gnu_type (Base_Type (Etype (gnat_entity)));

	    /* In case the object with the template has already been allocated
	       just above, we have nothing to do here.  */
	    if (!TYPE_IS_THIN_POINTER_P (gnu_type))
	      {
	        gnu_size = NULL_TREE;
		used_by_ref = true;

		if (definition && !imported_p)
		  {
		    tree gnu_unc_var
		      = create_var_decl (concat_name (gnu_entity_name, "UNC"),
					 NULL_TREE, gnu_type, gnu_expr,
					 const_flag, Is_Public (gnat_entity),
					 false, static_p, NULL, gnat_entity);
		    gnu_expr
		      = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_unc_var);
		    TREE_CONSTANT (gnu_expr) = 1;
		    const_flag = true;
		  }
		else
		  {
		    gnu_expr = NULL_TREE;
		    const_flag = false;
		  }
	      }

	    gnu_type
	      = build_reference_type (TYPE_OBJECT_RECORD_TYPE (gnu_array));
	  }

	if (const_flag)
	  gnu_type = build_qualified_type (gnu_type, (TYPE_QUALS (gnu_type)
						      | TYPE_QUAL_CONST));

	/* Convert the expression to the type of the object except in the
	   case where the object's type is unconstrained or the object's type
	   is a padded record whose field is of self-referential size.  In
	   the former case, converting will generate unnecessary evaluations
	   of the CONSTRUCTOR to compute the size and in the latter case, we
	   want to only copy the actual data.  Also don't convert to a record
	   type with a variant part from a record type without one, to keep
	   the object simpler.  */
	if (gnu_expr
	    && TREE_CODE (gnu_type) != UNCONSTRAINED_ARRAY_TYPE
	    && !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type))
	    && !(TYPE_IS_PADDING_P (gnu_type)
		 && CONTAINS_PLACEHOLDER_P
		    (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (gnu_type)))))
	    && !(TREE_CODE (gnu_type) == RECORD_TYPE
		 && TREE_CODE (TREE_TYPE (gnu_expr)) == RECORD_TYPE
		 && get_variant_part (gnu_type) != NULL_TREE
		 && get_variant_part (TREE_TYPE (gnu_expr)) == NULL_TREE))
	  gnu_expr = convert (gnu_type, gnu_expr);

	/* If this name is external or there was a name specified, use it,
	   unless this is a VMS exception object since this would conflict
	   with the symbol we need to export in addition.  Don't use the
	   Interface_Name if there is an address clause (see CD30005).  */
	if (!Is_VMS_Exception (gnat_entity)
	    && ((Present (Interface_Name (gnat_entity))
		 && No (Address_Clause (gnat_entity)))
		|| (Is_Public (gnat_entity)
		    && (!Is_Imported (gnat_entity)
			|| Is_Exported (gnat_entity)))))
	  gnu_ext_name = create_concat_name (gnat_entity, NULL);

	/* If this is an aggregate constant initialized to a constant, force it
	   to be statically allocated.  This saves an initialization copy.  */
	if (!static_p
	    && const_flag
	    && gnu_expr && TREE_CONSTANT (gnu_expr)
	    && AGGREGATE_TYPE_P (gnu_type)
	    && host_integerp (TYPE_SIZE_UNIT (gnu_type), 1)
	    && !(TYPE_IS_PADDING_P (gnu_type)
		 && !host_integerp (TYPE_SIZE_UNIT
				    (TREE_TYPE (TYPE_FIELDS (gnu_type))), 1)))
	  static_p = true;

	/* Now create the variable or the constant and set various flags.  */
	gnu_decl
	  = create_var_decl (gnu_entity_name, gnu_ext_name, gnu_type,
			     gnu_expr, const_flag, Is_Public (gnat_entity),
			     imported_p || !definition, static_p, attr_list,
			     gnat_entity);
	DECL_BY_REF_P (gnu_decl) = used_by_ref;
	DECL_POINTS_TO_READONLY_P (gnu_decl) = used_by_ref && inner_const_flag;
	DECL_CAN_NEVER_BE_NULL_P (gnu_decl) = Can_Never_Be_Null (gnat_entity);

	/* If we are defining an Out parameter and optimization isn't enabled,
	   create a fake PARM_DECL for debugging purposes and make it point to
	   the VAR_DECL.  Suppress debug info for the latter but make sure it
	   will live on the stack so that it can be accessed from within the
	   debugger through the PARM_DECL.  */
	if (kind == E_Out_Parameter
	    && definition
	    && debug_info_p
	    && !optimize
	    && !flag_generate_lto)
	  {
	    tree param = create_param_decl (gnu_entity_name, gnu_type, false);
	    gnat_pushdecl (param, gnat_entity);
	    SET_DECL_VALUE_EXPR (param, gnu_decl);
	    DECL_HAS_VALUE_EXPR_P (param) = 1;
	    DECL_IGNORED_P (gnu_decl) = 1;
	    TREE_ADDRESSABLE (gnu_decl) = 1;
	  }

	/* If this is a loop parameter, set the corresponding flag.  */
	else if (kind == E_Loop_Parameter)
	  DECL_LOOP_PARM_P (gnu_decl) = 1;

	/* If this is a renaming pointer, attach the renamed object to it and
	   register it if we are at the global level.  Note that an external
	   constant is at the global level.  */
	else if (TREE_CODE (gnu_decl) == VAR_DECL && renamed_obj)
	  {
	    SET_DECL_RENAMED_OBJECT (gnu_decl, renamed_obj);
	    if ((!definition && kind == E_Constant) || global_bindings_p ())
	      {
		DECL_RENAMING_GLOBAL_P (gnu_decl) = 1;
		record_global_renaming_pointer (gnu_decl);
	      }
	  }

	/* If this is a constant and we are defining it or it generates a real
	   symbol at the object level and we are referencing it, we may want
	   or need to have a true variable to represent it:
	     - if optimization isn't enabled, for debugging purposes,
	     - if the constant is public and not overlaid on something else,
	     - if its address is taken,
	     - if either itself or its type is aliased.  */
	if (TREE_CODE (gnu_decl) == CONST_DECL
	    && (definition || Sloc (gnat_entity) > Standard_Location)
	    && ((!optimize && debug_info_p)
		|| (Is_Public (gnat_entity)
		    && No (Address_Clause (gnat_entity)))
		|| Address_Taken (gnat_entity)
		|| Is_Aliased (gnat_entity)
		|| Is_Aliased (Etype (gnat_entity))))
	  {
	    tree gnu_corr_var
	      = create_true_var_decl (gnu_entity_name, gnu_ext_name, gnu_type,
				      gnu_expr, true, Is_Public (gnat_entity),
				      !definition, static_p, attr_list,
				      gnat_entity);

	    SET_DECL_CONST_CORRESPONDING_VAR (gnu_decl, gnu_corr_var);

	    /* As debugging information will be generated for the variable,
	       do not generate debugging information for the constant.  */
	    if (debug_info_p)
	      DECL_IGNORED_P (gnu_decl) = 1;
	    else
	      DECL_IGNORED_P (gnu_corr_var) = 1;
	  }

	/* If this is a constant, even if we don't need a true variable, we
	   may need to avoid returning the initializer in every case.  That
	   can happen for the address of a (constant) constructor because,
	   upon dereferencing it, the constructor will be reinjected in the
	   tree, which may not be valid in every case; see lvalue_required_p
	   for more details.  */
	if (TREE_CODE (gnu_decl) == CONST_DECL)
	  DECL_CONST_ADDRESS_P (gnu_decl) = constructor_address_p (gnu_expr);

	/* If this object is declared in a block that contains a block with an
	   exception handler, and we aren't using the GCC exception mechanism,
	   we must force this variable in memory in order to avoid an invalid
	   optimization.  */
	if (Exception_Mechanism != Back_End_Exceptions
	    && Has_Nested_Block_With_Handler (Scope (gnat_entity)))
	  TREE_ADDRESSABLE (gnu_decl) = 1;

	/* If we are defining an object with variable size or an object with
	   fixed size that will be dynamically allocated, and we are using the
	   setjmp/longjmp exception mechanism, update the setjmp buffer.  */
	if (definition
	    && Exception_Mechanism == Setjmp_Longjmp
	    && get_block_jmpbuf_decl ()
	    && DECL_SIZE_UNIT (gnu_decl)
	    && (TREE_CODE (DECL_SIZE_UNIT (gnu_decl)) != INTEGER_CST
		|| (flag_stack_check == GENERIC_STACK_CHECK
		    && compare_tree_int (DECL_SIZE_UNIT (gnu_decl),
					 STACK_CHECK_MAX_VAR_SIZE) > 0)))
	  add_stmt_with_node (build_call_n_expr
			      (update_setjmp_buf_decl, 1,
			       build_unary_op (ADDR_EXPR, NULL_TREE,
					       get_block_jmpbuf_decl ())),
			      gnat_entity);

	/* Back-annotate Esize and Alignment of the object if not already
	   known.  Note that we pick the values of the type, not those of
	   the object, to shield ourselves from low-level platform-dependent
	   adjustments like alignment promotion.  This is both consistent with
	   all the treatment above, where alignment and size are set on the
	   type of the object and not on the object directly, and makes it
	   possible to support all confirming representation clauses.  */
	annotate_object (gnat_entity, TREE_TYPE (gnu_decl), gnu_object_size,
			 used_by_ref);
      }
      break;

    case E_Void:
      /* Return a TYPE_DECL for "void" that we previously made.  */
      gnu_decl = TYPE_NAME (void_type_node);
      break;

    case E_Enumeration_Type:
      /* A special case: for the types Character and Wide_Character in
	 Standard, we do not list all the literals.  So if the literals
	 are not specified, make this an unsigned type.  */
      if (No (First_Literal (gnat_entity)))
	{
	  gnu_type = make_unsigned_type (esize);
	  TYPE_NAME (gnu_type) = gnu_entity_name;

	  /* Set TYPE_STRING_FLAG for Character and Wide_Character types.
	     This is needed by the DWARF-2 back-end to distinguish between
	     unsigned integer types and character types.  */
	  TYPE_STRING_FLAG (gnu_type) = 1;
	  break;
	}

      {
	/* We have a list of enumeral constants in First_Literal.  We make a
	   CONST_DECL for each one and build into GNU_LITERAL_LIST the list to
	   be placed into TYPE_FIELDS.  Each node in the list is a TREE_LIST
	   whose TREE_VALUE is the literal name and whose TREE_PURPOSE is the
	   value of the literal.  But when we have a regular boolean type, we
	   simplify this a little by using a BOOLEAN_TYPE.  */
	bool is_boolean = Is_Boolean_Type (gnat_entity)
			  && !Has_Non_Standard_Rep (gnat_entity);
	tree gnu_literal_list = NULL_TREE;
	Entity_Id gnat_literal;

	if (Is_Unsigned_Type (gnat_entity))
	  gnu_type = make_unsigned_type (esize);
	else
	  gnu_type = make_signed_type (esize);

	TREE_SET_CODE (gnu_type, is_boolean ? BOOLEAN_TYPE : ENUMERAL_TYPE);

	for (gnat_literal = First_Literal (gnat_entity);
	     Present (gnat_literal);
	     gnat_literal = Next_Literal (gnat_literal))
	  {
	    tree gnu_value
	      = UI_To_gnu (Enumeration_Rep (gnat_literal), gnu_type);
	    tree gnu_literal
	      = create_var_decl (get_entity_name (gnat_literal), NULL_TREE,
				 gnu_type, gnu_value, true, false, false,
				 false, NULL, gnat_literal);
	    /* Do not generate debug info for individual enumerators.  */
	    DECL_IGNORED_P (gnu_literal) = 1;
	    save_gnu_tree (gnat_literal, gnu_literal, false);
	    gnu_literal_list = tree_cons (DECL_NAME (gnu_literal),
					  gnu_value, gnu_literal_list);
	  }

	if (!is_boolean)
	  TYPE_VALUES (gnu_type) = nreverse (gnu_literal_list);

	/* Note that the bounds are updated at the end of this function
	   to avoid an infinite recursion since they refer to the type.  */
      }
      goto discrete_type;

    case E_Signed_Integer_Type:
    case E_Ordinary_Fixed_Point_Type:
    case E_Decimal_Fixed_Point_Type:
      /* For integer types, just make a signed type the appropriate number
	 of bits.  */
      gnu_type = make_signed_type (esize);
      goto discrete_type;

    case E_Modular_Integer_Type:
      {
	/* For modular types, make the unsigned type of the proper number
	   of bits and then set up the modulus, if required.  */
	tree gnu_modulus, gnu_high = NULL_TREE;

	/* Packed array types are supposed to be subtypes only.  */
	gcc_assert (!Is_Packed_Array_Type (gnat_entity));

	gnu_type = make_unsigned_type (esize);

	/* Get the modulus in this type.  If it overflows, assume it is because
	   it is equal to 2**Esize.  Note that there is no overflow checking
	   done on unsigned type, so we detect the overflow by looking for
	   a modulus of zero, which is otherwise invalid.  */
	gnu_modulus = UI_To_gnu (Modulus (gnat_entity), gnu_type);

	if (!integer_zerop (gnu_modulus))
	  {
	    TYPE_MODULAR_P (gnu_type) = 1;
	    SET_TYPE_MODULUS (gnu_type, gnu_modulus);
	    gnu_high = fold_build2 (MINUS_EXPR, gnu_type, gnu_modulus,
				    convert (gnu_type, integer_one_node));
	  }

	/* If the upper bound is not maximal, make an extra subtype.  */
	if (gnu_high
	    && !tree_int_cst_equal (gnu_high, TYPE_MAX_VALUE (gnu_type)))
	  {
	    tree gnu_subtype = make_unsigned_type (esize);
	    SET_TYPE_RM_MAX_VALUE (gnu_subtype, gnu_high);
	    TREE_TYPE (gnu_subtype) = gnu_type;
	    TYPE_EXTRA_SUBTYPE_P (gnu_subtype) = 1;
	    TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "UMT");
	    gnu_type = gnu_subtype;
	  }
      }
      goto discrete_type;

    case E_Signed_Integer_Subtype:
    case E_Enumeration_Subtype:
    case E_Modular_Integer_Subtype:
    case E_Ordinary_Fixed_Point_Subtype:
    case E_Decimal_Fixed_Point_Subtype:

      /* For integral subtypes, we make a new INTEGER_TYPE.  Note that we do
	 not want to call create_range_type since we would like each subtype
	 node to be distinct.  ??? Historically this was in preparation for
	 when memory aliasing is implemented, but that's obsolete now given
	 the call to relate_alias_sets below.

	 The TREE_TYPE field of the INTEGER_TYPE points to the base type;
	 this fact is used by the arithmetic conversion functions.

	 We elaborate the Ancestor_Subtype if it is not in the current unit
	 and one of our bounds is non-static.  We do this to ensure consistent
	 naming in the case where several subtypes share the same bounds, by
	 elaborating the first such subtype first, thus using its name.  */

      if (!definition
	  && Present (Ancestor_Subtype (gnat_entity))
	  && !In_Extended_Main_Code_Unit (Ancestor_Subtype (gnat_entity))
	  && (!Compile_Time_Known_Value (Type_Low_Bound (gnat_entity))
	      || !Compile_Time_Known_Value (Type_High_Bound (gnat_entity))))
	gnat_to_gnu_entity (Ancestor_Subtype (gnat_entity), gnu_expr, 0);

      /* Set the precision to the Esize except for bit-packed arrays.  */
      if (Is_Packed_Array_Type (gnat_entity)
	  && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
	esize = UI_To_Int (RM_Size (gnat_entity));

      /* This should be an unsigned type if the base type is unsigned or
	 if the lower bound is constant and non-negative or if the type
	 is biased.  */
      if (Is_Unsigned_Type (Etype (gnat_entity))
	  || Is_Unsigned_Type (gnat_entity)
	  || Has_Biased_Representation (gnat_entity))
	gnu_type = make_unsigned_type (esize);
      else
	gnu_type = make_signed_type (esize);
      TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));

      SET_TYPE_RM_MIN_VALUE
	(gnu_type,
	 convert (TREE_TYPE (gnu_type),
		  elaborate_expression (Type_Low_Bound (gnat_entity),
					gnat_entity, get_identifier ("L"),
					definition, true,
					Needs_Debug_Info (gnat_entity))));

      SET_TYPE_RM_MAX_VALUE
	(gnu_type,
	 convert (TREE_TYPE (gnu_type),
		  elaborate_expression (Type_High_Bound (gnat_entity),
					gnat_entity, get_identifier ("U"),
					definition, true,
					Needs_Debug_Info (gnat_entity))));

      /* One of the above calls might have caused us to be elaborated,
	 so don't blow up if so.  */
      if (present_gnu_tree (gnat_entity))
	{
	  maybe_present = true;
	  break;
	}

      TYPE_BIASED_REPRESENTATION_P (gnu_type)
	= Has_Biased_Representation (gnat_entity);

      /* Attach the TYPE_STUB_DECL in case we have a parallel type.  */
      TYPE_STUB_DECL (gnu_type)
	= create_type_stub_decl (gnu_entity_name, gnu_type);

      /* Inherit our alias set from what we're a subtype of.  Subtypes
	 are not different types and a pointer can designate any instance
	 within a subtype hierarchy.  */
      relate_alias_sets (gnu_type, TREE_TYPE (gnu_type), ALIAS_SET_COPY);

      /* For a packed array, make the original array type a parallel type.  */
      if (debug_info_p
	  && Is_Packed_Array_Type (gnat_entity)
	  && present_gnu_tree (Original_Array_Type (gnat_entity)))
	add_parallel_type (gnu_type,
			   gnat_to_gnu_type
			   (Original_Array_Type (gnat_entity)));

    discrete_type:

      /* We have to handle clauses that under-align the type specially.  */
      if ((Present (Alignment_Clause (gnat_entity))
	   || (Is_Packed_Array_Type (gnat_entity)
	       && Present
		  (Alignment_Clause (Original_Array_Type (gnat_entity)))))
	  && UI_Is_In_Int_Range (Alignment (gnat_entity)))
	{
	  align = UI_To_Int (Alignment (gnat_entity)) * BITS_PER_UNIT;
	  if (align >= TYPE_ALIGN (gnu_type))
	    align = 0;
	}

      /* If the type we are dealing with represents a bit-packed array,
	 we need to have the bits left justified on big-endian targets
	 and right justified on little-endian targets.  We also need to
	 ensure that when the value is read (e.g. for comparison of two
	 such values), we only get the good bits, since the unused bits
	 are uninitialized.  Both goals are accomplished by wrapping up
	 the modular type in an enclosing record type.  */
      if (Is_Packed_Array_Type (gnat_entity)
	  && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
	{
	  tree gnu_field_type, gnu_field;

	  /* Set the RM size before wrapping up the original type.  */
	  SET_TYPE_RM_SIZE (gnu_type,
			    UI_To_gnu (RM_Size (gnat_entity), bitsizetype));
	  TYPE_PACKED_ARRAY_TYPE_P (gnu_type) = 1;

	  /* Create a stripped-down declaration, mainly for debugging.  */
	  create_type_decl (gnu_entity_name, gnu_type, NULL, true,
			    debug_info_p, gnat_entity);

	  /* Now save it and build the enclosing record type.  */
	  gnu_field_type = gnu_type;

	  gnu_type = make_node (RECORD_TYPE);
	  TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "JM");
	  TYPE_PACKED (gnu_type) = 1;
	  TYPE_SIZE (gnu_type) = TYPE_SIZE (gnu_field_type);
	  TYPE_SIZE_UNIT (gnu_type) = TYPE_SIZE_UNIT (gnu_field_type);
	  SET_TYPE_ADA_SIZE (gnu_type, TYPE_RM_SIZE (gnu_field_type));

	  /* Propagate the alignment of the modular type to the record type,
	     unless there is an alignment clause that under-aligns the type.
	     This means that bit-packed arrays are given "ceil" alignment for
	     their size by default, which may seem counter-intuitive but makes
	     it possible to overlay them on modular types easily.  */
	  TYPE_ALIGN (gnu_type)
	    = align > 0 ? align : TYPE_ALIGN (gnu_field_type);

	  relate_alias_sets (gnu_type, gnu_field_type, ALIAS_SET_COPY);

	  /* Don't declare the field as addressable since we won't be taking
	     its address and this would prevent create_field_decl from making
	     a bitfield.  */
	  gnu_field
	    = create_field_decl (get_identifier ("OBJECT"), gnu_field_type,
				 gnu_type, NULL_TREE, bitsize_zero_node, 1, 0);

	  /* Do not emit debug info until after the parallel type is added.  */
	  finish_record_type (gnu_type, gnu_field, 2, false);
	  compute_record_mode (gnu_type);
	  TYPE_JUSTIFIED_MODULAR_P (gnu_type) = 1;

	  if (debug_info_p)
	    {
	      /* Make the original array type a parallel type.  */
	      if (present_gnu_tree (Original_Array_Type (gnat_entity)))
		add_parallel_type (gnu_type,
				   gnat_to_gnu_type
				   (Original_Array_Type (gnat_entity)));

	      rest_of_record_type_compilation (gnu_type);
	    }
	}

      /* If the type we are dealing with has got a smaller alignment than the
	 natural one, we need to wrap it up in a record type and misalign the
	 latter; we reuse the padding machinery for this purpose.  Note that,
	 even if the record type is marked as packed because of misalignment,
	 we don't pack the field so as to give it the size of the type.  */
      else if (align > 0)
	{
	  tree gnu_field_type, gnu_field;

	  /* Set the RM size before wrapping up the type.  */
	  SET_TYPE_RM_SIZE (gnu_type,
			    UI_To_gnu (RM_Size (gnat_entity), bitsizetype));

	  /* Create a stripped-down declaration, mainly for debugging.  */
	  create_type_decl (gnu_entity_name, gnu_type, NULL, true,
			    debug_info_p, gnat_entity);

	  /* Now save it and build the enclosing record type.  */
	  gnu_field_type = gnu_type;

	  gnu_type = make_node (RECORD_TYPE);
	  TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "PAD");
	  TYPE_PACKED (gnu_type) = 1;
	  TYPE_SIZE (gnu_type) = TYPE_SIZE (gnu_field_type);
	  TYPE_SIZE_UNIT (gnu_type) = TYPE_SIZE_UNIT (gnu_field_type);
	  SET_TYPE_ADA_SIZE (gnu_type, TYPE_RM_SIZE (gnu_field_type));
	  TYPE_ALIGN (gnu_type) = align;
	  relate_alias_sets (gnu_type, gnu_field_type, ALIAS_SET_COPY);

	  /* Don't declare the field as addressable since we won't be taking
	     its address and this would prevent create_field_decl from making
	     a bitfield.  */
	  gnu_field
	    = create_field_decl (get_identifier ("F"), gnu_field_type,
				 gnu_type, TYPE_SIZE (gnu_field_type),
				 bitsize_zero_node, 0, 0);

	  finish_record_type (gnu_type, gnu_field, 2, debug_info_p);
	  compute_record_mode (gnu_type);
	  TYPE_PADDING_P (gnu_type) = 1;
	}

      break;

    case E_Floating_Point_Type:
      /* If this is a VAX floating-point type, use an integer of the proper
	 size.  All the operations will be handled with ASM statements.  */
      if (Vax_Float (gnat_entity))
	{
	  gnu_type = make_signed_type (esize);
	  TYPE_VAX_FLOATING_POINT_P (gnu_type) = 1;
	  SET_TYPE_DIGITS_VALUE (gnu_type,
				 UI_To_gnu (Digits_Value (gnat_entity),
					    sizetype));
	  break;
	}

      /* The type of the Low and High bounds can be our type if this is
	 a type from Standard, so set them at the end of the function.  */
      gnu_type = make_node (REAL_TYPE);
      TYPE_PRECISION (gnu_type) = fp_size_to_prec (esize);
      layout_type (gnu_type);
      break;

    case E_Floating_Point_Subtype:
      if (Vax_Float (gnat_entity))
	{
	  gnu_type = gnat_to_gnu_type (Etype (gnat_entity));
	  break;
	}

      {
	if (!definition
	    && Present (Ancestor_Subtype (gnat_entity))
	    && !In_Extended_Main_Code_Unit (Ancestor_Subtype (gnat_entity))
	    && (!Compile_Time_Known_Value (Type_Low_Bound (gnat_entity))
		|| !Compile_Time_Known_Value (Type_High_Bound (gnat_entity))))
	  gnat_to_gnu_entity (Ancestor_Subtype (gnat_entity),
			      gnu_expr, 0);

	gnu_type = make_node (REAL_TYPE);
	TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));
	TYPE_PRECISION (gnu_type) = fp_size_to_prec (esize);
	TYPE_GCC_MIN_VALUE (gnu_type)
	  = TYPE_GCC_MIN_VALUE (TREE_TYPE (gnu_type));
	TYPE_GCC_MAX_VALUE (gnu_type)
	  = TYPE_GCC_MAX_VALUE (TREE_TYPE (gnu_type));
	layout_type (gnu_type);

	SET_TYPE_RM_MIN_VALUE
	  (gnu_type,
	   convert (TREE_TYPE (gnu_type),
		    elaborate_expression (Type_Low_Bound (gnat_entity),
					  gnat_entity, get_identifier ("L"),
					  definition, true,
					  Needs_Debug_Info (gnat_entity))));

	SET_TYPE_RM_MAX_VALUE
	  (gnu_type,
	   convert (TREE_TYPE (gnu_type),
		    elaborate_expression (Type_High_Bound (gnat_entity),
					  gnat_entity, get_identifier ("U"),
					  definition, true,
					  Needs_Debug_Info (gnat_entity))));

	/* One of the above calls might have caused us to be elaborated,
	   so don't blow up if so.  */
	if (present_gnu_tree (gnat_entity))
	  {
	    maybe_present = true;
	    break;
	  }

	/* Inherit our alias set from what we're a subtype of, as for
	   integer subtypes.  */
	relate_alias_sets (gnu_type, TREE_TYPE (gnu_type), ALIAS_SET_COPY);
      }
    break;

      /* Array and String Types and Subtypes

	 Unconstrained array types are represented by E_Array_Type and
	 constrained array types are represented by E_Array_Subtype.  There
	 are no actual objects of an unconstrained array type; all we have
	 are pointers to that type.

	 The following fields are defined on array types and subtypes:

		Component_Type     Component type of the array.
		Number_Dimensions  Number of dimensions (an int).
		First_Index	   Type of first index.  */

    case E_String_Type:
    case E_Array_Type:
      {
	const bool convention_fortran_p
	  = (Convention (gnat_entity) == Convention_Fortran);
	const int ndim = Number_Dimensions (gnat_entity);
	tree gnu_template_type;
	tree gnu_ptr_template;
	tree gnu_template_reference, gnu_template_fields, gnu_fat_type;
	tree *gnu_index_types = XALLOCAVEC (tree, ndim);
	tree *gnu_temp_fields = XALLOCAVEC (tree, ndim);
	tree gnu_max_size = size_one_node, gnu_max_size_unit, tem, t;
	Entity_Id gnat_index, gnat_name;
	int index;
	tree comp_type;

	/* Create the type for the component now, as it simplifies breaking
	   type reference loops.  */
	comp_type
	  = gnat_to_gnu_component_type (gnat_entity, definition, debug_info_p);
	if (present_gnu_tree (gnat_entity))
	  {
	    /* As a side effect, the type may have been translated.  */
	    maybe_present = true;
	    break;
	  }

	/* We complete an existing dummy fat pointer type in place.  This both
	   avoids further complex adjustments in update_pointer_to and yields
	   better debugging information in DWARF by leveraging the support for
	   incomplete declarations of "tagged" types in the DWARF back-end.  */
	gnu_type = get_dummy_type (gnat_entity);
	if (gnu_type && TYPE_POINTER_TO (gnu_type))
	  {
	    gnu_fat_type = TYPE_MAIN_VARIANT (TYPE_POINTER_TO (gnu_type));
	    TYPE_NAME (gnu_fat_type) = NULL_TREE;
	    /* Save the contents of the dummy type for update_pointer_to.  */
	    TYPE_POINTER_TO (gnu_type) = copy_type (gnu_fat_type);
	    gnu_ptr_template =
	      TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (gnu_fat_type)));
	    gnu_template_type = TREE_TYPE (gnu_ptr_template);
	  }
	else
	  {
	    gnu_fat_type = make_node (RECORD_TYPE);
	    gnu_template_type = make_node (RECORD_TYPE);
	    gnu_ptr_template = build_pointer_type (gnu_template_type);
	  }

	/* Make a node for the array.  If we are not defining the array
	   suppress expanding incomplete types.  */
	gnu_type = make_node (UNCONSTRAINED_ARRAY_TYPE);

	if (!definition)
	  {
	    defer_incomplete_level++;
	    this_deferred = true;
	  }

	/* Build the fat pointer type.  Use a "void *" object instead of
	   a pointer to the array type since we don't have the array type
	   yet (it will reference the fat pointer via the bounds).  */
	tem
	  = create_field_decl (get_identifier ("P_ARRAY"), ptr_void_type_node,
			       gnu_fat_type, NULL_TREE, NULL_TREE, 0, 0);
	DECL_CHAIN (tem)
	  = create_field_decl (get_identifier ("P_BOUNDS"), gnu_ptr_template,
			       gnu_fat_type, NULL_TREE, NULL_TREE, 0, 0);

	if (COMPLETE_TYPE_P (gnu_fat_type))
	  {
	    /* We are going to lay it out again so reset the alias set.  */
	    alias_set_type alias_set = TYPE_ALIAS_SET (gnu_fat_type);
	    TYPE_ALIAS_SET (gnu_fat_type) = -1;
	    finish_fat_pointer_type (gnu_fat_type, tem);
	    TYPE_ALIAS_SET (gnu_fat_type) = alias_set;
	    for (t = gnu_fat_type; t; t = TYPE_NEXT_VARIANT (t))
	      {
		TYPE_FIELDS (t) = tem;
		SET_TYPE_UNCONSTRAINED_ARRAY (t, gnu_type);
	      }
	  }
	else
	  {
	    finish_fat_pointer_type (gnu_fat_type, tem);
	    SET_TYPE_UNCONSTRAINED_ARRAY (gnu_fat_type, gnu_type);
	  }

	/* Build a reference to the template from a PLACEHOLDER_EXPR that
	   is the fat pointer.  This will be used to access the individual
	   fields once we build them.  */
	tem = build3 (COMPONENT_REF, gnu_ptr_template,
		      build0 (PLACEHOLDER_EXPR, gnu_fat_type),
		      DECL_CHAIN (TYPE_FIELDS (gnu_fat_type)), NULL_TREE);
	gnu_template_reference
	  = build_unary_op (INDIRECT_REF, gnu_template_type, tem);
	TREE_READONLY (gnu_template_reference) = 1;
	TREE_THIS_NOTRAP (gnu_template_reference) = 1;

	/* Now create the GCC type for each index and add the fields for that
	   index to the template.  */
	for (index = (convention_fortran_p ? ndim - 1 : 0),
	     gnat_index = First_Index (gnat_entity);
	     0 <= index && index < ndim;
	     index += (convention_fortran_p ? - 1 : 1),
	     gnat_index = Next_Index (gnat_index))
	  {
	    char field_name[16];
	    tree gnu_index_base_type
	      = get_unpadded_type (Base_Type (Etype (gnat_index)));
	    tree gnu_lb_field, gnu_hb_field, gnu_orig_min, gnu_orig_max;
	    tree gnu_min, gnu_max, gnu_high;

	    /* Make the FIELD_DECLs for the low and high bounds of this
	       type and then make extractions of these fields from the
	       template.  */
	    sprintf (field_name, "LB%d", index);
	    gnu_lb_field = create_field_decl (get_identifier (field_name),
					      gnu_index_base_type,
					      gnu_template_type, NULL_TREE,
					      NULL_TREE, 0, 0);
	    Sloc_to_locus (Sloc (gnat_entity),
			   &DECL_SOURCE_LOCATION (gnu_lb_field));

	    field_name[0] = 'U';
	    gnu_hb_field = create_field_decl (get_identifier (field_name),
					      gnu_index_base_type,
					      gnu_template_type, NULL_TREE,
					      NULL_TREE, 0, 0);
	    Sloc_to_locus (Sloc (gnat_entity),
			   &DECL_SOURCE_LOCATION (gnu_hb_field));

	    gnu_temp_fields[index] = chainon (gnu_lb_field, gnu_hb_field);

	    /* We can't use build_component_ref here since the template type
	       isn't complete yet.  */
	    gnu_orig_min = build3 (COMPONENT_REF, gnu_index_base_type,
				   gnu_template_reference, gnu_lb_field,
				   NULL_TREE);
	    gnu_orig_max = build3 (COMPONENT_REF, gnu_index_base_type,
				   gnu_template_reference, gnu_hb_field,
				   NULL_TREE);
	    TREE_READONLY (gnu_orig_min) = TREE_READONLY (gnu_orig_max) = 1;

	    gnu_min = convert (sizetype, gnu_orig_min);
	    gnu_max = convert (sizetype, gnu_orig_max);

	    /* Compute the size of this dimension.  See the E_Array_Subtype
	       case below for the rationale.  */
	    gnu_high
	      = build3 (COND_EXPR, sizetype,
			build2 (GE_EXPR, boolean_type_node,
				gnu_orig_max, gnu_orig_min),
			gnu_max,
			size_binop (MINUS_EXPR, gnu_min, size_one_node));

	    /* Make a range type with the new range in the Ada base type.
	       Then make an index type with the size range in sizetype.  */
	    gnu_index_types[index]
	      = create_index_type (gnu_min, gnu_high,
				   create_range_type (gnu_index_base_type,
						      gnu_orig_min,
						      gnu_orig_max),
				   gnat_entity);

	    /* Update the maximum size of the array in elements.  */
	    if (gnu_max_size)
	      {
		tree gnu_index_type = get_unpadded_type (Etype (gnat_index));
		tree gnu_min
		  = convert (sizetype, TYPE_MIN_VALUE (gnu_index_type));
		tree gnu_max
		  = convert (sizetype, TYPE_MAX_VALUE (gnu_index_type));
		tree gnu_this_max
		  = size_binop (MAX_EXPR,
				size_binop (PLUS_EXPR, size_one_node,
					    size_binop (MINUS_EXPR,
							gnu_max, gnu_min)),
				size_zero_node);

		if (TREE_CODE (gnu_this_max) == INTEGER_CST
		    && TREE_OVERFLOW (gnu_this_max))
		  gnu_max_size = NULL_TREE;
		else
		  gnu_max_size
		    = size_binop (MULT_EXPR, gnu_max_size, gnu_this_max);
	      }

	    TYPE_NAME (gnu_index_types[index])
	      = create_concat_name (gnat_entity, field_name);
	  }

	/* Install all the fields into the template.  */
	TYPE_NAME (gnu_template_type)
	  = create_concat_name (gnat_entity, "XUB");
	gnu_template_fields = NULL_TREE;
	for (index = 0; index < ndim; index++)
	  gnu_template_fields
	    = chainon (gnu_template_fields, gnu_temp_fields[index]);
	finish_record_type (gnu_template_type, gnu_template_fields, 0,
			    debug_info_p);
	TYPE_READONLY (gnu_template_type) = 1;

	/* If Component_Size is not already specified, annotate it with the
	   size of the component.  */
	if (Unknown_Component_Size (gnat_entity))
	  Set_Component_Size (gnat_entity,
                              annotate_value (TYPE_SIZE (comp_type)));

	/* Compute the maximum size of the array in units and bits.  */
	if (gnu_max_size)
	  {
	    gnu_max_size_unit = size_binop (MULT_EXPR, gnu_max_size,
					    TYPE_SIZE_UNIT (comp_type));
	    gnu_max_size = size_binop (MULT_EXPR,
				       convert (bitsizetype, gnu_max_size),
				       TYPE_SIZE (comp_type));
	  }
	else
	  gnu_max_size_unit = NULL_TREE;

	/* Now build the array type.  */
        tem = comp_type;
	for (index = ndim - 1; index >= 0; index--)
	  {
	    tem = build_nonshared_array_type (tem, gnu_index_types[index]);
	    if (Reverse_Storage_Order (gnat_entity))
	      sorry ("non-default Scalar_Storage_Order");
	    TYPE_MULTI_ARRAY_P (tem) = (index > 0);
	    if (array_type_has_nonaliased_component (tem, gnat_entity))
	      TYPE_NONALIASED_COMPONENT (tem) = 1;

	    /* If it is passed by reference, force BLKmode to ensure that
	       objects of this type will always be put in memory.  */
	    if (TYPE_MODE (tem) != BLKmode
		&& Is_By_Reference_Type (gnat_entity))
	      SET_TYPE_MODE (tem, BLKmode);
	  }

	/* If an alignment is specified, use it if valid.  But ignore it
	   for the original type of packed array types.  If the alignment
	   was requested with an explicit alignment clause, state so.  */
	if (No (Packed_Array_Type (gnat_entity))
	    && Known_Alignment (gnat_entity))
	  {
	    TYPE_ALIGN (tem)
	      = validate_alignment (Alignment (gnat_entity), gnat_entity,
				    TYPE_ALIGN (tem));
	    if (Present (Alignment_Clause (gnat_entity)))
	      TYPE_USER_ALIGN (tem) = 1;
	  }

	TYPE_CONVENTION_FORTRAN_P (tem) = convention_fortran_p;

	/* Adjust the type of the pointer-to-array field of the fat pointer
	   and record the aliasing relationships if necessary.  */
	TREE_TYPE (TYPE_FIELDS (gnu_fat_type)) = build_pointer_type (tem);
	if (TYPE_ALIAS_SET_KNOWN_P (gnu_fat_type))
	  record_component_aliases (gnu_fat_type);

	/* The result type is an UNCONSTRAINED_ARRAY_TYPE that indicates the
	   corresponding fat pointer.  */
	TREE_TYPE (gnu_type) = gnu_fat_type;
	TYPE_POINTER_TO (gnu_type) = gnu_fat_type;
	TYPE_REFERENCE_TO (gnu_type) = gnu_fat_type;
	SET_TYPE_MODE (gnu_type, BLKmode);
	TYPE_ALIGN (gnu_type) = TYPE_ALIGN (tem);

	/* If the maximum size doesn't overflow, use it.  */
	if (gnu_max_size
	    && TREE_CODE (gnu_max_size) == INTEGER_CST
	    && !TREE_OVERFLOW (gnu_max_size)
	    && TREE_CODE (gnu_max_size_unit) == INTEGER_CST
	    && !TREE_OVERFLOW (gnu_max_size_unit))
	  {
	    TYPE_SIZE (tem) = size_binop (MIN_EXPR, gnu_max_size,
					  TYPE_SIZE (tem));
	    TYPE_SIZE_UNIT (tem) = size_binop (MIN_EXPR, gnu_max_size_unit,
					       TYPE_SIZE_UNIT (tem));
	  }

	create_type_decl (create_concat_name (gnat_entity, "XUA"),
			  tem, NULL, !Comes_From_Source (gnat_entity),
			  debug_info_p, gnat_entity);

	/* Give the fat pointer type a name.  If this is a packed type, tell
	   the debugger how to interpret the underlying bits.  */
	if (Present (Packed_Array_Type (gnat_entity)))
	  gnat_name = Packed_Array_Type (gnat_entity);
	else
	  gnat_name = gnat_entity;
	create_type_decl (create_concat_name (gnat_name, "XUP"),
			  gnu_fat_type, NULL, !Comes_From_Source (gnat_entity),
			  debug_info_p, gnat_entity);

	/* Create the type to be designated by thin pointers: a record type for
	   the array and its template.  We used to shift the fields to have the
	   template at a negative offset, but this was somewhat of a kludge; we
	   now shift thin pointer values explicitly but only those which have a
	   TYPE_UNCONSTRAINED_ARRAY attached to the designated RECORD_TYPE.  */
	tem = build_unc_object_type (gnu_template_type, tem,
				     create_concat_name (gnat_name, "XUT"),
				     debug_info_p);

	SET_TYPE_UNCONSTRAINED_ARRAY (tem, gnu_type);
	TYPE_OBJECT_RECORD_TYPE (gnu_type) = tem;
      }
      break;

    case E_String_Subtype:
    case E_Array_Subtype:

      /* This is the actual data type for array variables.  Multidimensional
	 arrays are implemented as arrays of arrays.  Note that arrays which
	 have sparse enumeration subtypes as index components create sparse
	 arrays, which is obviously space inefficient but so much easier to
	 code for now.

	 Also note that the subtype never refers to the unconstrained array
	 type, which is somewhat at variance with Ada semantics.

	 First check to see if this is simply a renaming of the array type.
	 If so, the result is the array type.  */

      gnu_type = gnat_to_gnu_type (Etype (gnat_entity));
      if (!Is_Constrained (gnat_entity))
	;
      else
	{
	  Entity_Id gnat_index, gnat_base_index;
	  const bool convention_fortran_p
	    = (Convention (gnat_entity) == Convention_Fortran);
	  const int ndim = Number_Dimensions (gnat_entity);
	  tree gnu_base_type = gnu_type;
	  tree *gnu_index_types = XALLOCAVEC (tree, ndim);
	  tree gnu_max_size = size_one_node, gnu_max_size_unit;
	  bool need_index_type_struct = false;
	  int index;

	  /* First create the GCC type for each index and find out whether
	     special types are needed for debugging information.  */
	  for (index = (convention_fortran_p ? ndim - 1 : 0),
	       gnat_index = First_Index (gnat_entity),
	       gnat_base_index
		 = First_Index (Implementation_Base_Type (gnat_entity));
	       0 <= index && index < ndim;
	       index += (convention_fortran_p ? - 1 : 1),
	       gnat_index = Next_Index (gnat_index),
	       gnat_base_index = Next_Index (gnat_base_index))
	    {
	      tree gnu_index_type = get_unpadded_type (Etype (gnat_index));
	      tree gnu_orig_min = TYPE_MIN_VALUE (gnu_index_type);
	      tree gnu_orig_max = TYPE_MAX_VALUE (gnu_index_type);
	      tree gnu_min = convert (sizetype, gnu_orig_min);
	      tree gnu_max = convert (sizetype, gnu_orig_max);
	      tree gnu_base_index_type
		= get_unpadded_type (Etype (gnat_base_index));
	      tree gnu_base_orig_min = TYPE_MIN_VALUE (gnu_base_index_type);
	      tree gnu_base_orig_max = TYPE_MAX_VALUE (gnu_base_index_type);
	      tree gnu_high;

	      /* See if the base array type is already flat.  If it is, we
		 are probably compiling an ACATS test but it will cause the
		 code below to malfunction if we don't handle it specially.  */
	      if (TREE_CODE (gnu_base_orig_min) == INTEGER_CST
		  && TREE_CODE (gnu_base_orig_max) == INTEGER_CST
		  && tree_int_cst_lt (gnu_base_orig_max, gnu_base_orig_min))
		{
		  gnu_min = size_one_node;
		  gnu_max = size_zero_node;
		  gnu_high = gnu_max;
		}

	      /* Similarly, if one of the values overflows in sizetype and the
		 range is null, use 1..0 for the sizetype bounds.  */
	      else if (TREE_CODE (gnu_min) == INTEGER_CST
		       && TREE_CODE (gnu_max) == INTEGER_CST
		       && (TREE_OVERFLOW (gnu_min) || TREE_OVERFLOW (gnu_max))
		       && tree_int_cst_lt (gnu_orig_max, gnu_orig_min))
		{
		  gnu_min = size_one_node;
		  gnu_max = size_zero_node;
		  gnu_high = gnu_max;
		}

	      /* If the minimum and maximum values both overflow in sizetype,
		 but the difference in the original type does not overflow in
		 sizetype, ignore the overflow indication.  */
	      else if (TREE_CODE (gnu_min) == INTEGER_CST
		       && TREE_CODE (gnu_max) == INTEGER_CST
		       && TREE_OVERFLOW (gnu_min) && TREE_OVERFLOW (gnu_max)
		       && !TREE_OVERFLOW
			   (convert (sizetype,
				     fold_build2 (MINUS_EXPR, gnu_index_type,
						  gnu_orig_max,
						  gnu_orig_min))))
		{
		  TREE_OVERFLOW (gnu_min) = 0;
		  TREE_OVERFLOW (gnu_max) = 0;
		  gnu_high = gnu_max;
		}

	      /* Compute the size of this dimension in the general case.  We
		 need to provide GCC with an upper bound to use but have to
		 deal with the "superflat" case.  There are three ways to do
		 this.  If we can prove that the array can never be superflat,
		 we can just use the high bound of the index type.  */
	      else if ((Nkind (gnat_index) == N_Range
		        && cannot_be_superflat_p (gnat_index))
		       /* Packed Array Types are never superflat.  */
		       || Is_Packed_Array_Type (gnat_entity))
		gnu_high = gnu_max;

	      /* Otherwise, if the high bound is constant but the low bound is
		 not, we use the expression (hb >= lb) ? lb : hb + 1 for the
		 lower bound.  Note that the comparison must be done in the
		 original type to avoid any overflow during the conversion.  */
	      else if (TREE_CODE (gnu_max) == INTEGER_CST
		       && TREE_CODE (gnu_min) != INTEGER_CST)
		{
		  gnu_high = gnu_max;
		  gnu_min
		    = build_cond_expr (sizetype,
				       build_binary_op (GE_EXPR,
							boolean_type_node,
							gnu_orig_max,
							gnu_orig_min),
				       gnu_min,
				       int_const_binop (PLUS_EXPR, gnu_max,
							size_one_node));
		}

	      /* Finally we use (hb >= lb) ? hb : lb - 1 for the upper bound
		 in all the other cases.  Note that, here as well as above,
		 the condition used in the comparison must be equivalent to
		 the condition (length != 0).  This is relied upon in order
		 to optimize array comparisons in compare_arrays.  Moreover
		 we use int_const_binop for the shift by 1 if the bound is
		 constant to avoid any unwanted overflow.  */
	      else
		gnu_high
		  = build_cond_expr (sizetype,
				     build_binary_op (GE_EXPR,
						      boolean_type_node,
						      gnu_orig_max,
						      gnu_orig_min),
				     gnu_max,
				     TREE_CODE (gnu_min) == INTEGER_CST
				     ? int_const_binop (MINUS_EXPR, gnu_min,
							size_one_node)
				     : size_binop (MINUS_EXPR, gnu_min,
						   size_one_node));

	      /* Reuse the index type for the range type.  Then make an index
		 type with the size range in sizetype.  */
	      gnu_index_types[index]
		= create_index_type (gnu_min, gnu_high, gnu_index_type,
				     gnat_entity);

	      /* Update the maximum size of the array in elements.  Here we
		 see if any constraint on the index type of the base type
		 can be used in the case of self-referential bound on the
		 index type of the subtype.  We look for a non-"infinite"
		 and non-self-referential bound from any type involved and
		 handle each bound separately.  */
	      if (gnu_max_size)
		{
		  tree gnu_base_min = convert (sizetype, gnu_base_orig_min);
		  tree gnu_base_max = convert (sizetype, gnu_base_orig_max);
		  tree gnu_base_index_base_type
		    = get_base_type (gnu_base_index_type);
		  tree gnu_base_base_min
		    = convert (sizetype,
			       TYPE_MIN_VALUE (gnu_base_index_base_type));
		  tree gnu_base_base_max
		    = convert (sizetype,
			       TYPE_MAX_VALUE (gnu_base_index_base_type));

		  if (!CONTAINS_PLACEHOLDER_P (gnu_min)
		      || !(TREE_CODE (gnu_base_min) == INTEGER_CST
			   && !TREE_OVERFLOW (gnu_base_min)))
		    gnu_base_min = gnu_min;

		  if (!CONTAINS_PLACEHOLDER_P (gnu_max)
		      || !(TREE_CODE (gnu_base_max) == INTEGER_CST
			   && !TREE_OVERFLOW (gnu_base_max)))
		    gnu_base_max = gnu_max;

		  if ((TREE_CODE (gnu_base_min) == INTEGER_CST
		       && TREE_OVERFLOW (gnu_base_min))
		      || operand_equal_p (gnu_base_min, gnu_base_base_min, 0)
		      || (TREE_CODE (gnu_base_max) == INTEGER_CST
			  && TREE_OVERFLOW (gnu_base_max))
		      || operand_equal_p (gnu_base_max, gnu_base_base_max, 0))
		    gnu_max_size = NULL_TREE;
		  else
		    {
		      tree gnu_this_max
			= size_binop (MAX_EXPR,
				      size_binop (PLUS_EXPR, size_one_node,
						  size_binop (MINUS_EXPR,
							      gnu_base_max,
							      gnu_base_min)),
				      size_zero_node);

		      if (TREE_CODE (gnu_this_max) == INTEGER_CST
			  && TREE_OVERFLOW (gnu_this_max))
			gnu_max_size = NULL_TREE;
		      else
			gnu_max_size
			  = size_binop (MULT_EXPR, gnu_max_size, gnu_this_max);
		    }
		}

	      /* We need special types for debugging information to point to
		 the index types if they have variable bounds, are not integer
		 types, are biased or are wider than sizetype.  */
	      if (!integer_onep (gnu_orig_min)
		  || TREE_CODE (gnu_orig_max) != INTEGER_CST
		  || TREE_CODE (gnu_index_type) != INTEGER_TYPE
		  || (TREE_TYPE (gnu_index_type)
		      && TREE_CODE (TREE_TYPE (gnu_index_type))
			 != INTEGER_TYPE)
		  || TYPE_BIASED_REPRESENTATION_P (gnu_index_type)
		  || compare_tree_int (rm_size (gnu_index_type),
				       TYPE_PRECISION (sizetype)) > 0)
		need_index_type_struct = true;
	    }

	  /* Then flatten: create the array of arrays.  For an array type
	     used to implement a packed array, get the component type from
	     the original array type since the representation clauses that
	     can affect it are on the latter.  */
	  if (Is_Packed_Array_Type (gnat_entity)
	      && !Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
	    {
	      gnu_type = gnat_to_gnu_type (Original_Array_Type (gnat_entity));
	      for (index = ndim - 1; index >= 0; index--)
		gnu_type = TREE_TYPE (gnu_type);

	      /* One of the above calls might have caused us to be elaborated,
		 so don't blow up if so.  */
	      if (present_gnu_tree (gnat_entity))
		{
		  maybe_present = true;
		  break;
		}
	    }
	  else
	    {
	      gnu_type = gnat_to_gnu_component_type (gnat_entity, definition,
						     debug_info_p);

	      /* One of the above calls might have caused us to be elaborated,
		 so don't blow up if so.  */
	      if (present_gnu_tree (gnat_entity))
		{
		  maybe_present = true;
		  break;
		}
	    }

	  /* Compute the maximum size of the array in units and bits.  */
	  if (gnu_max_size)
	    {
	      gnu_max_size_unit = size_binop (MULT_EXPR, gnu_max_size,
					      TYPE_SIZE_UNIT (gnu_type));
	      gnu_max_size = size_binop (MULT_EXPR,
					 convert (bitsizetype, gnu_max_size),
					 TYPE_SIZE (gnu_type));
	    }
	  else
	    gnu_max_size_unit = NULL_TREE;

	  /* Now build the array type.  */
	  for (index = ndim - 1; index >= 0; index --)
	    {
	      gnu_type = build_nonshared_array_type (gnu_type,
						     gnu_index_types[index]);
	      TYPE_MULTI_ARRAY_P (gnu_type) = (index > 0);
	      if (array_type_has_nonaliased_component (gnu_type, gnat_entity))
		TYPE_NONALIASED_COMPONENT (gnu_type) = 1;

	      /* See the E_Array_Type case for the rationale.  */
	      if (TYPE_MODE (gnu_type) != BLKmode
		  && Is_By_Reference_Type (gnat_entity))
		SET_TYPE_MODE (gnu_type, BLKmode);
	    }

	  /* Attach the TYPE_STUB_DECL in case we have a parallel type.  */
	  TYPE_STUB_DECL (gnu_type)
	    = create_type_stub_decl (gnu_entity_name, gnu_type);

	  /* If we are at file level and this is a multi-dimensional array,
	     we need to make a variable corresponding to the stride of the
	     inner dimensions.   */
	  if (global_bindings_p () && ndim > 1)
	    {
	      tree gnu_st_name = get_identifier ("ST");
	      tree gnu_arr_type;

	      for (gnu_arr_type = TREE_TYPE (gnu_type);
		   TREE_CODE (gnu_arr_type) == ARRAY_TYPE;
		   gnu_arr_type = TREE_TYPE (gnu_arr_type),
		   gnu_st_name = concat_name (gnu_st_name, "ST"))
		{
		  tree eltype = TREE_TYPE (gnu_arr_type);

		  TYPE_SIZE (gnu_arr_type)
		    = elaborate_expression_1 (TYPE_SIZE (gnu_arr_type),
					      gnat_entity, gnu_st_name,
					      definition, false);

		  /* ??? For now, store the size as a multiple of the
		     alignment of the element type in bytes so that we
		     can see the alignment from the tree.  */
		  TYPE_SIZE_UNIT (gnu_arr_type)
		    = elaborate_expression_2 (TYPE_SIZE_UNIT (gnu_arr_type),
					      gnat_entity,
					      concat_name (gnu_st_name, "A_U"),
					      definition, false,
					      TYPE_ALIGN (eltype));

		  /* ??? create_type_decl is not invoked on the inner types so
		     the MULT_EXPR node built above will never be marked.  */
		  MARK_VISITED (TYPE_SIZE_UNIT (gnu_arr_type));
		}
	    }

	  /* If we need to write out a record type giving the names of the
	     bounds for debugging purposes, do it now and make the record
	     type a parallel type.  This is not needed for a packed array
	     since the bounds are conveyed by the original array type.  */
	  if (need_index_type_struct
	      && debug_info_p
	      && !Is_Packed_Array_Type (gnat_entity))
	    {
	      tree gnu_bound_rec = make_node (RECORD_TYPE);
	      tree gnu_field_list = NULL_TREE;
	      tree gnu_field;

	      TYPE_NAME (gnu_bound_rec)
		= create_concat_name (gnat_entity, "XA");

	      for (index = ndim - 1; index >= 0; index--)
		{
		  tree gnu_index = TYPE_INDEX_TYPE (gnu_index_types[index]);
		  tree gnu_index_name = TYPE_NAME (gnu_index);

		  if (TREE_CODE (gnu_index_name) == TYPE_DECL)
		    gnu_index_name = DECL_NAME (gnu_index_name);

		  /* Make sure to reference the types themselves, and not just
		     their names, as the debugger may fall back on them.  */
		  gnu_field = create_field_decl (gnu_index_name, gnu_index,
						 gnu_bound_rec, NULL_TREE,
						 NULL_TREE, 0, 0);
		  DECL_CHAIN (gnu_field) = gnu_field_list;
		  gnu_field_list = gnu_field;
		}

	      finish_record_type (gnu_bound_rec, gnu_field_list, 0, true);
	      add_parallel_type (gnu_type, gnu_bound_rec);
	    }

	  /* If this is a packed array type, make the original array type a
	     parallel type.  Otherwise, do it for the base array type if it
	     isn't artificial to make sure it is kept in the debug info.  */
	  if (debug_info_p)
	    {
	      if (Is_Packed_Array_Type (gnat_entity)
		  && present_gnu_tree (Original_Array_Type (gnat_entity)))
		add_parallel_type (gnu_type,
				   gnat_to_gnu_type
				   (Original_Array_Type (gnat_entity)));
	      else
		{
		  tree gnu_base_decl
		    = gnat_to_gnu_entity (Etype (gnat_entity), NULL_TREE, 0);
		  if (!DECL_ARTIFICIAL (gnu_base_decl))
		    add_parallel_type (gnu_type,
				       TREE_TYPE (TREE_TYPE (gnu_base_decl)));
		}
	    }

	  TYPE_CONVENTION_FORTRAN_P (gnu_type) = convention_fortran_p;
	  TYPE_PACKED_ARRAY_TYPE_P (gnu_type)
	    = (Is_Packed_Array_Type (gnat_entity)
	       && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)));

	  /* If the size is self-referential and the maximum size doesn't
	     overflow, use it.  */
	  if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type))
	      && gnu_max_size
	      && !(TREE_CODE (gnu_max_size) == INTEGER_CST
		   && TREE_OVERFLOW (gnu_max_size))
	      && !(TREE_CODE (gnu_max_size_unit) == INTEGER_CST
		   && TREE_OVERFLOW (gnu_max_size_unit)))
	    {
	      TYPE_SIZE (gnu_type) = size_binop (MIN_EXPR, gnu_max_size,
						 TYPE_SIZE (gnu_type));
	      TYPE_SIZE_UNIT (gnu_type)
		= size_binop (MIN_EXPR, gnu_max_size_unit,
			      TYPE_SIZE_UNIT (gnu_type));
	    }

	  /* Set our alias set to that of our base type.  This gives all
	     array subtypes the same alias set.  */
	  relate_alias_sets (gnu_type, gnu_base_type, ALIAS_SET_COPY);

	  /* If this is a packed type, make this type the same as the packed
	     array type, but do some adjusting in the type first.  */
	  if (Present (Packed_Array_Type (gnat_entity)))
	    {
	      Entity_Id gnat_index;
	      tree gnu_inner;

	      /* First finish the type we had been making so that we output
		 debugging information for it.  */
	      if (Treat_As_Volatile (gnat_entity))
		gnu_type
		  = build_qualified_type (gnu_type,
					  TYPE_QUALS (gnu_type)
					  | TYPE_QUAL_VOLATILE);

	      /* Make it artificial only if the base type was artificial too.
		 That's sort of "morally" true and will make it possible for
		 the debugger to look it up by name in DWARF, which is needed
		 in order to decode the packed array type.  */
	      gnu_decl
		= create_type_decl (gnu_entity_name, gnu_type, attr_list,
				    !Comes_From_Source (Etype (gnat_entity))
				    && !Comes_From_Source (gnat_entity),
				    debug_info_p, gnat_entity);

	      /* Save it as our equivalent in case the call below elaborates
		 this type again.  */
	      save_gnu_tree (gnat_entity, gnu_decl, false);

	      gnu_decl = gnat_to_gnu_entity (Packed_Array_Type (gnat_entity),
					     NULL_TREE, 0);
	      this_made_decl = true;
	      gnu_type = TREE_TYPE (gnu_decl);
	      save_gnu_tree (gnat_entity, NULL_TREE, false);

	      gnu_inner = gnu_type;
	      while (TREE_CODE (gnu_inner) == RECORD_TYPE
		     && (TYPE_JUSTIFIED_MODULAR_P (gnu_inner)
			 || TYPE_PADDING_P (gnu_inner)))
		gnu_inner = TREE_TYPE (TYPE_FIELDS (gnu_inner));

	      /* We need to attach the index type to the type we just made so
		 that the actual bounds can later be put into a template.  */
	      if ((TREE_CODE (gnu_inner) == ARRAY_TYPE
		   && !TYPE_ACTUAL_BOUNDS (gnu_inner))
		  || (TREE_CODE (gnu_inner) == INTEGER_TYPE
		      && !TYPE_HAS_ACTUAL_BOUNDS_P (gnu_inner)))
		{
		  if (TREE_CODE (gnu_inner) == INTEGER_TYPE)
		    {
		      /* The TYPE_ACTUAL_BOUNDS field is overloaded with the
			 TYPE_MODULUS for modular types so we make an extra
			 subtype if necessary.  */
		      if (TYPE_MODULAR_P (gnu_inner))
			{
			  tree gnu_subtype
			    = make_unsigned_type (TYPE_PRECISION (gnu_inner));
			  TREE_TYPE (gnu_subtype) = gnu_inner;
			  TYPE_EXTRA_SUBTYPE_P (gnu_subtype) = 1;
			  SET_TYPE_RM_MIN_VALUE (gnu_subtype,
						 TYPE_MIN_VALUE (gnu_inner));
			  SET_TYPE_RM_MAX_VALUE (gnu_subtype,
						 TYPE_MAX_VALUE (gnu_inner));
			  gnu_inner = gnu_subtype;
			}

		      TYPE_HAS_ACTUAL_BOUNDS_P (gnu_inner) = 1;

#ifdef ENABLE_CHECKING
		      /* Check for other cases of overloading.  */
		      gcc_assert (!TYPE_ACTUAL_BOUNDS (gnu_inner));
#endif
		    }

		  for (gnat_index = First_Index (gnat_entity);
		       Present (gnat_index);
		       gnat_index = Next_Index (gnat_index))
		    SET_TYPE_ACTUAL_BOUNDS
		      (gnu_inner,
		       tree_cons (NULL_TREE,
				  get_unpadded_type (Etype (gnat_index)),
				  TYPE_ACTUAL_BOUNDS (gnu_inner)));

		  if (Convention (gnat_entity) != Convention_Fortran)
		    SET_TYPE_ACTUAL_BOUNDS
		      (gnu_inner, nreverse (TYPE_ACTUAL_BOUNDS (gnu_inner)));

		  if (TREE_CODE (gnu_type) == RECORD_TYPE
		      && TYPE_JUSTIFIED_MODULAR_P (gnu_type))
		    TREE_TYPE (TYPE_FIELDS (gnu_type)) = gnu_inner;
		}
	    }

	  else
	    /* Abort if packed array with no Packed_Array_Type field set.  */
	    gcc_assert (!Is_Packed (gnat_entity));
	}
      break;

    case E_String_Literal_Subtype:
      /* Create the type for a string literal.  */
      {
	Entity_Id gnat_full_type
	  = (IN (Ekind (Etype (gnat_entity)), Private_Kind)
	     && Present (Full_View (Etype (gnat_entity)))
	     ? Full_View (Etype (gnat_entity)) : Etype (gnat_entity));
	tree gnu_string_type = get_unpadded_type (gnat_full_type);
	tree gnu_string_array_type
	  = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_string_type))));
	tree gnu_string_index_type
	  = get_base_type (TREE_TYPE (TYPE_INDEX_TYPE
				      (TYPE_DOMAIN (gnu_string_array_type))));
	tree gnu_lower_bound
	  = convert (gnu_string_index_type,
		     gnat_to_gnu (String_Literal_Low_Bound (gnat_entity)));
	tree gnu_length
	  = UI_To_gnu (String_Literal_Length (gnat_entity),
		       gnu_string_index_type);
	tree gnu_upper_bound
	  = build_binary_op (PLUS_EXPR, gnu_string_index_type,
			     gnu_lower_bound,
			     int_const_binop (MINUS_EXPR, gnu_length,
					      integer_one_node));
	tree gnu_index_type
	  = create_index_type (convert (sizetype, gnu_lower_bound),
			       convert (sizetype, gnu_upper_bound),
			       create_range_type (gnu_string_index_type,
						  gnu_lower_bound,
						  gnu_upper_bound),
			       gnat_entity);

	gnu_type
	  = build_nonshared_array_type (gnat_to_gnu_type
					(Component_Type (gnat_entity)),
					gnu_index_type);
	if (array_type_has_nonaliased_component (gnu_type, gnat_entity))
	  TYPE_NONALIASED_COMPONENT (gnu_type) = 1;
	relate_alias_sets (gnu_type, gnu_string_type, ALIAS_SET_COPY);
      }
      break;

    /* Record Types and Subtypes

       The following fields are defined on record types:

		Has_Discriminants	True if the record has discriminants
		First_Discriminant      Points to head of list of discriminants
		First_Entity		Points to head of list of fields
		Is_Tagged_Type		True if the record is tagged

       Implementation of Ada records and discriminated records:

       A record type definition is transformed into the equivalent of a C
       struct definition.  The fields that are the discriminants which are
       found in the Full_Type_Declaration node and the elements of the
       Component_List found in the Record_Type_Definition node.  The
       Component_List can be a recursive structure since each Variant of
       the Variant_Part of the Component_List has a Component_List.

       Processing of a record type definition comprises starting the list of
       field declarations here from the discriminants and the calling the
       function components_to_record to add the rest of the fields from the
       component list and return the gnu type node.  The function
       components_to_record will call itself recursively as it traverses
       the tree.  */

    case E_Record_Type:
      if (Has_Complex_Representation (gnat_entity))
	{
	  gnu_type
	    = build_complex_type
	      (get_unpadded_type
	       (Etype (Defining_Entity
		       (First (Component_Items
			       (Component_List
				(Type_Definition
				 (Declaration_Node (gnat_entity)))))))));

	  break;
	}

      {
	Node_Id full_definition = Declaration_Node (gnat_entity);
	Node_Id record_definition = Type_Definition (full_definition);
	Entity_Id gnat_field;
	tree gnu_field, gnu_field_list = NULL_TREE, gnu_get_parent;
	/* Set PACKED in keeping with gnat_to_gnu_field.  */
	int packed
	  = Is_Packed (gnat_entity)
	    ? 1
	    : Component_Alignment (gnat_entity) == Calign_Storage_Unit
	      ? -1
	      : (Known_Alignment (gnat_entity)
		 || (Strict_Alignment (gnat_entity)
		     && Known_RM_Size (gnat_entity)))
		? -2
		: 0;
	bool has_discr = Has_Discriminants (gnat_entity);
	bool has_rep = Has_Specified_Layout (gnat_entity);
	bool all_rep = has_rep;
	bool is_extension
	  = (Is_Tagged_Type (gnat_entity)
	     && Nkind (record_definition) == N_Derived_Type_Definition);
	bool is_unchecked_union = Is_Unchecked_Union (gnat_entity);

	/* See if all fields have a rep clause.  Stop when we find one
	   that doesn't.  */
	if (all_rep)
	  for (gnat_field = First_Entity (gnat_entity);
	       Present (gnat_field);
	       gnat_field = Next_Entity (gnat_field))
	    if ((Ekind (gnat_field) == E_Component
		 || Ekind (gnat_field) == E_Discriminant)
		&& No (Component_Clause (gnat_field)))
	      {
		all_rep = false;
		break;
	      }

	/* If this is a record extension, go a level further to find the
	   record definition.  Also, verify we have a Parent_Subtype.  */
	if (is_extension)
	  {
	    if (!type_annotate_only
		|| Present (Record_Extension_Part (record_definition)))
	      record_definition = Record_Extension_Part (record_definition);

	    gcc_assert (type_annotate_only
			|| Present (Parent_Subtype (gnat_entity)));
	  }

	/* Make a node for the record.  If we are not defining the record,
	   suppress expanding incomplete types.  */
	gnu_type = make_node (tree_code_for_record_type (gnat_entity));
	TYPE_NAME (gnu_type) = gnu_entity_name;
	TYPE_PACKED (gnu_type) = (packed != 0) || has_rep;
	if (Reverse_Storage_Order (gnat_entity))
	  sorry ("non-default Scalar_Storage_Order");

	if (!definition)
	  {
	    defer_incomplete_level++;
	    this_deferred = true;
	  }

	/* If both a size and rep clause was specified, put the size in
	   the record type now so that it can get the proper mode.  */
	if (has_rep && Known_RM_Size (gnat_entity))
	  TYPE_SIZE (gnu_type)
	    = UI_To_gnu (RM_Size (gnat_entity), bitsizetype);

	/* Always set the alignment here so that it can be used to
	   set the mode, if it is making the alignment stricter.  If
	   it is invalid, it will be checked again below.  If this is to
	   be Atomic, choose a default alignment of a word unless we know
	   the size and it's smaller.  */
	if (Known_Alignment (gnat_entity))
	  TYPE_ALIGN (gnu_type)
	    = validate_alignment (Alignment (gnat_entity), gnat_entity, 0);
	else if (Is_Atomic (gnat_entity) && Known_Esize (gnat_entity))
	  {
	    unsigned int size = UI_To_Int (Esize (gnat_entity));
	    TYPE_ALIGN (gnu_type)
	      = size >= BITS_PER_WORD ? BITS_PER_WORD : ceil_pow2 (size);
	  }
	/* If a type needs strict alignment, the minimum size will be the
	   type size instead of the RM size (see validate_size).  Cap the
	   alignment, lest it causes this type size to become too large.  */
	else if (Strict_Alignment (gnat_entity) && Known_RM_Size (gnat_entity))
	  {
	    unsigned int raw_size = UI_To_Int (RM_Size (gnat_entity));
	    unsigned int raw_align = raw_size & -raw_size;
	    if (raw_align < BIGGEST_ALIGNMENT)
	      TYPE_ALIGN (gnu_type) = raw_align;
	  }
	else
	  TYPE_ALIGN (gnu_type) = 0;

	/* If we have a Parent_Subtype, make a field for the parent.  If
	   this record has rep clauses, force the position to zero.  */
	if (Present (Parent_Subtype (gnat_entity)))
	  {
	    Entity_Id gnat_parent = Parent_Subtype (gnat_entity);
	    tree gnu_dummy_parent_type = make_node (RECORD_TYPE);
	    tree gnu_parent;

	    /* A major complexity here is that the parent subtype will
	       reference our discriminants in its Stored_Constraint list.
	       But those must reference the parent component of this record
	       which is precisely of the parent subtype we have not built yet!
	       To break the circle we first build a dummy COMPONENT_REF which
	       represents the "get to the parent" operation and initialize
	       each of those discriminants to a COMPONENT_REF of the above
	       dummy parent referencing the corresponding discriminant of the
	       base type of the parent subtype.  */
	    gnu_get_parent = build3 (COMPONENT_REF, gnu_dummy_parent_type,
				     build0 (PLACEHOLDER_EXPR, gnu_type),
				     build_decl (input_location,
						 FIELD_DECL, NULL_TREE,
						 gnu_dummy_parent_type),
				     NULL_TREE);

	    if (has_discr)
	      for (gnat_field = First_Stored_Discriminant (gnat_entity);
		   Present (gnat_field);
		   gnat_field = Next_Stored_Discriminant (gnat_field))
		if (Present (Corresponding_Discriminant (gnat_field)))
		  {
		    tree gnu_field
		      = gnat_to_gnu_field_decl (Corresponding_Discriminant
						(gnat_field));
		    save_gnu_tree
		      (gnat_field,
		       build3 (COMPONENT_REF, TREE_TYPE (gnu_field),
			       gnu_get_parent, gnu_field, NULL_TREE),
		       true);
		  }

	    /* Then we build the parent subtype.  If it has discriminants but
	       the type itself has unknown discriminants, this means that it
	       doesn't contain information about how the discriminants are
	       derived from those of the ancestor type, so it cannot be used
	       directly.  Instead it is built by cloning the parent subtype
	       of the underlying record view of the type, for which the above
	       derivation of discriminants has been made explicit.  */
	    if (Has_Discriminants (gnat_parent)
		&& Has_Unknown_Discriminants (gnat_entity))
	      {
		Entity_Id gnat_uview = Underlying_Record_View (gnat_entity);

		/* If we are defining the type, the underlying record
		   view must already have been elaborated at this point.
		   Otherwise do it now as its parent subtype cannot be
		   technically elaborated on its own.  */
		if (definition)
		  gcc_assert (present_gnu_tree (gnat_uview));
		else
		  gnat_to_gnu_entity (gnat_uview, NULL_TREE, 0);

		gnu_parent = gnat_to_gnu_type (Parent_Subtype (gnat_uview));

		/* Substitute the "get to the parent" of the type for that
		   of its underlying record view in the cloned type.  */
		for (gnat_field = First_Stored_Discriminant (gnat_uview);
		     Present (gnat_field);
		     gnat_field = Next_Stored_Discriminant (gnat_field))
		  if (Present (Corresponding_Discriminant (gnat_field)))
		    {
		      tree gnu_field = gnat_to_gnu_field_decl (gnat_field);
		      tree gnu_ref
			= build3 (COMPONENT_REF, TREE_TYPE (gnu_field),
				  gnu_get_parent, gnu_field, NULL_TREE);
		      gnu_parent
			= substitute_in_type (gnu_parent, gnu_field, gnu_ref);
		    }
	      }
	    else
	      gnu_parent = gnat_to_gnu_type (gnat_parent);

	    /* Finally we fix up both kinds of twisted COMPONENT_REF we have
	       initially built.  The discriminants must reference the fields
	       of the parent subtype and not those of its base type for the
	       placeholder machinery to properly work.  */
	    if (has_discr)
	      {
		/* The actual parent subtype is the full view.  */
		if (IN (Ekind (gnat_parent), Private_Kind))
		  {
		    if (Present (Full_View (gnat_parent)))
		      gnat_parent = Full_View (gnat_parent);
		    else
		      gnat_parent = Underlying_Full_View (gnat_parent);
		  }

		for (gnat_field = First_Stored_Discriminant (gnat_entity);
		     Present (gnat_field);
		     gnat_field = Next_Stored_Discriminant (gnat_field))
		  if (Present (Corresponding_Discriminant (gnat_field)))
		    {
		      Entity_Id field = Empty;
		      for (field = First_Stored_Discriminant (gnat_parent);
			   Present (field);
			   field = Next_Stored_Discriminant (field))
			if (same_discriminant_p (gnat_field, field))
			  break;
		      gcc_assert (Present (field));
		      TREE_OPERAND (get_gnu_tree (gnat_field), 1)
			= gnat_to_gnu_field_decl (field);
		    }
	      }

	    /* The "get to the parent" COMPONENT_REF must be given its
	       proper type...  */
	    TREE_TYPE (gnu_get_parent) = gnu_parent;

	    /* ...and reference the _Parent field of this record.  */
	    gnu_field
	      = create_field_decl (parent_name_id,
				   gnu_parent, gnu_type,
				   has_rep
				   ? TYPE_SIZE (gnu_parent) : NULL_TREE,
				   has_rep
				   ? bitsize_zero_node : NULL_TREE,
				   0, 1);
	    DECL_INTERNAL_P (gnu_field) = 1;
	    TREE_OPERAND (gnu_get_parent, 1) = gnu_field;
	    TYPE_FIELDS (gnu_type) = gnu_field;
	  }

	/* Make the fields for the discriminants and put them into the record
	   unless it's an Unchecked_Union.  */
	if (has_discr)
	  for (gnat_field = First_Stored_Discriminant (gnat_entity);
	       Present (gnat_field);
	       gnat_field = Next_Stored_Discriminant (gnat_field))
	    {
	      /* If this is a record extension and this discriminant is the
		 renaming of another discriminant, we've handled it above.  */
	      if (Present (Parent_Subtype (gnat_entity))
		  && Present (Corresponding_Discriminant (gnat_field)))
		continue;

	      gnu_field
		= gnat_to_gnu_field (gnat_field, gnu_type, packed, definition,
				     debug_info_p);

	      /* Make an expression using a PLACEHOLDER_EXPR from the
		 FIELD_DECL node just created and link that with the
		 corresponding GNAT defining identifier.  */
	      save_gnu_tree (gnat_field,
			     build3 (COMPONENT_REF, TREE_TYPE (gnu_field),
				     build0 (PLACEHOLDER_EXPR, gnu_type),
				     gnu_field, NULL_TREE),
			     true);

	      if (!is_unchecked_union)
		{
		  DECL_CHAIN (gnu_field) = gnu_field_list;
		  gnu_field_list = gnu_field;
		}
	    }

	/* Add the fields into the record type and finish it up.  */
	components_to_record (gnu_type, Component_List (record_definition),
			      gnu_field_list, packed, definition, false,
			      all_rep, is_unchecked_union,
			      !Comes_From_Source (gnat_entity), debug_info_p,
			      false, OK_To_Reorder_Components (gnat_entity),
			      all_rep ? NULL_TREE : bitsize_zero_node, NULL);

	/* If it is passed by reference, force BLKmode to ensure that objects
	   of this type will always be put in memory.  */
	if (TYPE_MODE (gnu_type) != BLKmode
	    && Is_By_Reference_Type (gnat_entity))
	  SET_TYPE_MODE (gnu_type, BLKmode);

	/* We used to remove the associations of the discriminants and _Parent
	   for validity checking but we may need them if there's a Freeze_Node
	   for a subtype used in this record.  */
	TYPE_VOLATILE (gnu_type) = Treat_As_Volatile (gnat_entity);

	/* Fill in locations of fields.  */
	annotate_rep (gnat_entity, gnu_type);

	/* If there are any entities in the chain corresponding to components
	   that we did not elaborate, ensure we elaborate their types if they
	   are Itypes.  */
	for (gnat_temp = First_Entity (gnat_entity);
	     Present (gnat_temp);
	     gnat_temp = Next_Entity (gnat_temp))
	  if ((Ekind (gnat_temp) == E_Component
	       || Ekind (gnat_temp) == E_Discriminant)
	      && Is_Itype (Etype (gnat_temp))
	      && !present_gnu_tree (gnat_temp))
	    gnat_to_gnu_entity (Etype (gnat_temp), NULL_TREE, 0);

	/* If this is a record type associated with an exception definition,
	   equate its fields to those of the standard exception type.  This
	   will make it possible to convert between them.  */
	if (gnu_entity_name == exception_data_name_id)
	  {
	    tree gnu_std_field;
	    for (gnu_field = TYPE_FIELDS (gnu_type),
		 gnu_std_field = TYPE_FIELDS (except_type_node);
		 gnu_field;
		 gnu_field = DECL_CHAIN (gnu_field),
		 gnu_std_field = DECL_CHAIN (gnu_std_field))
	      SET_DECL_ORIGINAL_FIELD_TO_FIELD (gnu_field, gnu_std_field);
	    gcc_assert (!gnu_std_field);
	  }
      }
      break;

    case E_Class_Wide_Subtype:
      /* If an equivalent type is present, that is what we should use.
	 Otherwise, fall through to handle this like a record subtype
	 since it may have constraints.  */
      if (gnat_equiv_type != gnat_entity)
	{
	  gnu_decl = gnat_to_gnu_entity (gnat_equiv_type, NULL_TREE, 0);
	  maybe_present = true;
	  break;
	}

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

    case E_Record_Subtype:
      /* If Cloned_Subtype is Present it means this record subtype has
	 identical layout to that type or subtype and we should use
	 that GCC type for this one.  The front end guarantees that
	 the component list is shared.  */
      if (Present (Cloned_Subtype (gnat_entity)))
	{
	  gnu_decl = gnat_to_gnu_entity (Cloned_Subtype (gnat_entity),
					 NULL_TREE, 0);
	  maybe_present = true;
	  break;
	}

      /* Otherwise, first ensure the base type is elaborated.  Then, if we are
	 changing the type, make a new type with each field having the type of
	 the field in the new subtype but the position computed by transforming
	 every discriminant reference according to the constraints.  We don't
	 see any difference between private and non-private type here since
	 derivations from types should have been deferred until the completion
	 of the private type.  */
      else
	{
	  Entity_Id gnat_base_type = Implementation_Base_Type (gnat_entity);
	  tree gnu_base_type;

	  if (!definition)
	    {
	      defer_incomplete_level++;
	      this_deferred = true;
	    }

	  gnu_base_type = gnat_to_gnu_type (gnat_base_type);

	  if (present_gnu_tree (gnat_entity))
	    {
	      maybe_present = true;
	      break;
	    }

	  /* If this is a record subtype associated with a dispatch table,
	     strip the suffix.  This is necessary to make sure 2 different
	     subtypes associated with the imported and exported views of a
	     dispatch table are properly merged in LTO mode.  */
	  if (Is_Dispatch_Table_Entity (gnat_entity))
	    {
	      char *p;
	      Get_Encoded_Name (gnat_entity);
	      p = strchr (Name_Buffer, '_');
	      gcc_assert (p);
	      strcpy (p+2, "dtS");
	      gnu_entity_name = get_identifier (Name_Buffer);
	    }

	  /* When the subtype has discriminants and these discriminants affect
	     the initial shape it has inherited, factor them in.  But for an
	     Unchecked_Union (it must be an Itype), just return the type.
	     We can't just test Is_Constrained because private subtypes without
	     discriminants of types with discriminants with default expressions
	     are Is_Constrained but aren't constrained!  */
	  if (IN (Ekind (gnat_base_type), Record_Kind)
	      && !Is_Unchecked_Union (gnat_base_type)
	      && !Is_For_Access_Subtype (gnat_entity)
	      && Has_Discriminants (gnat_entity)
	      && Is_Constrained (gnat_entity)
	      && Stored_Constraint (gnat_entity) != No_Elist)
	    {
	      vec<subst_pair> gnu_subst_list
		= build_subst_list (gnat_entity, gnat_base_type, definition);
	      tree gnu_unpad_base_type, gnu_rep_part, gnu_variant_part, t;
	      tree gnu_pos_list, gnu_field_list = NULL_TREE;
	      bool selected_variant = false;
	      Entity_Id gnat_field;
	      vec<variant_desc> gnu_variant_list;

	      gnu_type = make_node (RECORD_TYPE);
	      TYPE_NAME (gnu_type) = gnu_entity_name;
	      TYPE_PACKED (gnu_type) = TYPE_PACKED (gnu_base_type);

	      /* Set the size, alignment and alias set of the new type to
		 match that of the old one, doing required substitutions.  */
	      copy_and_substitute_in_size (gnu_type, gnu_base_type,
					   gnu_subst_list);

	      if (TYPE_IS_PADDING_P (gnu_base_type))
		gnu_unpad_base_type = TREE_TYPE (TYPE_FIELDS (gnu_base_type));
	      else
		gnu_unpad_base_type = gnu_base_type;

	      /* Look for a variant part in the base type.  */
	      gnu_variant_part = get_variant_part (gnu_unpad_base_type);

	      /* If there is a variant part, we must compute whether the
		 constraints statically select a particular variant.  If
		 so, we simply drop the qualified union and flatten the
		 list of fields.  Otherwise we'll build a new qualified
		 union for the variants that are still relevant.  */
	      if (gnu_variant_part)
		{
		  variant_desc *v;
		  unsigned int i;

		  gnu_variant_list
		    = build_variant_list (TREE_TYPE (gnu_variant_part),
					  gnu_subst_list,
					  vNULL);

		  /* If all the qualifiers are unconditionally true, the
		     innermost variant is statically selected.  */
		  selected_variant = true;
		  FOR_EACH_VEC_ELT (gnu_variant_list, i, v)
		    if (!integer_onep (v->qual))
		      {
			selected_variant = false;
			break;
		      }

		  /* Otherwise, create the new variants.  */
		  if (!selected_variant)
		    FOR_EACH_VEC_ELT (gnu_variant_list, i, v)
		      {
			tree old_variant = v->type;
			tree new_variant = make_node (RECORD_TYPE);
			tree suffix
			  = concat_name (DECL_NAME (gnu_variant_part),
					 IDENTIFIER_POINTER
					 (DECL_NAME (v->field)));
			TYPE_NAME (new_variant)
			  = concat_name (TYPE_NAME (gnu_type),
					 IDENTIFIER_POINTER (suffix));
			copy_and_substitute_in_size (new_variant, old_variant,
						     gnu_subst_list);
			v->new_type = new_variant;
		      }
		}
	      else
		{
		  gnu_variant_list.create (0);
		  selected_variant = false;
		}

	      gnu_pos_list
		= build_position_list (gnu_unpad_base_type,
				       gnu_variant_list.exists ()
					  && !selected_variant,
				       size_zero_node, bitsize_zero_node,
				       BIGGEST_ALIGNMENT, NULL_TREE);

	      for (gnat_field = First_Entity (gnat_entity);
		   Present (gnat_field);
		   gnat_field = Next_Entity (gnat_field))
		if ((Ekind (gnat_field) == E_Component
		     || Ekind (gnat_field) == E_Discriminant)
		    && !(Present (Corresponding_Discriminant (gnat_field))
			 && Is_Tagged_Type (gnat_base_type))
		    && Underlying_Type (Scope (Original_Record_Component
					       (gnat_field)))
		       == gnat_base_type)
		  {
		    Name_Id gnat_name = Chars (gnat_field);
		    Entity_Id gnat_old_field
		      = Original_Record_Component (gnat_field);
		    tree gnu_old_field
		      = gnat_to_gnu_field_decl (gnat_old_field);
		    tree gnu_context = DECL_CONTEXT (gnu_old_field);
		    tree gnu_field, gnu_field_type, gnu_size;
		    tree gnu_cont_type, gnu_last = NULL_TREE;

		    /* If the type is the same, retrieve the GCC type from the
		       old field to take into account possible adjustments.  */
		    if (Etype (gnat_field) == Etype (gnat_old_field))
		      gnu_field_type = TREE_TYPE (gnu_old_field);
		    else
		      gnu_field_type = gnat_to_gnu_type (Etype (gnat_field));

		    /* If there was a component clause, the field types must be
		       the same for the type and subtype, so copy the data from
		       the old field to avoid recomputation here.  Also if the
		       field is justified modular and the optimization in
		       gnat_to_gnu_field was applied.  */
		    if (Present (Component_Clause (gnat_old_field))
			|| (TREE_CODE (gnu_field_type) == RECORD_TYPE
			    && TYPE_JUSTIFIED_MODULAR_P (gnu_field_type)
			    && TREE_TYPE (TYPE_FIELDS (gnu_field_type))
			       == TREE_TYPE (gnu_old_field)))
		      {
			gnu_size = DECL_SIZE (gnu_old_field);
			gnu_field_type = TREE_TYPE (gnu_old_field);
		      }

		    /* If the old field was packed and of constant size, we
		       have to get the old size here, as it might differ from
		       what the Etype conveys and the latter might overlap
		       onto the following field.  Try to arrange the type for
		       possible better packing along the way.  */
		    else if (DECL_PACKED (gnu_old_field)
			     && TREE_CODE (DECL_SIZE (gnu_old_field))
			        == INTEGER_CST)
		      {
			gnu_size = DECL_SIZE (gnu_old_field);
			if (RECORD_OR_UNION_TYPE_P (gnu_field_type)
			    && !TYPE_FAT_POINTER_P (gnu_field_type)
			    && host_integerp (TYPE_SIZE (gnu_field_type), 1))
			  gnu_field_type
			    = make_packable_type (gnu_field_type, true);
		      }

		    else
		      gnu_size = TYPE_SIZE (gnu_field_type);

		    /* If the context of the old field is the base type or its
		       REP part (if any), put the field directly in the new
		       type; otherwise look up the context in the variant list
		       and put the field either in the new type if there is a
		       selected variant or in one of the new variants.  */
		    if (gnu_context == gnu_unpad_base_type
		        || ((gnu_rep_part = get_rep_part (gnu_unpad_base_type))
			    && gnu_context == TREE_TYPE (gnu_rep_part)))
		      gnu_cont_type = gnu_type;
		    else
		      {
			variant_desc *v;
			unsigned int i;

			t = NULL_TREE;
			FOR_EACH_VEC_ELT (gnu_variant_list, i, v)
			  if (gnu_context == v->type
			      || ((gnu_rep_part = get_rep_part (v->type))
				  && gnu_context == TREE_TYPE (gnu_rep_part)))
			    {
			      t = v->type;
			      break;
			    }
			if (t)
			  {
			    if (selected_variant)
			      gnu_cont_type = gnu_type;
			    else
			      gnu_cont_type = v->new_type;
			  }
			else
			  /* The front-end may pass us "ghost" components if
			     it fails to recognize that a constrained subtype
			     is statically constrained.  Discard them.  */
			  continue;
		      }

		    /* Now create the new field modeled on the old one.  */
		    gnu_field
		      = create_field_decl_from (gnu_old_field, gnu_field_type,
						gnu_cont_type, gnu_size,
						gnu_pos_list, gnu_subst_list);

		    /* Put it in one of the new variants directly.  */
		    if (gnu_cont_type != gnu_type)
		      {
			DECL_CHAIN (gnu_field) = TYPE_FIELDS (gnu_cont_type);
			TYPE_FIELDS (gnu_cont_type) = gnu_field;
		      }

		    /* To match the layout crafted in components_to_record,
		       if this is the _Tag or _Parent field, put it before
		       any other fields.  */
		    else if (gnat_name == Name_uTag
			     || gnat_name == Name_uParent)
		      gnu_field_list = chainon (gnu_field_list, gnu_field);

		    /* Similarly, if this is the _Controller field, put
		       it before the other fields except for the _Tag or
		       _Parent field.  */
		    else if (gnat_name == Name_uController && gnu_last)
		      {
			DECL_CHAIN (gnu_field) = DECL_CHAIN (gnu_last);
			DECL_CHAIN (gnu_last) = gnu_field;
		      }

		    /* Otherwise, if this is a regular field, put it after
		       the other fields.  */
		    else
		      {
			DECL_CHAIN (gnu_field) = gnu_field_list;
			gnu_field_list = gnu_field;
			if (!gnu_last)
			  gnu_last = gnu_field;
		      }

		    save_gnu_tree (gnat_field, gnu_field, false);
		  }

	      /* If there is a variant list and no selected variant, we need
		 to create the nest of variant parts from the old nest.  */
	      if (gnu_variant_list.exists () && !selected_variant)
		{
		  tree new_variant_part
		    = create_variant_part_from (gnu_variant_part,
						gnu_variant_list, gnu_type,
						gnu_pos_list, gnu_subst_list);
		  DECL_CHAIN (new_variant_part) = gnu_field_list;
		  gnu_field_list = new_variant_part;
		}

	      /* Now go through the entities again looking for Itypes that
		 we have not elaborated but should (e.g., Etypes of fields
		 that have Original_Components).  */
	      for (gnat_field = First_Entity (gnat_entity);
		   Present (gnat_field); gnat_field = Next_Entity (gnat_field))
		if ((Ekind (gnat_field) == E_Discriminant
		     || Ekind (gnat_field) == E_Component)
		    && !present_gnu_tree (Etype (gnat_field)))
		  gnat_to_gnu_entity (Etype (gnat_field), NULL_TREE, 0);

	      /* Do not emit debug info for the type yet since we're going to
		 modify it below.  */
	      finish_record_type (gnu_type, nreverse (gnu_field_list), 2,
				  false);
	      compute_record_mode (gnu_type);

	      /* See the E_Record_Type case for the rationale.  */
	      if (TYPE_MODE (gnu_type) != BLKmode
		  && Is_By_Reference_Type (gnat_entity))
		SET_TYPE_MODE (gnu_type, BLKmode);

	      TYPE_VOLATILE (gnu_type) = Treat_As_Volatile (gnat_entity);

	      /* Fill in locations of fields.  */
	      annotate_rep (gnat_entity, gnu_type);

	      /* If debugging information is being written for the type, write
		 a record that shows what we are a subtype of and also make a
		 variable that indicates our size, if still variable.  */
	      if (debug_info_p)
		{
		  tree gnu_subtype_marker = make_node (RECORD_TYPE);
		  tree gnu_unpad_base_name = TYPE_NAME (gnu_unpad_base_type);
		  tree gnu_size_unit = TYPE_SIZE_UNIT (gnu_type);

		  if (TREE_CODE (gnu_unpad_base_name) == TYPE_DECL)
		    gnu_unpad_base_name = DECL_NAME (gnu_unpad_base_name);

		  TYPE_NAME (gnu_subtype_marker)
		    = create_concat_name (gnat_entity, "XVS");
		  finish_record_type (gnu_subtype_marker,
				      create_field_decl (gnu_unpad_base_name,
							 build_reference_type
							 (gnu_unpad_base_type),
							 gnu_subtype_marker,
							 NULL_TREE, NULL_TREE,
							 0, 0),
				      0, true);

		  add_parallel_type (gnu_type, gnu_subtype_marker);

		  if (definition
		      && TREE_CODE (gnu_size_unit) != INTEGER_CST
		      && !CONTAINS_PLACEHOLDER_P (gnu_size_unit))
		    TYPE_SIZE_UNIT (gnu_subtype_marker)
		      = create_var_decl (create_concat_name (gnat_entity,
							     "XVZ"),
					 NULL_TREE, sizetype, gnu_size_unit,
					 false, false, false, false, NULL,
					 gnat_entity);
		}

	      gnu_variant_list.release ();
	      gnu_subst_list.release ();

	      /* Now we can finalize it.  */
	      rest_of_record_type_compilation (gnu_type);
	    }

	  /* Otherwise, go down all the components in the new type and make
	     them equivalent to those in the base type.  */
	  else
	    {
	      gnu_type = gnu_base_type;

	      for (gnat_temp = First_Entity (gnat_entity);
		   Present (gnat_temp);
		   gnat_temp = Next_Entity (gnat_temp))
		if ((Ekind (gnat_temp) == E_Discriminant
		     && !Is_Unchecked_Union (gnat_base_type))
		    || Ekind (gnat_temp) == E_Component)
		  save_gnu_tree (gnat_temp,
				 gnat_to_gnu_field_decl
				 (Original_Record_Component (gnat_temp)),
				 false);
	    }
	}
      break;

    case E_Access_Subprogram_Type:
      /* Use the special descriptor type for dispatch tables if needed,
	 that is to say for the Prim_Ptr of a-tags.ads and its clones.
	 Note that we are only required to do so for static tables in
	 order to be compatible with the C++ ABI, but Ada 2005 allows
	 to extend library level tagged types at the local level so
	 we do it in the non-static case as well.  */
      if (TARGET_VTABLE_USES_DESCRIPTORS
	  && Is_Dispatch_Table_Entity (gnat_entity))
	{
	    gnu_type = fdesc_type_node;
	    gnu_size = TYPE_SIZE (gnu_type);
	    break;
	}

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

    case E_Anonymous_Access_Subprogram_Type:
      /* If we are not defining this entity, and we have incomplete
	 entities being processed above us, make a dummy type and
	 fill it in later.  */
      if (!definition && defer_incomplete_level != 0)
	{
	  struct incomplete *p = XNEW (struct incomplete);

	  gnu_type
	    = build_pointer_type
	      (make_dummy_type (Directly_Designated_Type (gnat_entity)));
	  gnu_decl = create_type_decl (gnu_entity_name, gnu_type, attr_list,
				       !Comes_From_Source (gnat_entity),
				       debug_info_p, gnat_entity);
	  this_made_decl = true;
	  gnu_type = TREE_TYPE (gnu_decl);
	  save_gnu_tree (gnat_entity, gnu_decl, false);
	  saved = true;

	  p->old_type = TREE_TYPE (gnu_type);
	  p->full_type = Directly_Designated_Type (gnat_entity);
	  p->next = defer_incomplete_list;
	  defer_incomplete_list = p;
	  break;
	}

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

    case E_Allocator_Type:
    case E_Access_Type:
    case E_Access_Attribute_Type:
    case E_Anonymous_Access_Type:
    case E_General_Access_Type:
      {
	/* The designated type and its equivalent type for gigi.  */
	Entity_Id gnat_desig_type = Directly_Designated_Type (gnat_entity);
	Entity_Id gnat_desig_equiv = Gigi_Equivalent_Type (gnat_desig_type);
	/* Whether it comes from a limited with.  */
	bool is_from_limited_with
	  = (IN (Ekind (gnat_desig_equiv), Incomplete_Kind)
	     && From_With_Type (gnat_desig_equiv));
	/* The "full view" of the designated type.  If this is an incomplete
	   entity from a limited with, treat its non-limited view as the full
	   view.  Otherwise, if this is an incomplete or private type, use the
	   full view.  In the former case, we might point to a private type,
	   in which case, we need its full view.  Also, we want to look at the
	   actual type used for the representation, so this takes a total of
	   three steps.  */
	Entity_Id gnat_desig_full_direct_first
	  = (is_from_limited_with
	     ? Non_Limited_View (gnat_desig_equiv)
	     : (IN (Ekind (gnat_desig_equiv), Incomplete_Or_Private_Kind)
		? Full_View (gnat_desig_equiv) : Empty));
	Entity_Id gnat_desig_full_direct
	  = ((is_from_limited_with
	      && Present (gnat_desig_full_direct_first)
	      && IN (Ekind (gnat_desig_full_direct_first), Private_Kind))
	     ? Full_View (gnat_desig_full_direct_first)
	     : gnat_desig_full_direct_first);
	Entity_Id gnat_desig_full
	  = Gigi_Equivalent_Type (gnat_desig_full_direct);
	/* The type actually used to represent the designated type, either
	   gnat_desig_full or gnat_desig_equiv.  */
	Entity_Id gnat_desig_rep;
	/* True if this is a pointer to an unconstrained array.  */
	bool is_unconstrained_array;
	/* We want to know if we'll be seeing the freeze node for any
	   incomplete type we may be pointing to.  */
	bool in_main_unit
	  = (Present (gnat_desig_full)
	     ? In_Extended_Main_Code_Unit (gnat_desig_full)
	     : In_Extended_Main_Code_Unit (gnat_desig_type));
	/* True if we make a dummy type here.  */
	bool made_dummy = false;
	/* The mode to be used for the pointer type.  */
	enum machine_mode p_mode = mode_for_size (esize, MODE_INT, 0);
	/* The GCC type used for the designated type.  */
	tree gnu_desig_type = NULL_TREE;

	if (!targetm.valid_pointer_mode (p_mode))
	  p_mode = ptr_mode;

	/* If either the designated type or its full view is an unconstrained
	   array subtype, replace it with the type it's a subtype of.  This
	   avoids problems with multiple copies of unconstrained array types.
	   Likewise, if the designated type is a subtype of an incomplete
	   record type, use the parent type to avoid order of elaboration
	   issues.  This can lose some code efficiency, but there is no
	   alternative.  */
	if (Ekind (gnat_desig_equiv) == E_Array_Subtype
	    && !Is_Constrained (gnat_desig_equiv))
	  gnat_desig_equiv = Etype (gnat_desig_equiv);
	if (Present (gnat_desig_full)
	    && ((Ekind (gnat_desig_full) == E_Array_Subtype
		 && !Is_Constrained (gnat_desig_full))
		|| (Ekind (gnat_desig_full) == E_Record_Subtype
		    && Ekind (Etype (gnat_desig_full)) == E_Record_Type)))
	  gnat_desig_full = Etype (gnat_desig_full);

	/* Set the type that's actually the representation of the designated
	   type and also flag whether we have a unconstrained array.  */
	gnat_desig_rep
	  = Present (gnat_desig_full) ? gnat_desig_full : gnat_desig_equiv;
	is_unconstrained_array
	  = Is_Array_Type (gnat_desig_rep) && !Is_Constrained (gnat_desig_rep);

	/* If we are pointing to an incomplete type whose completion is an
	   unconstrained array, make dummy fat and thin pointer types to it.
	   Likewise if the type itself is dummy or an unconstrained array.  */
	if (is_unconstrained_array
	    && (Present (gnat_desig_full)
		|| (present_gnu_tree (gnat_desig_equiv)
		    && TYPE_IS_DUMMY_P
		       (TREE_TYPE (get_gnu_tree (gnat_desig_equiv))))
		|| (!in_main_unit
		    && defer_incomplete_level != 0
		    && !present_gnu_tree (gnat_desig_equiv))
		|| (in_main_unit
		    && is_from_limited_with
		    && Present (Freeze_Node (gnat_desig_equiv)))))
	  {
	    if (present_gnu_tree (gnat_desig_rep))
	      gnu_desig_type = TREE_TYPE (get_gnu_tree (gnat_desig_rep));
	    else
	      {
		gnu_desig_type = make_dummy_type (gnat_desig_rep);
		made_dummy = true;
	      }

	    /* If the call above got something that has a pointer, the pointer
	       is our type.  This could have happened either because the type
	       was elaborated or because somebody else executed the code.  */
	    if (!TYPE_POINTER_TO (gnu_desig_type))
	      build_dummy_unc_pointer_types (gnat_desig_equiv, gnu_desig_type);
	    gnu_type = TYPE_POINTER_TO (gnu_desig_type);
	  }

	/* If we already know what the full type is, use it.  */
	else if (Present (gnat_desig_full)
		 && present_gnu_tree (gnat_desig_full))
	  gnu_desig_type = TREE_TYPE (get_gnu_tree (gnat_desig_full));

	/* Get the type of the thing we are to point to and build a pointer to
	   it.  If it is a reference to an incomplete or private type with a
	   full view that is a record, make a dummy type node and get the
	   actual type later when we have verified it is safe.  */
	else if ((!in_main_unit
		  && !present_gnu_tree (gnat_desig_equiv)
		  && Present (gnat_desig_full)
		  && !present_gnu_tree (gnat_desig_full)
		  && Is_Record_Type (gnat_desig_full))
		 /* Likewise if we are pointing to a record or array and we are
		    to defer elaborating incomplete types.  We do this as this
		    access type may be the full view of a private type.  Note
		    that the unconstrained array case is handled above.  */
		 || ((!in_main_unit || imported_p)
		     && defer_incomplete_level != 0
		     && !present_gnu_tree (gnat_desig_equiv)
		     && (Is_Record_Type (gnat_desig_rep)
			 || Is_Array_Type (gnat_desig_rep)))
		 /* If this is a reference from a limited_with type back to our
		    main unit and there's a freeze node for it, either we have
		    already processed the declaration and made the dummy type,
		    in which case we just reuse the latter, or we have not yet,
		    in which case we make the dummy type and it will be reused
		    when the declaration is finally processed.  In both cases,
		    the pointer eventually created below will be automatically
		    adjusted when the freeze node is processed.  Note that the
		    unconstrained array case is handled above.  */
		 ||  (in_main_unit
		      && is_from_limited_with
		      && Present (Freeze_Node (gnat_desig_rep))))
	  {
	    gnu_desig_type = make_dummy_type (gnat_desig_equiv);
	    made_dummy = true;
	  }

	/* Otherwise handle the case of a pointer to itself.  */
	else if (gnat_desig_equiv == gnat_entity)
	  {
	    gnu_type
	      = build_pointer_type_for_mode (void_type_node, p_mode,
					     No_Strict_Aliasing (gnat_entity));
	    TREE_TYPE (gnu_type) = TYPE_POINTER_TO (gnu_type) = gnu_type;
	  }

	/* If expansion is disabled, the equivalent type of a concurrent type
	   is absent, so build a dummy pointer type.  */
	else if (type_annotate_only && No (gnat_desig_equiv))
	  gnu_type = ptr_void_type_node;

	/* Finally, handle the default case where we can just elaborate our
	   designated type.  */
	else
	  gnu_desig_type = gnat_to_gnu_type (gnat_desig_equiv);

	/* It is possible that a call to gnat_to_gnu_type above resolved our
	   type.  If so, just return it.  */
	if (present_gnu_tree (gnat_entity))
	  {
	    maybe_present = true;
	    break;
	  }

	/* If we haven't done it yet, build the pointer type the usual way.  */
	if (!gnu_type)
	  {
	    /* Modify the designated type if we are pointing only to constant
	       objects, but don't do it for unconstrained arrays.  */
	    if (Is_Access_Constant (gnat_entity)
		&& TREE_CODE (gnu_desig_type) != UNCONSTRAINED_ARRAY_TYPE)
	      {
		gnu_desig_type
		  = build_qualified_type
		    (gnu_desig_type,
		     TYPE_QUALS (gnu_desig_type) | TYPE_QUAL_CONST);

		/* Some extra processing is required if we are building a
		   pointer to an incomplete type (in the GCC sense).  We might
		   have such a type if we just made a dummy, or directly out
		   of the call to gnat_to_gnu_type above if we are processing
		   an access type for a record component designating the
		   record type itself.  */
		if (TYPE_MODE (gnu_desig_type) == VOIDmode)
		  {
		    /* We must ensure that the pointer to variant we make will
		       be processed by update_pointer_to when the initial type
		       is completed.  Pretend we made a dummy and let further
		       processing act as usual.  */
		    made_dummy = true;

		    /* We must ensure that update_pointer_to will not retrieve
		       the dummy variant when building a properly qualified
		       version of the complete type.  We take advantage of the
		       fact that get_qualified_type is requiring TYPE_NAMEs to
		       match to influence build_qualified_type and then also
		       update_pointer_to here.  */
		    TYPE_NAME (gnu_desig_type)
		      = create_concat_name (gnat_desig_type, "INCOMPLETE_CST");
		  }
	      }

	    gnu_type
	      = build_pointer_type_for_mode (gnu_desig_type, p_mode,
					     No_Strict_Aliasing (gnat_entity));
	  }

	/* If we are not defining this object and we have made a dummy pointer,
	   save our current definition, evaluate the actual type, and replace
	   the tentative type we made with the actual one.  If we are to defer
	   actually looking up the actual type, make an entry in the deferred
	   list.  If this is from a limited with, we may have to defer to the
	   end of the current unit.  */
	if ((!in_main_unit || is_from_limited_with) && made_dummy)
	  {
	    tree gnu_old_desig_type;

	    if (TYPE_IS_FAT_POINTER_P (gnu_type))
	      {
		gnu_old_desig_type = TYPE_UNCONSTRAINED_ARRAY (gnu_type);
		if (esize == POINTER_SIZE)
		  gnu_type = build_pointer_type
			     (TYPE_OBJECT_RECORD_TYPE (gnu_old_desig_type));
	      }
	    else
	      gnu_old_desig_type = TREE_TYPE (gnu_type);

	    gnu_decl = create_type_decl (gnu_entity_name, gnu_type, attr_list,
					 !Comes_From_Source (gnat_entity),
					 debug_info_p, gnat_entity);
	    this_made_decl = true;
	    gnu_type = TREE_TYPE (gnu_decl);
	    save_gnu_tree (gnat_entity, gnu_decl, false);
	    saved = true;

	    /* Note that the call to gnat_to_gnu_type on gnat_desig_equiv might
	       update gnu_old_desig_type directly, in which case it will not be
	       a dummy type any more when we get into update_pointer_to.

	       This can happen e.g. when the designated type is a record type,
	       because their elaboration starts with an initial node from
	       make_dummy_type, which may be the same node as the one we got.

	       Besides, variants of this non-dummy type might have been created
	       along the way.  update_pointer_to is expected to properly take
	       care of those situations.  */
	    if (defer_incomplete_level == 0 && !is_from_limited_with)
	      {
		update_pointer_to (TYPE_MAIN_VARIANT (gnu_old_desig_type),
				   gnat_to_gnu_type (gnat_desig_equiv));
	      }
	    else
	      {
		struct incomplete *p = XNEW (struct incomplete);
		struct incomplete **head
		  = (is_from_limited_with
		     ? &defer_limited_with : &defer_incomplete_list);
		p->old_type = gnu_old_desig_type;
		p->full_type = gnat_desig_equiv;
		p->next = *head;
		*head = p;
	      }
	  }
      }
      break;

    case E_Access_Protected_Subprogram_Type:
    case E_Anonymous_Access_Protected_Subprogram_Type:
      if (type_annotate_only && No (gnat_equiv_type))
	gnu_type = ptr_void_type_node;
      else
	{
	  /* The run-time representation is the equivalent type.  */
	  gnu_type = gnat_to_gnu_type (gnat_equiv_type);
	  maybe_present = true;
	}

      if (Is_Itype (Directly_Designated_Type (gnat_entity))
	  && !present_gnu_tree (Directly_Designated_Type (gnat_entity))
	  && No (Freeze_Node (Directly_Designated_Type (gnat_entity)))
	  && !Is_Record_Type (Scope (Directly_Designated_Type (gnat_entity))))
	gnat_to_gnu_entity (Directly_Designated_Type (gnat_entity),
			    NULL_TREE, 0);

      break;

    case E_Access_Subtype:

      /* We treat this as identical to its base type; any constraint is
	 meaningful only to the front-end.

	 The designated type must be elaborated as well, if it does
	 not have its own freeze node.  Designated (sub)types created
	 for constrained components of records with discriminants are
	 not frozen by the front-end and thus not elaborated by gigi,
	 because their use may appear before the base type is frozen,
	 and because it is not clear that they are needed anywhere in
	 gigi.  With the current model, there is no correct place where
	 they could be elaborated.  */

      gnu_type = gnat_to_gnu_type (Etype (gnat_entity));
      if (Is_Itype (Directly_Designated_Type (gnat_entity))
	  && !present_gnu_tree (Directly_Designated_Type (gnat_entity))
	  && Is_Frozen (Directly_Designated_Type (gnat_entity))
	  && No (Freeze_Node (Directly_Designated_Type (gnat_entity))))
	{
	  /* If we are not defining this entity, and we have incomplete
	     entities being processed above us, make a dummy type and
	     elaborate it later.  */
	  if (!definition && defer_incomplete_level != 0)
	    {
	      struct incomplete *p = XNEW (struct incomplete);

	      p->old_type
		= make_dummy_type (Directly_Designated_Type (gnat_entity));
	      p->full_type = Directly_Designated_Type (gnat_entity);
	      p->next = defer_incomplete_list;
	      defer_incomplete_list = p;
	    }
	  else if (!IN (Ekind (Base_Type
			       (Directly_Designated_Type (gnat_entity))),
		        Incomplete_Or_Private_Kind))
	    gnat_to_gnu_entity (Directly_Designated_Type (gnat_entity),
				NULL_TREE, 0);
	}

      maybe_present = true;
      break;

    /* Subprogram Entities

       The following access functions are defined for subprograms:

		Etype       	Return type or Standard_Void_Type.
		First_Formal	The first formal parameter.
		Is_Imported     Indicates that the subprogram has appeared in
				an INTERFACE or IMPORT pragma.  For now we
				assume that the external language is C.
		Is_Exported     Likewise but for an EXPORT pragma.
		Is_Inlined      True if the subprogram is to be inlined.

       Each parameter is first checked by calling must_pass_by_ref on its
       type to determine if it is passed by reference.  For parameters which
       are copied in, if they are Ada In Out or Out parameters, their return
       value becomes part of a record which becomes the return type of the
       function (C function - note that this applies only to Ada procedures
       so there is no Ada return type).  Additional code to store back the
       parameters will be generated on the caller side.  This transformation
       is done here, not in the front-end.

       The intended result of the transformation can be seen from the
       equivalent source rewritings that follow:

						struct temp {int a,b};
       procedure P (A,B: In Out ...) is		temp P (int A,B)
       begin					{
	 ..					  ..
       end P;					  return {A,B};
						}

						temp t;
       P(X,Y);					t = P(X,Y);
						X = t.a , Y = t.b;

       For subprogram types we need to perform mainly the same conversions to
       GCC form that are needed for procedures and function declarations.  The
       only difference is that at the end, we make a type declaration instead
       of a function declaration.  */

    case E_Subprogram_Type:
    case E_Function:
    case E_Procedure:
      {
	/* The type returned by a function or else Standard_Void_Type for a
	   procedure.  */
	Entity_Id gnat_return_type = Etype (gnat_entity);
	tree gnu_return_type;
	/* The first GCC parameter declaration (a PARM_DECL node).  The
	   PARM_DECL nodes are chained through the DECL_CHAIN field, so this
	   actually is the head of this parameter list.  */
	tree gnu_param_list = NULL_TREE;
	/* Likewise for the stub associated with an exported procedure.  */
	tree gnu_stub_param_list = NULL_TREE;
	/* Non-null for subprograms containing parameters passed by copy-in
	   copy-out (Ada In Out or Out parameters not passed by reference),
	   in which case it is the list of nodes used to specify the values
	   of the In Out/Out parameters that are returned as a record upon
	   procedure return.  The TREE_PURPOSE of an element of this list is
	   a field of the record and the TREE_VALUE is the PARM_DECL
	   corresponding to that field.  This list will be saved in the
	   TYPE_CI_CO_LIST field of the FUNCTION_TYPE node we create.  */
	tree gnu_cico_list = NULL_TREE;
	/* List of fields in return type of procedure with copy-in copy-out
	   parameters.  */
	tree gnu_field_list = NULL_TREE;
	/* If an import pragma asks to map this subprogram to a GCC builtin,
	   this is the builtin DECL node.  */
	tree gnu_builtin_decl = NULL_TREE;
	/* For the stub associated with an exported procedure.  */
	tree gnu_stub_type = NULL_TREE, gnu_stub_name = NULL_TREE;
	tree gnu_ext_name = create_concat_name (gnat_entity, NULL);
	Entity_Id gnat_param;
	bool inline_flag = Is_Inlined (gnat_entity);
	bool public_flag = Is_Public (gnat_entity) || imported_p;
	bool extern_flag
	  = (Is_Public (gnat_entity) && !definition) || imported_p;
	bool artificial_flag = !Comes_From_Source (gnat_entity);
       /* The semantics of "pure" in Ada essentially matches that of "const"
          in the back-end.  In particular, both properties are orthogonal to
          the "nothrow" property if the EH circuitry is explicit in the
          internal representation of the back-end.  If we are to completely
          hide the EH circuitry from it, we need to declare that calls to pure
          Ada subprograms that can throw have side effects since they can
          trigger an "abnormal" transfer of control flow; thus they can be
          neither "const" nor "pure" in the back-end sense.  */
	bool const_flag
	  = (Exception_Mechanism == Back_End_Exceptions
	     && Is_Pure (gnat_entity));
	bool volatile_flag = No_Return (gnat_entity);
	bool return_by_direct_ref_p = false;
	bool return_by_invisi_ref_p = false;
	bool return_unconstrained_p = false;
	bool has_stub = false;
	int parmnum;

	/* A parameter may refer to this type, so defer completion of any
	   incomplete types.  */
	if (kind == E_Subprogram_Type && !definition)
	  {
	    defer_incomplete_level++;
	    this_deferred = true;
	  }

	/* If the subprogram has an alias, it is probably inherited, so
	   we can use the original one.  If the original "subprogram"
	   is actually an enumeration literal, it may be the first use
	   of its type, so we must elaborate that type now.  */
	if (Present (Alias (gnat_entity)))
	  {
	    if (Ekind (Alias (gnat_entity)) == E_Enumeration_Literal)
	      gnat_to_gnu_entity (Etype (Alias (gnat_entity)), NULL_TREE, 0);

	    gnu_decl = gnat_to_gnu_entity (Alias (gnat_entity), gnu_expr, 0);

	    /* Elaborate any Itypes in the parameters of this entity.  */
	    for (gnat_temp = First_Formal_With_Extras (gnat_entity);
		 Present (gnat_temp);
		 gnat_temp = Next_Formal_With_Extras (gnat_temp))
	      if (Is_Itype (Etype (gnat_temp)))
		gnat_to_gnu_entity (Etype (gnat_temp), NULL_TREE, 0);

	    break;
	  }

	/* If this subprogram is expectedly bound to a GCC builtin, fetch the
	   corresponding DECL node.  Proper generation of calls later on need
	   proper parameter associations so we don't "break;" here.  */
	if (Convention (gnat_entity) == Convention_Intrinsic
	    && Present (Interface_Name (gnat_entity)))
	  {
	    gnu_builtin_decl = builtin_decl_for (gnu_ext_name);

	    /* Inability to find the builtin decl most often indicates a
	       genuine mistake, but imports of unregistered intrinsics are
	       sometimes issued on purpose to allow hooking in alternate
	       bodies.  We post a warning conditioned on Wshadow in this case,
	       to let developers be notified on demand without risking false
	       positives with common default sets of options.  */

	    if (gnu_builtin_decl == NULL_TREE && warn_shadow)
	      post_error ("?gcc intrinsic not found for&!", gnat_entity);
	  }

	/* ??? What if we don't find the builtin node above ? warn ? err ?
	   In the current state we neither warn nor err, and calls will just
	   be handled as for regular subprograms.  */

	/* Look into the return type and get its associated GCC tree.  If it
	   is not void, compute various flags for the subprogram type.  */
	if (Ekind (gnat_return_type) == E_Void)
	  gnu_return_type = void_type_node;
	else
	  {
	    /* Ada 2012 (AI05-0151): Incomplete types coming from a limited
	       context may now appear in parameter and result profiles.  If
	       we are only annotating types, break circularities here.  */
	    if (type_annotate_only
		&& IN (Ekind (gnat_return_type), Incomplete_Kind)
	        && From_With_Type (gnat_return_type)
		&& In_Extended_Main_Code_Unit
		   (Non_Limited_View (gnat_return_type))
		&& !present_gnu_tree (Non_Limited_View (gnat_return_type)))
	      gnu_return_type = ptr_void_type_node;
	    else
	      gnu_return_type = gnat_to_gnu_type (gnat_return_type);

	    /* If this function returns by reference, make the actual return
	       type the pointer type and make a note of that.  */
	    if (Returns_By_Ref (gnat_entity))
	      {
		gnu_return_type = build_pointer_type (gnu_return_type);
		return_by_direct_ref_p = true;
	      }

	    /* If we are supposed to return an unconstrained array type, make
	       the actual return type the fat pointer type.  */
	    else if (TREE_CODE (gnu_return_type) == UNCONSTRAINED_ARRAY_TYPE)
	      {
		gnu_return_type = TREE_TYPE (gnu_return_type);
		return_unconstrained_p = true;
	      }

	    /* Likewise, if the return type requires a transient scope, the
	       return value will be allocated on the secondary stack so the
	       actual return type is the pointer type.  */
	    else if (Requires_Transient_Scope (gnat_return_type))
	      {
		gnu_return_type = build_pointer_type (gnu_return_type);
		return_unconstrained_p = true;
	      }

	    /* If the Mechanism is By_Reference, ensure this function uses the
	       target's by-invisible-reference mechanism, which may not be the
	       same as above (e.g. it might be passing an extra parameter).  */
	    else if (kind == E_Function
		     && Mechanism (gnat_entity) == By_Reference)
	      return_by_invisi_ref_p = true;

	    /* Likewise, if the return type is itself By_Reference.  */
	    else if (TYPE_IS_BY_REFERENCE_P (gnu_return_type))
	      return_by_invisi_ref_p = true;

	    /* If the type is a padded type and the underlying type would not
	       be passed by reference or the function has a foreign convention,
	       return the underlying type.  */
	    else if (TYPE_IS_PADDING_P (gnu_return_type)
		     && (!default_pass_by_ref
			  (TREE_TYPE (TYPE_FIELDS (gnu_return_type)))
			 || Has_Foreign_Convention (gnat_entity)))
	      gnu_return_type = TREE_TYPE (TYPE_FIELDS (gnu_return_type));

	    /* If the return type is unconstrained, that means it must have a
	       maximum size.  Use the padded type as the effective return type.
	       And ensure the function uses the target's by-invisible-reference
	       mechanism to avoid copying too much data when it returns.  */
	    if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_return_type)))
	      {
		tree orig_type = gnu_return_type;

		gnu_return_type
		  = maybe_pad_type (gnu_return_type,
				    max_size (TYPE_SIZE (gnu_return_type),
					      true),
				    0, gnat_entity, false, false, false, true);

		/* Declare it now since it will never be declared otherwise.
		   This is necessary to ensure that its subtrees are properly
		   marked.  */
		if (gnu_return_type != orig_type
		    && !DECL_P (TYPE_NAME (gnu_return_type)))
		  create_type_decl (TYPE_NAME (gnu_return_type),
				    gnu_return_type, NULL, true,
				    debug_info_p, gnat_entity);

		return_by_invisi_ref_p = true;
	      }

	    /* If the return type has a size that overflows, we cannot have
	       a function that returns that type.  This usage doesn't make
	       sense anyway, so give an error here.  */
	    if (TYPE_SIZE_UNIT (gnu_return_type)
		&& TREE_CODE (TYPE_SIZE_UNIT (gnu_return_type)) == INTEGER_CST
		&& !valid_constant_size_p (TYPE_SIZE_UNIT (gnu_return_type)))
	      {
		post_error ("cannot return type whose size overflows",
			    gnat_entity);
		gnu_return_type = copy_node (gnu_return_type);
		TYPE_SIZE (gnu_return_type) = bitsize_zero_node;
		TYPE_SIZE_UNIT (gnu_return_type) = size_zero_node;
		TYPE_MAIN_VARIANT (gnu_return_type) = gnu_return_type;
		TYPE_NEXT_VARIANT (gnu_return_type) = NULL_TREE;
	      }
	  }

	/* Loop over the parameters and get their associated GCC tree.  While
	   doing this, build a copy-in copy-out structure if we need one.  */
	for (gnat_param = First_Formal_With_Extras (gnat_entity), parmnum = 0;
	     Present (gnat_param);
	     gnat_param = Next_Formal_With_Extras (gnat_param), parmnum++)
	  {
	    Entity_Id gnat_param_type = Etype (gnat_param);
	    tree gnu_param_name = get_entity_name (gnat_param);
	    tree gnu_param_type, gnu_param, gnu_field;
	    Mechanism_Type mech = Mechanism (gnat_param);
  	    bool copy_in_copy_out = false, fake_param_type;

	    /* Ada 2012 (AI05-0151): Incomplete types coming from a limited
	       context may now appear in parameter and result profiles.  If
	       we are only annotating types, break circularities here.  */
	    if (type_annotate_only
		&& IN (Ekind (gnat_param_type), Incomplete_Kind)
	        && From_With_Type (Etype (gnat_param_type))
		&& In_Extended_Main_Code_Unit
		   (Non_Limited_View (gnat_param_type))
		&& !present_gnu_tree (Non_Limited_View (gnat_param_type)))
	      {
		gnu_param_type = ptr_void_type_node;
		fake_param_type = true;
	      }
	    else
	      {
		gnu_param_type = gnat_to_gnu_type (gnat_param_type);
		fake_param_type = false;
	      }

	    /* Builtins are expanded inline and there is no real call sequence
	       involved.  So the type expected by the underlying expander is
	       always the type of each argument "as is".  */
	    if (gnu_builtin_decl)
	      mech = By_Copy;
	    /* Handle the first parameter of a valued procedure specially.  */
	    else if (Is_Valued_Procedure (gnat_entity) && parmnum == 0)
	      mech = By_Copy_Return;
	    /* Otherwise, see if a Mechanism was supplied that forced this
	       parameter to be passed one way or another.  */
	    else if (mech == Default
		     || mech == By_Copy || mech == By_Reference)
	      ;
	    else if (By_Descriptor_Last <= mech && mech <= By_Descriptor)
	      mech = By_Descriptor;

	    else if (By_Short_Descriptor_Last <= mech &&
                     mech <= By_Short_Descriptor)
	      mech = By_Short_Descriptor;

	    else if (mech > 0)
	      {
		if (TREE_CODE (gnu_param_type) == UNCONSTRAINED_ARRAY_TYPE
		    || TREE_CODE (TYPE_SIZE (gnu_param_type)) != INTEGER_CST
		    || 0 < compare_tree_int (TYPE_SIZE (gnu_param_type),
					     mech))
		  mech = By_Reference;
		else
		  mech = By_Copy;
	      }
	    else
	      {
		post_error ("unsupported mechanism for&", gnat_param);
		mech = Default;
	      }

	    /* Do not call gnat_to_gnu_param for a fake parameter type since
	       it will try to use the real type again.  */
	    if (fake_param_type)
	      {
		if (Ekind (gnat_param) == E_Out_Parameter)
		  gnu_param = NULL_TREE;
		else
		  {
		    gnu_param
		      = create_param_decl (gnu_param_name, gnu_param_type,
					   false);
		    Set_Mechanism (gnat_param,
				   mech == Default ? By_Copy : mech);
		    if (Ekind (gnat_param) == E_In_Out_Parameter)
		      copy_in_copy_out = true;
		  }
	      }
	    else
	      gnu_param
		= gnat_to_gnu_param (gnat_param, mech, gnat_entity,
				     Has_Foreign_Convention (gnat_entity),
				     &copy_in_copy_out);

	    /* We are returned either a PARM_DECL or a type if no parameter
	       needs to be passed; in either case, adjust the type.  */
	    if (DECL_P (gnu_param))
	      gnu_param_type = TREE_TYPE (gnu_param);
	    else
	      {
		gnu_param_type = gnu_param;
		gnu_param = NULL_TREE;
	      }

	    /* The failure of this assertion will very likely come from an
	       order of elaboration issue for the type of the parameter.  */
	    gcc_assert (kind == E_Subprogram_Type
			|| !TYPE_IS_DUMMY_P (gnu_param_type)
			|| type_annotate_only);

	    if (gnu_param)
	      {
		/* If it's an exported subprogram, we build a parameter list
		   in parallel, in case we need to emit a stub for it.  */
		if (Is_Exported (gnat_entity))
		  {
		    gnu_stub_param_list
		      = chainon (gnu_param, gnu_stub_param_list);
		    /* Change By_Descriptor parameter to By_Reference for
		       the internal version of an exported subprogram.  */
		    if (mech == By_Descriptor || mech == By_Short_Descriptor)
		      {
			gnu_param
			  = gnat_to_gnu_param (gnat_param, By_Reference,
					       gnat_entity, false,
					       &copy_in_copy_out);
			has_stub = true;
		      }
		    else
		      gnu_param = copy_node (gnu_param);
		  }

		gnu_param_list = chainon (gnu_param, gnu_param_list);
		Sloc_to_locus (Sloc (gnat_param),
			       &DECL_SOURCE_LOCATION (gnu_param));
		save_gnu_tree (gnat_param, gnu_param, false);

		/* If a parameter is a pointer, this function may modify
		   memory through it and thus shouldn't be considered
		   a const function.  Also, the memory may be modified
		   between two calls, so they can't be CSE'ed.  The latter
		   case also handles by-ref parameters.  */
		if (POINTER_TYPE_P (gnu_param_type)
		    || TYPE_IS_FAT_POINTER_P (gnu_param_type))
		  const_flag = false;
	      }

	    if (copy_in_copy_out)
	      {
		if (!gnu_cico_list)
		  {
		    tree gnu_new_ret_type = make_node (RECORD_TYPE);

		    /* If this is a function, we also need a field for the
		       return value to be placed.  */
		    if (TREE_CODE (gnu_return_type) != VOID_TYPE)
		      {
			gnu_field
			  = create_field_decl (get_identifier ("RETVAL"),
					       gnu_return_type,
					       gnu_new_ret_type, NULL_TREE,
					       NULL_TREE, 0, 0);
			Sloc_to_locus (Sloc (gnat_entity),
				       &DECL_SOURCE_LOCATION (gnu_field));
			gnu_field_list = gnu_field;
			gnu_cico_list
			  = tree_cons (gnu_field, void_type_node, NULL_TREE);
		      }

		    gnu_return_type = gnu_new_ret_type;
		    TYPE_NAME (gnu_return_type) = get_identifier ("RETURN");
		    /* Set a default alignment to speed up accesses.  But we
		       shouldn't increase the size of the structure too much,
		       lest it doesn't fit in return registers anymore.  */
		    TYPE_ALIGN (gnu_return_type)
		      = get_mode_alignment (ptr_mode);
		  }

		gnu_field
		  = create_field_decl (gnu_param_name, gnu_param_type,
				       gnu_return_type, NULL_TREE, NULL_TREE,
				       0, 0);
		Sloc_to_locus (Sloc (gnat_param),
			       &DECL_SOURCE_LOCATION (gnu_field));
		DECL_CHAIN (gnu_field) = gnu_field_list;
		gnu_field_list = gnu_field;
		gnu_cico_list
		  = tree_cons (gnu_field, gnu_param, gnu_cico_list);
	      }
	  }

	if (gnu_cico_list)
	  {
	    /* If we have a CICO list but it has only one entry, we convert
	       this function into a function that returns this object.  */
	    if (list_length (gnu_cico_list) == 1)
	      gnu_return_type = TREE_TYPE (TREE_PURPOSE (gnu_cico_list));

	    /* Do not finalize the return type if the subprogram is stubbed
	       since structures are incomplete for the back-end.  */
	    else if (Convention (gnat_entity) != Convention_Stubbed)
	      {
		finish_record_type (gnu_return_type, nreverse (gnu_field_list),
				    0, false);

	        /* Try to promote the mode of the return type if it is passed
		   in registers, again to speed up accesses.  */
		if (TYPE_MODE (gnu_return_type) == BLKmode
		    && !targetm.calls.return_in_memory (gnu_return_type,
							NULL_TREE))
		  {
		    unsigned int size
		      = TREE_INT_CST_LOW (TYPE_SIZE (gnu_return_type));
		    unsigned int i = BITS_PER_UNIT;
		    enum machine_mode mode;

		    while (i < size)
		      i <<= 1;
		    mode = mode_for_size (i, MODE_INT, 0);
		    if (mode != BLKmode)
		      {
			SET_TYPE_MODE (gnu_return_type, mode);
			TYPE_ALIGN (gnu_return_type)
			  = GET_MODE_ALIGNMENT (mode);
			TYPE_SIZE (gnu_return_type)
			  = bitsize_int (GET_MODE_BITSIZE (mode));
			TYPE_SIZE_UNIT (gnu_return_type)
			  = size_int (GET_MODE_SIZE (mode));
		      }
		  }

	        if (debug_info_p)
		  rest_of_record_type_compilation (gnu_return_type);
	      }
	  }

	if (Has_Stdcall_Convention (gnat_entity))
	  prepend_one_attribute_to
	    (&attr_list, ATTR_MACHINE_ATTRIBUTE,
	     get_identifier ("stdcall"), NULL_TREE,
	     gnat_entity);
	else if (Has_Thiscall_Convention (gnat_entity))
	  prepend_one_attribute_to
	    (&attr_list, ATTR_MACHINE_ATTRIBUTE,
	     get_identifier ("thiscall"), NULL_TREE,
	     gnat_entity);

	/* If we should request stack realignment for a foreign convention
	   subprogram, do so.  Note that this applies to task entry points in
	   particular.  */
	if (FOREIGN_FORCE_REALIGN_STACK
	    && Has_Foreign_Convention (gnat_entity))
	  prepend_one_attribute_to
	    (&attr_list, ATTR_MACHINE_ATTRIBUTE,
	     get_identifier ("force_align_arg_pointer"), NULL_TREE,
	     gnat_entity);

	/* The lists have been built in reverse.  */
	gnu_param_list = nreverse (gnu_param_list);
	if (has_stub)
	  gnu_stub_param_list = nreverse (gnu_stub_param_list);
	gnu_cico_list = nreverse (gnu_cico_list);

	if (kind == E_Function)
	  Set_Mechanism (gnat_entity, return_unconstrained_p
				      || return_by_direct_ref_p
				      || return_by_invisi_ref_p
				      ? By_Reference : By_Copy);
	gnu_type
	  = create_subprog_type (gnu_return_type, gnu_param_list,
				 gnu_cico_list, return_unconstrained_p,
				 return_by_direct_ref_p,
				 return_by_invisi_ref_p);

	if (has_stub)
	  gnu_stub_type
	    = create_subprog_type (gnu_return_type, gnu_stub_param_list,
				   gnu_cico_list, return_unconstrained_p,
				   return_by_direct_ref_p,
				   return_by_invisi_ref_p);

	/* A subprogram (something that doesn't return anything) shouldn't
	   be considered const since there would be no reason for such a
	   subprogram.  Note that procedures with Out (or In Out) parameters
	   have already been converted into a function with a return type.  */
	if (TREE_CODE (gnu_return_type) == VOID_TYPE)
	  const_flag = false;

	gnu_type
	  = build_qualified_type (gnu_type,
				  TYPE_QUALS (gnu_type)
				  | (TYPE_QUAL_CONST * const_flag)
				  | (TYPE_QUAL_VOLATILE * volatile_flag));

	if (has_stub)
	  gnu_stub_type
	    = build_qualified_type (gnu_stub_type,
				    TYPE_QUALS (gnu_stub_type)
				    | (TYPE_QUAL_CONST * const_flag)
				    | (TYPE_QUAL_VOLATILE * volatile_flag));

	/* If we have a builtin decl for that function, use it.  Check if the
	   profiles are compatible and warn if they are not.  The checker is
	   expected to post extra diagnostics in this case.  */
	if (gnu_builtin_decl)
	  {
	    intrin_binding_t inb;

	    inb.gnat_entity = gnat_entity;
	    inb.ada_fntype = gnu_type;
	    inb.btin_fntype = TREE_TYPE (gnu_builtin_decl);

	    if (!intrin_profiles_compatible_p (&inb))
	      post_error
		("?profile of& doesn''t match the builtin it binds!",
		 gnat_entity);

	    gnu_decl = gnu_builtin_decl;
	    gnu_type = TREE_TYPE (gnu_builtin_decl);
	    break;
	  }

	/* If there was no specified Interface_Name and the external and
	   internal names of the subprogram are the same, only use the
	   internal name to allow disambiguation of nested subprograms.  */
	if (No (Interface_Name (gnat_entity))
	    && gnu_ext_name == gnu_entity_name)
	  gnu_ext_name = NULL_TREE;

	/* If we are defining the subprogram and it has an Address clause
	   we must get the address expression from the saved GCC tree for the
	   subprogram if it has a Freeze_Node.  Otherwise, we elaborate
	   the address expression here since the front-end has guaranteed
	   in that case that the elaboration has no effects.  If there is
	   an Address clause and we are not defining the object, just
	   make it a constant.  */
	if (Present (Address_Clause (gnat_entity)))
	  {
	    tree gnu_address = NULL_TREE;

	    if (definition)
	      gnu_address
		= (present_gnu_tree (gnat_entity)
		   ? get_gnu_tree (gnat_entity)
		   : gnat_to_gnu (Expression (Address_Clause (gnat_entity))));

	    save_gnu_tree (gnat_entity, NULL_TREE, false);

	    /* Convert the type of the object to a reference type that can
	       alias everything as per 13.3(19).  */
	    gnu_type
	      = build_reference_type_for_mode (gnu_type, ptr_mode, true);
	    if (gnu_address)
	      gnu_address = convert (gnu_type, gnu_address);

	    gnu_decl
	      = create_var_decl (gnu_entity_name, gnu_ext_name, gnu_type,
				 gnu_address, false, Is_Public (gnat_entity),
				 extern_flag, false, NULL, gnat_entity);
	    DECL_BY_REF_P (gnu_decl) = 1;
	  }

	else if (kind == E_Subprogram_Type)
	  gnu_decl
	    = create_type_decl (gnu_entity_name, gnu_type, attr_list,
				artificial_flag, debug_info_p, gnat_entity);
	else
	  {
	    if (has_stub)
	      {
		gnu_stub_name = gnu_ext_name;
		gnu_ext_name = create_concat_name (gnat_entity, "internal");
		public_flag = false;
 		artificial_flag = true;
	      }

	    gnu_decl
	      = create_subprog_decl (gnu_entity_name, gnu_ext_name, gnu_type,
				     gnu_param_list, inline_flag, public_flag,
				     extern_flag, artificial_flag, attr_list,
				     gnat_entity);
	    if (has_stub)
	      {
		tree gnu_stub_decl
		  = create_subprog_decl (gnu_entity_name, gnu_stub_name,
					 gnu_stub_type, gnu_stub_param_list,
					 inline_flag, true, extern_flag,
					 false, attr_list, gnat_entity);
		SET_DECL_FUNCTION_STUB (gnu_decl, gnu_stub_decl);
	      }

	    /* This is unrelated to the stub built right above.  */
	    DECL_STUBBED_P (gnu_decl)
	      = Convention (gnat_entity) == Convention_Stubbed;
	  }
      }
      break;

    case E_Incomplete_Type:
    case E_Incomplete_Subtype:
    case E_Private_Type:
    case E_Private_Subtype:
    case E_Limited_Private_Type:
    case E_Limited_Private_Subtype:
    case E_Record_Type_With_Private:
    case E_Record_Subtype_With_Private:
      {
	/* Get the "full view" of this entity.  If this is an incomplete
	   entity from a limited with, treat its non-limited view as the
	   full view.  Otherwise, use either the full view or the underlying
	   full view, whichever is present.  This is used in all the tests
	   below.  */
	Entity_Id full_view
	  = (IN (kind, Incomplete_Kind) && From_With_Type (gnat_entity))
	    ? Non_Limited_View (gnat_entity)
	    : Present (Full_View (gnat_entity))
	      ? Full_View (gnat_entity)
	      : Underlying_Full_View (gnat_entity);

	/* If this is an incomplete type with no full view, it must be a Taft
	   Amendment type, in which case we return a dummy type.  Otherwise,
	   just get the type from its Etype.  */
	if (No (full_view))
	  {
	    if (kind == E_Incomplete_Type)
	      {
		gnu_type = make_dummy_type (gnat_entity);
		gnu_decl = TYPE_STUB_DECL (gnu_type);
	      }
	    else
	      {
		gnu_decl = gnat_to_gnu_entity (Etype (gnat_entity),
					       NULL_TREE, 0);
		maybe_present = true;
	      }
	    break;
	  }

	/* If we already made a type for the full view, reuse it.  */
	else if (present_gnu_tree (full_view))
	  {
	    gnu_decl = get_gnu_tree (full_view);
	    break;
	  }

	/* Otherwise, if we are not defining the type now, get the type
	   from the full view.  But always get the type from the full view
	   for define on use types, since otherwise we won't see them!  */
	else if (!definition
		 || (Is_Itype (full_view)
		   && No (Freeze_Node (gnat_entity)))
		 || (Is_Itype (gnat_entity)
		   && No (Freeze_Node (full_view))))
	  {
	    gnu_decl = gnat_to_gnu_entity (full_view, NULL_TREE, 0);
	    maybe_present = true;
	    break;
	  }

	/* For incomplete types, make a dummy type entry which will be
	   replaced later.  Save it as the full declaration's type so
	   we can do any needed updates when we see it.  */
	gnu_type = make_dummy_type (gnat_entity);
	gnu_decl = TYPE_STUB_DECL (gnu_type);
	if (Has_Completion_In_Body (gnat_entity))
	  DECL_TAFT_TYPE_P (gnu_decl) = 1;
	save_gnu_tree (full_view, gnu_decl, 0);
	break;
      }

    case E_Class_Wide_Type:
      /* Class-wide types are always transformed into their root type.  */
      gnu_decl = gnat_to_gnu_entity (gnat_equiv_type, NULL_TREE, 0);
      maybe_present = true;
      break;

    case E_Task_Type:
    case E_Task_Subtype:
    case E_Protected_Type:
    case E_Protected_Subtype:
      /* Concurrent types are always transformed into their record type.  */
      if (type_annotate_only && No (gnat_equiv_type))
	gnu_type = void_type_node;
      else
	gnu_decl = gnat_to_gnu_entity (gnat_equiv_type, NULL_TREE, 0);
      maybe_present = true;
      break;

    case E_Label:
      gnu_decl = create_label_decl (gnu_entity_name, gnat_entity);
      break;

    case E_Block:
    case E_Loop:
      /* Nothing at all to do here, so just return an ERROR_MARK and claim
	 we've already saved it, so we don't try to.  */
      gnu_decl = error_mark_node;
      saved = true;
      break;

    default:
      gcc_unreachable ();
    }

  /* If we had a case where we evaluated another type and it might have
     defined this one, handle it here.  */
  if (maybe_present && present_gnu_tree (gnat_entity))
    {
      gnu_decl = get_gnu_tree (gnat_entity);
      saved = true;
    }

  /* If we are processing a type and there is either no decl for it or
     we just made one, do some common processing for the type, such as
     handling alignment and possible padding.  */
  if (is_type && (!gnu_decl || this_made_decl))
    {
      /* Tell the middle-end that objects of tagged types are guaranteed to
	 be properly aligned.  This is necessary because conversions to the
	 class-wide type are translated into conversions to the root type,
	 which can be less aligned than some of its derived types.  */
      if (Is_Tagged_Type (gnat_entity)
	  || Is_Class_Wide_Equivalent_Type (gnat_entity))
	TYPE_ALIGN_OK (gnu_type) = 1;

      /* Record whether the type is passed by reference.  */
      if (!VOID_TYPE_P (gnu_type) && Is_By_Reference_Type (gnat_entity))
	TYPE_BY_REFERENCE_P (gnu_type) = 1;

      /* ??? Don't set the size for a String_Literal since it is either
	 confirming or we don't handle it properly (if the low bound is
	 non-constant).  */
      if (!gnu_size && kind != E_String_Literal_Subtype)
	{
	  Uint gnat_size = Known_Esize (gnat_entity)
			   ? Esize (gnat_entity) : RM_Size (gnat_entity);
	  gnu_size
	    = validate_size (gnat_size, gnu_type, gnat_entity, TYPE_DECL,
			     false, Has_Size_Clause (gnat_entity));
	}

      /* If a size was specified, see if we can make a new type of that size
	 by rearranging the type, for example from a fat to a thin pointer.  */
      if (gnu_size)
	{
	  gnu_type
	    = make_type_from_size (gnu_type, gnu_size,
				   Has_Biased_Representation (gnat_entity));

	  if (operand_equal_p (TYPE_SIZE (gnu_type), gnu_size, 0)
	      && operand_equal_p (rm_size (gnu_type), gnu_size, 0))
	    gnu_size = NULL_TREE;
	}

      /* If the alignment hasn't already been processed and this is
	 not an unconstrained array, see if an alignment is specified.
	 If not, we pick a default alignment for atomic objects.  */
      if (align != 0 || TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
	;
      else if (Known_Alignment (gnat_entity))
	{
	  align = validate_alignment (Alignment (gnat_entity), gnat_entity,
				      TYPE_ALIGN (gnu_type));

	  /* Warn on suspiciously large alignments.  This should catch
	     errors about the (alignment,byte)/(size,bit) discrepancy.  */
	  if (align > BIGGEST_ALIGNMENT && Has_Alignment_Clause (gnat_entity))
	    {
	      tree size;

	      /* If a size was specified, take it into account.  Otherwise
		 use the RM size for records or unions as the type size has
		 already been adjusted to the alignment.  */
	      if (gnu_size)
		size = gnu_size;
	      else if (RECORD_OR_UNION_TYPE_P (gnu_type)
		       && !TYPE_FAT_POINTER_P (gnu_type))
		size = rm_size (gnu_type);
	      else
	        size = TYPE_SIZE (gnu_type);

	      /* Consider an alignment as suspicious if the alignment/size
		 ratio is greater or equal to the byte/bit ratio.  */
	      if (host_integerp (size, 1)
		  && align >= TREE_INT_CST_LOW (size) * BITS_PER_UNIT)
		post_error_ne ("?suspiciously large alignment specified for&",
			       Expression (Alignment_Clause (gnat_entity)),
			       gnat_entity);
	    }
	}
      else if (Is_Atomic (gnat_entity) && !gnu_size
	       && host_integerp (TYPE_SIZE (gnu_type), 1)
	       && integer_pow2p (TYPE_SIZE (gnu_type)))
	align = MIN (BIGGEST_ALIGNMENT,
		     tree_low_cst (TYPE_SIZE (gnu_type), 1));
      else if (Is_Atomic (gnat_entity) && gnu_size
	       && host_integerp (gnu_size, 1)
	       && integer_pow2p (gnu_size))
	align = MIN (BIGGEST_ALIGNMENT, tree_low_cst (gnu_size, 1));

      /* See if we need to pad the type.  If we did, and made a record,
	 the name of the new type may be changed.  So get it back for
	 us when we make the new TYPE_DECL below.  */
      if (gnu_size || align > 0)
	gnu_type = maybe_pad_type (gnu_type, gnu_size, align, gnat_entity,
				   false, !gnu_decl, definition, false);

      if (TYPE_IS_PADDING_P (gnu_type))
	{
	  gnu_entity_name = TYPE_NAME (gnu_type);
	  if (TREE_CODE (gnu_entity_name) == TYPE_DECL)
	    gnu_entity_name = DECL_NAME (gnu_entity_name);
	}

      /* Now set the RM size of the type.  We cannot do it before padding
	 because we need to accept arbitrary RM sizes on integral types.  */
      set_rm_size (RM_Size (gnat_entity), gnu_type, gnat_entity);

      /* If we are at global level, GCC will have applied variable_size to
	 the type, but that won't have done anything.  So, if it's not
	 a constant or self-referential, call elaborate_expression_1 to
	 make a variable for the size rather than calculating it each time.
	 Handle both the RM size and the actual size.  */
      if (global_bindings_p ()
	  && TYPE_SIZE (gnu_type)
	  && !TREE_CONSTANT (TYPE_SIZE (gnu_type))
	  && !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type)))
	{
	  tree size = TYPE_SIZE (gnu_type);

	  TYPE_SIZE (gnu_type)
	    = elaborate_expression_1 (size, gnat_entity,
				      get_identifier ("SIZE"),
				      definition, false);

	  /* ??? For now, store the size as a multiple of the alignment in
	     bytes so that we can see the alignment from the tree.  */
	  TYPE_SIZE_UNIT (gnu_type)
	    = elaborate_expression_2 (TYPE_SIZE_UNIT (gnu_type), gnat_entity,
				      get_identifier ("SIZE_A_UNIT"),
				      definition, false,
				      TYPE_ALIGN (gnu_type));

	  /* ??? gnu_type may come from an existing type so the MULT_EXPR node
	     may not be marked by the call to create_type_decl below.  */
	  MARK_VISITED (TYPE_SIZE_UNIT (gnu_type));

	  if (TREE_CODE (gnu_type) == RECORD_TYPE)
	    {
	      tree variant_part = get_variant_part (gnu_type);
	      tree ada_size = TYPE_ADA_SIZE (gnu_type);

	      if (variant_part)
		{
		  tree union_type = TREE_TYPE (variant_part);
		  tree offset = DECL_FIELD_OFFSET (variant_part);

		  /* If the position of the variant part is constant, subtract
		     it from the size of the type of the parent to get the new
		     size.  This manual CSE reduces the data size.  */
		  if (TREE_CODE (offset) == INTEGER_CST)
		    {
		      tree bitpos = DECL_FIELD_BIT_OFFSET (variant_part);
		      TYPE_SIZE (union_type)
			= size_binop (MINUS_EXPR, TYPE_SIZE (gnu_type),
				      bit_from_pos (offset, bitpos));
		      TYPE_SIZE_UNIT (union_type)
			= size_binop (MINUS_EXPR, TYPE_SIZE_UNIT (gnu_type),
				      byte_from_pos (offset, bitpos));
		    }
		  else
		    {
		      TYPE_SIZE (union_type)
			= elaborate_expression_1 (TYPE_SIZE (union_type),
						  gnat_entity,
						  get_identifier ("VSIZE"),
						  definition, false);

		      /* ??? For now, store the size as a multiple of the
			 alignment in bytes so that we can see the alignment
			 from the tree.  */
		      TYPE_SIZE_UNIT (union_type)
			= elaborate_expression_2 (TYPE_SIZE_UNIT (union_type),
						  gnat_entity,
						  get_identifier
						  ("VSIZE_A_UNIT"),
						  definition, false,
						  TYPE_ALIGN (union_type));

		      /* ??? For now, store the offset as a multiple of the
			 alignment in bytes so that we can see the alignment
			 from the tree.  */
		      DECL_FIELD_OFFSET (variant_part)
			= elaborate_expression_2 (offset,
						  gnat_entity,
						  get_identifier ("VOFFSET"),
						  definition, false,
						  DECL_OFFSET_ALIGN
						  (variant_part));
		    }

		  DECL_SIZE (variant_part) = TYPE_SIZE (union_type);
		  DECL_SIZE_UNIT (variant_part) = TYPE_SIZE_UNIT (union_type);
		}

	      if (operand_equal_p (ada_size, size, 0))
		ada_size = TYPE_SIZE (gnu_type);
	      else
		ada_size
		  = elaborate_expression_1 (ada_size, gnat_entity,
					    get_identifier ("RM_SIZE"),
					    definition, false);
	      SET_TYPE_ADA_SIZE (gnu_type, ada_size);
	    }
	}

      /* If this is a record type or subtype, call elaborate_expression_2 on
	 any field position.  Do this for both global and local types.
	 Skip any fields that we haven't made trees for to avoid problems with
	 class wide types.  */
      if (IN (kind, Record_Kind))
	for (gnat_temp = First_Entity (gnat_entity); Present (gnat_temp);
	     gnat_temp = Next_Entity (gnat_temp))
	  if (Ekind (gnat_temp) == E_Component && present_gnu_tree (gnat_temp))
	    {
	      tree gnu_field = get_gnu_tree (gnat_temp);

	      /* ??? For now, store the offset as a multiple of the alignment
		 in bytes so that we can see the alignment from the tree.  */
	      if (!CONTAINS_PLACEHOLDER_P (DECL_FIELD_OFFSET (gnu_field)))
		{
		  DECL_FIELD_OFFSET (gnu_field)
		    = elaborate_expression_2 (DECL_FIELD_OFFSET (gnu_field),
					      gnat_temp,
					      get_identifier ("OFFSET"),
					      definition, false,
					      DECL_OFFSET_ALIGN (gnu_field));

		  /* ??? The context of gnu_field is not necessarily gnu_type
		     so the MULT_EXPR node built above may not be marked by
		     the call to create_type_decl below.  */
		  if (global_bindings_p ())
		    MARK_VISITED (DECL_FIELD_OFFSET (gnu_field));
		}
	    }

      if (Treat_As_Volatile (gnat_entity))
	gnu_type
	  = build_qualified_type (gnu_type,
				  TYPE_QUALS (gnu_type) | TYPE_QUAL_VOLATILE);

      if (Is_Atomic (gnat_entity))
	check_ok_for_atomic (gnu_type, gnat_entity, false);

      if (Present (Alignment_Clause (gnat_entity)))
	TYPE_USER_ALIGN (gnu_type) = 1;

      if (Universal_Aliasing (gnat_entity))
	TYPE_UNIVERSAL_ALIASING_P (TYPE_MAIN_VARIANT (gnu_type)) = 1;

      if (!gnu_decl)
	gnu_decl = create_type_decl (gnu_entity_name, gnu_type, attr_list,
				     !Comes_From_Source (gnat_entity),
				     debug_info_p, gnat_entity);
      else
	{
	  TREE_TYPE (gnu_decl) = gnu_type;
	  TYPE_STUB_DECL (gnu_type) = gnu_decl;
	}
    }

  if (is_type && !TYPE_IS_DUMMY_P (TREE_TYPE (gnu_decl)))
    {
      gnu_type = TREE_TYPE (gnu_decl);

      /* If this is a derived type, relate its alias set to that of its parent
	 to avoid troubles when a call to an inherited primitive is inlined in
	 a context where a derived object is accessed.  The inlined code works
	 on the parent view so the resulting code may access the same object
	 using both the parent and the derived alias sets, which thus have to
	 conflict.  As the same issue arises with component references, the
	 parent alias set also has to conflict with composite types enclosing
	 derived components.  For instance, if we have:

	    type D is new T;
	    type R is record
	       Component : D;
	    end record;

	 we want T to conflict with both D and R, in addition to R being a
	 superset of D by record/component construction.

	 One way to achieve this is to perform an alias set copy from the
	 parent to the derived type.  This is not quite appropriate, though,
	 as we don't want separate derived types to conflict with each other:

	    type I1 is new Integer;
	    type I2 is new Integer;

	 We want I1 and I2 to both conflict with Integer but we do not want
	 I1 to conflict with I2, and an alias set copy on derivation would
	 have that effect.

	 The option chosen is to make the alias set of the derived type a
	 superset of that of its parent type.  It trivially fulfills the
	 simple requirement for the Integer derivation example above, and
	 the component case as well by superset transitivity:

		   superset      superset
		R ----------> D ----------> T

	 However, for composite types, conversions between derived types are
	 translated into VIEW_CONVERT_EXPRs so a sequence like:

	    type Comp1 is new Comp;
	    type Comp2 is new Comp;
	    procedure Proc (C : Comp1);

	    C : Comp2;
	    Proc (Comp1 (C));

	 is translated into:

	    C : Comp2;
	    Proc ((Comp1 &) &VIEW_CONVERT_EXPR <Comp1> (C));

	 and gimplified into:

	    C : Comp2;
	    Comp1 *C.0;
	    C.0 = (Comp1 *) &C;
	    Proc (C.0);

	 i.e. generates code involving type punning.  Therefore, Comp1 needs
	 to conflict with Comp2 and an alias set copy is required.

	 The language rules ensure the parent type is already frozen here.  */
      if (Is_Derived_Type (gnat_entity))
	{
	  tree gnu_parent_type = gnat_to_gnu_type (Etype (gnat_entity));
	  relate_alias_sets (gnu_type, gnu_parent_type,
			     Is_Composite_Type (gnat_entity)
			     ? ALIAS_SET_COPY : ALIAS_SET_SUPERSET);
	}

      /* Back-annotate the Alignment of the type if not already in the
	 tree.  Likewise for sizes.  */
      if (Unknown_Alignment (gnat_entity))
	{
	  unsigned int double_align, align;
	  bool is_capped_double, align_clause;

	  /* If the default alignment of "double" or larger scalar types is
	     specifically capped and this is not an array with an alignment
	     clause on the component type, return the cap.  */
	  if ((double_align = double_float_alignment) > 0)
	    is_capped_double
	      = is_double_float_or_array (gnat_entity, &align_clause);
	  else if ((double_align = double_scalar_alignment) > 0)
	    is_capped_double
	      = is_double_scalar_or_array (gnat_entity, &align_clause);
	  else
	    is_capped_double = align_clause = false;

	  if (is_capped_double && !align_clause)
	    align = double_align;
	  else
	    align = TYPE_ALIGN (gnu_type) / BITS_PER_UNIT;

	  Set_Alignment (gnat_entity, UI_From_Int (align));
	}

      if (Unknown_Esize (gnat_entity) && TYPE_SIZE (gnu_type))
	{
	  tree gnu_size = TYPE_SIZE (gnu_type);

	  /* If the size is self-referential, annotate the maximum value.  */
	  if (CONTAINS_PLACEHOLDER_P (gnu_size))
	    gnu_size = max_size (gnu_size, true);

	  /* If we are just annotating types and the type is tagged, the tag
	     and the parent components are not generated by the front-end so
	     sizes must be adjusted if there is no representation clause.  */
	  if (type_annotate_only
	      && Is_Tagged_Type (gnat_entity)
	      && !VOID_TYPE_P (gnu_type)
	      && (!TYPE_FIELDS (gnu_type)
		  || integer_zerop (bit_position (TYPE_FIELDS (gnu_type)))))
	    {
	      tree pointer_size = bitsize_int (POINTER_SIZE), offset;
	      Uint uint_size;

	      if (Is_Derived_Type (gnat_entity))
		{
		  Entity_Id gnat_parent = Etype (Base_Type (gnat_entity));
		  offset = UI_To_gnu (Esize (gnat_parent), bitsizetype);
		  Set_Alignment (gnat_entity, Alignment (gnat_parent));
		}
	      else
		offset = pointer_size;

	      if (TYPE_FIELDS (gnu_type))
		offset
		  = round_up (offset, DECL_ALIGN (TYPE_FIELDS (gnu_type)));

	      gnu_size = size_binop (PLUS_EXPR, gnu_size, offset);
	      gnu_size = round_up (gnu_size, POINTER_SIZE);
	      uint_size = annotate_value (gnu_size);
	      Set_Esize (gnat_entity, uint_size);
	      Set_RM_Size (gnat_entity, uint_size);
	    }
	  else
	    Set_Esize (gnat_entity, annotate_value (gnu_size));
	}

      if (Unknown_RM_Size (gnat_entity) && rm_size (gnu_type))
	Set_RM_Size (gnat_entity, annotate_value (rm_size (gnu_type)));
    }

  /* If we really have a ..._DECL node, set a couple of flags on it.  But we
     cannot do so if we are reusing the ..._DECL node made for an equivalent
     type or an alias or a renamed object as the predicates don't apply to it
     but to GNAT_ENTITY.  */
  if (DECL_P (gnu_decl)
      && !(is_type && gnat_equiv_type != gnat_entity)
      && !Present (Alias (gnat_entity))
      && !(Present (Renamed_Object (gnat_entity)) && saved))
    {
      if (!Comes_From_Source (gnat_entity))
	DECL_ARTIFICIAL (gnu_decl) = 1;

      if (!debug_info_p)
	DECL_IGNORED_P (gnu_decl) = 1;
    }

  /* If we haven't already, associate the ..._DECL node that we just made with
     the input GNAT entity node.  */
  if (!saved)
    save_gnu_tree (gnat_entity, gnu_decl, false);

  /* If this is an enumeration or floating-point type, we were not able to set
     the bounds since they refer to the type.  These are always static.  */
  if ((kind == E_Enumeration_Type && Present (First_Literal (gnat_entity)))
      || (kind == E_Floating_Point_Type && !Vax_Float (gnat_entity)))
    {
      tree gnu_scalar_type = gnu_type;
      tree gnu_low_bound, gnu_high_bound;

      /* If this is a padded type, we need to use the underlying type.  */
      if (TYPE_IS_PADDING_P (gnu_scalar_type))
	gnu_scalar_type = TREE_TYPE (TYPE_FIELDS (gnu_scalar_type));

      /* If this is a floating point type and we haven't set a floating
	 point type yet, use this in the evaluation of the bounds.  */
      if (!longest_float_type_node && kind == E_Floating_Point_Type)
	longest_float_type_node = gnu_scalar_type;

      gnu_low_bound = gnat_to_gnu (Type_Low_Bound (gnat_entity));
      gnu_high_bound = gnat_to_gnu (Type_High_Bound (gnat_entity));

      if (kind == E_Enumeration_Type)
	{
	  /* Enumeration types have specific RM bounds.  */
	  SET_TYPE_RM_MIN_VALUE (gnu_scalar_type, gnu_low_bound);
	  SET_TYPE_RM_MAX_VALUE (gnu_scalar_type, gnu_high_bound);
	}
      else
	{
	  /* Floating-point types don't have specific RM bounds.  */
	  TYPE_GCC_MIN_VALUE (gnu_scalar_type) = gnu_low_bound;
	  TYPE_GCC_MAX_VALUE (gnu_scalar_type) = gnu_high_bound;
	}
    }

  /* If we deferred processing of incomplete types, re-enable it.  If there
     were no other disables and we have deferred types to process, do so.  */
  if (this_deferred
      && --defer_incomplete_level == 0
      && defer_incomplete_list)
    {
      struct incomplete *p, *next;

      /* We are back to level 0 for the deferring of incomplete types.
	 But processing these incomplete types below may itself require
	 deferring, so preserve what we have and restart from scratch.  */
      p = defer_incomplete_list;
      defer_incomplete_list = NULL;

      for (; p; p = next)
	{
	  next = p->next;

	  if (p->old_type)
	    update_pointer_to (TYPE_MAIN_VARIANT (p->old_type),
			       gnat_to_gnu_type (p->full_type));
	  free (p);
	}
    }

  /* If we are not defining this type, see if it's on one of the lists of
     incomplete types.  If so, handle the list entry now.  */
  if (is_type && !definition)
    {
      struct incomplete *p;

      for (p = defer_incomplete_list; p; p = p->next)
	if (p->old_type && p->full_type == gnat_entity)
	  {
	    update_pointer_to (TYPE_MAIN_VARIANT (p->old_type),
			       TREE_TYPE (gnu_decl));
	    p->old_type = NULL_TREE;
	  }

      for (p = defer_limited_with; p; p = p->next)
	if (p->old_type && Non_Limited_View (p->full_type) == gnat_entity)
	  {
	    update_pointer_to (TYPE_MAIN_VARIANT (p->old_type),
			       TREE_TYPE (gnu_decl));
	    p->old_type = NULL_TREE;
	  }
    }

  if (this_global)
    force_global--;

  /* If this is a packed array type whose original array type is itself
     an Itype without freeze node, make sure the latter is processed.  */
  if (Is_Packed_Array_Type (gnat_entity)
      && Is_Itype (Original_Array_Type (gnat_entity))
      && No (Freeze_Node (Original_Array_Type (gnat_entity)))
      && !present_gnu_tree (Original_Array_Type (gnat_entity)))
    gnat_to_gnu_entity (Original_Array_Type (gnat_entity), NULL_TREE, 0);

  return gnu_decl;
}

/* Similar, but if the returned value is a COMPONENT_REF, return the
   FIELD_DECL.  */

tree
gnat_to_gnu_field_decl (Entity_Id gnat_entity)
{
  tree gnu_field = gnat_to_gnu_entity (gnat_entity, NULL_TREE, 0);

  if (TREE_CODE (gnu_field) == COMPONENT_REF)
    gnu_field = TREE_OPERAND (gnu_field, 1);

  return gnu_field;
}

/* Similar, but GNAT_ENTITY is assumed to refer to a GNAT type.  Return
   the GCC type corresponding to that entity.  */

tree
gnat_to_gnu_type (Entity_Id gnat_entity)
{
  tree gnu_decl;

  /* The back end never attempts to annotate generic types.  */
  if (Is_Generic_Type (gnat_entity) && type_annotate_only)
     return void_type_node;

  gnu_decl = gnat_to_gnu_entity (gnat_entity, NULL_TREE, 0);
  gcc_assert (TREE_CODE (gnu_decl) == TYPE_DECL);

  return TREE_TYPE (gnu_decl);
}

/* Similar, but GNAT_ENTITY is assumed to refer to a GNAT type.  Return
   the unpadded version of the GCC type corresponding to that entity.  */

tree
get_unpadded_type (Entity_Id gnat_entity)
{
  tree type = gnat_to_gnu_type (gnat_entity);

  if (TYPE_IS_PADDING_P (type))
    type = TREE_TYPE (TYPE_FIELDS (type));

  return type;
}

/* Return the DECL associated with the public subprogram GNAT_ENTITY but whose
   type has been changed to that of the parameterless procedure, except if an
   alias is already present, in which case it is returned instead.  */

tree
get_minimal_subprog_decl (Entity_Id gnat_entity)
{
  tree gnu_entity_name, gnu_ext_name;
  struct attrib *attr_list = NULL;

  /* See the E_Function/E_Procedure case of gnat_to_gnu_entity for the model
     of the handling applied here.  */

  while (Present (Alias (gnat_entity)))
    {
      gnat_entity = Alias (gnat_entity);
      if (present_gnu_tree (gnat_entity))
	return get_gnu_tree (gnat_entity);
    }

  gnu_entity_name = get_entity_name (gnat_entity);
  gnu_ext_name = create_concat_name (gnat_entity, NULL);

  if (Has_Stdcall_Convention (gnat_entity))
    prepend_one_attribute_to (&attr_list, ATTR_MACHINE_ATTRIBUTE,
			      get_identifier ("stdcall"), NULL_TREE,
			      gnat_entity);
  else if (Has_Thiscall_Convention (gnat_entity))
    prepend_one_attribute_to (&attr_list, ATTR_MACHINE_ATTRIBUTE,
			      get_identifier ("thiscall"), NULL_TREE,
			      gnat_entity);

  if (No (Interface_Name (gnat_entity)) && gnu_ext_name == gnu_entity_name)
    gnu_ext_name = NULL_TREE;

  return
    create_subprog_decl (gnu_entity_name, gnu_ext_name, void_ftype, NULL_TREE,
			 false, true, true, true, attr_list, gnat_entity);
}

/* Return whether the E_Subprogram_Type/E_Function/E_Procedure GNAT_ENTITY is
   a C++ imported method or equivalent.

   We use the predicate on 32-bit x86/Windows to find out whether we need to
   use the "thiscall" calling convention for GNAT_ENTITY.  This convention is
   used for C++ methods (functions with METHOD_TYPE) by the back-end.  */

bool
is_cplusplus_method (Entity_Id gnat_entity)
{
  if (Convention (gnat_entity) != Convention_CPP)
    return False;

  /* This is the main case: C++ method imported as a primitive operation.  */
  if (Is_Dispatching_Operation (gnat_entity))
    return True;

  /* A thunk needs to be handled like its associated primitive operation.  */
  if (Is_Subprogram (gnat_entity) && Is_Thunk (gnat_entity))
    return True;

  /* C++ classes with no virtual functions can be imported as limited
     record types, but we need to return true for the constructors.  */
  if (Is_Constructor (gnat_entity))
    return True;

  /* This is set on the E_Subprogram_Type built for a dispatching call.  */
  if (Is_Dispatch_Table_Entity (gnat_entity))
    return True;

  return False;
}

/* Finalize the processing of From_With_Type incomplete types.  */

void
finalize_from_with_types (void)
{
  struct incomplete *p, *next;

  p = defer_limited_with;
  defer_limited_with = NULL;

  for (; p; p = next)
    {
      next = p->next;

      if (p->old_type)
	update_pointer_to (TYPE_MAIN_VARIANT (p->old_type),
			   gnat_to_gnu_type (p->full_type));
      free (p);
    }
}

/* Return the equivalent type to be used for GNAT_ENTITY, if it's a
   kind of type (such E_Task_Type) that has a different type which Gigi
   uses for its representation.  If the type does not have a special type
   for its representation, return GNAT_ENTITY.  If a type is supposed to
   exist, but does not, abort unless annotating types, in which case
   return Empty.  If GNAT_ENTITY is Empty, return Empty.  */

Entity_Id
Gigi_Equivalent_Type (Entity_Id gnat_entity)
{
  Entity_Id gnat_equiv = gnat_entity;

  if (No (gnat_entity))
    return gnat_entity;

  switch (Ekind (gnat_entity))
    {
    case E_Class_Wide_Subtype:
      if (Present (Equivalent_Type (gnat_entity)))
	gnat_equiv = Equivalent_Type (gnat_entity);
      break;

    case E_Access_Protected_Subprogram_Type:
    case E_Anonymous_Access_Protected_Subprogram_Type:
      gnat_equiv = Equivalent_Type (gnat_entity);
      break;

    case E_Class_Wide_Type:
      gnat_equiv = Root_Type (gnat_entity);
      break;

    case E_Task_Type:
    case E_Task_Subtype:
    case E_Protected_Type:
    case E_Protected_Subtype:
      gnat_equiv = Corresponding_Record_Type (gnat_entity);
      break;

    default:
      break;
    }

  gcc_assert (Present (gnat_equiv) || type_annotate_only);

  return gnat_equiv;
}

/* Return a GCC tree for a type corresponding to the component type of the
   array type or subtype GNAT_ARRAY.  DEFINITION is true if this component
   is for an array being defined.  DEBUG_INFO_P is true if we need to write
   debug information for other types that we may create in the process.  */

static tree
gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
			    bool debug_info_p)
{
  const Entity_Id gnat_type = Component_Type (gnat_array);
  tree gnu_type = gnat_to_gnu_type (gnat_type);
  tree gnu_comp_size;

  /* Try to get a smaller form of the component if needed.  */
  if ((Is_Packed (gnat_array)
       || Has_Component_Size_Clause (gnat_array))
      && !Is_Bit_Packed_Array (gnat_array)
      && !Has_Aliased_Components (gnat_array)
      && !Strict_Alignment (gnat_type)
      && RECORD_OR_UNION_TYPE_P (gnu_type)
      && !TYPE_FAT_POINTER_P (gnu_type)
      && host_integerp (TYPE_SIZE (gnu_type), 1))
    gnu_type = make_packable_type (gnu_type, false);

  if (Has_Atomic_Components (gnat_array))
    check_ok_for_atomic (gnu_type, gnat_array, true);

  /* Get and validate any specified Component_Size.  */
  gnu_comp_size
    = validate_size (Component_Size (gnat_array), gnu_type, gnat_array,
		     Is_Bit_Packed_Array (gnat_array) ? TYPE_DECL : VAR_DECL,
		     true, Has_Component_Size_Clause (gnat_array));

  /* If the array has aliased components and the component size can be zero,
     force at least unit size to ensure that the components have distinct
     addresses.  */
  if (!gnu_comp_size
      && Has_Aliased_Components (gnat_array)
      && (integer_zerop (TYPE_SIZE (gnu_type))
	  || (TREE_CODE (gnu_type) == ARRAY_TYPE
	      && !TREE_CONSTANT (TYPE_SIZE (gnu_type)))))
    gnu_comp_size
      = size_binop (MAX_EXPR, TYPE_SIZE (gnu_type), bitsize_unit_node);

  /* If the component type is a RECORD_TYPE that has a self-referential size,
     then use the maximum size for the component size.  */
  if (!gnu_comp_size
      && TREE_CODE (gnu_type) == RECORD_TYPE
      && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type)))
    gnu_comp_size = max_size (TYPE_SIZE (gnu_type), true);

  /* Honor the component size.  This is not needed for bit-packed arrays.  */
  if (gnu_comp_size && !Is_Bit_Packed_Array (gnat_array))
    {
      tree orig_type = gnu_type;
      unsigned int max_align;

      /* If an alignment is specified, use it as a cap on the component type
	 so that it can be honored for the whole type.  But ignore it for the
	 original type of packed array types.  */
      if (No (Packed_Array_Type (gnat_array)) && Known_Alignment (gnat_array))
	max_align = validate_alignment (Alignment (gnat_array), gnat_array, 0);
      else
	max_align = 0;

      gnu_type = make_type_from_size (gnu_type, gnu_comp_size, false);
      if (max_align > 0 && TYPE_ALIGN (gnu_type) > max_align)
	gnu_type = orig_type;
      else
	orig_type = gnu_type;

      gnu_type = maybe_pad_type (gnu_type, gnu_comp_size, 0, gnat_array,
				 true, false, definition, true);

      /* If a padding record was made, declare it now since it will never be
	 declared otherwise.  This is necessary to ensure that its subtrees
	 are properly marked.  */
      if (gnu_type != orig_type && !DECL_P (TYPE_NAME (gnu_type)))
	create_type_decl (TYPE_NAME (gnu_type), gnu_type, NULL, true,
			  debug_info_p, gnat_array);
    }

  if (Has_Volatile_Components (gnat_array))
    gnu_type
      = build_qualified_type (gnu_type,
			      TYPE_QUALS (gnu_type) | TYPE_QUAL_VOLATILE);

  return gnu_type;
}

/* Return a GCC tree for a parameter corresponding to GNAT_PARAM and
   using MECH as its passing mechanism, to be placed in the parameter
   list built for GNAT_SUBPROG.  Assume a foreign convention for the
   latter if FOREIGN is true.  Also set CICO to true if the parameter
   must use the copy-in copy-out implementation mechanism.

   The returned tree is a PARM_DECL, except for those cases where no
   parameter needs to be actually passed to the subprogram; the type
   of this "shadow" parameter is then returned instead.  */

static tree
gnat_to_gnu_param (Entity_Id gnat_param, Mechanism_Type mech,
		   Entity_Id gnat_subprog, bool foreign, bool *cico)
{
  tree gnu_param_name = get_entity_name (gnat_param);
  tree gnu_param_type = gnat_to_gnu_type (Etype (gnat_param));
  tree gnu_param_type_alt = NULL_TREE;
  bool in_param = (Ekind (gnat_param) == E_In_Parameter);
  /* The parameter can be indirectly modified if its address is taken.  */
  bool ro_param = in_param && !Address_Taken (gnat_param);
  bool by_return = false, by_component_ptr = false;
  bool by_ref = false;
  tree gnu_param;

  /* Copy-return is used only for the first parameter of a valued procedure.
     It's a copy mechanism for which a parameter is never allocated.  */
  if (mech == By_Copy_Return)
    {
      gcc_assert (Ekind (gnat_param) == E_Out_Parameter);
      mech = By_Copy;
      by_return = true;
    }

  /* If this is either a foreign function or if the underlying type won't
     be passed by reference, strip off possible padding type.  */
  if (TYPE_IS_PADDING_P (gnu_param_type))
    {
      tree unpadded_type = TREE_TYPE (TYPE_FIELDS (gnu_param_type));

      if (mech == By_Reference
	  || foreign
	  || (!must_pass_by_ref (unpadded_type)
	      && (mech == By_Copy || !default_pass_by_ref (unpadded_type))))
	gnu_param_type = unpadded_type;
    }

  /* If this is a read-only parameter, make a variant of the type that is
     read-only.  ??? However, if this is an unconstrained array, that type
     can be very complex, so skip it for now.  Likewise for any other
     self-referential type.  */
  if (ro_param
      && TREE_CODE (gnu_param_type) != UNCONSTRAINED_ARRAY_TYPE
      && !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_param_type)))
    gnu_param_type = build_qualified_type (gnu_param_type,
					   (TYPE_QUALS (gnu_param_type)
					    | TYPE_QUAL_CONST));

  /* For foreign conventions, pass arrays as pointers to the element type.
     First check for unconstrained array and get the underlying array.  */
  if (foreign && TREE_CODE (gnu_param_type) == UNCONSTRAINED_ARRAY_TYPE)
    gnu_param_type
      = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_param_type))));

  /* For GCC builtins, pass Address integer types as (void *)  */
  if (Convention (gnat_subprog) == Convention_Intrinsic
      && Present (Interface_Name (gnat_subprog))
      && Is_Descendent_Of_Address (Etype (gnat_param)))
    gnu_param_type = ptr_void_type_node;

  /* VMS descriptors are themselves passed by reference.  */
  if (mech == By_Short_Descriptor ||
      (mech == By_Descriptor && TARGET_ABI_OPEN_VMS && !flag_vms_malloc64))
    gnu_param_type
      = build_pointer_type (build_vms_descriptor32 (gnu_param_type,
						    Mechanism (gnat_param),
						    gnat_subprog));
  else if (mech == By_Descriptor)
    {
      /* Build both a 32-bit and 64-bit descriptor, one of which will be
	 chosen in fill_vms_descriptor.  */
      gnu_param_type_alt
        = build_pointer_type (build_vms_descriptor32 (gnu_param_type,
						      Mechanism (gnat_param),
						      gnat_subprog));
      gnu_param_type
        = build_pointer_type (build_vms_descriptor (gnu_param_type,
						    Mechanism (gnat_param),
						    gnat_subprog));
    }

  /* Arrays are passed as pointers to element type for foreign conventions.  */
  else if (foreign
	   && mech != By_Copy
	   && TREE_CODE (gnu_param_type) == ARRAY_TYPE)
    {
      /* Strip off any multi-dimensional entries, then strip
	 off the last array to get the component type.  */
      while (TREE_CODE (TREE_TYPE (gnu_param_type)) == ARRAY_TYPE
	     && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_param_type)))
	gnu_param_type = TREE_TYPE (gnu_param_type);

      by_component_ptr = true;
      gnu_param_type = TREE_TYPE (gnu_param_type);

      if (ro_param)
	gnu_param_type = build_qualified_type (gnu_param_type,
					       (TYPE_QUALS (gnu_param_type)
						| TYPE_QUAL_CONST));

      gnu_param_type = build_pointer_type (gnu_param_type);
    }

  /* Fat pointers are passed as thin pointers for foreign conventions.  */
  else if (foreign && TYPE_IS_FAT_POINTER_P (gnu_param_type))
    gnu_param_type
      = make_type_from_size (gnu_param_type, size_int (POINTER_SIZE), 0);

  /* If we must pass or were requested to pass by reference, do so.
     If we were requested to pass by copy, do so.
     Otherwise, for foreign conventions, pass In Out or Out parameters
     or aggregates by reference.  For COBOL and Fortran, pass all
     integer and FP types that way too.  For Convention Ada, use
     the standard Ada default.  */
  else if (must_pass_by_ref (gnu_param_type)
	   || mech == By_Reference
	   || (mech != By_Copy
	       && ((foreign
		    && (!in_param || AGGREGATE_TYPE_P (gnu_param_type)))
		   || (foreign
		       && (Convention (gnat_subprog) == Convention_Fortran
			   || Convention (gnat_subprog) == Convention_COBOL)
		       && (INTEGRAL_TYPE_P (gnu_param_type)
			   || FLOAT_TYPE_P (gnu_param_type)))
		   || (!foreign
		       && default_pass_by_ref (gnu_param_type)))))
    {
      /* We take advantage of 6.2(12) by considering that references built for
	 parameters whose type isn't by-ref and for which the mechanism hasn't
	 been forced to by-ref are restrict-qualified in the C sense.  */
      bool restrict_p
	= !TYPE_IS_BY_REFERENCE_P (gnu_param_type) && mech != By_Reference;
      gnu_param_type = build_reference_type (gnu_param_type);
      if (restrict_p)
	gnu_param_type
	  = build_qualified_type (gnu_param_type, TYPE_QUAL_RESTRICT);
      by_ref = true;
    }

  /* Pass In Out or Out parameters using copy-in copy-out mechanism.  */
  else if (!in_param)
    *cico = true;

  if (mech == By_Copy && (by_ref || by_component_ptr))
    post_error ("?cannot pass & by copy", gnat_param);

  /* If this is an Out parameter that isn't passed by reference and isn't
     a pointer or aggregate, we don't make a PARM_DECL for it.  Instead,
     it will be a VAR_DECL created when we process the procedure, so just
     return its type.  For the special parameter of a valued procedure,
     never pass it in.

     An exception is made to cover the RM-6.4.1 rule requiring "by copy"
     Out parameters with discriminants or implicit initial values to be
     handled like In Out parameters.  These type are normally built as
     aggregates, hence passed by reference, except for some packed arrays
     which end up encoded in special integer types.

     The exception we need to make is then for packed arrays of records
     with discriminants or implicit initial values.  We have no light/easy
     way to check for the latter case, so we merely check for packed arrays
     of records.  This may lead to useless copy-in operations, but in very
     rare cases only, as these would be exceptions in a set of already
     exceptional situations.  */
  if (Ekind (gnat_param) == E_Out_Parameter
      && !by_ref
      && (by_return
	  || (mech != By_Descriptor
              && mech != By_Short_Descriptor
	      && !POINTER_TYPE_P (gnu_param_type)
	      && !AGGREGATE_TYPE_P (gnu_param_type)))
      && !(Is_Array_Type (Etype (gnat_param))
	   && Is_Packed (Etype (gnat_param))
	   && Is_Composite_Type (Component_Type (Etype (gnat_param)))))
    return gnu_param_type;

  gnu_param = create_param_decl (gnu_param_name, gnu_param_type,
				 ro_param || by_ref || by_component_ptr);
  DECL_BY_REF_P (gnu_param) = by_ref;
  DECL_BY_COMPONENT_PTR_P (gnu_param) = by_component_ptr;
  DECL_BY_DESCRIPTOR_P (gnu_param) = (mech == By_Descriptor ||
                                      mech == By_Short_Descriptor);
  /* Note that, in case of a parameter passed by double reference, the
     DECL_POINTS_TO_READONLY_P flag is meant for the second reference.
     The first reference always points to read-only, as it points to
     the second reference, i.e. the reference to the actual parameter.  */
  DECL_POINTS_TO_READONLY_P (gnu_param)
    = (ro_param && (by_ref || by_component_ptr));
  DECL_CAN_NEVER_BE_NULL_P (gnu_param) = Can_Never_Be_Null (gnat_param);

  /* Save the alternate descriptor type, if any.  */
  if (gnu_param_type_alt)
    SET_DECL_PARM_ALT_TYPE (gnu_param, gnu_param_type_alt);

  /* If no Mechanism was specified, indicate what we're using, then
     back-annotate it.  */
  if (mech == Default)
    mech = (by_ref || by_component_ptr) ? By_Reference : By_Copy;

  Set_Mechanism (gnat_param, mech);
  return gnu_param;
}

/* Return true if DISCR1 and DISCR2 represent the same discriminant.  */

static bool
same_discriminant_p (Entity_Id discr1, Entity_Id discr2)
{
  while (Present (Corresponding_Discriminant (discr1)))
    discr1 = Corresponding_Discriminant (discr1);

  while (Present (Corresponding_Discriminant (discr2)))
    discr2 = Corresponding_Discriminant (discr2);

  return
    Original_Record_Component (discr1) == Original_Record_Component (discr2);
}

/* Return true if the array type GNU_TYPE, which represents a dimension of
   GNAT_TYPE, has a non-aliased component in the back-end sense.  */

static bool
array_type_has_nonaliased_component (tree gnu_type, Entity_Id gnat_type)
{
  /* If the array type is not the innermost dimension of the GNAT type,
     then it has a non-aliased component.  */
  if (TREE_CODE (TREE_TYPE (gnu_type)) == ARRAY_TYPE
      && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type)))
    return true;

  /* If the array type has an aliased component in the front-end sense,
     then it also has an aliased component in the back-end sense.  */
  if (Has_Aliased_Components (gnat_type))
    return false;

  /* If this is a derived type, then it has a non-aliased component if
     and only if its parent type also has one.  */
  if (Is_Derived_Type (gnat_type))
    {
      tree gnu_parent_type = gnat_to_gnu_type (Etype (gnat_type));
      int index;
      if (TREE_CODE (gnu_parent_type) == UNCONSTRAINED_ARRAY_TYPE)
	gnu_parent_type
	  = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_parent_type))));
      for (index = Number_Dimensions (gnat_type) - 1; index > 0; index--)
	gnu_parent_type = TREE_TYPE (gnu_parent_type);
      return TYPE_NONALIASED_COMPONENT (gnu_parent_type);
    }

  /* Otherwise, rely exclusively on properties of the element type.  */
  return type_for_nonaliased_component_p (TREE_TYPE (gnu_type));
}

/* Return true if GNAT_ADDRESS is a value known at compile-time.  */

static bool
compile_time_known_address_p (Node_Id gnat_address)
{
  /* Catch System'To_Address.  */
  if (Nkind (gnat_address) == N_Unchecked_Type_Conversion)
    gnat_address = Expression (gnat_address);

  return Compile_Time_Known_Value (gnat_address);
}

/* Return true if GNAT_RANGE, a N_Range node, cannot be superflat, i.e. if the
   inequality HB >= LB-1 is true.  LB and HB are the low and high bounds.  */

static bool
cannot_be_superflat_p (Node_Id gnat_range)
{
  Node_Id gnat_lb = Low_Bound (gnat_range), gnat_hb = High_Bound (gnat_range);
  Node_Id scalar_range;
  tree gnu_lb, gnu_hb, gnu_lb_minus_one;

  /* If the low bound is not constant, try to find an upper bound.  */
  while (Nkind (gnat_lb) != N_Integer_Literal
	 && (Ekind (Etype (gnat_lb)) == E_Signed_Integer_Subtype
	     || Ekind (Etype (gnat_lb)) == E_Modular_Integer_Subtype)
	 && (scalar_range = Scalar_Range (Etype (gnat_lb)))
	 && (Nkind (scalar_range) == N_Signed_Integer_Type_Definition
	     || Nkind (scalar_range) == N_Range))
    gnat_lb = High_Bound (scalar_range);

  /* If the high bound is not constant, try to find a lower bound.  */
  while (Nkind (gnat_hb) != N_Integer_Literal
	 && (Ekind (Etype (gnat_hb)) == E_Signed_Integer_Subtype
	     || Ekind (Etype (gnat_hb)) == E_Modular_Integer_Subtype)
	 && (scalar_range = Scalar_Range (Etype (gnat_hb)))
	 && (Nkind (scalar_range) == N_Signed_Integer_Type_Definition
	     || Nkind (scalar_range) == N_Range))
    gnat_hb = Low_Bound (scalar_range);

  /* If we have failed to find constant bounds, punt.  */
  if (Nkind (gnat_lb) != N_Integer_Literal
      || Nkind (gnat_hb) != N_Integer_Literal)
    return false;

  /* We need at least a signed 64-bit type to catch most cases.  */
  gnu_lb = UI_To_gnu (Intval (gnat_lb), sbitsizetype);
  gnu_hb = UI_To_gnu (Intval (gnat_hb), sbitsizetype);
  if (TREE_OVERFLOW (gnu_lb) || TREE_OVERFLOW (gnu_hb))
    return false;

  /* If the low bound is the smallest integer, nothing can be smaller.  */
  gnu_lb_minus_one = size_binop (MINUS_EXPR, gnu_lb, sbitsize_one_node);
  if (TREE_OVERFLOW (gnu_lb_minus_one))
    return true;

  return !tree_int_cst_lt (gnu_hb, gnu_lb_minus_one);
}

/* Return true if GNU_EXPR is (essentially) the address of a CONSTRUCTOR.  */

static bool
constructor_address_p (tree gnu_expr)
{
  while (TREE_CODE (gnu_expr) == NOP_EXPR
	 || TREE_CODE (gnu_expr) == CONVERT_EXPR
	 || TREE_CODE (gnu_expr) == NON_LVALUE_EXPR)
    gnu_expr = TREE_OPERAND (gnu_expr, 0);

  return (TREE_CODE (gnu_expr) == ADDR_EXPR
	  && TREE_CODE (TREE_OPERAND (gnu_expr, 0)) == CONSTRUCTOR);
}

/* Given GNAT_ENTITY, elaborate all expressions that are required to
   be elaborated at the point of its definition, but do nothing else.  */

void
elaborate_entity (Entity_Id gnat_entity)
{
  switch (Ekind (gnat_entity))
    {
    case E_Signed_Integer_Subtype:
    case E_Modular_Integer_Subtype:
    case E_Enumeration_Subtype:
    case E_Ordinary_Fixed_Point_Subtype:
    case E_Decimal_Fixed_Point_Subtype:
    case E_Floating_Point_Subtype:
      {
	Node_Id gnat_lb = Type_Low_Bound (gnat_entity);
	Node_Id gnat_hb = Type_High_Bound (gnat_entity);

	/* ??? Tests to avoid Constraint_Error in static expressions
	   are needed until after the front stops generating bogus
	   conversions on bounds of real types.  */
	if (!Raises_Constraint_Error (gnat_lb))
	  elaborate_expression (gnat_lb, gnat_entity, get_identifier ("L"),
				true, false, Needs_Debug_Info (gnat_entity));
	if (!Raises_Constraint_Error (gnat_hb))
	  elaborate_expression (gnat_hb, gnat_entity, get_identifier ("U"),
				true, false, Needs_Debug_Info (gnat_entity));
      break;
      }

    case E_Record_Subtype:
    case E_Private_Subtype:
    case E_Limited_Private_Subtype:
    case E_Record_Subtype_With_Private:
      if (Has_Discriminants (gnat_entity) && Is_Constrained (gnat_entity))
	{
	  Node_Id gnat_discriminant_expr;
	  Entity_Id gnat_field;

	  for (gnat_field
	       = First_Discriminant (Implementation_Base_Type (gnat_entity)),
	       gnat_discriminant_expr
	       = First_Elmt (Discriminant_Constraint (gnat_entity));
	       Present (gnat_field);
	       gnat_field = Next_Discriminant (gnat_field),
	       gnat_discriminant_expr = Next_Elmt (gnat_discriminant_expr))
	    /* ??? For now, ignore access discriminants.  */
	    if (!Is_Access_Type (Etype (Node (gnat_discriminant_expr))))
	      elaborate_expression (Node (gnat_discriminant_expr),
				    gnat_entity, get_entity_name (gnat_field),
				    true, false, false);
	}
      break;

    }
}

/* Return true if the size in units represented by GNU_SIZE can be handled by
   an allocation.  If STATIC_P is true, consider only what can be done with a
   static allocation.  */

static bool
allocatable_size_p (tree gnu_size, bool static_p)
{
  /* We can allocate a fixed size if it is a valid for the middle-end.  */
  if (TREE_CODE (gnu_size) == INTEGER_CST)
    return valid_constant_size_p (gnu_size);

  /* We can allocate a variable size if this isn't a static allocation.  */
  else
    return !static_p;
}

/* Prepend to ATTR_LIST an entry for an attribute with provided TYPE,
   NAME, ARGS and ERROR_POINT.  */

static void
prepend_one_attribute_to (struct attrib ** attr_list,
			  enum attr_type attr_type,
			  tree attr_name,
			  tree attr_args,
			  Node_Id attr_error_point)
{
  struct attrib * attr = (struct attrib *) xmalloc (sizeof (struct attrib));

  attr->type = attr_type;
  attr->name = attr_name;
  attr->args = attr_args;
  attr->error_point = attr_error_point;

  attr->next = *attr_list;
  *attr_list = attr;
}

/* Prepend to ATTR_LIST the list of attributes for GNAT_ENTITY, if any.  */

static void
prepend_attributes (Entity_Id gnat_entity, struct attrib ** attr_list)
{
  Node_Id gnat_temp;

  /* Attributes are stored as Representation Item pragmas.  */

  for (gnat_temp = First_Rep_Item (gnat_entity); Present (gnat_temp);
       gnat_temp = Next_Rep_Item (gnat_temp))
    if (Nkind (gnat_temp) == N_Pragma)
      {
	tree gnu_arg0 = NULL_TREE, gnu_arg1 = NULL_TREE;
	Node_Id gnat_assoc = Pragma_Argument_Associations (gnat_temp);
	enum attr_type etype;

	/* Map the kind of pragma at hand.  Skip if this is not one
	   we know how to handle.  */

	switch (Get_Pragma_Id (Chars (Pragma_Identifier (gnat_temp))))
	  {
	  case Pragma_Machine_Attribute:
	    etype = ATTR_MACHINE_ATTRIBUTE;
	    break;

	  case Pragma_Linker_Alias:
	    etype = ATTR_LINK_ALIAS;
	    break;

	  case Pragma_Linker_Section:
	    etype = ATTR_LINK_SECTION;
	    break;

	  case Pragma_Linker_Constructor:
	    etype = ATTR_LINK_CONSTRUCTOR;
	    break;

	  case Pragma_Linker_Destructor:
	    etype = ATTR_LINK_DESTRUCTOR;
	    break;

	  case Pragma_Weak_External:
	    etype = ATTR_WEAK_EXTERNAL;
	    break;

	  case Pragma_Thread_Local_Storage:
	    etype = ATTR_THREAD_LOCAL_STORAGE;
	    break;

	  default:
	    continue;
	  }

	/* See what arguments we have and turn them into GCC trees for
	   attribute handlers.  These expect identifier for strings.  We
	   handle at most two arguments, static expressions only.  */

	if (Present (gnat_assoc) && Present (First (gnat_assoc)))
	  {
	    Node_Id gnat_arg0 = Next (First (gnat_assoc));
	    Node_Id gnat_arg1 = Empty;

	    if (Present (gnat_arg0)
		&& Is_Static_Expression (Expression (gnat_arg0)))
	      {
		gnu_arg0 = gnat_to_gnu (Expression (gnat_arg0));

		if (TREE_CODE (gnu_arg0) == STRING_CST)
		  gnu_arg0 = get_identifier (TREE_STRING_POINTER (gnu_arg0));

		gnat_arg1 = Next (gnat_arg0);
	      }

	    if (Present (gnat_arg1)
		&& Is_Static_Expression (Expression (gnat_arg1)))
	      {
		gnu_arg1 = gnat_to_gnu (Expression (gnat_arg1));

		if (TREE_CODE (gnu_arg1) == STRING_CST)
		  gnu_arg1 = get_identifier (TREE_STRING_POINTER (gnu_arg1));
	      }
	  }

	/* Prepend to the list now.  Make a list of the argument we might
	   have, as GCC expects it.  */
	prepend_one_attribute_to
	  (attr_list,
	   etype, gnu_arg0,
	   (gnu_arg1 != NULL_TREE)
	   ? build_tree_list (NULL_TREE, gnu_arg1) : NULL_TREE,
	   Present (Next (First (gnat_assoc)))
	   ? Expression (Next (First (gnat_assoc))) : gnat_temp);
      }
}

/* Given a GNAT tree GNAT_EXPR, for an expression which is a value within a
   type definition (either a bound or a discriminant value) for GNAT_ENTITY,
   return the GCC tree to use for that expression.  GNU_NAME is the suffix
   to use if a variable needs to be created and DEFINITION is true if this
   is a definition of GNAT_ENTITY.  If NEED_VALUE is true, we need a result;
   otherwise, we are just elaborating the expression for side-effects.  If
   NEED_DEBUG is true, we need a variable for debugging purposes even if it
   isn't needed for code generation.  */

static tree
elaborate_expression (Node_Id gnat_expr, Entity_Id gnat_entity, tree gnu_name,
		      bool definition, bool need_value, bool need_debug)
{
  tree gnu_expr;

  /* If we already elaborated this expression (e.g. it was involved
     in the definition of a private type), use the old value.  */
  if (present_gnu_tree (gnat_expr))
    return get_gnu_tree (gnat_expr);

  /* If we don't need a value and this is static or a discriminant,
     we don't need to do anything.  */
  if (!need_value
      && (Is_OK_Static_Expression (gnat_expr)
	  || (Nkind (gnat_expr) == N_Identifier
	      && Ekind (Entity (gnat_expr)) == E_Discriminant)))
    return NULL_TREE;

  /* If it's a static expression, we don't need a variable for debugging.  */
  if (need_debug && Is_OK_Static_Expression (gnat_expr))
    need_debug = false;

  /* Otherwise, convert this tree to its GCC equivalent and elaborate it.  */
  gnu_expr = elaborate_expression_1 (gnat_to_gnu (gnat_expr), gnat_entity,
				     gnu_name, definition, need_debug);

  /* Save the expression in case we try to elaborate this entity again.  Since
     it's not a DECL, don't check it.  Don't save if it's a discriminant.  */
  if (!CONTAINS_PLACEHOLDER_P (gnu_expr))
    save_gnu_tree (gnat_expr, gnu_expr, true);

  return need_value ? gnu_expr : error_mark_node;
}

/* Similar, but take a GNU expression and always return a result.  */

static tree
elaborate_expression_1 (tree gnu_expr, Entity_Id gnat_entity, tree gnu_name,
			bool definition, bool need_debug)
{
  const bool expr_public_p = Is_Public (gnat_entity);
  const bool expr_global_p = expr_public_p || global_bindings_p ();
  bool expr_variable_p, use_variable;

  /* In most cases, we won't see a naked FIELD_DECL because a discriminant
     reference will have been replaced with a COMPONENT_REF when the type
     is being elaborated.  However, there are some cases involving child
     types where we will.  So convert it to a COMPONENT_REF.  We hope it
     will be at the highest level of the expression in these cases.  */
  if (TREE_CODE (gnu_expr) == FIELD_DECL)
    gnu_expr = build3 (COMPONENT_REF, TREE_TYPE (gnu_expr),
		       build0 (PLACEHOLDER_EXPR, DECL_CONTEXT (gnu_expr)),
		       gnu_expr, NULL_TREE);

  /* If GNU_EXPR contains a placeholder, just return it.  We rely on the fact
     that an expression cannot contain both a discriminant and a variable.  */
  if (CONTAINS_PLACEHOLDER_P (gnu_expr))
    return gnu_expr;

  /* If GNU_EXPR is neither a constant nor based on a read-only variable, make
     a variable that is initialized to contain the expression when the package
     containing the definition is elaborated.  If this entity is defined at top
     level, replace the expression by the variable; otherwise use a SAVE_EXPR
     if this is necessary.  */
  if (CONSTANT_CLASS_P (gnu_expr))
    expr_variable_p = false;
  else
    {
      /* Skip any conversions and simple arithmetics to see if the expression
	 is based on a read-only variable.
	 ??? This really should remain read-only, but we have to think about
	 the typing of the tree here.  */
      tree inner
	= skip_simple_arithmetic (remove_conversions (gnu_expr, true));

      if (handled_component_p (inner))
	{
	  HOST_WIDE_INT bitsize, bitpos;
	  tree offset;
	  enum machine_mode mode;
	  int unsignedp, volatilep;

	  inner = get_inner_reference (inner, &bitsize, &bitpos, &offset,
				       &mode, &unsignedp, &volatilep, false);
	  /* If the offset is variable, err on the side of caution.  */
	  if (offset)
	    inner = NULL_TREE;
	}

      expr_variable_p
	= !(inner
	    && TREE_CODE (inner) == VAR_DECL
	    && (TREE_READONLY (inner) || DECL_READONLY_ONCE_ELAB (inner)));
    }

  /* We only need to use the variable if we are in a global context since GCC
     can do the right thing in the local case.  However, when not optimizing,
     use it for bounds of loop iteration scheme to avoid code duplication.  */
  use_variable = expr_variable_p
		 && (expr_global_p
		     || (!optimize
		         && definition
			 && Is_Itype (gnat_entity)
			 && Nkind (Associated_Node_For_Itype (gnat_entity))
			    == N_Loop_Parameter_Specification));

  /* Now create it, possibly only for debugging purposes.  */
  if (use_variable || need_debug)
    {
      tree gnu_decl
	= create_var_decl_1
	  (create_concat_name (gnat_entity, IDENTIFIER_POINTER (gnu_name)),
	   NULL_TREE, TREE_TYPE (gnu_expr), gnu_expr, true, expr_public_p,
	   !definition, expr_global_p, !need_debug, NULL, gnat_entity);

      if (use_variable)
	return gnu_decl;
    }

  return expr_variable_p ? gnat_save_expr (gnu_expr) : gnu_expr;
}

/* Similar, but take an alignment factor and make it explicit in the tree.  */

static tree
elaborate_expression_2 (tree gnu_expr, Entity_Id gnat_entity, tree gnu_name,
			bool definition, bool need_debug, unsigned int align)
{
  tree unit_align = size_int (align / BITS_PER_UNIT);
  return
    size_binop (MULT_EXPR,
		elaborate_expression_1 (size_binop (EXACT_DIV_EXPR,
						    gnu_expr,
						    unit_align),
					gnat_entity, gnu_name, definition,
					need_debug),
		unit_align);
}

/* Given a GNU tree and a GNAT list of choices, generate an expression to test
   the value passed against the list of choices.  */

tree
choices_to_gnu (tree operand, Node_Id choices)
{
  Node_Id choice;
  Node_Id gnat_temp;
  tree result = boolean_false_node;
  tree this_test, low = 0, high = 0, single = 0;

  for (choice = First (choices); Present (choice); choice = Next (choice))
    {
      switch (Nkind (choice))
	{
	case N_Range:
	  low = gnat_to_gnu (Low_Bound (choice));
	  high = gnat_to_gnu (High_Bound (choice));

	  this_test
	    = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
			       build_binary_op (GE_EXPR, boolean_type_node,
						operand, low),
			       build_binary_op (LE_EXPR, boolean_type_node,
						operand, high));

	  break;

	case N_Subtype_Indication:
	  gnat_temp = Range_Expression (Constraint (choice));
	  low = gnat_to_gnu (Low_Bound (gnat_temp));
	  high = gnat_to_gnu (High_Bound (gnat_temp));

	  this_test
	    = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
			       build_binary_op (GE_EXPR, boolean_type_node,
						operand, low),
			       build_binary_op (LE_EXPR, boolean_type_node,
						operand, high));
	  break;

	case N_Identifier:
	case N_Expanded_Name:
	  /* This represents either a subtype range, an enumeration
	     literal, or a constant  Ekind says which.  If an enumeration
	     literal or constant, fall through to the next case.  */
	  if (Ekind (Entity (choice)) != E_Enumeration_Literal
	      && Ekind (Entity (choice)) != E_Constant)
	    {
	      tree type = gnat_to_gnu_type (Entity (choice));

	      low = TYPE_MIN_VALUE (type);
	      high = TYPE_MAX_VALUE (type);

	      this_test
		= build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
				   build_binary_op (GE_EXPR, boolean_type_node,
						    operand, low),
				   build_binary_op (LE_EXPR, boolean_type_node,
						    operand, high));
	      break;
	    }

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

	case N_Character_Literal:
	case N_Integer_Literal:
	  single = gnat_to_gnu (choice);
	  this_test = build_binary_op (EQ_EXPR, boolean_type_node, operand,
				       single);
	  break;

	case N_Others_Choice:
	  this_test = boolean_true_node;
	  break;

	default:
	  gcc_unreachable ();
	}

      result = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, result,
				this_test);
    }

  return result;
}

/* Adjust PACKED setting as passed to gnat_to_gnu_field for a field of
   type FIELD_TYPE to be placed in RECORD_TYPE.  Return the result.  */

static int
adjust_packed (tree field_type, tree record_type, int packed)
{
  /* If the field contains an item of variable size, we cannot pack it
     because we cannot create temporaries of non-fixed size in case
     we need to take the address of the field.  See addressable_p and
     the notes on the addressability issues for further details.  */
  if (type_has_variable_size (field_type))
    return 0;

  /* If the alignment of the record is specified and the field type
     is over-aligned, request Storage_Unit alignment for the field.  */
  if (packed == -2)
    {
      if (TYPE_ALIGN (field_type) > TYPE_ALIGN (record_type))
	return -1;
      else
	return 0;
    }

  return packed;
}

/* Return a GCC tree for a field corresponding to GNAT_FIELD to be
   placed in GNU_RECORD_TYPE.

   PACKED is 1 if the enclosing record is packed, -1 if the enclosing
   record has Component_Alignment of Storage_Unit, -2 if the enclosing
   record has a specified alignment.

   DEFINITION is true if this field is for a record being defined.

   DEBUG_INFO_P is true if we need to write debug information for types
   that we may create in the process.  */

static tree
gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
		   bool definition, bool debug_info_p)
{
  const Entity_Id gnat_field_type = Etype (gnat_field);
  tree gnu_field_type = gnat_to_gnu_type (gnat_field_type);
  tree gnu_field_id = get_entity_name (gnat_field);
  tree gnu_field, gnu_size, gnu_pos;
  bool is_volatile
    = (Treat_As_Volatile (gnat_field) || Treat_As_Volatile (gnat_field_type));
  bool needs_strict_alignment
    = (is_volatile
       || Is_Aliased (gnat_field)
       || Strict_Alignment (gnat_field_type));

  /* If this field requires strict alignment, we cannot pack it because
     it would very likely be under-aligned in the record.  */
  if (needs_strict_alignment)
    packed = 0;
  else
    packed = adjust_packed (gnu_field_type, gnu_record_type, packed);

  /* If a size is specified, use it.  Otherwise, if the record type is packed,
     use the official RM size.  See "Handling of Type'Size Values" in Einfo
     for further details.  */
  if (Known_Esize (gnat_field))
    gnu_size = validate_size (Esize (gnat_field), gnu_field_type,
			      gnat_field, FIELD_DECL, false, true);
  else if (packed == 1)
    gnu_size = validate_size (RM_Size (gnat_field_type), gnu_field_type,
			      gnat_field, FIELD_DECL, false, true);
  else
    gnu_size = NULL_TREE;

  /* If we have a specified size that is smaller than that of the field's type,
     or a position is specified, and the field's type is a record that doesn't
     require strict alignment, see if we can get either an integral mode form
     of the type or a smaller form.  If we can, show a size was specified for
     the field if there wasn't one already, so we know to make this a bitfield
     and avoid making things wider.

     Changing to an integral mode form is useful when the record is packed as
     we can then place the field at a non-byte-aligned position and so achieve
     tighter packing.  This is in addition required if the field shares a byte
     with another field and the front-end lets the back-end handle the access
     to the field, because GCC cannot handle non-byte-aligned BLKmode fields.

     Changing to a smaller form is required if the specified size is smaller
     than that of the field's type and the type contains sub-fields that are
     padded, in order to avoid generating accesses to these sub-fields that
     are wider than the field.

     We avoid the transformation if it is not required or potentially useful,
     as it might entail an increase of the field's alignment and have ripple
     effects on the outer record type.  A typical case is a field known to be
     byte-aligned and not to share a byte with another field.  */
  if (!needs_strict_alignment
      && RECORD_OR_UNION_TYPE_P (gnu_field_type)
      && !TYPE_FAT_POINTER_P (gnu_field_type)
      && host_integerp (TYPE_SIZE (gnu_field_type), 1)
      && (packed == 1
	  || (gnu_size
	      && (tree_int_cst_lt (gnu_size, TYPE_SIZE (gnu_field_type))
		  || (Present (Component_Clause (gnat_field))
		      && !(UI_To_Int (Component_Bit_Offset (gnat_field))
			   % BITS_PER_UNIT == 0
			   && value_factor_p (gnu_size, BITS_PER_UNIT)))))))
    {
      tree gnu_packable_type = make_packable_type (gnu_field_type, true);
      if (gnu_packable_type != gnu_field_type)
	{
	  gnu_field_type = gnu_packable_type;
	  if (!gnu_size)
	    gnu_size = rm_size (gnu_field_type);
	}
    }

  if (Is_Atomic (gnat_field))
    check_ok_for_atomic (gnu_field_type, gnat_field, false);

  if (Present (Component_Clause (gnat_field)))
    {
      Entity_Id gnat_parent
	= Parent_Subtype (Underlying_Type (Scope (gnat_field)));

      gnu_pos = UI_To_gnu (Component_Bit_Offset (gnat_field), bitsizetype);
      gnu_size = validate_size (Esize (gnat_field), gnu_field_type,
				gnat_field, FIELD_DECL, false, true);

      /* Ensure the position does not overlap with the parent subtype, if there
	 is one.  This test is omitted if the parent of the tagged type has a
	 full rep clause since, in this case, component clauses are allowed to
	 overlay the space allocated for the parent type and the front-end has
	 checked that there are no overlapping components.  */
      if (Present (gnat_parent) && !Is_Fully_Repped_Tagged_Type (gnat_parent))
	{
	  tree gnu_parent = gnat_to_gnu_type (gnat_parent);

	  if (TREE_CODE (TYPE_SIZE (gnu_parent)) == INTEGER_CST
	      && tree_int_cst_lt (gnu_pos, TYPE_SIZE (gnu_parent)))
	    {
	      post_error_ne_tree
		("offset of& must be beyond parent{, minimum allowed is ^}",
		 First_Bit (Component_Clause (gnat_field)), gnat_field,
		 TYPE_SIZE_UNIT (gnu_parent));
	    }
	}

      /* If this field needs strict alignment, check that the record is
	 sufficiently aligned and that position and size are consistent with
	 the alignment.  But don't do it if we are just annotating types and
	 the field's type is tagged, since tagged types aren't fully laid out
	 in this mode.  Also, note that atomic implies volatile so the inner
	 test sequences ordering is significant here.  */
      if (needs_strict_alignment
	  && !(type_annotate_only && Is_Tagged_Type (gnat_field_type)))
	{
	  TYPE_ALIGN (gnu_record_type)
	    = MAX (TYPE_ALIGN (gnu_record_type), TYPE_ALIGN (gnu_field_type));

	  if (gnu_size
	      && !operand_equal_p (gnu_size, TYPE_SIZE (gnu_field_type), 0))
	    {
	      if (Is_Atomic (gnat_field) || Is_Atomic (gnat_field_type))
		post_error_ne_tree
		  ("atomic field& must be natural size of type{ (^)}",
		   Last_Bit (Component_Clause (gnat_field)), gnat_field,
		   TYPE_SIZE (gnu_field_type));

	      else if (is_volatile)
		post_error_ne_tree
		  ("volatile field& must be natural size of type{ (^)}",
		   Last_Bit (Component_Clause (gnat_field)), gnat_field,
		   TYPE_SIZE (gnu_field_type));

	      else if (Is_Aliased (gnat_field))
		post_error_ne_tree
		  ("size of aliased field& must be ^ bits",
		   Last_Bit (Component_Clause (gnat_field)), gnat_field,
		   TYPE_SIZE (gnu_field_type));

	      else if (Strict_Alignment (gnat_field_type))
		post_error_ne_tree
		  ("size of & with aliased or tagged components not ^ bits",
		   Last_Bit (Component_Clause (gnat_field)), gnat_field,
		   TYPE_SIZE (gnu_field_type));

              else
		gcc_unreachable ();

	      gnu_size = NULL_TREE;
	    }

	  if (!integer_zerop (size_binop
			      (TRUNC_MOD_EXPR, gnu_pos,
			       bitsize_int (TYPE_ALIGN (gnu_field_type)))))
	    {
	      if (Is_Atomic (gnat_field) || Is_Atomic (gnat_field_type))
		post_error_ne_num
		  ("position of atomic field& must be multiple of ^ bits",
		   First_Bit (Component_Clause (gnat_field)), gnat_field,
		   TYPE_ALIGN (gnu_field_type));

              else if (is_volatile)
		post_error_ne_num
		  ("position of volatile field& must be multiple of ^ bits",
		   First_Bit (Component_Clause (gnat_field)), gnat_field,
		   TYPE_ALIGN (gnu_field_type));

	      else if (Is_Aliased (gnat_field))
		post_error_ne_num
		  ("position of aliased field& must be multiple of ^ bits",
		   First_Bit (Component_Clause (gnat_field)), gnat_field,
		   TYPE_ALIGN (gnu_field_type));

	      else if (Strict_Alignment (gnat_field_type))
		post_error_ne
		  ("position of & is not compatible with alignment required "
		   "by its components",
		    First_Bit (Component_Clause (gnat_field)), gnat_field);

	      else
		gcc_unreachable ();

	      gnu_pos = NULL_TREE;
	    }
	}
    }

  /* If the record has rep clauses and this is the tag field, make a rep
     clause for it as well.  */
  else if (Has_Specified_Layout (Scope (gnat_field))
	   && Chars (gnat_field) == Name_uTag)
    {
      gnu_pos = bitsize_zero_node;
      gnu_size = TYPE_SIZE (gnu_field_type);
    }

  else
    {
      gnu_pos = NULL_TREE;

      /* If we are packing the record and the field is BLKmode, round the
	 size up to a byte boundary.  */
      if (packed && TYPE_MODE (gnu_field_type) == BLKmode && gnu_size)
	gnu_size = round_up (gnu_size, BITS_PER_UNIT);
    }

  /* We need to make the size the maximum for the type if it is
     self-referential and an unconstrained type.  In that case, we can't
     pack the field since we can't make a copy to align it.  */
  if (TREE_CODE (gnu_field_type) == RECORD_TYPE
      && !gnu_size
      && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_field_type))
      && !Is_Constrained (Underlying_Type (gnat_field_type)))
    {
      gnu_size = max_size (TYPE_SIZE (gnu_field_type), true);
      packed = 0;
    }

  /* If a size is specified, adjust the field's type to it.  */
  if (gnu_size)
    {
      tree orig_field_type;

      /* If the field's type is justified modular, we would need to remove
	 the wrapper to (better) meet the layout requirements.  However we
	 can do so only if the field is not aliased to preserve the unique
	 layout and if the prescribed size is not greater than that of the
	 packed array to preserve the justification.  */
      if (!needs_strict_alignment
	  && TREE_CODE (gnu_field_type) == RECORD_TYPE
	  && TYPE_JUSTIFIED_MODULAR_P (gnu_field_type)
	  && tree_int_cst_compare (gnu_size, TYPE_ADA_SIZE (gnu_field_type))
	       <= 0)
	gnu_field_type = TREE_TYPE (TYPE_FIELDS (gnu_field_type));

      /* Similarly if the field's type is a misaligned integral type, but
	 there is no restriction on the size as there is no justification.  */
      if (!needs_strict_alignment
	  && TYPE_IS_PADDING_P (gnu_field_type)
	  && INTEGRAL_TYPE_P (TREE_TYPE (TYPE_FIELDS (gnu_field_type))))
	gnu_field_type = TREE_TYPE (TYPE_FIELDS (gnu_field_type));

      gnu_field_type
	= make_type_from_size (gnu_field_type, gnu_size,
			       Has_Biased_Representation (gnat_field));

      orig_field_type = gnu_field_type;
      gnu_field_type = maybe_pad_type (gnu_field_type, gnu_size, 0, gnat_field,
				       false, false, definition, true);

      /* If a padding record was made, declare it now since it will never be
	 declared otherwise.  This is necessary to ensure that its subtrees
	 are properly marked.  */
      if (gnu_field_type != orig_field_type
	  && !DECL_P (TYPE_NAME (gnu_field_type)))
	create_type_decl (TYPE_NAME (gnu_field_type), gnu_field_type, NULL,
			  true, debug_info_p, gnat_field);
    }

  /* Otherwise (or if there was an error), don't specify a position.  */
  else
    gnu_pos = NULL_TREE;

  gcc_assert (TREE_CODE (gnu_field_type) != RECORD_TYPE
	      || !TYPE_CONTAINS_TEMPLATE_P (gnu_field_type));

  /* Now create the decl for the field.  */
  gnu_field
    = create_field_decl (gnu_field_id, gnu_field_type, gnu_record_type,
			 gnu_size, gnu_pos, packed, Is_Aliased (gnat_field));
  Sloc_to_locus (Sloc (gnat_field), &DECL_SOURCE_LOCATION (gnu_field));
  DECL_ALIASED_P (gnu_field) = Is_Aliased (gnat_field);
  TREE_THIS_VOLATILE (gnu_field) = TREE_SIDE_EFFECTS (gnu_field) = is_volatile;

  if (Ekind (gnat_field) == E_Discriminant)
    DECL_DISCRIMINANT_NUMBER (gnu_field)
      = UI_To_gnu (Discriminant_Number (gnat_field), sizetype);

  return gnu_field;
}

/* Return true if at least one member of COMPONENT_LIST needs strict
   alignment.  */

static bool
components_need_strict_alignment (Node_Id component_list)
{
  Node_Id component_decl;

  for (component_decl = First_Non_Pragma (Component_Items (component_list));
       Present (component_decl);
       component_decl = Next_Non_Pragma (component_decl))
    {
      Entity_Id gnat_field = Defining_Entity (component_decl);

      if (Is_Aliased (gnat_field))
	return True;

      if (Strict_Alignment (Etype (gnat_field)))
	return True;
    }

  return False;
}

/* Return true if TYPE is a type with variable size or a padding type with a
   field of variable size or a record that has a field with such a type.  */

static bool
type_has_variable_size (tree type)
{
  tree field;

  if (!TREE_CONSTANT (TYPE_SIZE (type)))
    return true;

  if (TYPE_IS_PADDING_P (type)
      && !TREE_CONSTANT (DECL_SIZE (TYPE_FIELDS (type))))
    return true;

  if (!RECORD_OR_UNION_TYPE_P (type))
    return false;

  for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    if (type_has_variable_size (TREE_TYPE (field)))
      return true;

  return false;
}

/* Return true if FIELD is an artificial field.  */

static bool
field_is_artificial (tree field)
{
  /* These fields are generated by the front-end proper.  */
  if (IDENTIFIER_POINTER (DECL_NAME (field)) [0] == '_')
    return true;

  /* These fields are generated by gigi.  */
  if (DECL_INTERNAL_P (field))
    return true;

  return false;
}

/* Return true if FIELD is a non-artificial aliased field.  */

static bool
field_is_aliased (tree field)
{
  if (field_is_artificial (field))
    return false;

  return DECL_ALIASED_P (field);
}

/* Return true if FIELD is a non-artificial field with self-referential
   size.  */

static bool
field_has_self_size (tree field)
{
  if (field_is_artificial (field))
    return false;

  if (DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST)
    return false;

  return CONTAINS_PLACEHOLDER_P (TYPE_SIZE (TREE_TYPE (field)));
}

/* Return true if FIELD is a non-artificial field with variable size.  */

static bool
field_has_variable_size (tree field)
{
  if (field_is_artificial (field))
    return false;

  if (DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST)
    return false;

  return TREE_CODE (TYPE_SIZE (TREE_TYPE (field))) != INTEGER_CST;
}

/* qsort comparer for the bit positions of two record components.  */

static int
compare_field_bitpos (const PTR rt1, const PTR rt2)
{
  const_tree const field1 = * (const_tree const *) rt1;
  const_tree const field2 = * (const_tree const *) rt2;
  const int ret
    = tree_int_cst_compare (bit_position (field1), bit_position (field2));

  return ret ? ret : (int) (DECL_UID (field1) - DECL_UID (field2));
}

/* Translate and chain the GNAT_COMPONENT_LIST to the GNU_FIELD_LIST, set
   the result as the field list of GNU_RECORD_TYPE and finish it up.  When
   called from gnat_to_gnu_entity during the processing of a record type
   definition, the GCC node for the parent, if any, will be the single field
   of GNU_RECORD_TYPE and the GCC nodes for the discriminants will be on the
   GNU_FIELD_LIST.  The other calls to this function are recursive calls for
   the component list of a variant and, in this case, GNU_FIELD_LIST is empty.

   PACKED is 1 if this is for a packed record, -1 if this is for a record
   with Component_Alignment of Storage_Unit, -2 if this is for a record
   with a specified alignment.

   DEFINITION is true if we are defining this record type.

   CANCEL_ALIGNMENT is true if the alignment should be zeroed before laying
   out the record.  This means the alignment only serves to force fields to
   be bitfields, but not to require the record to be that aligned.  This is
   used for variants.

   ALL_REP is true if a rep clause is present for all the fields.

   UNCHECKED_UNION is true if we are building this type for a record with a
   Pragma Unchecked_Union.

   ARTIFICIAL is true if this is a type that was generated by the compiler.

   DEBUG_INFO is true if we need to write debug information about the type.

   MAYBE_UNUSED is true if this type may be unused in the end; this doesn't
   mean that its contents may be unused as well, only the container itself.

   REORDER is true if we are permitted to reorder components of this type.

   FIRST_FREE_POS, if nonzero, is the first (lowest) free field position in
   the outer record type down to this variant level.  It is nonzero only if
   all the fields down to this level have a rep clause and ALL_REP is false.

   P_GNU_REP_LIST, if nonzero, is a pointer to a list to which each field
   with a rep clause is to be added; in this case, that is all that should
   be done with such fields.  */

static void
components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
		      tree gnu_field_list, int packed, bool definition,
		      bool cancel_alignment, bool all_rep,
		      bool unchecked_union, bool artificial,
		      bool debug_info, bool maybe_unused, bool reorder,
		      tree first_free_pos, tree *p_gnu_rep_list)
{
  bool all_rep_and_size = all_rep && TYPE_SIZE (gnu_record_type);
  bool layout_with_rep = false;
  bool has_self_field = false;
  bool has_aliased_after_self_field = false;
  Node_Id component_decl, variant_part;
  tree gnu_field, gnu_next, gnu_last;
  tree gnu_rep_part = NULL_TREE;
  tree gnu_variant_part = NULL_TREE;
  tree gnu_rep_list = NULL_TREE;
  tree gnu_var_list = NULL_TREE;
  tree gnu_self_list = NULL_TREE;

  /* For each component referenced in a component declaration create a GCC
     field and add it to the list, skipping pragmas in the GNAT list.  */
  gnu_last = tree_last (gnu_field_list);
  if (Present (Component_Items (gnat_component_list)))
    for (component_decl
	   = First_Non_Pragma (Component_Items (gnat_component_list));
	 Present (component_decl);
	 component_decl = Next_Non_Pragma (component_decl))
      {
	Entity_Id gnat_field = Defining_Entity (component_decl);
	Name_Id gnat_name = Chars (gnat_field);

	/* If present, the _Parent field must have been created as the single
	   field of the record type.  Put it before any other fields.  */
	if (gnat_name == Name_uParent)
	  {
	    gnu_field = TYPE_FIELDS (gnu_record_type);
	    gnu_field_list = chainon (gnu_field_list, gnu_field);
	  }
	else
	  {
	    gnu_field = gnat_to_gnu_field (gnat_field, gnu_record_type, packed,
					   definition, debug_info);

	    /* If this is the _Tag field, put it before any other fields.  */
	    if (gnat_name == Name_uTag)
	      gnu_field_list = chainon (gnu_field_list, gnu_field);

	    /* If this is the _Controller field, put it before the other
	       fields except for the _Tag or _Parent field.  */
	    else if (gnat_name == Name_uController && gnu_last)
	      {
		DECL_CHAIN (gnu_field) = DECL_CHAIN (gnu_last);
		DECL_CHAIN (gnu_last) = gnu_field;
	      }

	    /* If this is a regular field, put it after the other fields.  */
	    else
	      {
		DECL_CHAIN (gnu_field) = gnu_field_list;
		gnu_field_list = gnu_field;
		if (!gnu_last)
		  gnu_last = gnu_field;

		/* And record information for the final layout.  */
		if (field_has_self_size (gnu_field))
		  has_self_field = true;
		else if (has_self_field && field_is_aliased (gnu_field))
		  has_aliased_after_self_field = true;
	      }
	  }

	save_gnu_tree (gnat_field, gnu_field, false);
      }

  /* At the end of the component list there may be a variant part.  */
  variant_part = Variant_Part (gnat_component_list);

  /* We create a QUAL_UNION_TYPE for the variant part since the variants are
     mutually exclusive and should go in the same memory.  To do this we need
     to treat each variant as a record whose elements are created from the
     component list for the variant.  So here we create the records from the
     lists for the variants and put them all into the QUAL_UNION_TYPE.
     If this is an Unchecked_Union, we make a UNION_TYPE instead or
     use GNU_RECORD_TYPE if there are no fields so far.  */
  if (Present (variant_part))
    {
      Node_Id gnat_discr = Name (variant_part), variant;
      tree gnu_discr = gnat_to_gnu (gnat_discr);
      tree gnu_name = TYPE_NAME (gnu_record_type);
      tree gnu_var_name
	= concat_name (get_identifier (Get_Name_String (Chars (gnat_discr))),
		       "XVN");
      tree gnu_union_type, gnu_union_name;
      tree this_first_free_pos, gnu_variant_list = NULL_TREE;
      bool union_field_needs_strict_alignment = false;

      if (TREE_CODE (gnu_name) == TYPE_DECL)
	gnu_name = DECL_NAME (gnu_name);

      gnu_union_name
	= concat_name (gnu_name, IDENTIFIER_POINTER (gnu_var_name));

      /* Reuse the enclosing union if this is an Unchecked_Union whose fields
	 are all in the variant part, to match the layout of C unions.  There
	 is an associated check below.  */
      if (TREE_CODE (gnu_record_type) == UNION_TYPE)
	gnu_union_type = gnu_record_type;
      else
	{
	  gnu_union_type
	    = make_node (unchecked_union ? UNION_TYPE : QUAL_UNION_TYPE);

	  TYPE_NAME (gnu_union_type) = gnu_union_name;
	  TYPE_ALIGN (gnu_union_type) = 0;
	  TYPE_PACKED (gnu_union_type) = TYPE_PACKED (gnu_record_type);
	}

      /* If all the fields down to this level have a rep clause, find out
	 whether all the fields at this level also have one.  If so, then
	 compute the new first free position to be passed downward.  */
      this_first_free_pos = first_free_pos;
      if (this_first_free_pos)
	{
	  for (gnu_field = gnu_field_list;
	       gnu_field;
	       gnu_field = DECL_CHAIN (gnu_field))
	    if (DECL_FIELD_OFFSET (gnu_field))
	      {
		tree pos = bit_position (gnu_field);
		if (!tree_int_cst_lt (pos, this_first_free_pos))
		  this_first_free_pos
		    = size_binop (PLUS_EXPR, pos, DECL_SIZE (gnu_field));
	      }
	    else
	      {
		this_first_free_pos = NULL_TREE;
		break;
	      }
	}

      for (variant = First_Non_Pragma (Variants (variant_part));
	   Present (variant);
	   variant = Next_Non_Pragma (variant))
	{
	  tree gnu_variant_type = make_node (RECORD_TYPE);
	  tree gnu_inner_name;
	  tree gnu_qual;

	  Get_Variant_Encoding (variant);
	  gnu_inner_name = get_identifier_with_length (Name_Buffer, Name_Len);
	  TYPE_NAME (gnu_variant_type)
	    = concat_name (gnu_union_name,
			   IDENTIFIER_POINTER (gnu_inner_name));

	  /* Set the alignment of the inner type in case we need to make
	     inner objects into bitfields, but then clear it out so the
	     record actually gets only the alignment required.  */
	  TYPE_ALIGN (gnu_variant_type) = TYPE_ALIGN (gnu_record_type);
	  TYPE_PACKED (gnu_variant_type) = TYPE_PACKED (gnu_record_type);

	  /* Similarly, if the outer record has a size specified and all
	     the fields have a rep clause, we can propagate the size.  */
	  if (all_rep_and_size)
	    {
	      TYPE_SIZE (gnu_variant_type) = TYPE_SIZE (gnu_record_type);
	      TYPE_SIZE_UNIT (gnu_variant_type)
		= TYPE_SIZE_UNIT (gnu_record_type);
	    }

	  /* Add the fields into the record type for the variant.  Note that
	     we aren't sure to really use it at this point, see below.  */
	  components_to_record (gnu_variant_type, Component_List (variant),
				NULL_TREE, packed, definition,
				!all_rep_and_size, all_rep, unchecked_union,
				true, debug_info, true, reorder,
				this_first_free_pos,
				all_rep || this_first_free_pos
				? NULL : &gnu_rep_list);

	  gnu_qual = choices_to_gnu (gnu_discr, Discrete_Choices (variant));
	  Set_Present_Expr (variant, annotate_value (gnu_qual));

	  /* If this is an Unchecked_Union whose fields are all in the variant
	     part and we have a single field with no representation clause or
	     placed at offset zero, use the field directly to match the layout
	     of C unions.  */
	  if (TREE_CODE (gnu_record_type) == UNION_TYPE
	      && (gnu_field = TYPE_FIELDS (gnu_variant_type)) != NULL_TREE
	      && !DECL_CHAIN (gnu_field)
	      && (!DECL_FIELD_OFFSET (gnu_field)
		  || integer_zerop (bit_position (gnu_field))))
	    DECL_CONTEXT (gnu_field) = gnu_union_type;
	  else
	    {
	      /* Deal with packedness like in gnat_to_gnu_field.  */
	      bool field_needs_strict_alignment
	        = components_need_strict_alignment (Component_List (variant));
	      int field_packed;

	      if (field_needs_strict_alignment)
		{
		  field_packed = 0;
		  union_field_needs_strict_alignment = true;
		}
	      else
		field_packed
		  = adjust_packed (gnu_variant_type, gnu_record_type, packed);

	      /* Finalize the record type now.  We used to throw away
		 empty records but we no longer do that because we need
		 them to generate complete debug info for the variant;
		 otherwise, the union type definition will be lacking
		 the fields associated with these empty variants.  */
	      rest_of_record_type_compilation (gnu_variant_type);
	      create_type_decl (TYPE_NAME (gnu_variant_type), gnu_variant_type,
				NULL, true, debug_info, gnat_component_list);

	      gnu_field
		= create_field_decl (gnu_inner_name, gnu_variant_type,
				     gnu_union_type,
				     all_rep_and_size
				     ? TYPE_SIZE (gnu_variant_type) : 0,
				     all_rep ? bitsize_zero_node : 0,
				     field_packed, 0);

	      DECL_INTERNAL_P (gnu_field) = 1;

	      if (!unchecked_union)
		DECL_QUALIFIER (gnu_field) = gnu_qual;
	    }

	  DECL_CHAIN (gnu_field) = gnu_variant_list;
	  gnu_variant_list = gnu_field;
	}

      /* Only make the QUAL_UNION_TYPE if there are non-empty variants.  */
      if (gnu_variant_list)
	{
	  int union_field_packed;

	  if (all_rep_and_size)
	    {
	      TYPE_SIZE (gnu_union_type) = TYPE_SIZE (gnu_record_type);
	      TYPE_SIZE_UNIT (gnu_union_type)
		= TYPE_SIZE_UNIT (gnu_record_type);
	    }

	  finish_record_type (gnu_union_type, nreverse (gnu_variant_list),
			      all_rep_and_size ? 1 : 0, debug_info);

	  /* If GNU_UNION_TYPE is our record type, it means we must have an
	     Unchecked_Union with no fields.  Verify that and, if so, just
	     return.  */
	  if (gnu_union_type == gnu_record_type)
	    {
	      gcc_assert (unchecked_union
			  && !gnu_field_list
			  && !gnu_rep_list);
	      return;
	    }

	  create_type_decl (TYPE_NAME (gnu_union_type), gnu_union_type,
			    NULL, true, debug_info, gnat_component_list);

	  /* Deal with packedness like in gnat_to_gnu_field.  */
	  if (union_field_needs_strict_alignment)
	    union_field_packed = 0;
	  else
	    union_field_packed
	      = adjust_packed (gnu_union_type, gnu_record_type, packed);

	  gnu_variant_part
	    = create_field_decl (gnu_var_name, gnu_union_type, gnu_record_type,
				 all_rep_and_size
				 ? TYPE_SIZE (gnu_union_type) : 0,
				 all_rep || this_first_free_pos
				 ? bitsize_zero_node : 0,
				 union_field_packed, 0);

	  DECL_INTERNAL_P (gnu_variant_part) = 1;
	}
    }

  /* From now on, a zero FIRST_FREE_POS is totally useless.  */
  if (first_free_pos && integer_zerop (first_free_pos))
    first_free_pos = NULL_TREE;

  /* Scan GNU_FIELD_LIST and see if any fields have rep clauses and, if we are
     permitted to reorder components, self-referential sizes or variable sizes.
     If they do, pull them out and put them onto the appropriate list.  We have
     to do this in a separate pass since we want to handle the discriminants
     but can't play with them until we've used them in debugging data above.

     ??? If we reorder them, debugging information will be wrong but there is
     nothing that can be done about this at the moment.  */
  gnu_last = NULL_TREE;

#define MOVE_FROM_FIELD_LIST_TO(LIST)	\
  do {					\
    if (gnu_last)			\
      DECL_CHAIN (gnu_last) = gnu_next;	\
    else				\
      gnu_field_list = gnu_next;	\
					\
    DECL_CHAIN (gnu_field) = (LIST);	\
    (LIST) = gnu_field;			\
  } while (0)

  for (gnu_field = gnu_field_list; gnu_field; gnu_field = gnu_next)
    {
      gnu_next = DECL_CHAIN (gnu_field);

      if (DECL_FIELD_OFFSET (gnu_field))
	{
	  MOVE_FROM_FIELD_LIST_TO (gnu_rep_list);
	  continue;
	}

      if ((reorder || has_aliased_after_self_field)
	  && field_has_self_size (gnu_field))
	{
	  MOVE_FROM_FIELD_LIST_TO (gnu_self_list);
	  continue;
	}

      if (reorder && field_has_variable_size (gnu_field))
	{
	  MOVE_FROM_FIELD_LIST_TO (gnu_var_list);
	  continue;
	}

      gnu_last = gnu_field;
    }

#undef MOVE_FROM_FIELD_LIST_TO

  /* If permitted, we reorder the fields as follows:

       1) all fixed length fields,
       2) all fields whose length doesn't depend on discriminants,
       3) all fields whose length depends on discriminants,
       4) the variant part,

     within the record and within each variant recursively.  */
  if (reorder)
    gnu_field_list
      = chainon (nreverse (gnu_self_list),
		 chainon (nreverse (gnu_var_list), gnu_field_list));

  /* Otherwise, if there is an aliased field placed after a field whose length
     depends on discriminants, we put all the fields of the latter sort, last.
     We need to do this in case an object of this record type is mutable.  */
  else if (has_aliased_after_self_field)
    gnu_field_list = chainon (nreverse (gnu_self_list), gnu_field_list);

  /* If P_REP_LIST is nonzero, this means that we are asked to move the fields
     in our REP list to the previous level because this level needs them in
     order to do a correct layout, i.e. avoid having overlapping fields.  */
  if (p_gnu_rep_list && gnu_rep_list)
    *p_gnu_rep_list = chainon (*p_gnu_rep_list, gnu_rep_list);

  /* Otherwise, sort the fields by bit position and put them into their own
     record, before the others, if we also have fields without rep clause.  */
  else if (gnu_rep_list)
    {
      tree gnu_rep_type
	= (gnu_field_list ? make_node (RECORD_TYPE) : gnu_record_type);
      int i, len = list_length (gnu_rep_list);
      tree *gnu_arr = XALLOCAVEC (tree, len);

      for (gnu_field = gnu_rep_list, i = 0;
	   gnu_field;
	   gnu_field = DECL_CHAIN (gnu_field), i++)
	gnu_arr[i] = gnu_field;

      qsort (gnu_arr, len, sizeof (tree), compare_field_bitpos);

      /* Put the fields in the list in order of increasing position, which
	 means we start from the end.  */
      gnu_rep_list = NULL_TREE;
      for (i = len - 1; i >= 0; i--)
	{
	  DECL_CHAIN (gnu_arr[i]) = gnu_rep_list;
	  gnu_rep_list = gnu_arr[i];
	  DECL_CONTEXT (gnu_arr[i]) = gnu_rep_type;
	}

      if (gnu_field_list)
	{
	  finish_record_type (gnu_rep_type, gnu_rep_list, 1, debug_info);

	  /* If FIRST_FREE_POS is nonzero, we need to ensure that the fields
	     without rep clause are laid out starting from this position.
	     Therefore, we force it as a minimal size on the REP part.  */
	  gnu_rep_part
	    = create_rep_part (gnu_rep_type, gnu_record_type, first_free_pos);
	}
      else
	{
	  layout_with_rep = true;
	  gnu_field_list = nreverse (gnu_rep_list);
	}
    }

  /* If FIRST_FREE_POS is nonzero, we need to ensure that the fields without
     rep clause are laid out starting from this position.  Therefore, if we
     have not already done so, we create a fake REP part with this size.  */
  if (first_free_pos && !layout_with_rep && !gnu_rep_part)
    {
      tree gnu_rep_type = make_node (RECORD_TYPE);
      finish_record_type (gnu_rep_type, NULL_TREE, 0, debug_info);
      gnu_rep_part
	= create_rep_part (gnu_rep_type, gnu_record_type, first_free_pos);
    }

  /* Now chain the REP part at the end of the reversed field list.  */
  if (gnu_rep_part)
    gnu_field_list = chainon (gnu_field_list, gnu_rep_part);

  /* And the variant part at the beginning.  */
  if (gnu_variant_part)
    {
      DECL_CHAIN (gnu_variant_part) = gnu_field_list;
      gnu_field_list = gnu_variant_part;
    }

  if (cancel_alignment)
    TYPE_ALIGN (gnu_record_type) = 0;

  finish_record_type (gnu_record_type, nreverse (gnu_field_list),
		      layout_with_rep ? 1 : 0, false);
  TYPE_ARTIFICIAL (gnu_record_type) = artificial;
  if (debug_info && !maybe_unused)
    rest_of_record_type_compilation (gnu_record_type);
}

/* Given GNU_SIZE, a GCC tree representing a size, return a Uint to be
   placed into an Esize, Component_Bit_Offset, or Component_Size value
   in the GNAT tree.  */

static Uint
annotate_value (tree gnu_size)
{
  TCode tcode;
  Node_Ref_Or_Val ops[3], ret, pre_op1 = No_Uint;
  struct tree_int_map in;
  int i;

  /* See if we've already saved the value for this node.  */
  if (EXPR_P (gnu_size))
    {
      struct tree_int_map *e;

      if (!annotate_value_cache)
        annotate_value_cache = htab_create_ggc (512, tree_int_map_hash,
					        tree_int_map_eq, 0);
      in.base.from = gnu_size;
      e = (struct tree_int_map *)
	    htab_find (annotate_value_cache, &in);

      if (e)
	return (Node_Ref_Or_Val) e->to;
    }
  else
    in.base.from = NULL_TREE;

  /* If we do not return inside this switch, TCODE will be set to the
     code to use for a Create_Node operand and LEN (set above) will be
     the number of recursive calls for us to make.  */

  switch (TREE_CODE (gnu_size))
    {
    case INTEGER_CST:
      return TREE_OVERFLOW (gnu_size) ? No_Uint : UI_From_gnu (gnu_size);

    case COMPONENT_REF:
      /* The only case we handle here is a simple discriminant reference.  */
      if (DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1)))
	{
	  tree n = DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1));

	  /* Climb up the chain of successive extensions, if any.  */
	  while (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == COMPONENT_REF
		 && DECL_NAME (TREE_OPERAND (TREE_OPERAND (gnu_size, 0), 1))
		    == parent_name_id)
	    gnu_size = TREE_OPERAND (gnu_size, 0);

	  if (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == PLACEHOLDER_EXPR)
	    return
	      Create_Node (Discrim_Val, annotate_value (n), No_Uint, No_Uint);
	}

      return No_Uint;

    CASE_CONVERT:   case NON_LVALUE_EXPR:
      return annotate_value (TREE_OPERAND (gnu_size, 0));

      /* Now just list the operations we handle.  */
    case COND_EXPR:		tcode = Cond_Expr; break;
    case PLUS_EXPR:		tcode = Plus_Expr; break;
    case MINUS_EXPR:		tcode = Minus_Expr; break;
    case MULT_EXPR:		tcode = Mult_Expr; break;
    case TRUNC_DIV_EXPR:	tcode = Trunc_Div_Expr; break;
    case CEIL_DIV_EXPR:		tcode = Ceil_Div_Expr; break;
    case FLOOR_DIV_EXPR:	tcode = Floor_Div_Expr; break;
    case TRUNC_MOD_EXPR:	tcode = Trunc_Mod_Expr; break;
    case CEIL_MOD_EXPR:		tcode = Ceil_Mod_Expr; break;
    case FLOOR_MOD_EXPR:	tcode = Floor_Mod_Expr; break;
    case EXACT_DIV_EXPR:	tcode = Exact_Div_Expr; break;
    case NEGATE_EXPR:		tcode = Negate_Expr; break;
    case MIN_EXPR:		tcode = Min_Expr; break;
    case MAX_EXPR:		tcode = Max_Expr; break;
    case ABS_EXPR:		tcode = Abs_Expr; break;
    case TRUTH_ANDIF_EXPR:	tcode = Truth_Andif_Expr; break;
    case TRUTH_ORIF_EXPR:	tcode = Truth_Orif_Expr; break;
    case TRUTH_AND_EXPR:	tcode = Truth_And_Expr; break;
    case TRUTH_OR_EXPR:		tcode = Truth_Or_Expr; break;
    case TRUTH_XOR_EXPR:	tcode = Truth_Xor_Expr; break;
    case TRUTH_NOT_EXPR:	tcode = Truth_Not_Expr; break;
    case LT_EXPR:		tcode = Lt_Expr; break;
    case LE_EXPR:		tcode = Le_Expr; break;
    case GT_EXPR:		tcode = Gt_Expr; break;
    case GE_EXPR:		tcode = Ge_Expr; break;
    case EQ_EXPR:		tcode = Eq_Expr; break;
    case NE_EXPR:		tcode = Ne_Expr; break;

    case BIT_AND_EXPR:
      tcode = Bit_And_Expr;
      /* For negative values, build NEGATE_EXPR of the opposite.  Such values
	 appear in expressions containing aligning patterns.  Note that, since
	 sizetype is unsigned, we have to jump through some hoops.   */
      if (TREE_CODE (TREE_OPERAND (gnu_size, 1)) == INTEGER_CST)
	{
	  tree op1 = TREE_OPERAND (gnu_size, 1);
	  double_int signed_op1
	    = tree_to_double_int (op1).sext (TYPE_PRECISION (sizetype));
	  if (signed_op1.is_negative ())
	    {
	      op1 = double_int_to_tree (sizetype, -signed_op1);
	      pre_op1 = annotate_value (build1 (NEGATE_EXPR, sizetype, op1));
	    }
	}
      break;

    case CALL_EXPR:
      {
	tree t = maybe_inline_call_in_expr (gnu_size);
	if (t)
	  return annotate_value (t);
      }

      /* Fall through... */

    default:
      return No_Uint;
    }

  /* Now get each of the operands that's relevant for this code.  If any
     cannot be expressed as a repinfo node, say we can't.  */
  for (i = 0; i < 3; i++)
    ops[i] = No_Uint;

  for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (gnu_size)); i++)
    {
      if (i == 1 && pre_op1 != No_Uint)
	ops[i] = pre_op1;
      else
	ops[i] = annotate_value (TREE_OPERAND (gnu_size, i));
      if (ops[i] == No_Uint)
	return No_Uint;
    }

  ret = Create_Node (tcode, ops[0], ops[1], ops[2]);

  /* Save the result in the cache.  */
  if (in.base.from)
    {
      struct tree_int_map **h;
      /* We can't assume the hash table data hasn't moved since the
	 initial look up, so we have to search again.  Allocating and
	 inserting an entry at that point would be an alternative, but
	 then we'd better discard the entry if we decided not to cache
	 it.  */
      h = (struct tree_int_map **)
	    htab_find_slot (annotate_value_cache, &in, INSERT);
      gcc_assert (!*h);
      *h = ggc_alloc_tree_int_map ();
      (*h)->base.from = gnu_size;
      (*h)->to = ret;
    }

  return ret;
}

/* Given GNAT_ENTITY, an object (constant, variable, parameter, exception)
   and GNU_TYPE, its corresponding GCC type, set Esize and Alignment to the
   size and alignment used by Gigi.  Prefer SIZE over TYPE_SIZE if non-null.
   BY_REF is true if the object is used by reference.  */

void
annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size, bool by_ref)
{
  if (by_ref)
    {
      if (TYPE_IS_FAT_POINTER_P (gnu_type))
	gnu_type = TYPE_UNCONSTRAINED_ARRAY (gnu_type);
      else
	gnu_type = TREE_TYPE (gnu_type);
    }

  if (Unknown_Esize (gnat_entity))
    {
      if (TREE_CODE (gnu_type) == RECORD_TYPE
	  && TYPE_CONTAINS_TEMPLATE_P (gnu_type))
	size = TYPE_SIZE (TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_type))));
      else if (!size)
	size = TYPE_SIZE (gnu_type);

      if (size)
	Set_Esize (gnat_entity, annotate_value (size));
    }

  if (Unknown_Alignment (gnat_entity))
    Set_Alignment (gnat_entity,
		   UI_From_Int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT));
}

/* Return first element of field list whose TREE_PURPOSE is the same as ELEM.
   Return NULL_TREE if there is no such element in the list.  */

static tree
purpose_member_field (const_tree elem, tree list)
{
  while (list)
    {
      tree field = TREE_PURPOSE (list);
      if (SAME_FIELD_P (field, elem))
	return list;
      list = TREE_CHAIN (list);
    }
  return NULL_TREE;
}

/* Given GNAT_ENTITY, a record type, and GNU_TYPE, its corresponding GCC type,
   set Component_Bit_Offset and Esize of the components to the position and
   size used by Gigi.  */

static void
annotate_rep (Entity_Id gnat_entity, tree gnu_type)
{
  Entity_Id gnat_field;
  tree gnu_list;

  /* We operate by first making a list of all fields and their position (we
     can get the size easily) and then update all the sizes in the tree.  */
  gnu_list
    = build_position_list (gnu_type, false, size_zero_node, bitsize_zero_node,
			   BIGGEST_ALIGNMENT, NULL_TREE);

  for (gnat_field = First_Entity (gnat_entity);
       Present (gnat_field);
       gnat_field = Next_Entity (gnat_field))
    if (Ekind (gnat_field) == E_Component
	|| (Ekind (gnat_field) == E_Discriminant
	    && !Is_Unchecked_Union (Scope (gnat_field))))
      {
	tree t = purpose_member_field (gnat_to_gnu_field_decl (gnat_field),
				       gnu_list);
	if (t)
	  {
	    tree parent_offset;

	    /* If we are just annotating types and the type is tagged, the tag
	       and the parent components are not generated by the front-end so
	       we need to add the appropriate offset to each component without
	       representation clause.  */
	    if (type_annotate_only
		&& Is_Tagged_Type (gnat_entity)
		&& No (Component_Clause (gnat_field)))
	      {
		/* For a component appearing in the current extension, the
		   offset is the size of the parent.  */
		if (Is_Derived_Type (gnat_entity)
		    && Original_Record_Component (gnat_field) == gnat_field)
		  parent_offset
		    = UI_To_gnu (Esize (Etype (Base_Type (gnat_entity))),
				 bitsizetype);
		else
		  parent_offset = bitsize_int (POINTER_SIZE);

		if (TYPE_FIELDS (gnu_type))
		  parent_offset
		    = round_up (parent_offset,
				DECL_ALIGN (TYPE_FIELDS (gnu_type)));
	      }
	    else
	      parent_offset = bitsize_zero_node;

	    Set_Component_Bit_Offset
	      (gnat_field,
	       annotate_value
		 (size_binop (PLUS_EXPR,
			      bit_from_pos (TREE_VEC_ELT (TREE_VALUE (t), 0),
					    TREE_VEC_ELT (TREE_VALUE (t), 2)),
			      parent_offset)));

	    Set_Esize (gnat_field,
		       annotate_value (DECL_SIZE (TREE_PURPOSE (t))));
	  }
	else if (Is_Tagged_Type (gnat_entity) && Is_Derived_Type (gnat_entity))
	  {
	    /* If there is no entry, this is an inherited component whose
	       position is the same as in the parent type.  */
	    Set_Component_Bit_Offset
	      (gnat_field,
	       Component_Bit_Offset (Original_Record_Component (gnat_field)));

	    Set_Esize (gnat_field,
		       Esize (Original_Record_Component (gnat_field)));
	  }
      }
}

/* Scan all fields in GNU_TYPE and return a TREE_LIST where TREE_PURPOSE is
   the FIELD_DECL and TREE_VALUE a TREE_VEC containing the byte position, the
   value to be placed into DECL_OFFSET_ALIGN and the bit position.  The list
   of fields is flattened, except for variant parts if DO_NOT_FLATTEN_VARIANT
   is set to true.  GNU_POS is to be added to the position, GNU_BITPOS to the
   bit position, OFFSET_ALIGN is the present offset alignment.  GNU_LIST is a
   pre-existing list to be chained to the newly created entries.  */

static tree
build_position_list (tree gnu_type, bool do_not_flatten_variant, tree gnu_pos,
		     tree gnu_bitpos, unsigned int offset_align, tree gnu_list)
{
  tree gnu_field;

  for (gnu_field = TYPE_FIELDS (gnu_type);
       gnu_field;
       gnu_field = DECL_CHAIN (gnu_field))
    {
      tree gnu_our_bitpos = size_binop (PLUS_EXPR, gnu_bitpos,
					DECL_FIELD_BIT_OFFSET (gnu_field));
      tree gnu_our_offset = size_binop (PLUS_EXPR, gnu_pos,
					DECL_FIELD_OFFSET (gnu_field));
      unsigned int our_offset_align
	= MIN (offset_align, DECL_OFFSET_ALIGN (gnu_field));
      tree v = make_tree_vec (3);

      TREE_VEC_ELT (v, 0) = gnu_our_offset;
      TREE_VEC_ELT (v, 1) = size_int (our_offset_align);
      TREE_VEC_ELT (v, 2) = gnu_our_bitpos;
      gnu_list = tree_cons (gnu_field, v, gnu_list);

      /* Recurse on internal fields, flattening the nested fields except for
	 those in the variant part, if requested.  */
      if (DECL_INTERNAL_P (gnu_field))
	{
	  tree gnu_field_type = TREE_TYPE (gnu_field);
	  if (do_not_flatten_variant
	      && TREE_CODE (gnu_field_type) == QUAL_UNION_TYPE)
	    gnu_list
	      = build_position_list (gnu_field_type, do_not_flatten_variant,
				     size_zero_node, bitsize_zero_node,
				     BIGGEST_ALIGNMENT, gnu_list);
	  else
	    gnu_list
	      = build_position_list (gnu_field_type, do_not_flatten_variant,
				     gnu_our_offset, gnu_our_bitpos,
				     our_offset_align, gnu_list);
	}
    }

  return gnu_list;
}

/* Return a list describing the substitutions needed to reflect the
   discriminant substitutions from GNAT_TYPE to GNAT_SUBTYPE.  They can
   be in any order.  The values in an element of the list are in the form
   of operands to SUBSTITUTE_IN_EXPR.  DEFINITION is true if this is for
   a definition of GNAT_SUBTYPE.  */

static vec<subst_pair>
build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition)
{
  vec<subst_pair> gnu_list = vNULL;
  Entity_Id gnat_discrim;
  Node_Id gnat_value;

  for (gnat_discrim = First_Stored_Discriminant (gnat_type),
       gnat_value = First_Elmt (Stored_Constraint (gnat_subtype));
       Present (gnat_discrim);
       gnat_discrim = Next_Stored_Discriminant (gnat_discrim),
       gnat_value = Next_Elmt (gnat_value))
    /* Ignore access discriminants.  */
    if (!Is_Access_Type (Etype (Node (gnat_value))))
      {
	tree gnu_field = gnat_to_gnu_field_decl (gnat_discrim);
	tree replacement = convert (TREE_TYPE (gnu_field),
				    elaborate_expression
				    (Node (gnat_value), gnat_subtype,
				     get_entity_name (gnat_discrim),
				     definition, true, false));
	subst_pair s = {gnu_field, replacement};
	gnu_list.safe_push (s);
      }

  return gnu_list;
}

/* Scan all fields in QUAL_UNION_TYPE and return a list describing the
   variants of QUAL_UNION_TYPE that are still relevant after applying
   the substitutions described in SUBST_LIST.  GNU_LIST is a pre-existing
   list to be prepended to the newly created entries.  */

static vec<variant_desc>
build_variant_list (tree qual_union_type, vec<subst_pair> subst_list,
		    vec<variant_desc> gnu_list)
{
  tree gnu_field;

  for (gnu_field = TYPE_FIELDS (qual_union_type);
       gnu_field;
       gnu_field = DECL_CHAIN (gnu_field))
    {
      tree qual = DECL_QUALIFIER (gnu_field);
      unsigned int i;
      subst_pair *s;

      FOR_EACH_VEC_ELT (subst_list, i, s)
	qual = SUBSTITUTE_IN_EXPR (qual, s->discriminant, s->replacement);

      /* If the new qualifier is not unconditionally false, its variant may
	 still be accessed.  */
      if (!integer_zerop (qual))
	{
	  tree variant_type = TREE_TYPE (gnu_field), variant_subpart;
	  variant_desc v = {variant_type, gnu_field, qual, NULL_TREE};

	  gnu_list.safe_push (v);

	  /* Recurse on the variant subpart of the variant, if any.  */
	  variant_subpart = get_variant_part (variant_type);
	  if (variant_subpart)
	    gnu_list = build_variant_list (TREE_TYPE (variant_subpart),
					   subst_list, gnu_list);

	  /* If the new qualifier is unconditionally true, the subsequent
	     variants cannot be accessed.  */
	  if (integer_onep (qual))
	    break;
	}
    }

  return gnu_list;
}

/* UINT_SIZE is a Uint giving the specified size for an object of GNU_TYPE
   corresponding to GNAT_OBJECT.  If the size is valid, return an INTEGER_CST
   corresponding to its value.  Otherwise, return NULL_TREE.  KIND is set to
   VAR_DECL if we are specifying the size of an object, TYPE_DECL for the
   size of a type, and FIELD_DECL for the size of a field.  COMPONENT_P is
   true if we are being called to process the Component_Size of GNAT_OBJECT;
   this is used only for error messages.  ZERO_OK is true if a size of zero
   is permitted; if ZERO_OK is false, it means that a size of zero should be
   treated as an unspecified size.  */

static tree
validate_size (Uint uint_size, tree gnu_type, Entity_Id gnat_object,
	       enum tree_code kind, bool component_p, bool zero_ok)
{
  Node_Id gnat_error_node;
  tree type_size, size;

  /* Return 0 if no size was specified.  */
  if (uint_size == No_Uint)
    return NULL_TREE;

  /* Ignore a negative size since that corresponds to our back-annotation.  */
  if (UI_Lt (uint_size, Uint_0))
    return NULL_TREE;

  /* Find the node to use for error messages.  */
  if ((Ekind (gnat_object) == E_Component
       || Ekind (gnat_object) == E_Discriminant)
      && Present (Component_Clause (gnat_object)))
    gnat_error_node = Last_Bit (Component_Clause (gnat_object));
  else if (Present (Size_Clause (gnat_object)))
    gnat_error_node = Expression (Size_Clause (gnat_object));
  else
    gnat_error_node = gnat_object;

  /* Get the size as an INTEGER_CST.  Issue an error if a size was specified
     but cannot be represented in bitsizetype.  */
  size = UI_To_gnu (uint_size, bitsizetype);
  if (TREE_OVERFLOW (size))
    {
      if (component_p)
	post_error_ne ("component size for& is too large", gnat_error_node,
		       gnat_object);
      else
	post_error_ne ("size for& is too large", gnat_error_node,
		       gnat_object);
      return NULL_TREE;
    }

  /* Ignore a zero size if it is not permitted.  */
  if (!zero_ok && integer_zerop (size))
    return NULL_TREE;

  /* The size of objects is always a multiple of a byte.  */
  if (kind == VAR_DECL
      && !integer_zerop (size_binop (TRUNC_MOD_EXPR, size, bitsize_unit_node)))
    {
      if (component_p)
	post_error_ne ("component size for& is not a multiple of Storage_Unit",
		       gnat_error_node, gnat_object);
      else
	post_error_ne ("size for& is not a multiple of Storage_Unit",
		       gnat_error_node, gnat_object);
      return NULL_TREE;
    }

  /* If this is an integral type or a packed array type, the front-end has
     already verified the size, so we need not do it here (which would mean
     checking against the bounds).  However, if this is an aliased object,
     it may not be smaller than the type of the object.  */
  if ((INTEGRAL_TYPE_P (gnu_type) || TYPE_IS_PACKED_ARRAY_TYPE_P (gnu_type))
      && !(kind == VAR_DECL && Is_Aliased (gnat_object)))
    return size;

  /* If the object is a record that contains a template, add the size of the
     template to the specified size.  */
  if (TREE_CODE (gnu_type) == RECORD_TYPE
      && TYPE_CONTAINS_TEMPLATE_P (gnu_type))
    size = size_binop (PLUS_EXPR, DECL_SIZE (TYPE_FIELDS (gnu_type)), size);

  if (kind == VAR_DECL
      /* If a type needs strict alignment, a component of this type in
	 a packed record cannot be packed and thus uses the type size.  */
      || (kind == TYPE_DECL && Strict_Alignment (gnat_object)))
    type_size = TYPE_SIZE (gnu_type);
  else
    type_size = rm_size (gnu_type);

  /* Modify the size of a discriminated type to be the maximum size.  */
  if (type_size && CONTAINS_PLACEHOLDER_P (type_size))
    type_size = max_size (type_size, true);

  /* If this is an access type or a fat pointer, the minimum size is that given
     by the smallest integral mode that's valid for pointers.  */
  if (TREE_CODE (gnu_type) == POINTER_TYPE || TYPE_IS_FAT_POINTER_P (gnu_type))
    {
      enum machine_mode p_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
      while (!targetm.valid_pointer_mode (p_mode))
	p_mode = GET_MODE_WIDER_MODE (p_mode);
      type_size = bitsize_int (GET_MODE_BITSIZE (p_mode));
    }

  /* Issue an error either if the default size of the object isn't a constant
     or if the new size is smaller than it.  */
  if (TREE_CODE (type_size) != INTEGER_CST
      || TREE_OVERFLOW (type_size)
      || tree_int_cst_lt (size, type_size))
    {
      if (component_p)
	post_error_ne_tree
	  ("component size for& too small{, minimum allowed is ^}",
	   gnat_error_node, gnat_object, type_size);
      else
	post_error_ne_tree
	  ("size for& too small{, minimum allowed is ^}",
	   gnat_error_node, gnat_object, type_size);
      return NULL_TREE;
    }

  return size;
}

/* Similarly, but both validate and process a value of RM size.  This routine
   is only called for types.  */

static void
set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity)
{
  Node_Id gnat_attr_node;
  tree old_size, size;

  /* Do nothing if no size was specified.  */
  if (uint_size == No_Uint)
    return;

  /* Ignore a negative size since that corresponds to our back-annotation.  */
  if (UI_Lt (uint_size, Uint_0))
    return;

  /* Only issue an error if a Value_Size clause was explicitly given.
     Otherwise, we'd be duplicating an error on the Size clause.  */
  gnat_attr_node
    = Get_Attribute_Definition_Clause (gnat_entity, Attr_Value_Size);

  /* Get the size as an INTEGER_CST.  Issue an error if a size was specified
     but cannot be represented in bitsizetype.  */
  size = UI_To_gnu (uint_size, bitsizetype);
  if (TREE_OVERFLOW (size))
    {
      if (Present (gnat_attr_node))
	post_error_ne ("Value_Size for& is too large", gnat_attr_node,
		       gnat_entity);
      return;
    }

  /* Ignore a zero size unless a Value_Size clause exists, or a size clause
     exists, or this is an integer type, in which case the front-end will
     have always set it.  */
  if (No (gnat_attr_node)
      && integer_zerop (size)
      && !Has_Size_Clause (gnat_entity)
      && !Is_Discrete_Or_Fixed_Point_Type (gnat_entity))
    return;

  old_size = rm_size (gnu_type);

  /* If the old size is self-referential, get the maximum size.  */
  if (CONTAINS_PLACEHOLDER_P (old_size))
    old_size = max_size (old_size, true);

  /* Issue an error either if the old size of the object isn't a constant or
     if the new size is smaller than it.  The front-end has already verified
     this for scalar and packed array types.  */
  if (TREE_CODE (old_size) != INTEGER_CST
      || TREE_OVERFLOW (old_size)
      || (AGGREGATE_TYPE_P (gnu_type)
	  && !(TREE_CODE (gnu_type) == ARRAY_TYPE
	       && TYPE_PACKED_ARRAY_TYPE_P (gnu_type))
	  && !(TYPE_IS_PADDING_P (gnu_type)
	       && TREE_CODE (TREE_TYPE (TYPE_FIELDS (gnu_type))) == ARRAY_TYPE
	       && TYPE_PACKED_ARRAY_TYPE_P
		  (TREE_TYPE (TYPE_FIELDS (gnu_type))))
	  && tree_int_cst_lt (size, old_size)))
    {
      if (Present (gnat_attr_node))
	post_error_ne_tree
	  ("Value_Size for& too small{, minimum allowed is ^}",
	   gnat_attr_node, gnat_entity, old_size);
      return;
    }

  /* Otherwise, set the RM size proper for integral types...  */
  if ((TREE_CODE (gnu_type) == INTEGER_TYPE
       && Is_Discrete_Or_Fixed_Point_Type (gnat_entity))
      || (TREE_CODE (gnu_type) == ENUMERAL_TYPE
	  || TREE_CODE (gnu_type) == BOOLEAN_TYPE))
    SET_TYPE_RM_SIZE (gnu_type, size);

  /* ...or the Ada size for record and union types.  */
  else if (RECORD_OR_UNION_TYPE_P (gnu_type)
	   && !TYPE_FAT_POINTER_P (gnu_type))
    SET_TYPE_ADA_SIZE (gnu_type, size);
}

/* ALIGNMENT is a Uint giving the alignment specified for GNAT_ENTITY,
   a type or object whose present alignment is ALIGN.  If this alignment is
   valid, return it.  Otherwise, give an error and return ALIGN.  */

static unsigned int
validate_alignment (Uint alignment, Entity_Id gnat_entity, unsigned int align)
{
  unsigned int max_allowed_alignment = get_target_maximum_allowed_alignment ();
  unsigned int new_align;
  Node_Id gnat_error_node;

  /* Don't worry about checking alignment if alignment was not specified
     by the source program and we already posted an error for this entity.  */
  if (Error_Posted (gnat_entity) && !Has_Alignment_Clause (gnat_entity))
    return align;

  /* Post the error on the alignment clause if any.  Note, for the implicit
     base type of an array type, the alignment clause is on the first
     subtype.  */
  if (Present (Alignment_Clause (gnat_entity)))
    gnat_error_node = Expression (Alignment_Clause (gnat_entity));

  else if (Is_Itype (gnat_entity)
           && Is_Array_Type (gnat_entity)
           && Etype (gnat_entity) == gnat_entity
           && Present (Alignment_Clause (First_Subtype (gnat_entity))))
    gnat_error_node =
      Expression (Alignment_Clause (First_Subtype (gnat_entity)));

  else
    gnat_error_node = gnat_entity;

  /* Within GCC, an alignment is an integer, so we must make sure a value is
     specified that fits in that range.  Also, there is an upper bound to
     alignments we can support/allow.  */
  if (!UI_Is_In_Int_Range (alignment)
      || ((new_align = UI_To_Int (alignment)) > max_allowed_alignment))
    post_error_ne_num ("largest supported alignment for& is ^",
		       gnat_error_node, gnat_entity, max_allowed_alignment);
  else if (!(Present (Alignment_Clause (gnat_entity))
	     && From_At_Mod (Alignment_Clause (gnat_entity)))
	   && new_align * BITS_PER_UNIT < align)
    {
      unsigned int double_align;
      bool is_capped_double, align_clause;

      /* If the default alignment of "double" or larger scalar types is
	 specifically capped and the new alignment is above the cap, do
	 not post an error and change the alignment only if there is an
	 alignment clause; this makes it possible to have the associated
	 GCC type overaligned by default for performance reasons.  */
      if ((double_align = double_float_alignment) > 0)
	{
	  Entity_Id gnat_type
	    = Is_Type (gnat_entity) ? gnat_entity : Etype (gnat_entity);
	  is_capped_double
	    = is_double_float_or_array (gnat_type, &align_clause);
	}
      else if ((double_align = double_scalar_alignment) > 0)
	{
	  Entity_Id gnat_type
	    = Is_Type (gnat_entity) ? gnat_entity : Etype (gnat_entity);
	  is_capped_double
	    = is_double_scalar_or_array (gnat_type, &align_clause);
	}
      else
	is_capped_double = align_clause = false;

      if (is_capped_double && new_align >= double_align)
	{
	  if (align_clause)
	    align = new_align * BITS_PER_UNIT;
	}
      else
	{
	  if (is_capped_double)
	    align = double_align * BITS_PER_UNIT;

	  post_error_ne_num ("alignment for& must be at least ^",
			     gnat_error_node, gnat_entity,
			     align / BITS_PER_UNIT);
	}
    }
  else
    {
      new_align = (new_align > 0 ? new_align * BITS_PER_UNIT : 1);
      if (new_align > align)
	align = new_align;
    }

  return align;
}

/* Verify that OBJECT, a type or decl, is something we can implement
   atomically.  If not, give an error for GNAT_ENTITY.  COMP_P is true
   if we require atomic components.  */

static void
check_ok_for_atomic (tree object, Entity_Id gnat_entity, bool comp_p)
{
  Node_Id gnat_error_point = gnat_entity;
  Node_Id gnat_node;
  enum machine_mode mode;
  unsigned int align;
  tree size;

  /* There are three case of what OBJECT can be.  It can be a type, in which
     case we take the size, alignment and mode from the type.  It can be a
     declaration that was indirect, in which case the relevant values are
     that of the type being pointed to, or it can be a normal declaration,
     in which case the values are of the decl.  The code below assumes that
     OBJECT is either a type or a decl.  */
  if (TYPE_P (object))
    {
      /* If this is an anonymous base type, nothing to check.  Error will be
	 reported on the source type.  */
      if (!Comes_From_Source (gnat_entity))
	return;

      mode = TYPE_MODE (object);
      align = TYPE_ALIGN (object);
      size = TYPE_SIZE (object);
    }
  else if (DECL_BY_REF_P (object))
    {
      mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (object)));
      align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (object)));
      size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (object)));
    }
  else
    {
      mode = DECL_MODE (object);
      align = DECL_ALIGN (object);
      size = DECL_SIZE (object);
    }

  /* Consider all floating-point types atomic and any types that that are
     represented by integers no wider than a machine word.  */
  if (GET_MODE_CLASS (mode) == MODE_FLOAT
      || ((GET_MODE_CLASS (mode) == MODE_INT
	   || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
	  && GET_MODE_BITSIZE (mode) <= BITS_PER_WORD))
    return;

  /* For the moment, also allow anything that has an alignment equal
     to its size and which is smaller than a word.  */
  if (size && TREE_CODE (size) == INTEGER_CST
      && compare_tree_int (size, align) == 0
      && align <= BITS_PER_WORD)
    return;

  for (gnat_node = First_Rep_Item (gnat_entity); Present (gnat_node);
       gnat_node = Next_Rep_Item (gnat_node))
    {
      if (!comp_p && Nkind (gnat_node) == N_Pragma
	  && (Get_Pragma_Id (Chars (Pragma_Identifier (gnat_node)))
              == Pragma_Atomic))
	gnat_error_point = First (Pragma_Argument_Associations (gnat_node));
      else if (comp_p && Nkind (gnat_node) == N_Pragma
	       && (Get_Pragma_Id (Chars (Pragma_Identifier (gnat_node)))
		   == Pragma_Atomic_Components))
	gnat_error_point = First (Pragma_Argument_Associations (gnat_node));
    }

  if (comp_p)
    post_error_ne ("atomic access to component of & cannot be guaranteed",
		   gnat_error_point, gnat_entity);
  else
    post_error_ne ("atomic access to & cannot be guaranteed",
		   gnat_error_point, gnat_entity);
}


/* Helper for the intrin compatibility checks family.  Evaluate whether
   two types are definitely incompatible.  */

static bool
intrin_types_incompatible_p (tree t1, tree t2)
{
  enum tree_code code;

  if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
    return false;

  if (TYPE_MODE (t1) != TYPE_MODE (t2))
    return true;

  if (TREE_CODE (t1) != TREE_CODE (t2))
    return true;

  code = TREE_CODE (t1);

  switch (code)
    {
    case INTEGER_TYPE:
    case REAL_TYPE:
      return TYPE_PRECISION (t1) != TYPE_PRECISION (t2);

    case POINTER_TYPE:
    case REFERENCE_TYPE:
      /* Assume designated types are ok.  We'd need to account for char * and
	 void * variants to do better, which could rapidly get messy and isn't
	 clearly worth the effort.  */
      return false;

    default:
      break;
    }

  return false;
}

/* Helper for intrin_profiles_compatible_p, to perform compatibility checks
   on the Ada/builtin argument lists for the INB binding.  */

static bool
intrin_arglists_compatible_p (intrin_binding_t * inb)
{
  function_args_iterator ada_iter, btin_iter;

  function_args_iter_init (&ada_iter, inb->ada_fntype);
  function_args_iter_init (&btin_iter, inb->btin_fntype);

  /* Sequence position of the last argument we checked.  */
  int argpos = 0;

  while (1)
    {
      tree ada_type = function_args_iter_cond (&ada_iter);
      tree btin_type = function_args_iter_cond (&btin_iter);

      /* If we've exhausted both lists simultaneously, we're done.  */
      if (ada_type == NULL_TREE && btin_type == NULL_TREE)
	break;

      /* If one list is shorter than the other, they fail to match.  */
      if (ada_type == NULL_TREE || btin_type == NULL_TREE)
	return false;

      /* If we're done with the Ada args and not with the internal builtin
	 args, or the other way around, complain.  */
      if (ada_type == void_type_node
	  && btin_type != void_type_node)
	{
	  post_error ("?Ada arguments list too short!", inb->gnat_entity);
	  return false;
	}

      if (btin_type == void_type_node
	  && ada_type != void_type_node)
	{
	  post_error_ne_num ("?Ada arguments list too long ('> ^)!",
			     inb->gnat_entity, inb->gnat_entity, argpos);
	  return false;
	}

      /* Otherwise, check that types match for the current argument.  */
      argpos ++;
      if (intrin_types_incompatible_p (ada_type, btin_type))
	{
	  post_error_ne_num ("?intrinsic binding type mismatch on argument ^!",
			     inb->gnat_entity, inb->gnat_entity, argpos);
	  return false;
	}


      function_args_iter_next (&ada_iter);
      function_args_iter_next (&btin_iter);
    }

  return true;
}

/* Helper for intrin_profiles_compatible_p, to perform compatibility checks
   on the Ada/builtin return values for the INB binding.  */

static bool
intrin_return_compatible_p (intrin_binding_t * inb)
{
  tree ada_return_type = TREE_TYPE (inb->ada_fntype);
  tree btin_return_type = TREE_TYPE (inb->btin_fntype);

  /* Accept function imported as procedure, common and convenient.  */
  if (VOID_TYPE_P (ada_return_type)
      && !VOID_TYPE_P (btin_return_type))
    return true;

  /* If return type is Address (integer type), map it to void *.  */
  if (Is_Descendent_Of_Address (Etype (inb->gnat_entity)))
    ada_return_type = ptr_void_type_node;

  /* Check return types compatibility otherwise.  Note that this
     handles void/void as well.  */
  if (intrin_types_incompatible_p (btin_return_type, ada_return_type))
    {
      post_error ("?intrinsic binding type mismatch on return value!",
		  inb->gnat_entity);
      return false;
    }

  return true;
}

/* Check and return whether the Ada and gcc builtin profiles bound by INB are
   compatible.  Issue relevant warnings when they are not.

   This is intended as a light check to diagnose the most obvious cases, not
   as a full fledged type compatibility predicate.  It is the programmer's
   responsibility to ensure correctness of the Ada declarations in Imports,
   especially when binding straight to a compiler internal.  */

static bool
intrin_profiles_compatible_p (intrin_binding_t * inb)
{
  /* Check compatibility on return values and argument lists, each responsible
     for posting warnings as appropriate.  Ensure use of the proper sloc for
     this purpose.  */

  bool arglists_compatible_p, return_compatible_p;
  location_t saved_location = input_location;

  Sloc_to_locus (Sloc (inb->gnat_entity), &input_location);

  return_compatible_p = intrin_return_compatible_p (inb);
  arglists_compatible_p = intrin_arglists_compatible_p (inb);

  input_location = saved_location;

  return return_compatible_p && arglists_compatible_p;
}

/* Return a FIELD_DECL node modeled on OLD_FIELD.  FIELD_TYPE is its type
   and RECORD_TYPE is the type of the parent.  If SIZE is nonzero, it is the
   specified size for this field.  POS_LIST is a position list describing
   the layout of OLD_FIELD and SUBST_LIST a substitution list to be applied
   to this layout.  */

static tree
create_field_decl_from (tree old_field, tree field_type, tree record_type,
			tree size, tree pos_list,
			vec<subst_pair> subst_list)
{
  tree t = TREE_VALUE (purpose_member (old_field, pos_list));
  tree pos = TREE_VEC_ELT (t, 0), bitpos = TREE_VEC_ELT (t, 2);
  unsigned int offset_align = tree_low_cst (TREE_VEC_ELT (t, 1), 1);
  tree new_pos, new_field;
  unsigned int i;
  subst_pair *s;

  if (CONTAINS_PLACEHOLDER_P (pos))
    FOR_EACH_VEC_ELT (subst_list, i, s)
      pos = SUBSTITUTE_IN_EXPR (pos, s->discriminant, s->replacement);

  /* If the position is now a constant, we can set it as the position of the
     field when we make it.  Otherwise, we need to deal with it specially.  */
  if (TREE_CONSTANT (pos))
    new_pos = bit_from_pos (pos, bitpos);
  else
    new_pos = NULL_TREE;

  new_field
    = create_field_decl (DECL_NAME (old_field), field_type, record_type,
			 size, new_pos, DECL_PACKED (old_field),
			 !DECL_NONADDRESSABLE_P (old_field));

  if (!new_pos)
    {
      normalize_offset (&pos, &bitpos, offset_align);
      DECL_FIELD_OFFSET (new_field) = pos;
      DECL_FIELD_BIT_OFFSET (new_field) = bitpos;
      SET_DECL_OFFSET_ALIGN (new_field, offset_align);
      DECL_SIZE (new_field) = size;
      DECL_SIZE_UNIT (new_field)
	= convert (sizetype,
		   size_binop (CEIL_DIV_EXPR, size, bitsize_unit_node));
      layout_decl (new_field, DECL_OFFSET_ALIGN (new_field));
    }

  DECL_INTERNAL_P (new_field) = DECL_INTERNAL_P (old_field);
  SET_DECL_ORIGINAL_FIELD_TO_FIELD (new_field, old_field);
  DECL_DISCRIMINANT_NUMBER (new_field) = DECL_DISCRIMINANT_NUMBER (old_field);
  TREE_THIS_VOLATILE (new_field) = TREE_THIS_VOLATILE (old_field);

  return new_field;
}

/* Create the REP part of RECORD_TYPE with REP_TYPE.  If MIN_SIZE is nonzero,
   it is the minimal size the REP_PART must have.  */

static tree
create_rep_part (tree rep_type, tree record_type, tree min_size)
{
  tree field;

  if (min_size && !tree_int_cst_lt (TYPE_SIZE (rep_type), min_size))
    min_size = NULL_TREE;

  field = create_field_decl (get_identifier ("REP"), rep_type, record_type,
			     min_size, bitsize_zero_node, 0, 1);
  DECL_INTERNAL_P (field) = 1;

  return field;
}

/* Return the REP part of RECORD_TYPE, if any.  Otherwise return NULL.  */

static tree
get_rep_part (tree record_type)
{
  tree field = TYPE_FIELDS (record_type);

  /* The REP part is the first field, internal, another record, and its name
     starts with an 'R'.  */
  if (field
      && DECL_INTERNAL_P (field)
      && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
      && IDENTIFIER_POINTER (DECL_NAME (field)) [0] == 'R')
    return field;

  return NULL_TREE;
}

/* Return the variant part of RECORD_TYPE, if any.  Otherwise return NULL.  */

tree
get_variant_part (tree record_type)
{
  tree field;

  /* The variant part is the only internal field that is a qualified union.  */
  for (field = TYPE_FIELDS (record_type); field; field = DECL_CHAIN (field))
    if (DECL_INTERNAL_P (field)
	&& TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE)
      return field;

  return NULL_TREE;
}

/* Return a new variant part modeled on OLD_VARIANT_PART.  VARIANT_LIST is
   the list of variants to be used and RECORD_TYPE is the type of the parent.
   POS_LIST is a position list describing the layout of fields present in
   OLD_VARIANT_PART and SUBST_LIST a substitution list to be applied to this
   layout.  */

static tree
create_variant_part_from (tree old_variant_part,
			  vec<variant_desc> variant_list,
			  tree record_type, tree pos_list,
			  vec<subst_pair> subst_list)
{
  tree offset = DECL_FIELD_OFFSET (old_variant_part);
  tree old_union_type = TREE_TYPE (old_variant_part);
  tree new_union_type, new_variant_part;
  tree union_field_list = NULL_TREE;
  variant_desc *v;
  unsigned int i;

  /* First create the type of the variant part from that of the old one.  */
  new_union_type = make_node (QUAL_UNION_TYPE);
  TYPE_NAME (new_union_type)
    = concat_name (TYPE_NAME (record_type),
		   IDENTIFIER_POINTER (DECL_NAME (old_variant_part)));

  /* If the position of the variant part is constant, subtract it from the
     size of the type of the parent to get the new size.  This manual CSE
     reduces the code size when not optimizing.  */
  if (TREE_CODE (offset) == INTEGER_CST)
    {
      tree bitpos = DECL_FIELD_BIT_OFFSET (old_variant_part);
      tree first_bit = bit_from_pos (offset, bitpos);
      TYPE_SIZE (new_union_type)
	= size_binop (MINUS_EXPR, TYPE_SIZE (record_type), first_bit);
      TYPE_SIZE_UNIT (new_union_type)
	= size_binop (MINUS_EXPR, TYPE_SIZE_UNIT (record_type),
		      byte_from_pos (offset, bitpos));
      SET_TYPE_ADA_SIZE (new_union_type,
			 size_binop (MINUS_EXPR, TYPE_ADA_SIZE (record_type),
 				     first_bit));
      TYPE_ALIGN (new_union_type) = TYPE_ALIGN (old_union_type);
      relate_alias_sets (new_union_type, old_union_type, ALIAS_SET_COPY);
    }
  else
    copy_and_substitute_in_size (new_union_type, old_union_type, subst_list);

  /* Now finish up the new variants and populate the union type.  */
  FOR_EACH_VEC_ELT_REVERSE (variant_list, i, v)
    {
      tree old_field = v->field, new_field;
      tree old_variant, old_variant_subpart, new_variant, field_list;

      /* Skip variants that don't belong to this nesting level.  */
      if (DECL_CONTEXT (old_field) != old_union_type)
	continue;

      /* Retrieve the list of fields already added to the new variant.  */
      new_variant = v->new_type;
      field_list = TYPE_FIELDS (new_variant);

      /* If the old variant had a variant subpart, we need to create a new
	 variant subpart and add it to the field list.  */
      old_variant = v->type;
      old_variant_subpart = get_variant_part (old_variant);
      if (old_variant_subpart)
	{
	  tree new_variant_subpart
	    = create_variant_part_from (old_variant_subpart, variant_list,
					new_variant, pos_list, subst_list);
	  DECL_CHAIN (new_variant_subpart) = field_list;
	  field_list = new_variant_subpart;
	}

      /* Finish up the new variant and create the field.  No need for debug
	 info thanks to the XVS type.  */
      finish_record_type (new_variant, nreverse (field_list), 2, false);
      compute_record_mode (new_variant);
      create_type_decl (TYPE_NAME (new_variant), new_variant, NULL,
			true, false, Empty);

      new_field
	= create_field_decl_from (old_field, new_variant, new_union_type,
				  TYPE_SIZE (new_variant),
				  pos_list, subst_list);
      DECL_QUALIFIER (new_field) = v->qual;
      DECL_INTERNAL_P (new_field) = 1;
      DECL_CHAIN (new_field) = union_field_list;
      union_field_list = new_field;
    }

  /* Finish up the union type and create the variant part.  No need for debug
     info thanks to the XVS type.  Note that we don't reverse the field list
     because VARIANT_LIST has been traversed in reverse order.  */
  finish_record_type (new_union_type, union_field_list, 2, false);
  compute_record_mode (new_union_type);
  create_type_decl (TYPE_NAME (new_union_type), new_union_type, NULL,
		    true, false, Empty);

  new_variant_part
    = create_field_decl_from (old_variant_part, new_union_type, record_type,
			      TYPE_SIZE (new_union_type),
			      pos_list, subst_list);
  DECL_INTERNAL_P (new_variant_part) = 1;

  /* With multiple discriminants it is possible for an inner variant to be
     statically selected while outer ones are not; in this case, the list
     of fields of the inner variant is not flattened and we end up with a
     qualified union with a single member.  Drop the useless container.  */
  if (!DECL_CHAIN (union_field_list))
    {
      DECL_CONTEXT (union_field_list) = record_type;
      DECL_FIELD_OFFSET (union_field_list)
	= DECL_FIELD_OFFSET (new_variant_part);
      DECL_FIELD_BIT_OFFSET (union_field_list)
	= DECL_FIELD_BIT_OFFSET (new_variant_part);
      SET_DECL_OFFSET_ALIGN (union_field_list,
			     DECL_OFFSET_ALIGN (new_variant_part));
      new_variant_part = union_field_list;
    }

  return new_variant_part;
}

/* Copy the size (and alignment and alias set) from OLD_TYPE to NEW_TYPE,
   which are both RECORD_TYPE, after applying the substitutions described
   in SUBST_LIST.  */

static void
copy_and_substitute_in_size (tree new_type, tree old_type,
			     vec<subst_pair> subst_list)
{
  unsigned int i;
  subst_pair *s;

  TYPE_SIZE (new_type) = TYPE_SIZE (old_type);
  TYPE_SIZE_UNIT (new_type) = TYPE_SIZE_UNIT (old_type);
  SET_TYPE_ADA_SIZE (new_type, TYPE_ADA_SIZE (old_type));
  TYPE_ALIGN (new_type) = TYPE_ALIGN (old_type);
  relate_alias_sets (new_type, old_type, ALIAS_SET_COPY);

  if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (new_type)))
    FOR_EACH_VEC_ELT (subst_list, i, s)
      TYPE_SIZE (new_type)
	= SUBSTITUTE_IN_EXPR (TYPE_SIZE (new_type),
			      s->discriminant, s->replacement);

  if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE_UNIT (new_type)))
    FOR_EACH_VEC_ELT (subst_list, i, s)
      TYPE_SIZE_UNIT (new_type)
	= SUBSTITUTE_IN_EXPR (TYPE_SIZE_UNIT (new_type),
			      s->discriminant, s->replacement);

  if (CONTAINS_PLACEHOLDER_P (TYPE_ADA_SIZE (new_type)))
    FOR_EACH_VEC_ELT (subst_list, i, s)
      SET_TYPE_ADA_SIZE
	(new_type, SUBSTITUTE_IN_EXPR (TYPE_ADA_SIZE (new_type),
				       s->discriminant, s->replacement));

  /* Finalize the size.  */
  TYPE_SIZE (new_type) = variable_size (TYPE_SIZE (new_type));
  TYPE_SIZE_UNIT (new_type) = variable_size (TYPE_SIZE_UNIT (new_type));
}

/* Given a type T, a FIELD_DECL F, and a replacement value R, return a
   type with all size expressions that contain F in a PLACEHOLDER_EXPR
   updated by replacing F with R.

   The function doesn't update the layout of the type, i.e. it assumes
   that the substitution is purely formal.  That's why the replacement
   value R must itself contain a PLACEHOLDER_EXPR.  */

tree
substitute_in_type (tree t, tree f, tree r)
{
  tree nt;

  gcc_assert (CONTAINS_PLACEHOLDER_P (r));

  switch (TREE_CODE (t))
    {
    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
    case REAL_TYPE:

      /* First the domain types of arrays.  */
      if (CONTAINS_PLACEHOLDER_P (TYPE_GCC_MIN_VALUE (t))
	  || CONTAINS_PLACEHOLDER_P (TYPE_GCC_MAX_VALUE (t)))
	{
	  tree low = SUBSTITUTE_IN_EXPR (TYPE_GCC_MIN_VALUE (t), f, r);
	  tree high = SUBSTITUTE_IN_EXPR (TYPE_GCC_MAX_VALUE (t), f, r);

	  if (low == TYPE_GCC_MIN_VALUE (t) && high == TYPE_GCC_MAX_VALUE (t))
	    return t;

	  nt = copy_type (t);
	  TYPE_GCC_MIN_VALUE (nt) = low;
	  TYPE_GCC_MAX_VALUE (nt) = high;

	  if (TREE_CODE (t) == INTEGER_TYPE && TYPE_INDEX_TYPE (t))
	    SET_TYPE_INDEX_TYPE
	      (nt, substitute_in_type (TYPE_INDEX_TYPE (t), f, r));

	  return nt;
	}

      /* Then the subtypes.  */
      if (CONTAINS_PLACEHOLDER_P (TYPE_RM_MIN_VALUE (t))
	  || CONTAINS_PLACEHOLDER_P (TYPE_RM_MAX_VALUE (t)))
	{
	  tree low = SUBSTITUTE_IN_EXPR (TYPE_RM_MIN_VALUE (t), f, r);
	  tree high = SUBSTITUTE_IN_EXPR (TYPE_RM_MAX_VALUE (t), f, r);

	  if (low == TYPE_RM_MIN_VALUE (t) && high == TYPE_RM_MAX_VALUE (t))
	    return t;

	  nt = copy_type (t);
	  SET_TYPE_RM_MIN_VALUE (nt, low);
	  SET_TYPE_RM_MAX_VALUE (nt, high);

	  return nt;
	}

      return t;

    case COMPLEX_TYPE:
      nt = substitute_in_type (TREE_TYPE (t), f, r);
      if (nt == TREE_TYPE (t))
	return t;

      return build_complex_type (nt);

    case FUNCTION_TYPE:
      /* These should never show up here.  */
      gcc_unreachable ();

    case ARRAY_TYPE:
      {
	tree component = substitute_in_type (TREE_TYPE (t), f, r);
	tree domain = substitute_in_type (TYPE_DOMAIN (t), f, r);

	if (component == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
	  return t;

	nt = build_nonshared_array_type (component, domain);
	TYPE_ALIGN (nt) = TYPE_ALIGN (t);
	TYPE_USER_ALIGN (nt) = TYPE_USER_ALIGN (t);
	SET_TYPE_MODE (nt, TYPE_MODE (t));
	TYPE_SIZE (nt) = SUBSTITUTE_IN_EXPR (TYPE_SIZE (t), f, r);
	TYPE_SIZE_UNIT (nt) = SUBSTITUTE_IN_EXPR (TYPE_SIZE_UNIT (t), f, r);
	TYPE_NONALIASED_COMPONENT (nt) = TYPE_NONALIASED_COMPONENT (t);
	TYPE_MULTI_ARRAY_P (nt) = TYPE_MULTI_ARRAY_P (t);
	TYPE_CONVENTION_FORTRAN_P (nt) = TYPE_CONVENTION_FORTRAN_P (t);
	return nt;
      }

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      {
	bool changed_field = false;
	tree field;

	/* Start out with no fields, make new fields, and chain them
	   in.  If we haven't actually changed the type of any field,
	   discard everything we've done and return the old type.  */
	nt = copy_type (t);
	TYPE_FIELDS (nt) = NULL_TREE;

	for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
	  {
	    tree new_field = copy_node (field), new_n;

	    new_n = substitute_in_type (TREE_TYPE (field), f, r);
	    if (new_n != TREE_TYPE (field))
	      {
		TREE_TYPE (new_field) = new_n;
		changed_field = true;
	      }

	    new_n = SUBSTITUTE_IN_EXPR (DECL_FIELD_OFFSET (field), f, r);
	    if (new_n != DECL_FIELD_OFFSET (field))
	      {
		DECL_FIELD_OFFSET (new_field) = new_n;
		changed_field = true;
	      }

	    /* Do the substitution inside the qualifier, if any.  */
	    if (TREE_CODE (t) == QUAL_UNION_TYPE)
	      {
		new_n = SUBSTITUTE_IN_EXPR (DECL_QUALIFIER (field), f, r);
		if (new_n != DECL_QUALIFIER (field))
		  {
		    DECL_QUALIFIER (new_field) = new_n;
		    changed_field = true;
		  }
	      }

	    DECL_CONTEXT (new_field) = nt;
	    SET_DECL_ORIGINAL_FIELD_TO_FIELD (new_field, field);

	    DECL_CHAIN (new_field) = TYPE_FIELDS (nt);
	    TYPE_FIELDS (nt) = new_field;
	  }

	if (!changed_field)
	  return t;

	TYPE_FIELDS (nt) = nreverse (TYPE_FIELDS (nt));
	TYPE_SIZE (nt) = SUBSTITUTE_IN_EXPR (TYPE_SIZE (t), f, r);
	TYPE_SIZE_UNIT (nt) = SUBSTITUTE_IN_EXPR (TYPE_SIZE_UNIT (t), f, r);
	SET_TYPE_ADA_SIZE (nt, SUBSTITUTE_IN_EXPR (TYPE_ADA_SIZE (t), f, r));
	return nt;
      }

    default:
      return t;
    }
}

/* Return the RM size of GNU_TYPE.  This is the actual number of bits
   needed to represent the object.  */

tree
rm_size (tree gnu_type)
{
  /* For integral types, we store the RM size explicitly.  */
  if (INTEGRAL_TYPE_P (gnu_type) && TYPE_RM_SIZE (gnu_type))
    return TYPE_RM_SIZE (gnu_type);

  /* Return the RM size of the actual data plus the size of the template.  */
  if (TREE_CODE (gnu_type) == RECORD_TYPE
      && TYPE_CONTAINS_TEMPLATE_P (gnu_type))
    return
      size_binop (PLUS_EXPR,
		  rm_size (TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_type)))),
		  DECL_SIZE (TYPE_FIELDS (gnu_type)));

  /* For record or union types, we store the size explicitly.  */
  if (RECORD_OR_UNION_TYPE_P (gnu_type)
      && !TYPE_FAT_POINTER_P (gnu_type)
      && TYPE_ADA_SIZE (gnu_type))
    return TYPE_ADA_SIZE (gnu_type);

  /* For other types, this is just the size.  */
  return TYPE_SIZE (gnu_type);
}

/* Return the name to be used for GNAT_ENTITY.  If a type, create a
   fully-qualified name, possibly with type information encoding.
   Otherwise, return the name.  */

tree
get_entity_name (Entity_Id gnat_entity)
{
  Get_Encoded_Name (gnat_entity);
  return get_identifier_with_length (Name_Buffer, Name_Len);
}

/* Return an identifier representing the external name to be used for
   GNAT_ENTITY.  If SUFFIX is specified, the name is followed by "___"
   and the specified suffix.  */

tree
create_concat_name (Entity_Id gnat_entity, const char *suffix)
{
  Entity_Kind kind = Ekind (gnat_entity);

  if (suffix)
    {
      String_Template temp = {1, (int) strlen (suffix)};
      Fat_Pointer fp = {suffix, &temp};
      Get_External_Name_With_Suffix (gnat_entity, fp);
    }
  else
    Get_External_Name (gnat_entity, 0);

  /* A variable using the Stdcall convention lives in a DLL.  We adjust
     its name to use the jump table, the _imp__NAME contains the address
     for the NAME variable.  */
  if ((kind == E_Variable || kind == E_Constant)
      && Has_Stdcall_Convention (gnat_entity))
    {
      const int len = 6 + Name_Len;
      char *new_name = (char *) alloca (len + 1);
      strcpy (new_name, "_imp__");
      strcat (new_name, Name_Buffer);
      return get_identifier_with_length (new_name, len);
    }

  return get_identifier_with_length (Name_Buffer, Name_Len);
}

/* Given GNU_NAME, an IDENTIFIER_NODE containing a name and SUFFIX, a
   string, return a new IDENTIFIER_NODE that is the concatenation of
   the name followed by "___" and the specified suffix.  */

tree
concat_name (tree gnu_name, const char *suffix)
{
  const int len = IDENTIFIER_LENGTH (gnu_name) + 3 + strlen (suffix);
  char *new_name = (char *) alloca (len + 1);
  strcpy (new_name, IDENTIFIER_POINTER (gnu_name));
  strcat (new_name, "___");
  strcat (new_name, suffix);
  return get_identifier_with_length (new_name, len);
}

#include "gt-ada-decl.h"
