/****************************************************************************
 *                                                                          *
 *                         GNAT COMPILER COMPONENTS                         *
 *                                                                          *
 *                                T R A N S                                 *
 *                                                                          *
 *                          C Implementation File                           *
 *                                                                          *
 *          Copyright (C) 1992-2025, 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  distributed  with GNAT;  see 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 "target.h"
#include "function.h"
#include "bitmap.h"
#include "tree.h"
#include "gimple-expr.h"
#include "stringpool.h"
#include "cgraph.h"
#include "predict.h"
#include "diagnostic.h"
#include "alias.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "stmt.h"
#include "varasm.h"
#include "output.h"
#include "debug.h"
#include "libfuncs.h"	/* For set_stack_check_libfunc.  */
#include "tree-iterator.h"
#include "gimplify.h"
#include "opts.h"
#include "common/common-target.h"
#include "gomp-constants.h"
#include "stringpool.h"
#include "attribs.h"
#include "tree-nested.h"

#include "ada.h"
#include "adadecode.h"
#include "types.h"
#include "atree.h"
#include "namet.h"
#include "nlists.h"
#include "snames.h"
#include "stringt.h"
#include "uintp.h"
#include "urealp.h"
#include "fe.h"
#include "sinfo.h"
#include "einfo.h"
#include "gadaint.h"
#include "ada-tree.h"
#include "gigi.h"

/* The following #include is for strub_make_callable.

   This function marks a function as safe to call from strub contexts.  We mark
   Ada subprograms that may be called implicitly by the compiler, and that won't
   leave on the stack caller data passed to them.  This stops implicit calls
   introduced in subprograms that have their stack scrubbed from being flagged
   as unsafe, even in -fstrub=strict mode.

   These subprograms are also marked with the strub(callable) attribute in Ada
   sources, but their declarations aren't necessarily imported by GNAT, or made
   visible to gigi, in units that end up relying on them.  So when gigi
   introduces their declarations on its own, it must also add the attribute, by
   calling strub_make_callable.  */
#include "ipa-strub.h"

/* We should avoid allocating more than ALLOCA_THRESHOLD bytes via alloca,
   for fear of running out of stack space.  If we need more, we use xmalloc
   instead.  */
#define ALLOCA_THRESHOLD 1000

/* Pointers to front-end tables accessed through macros.  */
Node_Header *Node_Offsets_Ptr;
any_slot *Slots_Ptr;
Node_Id *Next_Node_Ptr;
Node_Id *Prev_Node_Ptr;
struct Elist_Header *Elists_Ptr;
struct Elmt_Item *Elmts_Ptr;
struct String_Entry *Strings_Ptr;
Char_Code *String_Chars_Ptr;
struct List_Header *List_Headers_Ptr;

/* Highest number in the front-end node table.  */
int max_gnat_nodes;

/* True when gigi is being called on an analyzed but unexpanded
   tree, and the only purpose of the call is to properly annotate
   types with representation information.  */
bool type_annotate_only;

/* List of N_Validate_Unchecked_Conversion nodes in the unit.  */
static vec<Node_Id> gnat_validate_uc_list;

/* List of expressions of pragma Compile_Time_{Error|Warning} in the unit.  */
static vec<Node_Id> gnat_compile_time_expr_list;

/* When not optimizing, we cache the 'First, 'Last and 'Length attributes
   of unconstrained array IN parameters to avoid emitting a great deal of
   redundant instructions to recompute them each time.  */
struct GTY (()) parm_attr_d {
  int id; /* GTY doesn't like Entity_Id.  */
  int dim;
  tree first;
  tree last;
  tree length;
};

typedef struct parm_attr_d *parm_attr;

/* Structure used to record information for a function.  */
struct GTY(()) language_function {
  vec<parm_attr, va_gc> *parm_attr_cache;
  bitmap named_ret_val;
  vec<tree, va_gc> *other_ret_val;
  int gnat_ret;
};

#define f_parm_attr_cache \
  DECL_STRUCT_FUNCTION (current_function_decl)->language->parm_attr_cache

#define f_named_ret_val \
  DECL_STRUCT_FUNCTION (current_function_decl)->language->named_ret_val

#define f_other_ret_val \
  DECL_STRUCT_FUNCTION (current_function_decl)->language->other_ret_val

#define f_gnat_ret \
  DECL_STRUCT_FUNCTION (current_function_decl)->language->gnat_ret

/* A structure used to gather together information about a statement group.
   We use this to gather related statements, for example the "then" part
   of a IF.  In the case where it represents a lexical scope, we may also
   have a BLOCK node corresponding to it and/or cleanups.  */

struct GTY((chain_next ("%h.previous"))) stmt_group {
  struct stmt_group *previous;	/* Previous code group.  */
  tree stmt_list;		/* List of statements for this code group.  */
  tree block;			/* BLOCK for this code group, if any.  */
  tree cleanups;		/* Cleanups for this code group, if any.  */
};

static GTY(()) struct stmt_group *current_stmt_group;

/* List of unused struct stmt_group nodes.  */
static GTY((deletable)) struct stmt_group *stmt_group_free_list;

/* A structure used to record information on elaboration procedures
   we've made and need to process.

   ??? gnat_node should be Node_Id, but gengtype gets confused.  */

struct GTY((chain_next ("%h.next"))) elab_info {
  struct elab_info *next;	/* Pointer to next in chain.  */
  tree elab_proc;		/* Elaboration procedure.  */
  int gnat_node;		/* The N_Compilation_Unit.  */
};

static GTY(()) struct elab_info *elab_info_list;

/* Stack of exception pointer variables.  Each entry is the VAR_DECL
   that stores the address of the raised exception.  Nonzero means we
   are in an exception handler.  Not used in the zero-cost case.  */
static GTY(()) vec<tree, va_gc> *gnu_except_ptr_stack;

/* In ZCX case, current exception pointer.  Used to re-raise it.  */
static GTY(()) tree gnu_incoming_exc_ptr;

/* Stack for storing the current elaboration procedure decl.  */
static GTY(()) vec<tree, va_gc> *gnu_elab_proc_stack;

/* Stack of labels to be used as a goto target instead of a return in
   some functions.  See processing for N_Subprogram_Body.  */
static GTY(()) vec<tree, va_gc> *gnu_return_label_stack;

/* Stack of variable for the return value of a function with copy-in/copy-out
   parameters.  See processing for N_Subprogram_Body.  */
static GTY(()) vec<tree, va_gc> *gnu_return_var_stack;

/* Structure used to record information for a range check.  */
struct GTY(()) range_check_info_d {
  tree low_bound;
  tree high_bound;
  tree disp;
  bool neg_p;
  tree type;
  tree invariant_cond;
  tree inserted_cond;
};

typedef struct range_check_info_d *range_check_info;

/* Structure used to record information for a loop.  */
struct GTY(()) loop_info_d {
  tree fndecl;
  tree stmt;
  tree loop_var;
  tree low_bound;
  tree high_bound;
  tree omp_loop_clauses;
  tree omp_construct_clauses;
  enum tree_code omp_code;
  vec<range_check_info, va_gc> *checks;
  vec<tree, va_gc> *invariants;
};

typedef struct loop_info_d *loop_info;

/* Stack of loop_info structures associated with LOOP_STMT nodes.  */
static GTY(()) vec<loop_info, va_gc> *gnu_loop_stack;

/* The stacks for N_{Push,Pop}_*_Label.  */
static vec<Entity_Id> gnu_constraint_error_label_stack;
static vec<Entity_Id> gnu_storage_error_label_stack;
static vec<Entity_Id> gnu_program_error_label_stack;

/* Map GNAT tree codes to GCC tree codes for simple expressions.  */
static enum tree_code gnu_codes[Number_Node_Kinds];

/* Map from identifier nodes to namespace decls.  */
static GTY(()) hash_map<tree, tree> *namespace_map;

static void init_code_table (void);
static tree get_elaboration_procedure (void);
static void Compilation_Unit_to_gnu (Node_Id);
static bool empty_stmt_list_p (tree);
static void record_code_position (Node_Id);
static void insert_code_for (Node_Id);
static void add_cleanup (tree, Node_Id);
static void add_stmt_list (List_Id);
static tree build_stmt_group (List_Id, bool);
static inline bool stmt_group_may_fallthru (void);
static enum gimplify_status gnat_gimplify_stmt (tree *);
static void elaborate_all_entities (Node_Id);
static void process_freeze_entity (Node_Id);
static void process_decls (List_Id, List_Id, bool, bool);
static tree emit_check (tree, tree, int, Node_Id);
static tree build_unary_op_trapv (enum tree_code, tree, tree, Node_Id);
static tree build_binary_op_trapv (enum tree_code, tree, tree, tree, Node_Id);
static tree convert_with_check (Entity_Id, tree, bool, bool, Node_Id);
static bool addressable_p (tree, tree, bool);
static bool aliasable_p (tree, tree);
static tree assoc_to_constructor (Entity_Id, Node_Id, tree);
static tree pos_to_constructor (Node_Id, tree);
static void validate_unchecked_conversion (Node_Id);
static void set_expr_location_from_node (tree, Node_Id, bool = false);
static void set_gnu_expr_location_from_node (tree, Node_Id);
static bool set_end_locus_from_node (tree, Node_Id);
static int lvalue_required_p (Node_Id, tree, bool, bool);
static tree build_raise_check (int, enum exception_info_kind);
static tree create_init_temporary (const char *, tree, tree *, Node_Id);
static bool maybe_make_gnu_thunk (Entity_Id gnat_thunk, tree gnu_thunk);

/* This makes gigi's file_info_ptr visible in this translation unit,
   so that Sloc_to_locus can look it up when deciding whether to map
   decls to instances.  */

static struct File_Info_Type *file_map;

/* Return the string of the identifier allocated for the file name Id.  */

static const char*
File_Name_to_gnu (Name_Id Id)
{
  /* __gnat_to_canonical_file_spec translates file names from pragmas
     Source_Reference that contain host style syntax not understood by GDB.  */
  const char *name = __gnat_to_canonical_file_spec (Get_Name_String (Id));

  /* Use the identifier table to make a permanent copy of the file name as
     the name table gets reallocated after Gigi returns but before all the
     debugging information is output.  */
  return IDENTIFIER_POINTER (get_identifier (name));
}

/* This is the main program of the back-end.  It sets up all the table
   structures and then generates code.  */

void
gigi (Node_Id gnat_root,
      int max_gnat_node,
      int number_name ATTRIBUTE_UNUSED,
      Node_Header *node_offsets_ptr,
      any_slot *slots_ptr,
      Node_Id *next_node_ptr,
      Node_Id *prev_node_ptr,
      struct Elist_Header *elists_ptr,
      struct Elmt_Item *elmts_ptr,
      struct String_Entry *strings_ptr,
      Char_Code *string_chars_ptr,
      struct List_Header *list_headers_ptr,
      Nat number_file,
      struct File_Info_Type *file_info_ptr,
      Entity_Id standard_address,
      Entity_Id standard_boolean,
      Entity_Id standard_character,
      Entity_Id standard_exception_type,
      Entity_Id standard_integer,
      Entity_Id standard_long_long_float,
      Int gigi_operating_mode)
{
  Node_Id gnat_iter;
  Entity_Id gnat_literal;
  tree t, ftype;
  struct elab_info *info;
  int i;

  max_gnat_nodes = max_gnat_node;

  Node_Offsets_Ptr = node_offsets_ptr;
  Slots_Ptr = slots_ptr;
  Next_Node_Ptr = next_node_ptr;
  Prev_Node_Ptr = prev_node_ptr;
  Elists_Ptr = elists_ptr;
  Elmts_Ptr = elmts_ptr;
  Strings_Ptr = strings_ptr;
  String_Chars_Ptr = string_chars_ptr;
  List_Headers_Ptr = list_headers_ptr;

  type_annotate_only = (gigi_operating_mode == 1);

  if (Generate_SCO_Instance_Table != 0)
    {
      file_map = file_info_ptr;
      maybe_create_decl_to_instance_map (number_file);
    }

  for (i = 0; i < number_file; i++)
    {
      /* We rely on the order isomorphism between files and line maps.  */
      if ((int) LINEMAPS_ORDINARY_USED (line_table) != i)
	{
	  gcc_assert (i > 0);
	  error ("%s contains too many lines",
		 File_Name_to_gnu (file_info_ptr[i - 1].File_Name));
	}

      /* We create the line map for a source file at once, with a fixed number
	 of columns chosen to avoid jumping over the next power of 2.  */
      linemap_add (line_table, LC_ENTER, 0,
		   File_Name_to_gnu (file_info_ptr[i].File_Name), 1);
      linemap_line_start (line_table, file_info_ptr[i].Num_Source_Lines, 252);
      linemap_position_for_column (line_table, 252 - 1);
      linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
    }

  gcc_assert (Nkind (gnat_root) == N_Compilation_Unit);

  /* Declare the name of the compilation unit as the first global
     name in order to make the middle-end fully deterministic.  */
  t = create_concat_name (Defining_Entity (Unit (gnat_root)), NULL);
  first_global_object_name = ggc_strdup (IDENTIFIER_POINTER (t));

  /* Initialize ourselves.  */
  init_code_table ();
  init_gnat_decl ();
  init_gnat_utils ();

  /* If we are just annotating types, give VOID_TYPE zero sizes to avoid
     errors.  */
  if (type_annotate_only)
    {
      TYPE_SIZE (void_type_node) = bitsize_zero_node;
      TYPE_SIZE_UNIT (void_type_node) = size_zero_node;
    }

  /* Enable GNAT stack checking method if needed */
  if (!Stack_Check_Probes_On_Target)
    {
      set_stack_check_libfunc ("__gnat_stack_check");
      if (flag_stack_check != NO_STACK_CHECK)
	Check_Restriction_No_Dependence_On_System (Name_Stack_Checking,
						   gnat_root);
    }

  /* Retrieve alignment settings.  */
  double_float_alignment = get_target_double_float_alignment ();
  double_scalar_alignment = get_target_double_scalar_alignment ();

  /* Record the builtin types.  */
  record_builtin_type ("address", pointer_sized_int_node, false);
  record_builtin_type ("integer", integer_type_node, false);
  record_builtin_type ("character", char_type_node, false);
  record_builtin_type ("boolean", boolean_type_node, false);
  record_builtin_type ("void", void_type_node, false);

  /* Save the type we made for address as the type for Standard.Address.  */
  save_gnu_tree (Base_Type (standard_address),
		 TYPE_NAME (pointer_sized_int_node),
		 false);

  /* Likewise for integer as the type for Standard.Integer.  */
  save_gnu_tree (Base_Type (standard_integer),
		 TYPE_NAME (integer_type_node),
		 false);

  /* Likewise for character as the type for Standard.Character.  */
  finish_character_type (char_type_node);
  save_gnu_tree (Base_Type (standard_character),
		 TYPE_NAME (char_type_node),
		 false);

  /* Likewise for boolean as the type for Standard.Boolean.  */
  save_gnu_tree (Base_Type (standard_boolean),
		 TYPE_NAME (boolean_type_node),
		 false);
  gnat_literal = First_Literal (Base_Type (standard_boolean));
  t = UI_To_gnu (Enumeration_Rep (gnat_literal), boolean_type_node);
  gcc_assert (t == boolean_false_node);
  t = create_var_decl (get_entity_name (gnat_literal), NULL_TREE,
		       boolean_type_node, t, true, false, false, false, false,
		       false, true, false, NULL, gnat_literal);
  save_gnu_tree (gnat_literal, t, false);
  gnat_literal = Next_Literal (gnat_literal);
  t = UI_To_gnu (Enumeration_Rep (gnat_literal), boolean_type_node);
  gcc_assert (t == boolean_true_node);
  t = create_var_decl (get_entity_name (gnat_literal), NULL_TREE,
		       boolean_type_node, t, true, false, false, false, false,
		       false, true, false, NULL, gnat_literal);
  save_gnu_tree (gnat_literal, t, false);

  /* Declare the building blocks of function nodes.  */
  void_ftype = build_function_type_list (void_type_node, NULL_TREE);
  ptr_void_ftype = build_pointer_type (void_ftype);

  /* Now declare run-time functions.  */
  malloc_decl
    = create_subprog_decl (get_identifier ("__gnat_malloc"), NULL_TREE,
			   build_function_type_list (ptr_type_node, sizetype,
						     NULL_TREE),
			   NULL_TREE, is_default, true, false, true, true,
			   false, false);
  DECL_IS_MALLOC (malloc_decl) = 1;

  free_decl
    = create_subprog_decl (get_identifier ("__gnat_free"), NULL_TREE,
			   build_function_type_list (void_type_node,
						     ptr_type_node, NULL_TREE),
			   NULL_TREE, is_default, true, false, true, true,
			   false, false);

  realloc_decl
    = create_subprog_decl (get_identifier ("__gnat_realloc"), NULL_TREE,
			   build_function_type_list (ptr_type_node,
						     ptr_type_node, sizetype,
						     NULL_TREE),
			   NULL_TREE, is_default, true, false, true, true,
			   false, false);

  /* This is used for 64-bit multiplication with overflow checking.  */
  tree int64_type = gnat_type_for_size (64, 0);
  mulv64_decl
    = create_subprog_decl (get_identifier ("__gnat_mulv64"), NULL_TREE,
			   build_function_type_list (int64_type, int64_type,
						     int64_type, NULL_TREE),
			   NULL_TREE, is_default, true, false, true, true,
			   false, false);
  strub_make_callable (mulv64_decl);

  tree uint64_type = gnat_type_for_size (64, 1);
  uns_mulv64_decl
    = create_subprog_decl (get_identifier ("__gnat_uns_mulv64"), NULL_TREE,
			   build_function_type_list (uint64_type, uint64_type,
						     uint64_type, NULL_TREE),
			   NULL_TREE, is_default, true, false, true, true,
			   false, false);
  strub_make_callable (uns_mulv64_decl);

  if (Enable_128bit_Types)
    {
      tree int128_type = gnat_type_for_size (128, 0);
      mulv128_decl
	= create_subprog_decl (get_identifier ("__gnat_mulv128"), NULL_TREE,
			       build_function_type_list (int128_type,
							 int128_type,
							 int128_type,
							 NULL_TREE),
			       NULL_TREE, is_default, true, false, true, true,
			       false, false);
      strub_make_callable (mulv128_decl);

      tree uint128_type = gnat_type_for_size (128, 1);
      uns_mulv128_decl
	= create_subprog_decl (get_identifier ("__gnat_uns_mulv128"), NULL_TREE,
			       build_function_type_list (uint128_type,
							 uint128_type,
							 uint128_type,
							 NULL_TREE),
			       NULL_TREE, is_default, true, false, true, true,
			       false, false);
      strub_make_callable (uns_mulv128_decl);
    }

  /* Name of the _Parent field in tagged record types.  */
  parent_name_id = get_identifier (Get_Name_String (Name_uParent));

  /* Name of the _Tag field in tagged record types.  */
  tag_name_id = get_identifier (Get_Name_String (Name_uTag));

  /* Name of the Not_Handled_By_Others field in exception record types.  */
  not_handled_by_others_name_id = get_identifier ("not_handled_by_others");

  /* Make the types and functions used for exception processing.  */
  except_type_node = gnat_to_gnu_type (Base_Type (standard_exception_type));

  set_exception_parameter_decl
    = create_subprog_decl
      (get_identifier ("__gnat_set_exception_parameter"), NULL_TREE,
       build_function_type_list (void_type_node, ptr_type_node, ptr_type_node,
				 NULL_TREE),
       NULL_TREE, is_default, true, false, true, true, false, false);

  /* Hooks to call when entering/leaving an exception handler.  */
  ftype = build_function_type_list (ptr_type_node,
				    ptr_type_node, NULL_TREE);
  begin_handler_decl
    = create_subprog_decl (get_identifier ("__gnat_begin_handler_v1"),
			   NULL_TREE, ftype, NULL_TREE,
			   is_default, true, false, true, true, false, false);
  /* __gnat_begin_handler_v1 is not a dummy procedure, but we arrange
     for it not to throw.  */
  TREE_NOTHROW (begin_handler_decl) = 1;

  ftype = build_function_type_list (ptr_type_node,
				    ptr_type_node, ptr_type_node,
				    ptr_type_node, NULL_TREE);
  end_handler_decl
    = create_subprog_decl (get_identifier ("__gnat_end_handler_v1"), NULL_TREE,
			   ftype, NULL_TREE,
			   is_default, true, false, true, true, false, false);

  ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
  unhandled_except_decl
    = create_subprog_decl (get_identifier ("__gnat_unhandled_except_handler"),
			   NULL_TREE, ftype, NULL_TREE,
			   is_default, true, false, true, true, false, false);

  /* Indicate that it never returns.  */
  ftype = build_qualified_type (ftype, TYPE_QUAL_VOLATILE);
  reraise_zcx_decl
    = create_subprog_decl (get_identifier ("__gnat_reraise_zcx"), NULL_TREE,
			   ftype, NULL_TREE,
			   is_default, true, false, true, true, false, false);
  set_call_expr_flags (reraise_zcx_decl, ECF_NORETURN | ECF_XTHROW);

  /* Dummy objects to materialize "others" and "all others" in the exception
     tables.  These are exported by a-exexpr-gcc.adb, so see this unit for
     the types to use.  */
  others_decl
    = create_var_decl (get_identifier ("OTHERS"),
		       get_identifier ("__gnat_others_value"),
		       char_type_node, NULL_TREE,
		       true, false, false, true, false, false, true, false,
		       NULL, Empty);

  all_others_decl
    = create_var_decl (get_identifier ("ALL_OTHERS"),
		       get_identifier ("__gnat_all_others_value"),
		       char_type_node, NULL_TREE,
		       true, false, false, true, false, false, true, false,
		       NULL, Empty);

  unhandled_others_decl
    = create_var_decl (get_identifier ("UNHANDLED_OTHERS"),
		       get_identifier ("__gnat_unhandled_others_value"),
		       char_type_node, NULL_TREE,
		       true, false, false, true, false, false, true, false,
		       NULL, Empty);

  /* If in no exception handlers mode, all raise statements are redirected to
     __gnat_last_chance_handler.  */
  if (No_Exception_Handlers_Set ())
    {
      /* Indicate that it never returns.  */
      ftype = build_function_type_list (void_type_node,
					build_pointer_type (char_type_node),
					integer_type_node, NULL_TREE);
      ftype = build_qualified_type (ftype, TYPE_QUAL_VOLATILE);
      tree decl
	= create_subprog_decl
	  (get_identifier ("__gnat_last_chance_handler"), NULL_TREE, ftype,
	   NULL_TREE, is_default, true, false, true, true, false, false);
      for (i = 0; i < (int) ARRAY_SIZE (gnat_raise_decls); i++)
	gnat_raise_decls[i] = decl;
    }
  else
    {
      /* Otherwise, make one decl for each exception reason.  */
      for (i = 0; i < (int) ARRAY_SIZE (gnat_raise_decls); i++)
	gnat_raise_decls[i] = build_raise_check (i, exception_simple);
      for (i = 0; i < (int) ARRAY_SIZE (gnat_raise_decls_ext); i++)
	gnat_raise_decls_ext[i]
	  = build_raise_check (i,
			       i == CE_Index_Check_Failed
			       || i == CE_Range_Check_Failed
			       || i == CE_Invalid_Data
			       ? exception_range : exception_column);
    }

  /* Build the special descriptor type and its null node if needed.  */
  if (TARGET_VTABLE_USES_DESCRIPTORS)
    {
      tree null_node = fold_convert (ptr_void_ftype, null_pointer_node);
      tree field_list = NULL_TREE;
      int j;
      vec<constructor_elt, va_gc> *null_vec = NULL;
      constructor_elt *elt;

      fdesc_type_node = make_node (RECORD_TYPE);
      vec_safe_grow (null_vec, TARGET_VTABLE_USES_DESCRIPTORS, true);
      elt = (null_vec->address () + TARGET_VTABLE_USES_DESCRIPTORS - 1);

      for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; j++)
	{
	  tree field
	    = create_field_decl (NULL_TREE, ptr_void_ftype, fdesc_type_node,
				 NULL_TREE, NULL_TREE, 0, 1);
	  DECL_CHAIN (field) = field_list;
	  field_list = field;
	  elt->index = field;
	  elt->value = null_node;
	  elt--;
	}

      finish_record_type (fdesc_type_node, nreverse (field_list), 0, false);
      record_builtin_type ("descriptor", fdesc_type_node, true);
      null_fdesc_node = gnat_build_constructor (fdesc_type_node, null_vec);
    }

  longest_float_type_node
    = get_unpadded_type (Base_Type (standard_long_long_float));

  main_identifier_node = get_identifier ("main");

  gnat_init_gcc_eh ();

  /* Initialize the GCC support for FP operations.  */
  gnat_init_gcc_fp ();

  /* Install the builtins we might need, either internally or as user-available
     facilities for Intrinsic imports.  Note that this must be done after the
     GCC exception mechanism is initialized.  */
  gnat_install_builtins ();

  vec_safe_push (gnu_except_ptr_stack, NULL_TREE);

  gnu_constraint_error_label_stack.safe_push (Empty);
  gnu_storage_error_label_stack.safe_push (Empty);
  gnu_program_error_label_stack.safe_push (Empty);

  /* Process any Pragma Ident for the main unit.  */
  if (Present (Ident_String (Main_Unit)))
    targetm.asm_out.output_ident
      (TREE_STRING_POINTER (gnat_to_gnu (Ident_String (Main_Unit))));

  /* Force -fno-strict-aliasing if the configuration pragma was seen.  */
  if (No_Strict_Aliasing_CP)
    flag_strict_aliasing = 0;

  /* Save the current optimization options again after the above possible
     global_options changes.  */
  optimization_default_node
    = build_optimization_node (&global_options, &global_options_set);
  optimization_current_node = optimization_default_node;

  /* Now translate the compilation unit proper.  */
  Compilation_Unit_to_gnu (gnat_root);

  /* Then process the N_Validate_Unchecked_Conversion nodes.  We do this at
     the very end to avoid having to second-guess the front-end when we run
     into dummy nodes during the regular processing.  */
  for (i = 0; gnat_validate_uc_list.iterate (i, &gnat_iter); i++)
    validate_unchecked_conversion (gnat_iter);
  gnat_validate_uc_list.release ();

  /* Finally see if we have any elaboration procedures to deal with.  */
  for (info = elab_info_list; info; info = info->next)
    {
      tree gnu_body = DECL_SAVED_TREE (info->elab_proc);

      /* We should have a BIND_EXPR but it may not have any statements in it.
	 If it doesn't have any, we have nothing to do except for setting the
	 flag on the GNAT node.  Otherwise, process the function as others.  */
      tree gnu_stmts = gnu_body;
      if (TREE_CODE (gnu_stmts) == BIND_EXPR)
	gnu_stmts = BIND_EXPR_BODY (gnu_stmts);
      if (!gnu_stmts || empty_stmt_list_p (gnu_stmts))
	Set_Has_No_Elaboration_Code (info->gnat_node, 1);
      else
	{
	  begin_subprog_body (info->elab_proc);
	  end_subprog_body (gnu_body);
	  rest_of_subprog_body_compilation (info->elab_proc);
	}
    }

  /* Destroy ourselves.  */
  file_map = NULL;
  destroy_gnat_decl ();
  destroy_gnat_utils ();

  /* We cannot track the location of errors past this point.  */
  Current_Error_Node = Empty;
}

/* Return a subprogram decl corresponding to __gnat_rcheck_xx for the given
   CHECK if KIND is EXCEPTION_SIMPLE, or else to __gnat_rcheck_xx_ext.  */

static tree
build_raise_check (int check, enum exception_info_kind kind)
{
  tree result, ftype;
  const char pfx[] = "__gnat_rcheck_";

  strcpy (Name_Buffer, pfx);
  Name_Len = sizeof (pfx) - 1;
  Get_RT_Exception_Name ((enum RT_Exception_Code) check);

  if (kind == exception_simple)
    {
      Name_Buffer[Name_Len] = 0;
      ftype
	= build_function_type_list (void_type_node,
				    build_pointer_type (char_type_node),
				    integer_type_node, NULL_TREE);
    }
  else
    {
      tree t = (kind == exception_column ? NULL_TREE : integer_type_node);

      strcpy (Name_Buffer + Name_Len, "_ext");
      Name_Buffer[Name_Len + 4] = 0;
      ftype
	= build_function_type_list (void_type_node,
				    build_pointer_type (char_type_node),
				    integer_type_node, integer_type_node,
				    t, t, NULL_TREE);
    }

  /* Indicate that it never returns.  */
  ftype = build_qualified_type (ftype, TYPE_QUAL_VOLATILE);
  result
    = create_subprog_decl (get_identifier (Name_Buffer), NULL_TREE, ftype,
			   NULL_TREE, is_default, true, false, true, true,
			   false, false);
  strub_make_callable (result);
  set_call_expr_flags (result, ECF_NORETURN | ECF_XTHROW);

  return result;
}

/* Return true if GNAT_NODE, which is an N_Attribute_Reference, is one of the
   access attributes.  */

static bool
access_attribute_p (Node_Id gnat_node)
{
  switch (Get_Attribute_Id (Attribute_Name (gnat_node)))
    {
    case Attr_Access:
    case Attr_Unchecked_Access:
    case Attr_Unrestricted_Access:
      return true;

    default:
      return false;
    }

  gcc_unreachable ();
}

/* Return a positive value if an lvalue is required for GNAT_NODE, which is
   an N_Attribute_Reference.  */

static int
lvalue_required_for_attribute_p (Node_Id gnat_node)
{
  switch (Get_Attribute_Id (Attribute_Name (gnat_node)))
    {
    case Attr_Pred:
    case Attr_Succ:
    case Attr_First:
    case Attr_Last:
    case Attr_Range_Length:
    case Attr_Length:
    case Attr_Object_Size:
    case Attr_Value_Size:
    case Attr_Component_Size:
    case Attr_Descriptor_Size:
    case Attr_Max_Size_In_Storage_Elements:
    case Attr_Min:
    case Attr_Max:
    case Attr_Null_Parameter:
    case Attr_Passed_By_Reference:
    case Attr_Mechanism_Code:
    case Attr_Machine:
    case Attr_Model:
      return 0;

    case Attr_Address:
    case Attr_Access:
    case Attr_Unchecked_Access:
    case Attr_Unrestricted_Access:
    case Attr_Code_Address:
    case Attr_Pool_Address:
    case Attr_Alignment:
    case Attr_Bit_Position:
    case Attr_Position:
    case Attr_First_Bit:
    case Attr_Last_Bit:
    case Attr_Bit:
    case Attr_Size:
    case Attr_Asm_Input:
    case Attr_Asm_Output:
    default:
      return 1;
    }

  gcc_unreachable ();
}

/* Return a positive value if an lvalue is required for GNAT_NODE.  GNU_TYPE
   is the type that will be used for GNAT_NODE in the translated GNU tree.
   CONSTANT indicates whether the underlying object represented by GNAT_NODE
   is constant in the Ada sense.  If it is, ADDRESS_OF_CONSTANT indicates
   whether its value is the address of another constant.  If it isn't, then
   ADDRESS_OF_CONSTANT is ignored.

   The function climbs up the GNAT tree starting from the node and returns 1
   upon encountering a node that effectively requires an lvalue downstream.
   It returns int instead of bool to facilitate usage in non-purely binary
   logic contexts.  */

static int
lvalue_required_p (Node_Id gnat_node, tree gnu_type, bool constant,
		   bool address_of_constant)
{
  Node_Id gnat_parent = Parent (gnat_node), gnat_temp;

  switch (Nkind (gnat_parent))
    {
    case N_Reference:
      return 1;

    case N_Attribute_Reference:
      return lvalue_required_for_attribute_p (gnat_parent);

    case N_Parameter_Association:
    case N_Function_Call:
    case N_Procedure_Call_Statement:
      /* If the parameter is by reference, an lvalue is required.  */
      return (!constant
	      || must_pass_by_ref (gnu_type)
	      || default_pass_by_ref (gnu_type));

    case N_Pragma_Argument_Association:
      return lvalue_required_p (gnat_parent, gnu_type, constant,
				address_of_constant);

    case N_Pragma:
      if (Is_Pragma_Name (Chars (Pragma_Identifier (gnat_parent))))
	{
	  const Pragma_Id id
	    = Get_Pragma_Id (Chars (Pragma_Identifier (gnat_parent)));
	  return id == Pragma_Inspection_Point;
	}
      else
	return 0;

    case N_Indexed_Component:
      /* Only the array expression can require an lvalue.  */
      if (Prefix (gnat_parent) != gnat_node)
	return 0;

      /* ??? Consider that referencing an indexed component with a variable
	 index forces the whole aggregate to memory.  Note that testing only
	 for literals is conservative, any static expression in the RM sense
	 could probably be accepted with some additional work.  */
      for (gnat_temp = First (Expressions (gnat_parent));
	   Present (gnat_temp);
	   gnat_temp = Next (gnat_temp))
	if (Nkind (gnat_temp) != N_Character_Literal
	    && Nkind (gnat_temp) != N_Integer_Literal
	    && !(Is_Entity_Name (gnat_temp)
		 && Ekind (Entity (gnat_temp)) == E_Enumeration_Literal))
	  return 1;

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

    case N_Selected_Component:
    case N_Slice:
      /* Only the prefix expression can require an lvalue.  */
      if (Prefix (gnat_parent) != gnat_node)
	return 0;

      return lvalue_required_p (gnat_parent,
				get_unpadded_type (Etype (gnat_parent)),
				constant, address_of_constant);

    case N_Object_Renaming_Declaration:
      /* We need to preserve addresses through a renaming.  */
      return 1;

    case N_Object_Declaration:
      /* We cannot use a constructor if this is an atomic object because
	 the actual assignment might end up being done component-wise.  */
      return (!constant
	      ||(Is_Composite_Type (Underlying_Type (Etype (gnat_node)))
		 && Is_Full_Access (Defining_Entity (gnat_parent)))
	      /* We don't use a constructor if this is a class-wide object
		 because the effective type of the object is the equivalent
		 type of the class-wide subtype and it smashes most of the
		 data into an array of bytes to which we cannot convert.  */
	      || Ekind ((Etype (Defining_Entity (gnat_parent))))
		 == E_Class_Wide_Subtype);

    case N_Assignment_Statement:
      /* We cannot use a constructor if the LHS is an atomic object because
	 the actual assignment might end up being done component-wise.  */
      return (!constant
	      || Name (gnat_parent) == gnat_node
	      || (Is_Composite_Type (Underlying_Type (Etype (gnat_node)))
		  && Is_Entity_Name (Name (gnat_parent))
		  && Is_Full_Access (Entity (Name (gnat_parent)))));

    case N_Unchecked_Type_Conversion:
	if (!constant)
	  return 1;

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

    case N_Type_Conversion:
    case N_Qualified_Expression:
      /* We must look through all conversions because we may need to bypass
	 an intermediate conversion that is meant to be purely formal.  */
     return lvalue_required_p (gnat_parent,
			       get_unpadded_type (Etype (gnat_parent)),
			       constant, address_of_constant);

   case N_Explicit_Dereference:
      /* We look through dereferences for address of constant because we need
	 to handle the special cases listed above.  */
      if (constant && address_of_constant)
	return lvalue_required_p (gnat_parent,
				  get_unpadded_type (Etype (gnat_parent)),
				  true, false);

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

    default:
      return 0;
    }

  gcc_unreachable ();
}

/* Return true if an lvalue should be used for GNAT_NODE.  GNU_TYPE is the type
   that will be used for GNAT_NODE in the translated GNU tree and is assumed to
   be an aggregate type.

   The function climbs up the GNAT tree starting from the node and returns true
   upon encountering a node that makes it doable to decide.  lvalue_required_p
   should have been previously invoked on the arguments and returned false.  */

static bool
lvalue_for_aggregate_p (Node_Id gnat_node, tree gnu_type)
{
  Node_Id gnat_parent = Parent (gnat_node);

  switch (Nkind (gnat_parent))
    {
    case N_Parameter_Association:
    case N_Function_Call:
    case N_Procedure_Call_Statement:
      /* Even if the parameter is by copy, prefer an lvalue.  */
      return true;

    case N_Simple_Return_Statement:
      /* Likewise for a return value.  */
      return true;

    case N_Indexed_Component:
    case N_Selected_Component:
      /* If an elementary component is used, take it from the constant.  */
      if (!Is_Composite_Type (Underlying_Type (Etype (gnat_parent))))
	return false;

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

    case N_Slice:
      return lvalue_for_aggregate_p (gnat_parent,
				     get_unpadded_type (Etype (gnat_parent)));

    case N_Object_Declaration:
      /* For an aggregate object declaration, return false consistently.  */
      return false;

    case N_Assignment_Statement:
      /* For an aggregate assignment, decide based on the size.  */
      {
	const HOST_WIDE_INT size = int_size_in_bytes (gnu_type);
	return size < 0 || size >= param_large_stack_frame / 4;
      }

    case N_Unchecked_Type_Conversion:
    case N_Type_Conversion:
    case N_Qualified_Expression:
      return lvalue_for_aggregate_p (gnat_parent,
				     get_unpadded_type (Etype (gnat_parent)));

    case N_Allocator:
      /* We should only reach here through the N_Qualified_Expression case.
	 Force an lvalue for aggregate types since a block-copy to the newly
	 allocated area of memory is made.  */
      return true;

    default:
      return false;
    }

  gcc_unreachable ();
}


/* Return true if T is a constant DECL node that can be safely replaced
   by its initializer.  */

static bool
constant_decl_with_initializer_p (tree t)
{
  if (!TREE_CONSTANT (t) || !DECL_P (t) || !DECL_INITIAL (t))
    return false;

  /* Return false for aggregate types that contain a placeholder since
     their initializers cannot be manipulated easily.  */
  if (AGGREGATE_TYPE_P (TREE_TYPE (t))
      && !TYPE_IS_FAT_POINTER_P (TREE_TYPE (t))
      && type_contains_placeholder_p (TREE_TYPE (t)))
    return false;

  return true;
}

/* Return an expression equivalent to EXP but where constant DECL nodes
   have been replaced by their initializer.  */

static tree
fold_constant_decl_in_expr (tree exp)
{
  enum tree_code code = TREE_CODE (exp);
  tree op0;

  switch (code)
    {
    case CONST_DECL:
    case VAR_DECL:
      if (!constant_decl_with_initializer_p (exp))
	return exp;

      return DECL_INITIAL (exp);

    case COMPONENT_REF:
      op0 = fold_constant_decl_in_expr (TREE_OPERAND (exp, 0));
      if (op0 == TREE_OPERAND (exp, 0))
	return exp;

      return fold_build3 (COMPONENT_REF, TREE_TYPE (exp), op0,
			  TREE_OPERAND (exp, 1), NULL_TREE);

    case BIT_FIELD_REF:
      op0 = fold_constant_decl_in_expr (TREE_OPERAND (exp, 0));
      if (op0 == TREE_OPERAND (exp, 0))
	return exp;

      return fold_build3 (BIT_FIELD_REF, TREE_TYPE (exp), op0,
			  TREE_OPERAND (exp, 1), TREE_OPERAND (exp, 2));

    case ARRAY_REF:
    case ARRAY_RANGE_REF:
      /* If the index is not itself constant, then nothing can be folded.  */
      if (!TREE_CONSTANT (TREE_OPERAND (exp, 1)))
	return exp;
      op0 = fold_constant_decl_in_expr (TREE_OPERAND (exp, 0));
      if (op0 == TREE_OPERAND (exp, 0))
	return exp;

      return fold (build4 (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1),
			   TREE_OPERAND (exp, 2), TREE_OPERAND (exp, 3)));

    case REALPART_EXPR:
    case IMAGPART_EXPR:
    case VIEW_CONVERT_EXPR:
      op0 = fold_constant_decl_in_expr (TREE_OPERAND (exp, 0));
      if (op0 == TREE_OPERAND (exp, 0))
	return exp;

      return fold_build1 (code, TREE_TYPE (exp), op0);

    default:
      return exp;
    }

  gcc_unreachable ();
}

/* Return true if TYPE and DEF_TYPE are compatible GNAT types for Gigi.  */

static bool
Gigi_Types_Compatible (Entity_Id type, Entity_Id def_type)
{
  /* The trivial case.  */
  if (type == def_type)
    return true;

  /* A class-wide type is equivalent to a subtype of itself.  */
  if (Is_Class_Wide_Type (type))
    return true;

  /* A packed array type is compatible with its implementation type.  */
  if (Is_Packed (def_type) && type == Packed_Array_Impl_Type (def_type))
    return true;

  /* If both types are Itypes, one may be a copy of the other.  */
  if (Is_Itype (def_type) && Is_Itype (type))
    return true;

  /* If the type is incomplete and comes from a limited context, then also
     consider its non-limited view.  */
  if (Is_Incomplete_Type (def_type)
      && From_Limited_With (def_type)
      && Present (Non_Limited_View (def_type)))
    return Gigi_Types_Compatible (type, Non_Limited_View (def_type));

  /* If the type is incomplete/private, then also consider its full view.  */
  if (Is_Incomplete_Or_Private_Type (def_type)
      && Present (Full_View (def_type)))
    return Gigi_Types_Compatible (type, Full_View (def_type));

  return false;
}

/* Return the full view of a private constant E, or of a renaming thereof, if
   its type has discriminants, and Empty otherwise.  */

static Entity_Id
Full_View_Of_Private_Constant (Entity_Id E)
{
  while (Present (Renamed_Object (E)) && Is_Entity_Name (Renamed_Object (E)))
    E = Entity (Renamed_Object (E));

  if (Ekind (E) != E_Constant || No (Full_View (E)))
    return Empty;

  const Entity_Id T = Etype (E);

  if (Is_Private_Type (T)
      && (Has_Unknown_Discriminants (T)
	  || (Present (Full_View (T)) && Has_Discriminants (Full_View (T)))))
    return Full_View (E);

  return Empty;
}

/* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Identifier, to a GCC
   tree, which is returned.  GNU_RESULT_TYPE_P is a pointer to where we should
   place the result type.  */

static tree
Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
{
  Entity_Id gnat_entity = (Nkind (gnat_node) == N_Defining_Identifier
			   || Nkind (gnat_node) == N_Defining_Operator_Symbol)
			  ? gnat_node : Entity (gnat_node);
  Entity_Id gnat_result_type;
  tree gnu_result, gnu_result_type;
  /* If GNAT_NODE is a constant, whether we should use the initialization
     value instead of the constant entity, typically for scalars with an
     address clause when the parent doesn't require an lvalue.  */
  bool use_constant_initializer;
  /* Whether we should require an lvalue for GNAT_NODE.  Needed in
     specific circumstances only, so evaluated lazily.  < 0 means
     unknown, > 0 means known true, 0 means known false.  */
  int require_lvalue;

  /* If the Etype of this node is not the same as that of the Entity, then
     something went wrong, probably in generic instantiation.  However, this
     does not apply to types.  Since we sometime have strange Ekind's, just
     do this test for objects, except for discriminants because their type
     may have been changed to a subtype by Exp_Ch3.Adjust_Discriminants.  */
  gcc_assert (!Is_Object (gnat_entity)
	      || Ekind (gnat_entity) == E_Discriminant
	      || Etype (gnat_node) == Etype (gnat_entity)
	      || Gigi_Types_Compatible (Etype (gnat_node),
					Etype (gnat_entity)));

  /* If this is a reference to a deferred constant whose partial view is of
     unconstrained private type, the proper type is on the full view of the
     constant, not on the full view of the type which may be unconstrained.  */
  const Entity_Id gnat_full_view = Full_View_Of_Private_Constant (gnat_entity);
  if (Present (gnat_full_view))
    {
      gnat_entity = gnat_full_view;
      gnat_result_type = Etype (gnat_entity);
    }
  else
    {
      /* We use the Actual_Subtype only if it has already been elaborated,
	 as we may be invoked precisely during its elaboration, otherwise
	 the Etype.  Avoid using it for packed arrays to simplify things,
	 except in a return statement because we need the actual size and
	 the front-end does not make it explicit in this case.  */
      if ((Ekind (gnat_entity) == E_Constant
	   || Ekind (gnat_entity) == E_Variable
	   || Is_Formal (gnat_entity))
	  && !(Is_Array_Type (Etype (gnat_entity))
	       && Present (Packed_Array_Impl_Type (Etype (gnat_entity)))
	       && Nkind (Parent (gnat_node)) != N_Simple_Return_Statement)
	  && Present (Actual_Subtype (gnat_entity))
	  && present_gnu_tree (Actual_Subtype (gnat_entity)))
	gnat_result_type = Actual_Subtype (gnat_entity);
      else
	gnat_result_type = Etype (gnat_node);
    }

  /* Expand the type of this identifier first if it is needed, in case it is an
     enumeral literal, which only get made when the type is expanded.  There is
     no order-of-elaboration issue here.  */
  if (Is_Subprogram (gnat_entity))
    gnu_result_type = NULL_TREE;
  else if (Nkind (Original_Node (gnat_node)) == N_Explicit_Dereference
	   && Is_Extended_Access_Type
	      (Etype (Prefix (Original_Node (gnat_node)))))
    gnu_result_type = get_unpadded_extended_type (gnat_result_type);
  else
    gnu_result_type = get_unpadded_type (gnat_result_type);

  /* If this is a non-imported elementary constant with an address clause,
     retrieve the value instead of a pointer to be dereferenced unless
     an lvalue is required.  This is generally more efficient and actually
     required if this is a static expression because it might be used
     in a context where a dereference is inappropriate, such as a case
     statement alternative or a record discriminant.  There is no possible
     volatile-ness short-circuit here since Volatile constants must be
     imported per C.6.  */
  if (Ekind (gnat_entity) == E_Constant
      && Is_Elementary_Type (gnat_result_type)
      && !Is_Imported (gnat_entity)
      && Present (Address_Clause (gnat_entity)))
    {
      require_lvalue
	= lvalue_required_p (gnat_node, gnu_result_type, true, false);
      use_constant_initializer = !require_lvalue;
    }
  else
    {
      require_lvalue = -1;
      use_constant_initializer = false;
    }

  /* Fetch the initialization value of a constant if requested.  */
  if (use_constant_initializer)
    {
      /* If this is a deferred constant, the initializer is attached to
	 the full view.  */
      if (Present (Full_View (gnat_entity)))
	gnat_entity = Full_View (gnat_entity);

      gnu_result = gnat_to_gnu (Expression (Declaration_Node (gnat_entity)));
    }
  else
    gnu_result = gnat_to_gnu_entity (gnat_entity, NULL_TREE, false);

  /* Some objects (such as parameters passed by reference, globals of
     variable size, and renamed objects) actually represent the address
     of the object.  In that case, we must do the dereference.  Likewise,
     deal with parameters to foreign convention subprograms.  */
  if (DECL_P (gnu_result)
      && (DECL_BY_REF_P (gnu_result)
	  || (TREE_CODE (gnu_result) == PARM_DECL
	      && DECL_BY_COMPONENT_PTR_P (gnu_result))))
    {
      const bool read_only = DECL_POINTS_TO_READONLY_P (gnu_result);

      /* If it's a PARM_DECL to foreign convention subprogram, convert it.  */
      if (TREE_CODE (gnu_result) == PARM_DECL
	  && DECL_BY_COMPONENT_PTR_P (gnu_result))
	gnu_result
	  = convert (build_pointer_type (gnu_result_type), gnu_result);

      /* If it's a CONST_DECL, return the underlying constant like below.  */
      else if (TREE_CODE (gnu_result) == CONST_DECL
	       && !(DECL_CONST_ADDRESS_P (gnu_result)
		    && lvalue_required_p (gnat_node, gnu_result_type, true,
					  true)))
	gnu_result = DECL_INITIAL (gnu_result);

      /* Do the final dereference.  */
      gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result);

      if ((INDIRECT_REF_P (gnu_result)
	   || TREE_CODE (gnu_result) == UNCONSTRAINED_ARRAY_REF)
	  && No (Address_Clause (gnat_entity)))
	TREE_THIS_NOTRAP (gnu_result) = 1;

      if (read_only)
	TREE_READONLY (gnu_result) = 1;
    }

  /* If we have a constant declaration and its initializer, try to return the
     latter to avoid the need to call fold in lots of places and the need for
     elaboration code if this identifier is used as an initializer itself.  */
  if (constant_decl_with_initializer_p (gnu_result))
    {
      bool constant_only = (TREE_CODE (gnu_result) == CONST_DECL
			    && !DECL_CONST_CORRESPONDING_VAR (gnu_result));
      bool address_of_constant = (TREE_CODE (gnu_result) == CONST_DECL
				  && DECL_CONST_ADDRESS_P (gnu_result));

      /* If there is a (corresponding) variable or this is the address of a
	 constant, we only want to return the initializer if an lvalue isn't
	 required.  Evaluate this now if we have not already done so.  */
      if ((!constant_only || address_of_constant) && require_lvalue < 0)
	require_lvalue
	  = lvalue_required_p (gnat_node, gnu_result_type, true,
			       address_of_constant)
	    || (AGGREGATE_TYPE_P (gnu_result_type)
		&& lvalue_for_aggregate_p (gnat_node, gnu_result_type));

      /* Finally retrieve the initializer if this is deemed valid.  */
      if ((constant_only && !address_of_constant) || !require_lvalue)
	gnu_result = DECL_INITIAL (gnu_result);
    }

  /* But for a constant renaming we couldn't do that incrementally for its
     definition because of the need to return an lvalue so, if the present
     context doesn't itself require an lvalue, we try again here.  */
  else if (Ekind (gnat_entity) == E_Constant
	   && Is_Elementary_Type (gnat_result_type)
	   && Present (Renamed_Object (gnat_entity)))
    {
      if (require_lvalue < 0)
	require_lvalue
	  = lvalue_required_p (gnat_node, gnu_result_type, true, false);
      if (!require_lvalue)
	gnu_result = fold_constant_decl_in_expr (gnu_result);
    }

  /* The GNAT tree has the type of a function set to its result type, so we
     adjust here.  Also use the type of the result if the Etype is a subtype
     that is nominally unconstrained.  Likewise if this is a deferred constant
     of a discriminated type whose full view can be elaborated statically, to
     avoid problematic conversions to the nominal subtype.  But remove any
     padding from the resulting type.  */
  if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (gnu_result))
      || Is_Constr_Array_Subt_With_Bounds (gnat_result_type)
      || (Ekind (gnat_entity) == E_Constant
	  && Present (Full_View (gnat_entity))
	  && Has_Discriminants (gnat_result_type)
	  && TREE_CODE (gnu_result) == CONSTRUCTOR))
    {
      gnu_result_type = TREE_TYPE (gnu_result);
      if (TYPE_IS_PADDING_P (gnu_result_type))
	gnu_result_type = TREE_TYPE (TYPE_FIELDS (gnu_result_type));
    }

  *gnu_result_type_p = gnu_result_type;

  return gnu_result;
}

/* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Pragma, to a GCC
   tree, which is returned.  */

static tree
Pragma_to_gnu (Node_Id gnat_node)
{
  tree gnu_result = alloc_stmt_list ();
  Node_Id gnat_temp;

  /* Check for (and ignore) unrecognized pragmas.  */
  if (!Is_Pragma_Name (Chars (Pragma_Identifier (gnat_node))))
    return gnu_result;

  const Pragma_Id id
    = Get_Pragma_Id (Chars (Pragma_Identifier (gnat_node)));

  /* Save the expression of pragma Compile_Time_{Error|Warning} for later.  */
  if (id == Pragma_Compile_Time_Error || id == Pragma_Compile_Time_Warning)
    {
      gnat_temp = First (Pragma_Argument_Associations (gnat_node));
      gnat_compile_time_expr_list.safe_push (Expression (gnat_temp));
      return gnu_result;
    }

  /* Stop there if we are just annotating types.  */
  if (type_annotate_only)
    return gnu_result;

  switch (id)
    {
    case Pragma_Inspection_Point:
      /* Do nothing at top level: all such variables are already viewable.  */
      if (global_bindings_p ())
	break;

      for (gnat_temp = First (Pragma_Argument_Associations (gnat_node));
	   Present (gnat_temp);
	   gnat_temp = Next (gnat_temp))
	{
	  Node_Id gnat_expr = Expression (gnat_temp);
	  tree gnu_expr = gnat_to_gnu (gnat_expr);
	  tree asm_constraint = NULL_TREE;
#ifdef ASM_COMMENT_START
	  char *comment;
#endif
	  gnu_expr = maybe_unconstrained_array (gnu_expr);
	  if (TREE_CODE (gnu_expr) == CONST_DECL
	      && DECL_CONST_CORRESPONDING_VAR (gnu_expr))
	    gnu_expr = DECL_CONST_CORRESPONDING_VAR (gnu_expr);
	  gnat_mark_addressable (gnu_expr);

#ifdef ASM_COMMENT_START
	  comment = concat (ASM_COMMENT_START,
			    " inspection point: ",
			    Get_Name_String (Chars (gnat_expr)),
			    " is at %0",
			    NULL);
	  asm_constraint = build_string (strlen (comment), comment);
	  free (comment);
#endif
	  gnu_expr = build5 (ASM_EXPR, void_type_node,
			     asm_constraint,
			     NULL_TREE,
			     tree_cons
			     (build_tree_list (NULL_TREE,
					       build_string (1, "m")),
					       gnu_expr, NULL_TREE),
			     NULL_TREE, NULL_TREE);
	  ASM_VOLATILE_P (gnu_expr) = 1;
	  set_expr_location_from_node (gnu_expr, gnat_node);
	  append_to_statement_list (gnu_expr, &gnu_result);
	}
      break;

    case Pragma_Loop_Optimize:
      for (gnat_temp = First (Pragma_Argument_Associations (gnat_node));
	   Present (gnat_temp);
	   gnat_temp = Next (gnat_temp))
	{
	  tree gnu_loop_stmt = gnu_loop_stack->last ()->stmt;

	  switch (Chars (Expression (gnat_temp)))
	    {
	    case Name_Ivdep:
	      LOOP_STMT_IVDEP (gnu_loop_stmt) = 1;
	      break;

	    case Name_No_Unroll:
	      LOOP_STMT_NO_UNROLL (gnu_loop_stmt) = 1;
	      break;

	    case Name_Unroll:
	      LOOP_STMT_UNROLL (gnu_loop_stmt) = 1;
	      break;

	    case Name_No_Vector:
	      LOOP_STMT_NO_VECTOR (gnu_loop_stmt) = 1;
	      break;

	    case Name_Vector:
	      LOOP_STMT_VECTOR (gnu_loop_stmt) = 1;
	      break;

	    default:
	      gcc_unreachable ();
	    }
	}
      break;

    case Pragma_Optimize:
      switch (Chars (Expression
		     (First (Pragma_Argument_Associations (gnat_node)))))
	{
	case Name_Off:
	  if (optimize)
	    post_error ("must specify -O0??", gnat_node);
	  break;

	case Name_Space:
	  if (!optimize_size)
	    post_error ("must specify -Os??", gnat_node);
	  break;

	case Name_Time:
	  if (!optimize)
	    post_error ("insufficient -O value??", gnat_node);
	  break;

	default:
	  gcc_unreachable ();
	}
      break;

    case Pragma_Reviewable:
      if (write_symbols == NO_DEBUG)
	post_error ("must specify -g??", gnat_node);
      break;

    case Pragma_Warning_As_Error:
    case Pragma_Warnings:
      {
	Node_Id gnat_expr;
	/* Preserve the location of the pragma.  */
	const location_t location = input_location;
	struct cl_option_handlers handlers;
	unsigned int option_index;
	enum diagnostics::kind kind;
	bool imply;

	gnat_temp = First (Pragma_Argument_Associations (gnat_node));

	/* This is the String form: pragma Warning{s|_As_Error}(String).  */
	if (Nkind (Expression (gnat_temp)) == N_String_Literal)
	  {
	    switch (id)
	      {
	      case Pragma_Warning_As_Error:
		kind = diagnostics::kind::error;
		imply = false;
		break;

	      case Pragma_Warnings:
		kind = diagnostics::kind::warning;
		imply = true;
		break;

	      default:
		gcc_unreachable ();
	      }

	    gnat_expr = Expression (gnat_temp);
	  }

	/* This is the On/Off form: pragma Warnings (On | Off [,String]).  */
	else if (Nkind (Expression (gnat_temp)) == N_Identifier)
	  {
	    switch (Chars (Expression (gnat_temp)))
	      {
		case Name_Off:
		  kind = diagnostics::kind::ignored;
		  break;

		case Name_On:
		  kind = diagnostics::kind::warning;
		  break;

		default:
		  gcc_unreachable ();
	      }

	    /* Deal with optional pattern (but ignore Reason => "...").  */
	    if (Present (Next (gnat_temp))
		&& Chars (Next (gnat_temp)) != Name_Reason)
	      {
		/* pragma Warnings (On | Off, Name) is handled differently.  */
		if (Nkind (Expression (Next (gnat_temp))) != N_String_Literal)
		  break;

	        gnat_expr = Expression (Next (gnat_temp));
	      }
	    else
	      {
		gnat_expr = Empty;

		/* For pragma Warnings (Off), we save the current state...  */
		if (kind == diagnostics::kind::ignored)
		  diagnostic_push_diagnostics (global_dc, location);

		/* ...so that, for pragma Warnings (On), we do not enable all
		   the warnings but just restore the previous state.  */
		else
		  {
		    diagnostic_pop_diagnostics (global_dc, location);
		    break;
		  }
	      }

	    imply = false;
	  }

	else
	  gcc_unreachable ();

	/* This is the same implementation as in the C family of compilers.  */
	const unsigned int lang_mask = CL_Ada | CL_COMMON;
	const char *arg = NULL;
	if (Present (gnat_expr))
	  {
	    tree gnu_expr = gnat_to_gnu (gnat_expr);
	    const char *option_string = TREE_STRING_POINTER (gnu_expr);
	    const int len = TREE_STRING_LENGTH (gnu_expr);
	    if (len < 3 || option_string[0] != '-' || option_string[1] != 'W')
	      break;
	    option_index = find_opt (option_string + 1, lang_mask);
	    if (option_index == OPT_SPECIAL_unknown)
	      {
		post_error ("unknown -W switch??", gnat_node);
		break;
	      }
	    else if (!(cl_options[option_index].flags & CL_WARNING))
	      {
		post_error ("-W switch does not control warning??", gnat_node);
		break;
	      }
	    else if (!(cl_options[option_index].flags & lang_mask))
	      {
		post_error ("-W switch not valid for Ada??", gnat_node);
		break;
	      }
	    if (cl_options[option_index].flags & CL_JOINED)
	      arg = option_string + 1 + cl_options[option_index].opt_len;
	  }
	else
	  option_index = 0;

	set_default_handlers (&handlers, NULL);
	control_warning_option (option_index, (int) kind, arg, imply, location,
				lang_mask, &handlers, &global_options,
				&global_options_set, global_dc);
      }
      break;

    default:
      break;
    }

  return gnu_result;
}

/* Check the inline status of nested function FNDECL wrt its parent function.

   If a non-inline nested function is referenced from an inline external
   function, we cannot honor both requests at the same time without cloning
   the nested function in the current unit since it is private to its unit.
   We could inline it as well but it's probably better to err on the side
   of too little inlining.

   This must be done only on nested functions present in the source code
   and not on nested functions generated by the compiler, e.g. finalizers,
   because they may be not marked inline and we don't want them to block
   the inlining of the parent function.  */

static void
check_inlining_for_nested_subprog (tree fndecl)
{
  if (DECL_IGNORED_P (current_function_decl) || DECL_IGNORED_P (fndecl))
    return;

  if (DECL_DECLARED_INLINE_P (fndecl))
    return;

  tree parent_decl = decl_function_context (fndecl);
  if (DECL_EXTERNAL (parent_decl) && DECL_DECLARED_INLINE_P (parent_decl))
    {
      const location_t loc1 = DECL_SOURCE_LOCATION (fndecl);
      const location_t loc2 = DECL_SOURCE_LOCATION (parent_decl);

      if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (parent_decl)))
	{
	  error_at (loc1, "subprogram %q+F not marked %<Inline_Always%>",
		    fndecl);
	  error_at (loc2, "parent subprogram cannot be inlined");
	}
      else
	{
	  warning_at (loc1, OPT_Winline, "subprogram %q+F not marked %<Inline%>",
		      fndecl);
	  warning_at (loc2, OPT_Winline, "parent subprogram cannot be inlined");
	}

      DECL_DECLARED_INLINE_P (parent_decl) = 0;
      DECL_UNINLINABLE (parent_decl) = 1;
    }
}

/* Return an expression for the length of TYPE, an integral type, computed in
   RESULT_TYPE, another integral type.

   We used to compute the length as MAX (hb - lb + 1, 0) which could overflow
   when lb == TYPE'First.  We now compute it as (hb >= lb) ? hb - lb + 1 : 0
   which would only overflow in much rarer cases, for extremely large arrays
   we expect never to encounter in practice.  Besides, the former computation
   required the use of potentially constraining signed arithmetics while the
   latter does not.  Note that the comparison must be done in the original
   base index type in order to avoid any overflow during the conversion.  */

static tree
get_type_length (tree type, tree result_type)
{
  tree comp_type = get_base_type (result_type);
  tree base_type = maybe_character_type (get_base_type (type));
  tree lb = convert (base_type, TYPE_MIN_VALUE (type));
  tree hb = convert (base_type, TYPE_MAX_VALUE (type));
  tree length
    = build_binary_op (PLUS_EXPR, comp_type,
		       build_binary_op (MINUS_EXPR, comp_type,
					convert (comp_type, hb),
					convert (comp_type, lb)),
		       build_int_cst (comp_type, 1));
  length
    = build_cond_expr (result_type,
		       build_binary_op (GE_EXPR, boolean_type_node, hb, lb),
		       convert (result_type, length),
		       build_int_cst (result_type, 0));
  return length;
}

/* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Attribute node, to a
   GCC tree, which is returned.  GNU_RESULT_TYPE_P is a pointer to where we
   should place the result type.  ATTRIBUTE is the attribute ID.  */

static tree
Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p,
		  Attribute_Id attribute)
{
  const Node_Id gnat_prefix = Prefix (gnat_node);
  tree gnu_prefix = gnat_to_gnu (gnat_prefix);
  tree gnu_type = TREE_TYPE (gnu_prefix);
  tree gnu_expr, gnu_result_type, gnu_result = error_mark_node;
  bool prefix_unused = false;
  Entity_Id gnat_smo;

  /* If the input is a NULL_EXPR, make a new one.  */
  if (TREE_CODE (gnu_prefix) == NULL_EXPR)
    {
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      *gnu_result_type_p = gnu_result_type;
      return build1 (NULL_EXPR, gnu_result_type, TREE_OPERAND (gnu_prefix, 0));
    }

  /* If the input is a LOAD_EXPR of an unconstrained array type, the second
     operand contains the storage model object.  */
  if (TREE_CODE (gnu_prefix) == LOAD_EXPR
      && TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
    gnat_smo = tree_to_shwi (TREE_OPERAND (gnu_prefix, 1));
  else
    gnat_smo = Empty;

  switch (attribute)
    {
    case Attr_Pred:
    case Attr_Succ:
      /* These just add or subtract the constant 1 since representation
	 clauses for enumeration types are handled in the front-end.  */
      gnu_expr = gnat_to_gnu (First (Expressions (gnat_node)));
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      gnu_type = maybe_character_type (gnu_result_type);
      if (TREE_TYPE (gnu_expr) != gnu_type)
	gnu_expr = convert (gnu_type, gnu_expr);
      gnu_result
	= build_binary_op (attribute == Attr_Pred ? MINUS_EXPR : PLUS_EXPR,
			   gnu_type, gnu_expr, build_int_cst (gnu_type, 1));
      break;

    case Attr_Address:
    case Attr_Unrestricted_Access:
      /* Conversions don't change the address of references but can cause
	 build_unary_op to miss the references below so strip them off.

         Also remove the conversions applied to declarations as the intent is
         to take the decls' address, not that of the copies that the
         conversions may create.

	 On the contrary, if the address-of operation causes a temporary
	 to be created, then it must be created with the proper type.  */
      gnu_expr = remove_conversions (gnu_prefix,
				     !Must_Be_Byte_Aligned (gnat_node));
      if (REFERENCE_CLASS_P (gnu_expr) || DECL_P (gnu_expr))
	gnu_prefix = gnu_expr;

      /* If we are taking 'Address of an unconstrained object, this is the
	 pointer to the underlying array.  */
      if (attribute == Attr_Address)
	gnu_prefix = maybe_unconstrained_array (gnu_prefix);

      /* If we are building a static dispatch table, we have to honor
	 TARGET_VTABLE_USES_DESCRIPTORS if we want to be compatible
	 with the C++ ABI.  We do it in the non-static case as well,
	 see gnat_to_gnu_entity, case E_Access_Subprogram_Type.  */
      else if (TARGET_VTABLE_USES_DESCRIPTORS
	       && Is_Dispatch_Table_Entity (Etype (gnat_node)))
	{
	  tree gnu_field, t;
	  /* Descriptors can only be built here for top-level functions.  */
	  bool build_descriptor = (global_bindings_p () != 0);
	  int i;
	  vec<constructor_elt, va_gc> *gnu_vec = NULL;
	  constructor_elt *elt;

	  gnu_result_type = get_unpadded_type (Etype (gnat_node));

	  /* If we're not going to build the descriptor, we have to retrieve
	     the one which will be built by the linker (or by the compiler
	     later if a static chain is requested).  */
	  if (!build_descriptor)
	    {
	      gnu_result = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_prefix);
	      gnu_result = fold_convert (build_pointer_type (gnu_result_type),
					 gnu_result);
	      gnu_result = build1 (INDIRECT_REF, gnu_result_type, gnu_result);
	    }

	  vec_safe_grow (gnu_vec, TARGET_VTABLE_USES_DESCRIPTORS, true);
	  elt = (gnu_vec->address () + TARGET_VTABLE_USES_DESCRIPTORS - 1);
	  for (gnu_field = TYPE_FIELDS (gnu_result_type), i = 0;
	       i < TARGET_VTABLE_USES_DESCRIPTORS;
	       gnu_field = DECL_CHAIN (gnu_field), i++)
	    {
	      if (build_descriptor)
		{
		  t = build2 (FDESC_EXPR, TREE_TYPE (gnu_field), gnu_prefix,
			      build_int_cst (NULL_TREE, i));
		  TREE_CONSTANT (t) = 1;
		}
	      else
		t = build3 (COMPONENT_REF, ptr_void_ftype, gnu_result,
			    gnu_field, NULL_TREE);

	      elt->index = gnu_field;
	      elt->value = t;
	      elt--;
	    }

	  gnu_result = gnat_build_constructor (gnu_result_type, gnu_vec);
	  break;
	}

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

    case Attr_Access:
    case Attr_Unchecked_Access:
    case Attr_Code_Address:
      /* Taking the address of a type does not make sense.  */
      gcc_assert (TREE_CODE (gnu_prefix) != TYPE_DECL);

      gnu_result_type = get_unpadded_type (Etype (gnat_node));

      /* We used to pass ATTR_ADDR_EXPR for Attr_Unrestricted_Access too, but
	 the processing done in build_unary_op for it flattens the reference,
	 in particular removes all intermediate (view) conversions, which may
	 cause SUBSTITUTE_PLACEHOLDER_IN_EXPR to fail to substitute in the
	 bounds of a fat pointer returned for Attr_Unrestricted_Access.  */
      gnu_result
	= build_unary_op (attribute == Attr_Address
			  && !Must_Be_Byte_Aligned (gnat_node)
			  ? ATTR_ADDR_EXPR : ADDR_EXPR,
			  gnu_result_type, gnu_prefix);

      /* For 'Code_Address, find an inner ADDR_EXPR and mark it so that we
	 don't try to build a trampoline.  */
      if (attribute == Attr_Code_Address)
	{
	  gnu_expr = remove_conversions (gnu_result, false);

	  if (TREE_CODE (gnu_expr) == ADDR_EXPR)
	    TREE_NO_TRAMPOLINE (gnu_expr) = TREE_CONSTANT (gnu_expr) = 1;

	  /* On targets for which function symbols denote a descriptor, the
	     code address is stored within the first slot of the descriptor
	     so we do an additional dereference:
	       result = *((result_type *) result)
	     where we expect result to be of some pointer type already.  */
	  if (targetm.calls.custom_function_descriptors == 0)
	    gnu_result
	      = build_unary_op (INDIRECT_REF, NULL_TREE,
				convert (build_pointer_type (gnu_result_type),
					 gnu_result));
	}

      /* For 'Access, issue an error message if the prefix is a C++ method
	 since it can use a special calling convention on some platforms,
	 which cannot be propagated to the access type.  */
      else if (attribute == Attr_Access
	       && TREE_CODE (TREE_TYPE (gnu_prefix)) == METHOD_TYPE)
	post_error ("access to C++ constructor or member function not allowed",
		    gnat_node);

      /* For other address attributes applied to a nested function,
	 find an inner ADDR_EXPR and annotate it so that we can issue
	 a useful warning with -Wtrampolines.  */
      else if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (gnu_prefix))
	       && (gnu_expr = remove_conversions (gnu_result, false))
	       && TREE_CODE (gnu_expr) == ADDR_EXPR
	       && decl_function_context (TREE_OPERAND (gnu_expr, 0)))
	{
	  set_expr_location_from_node (gnu_expr, gnat_node);

	  /* Also check the inlining status.  */
	  check_inlining_for_nested_subprog (TREE_OPERAND (gnu_expr, 0));

	  /* Moreover, for 'Access or 'Unrestricted_Access with non-
	     foreign-compatible representation, mark the ADDR_EXPR so
	     that we can build a descriptor instead of a trampoline.  */
	  if ((attribute == Attr_Access
	       || attribute == Attr_Unrestricted_Access)
	      && targetm.calls.custom_function_descriptors > 0
	      && Can_Use_Internal_Rep (Underlying_Type (Etype (gnat_node))))
	    FUNC_ADDR_BY_DESCRIPTOR (gnu_expr) = 1;

	  /* Otherwise, we need to check that we are not violating the
	     No_Implicit_Dynamic_Code restriction.  */
	  else if (targetm.calls.custom_function_descriptors != 0)
	    Check_Implicit_Dynamic_Code_Allowed (gnat_node);
	}
      break;

    case Attr_Pool_Address:
      {
	tree gnu_ptr = gnu_prefix;
	tree gnu_obj_type;

        if (Is_Extended_Access_Type (Etype (Prefix (gnat_node)))
            && !Is_Constrained (Etype (gnat_node)))
          gnu_result_type = get_unpadded_extended_type (Etype (gnat_node));
        else
          gnu_result_type = get_unpadded_type (Etype (gnat_node));

	/* If this is fat or extended pointer, the object must have been
	   allocated with the template in front of the array.  So compute the
	   template address; do it by converting to a thin pointer.  */
	if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (gnu_ptr))
            || TYPE_IS_EXTENDED_POINTER_P (TREE_TYPE (gnu_ptr)))
	  gnu_ptr
	    = convert (build_pointer_type
		       (TYPE_OBJECT_RECORD_TYPE
			(TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (gnu_ptr)))),
		       gnu_ptr);

	gnu_obj_type = TREE_TYPE (TREE_TYPE (gnu_ptr));

	/* If this is a thin pointer, the object must have been allocated with
	   the template in front of the array.  So compute the template address
	   and return it.  */
	if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr)))
	  gnu_ptr
	    = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
			       gnu_ptr,
			       fold_build1 (NEGATE_EXPR, sizetype,
					    byte_position
					    (DECL_CHAIN
					     TYPE_FIELDS ((gnu_obj_type)))));

	gnu_result = convert (gnu_result_type, gnu_ptr);
      }
      break;

    case Attr_Size:
    case Attr_Object_Size:
    case Attr_Value_Size:
    case Attr_Max_Size_In_Storage_Elements:
      /* Strip NOPs, conversions between original and packable versions, and
	 unpadding from GNU_PREFIX.  Note that we cannot simply strip every
	 VIEW_CONVERT_EXPR because some of them may give the actual size, e.g.
	 for nominally unconstrained packed array.  We use GNU_EXPR to see
	 if a COMPONENT_REF was involved.  */
      while (CONVERT_EXPR_P (gnu_prefix)
	     || TREE_CODE (gnu_prefix) == NON_LVALUE_EXPR
	     || (TREE_CODE (gnu_prefix) == VIEW_CONVERT_EXPR
		 && TREE_CODE (TREE_TYPE (gnu_prefix)) == RECORD_TYPE
		 && TREE_CODE (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))
		    == RECORD_TYPE
		 && TYPE_NAME (TREE_TYPE (gnu_prefix))
		    == TYPE_NAME (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))))
	gnu_prefix = TREE_OPERAND (gnu_prefix, 0);
      gnu_expr = gnu_prefix;
      if (TREE_CODE (gnu_prefix) == COMPONENT_REF
	  && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0))))
	gnu_prefix = TREE_OPERAND (gnu_prefix, 0);
      prefix_unused = true;
      gnu_type = TREE_TYPE (gnu_prefix);

      /* Replace an unconstrained array type with the type of the underlying
	 array, except for 'Max_Size_In_Storage_Elements because we need to
	 return the (maximum) size requested for an allocator.  */
      if (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
	{
	  gnu_type = TYPE_OBJECT_RECORD_TYPE (gnu_type);
	  if (attribute != Attr_Max_Size_In_Storage_Elements)
	    gnu_type = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_type)));
	}

      /* The type must be frozen at this point.  */
      gcc_assert (COMPLETE_TYPE_P (gnu_type));

      /* If we're looking for the size of a field, return the field size.  */
      if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
	gnu_result = DECL_SIZE (TREE_OPERAND (gnu_prefix, 1));

      /* Otherwise, if the prefix is an object, or if we are looking for
	 'Object_Size or 'Max_Size_In_Storage_Elements, the result is the
	 GCC size of the type.  We make an exception for padded objects,
	 as we do not take into account alignment promotions for the size.
	 This is in keeping with the object case of gnat_to_gnu_entity.  */
      else if ((TREE_CODE (gnu_prefix) != TYPE_DECL
		&& !(TYPE_IS_PADDING_P (gnu_type)
		     && TREE_CODE (gnu_expr) == COMPONENT_REF
		     && pad_type_has_rm_size (gnu_type)))
	       || attribute == Attr_Object_Size
	       || attribute == Attr_Max_Size_In_Storage_Elements)
	{
	  /* If this is a dereference and we have a special dynamic constrained
	     subtype on the prefix, use it to compute the size; otherwise, use
	     the designated subtype.  */
	  if (Nkind (gnat_prefix) == N_Explicit_Dereference
	      && Present (Actual_Designated_Subtype (gnat_prefix)))
	    {
	      tree gnu_actual_obj_type
		= gnat_to_gnu_type (Actual_Designated_Subtype (gnat_prefix));
	      tree gnu_ptr_type
		= TREE_TYPE (gnat_to_gnu (Prefix (gnat_prefix)));

	      if (TYPE_IS_FAT_OR_THIN_POINTER_P (gnu_ptr_type)
		  || TYPE_IS_EXTENDED_POINTER_P (gnu_ptr_type))
		gnu_type
		  = build_unc_object_type_from_ptr (gnu_ptr_type,
						    gnu_actual_obj_type,
						    get_identifier ("SIZE"),
						    false);
	    }

	  gnu_result = TYPE_SIZE (gnu_type);
	}

      /* Otherwise, the result is the RM size of the type.  */
      else
	gnu_result = rm_size (gnu_type);

      /* Deal with a self-referential size by qualifying the size with the
	 object or returning the maximum size for a type.  */
      if (TREE_CODE (gnu_prefix) != TYPE_DECL)
	{
	  gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result, gnu_prefix);
	  if (Present (gnat_smo)
	      && Present (Storage_Model_Copy_From (gnat_smo)))
	    gnu_result = INSTANTIATE_LOAD_IN_EXPR (gnu_result, gnat_smo);
	}
      else if (CONTAINS_PLACEHOLDER_P (gnu_result))
	gnu_result = max_size (gnu_result, true);

      /* If the type contains a template, subtract the padded size of the
	 template, except for 'Max_Size_In_Storage_Elements because we need
	 to return the (maximum) size requested for an allocator.  */
      if (TREE_CODE (gnu_type) == RECORD_TYPE
	  && TYPE_CONTAINS_TEMPLATE_P (gnu_type)
	  && attribute != Attr_Max_Size_In_Storage_Elements)
	gnu_result
	  = size_binop (MINUS_EXPR, gnu_result,
			bit_position (DECL_CHAIN (TYPE_FIELDS (gnu_type))));

      /* For 'Max_Size_In_Storage_Elements, adjust the unit.  */
      if (attribute == Attr_Max_Size_In_Storage_Elements)
	gnu_result = size_binop (CEIL_DIV_EXPR, gnu_result, bitsize_unit_node);

      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      break;

    case Attr_Alignment:
      {
	unsigned int align;

	if (TREE_CODE (gnu_prefix) == COMPONENT_REF
	    && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0))))
	  gnu_prefix = TREE_OPERAND (gnu_prefix, 0);

	gnu_type = TREE_TYPE (gnu_prefix);
	gnu_result_type = get_unpadded_type (Etype (gnat_node));
	prefix_unused = true;

	if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
	  align = DECL_ALIGN (TREE_OPERAND (gnu_prefix, 1)) / BITS_PER_UNIT;
	else
	  {
	    Entity_Id gnat_type = Etype (gnat_prefix);
	    unsigned int double_align;
	    bool is_capped_double, align_clause;

	    /* If the default alignment of "double" or larger scalar types is
	       specifically capped and there is an alignment clause neither
	       on the type nor on the prefix itself, return the cap.  */
	    if ((double_align = double_float_alignment) > 0)
	      is_capped_double
		= is_double_float_or_array (gnat_type, &align_clause);
	    else if ((double_align = double_scalar_alignment) > 0)
	      is_capped_double
		= is_double_scalar_or_array (gnat_type, &align_clause);
	    else
	      is_capped_double = align_clause = false;

	    if (is_capped_double
		&& Nkind (gnat_prefix) == N_Identifier
		&& Present (Alignment_Clause (Entity (gnat_prefix))))
	      align_clause = true;

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

	gnu_result = size_int (align);
      }
      break;

    case Attr_First:
    case Attr_Last:
    case Attr_Range_Length:
      prefix_unused = true;

      if (INTEGRAL_TYPE_P (gnu_type) || SCALAR_FLOAT_TYPE_P (gnu_type))
	{
	  gnu_result_type = get_unpadded_type (Etype (gnat_node));

	  if (attribute == Attr_First)
	    gnu_result = TYPE_MIN_VALUE (gnu_type);
	  else if (attribute == Attr_Last)
	    gnu_result = TYPE_MAX_VALUE (gnu_type);
	  else
	    gnu_result = get_type_length (gnu_type, gnu_result_type);
	  break;
	}

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

    case Attr_Length:
      {
	int Dimension = (Present (Expressions (gnat_node))
			 ? UI_To_Int (Intval (First (Expressions (gnat_node))))
			 : 1), i;
	struct parm_attr_d *pa = NULL;
	Entity_Id gnat_param = Empty;
	bool unconstrained_ptr_deref = false;

	gnu_prefix = maybe_padded_object (gnu_prefix);
	gnu_prefix = maybe_unconstrained_array (gnu_prefix);

	/* We treat unconstrained array In parameters specially.  We also note
	   whether we are dereferencing a pointer to unconstrained array.  */
	if (!Is_Constrained (Etype (gnat_prefix)))
	  switch (Nkind (gnat_prefix))
	    {
	    case N_Identifier:
	      /* This is the direct case.  */
	      if (Ekind (Entity (gnat_prefix)) == E_In_Parameter)
		gnat_param = Entity (gnat_prefix);
	      break;

	    case N_Explicit_Dereference:
	      /* This is the indirect case.  Note that we need to be sure that
		 the access value cannot be null as we'll hoist the load.  */
	      if (Nkind (Prefix (gnat_prefix)) == N_Identifier
		  && Ekind (Entity (Prefix (gnat_prefix))) == E_In_Parameter)
		{
		  if (Can_Never_Be_Null (Entity (Prefix (gnat_prefix))))
		    gnat_param = Entity (Prefix (gnat_prefix));
		}
	      else
		unconstrained_ptr_deref = true;
	      break;

	    default:
	      break;
	  }

	/* If the prefix is the view conversion of a constrained array to an
	   unconstrained form, we retrieve the constrained array because we
	   might not be able to substitute the PLACEHOLDER_EXPR coming from
	   the conversion.  This can occur with the 'Old attribute applied
	   to a parameter with an unconstrained type, which gets rewritten
	   into a constrained local variable very late in the game.  */
	if (TREE_CODE (gnu_prefix) == VIEW_CONVERT_EXPR
	    && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (TREE_TYPE (gnu_prefix)))
	    && !CONTAINS_PLACEHOLDER_P
	        (TYPE_SIZE (TREE_TYPE (TREE_OPERAND (gnu_prefix, 0)))))
	  gnu_type = TREE_TYPE (TREE_OPERAND (gnu_prefix, 0));
	else
	  gnu_type = TREE_TYPE (gnu_prefix);

	prefix_unused = true;
	gnu_result_type = get_unpadded_type (Etype (gnat_node));

	if (TYPE_CONVENTION_FORTRAN_P (gnu_type))
	  {
	    int ndim;
	    tree gnu_type_temp;

	    for (ndim = 1, gnu_type_temp = gnu_type;
		 TREE_CODE (TREE_TYPE (gnu_type_temp)) == ARRAY_TYPE
		 && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type_temp));
		 ndim++, gnu_type_temp = TREE_TYPE (gnu_type_temp))
	      ;

	    Dimension = ndim + 1 - Dimension;
	  }

	for (i = 1; i < Dimension; i++)
	  gnu_type = TREE_TYPE (gnu_type);

	gcc_assert (TREE_CODE (gnu_type) == ARRAY_TYPE);

	/* When not optimizing, look up the slot associated with the parameter
	   and the dimension in the cache and create a new one on failure.
	   Don't do this when the actual subtype needs debug info (this happens
	   with -gnatD): in elaborate_expression_1, we create variables that
	   hold the bounds, so caching attributes isn't very interesting and
	   causes dependency issues between these variables and cached
	   expressions.  */
	if (!optimize
	    && Present (gnat_param)
	    && !(Present (Actual_Subtype (gnat_param))
		 && Needs_Debug_Info (Actual_Subtype (gnat_param))))
	  {
	    FOR_EACH_VEC_SAFE_ELT (f_parm_attr_cache, i, pa)
	      if (pa->id == gnat_param && pa->dim == Dimension)
		break;

	    if (!pa)
	      {
		pa = ggc_cleared_alloc<parm_attr_d> ();
		pa->id = gnat_param;
		pa->dim = Dimension;
		vec_safe_push (f_parm_attr_cache, pa);
	      }
	  }

	/* Return the cached expression or build a new one.  */
	if (attribute == Attr_First)
	  {
	    if (pa && pa->first)
	      {
		gnu_result = pa->first;
		break;
	      }

	    gnu_result
	      = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type)));
	  }

	else if (attribute == Attr_Last)
	  {
	    if (pa && pa->last)
	      {
		gnu_result = pa->last;
		break;
	      }

	    gnu_result
	      = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type)));
	  }

	else /* attribute == Attr_Range_Length || attribute == Attr_Length  */
	  {
	    if (pa && pa->length)
	      {
		gnu_result = pa->length;
		break;
	      }

	    gnu_result
	      = get_type_length (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type)),
				 gnu_result_type);
	  }

	/* If this has a PLACEHOLDER_EXPR, qualify it by the object we are
	   handling.  Note that these attributes could not have been used on
	   an unconstrained array type.  */
	gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result, gnu_prefix);
	if (Present (gnat_smo)
	    && Present (Storage_Model_Copy_From (gnat_smo)))
	  gnu_result = INSTANTIATE_LOAD_IN_EXPR (gnu_result, gnat_smo);

	/* Cache the expression we have just computed.  Since we want to do it
	   at run time, we force the use of a SAVE_EXPR and let the gimplifier
	   create the temporary in the outermost binding level.  We will make
	   sure in Subprogram_Body_to_gnu that it is evaluated on all possible
	   paths by forcing its evaluation on entry of the function.  */
	if (pa)
	  {
	    gnu_result
	      = build1 (SAVE_EXPR, TREE_TYPE (gnu_result), gnu_result);
	    switch (attribute)
	      {
	      case Attr_First:
		pa->first = gnu_result;
		break;

	      case Attr_Last:
		pa->last = gnu_result;
		break;

	      case Attr_Length:
	      case Attr_Range_Length:
		pa->length = gnu_result;
		break;

	      default:
		gcc_unreachable ();
	      }
	  }

	/* Otherwise, evaluate it each time it is referenced.  */
	else
	  switch (attribute)
	    {
	    case Attr_First:
	    case Attr_Last:
	      /* If we are dereferencing a pointer to unconstrained array, we
		 need to capture the value because the pointed-to bounds may
		 subsequently be released.  */
	      if (unconstrained_ptr_deref)
		gnu_result
		  = build1 (SAVE_EXPR, TREE_TYPE (gnu_result), gnu_result);
	      break;

	    case Attr_Length:
	    case Attr_Range_Length:
	      /* Set the source location onto the predicate of the condition
		 but not if the expression is cached to avoid messing up the
		 debug info.  */
	      if (TREE_CODE (gnu_result) == COND_EXPR
		  && EXPR_P (TREE_OPERAND (gnu_result, 0)))
		set_expr_location_from_node (TREE_OPERAND (gnu_result, 0),
					     gnat_node);
	      break;

	    default:
	      gcc_unreachable ();
	    }

	break;
      }

    case Attr_Bit_Position:
    case Attr_Position:
    case Attr_First_Bit:
    case Attr_Last_Bit:
    case Attr_Bit:
      {
	poly_int64 bitsize;
	poly_int64 bitpos;
	tree gnu_offset;
	tree gnu_field_bitpos;
	tree gnu_field_offset;
	tree gnu_inner;
	machine_mode mode;
	int unsignedp, reversep, volatilep;

	gnu_result_type = get_unpadded_type (Etype (gnat_node));
	gnu_prefix = remove_conversions (gnu_prefix, true);
	prefix_unused = true;

	/* We can have 'Bit on any object, but if it isn't a COMPONENT_REF,
	   the result is 0.  Don't allow 'Bit on a bare component, though.  */
	if (attribute == Attr_Bit
	    && TREE_CODE (gnu_prefix) != COMPONENT_REF
	    && TREE_CODE (gnu_prefix) != FIELD_DECL)
	  {
	    gnu_result = integer_zero_node;
	    break;
	  }

	else
	  gcc_assert (TREE_CODE (gnu_prefix) == COMPONENT_REF
		      || (attribute == Attr_Bit_Position
			  && TREE_CODE (gnu_prefix) == FIELD_DECL));

	get_inner_reference (gnu_prefix, &bitsize, &bitpos, &gnu_offset,
			     &mode, &unsignedp, &reversep, &volatilep);

	if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
	  {
	    gnu_field_bitpos = bit_position (TREE_OPERAND (gnu_prefix, 1));
	    gnu_field_offset = byte_position (TREE_OPERAND (gnu_prefix, 1));

	    for (gnu_inner = TREE_OPERAND (gnu_prefix, 0);
		 TREE_CODE (gnu_inner) == COMPONENT_REF
		 && DECL_INTERNAL_P (TREE_OPERAND (gnu_inner, 1));
		 gnu_inner = TREE_OPERAND (gnu_inner, 0))
	      {
		gnu_field_bitpos
		  = size_binop (PLUS_EXPR, gnu_field_bitpos,
				bit_position (TREE_OPERAND (gnu_inner, 1)));
		gnu_field_offset
		  = size_binop (PLUS_EXPR, gnu_field_offset,
				byte_position (TREE_OPERAND (gnu_inner, 1)));
	      }
	  }
	else if (TREE_CODE (gnu_prefix) == FIELD_DECL)
	  {
	    gnu_field_bitpos = bit_position (gnu_prefix);
	    gnu_field_offset = byte_position (gnu_prefix);
	  }
	else
	  {
	    gnu_field_bitpos = bitsize_zero_node;
	    gnu_field_offset = size_zero_node;
	  }

	switch (attribute)
	  {
	  case Attr_Position:
	    gnu_result = gnu_field_offset;
	    break;

	  case Attr_First_Bit:
	  case Attr_Bit:
	    gnu_result = size_int (num_trailing_bits (bitpos));
	    break;

	  case Attr_Last_Bit:
	    gnu_result = bitsize_int (num_trailing_bits (bitpos));
	    gnu_result = size_binop (PLUS_EXPR, gnu_result,
				     TYPE_SIZE (TREE_TYPE (gnu_prefix)));
	    /* ??? Avoid a large unsigned result that will overflow when
	       converted to the signed universal_integer.  */
	    if (integer_zerop (gnu_result))
	      gnu_result = integer_minus_one_node;
	    else
	      gnu_result
		= size_binop (MINUS_EXPR, gnu_result, bitsize_one_node);
	    break;

	  case Attr_Bit_Position:
	    gnu_result = gnu_field_bitpos;
	    break;

	    /* -Wswitch warning avoidance.  */
	  default:
	    break;
	  }

	/* If this has a PLACEHOLDER_EXPR, qualify it by the object we are
	   handling.  */
	gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result, gnu_prefix);
	if (Present (gnat_smo)
	    && Present (Storage_Model_Copy_From (gnat_smo)))
	  gnu_result = INSTANTIATE_LOAD_IN_EXPR (gnu_result, gnat_smo);
	break;
      }

    case Attr_Min:
    case Attr_Max:
      {
	tree gnu_lhs = gnat_to_gnu (First (Expressions (gnat_node)));
	tree gnu_rhs = gnat_to_gnu (Next (First (Expressions (gnat_node))));

	gnu_result_type = get_unpadded_type (Etype (gnat_node));

	/* The result of {MIN,MAX}_EXPR is unspecified if either operand is
	   a NaN so we implement the semantics of C99 f{min,max} to make it
	   predictable in this case: if either operand is a NaN, the other
	   is returned; if both operands are NaN's, a NaN is returned.  */
	if (SCALAR_FLOAT_TYPE_P (gnu_result_type)
	    && !Machine_Overflows_On_Target)
	  {
	    const bool lhs_side_effects_p = TREE_SIDE_EFFECTS (gnu_lhs);
	    const bool rhs_side_effects_p = TREE_SIDE_EFFECTS (gnu_rhs);
	    tree t = builtin_decl_explicit (BUILT_IN_ISNAN);
	    tree lhs_is_nan, rhs_is_nan;

	    /* If the operands have side-effects, they need to be evaluated
	       only once in spite of the multiple references in the result.  */
	    if (lhs_side_effects_p)
	      gnu_lhs = gnat_protect_expr (gnu_lhs);
	    if (rhs_side_effects_p)
	      gnu_rhs = gnat_protect_expr (gnu_rhs);

	    lhs_is_nan = fold_build2 (NE_EXPR, boolean_type_node,
				      build_call_expr (t, 1, gnu_lhs),
				      integer_zero_node);

	    rhs_is_nan = fold_build2 (NE_EXPR, boolean_type_node,
				      build_call_expr (t, 1, gnu_rhs),
				      integer_zero_node);

	    gnu_result = build_binary_op (attribute == Attr_Min
					  ? MIN_EXPR : MAX_EXPR,
					  gnu_result_type, gnu_lhs, gnu_rhs);
	    gnu_result = fold_build3 (COND_EXPR, gnu_result_type,
				      rhs_is_nan, gnu_lhs, gnu_result);
	    gnu_result = fold_build3 (COND_EXPR, gnu_result_type,
				      lhs_is_nan, gnu_rhs, gnu_result);

	    /* If the operands have side-effects, they need to be evaluated
	       before doing the tests above since the place they otherwise
	       would end up being evaluated at run time could be wrong.  */
	    if (lhs_side_effects_p)
	      gnu_result
		= build2 (COMPOUND_EXPR, gnu_result_type, gnu_lhs, gnu_result);

	    if (rhs_side_effects_p)
	      gnu_result
		= build2 (COMPOUND_EXPR, gnu_result_type, gnu_rhs, gnu_result);
	  }
	else
	  gnu_result = build_binary_op (attribute == Attr_Min
					? MIN_EXPR : MAX_EXPR,
					gnu_result_type, gnu_lhs, gnu_rhs);
      }
      break;

    case Attr_Passed_By_Reference:
      gnu_result = size_int (default_pass_by_ref (gnu_type)
			     || must_pass_by_ref (gnu_type));
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      break;

    case Attr_Component_Size:
      gnu_prefix = maybe_padded_object (gnu_prefix);
      gnu_type = TREE_TYPE (gnu_prefix);

      if (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
	gnu_type = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_type))));

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

      gcc_assert (TREE_CODE (gnu_type) == ARRAY_TYPE);

      /* Note this size cannot be self-referential.  */
      gnu_result = TYPE_SIZE (TREE_TYPE (gnu_type));
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      prefix_unused = true;
      break;

    case Attr_Descriptor_Size:
      gnu_type = TREE_TYPE (gnu_prefix);
      gcc_assert (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE);

      /* Return the padded size of the template in the object record type.  */
      gnu_type = TYPE_OBJECT_RECORD_TYPE (gnu_type);
      gnu_result = bit_position (DECL_CHAIN (TYPE_FIELDS (gnu_type)));
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      prefix_unused = true;
      break;

    case Attr_Null_Parameter:
      /* This is just a zero cast to the pointer type for our prefix and
	 dereferenced.  */
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      gnu_result
	= build_unary_op (INDIRECT_REF, NULL_TREE,
			  convert (build_pointer_type (gnu_result_type),
				   integer_zero_node));
      break;

    case Attr_Mechanism_Code:
      {
	Entity_Id gnat_obj = Entity (gnat_prefix);
	int code;

	prefix_unused = true;
	gnu_result_type = get_unpadded_type (Etype (gnat_node));
	if (Present (Expressions (gnat_node)))
	  {
	    int i = UI_To_Int (Intval (First (Expressions (gnat_node))));

	    for (gnat_obj = First_Formal (gnat_obj); i > 1;
		 i--, gnat_obj = Next_Formal (gnat_obj))
	      ;
	  }

	code = Mechanism (gnat_obj);
	if (code == Default)
	  code = ((present_gnu_tree (gnat_obj)
		   && (DECL_BY_REF_P (get_gnu_tree (gnat_obj))
		       || ((TREE_CODE (get_gnu_tree (gnat_obj))
			    == PARM_DECL)
			   && (DECL_BY_COMPONENT_PTR_P
			       (get_gnu_tree (gnat_obj))))))
		  ? By_Reference : By_Copy);
	gnu_result = convert (gnu_result_type, size_int (- code));
      }
      break;

    case Attr_Model:
      /* We treat Model as identical to Machine.  This is true for at least
	 IEEE and some other nice floating-point systems.  */

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

    case Attr_Machine:
      /* The trick is to force the compiler to store the result in memory so
	 that we do not have extra precision used.  But do this only when this
	 is necessary, i.e. if FP_ARITH_MAY_WIDEN is true and the precision of
	 the type is lower than that of the longest floating-point type.  */
      prefix_unused = true;
      gnu_expr = gnat_to_gnu (First (Expressions (gnat_node)));
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      gnu_result = convert (gnu_result_type, gnu_expr);

      if (TREE_CODE (gnu_result) != REAL_CST
	  && fp_arith_may_widen
	  && TYPE_PRECISION (gnu_result_type)
	     < TYPE_PRECISION (longest_float_type_node))
	{
	  tree rec_type = make_node (RECORD_TYPE);
	  tree field
	    = create_field_decl (get_identifier ("OBJ"), gnu_result_type,
				 rec_type, NULL_TREE, NULL_TREE, 0, 0);
	  tree rec_val, asm_expr;

	  finish_record_type (rec_type, field, 0, false);

	  rec_val = build_constructor_single (rec_type, field, gnu_result);
	  rec_val = build1 (SAVE_EXPR, rec_type, rec_val);

	  asm_expr
	    = build5 (ASM_EXPR, void_type_node,
		      build_string (0, ""),
		      tree_cons (build_tree_list (NULL_TREE,
						  build_string (2, "=m")),
				 rec_val, NULL_TREE),
		      tree_cons (build_tree_list (NULL_TREE,
						  build_string (1, "m")),
				 rec_val, NULL_TREE),
		      NULL_TREE, NULL_TREE);
	  ASM_VOLATILE_P (asm_expr) = 1;

	  gnu_result
	    = build_compound_expr (gnu_result_type, asm_expr,
				   build_component_ref (rec_val, field,
							false));
	}
      break;

    case Attr_Deref:
      prefix_unused = true;
      gnu_expr = gnat_to_gnu (First (Expressions (gnat_node)));
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      /* This can be a random address so build an alias-all pointer type.  */
      gnu_expr
	= convert (build_pointer_type_for_mode (gnu_result_type, ptr_mode,
						true),
		   gnu_expr);
      gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_expr);
      break;

    default:
      /* This abort means that we have an unimplemented attribute.  */
      gcc_unreachable ();
    }

  /* If this is an attribute where the prefix was unused, force a use of it if
     it has a side-effect.  But don't do it if the prefix is just an entity
     name.  However, if an access check is needed, we must do it.  See second
     example in AARM 11.6(5.e).  */
  if (prefix_unused
      && TREE_SIDE_EFFECTS (gnu_prefix)
      && !Is_Entity_Name (gnat_prefix))
    gnu_result
      = build_compound_expr (TREE_TYPE (gnu_result), gnu_prefix, gnu_result);

  *gnu_result_type_p = gnu_result_type;
  return gnu_result;
}

/* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Case_Statement, to a
   GCC tree, which is returned.  */

static tree
Case_Statement_to_gnu (Node_Id gnat_node)
{
  tree gnu_result, gnu_expr, gnu_type, gnu_label;
  Node_Id gnat_when;
  location_t end_locus;
  bool may_fallthru = false;

  gnu_expr = gnat_to_gnu (Expression (gnat_node));
  gnu_expr = convert (get_base_type (TREE_TYPE (gnu_expr)), gnu_expr);
  gnu_expr = maybe_character_value (gnu_expr);
  gnu_type = TREE_TYPE (gnu_expr);

  /* We build a SWITCH_EXPR that contains the code with interspersed
     CASE_LABEL_EXPRs for each label.  */
  if (!Sloc_to_locus (End_Location (gnat_node), &end_locus))
    end_locus = input_location;
  gnu_label = create_artificial_label (end_locus);
  start_stmt_group ();

  for (gnat_when = First_Non_Pragma (Alternatives (gnat_node));
       Present (gnat_when);
       gnat_when = Next_Non_Pragma (gnat_when))
    {
      bool choices_added_p = false;
      Node_Id gnat_choice;

      /* First compile all the different case choices for the current WHEN
	 alternative.  */
      for (gnat_choice = First (Discrete_Choices (gnat_when));
	   Present (gnat_choice);
	   gnat_choice = Next (gnat_choice))
	{
	  tree gnu_low = NULL_TREE, gnu_high = NULL_TREE;
	  tree label = create_artificial_label (input_location);

	  switch (Nkind (gnat_choice))
	    {
	    case N_Range:
	      gnu_low = gnat_to_gnu (Low_Bound (gnat_choice));
	      gnu_high = gnat_to_gnu (High_Bound (gnat_choice));
	      break;

	    case N_Subtype_Indication:
	      gnu_low = gnat_to_gnu (Low_Bound (Range_Expression
						(Constraint (gnat_choice))));
	      gnu_high = gnat_to_gnu (High_Bound (Range_Expression
						  (Constraint (gnat_choice))));
	      break;

	    case N_Identifier:
	    case N_Expanded_Name:
	      /* This represents either a subtype range or a static value of
		 some kind; Ekind says which.  */
	      if (Is_Type (Entity (gnat_choice)))
		{
		  tree gnu_type = get_unpadded_type (Entity (gnat_choice));

		  gnu_low = TYPE_MIN_VALUE (gnu_type);
		  gnu_high = TYPE_MAX_VALUE (gnu_type);
		  break;
		}

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

	    case N_Character_Literal:
	    case N_Integer_Literal:
	      gnu_low = gnat_to_gnu (gnat_choice);
	      break;

	    case N_Others_Choice:
	      break;

	    default:
	      gcc_unreachable ();
	    }

	  /* Everything should be folded into constants at this point.  */
	  gcc_assert (!gnu_low  || TREE_CODE (gnu_low)  == INTEGER_CST);
	  gcc_assert (!gnu_high || TREE_CODE (gnu_high) == INTEGER_CST);

	  if (gnu_low && TREE_TYPE (gnu_low) != gnu_type)
	    gnu_low = convert (gnu_type, gnu_low);
	  if (gnu_high && TREE_TYPE (gnu_high) != gnu_type)
	    gnu_high = convert (gnu_type, gnu_high);

	  add_stmt_with_node (build_case_label (gnu_low, gnu_high, label),
			      gnat_choice);
	  choices_added_p = true;
	}

      /* This construct doesn't define a scope so we shouldn't push a binding
	 level around the statement list.  Except that we have always done so
	 historically and this makes it possible to reduce stack usage.  As a
	 compromise, we keep doing it for case statements, for which this has
	 never been problematic, but not for case expressions in Ada 2012.  */
      if (choices_added_p)
	{
	  const bool case_expr_p = From_Conditional_Expression (gnat_node);
	  tree group = build_stmt_group (Statements (gnat_when), !case_expr_p);
	  const bool group_may_fallthru = block_may_fallthru (group);
	  add_stmt (group);
	  if (group_may_fallthru)
	    {
	      tree stmt = build1 (GOTO_EXPR, void_type_node, gnu_label);
	      SET_EXPR_LOCATION (stmt, end_locus);
	      add_stmt (stmt);
	      may_fallthru = true;
	    }
	}
    }

  /* Now emit a definition of the label the cases branch to, if any.  */
  if (may_fallthru)
    add_stmt (build1 (LABEL_EXPR, void_type_node, gnu_label));
  gnu_result = build2 (SWITCH_EXPR, gnu_type, gnu_expr, end_stmt_group ());

  return gnu_result;
}

/* Return true if we are in the body of a loop.  */

static inline bool
inside_loop_p (void)
{
  return !vec_safe_is_empty (gnu_loop_stack);
}

/* Find out whether EXPR is a simple additive expression based on the iteration
   variable of some enclosing loop in the current function.  If so, return the
   loop and set *DISP to the displacement and *NEG_P to true if this is for a
   subtraction; otherwise, return NULL.  */

static struct loop_info_d *
find_loop_for (tree expr, tree *disp, bool *neg_p)
{
  tree var, add, cst;
  bool minus_p;
  struct loop_info_d *iter = NULL;
  unsigned int i;

  if (is_simple_additive_expression (expr, &add, &cst, &minus_p))
    {
      var = add;
      if (disp)
	*disp = cst;
      if (neg_p)
	*neg_p = minus_p;
    }
  else
    {
      var = expr;
      if (disp)
	*disp =  NULL_TREE;
      if (neg_p)
	*neg_p = false;
    }

  var = remove_conversions (var, false);

  if (TREE_CODE (var) != VAR_DECL)
    return NULL;

  gcc_checking_assert (vec_safe_length (gnu_loop_stack) > 0);

  FOR_EACH_VEC_ELT_REVERSE (*gnu_loop_stack, i, iter)
    if (iter->loop_var == var && iter->fndecl == current_function_decl)
      break;

  return iter;
}

/* Return the innermost enclosing loop in the current function.  */

static struct loop_info_d *
find_loop (void)
{
  struct loop_info_d *iter = NULL;
  unsigned int i;

  gcc_checking_assert (vec_safe_length (gnu_loop_stack) > 0);

  FOR_EACH_VEC_ELT_REVERSE (*gnu_loop_stack, i, iter)
    if (iter->fndecl == current_function_decl)
      break;

  return iter;
}

/* Return true if VAL (of type TYPE) can equal the minimum value if MAX is
   false, or the maximum value if MAX is true, of TYPE.  */

static bool
can_equal_min_or_max_val_p (tree val, tree type, bool max)
{
  tree min_or_max_val = (max ? TYPE_MAX_VALUE (type) : TYPE_MIN_VALUE (type));

  if (TREE_CODE (min_or_max_val) != INTEGER_CST)
    return true;

  if (TREE_CODE (val) == NOP_EXPR)
    val = (max
	   ? TYPE_MAX_VALUE (TREE_TYPE (TREE_OPERAND (val, 0)))
	   : TYPE_MIN_VALUE (TREE_TYPE (TREE_OPERAND (val, 0))));

  if (TREE_CODE (val) != INTEGER_CST)
    return true;

  if (max)
    return tree_int_cst_lt (val, min_or_max_val) == 0;
  else
    return tree_int_cst_lt (min_or_max_val, val) == 0;
}

/* Return true if VAL (of type TYPE) can equal the minimum value of TYPE.
   If REVERSE is true, minimum value is taken as maximum value.  */

static inline bool
can_equal_min_val_p (tree val, tree type, bool reverse)
{
  return can_equal_min_or_max_val_p (val, type, reverse);
}

/* Return true if VAL (of type TYPE) can equal the maximum value of TYPE.
   If REVERSE is true, maximum value is taken as minimum value.  */

static inline bool
can_equal_max_val_p (tree val, tree type, bool reverse)
{
  return can_equal_min_or_max_val_p (val, type, !reverse);
}

/* Replace EXPR1 and EXPR2 by invariant expressions if possible.  Return
   true if both expressions have been replaced and false otherwise.  */

static bool
make_invariant (tree *expr1, tree *expr2)
{
  tree inv_expr1 = gnat_invariant_expr (*expr1);
  tree inv_expr2 = gnat_invariant_expr (*expr2);

  if (inv_expr1)
    *expr1 = inv_expr1;

  if (inv_expr2)
    *expr2 = inv_expr2;

  return inv_expr1 && inv_expr2;
}

/* Helper function for walk_tree, used by independent_iterations_p below.  */

static tree
scan_rhs_r (tree *tp, int *walk_subtrees, void *data)
{
  bitmap *params = (bitmap *)data;
  tree t = *tp;

  /* No need to walk into types or decls.  */
  if (IS_TYPE_OR_DECL_P (t))
    *walk_subtrees = 0;

  if (TREE_CODE (t) == PARM_DECL && bitmap_bit_p (*params, DECL_UID (t)))
    return t;

  return NULL_TREE;
}

/* Return true if STMT_LIST generates independent iterations in a loop.  */

static bool
independent_iterations_p (tree stmt_list)
{
  tree_stmt_iterator tsi;
  bitmap params = BITMAP_GGC_ALLOC();
  auto_vec<tree, 16> rhs;
  tree iter;
  int i;

  if (TREE_CODE (stmt_list) == BIND_EXPR)
    stmt_list = BIND_EXPR_BODY (stmt_list);

  /* Scan the list and return false on anything that is not either a check
     or an assignment to a parameter with restricted aliasing.  */
  for (tsi = tsi_start (stmt_list); !tsi_end_p (tsi); tsi_next (&tsi))
    {
      tree stmt = tsi_stmt (tsi);

      switch (TREE_CODE (stmt))
	{
	case COND_EXPR:
	  {
	    if (COND_EXPR_ELSE (stmt))
	      return false;
	    if (TREE_CODE (COND_EXPR_THEN (stmt)) != CALL_EXPR)
	      return false;
	    tree func = get_callee_fndecl (COND_EXPR_THEN (stmt));
	    if (!(func && TREE_THIS_VOLATILE (func)))
	      return false;
	    break;
	  }

	case MODIFY_EXPR:
	  {
	    tree lhs = TREE_OPERAND (stmt, 0);
	    while (handled_component_p (lhs))
	      lhs = TREE_OPERAND (lhs, 0);
	    if (TREE_CODE (lhs) != INDIRECT_REF)
	      return false;
	    lhs = TREE_OPERAND (lhs, 0);
	    if (!(TREE_CODE (lhs) == PARM_DECL
		  && DECL_RESTRICTED_ALIASING_P (lhs)))
	      return false;
	    bitmap_set_bit (params, DECL_UID (lhs));
	    rhs.safe_push (TREE_OPERAND (stmt, 1));
	    break;
	  }

	default:
	  return false;
	}
    }

  /* At this point we know that the list contains only statements that will
     modify parameters with restricted aliasing.  Check that the statements
     don't at the time read from these parameters.  */
  FOR_EACH_VEC_ELT (rhs, i, iter)
    if (walk_tree_without_duplicates (&iter, scan_rhs_r, &params))
      return false;

  return true;
}

/* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Loop_Statement, to a
   GCC tree, which is returned.  */

static tree
Loop_Statement_to_gnu (Node_Id gnat_node)
{
  const Node_Id gnat_iter_scheme = Iteration_Scheme (gnat_node);
  struct loop_info_d *gnu_loop_info = ggc_cleared_alloc<loop_info_d> ();
  tree gnu_loop_stmt = build4 (LOOP_STMT, void_type_node, NULL_TREE,
			       NULL_TREE, NULL_TREE, NULL_TREE);
  tree gnu_loop_label = create_artificial_label (input_location);
  tree gnu_cond_expr = NULL_TREE, gnu_low = NULL_TREE, gnu_high = NULL_TREE;
  tree gnu_result;

  /* Push the loop_info structure associated with the LOOP_STMT.  */
  gnu_loop_info->fndecl = current_function_decl;
  gnu_loop_info->stmt = gnu_loop_stmt;
  vec_safe_push (gnu_loop_stack, gnu_loop_info);

  /* Set location information for statement and end label.  */
  set_expr_location_from_node (gnu_loop_stmt, gnat_node);
  Sloc_to_locus (Sloc (End_Label (gnat_node)),
		 &DECL_SOURCE_LOCATION (gnu_loop_label));
  LOOP_STMT_LABEL (gnu_loop_stmt) = gnu_loop_label;

  /* Set the condition under which the loop must keep going.  If we have an
     explicit condition, use it to set the location information throughout
     the translation of the loop statement to avoid having multiple SLOCs.

     For the case "LOOP .... END LOOP;" the condition is always true.  */
  if (No (gnat_iter_scheme))
    ;

  /* For the case "WHILE condition LOOP ..... END LOOP;" it's immediate.  */
  else if (Present (Condition (gnat_iter_scheme)))
    {
      LOOP_STMT_COND (gnu_loop_stmt)
	= gnat_to_gnu (Condition (gnat_iter_scheme));

      set_expr_location_from_node (gnu_loop_stmt, gnat_iter_scheme);
    }

  /* Otherwise we have an iteration scheme and the condition is given by the
     bounds of the subtype of the iteration variable.  */
  else
    {
      Node_Id gnat_loop_spec = Loop_Parameter_Specification (gnat_iter_scheme);
      Entity_Id gnat_loop_var = Defining_Entity (gnat_loop_spec);
      Entity_Id gnat_type = Etype (gnat_loop_var);
      tree gnu_type = get_unpadded_type (gnat_type);
      tree gnu_base_type = maybe_character_type (get_base_type (gnu_type));
      tree gnu_one_node = build_int_cst (gnu_base_type, 1);
      tree gnu_loop_var, gnu_loop_iv, gnu_first, gnu_last, gnu_stmt;
      enum tree_code update_code, test_code, shift_code;
      bool reverse = Reverse_Present (gnat_loop_spec), use_iv = false;

      gnu_low = convert (gnu_base_type, TYPE_MIN_VALUE (gnu_type));
      gnu_high = convert (gnu_base_type, TYPE_MAX_VALUE (gnu_type));

      /* We must disable modulo reduction for the iteration variable, if any,
	 in order for the loop comparison to be effective.  */
      if (reverse)
	{
	  gnu_first = gnu_high;
	  gnu_last = gnu_low;
	  update_code = MINUS_NOMOD_EXPR;
	  test_code = GE_EXPR;
	  shift_code = PLUS_NOMOD_EXPR;
	}
      else
	{
	  gnu_first = gnu_low;
	  gnu_last = gnu_high;
	  update_code = PLUS_NOMOD_EXPR;
	  test_code = LE_EXPR;
	  shift_code = MINUS_NOMOD_EXPR;
	}

      /* We use two different strategies to translate the loop, depending on
	 whether optimization is enabled, except for the very peculiar case
	 of a loop running over a boolean type where we use the simpler form
	 in order to avoid manipulating negative values in a boolean context.

	 If it is, we generate the canonical loop form expected by the loop
	 optimizer and the loop vectorizer, which is the do-while form:

	     ENTRY_COND
	   loop:
	     TOP_UPDATE
	     BODY
	     BOTTOM_COND
	     GOTO loop

	 This avoids an implicit dependency on loop header copying and makes
	 it possible to turn BOTTOM_COND into an inequality test.

	 If optimization is disabled, loop header copying doesn't come into
	 play and we try to generate the loop form with the fewer conditional
	 branches.  First, the default form, which is:

	   loop:
	     TOP_COND
	     BODY
	     BOTTOM_UPDATE
	     GOTO loop

	 It should catch most loops with constant ending point.  Then, if we
	 cannot, we try to generate the shifted form:

	   loop:
	     TOP_COND
	     TOP_UPDATE
	     BODY
	     GOTO loop

	 which should catch loops with constant starting point.  Otherwise, if
	 we cannot, we generate the fallback form:

	     ENTRY_COND
	   loop:
	     BODY
	     BOTTOM_COND
	     BOTTOM_UPDATE
	     GOTO loop

	 which works in all cases.  */

      if (optimize
	  && !optimize_debug
	  && TREE_CODE (gnu_base_type) != BOOLEAN_TYPE)
	{
	  /* We can use the do-while form directly if GNU_FIRST-1 doesn't
	     overflow.  */
	  if (!can_equal_min_val_p (gnu_first, gnu_base_type, reverse))
	    ;

	  /* Otherwise, use the do-while form with the help of a special
	     induction variable in the unsigned version of the base type
	     or the unsigned version of the size type, whichever is the
	     largest, in order to have wrap-around arithmetics for it.  */
	  else
	    {
	      if (TYPE_PRECISION (gnu_base_type)
		  > TYPE_PRECISION (size_type_node))
		gnu_base_type
		  = gnat_type_for_size (TYPE_PRECISION (gnu_base_type), 1);
	      else
		gnu_base_type = size_type_node;

	      gnu_first = convert (gnu_base_type, gnu_first);
	      gnu_last = convert (gnu_base_type, gnu_last);
	      gnu_one_node = build_int_cst (gnu_base_type, 1);
	      use_iv = true;
	    }

	  gnu_first
	    = build_binary_op (shift_code, gnu_base_type, gnu_first,
			       gnu_one_node);
	  LOOP_STMT_TOP_UPDATE_P (gnu_loop_stmt) = 1;
	  LOOP_STMT_BOTTOM_COND_P (gnu_loop_stmt) = 1;
	}
      else
	{
	  /* We can use the default form if GNU_LAST+1 doesn't overflow.  */
	  if (!can_equal_max_val_p (gnu_last, gnu_base_type, reverse))
	    ;

	  /* Otherwise, we can use the shifted form if neither GNU_FIRST-1 nor
	     GNU_LAST-1 does.  */
	  else if (!can_equal_min_val_p (gnu_first, gnu_base_type, reverse)
		   && !can_equal_min_val_p (gnu_last, gnu_base_type, reverse))
	    {
	      gnu_first
		= build_binary_op (shift_code, gnu_base_type, gnu_first,
				   gnu_one_node);
	      gnu_last
		= build_binary_op (shift_code, gnu_base_type, gnu_last,
				   gnu_one_node);
	      LOOP_STMT_TOP_UPDATE_P (gnu_loop_stmt) = 1;
	    }

	  /* Otherwise, use the fallback form.  */
	  else
	    LOOP_STMT_BOTTOM_COND_P (gnu_loop_stmt) = 1;
	}

      /* If we use the BOTTOM_COND, we can turn the test into an inequality
	 test but we have to add ENTRY_COND to protect the empty loop.  */
      if (LOOP_STMT_BOTTOM_COND_P (gnu_loop_stmt))
	{
	  test_code = NE_EXPR;
	  gnu_cond_expr
	    = build3 (COND_EXPR, void_type_node,
		      build_binary_op (LE_EXPR, boolean_type_node,
				       gnu_low, gnu_high),
		      NULL_TREE, alloc_stmt_list ());
	  set_expr_location_from_node (gnu_cond_expr, gnat_iter_scheme);
	}

      /* Open a new nesting level that will surround the loop to declare the
	 iteration variable.  */
      start_stmt_group ();
      gnat_pushlevel ();

      /* If we use the special induction variable, create it and set it to
	 its initial value.  Morever, the regular iteration variable cannot
	 itself be initialized, lest the initial value wrapped around.  */
      if (use_iv)
	{
	  gnu_loop_iv
	    = create_init_temporary ("I", gnu_first, &gnu_stmt, gnat_loop_var);
	  add_stmt (gnu_stmt);
	  gnu_first = NULL_TREE;
	}
      else
	gnu_loop_iv = NULL_TREE;

      /* Declare the iteration variable and set it to its initial value.  */
      gnu_loop_var = gnat_to_gnu_entity (gnat_loop_var, gnu_first, true);
      if (DECL_BY_REF_P (gnu_loop_var))
	gnu_loop_var = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_loop_var);
      else if (use_iv)
	{
	  gcc_assert (DECL_LOOP_PARM_P (gnu_loop_var));
	  SET_DECL_INDUCTION_VAR (gnu_loop_var, gnu_loop_iv);
	}
      gnu_loop_info->loop_var = gnu_loop_var;
      gnu_loop_info->low_bound = gnu_low;
      gnu_loop_info->high_bound = gnu_high;

      /* Do all the arithmetics in the base type.  */
      gnu_loop_var = convert (gnu_base_type, gnu_loop_var);

      /* Set either the top or bottom exit condition.  */
      if (use_iv)
        LOOP_STMT_COND (gnu_loop_stmt)
	  = build_binary_op (test_code, boolean_type_node, gnu_loop_iv,
			     gnu_last);
      else
        LOOP_STMT_COND (gnu_loop_stmt)
	  = build_binary_op (test_code, boolean_type_node, gnu_loop_var,
			     gnu_last);

      /* Set either the top or bottom update statement and give it the source
	 location of the iteration for better coverage info.  */
      if (use_iv)
	{
	  gnu_stmt
	    = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_loop_iv,
			       build_binary_op (update_code, gnu_base_type,
						gnu_loop_iv, gnu_one_node));
	  set_expr_location_from_node (gnu_stmt, gnat_iter_scheme);
	  append_to_statement_list (gnu_stmt,
				    &LOOP_STMT_UPDATE (gnu_loop_stmt));
	  gnu_stmt
	    = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_loop_var,
			       gnu_loop_iv);
	  set_expr_location_from_node (gnu_stmt, gnat_iter_scheme);
	  append_to_statement_list (gnu_stmt,
				    &LOOP_STMT_UPDATE (gnu_loop_stmt));
	}
      else
	{
	  gnu_stmt
	    = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_loop_var,
			       build_binary_op (update_code, gnu_base_type,
						gnu_loop_var, gnu_one_node));
	  set_expr_location_from_node (gnu_stmt, gnat_iter_scheme);
	  LOOP_STMT_UPDATE (gnu_loop_stmt) = gnu_stmt;
	}

      set_expr_location_from_node (gnu_loop_stmt, gnat_iter_scheme);
    }

  /* If the loop was named, have the name point to this loop.  In this case,
     the association is not a DECL node, but the end label of the loop.  */
  if (Present (Identifier (gnat_node)))
    save_gnu_tree (Entity (Identifier (gnat_node)), gnu_loop_label, true);

  /* Make the loop body into its own block, so any allocated storage will be
     released every iteration.  This is needed for stack allocation.  */
  LOOP_STMT_BODY (gnu_loop_stmt)
    = build_stmt_group (Statements (gnat_node), true);
  TREE_SIDE_EFFECTS (gnu_loop_stmt) = 1;

  /* If we have an iteration scheme, then we are in a statement group.  Add
     the LOOP_STMT to it, finish it and make it the "loop".  */
  if (Present (gnat_iter_scheme) && No (Condition (gnat_iter_scheme)))
    {
      /* First, if we have computed invariant conditions for range (or index)
	 checks applied to the iteration variable, find out whether they can
	 be evaluated to false at compile time; otherwise, if there are not
	 too many of them, combine them with the original checks.  If loop
	 unswitching is enabled, do not require the loop bounds to be also
	 invariant, as their evaluation will still be ahead of the loop.  */
      if (vec_safe_length (gnu_loop_info->checks) > 0
	 && (make_invariant (&gnu_low, &gnu_high) || optimize >= 3))
	{
	  struct range_check_info_d *rci;
	  unsigned int i, n_remaining_checks = 0;

	  FOR_EACH_VEC_ELT (*gnu_loop_info->checks, i, rci)
	    {
	      tree low_ok, high_ok;

	      if (rci->low_bound)
		{
		  tree gnu_adjusted_low = convert (rci->type, gnu_low);
		  if (rci->disp)
		    gnu_adjusted_low
		      = fold_build2 (rci->neg_p ? MINUS_EXPR : PLUS_EXPR,
				     rci->type, gnu_adjusted_low, rci->disp);
		  low_ok
		    = build_binary_op (GE_EXPR, boolean_type_node,
				       gnu_adjusted_low, rci->low_bound);
		}
	      else
		low_ok = boolean_true_node;

	      if (rci->high_bound)
		{
		  tree gnu_adjusted_high = convert (rci->type, gnu_high);
		  if (rci->disp)
		    gnu_adjusted_high
		      = fold_build2 (rci->neg_p ? MINUS_EXPR : PLUS_EXPR,
				     rci->type, gnu_adjusted_high, rci->disp);
		  high_ok
		    = build_binary_op (LE_EXPR, boolean_type_node,
				       gnu_adjusted_high, rci->high_bound);
		}
	      else
		high_ok = boolean_true_node;

	      tree range_ok
		= build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
				   low_ok, high_ok);

	      rci->invariant_cond
		= build_unary_op (TRUTH_NOT_EXPR, boolean_type_node, range_ok);

	      if (rci->invariant_cond == boolean_false_node)
		TREE_OPERAND (rci->inserted_cond, 0) = rci->invariant_cond;
	      else
		n_remaining_checks++;
	    }

	  /* Note that loop unswitching can only be applied a small number of
	     times to a given loop (PARAM_MAX_UNSWITCH_LEVEL default to 3).  */
	  if (IN_RANGE (n_remaining_checks, 1, 3)
	      && optimize >= 2
	      && !optimize_size)
	    FOR_EACH_VEC_ELT (*gnu_loop_info->checks, i, rci)
	      if (rci->invariant_cond != boolean_false_node)
		{
		  TREE_OPERAND (rci->inserted_cond, 0) = rci->invariant_cond;

		  if (optimize >= 3)
		    add_stmt_with_node_force (rci->inserted_cond, gnat_node);
		}
	}

      /* Second, if we have recorded invariants to be hoisted, emit them.  */
      if (vec_safe_length (gnu_loop_info->invariants) > 0)
	{
	  tree *iter;
	  unsigned int i;
	  FOR_EACH_VEC_ELT (*gnu_loop_info->invariants, i, iter)
	    add_stmt_with_node_force (*iter, gnat_node);
	}

      /* Third, if loop vectorization is enabled and the iterations of the
	 loop can easily be proved as independent, mark the loop.  */
      if (optimize >= 3
	  && independent_iterations_p (LOOP_STMT_BODY (gnu_loop_stmt)))
	LOOP_STMT_IVDEP (gnu_loop_stmt) = 1;

      add_stmt (gnu_loop_stmt);
      gnat_poplevel ();
      gnu_loop_stmt = end_stmt_group ();
    }

  /* If we have an outer COND_EXPR, that's our result and this loop is its
     "true" statement.  Otherwise, the result is the LOOP_STMT.  */
  if (gnu_cond_expr)
    {
      COND_EXPR_THEN (gnu_cond_expr) = gnu_loop_stmt;
      TREE_SIDE_EFFECTS (gnu_cond_expr) = 1;
      gnu_result = gnu_cond_expr;
    }
  else
    gnu_result = gnu_loop_stmt;

  gnu_loop_stack->pop ();

  return gnu_result;
}

/* This page implements a form of Named Return Value optimization modeled
   on the C++ optimization of the same name.  The main difference is that
   we disregard any semantical considerations when applying it here, the
   counterpart being that we don't try to apply it to semantically loaded
   return types, i.e. types with the TYPE_BY_REFERENCE_P flag set.

   We consider a function body of the following GENERIC form:

     return_type R1;
       [...]
     RETURN_EXPR [<retval> = ...]
       [...]
     RETURN_EXPR [<retval> = R1]
       [...]
     return_type Ri;
       [...]
     RETURN_EXPR [<retval> = ...]
       [...]
     RETURN_EXPR [<retval> = Ri]
       [...]

   where the Ri are not addressable and we try to fulfill a simple criterion
   that would make it possible to replace one or several Ri variables by the
   single RESULT_DECL of the function.

   The first observation is that RETURN_EXPRs that don't directly reference
   any of the Ri variables on the RHS of their assignment are transparent wrt
   the optimization.  This is because the Ri variables aren't addressable so
   any transformation applied to them doesn't affect the RHS; moreover, the
   assignment writes the full <retval> object so existing values are entirely
   discarded.

   This property can be extended to some forms of RETURN_EXPRs that reference
   the Ri variables, for example CONSTRUCTORs, but isn't true in the general
   case, in particular when function calls are involved.

   Therefore the algorithm is as follows:

     1. Collect the list of candidates for a Named Return Value (Ri variables
	on the RHS of assignments of RETURN_EXPRs) as well as the list of the
	other expressions on the RHS of such assignments.

     2. Prune the members of the first list (candidates) that are referenced
	by a member of the second list (expressions).

     3. Extract a set of candidates with non-overlapping live ranges from the
	first list.  These are the Named Return Values.

     4. Adjust the relevant RETURN_EXPRs and replace the occurrences of the
	Named Return Values in the function with the RESULT_DECL.

   If the function returns an unconstrained type, things are a bit different
   because the anonymous return object is allocated on the secondary stack
   and RESULT_DECL is only a pointer to it.  Each return object can be of a
   different size and is allocated separately so we need not care about the
   addressability and the aforementioned overlapping issues.  Therefore, we
   don't collect the other expressions and skip step #2 in the algorithm.  */

struct nrv_data
{
  bitmap nrv;
  tree result;
  Node_Id gnat_ret;
  hash_set<tree> *visited;
};

/* Return true if T is a Named Return Value.  */

static inline bool
is_nrv_p (bitmap nrv, tree t)
{
  return VAR_P (t) && bitmap_bit_p (nrv, DECL_UID (t));
}

/* Helper function for walk_tree, used by finalize_nrv below.  */

static tree
prune_nrv_r (tree *tp, int *walk_subtrees, void *data)
{
  struct nrv_data *dp = (struct nrv_data *)data;
  tree t = *tp;

  /* No need to walk into types or decls.  */
  if (IS_TYPE_OR_DECL_P (t))
    *walk_subtrees = 0;

  if (is_nrv_p (dp->nrv, t))
    bitmap_clear_bit (dp->nrv, DECL_UID (t));

  return NULL_TREE;
}

/* Prune Named Return Values in BLOCK and return true if there is still a
   Named Return Value in BLOCK or one of its sub-blocks.  */

static bool
prune_nrv_in_block (bitmap nrv, tree block)
{
  bool has_nrv = false;
  tree t;

  /* First recurse on the sub-blocks.  */
  for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t))
    has_nrv |= prune_nrv_in_block (nrv, t);

  /* Then make sure to keep at most one NRV per block.  */
  for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
    if (is_nrv_p (nrv, t))
      {
	if (has_nrv)
	  bitmap_clear_bit (nrv, DECL_UID (t));
	else
	  has_nrv = true;
      }

  return has_nrv;
}

/* Helper function for walk_tree, used by finalize_nrv below.  */

static tree
finalize_nrv_r (tree *tp, int *walk_subtrees, void *data)
{
  struct nrv_data *dp = (struct nrv_data *)data;
  tree t = *tp;

  /* No need to walk into types.  */
  if (TYPE_P (t))
    *walk_subtrees = 0;

  /* Change RETURN_EXPRs of NRVs to just refer to the RESULT_DECL; this is a
     nop, but differs from using NULL_TREE in that it indicates that we care
     about the value of the RESULT_DECL.  */
  else if (TREE_CODE (t) == RETURN_EXPR
	   && TREE_CODE (TREE_OPERAND (t, 0)) == INIT_EXPR)
    {
      tree ret_val = TREE_OPERAND (TREE_OPERAND (t, 0), 1);

      /* Strip useless conversions around the return value.  */
      if (gnat_useless_type_conversion (ret_val))
	ret_val = TREE_OPERAND (ret_val, 0);

      if (is_nrv_p (dp->nrv, ret_val))
	TREE_OPERAND (t, 0) = dp->result;
    }

  /* Replace the DECL_EXPR of NRVs with an initialization of the RESULT_DECL,
     if needed.  */
  else if (TREE_CODE (t) == DECL_EXPR
	   && is_nrv_p (dp->nrv, DECL_EXPR_DECL (t)))
    {
      tree var = DECL_EXPR_DECL (t), init;

      if (DECL_INITIAL (var))
	{
	  init = build_binary_op (INIT_EXPR, NULL_TREE, dp->result,
				  DECL_INITIAL (var));
	  SET_EXPR_LOCATION (init, EXPR_LOCATION (t));
	  DECL_INITIAL (var) = NULL_TREE;
	}
      else
	init = build_empty_stmt (EXPR_LOCATION (t));
      *tp = init;

      /* Identify the NRV to the RESULT_DECL for debugging purposes.  */
      SET_DECL_VALUE_EXPR (var, dp->result);
      DECL_HAS_VALUE_EXPR_P (var) = 1;
      /* ??? Kludge to avoid an assertion failure during inlining.  */
      DECL_SIZE (var) = bitsize_unit_node;
      DECL_SIZE_UNIT (var) = size_one_node;
    }

  /* And replace all uses of NRVs with the RESULT_DECL.  */
  else if (is_nrv_p (dp->nrv, t))
    *tp = convert (TREE_TYPE (t), dp->result);

  /* Avoid walking into the same tree more than once.  Unfortunately, we
     can't just use walk_tree_without_duplicates because it would only
     call us for the first occurrence of NRVs in the function body.  */
  if (dp->visited->add (*tp))
    *walk_subtrees = 0;

  return NULL_TREE;
}

/* Likewise, but used when the function returns an unconstrained type.  */

static tree
finalize_nrv_unc_r (tree *tp, int *walk_subtrees, void *data)
{
  struct nrv_data *dp = (struct nrv_data *)data;
  tree t = *tp;

  /* No need to walk into types.  */
  if (TYPE_P (t))
    *walk_subtrees = 0;

  /* We need to see the DECL_EXPR of NRVs before any other references so we
     walk the body of BIND_EXPR before walking its variables.  */
  else if (TREE_CODE (t) == BIND_EXPR)
    walk_tree (&BIND_EXPR_BODY (t), finalize_nrv_unc_r, data, NULL);

  /* Change RETURN_EXPRs of NRVs to assign to the RESULT_DECL only the final
     return value built by the allocator instead of the whole construct.  */
  else if (TREE_CODE (t) == RETURN_EXPR
	   && TREE_CODE (TREE_OPERAND (t, 0)) == INIT_EXPR)
    {
      tree ret_val = TREE_OPERAND (TREE_OPERAND (t, 0), 1);

      /* This is the construct returned by the allocator.  */
      if (TREE_CODE (ret_val) == COMPOUND_EXPR
	  && TREE_CODE (TREE_OPERAND (ret_val, 0)) == INIT_EXPR)
	{
	  tree rhs = TREE_OPERAND (TREE_OPERAND (ret_val, 0), 1);

	  if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (ret_val)))
	    ret_val = CONSTRUCTOR_ELT (rhs, 1)->value;
	  else
	    ret_val = rhs;
	}

      /* Strip useless conversions around the return value.  */
      if (gnat_useless_type_conversion (ret_val)
	  || TREE_CODE (ret_val) == VIEW_CONVERT_EXPR)
	ret_val = TREE_OPERAND (ret_val, 0);

      /* Strip unpadding around the return value.  */
      if (TREE_CODE (ret_val) == COMPONENT_REF
	  && TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (ret_val, 0))))
	ret_val = TREE_OPERAND (ret_val, 0);

      /* Assign the new return value to the RESULT_DECL.  */
      if (is_nrv_p (dp->nrv, ret_val))
	TREE_OPERAND (TREE_OPERAND (t, 0), 1)
	  = TREE_OPERAND (DECL_INITIAL (ret_val), 0);
    }

  /* Adjust the DECL_EXPR of NRVs to call the allocator and save the result
     into a new variable.  */
  else if (TREE_CODE (t) == DECL_EXPR
	   && is_nrv_p (dp->nrv, DECL_EXPR_DECL (t)))
    {
      tree saved_current_function_decl = current_function_decl;
      tree var = DECL_EXPR_DECL (t);
      tree alloc, p_array, new_var, new_ret;
      vec<constructor_elt, va_gc> *v;
      vec_alloc (v, 2);

      /* Create an artificial context to build the allocation.  */
      current_function_decl = decl_function_context (var);
      start_stmt_group ();
      gnat_pushlevel ();

      /* This will return a COMPOUND_EXPR with the allocation in the first
	 arm and the final return value in the second arm.  */
      alloc = build_allocator (TREE_TYPE (var), DECL_INITIAL (var),
			       TREE_TYPE (dp->result),
			       Procedure_To_Call (dp->gnat_ret),
			       Storage_Pool (dp->gnat_ret),
			       Empty, false);

      /* The new variable is built as a reference to the allocated space.  */
      new_var
	= build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, DECL_NAME (var),
		      build_reference_type (TREE_TYPE (var)));
      DECL_BY_REFERENCE (new_var) = 1;

      if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (alloc)))
	{
	  tree cst = TREE_OPERAND (alloc, 1);

	  /* The new initial value is a COMPOUND_EXPR with the allocation in
	     the first arm and the value of P_ARRAY in the second arm.  */
	  DECL_INITIAL (new_var)
	    = build2 (COMPOUND_EXPR, TREE_TYPE (new_var),
		      TREE_OPERAND (alloc, 0),
		      CONSTRUCTOR_ELT (cst, 0)->value);

	  /* Build a modified CONSTRUCTOR that references NEW_VAR.  */
	  p_array = TYPE_FIELDS (TREE_TYPE (alloc));
	  CONSTRUCTOR_APPEND_ELT (v, p_array,
				  fold_convert (TREE_TYPE (p_array), new_var));
	  CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (p_array),
				  CONSTRUCTOR_ELT (cst, 1)->value);
	  new_ret = build_constructor (TREE_TYPE (alloc), v);
	}
      else
	{
	  /* The new initial value is just the allocation.  */
	  DECL_INITIAL (new_var) = alloc;
	  new_ret = fold_convert (TREE_TYPE (alloc), new_var);
	}

      gnat_pushdecl (new_var, Empty);

      /* Destroy the artificial context and insert the new statements.  */
      gnat_zaplevel ();
      *tp = end_stmt_group ();
      current_function_decl = saved_current_function_decl;

      /* Chain NEW_VAR immediately after VAR and ignore the latter.  */
      DECL_CHAIN (new_var) = DECL_CHAIN (var);
      DECL_CHAIN (var) = new_var;
      DECL_IGNORED_P (var) = 1;

      /* Save the new return value and the dereference of NEW_VAR.  */
      DECL_INITIAL (var)
	= build2 (COMPOUND_EXPR, TREE_TYPE (var), new_ret,
		  build1 (INDIRECT_REF, TREE_TYPE (var), new_var));
      /* ??? Kludge to avoid messing up during inlining.  */
      DECL_CONTEXT (var) = NULL_TREE;
    }

  /* And replace all uses of NRVs with the dereference of NEW_VAR.  */
  else if (is_nrv_p (dp->nrv, t))
    *tp = TREE_OPERAND (DECL_INITIAL (t), 1);

  /* Avoid walking into the same tree more than once.  Unfortunately, we
     can't just use walk_tree_without_duplicates because it would only
     call us for the first occurrence of NRVs in the function body.  */
  if (dp->visited->add (*tp))
    *walk_subtrees = 0;

  return NULL_TREE;
}

/* Apply FUNC to all the sub-trees of nested functions in NODE.  FUNC is called
   with the DATA and the address of each sub-tree.  If FUNC returns a non-NULL
   value, the traversal is stopped.  */

static void
walk_nesting_tree (struct cgraph_node *node, walk_tree_fn func, void *data)
{
  for (node = first_nested_function (node);
       node; node = next_nested_function (node))
    {
      walk_tree_without_duplicates (&DECL_SAVED_TREE (node->decl), func, data);
      walk_nesting_tree (node, func, data);
    }
}

/* Finalize the Named Return Value optimization for FNDECL.  The NRV bitmap
   contains the candidates for Named Return Value and OTHER is a list of
   the other return values.  GNAT_RET is a representative return node.  */

static void
finalize_nrv (tree fndecl, bitmap nrv, vec<tree, va_gc> *other, Node_Id gnat_ret)
{
  struct nrv_data data;
  walk_tree_fn func;
  unsigned int i;
  tree iter;

  /* We shouldn't be applying the optimization to return types that we aren't
     allowed to manipulate freely.  */
  gcc_assert (!TYPE_IS_BY_REFERENCE_P (TREE_TYPE (TREE_TYPE (fndecl))));

  /* Prune the candidates that are referenced by other return values.  */
  data.nrv = nrv;
  data.result = NULL_TREE;
  data.gnat_ret = Empty;
  data.visited = NULL;
  FOR_EACH_VEC_SAFE_ELT (other, i, iter)
    walk_tree_without_duplicates (&iter, prune_nrv_r, &data);
  if (bitmap_empty_p (nrv))
    return;

  /* Prune also the candidates that are referenced by nested functions.  */
  walk_nesting_tree (cgraph_node::get_create (fndecl), prune_nrv_r, &data);
  if (bitmap_empty_p (nrv))
    return;

  /* Extract a set of NRVs with non-overlapping live ranges.  */
  if (!prune_nrv_in_block (nrv, DECL_INITIAL (fndecl)))
    return;

  /* Adjust the relevant RETURN_EXPRs and replace the occurrences of NRVs.  */
  data.nrv = nrv;
  data.result = DECL_RESULT (fndecl);
  data.gnat_ret = gnat_ret;
  data.visited = new hash_set<tree>;
  if (TYPE_RETURN_BY_DIRECT_REF_P (TREE_TYPE (fndecl)))
    func = finalize_nrv_unc_r;
  else
    func = finalize_nrv_r;
  walk_tree (&DECL_SAVED_TREE (fndecl), func, &data, NULL);
  delete data.visited;
}

/* Return true if RET_VAL can be used as a Named Return Value for the
   anonymous return object RET_OBJ.  */

static bool
return_value_ok_for_nrv_p (tree ret_obj, tree ret_val)
{
  if (TREE_CODE (ret_val) != VAR_DECL)
    return false;

  if (TREE_THIS_VOLATILE (ret_val))
    return false;

  if (DECL_CONTEXT (ret_val) != current_function_decl)
    return false;

  if (TREE_STATIC (ret_val))
    return false;

  /* For the constrained case, test for addressability.  */
  if (ret_obj && TREE_ADDRESSABLE (ret_val))
    return false;

  /* For the constrained case, test for overalignment.  */
  if (ret_obj && DECL_ALIGN (ret_val) > DECL_ALIGN (ret_obj))
    return false;

  /* For the unconstrained case, test for bogus initialization.  */
  if (!ret_obj
      && DECL_INITIAL (ret_val)
      && TREE_CODE (DECL_INITIAL (ret_val)) == NULL_EXPR)
    return false;

  return true;
}

/* Build a RETURN_EXPR.  If RET_VAL is non-null, build a RETURN_EXPR around
   the assignment of RET_VAL to RET_OBJ.  Otherwise build a bare RETURN_EXPR
   around RESULT_OBJ, which may be null in this case.  */

static tree
build_return_expr (tree ret_obj, tree ret_val)
{
  tree result_expr;

  if (ret_val)
    {
      /* The gimplifier explicitly enforces the following invariant:

	      RETURN_EXPR
		  |
	       INIT_EXPR
	      /        \
	     /          \
	 RET_OBJ        ...

	 As a consequence, type consistency dictates that we use the type
	 of the RET_OBJ as the operation type.  */
      tree operation_type = TREE_TYPE (ret_obj);

      /* Convert the right operand to the operation type.  Note that this is
	 the transformation applied in the INIT_EXPR case of build_binary_op,
	 with the assumption that the type cannot involve a placeholder.  */
      if (operation_type != TREE_TYPE (ret_val))
	ret_val = convert (operation_type, ret_val);

      /* We always can use an INIT_EXPR for the return object.  */
      result_expr = build2 (INIT_EXPR, void_type_node, ret_obj, ret_val);

      /* If the function returns an aggregate type, find out whether this is
	 a candidate for Named Return Value.  If so, record it.  Otherwise,
	 if this is an expression of some kind, record it elsewhere.  */
      if (optimize
	  && !optimize_debug
	  && AGGREGATE_TYPE_P (operation_type)
	  && !TYPE_IS_FAT_POINTER_P (operation_type)
	  && TYPE_MODE (operation_type) == BLKmode
	  && aggregate_value_p (operation_type, current_function_decl))
	{
	  /* Strip useless conversions around the return value.  */
	  if (gnat_useless_type_conversion (ret_val))
	    ret_val = TREE_OPERAND (ret_val, 0);

	  /* Now apply the test to the return value.  */
	  if (return_value_ok_for_nrv_p (ret_obj, ret_val))
	    {
	      if (!f_named_ret_val)
		f_named_ret_val = BITMAP_GGC_ALLOC ();
	      bitmap_set_bit (f_named_ret_val, DECL_UID (ret_val));
	    }

	  /* Note that we need not care about CONSTRUCTORs here, as they are
	     totally transparent given the read-compose-write semantics of
	     assignments from CONSTRUCTORs.  */
	  else if (EXPR_P (ret_val))
	    vec_safe_push (f_other_ret_val, ret_val);
	}
    }
  else
    result_expr = ret_obj;

  return build1 (RETURN_EXPR, void_type_node, result_expr);
}

/* Subroutine of gnat_to_gnu to translate the At_End_Proc of GNAT_NODE, an
   N_Block_Statement or N_Handled_Sequence_Of_Statements or N_*_Body node.

   To invoked the GCC mechanism, we call add_cleanup and when we leave the
   group, end_stmt_group will create the TRY_FINALLY_EXPR construct.  */

static void
At_End_Proc_to_gnu (Node_Id gnat_node)
{
  tree proc_decl = gnat_to_gnu (At_End_Proc (gnat_node));
  Node_Id gnat_end_label;

  /* When not optimizing, disable inlining of finalizers as this can
     create a more complex CFG in the parent function.  */
  if (!optimize || optimize_debug)
    DECL_DECLARED_INLINE_P (proc_decl) = 0;

  /* Retrieve the end label attached to the node, if any.  */
  if (Nkind (gnat_node) == N_Handled_Sequence_Of_Statements)
    gnat_end_label = End_Label (gnat_node);
  else if (Present (Handled_Statement_Sequence (gnat_node)))
    gnat_end_label = End_Label (Handled_Statement_Sequence (gnat_node));
  else
    gnat_end_label = Empty;

  /* If there is no end label attached, we use the location of the At_End
     procedure because Expand_Cleanup_Actions might reset the location of
     the enclosing construct to that of an inner statement.  */
  add_cleanup (build_call_n_expr (proc_decl, 0),
	       Present (gnat_end_label)
	       ? gnat_end_label : At_End_Proc (gnat_node));
}

/* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Subprogram_Body.  */

static void
Subprogram_Body_to_gnu (Node_Id gnat_node)
{
  /* The defining identifier for the subprogram body. Note that if a
     specification has appeared before for this body, then the identifier
     occurring in that specification will also be a defining identifier
     and calls to this subprogram will point to that specification.  */
  Entity_Id gnat_subprog
    = (Present (Corresponding_Spec (gnat_node))
       ? Corresponding_Spec (gnat_node) : Defining_Entity (gnat_node));
  /* The FUNCTION_DECL node corresponding to the defining identifier.  */
  tree gnu_subprog;
  /* Its RESULT_DECL node.  */
  tree gnu_result_decl;
  /* Its FUNCTION_TYPE node.  */
  tree gnu_subprog_type;
  /* The TYPE_CI_CO_LIST of its FUNCTION_TYPE node, if any.  */
  tree gnu_cico_list;
  /* The entry in the CI_CO_LIST that represents a function return, if any.  */
  tree gnu_return_var_elmt;
  /* Its source location.  */
  location_t locus;

  /* If this is a generic subprogram or it has been eliminated, ignore it.  */
  if (Is_Generic_Subprogram (gnat_subprog) || Is_Eliminated (gnat_subprog))
    return;

  /* Likewise if this is a protected subprogram and we are only annotating
     types, as the required expansion of references did not take place.  */
  if (Convention (gnat_subprog) == Convention_Protected
      && type_annotate_only)
    return;

  /* If this subprogram acts as its own spec, define it.  Otherwise, just get
     the already-elaborated tree node.  However, if this subprogram had its
     elaboration deferred, we will already have made a tree node for it.  So
     treat it as not being defined in that case.  Such a subprogram cannot
     have an address clause or a freeze node, so this test is safe, though it
     does disable some otherwise-useful error checking.  */
  gnu_subprog
    = gnat_to_gnu_entity (gnat_subprog, NULL_TREE,
			  Acts_As_Spec (gnat_node)
			  && !present_gnu_tree (gnat_subprog));
  DECL_FUNCTION_IS_DEF (gnu_subprog) = true;
  gnu_result_decl = DECL_RESULT (gnu_subprog);
  gnu_subprog_type = TREE_TYPE (gnu_subprog);
  gnu_cico_list = TYPE_CI_CO_LIST (gnu_subprog_type);
  if (gnu_cico_list && TREE_VALUE (gnu_cico_list) == void_type_node)
    gnu_return_var_elmt = gnu_cico_list;
  else
    gnu_return_var_elmt = NULL_TREE;

  /* If the function returns by invisible reference, make it explicit in the
     function body, but beware that maybe_make_gnu_thunk may already have done
     it if the function is inlined across units.  See gnat_to_gnu_subprog_type
     for more details.  */
  if (TREE_ADDRESSABLE (gnu_subprog_type)
      && TREE_CODE (TREE_TYPE (gnu_result_decl)) != REFERENCE_TYPE)
    {
      TREE_TYPE (gnu_result_decl)
	= build_reference_type (TREE_TYPE (gnu_result_decl));
      relayout_decl (gnu_result_decl);
    }

  /* Set the line number in the decl to correspond to that of the body.  */
  if (DECL_IGNORED_P (gnu_subprog))
    locus = UNKNOWN_LOCATION;
  else if (!Sloc_to_locus (Sloc (gnat_node), &locus, false, gnu_subprog))
    locus = input_location;
  DECL_SOURCE_LOCATION (gnu_subprog) = locus;

  /* Try to create a bona-fide thunk and hand it over to the middle-end.  */
  if (Is_Thunk (gnat_subprog)
      && !Is_Secondary_Stack_Thunk (gnat_subprog)
      && maybe_make_gnu_thunk (gnat_subprog, gnu_subprog))
    return;

  /* Initialize the information structure for the function.  */
  allocate_struct_function (gnu_subprog, false);
  language_function *gnu_subprog_lang = ggc_cleared_alloc<language_function> ();
  DECL_STRUCT_FUNCTION (gnu_subprog)->language = gnu_subprog_lang;
  DECL_STRUCT_FUNCTION (gnu_subprog)->function_start_locus = locus;
  set_cfun (NULL);

  begin_subprog_body (gnu_subprog);

  /* If there are copy-in/copy-out parameters, we need to ensure that they are
     properly copied out by the return statement.  We do this by making a new
     block and converting any return into a goto to a label at the end of the
     block.  */
  if (gnu_cico_list)
    {
      tree gnu_return_var;

      vec_safe_push (gnu_return_label_stack,
		     create_artificial_label (input_location));

      start_stmt_group ();
      gnat_pushlevel ();

      /* If this is a function with copy-in/copy-out parameters and which does
	 not return by invisible reference, we also need a variable for the
	 return value to be placed.  */
      if (gnu_return_var_elmt && !TREE_ADDRESSABLE (gnu_subprog_type))
	{
	  tree gnu_return_type
	    = TREE_TYPE (TREE_PURPOSE (gnu_return_var_elmt));

	  gnu_return_var
	    = create_var_decl (get_identifier ("RETVAL"), NULL_TREE,
			       gnu_return_type, NULL_TREE,
			       false, false, false, false, false, false,
			       true, false, NULL, gnat_subprog);
	  TREE_VALUE (gnu_return_var_elmt) = gnu_return_var;
	}
      else
	gnu_return_var = NULL_TREE;

      vec_safe_push (gnu_return_var_stack, gnu_return_var);

      /* See whether there are parameters for which we don't have a GCC tree
	 yet.  These must be Out parameters.  Make a VAR_DECL for them and
	 put it into TYPE_CI_CO_LIST, which must contain an empty entry too.
	 We can match up the entries because TYPE_CI_CO_LIST is in the order
	 of the parameters.  */
      for (Entity_Id gnat_param = First_Formal_With_Extras (gnat_subprog);
	   Present (gnat_param);
	   gnat_param = Next_Formal_With_Extras (gnat_param))
	if (!present_gnu_tree (gnat_param))
	  {
	    tree gnu_cico_entry = gnu_cico_list;
	    tree gnu_decl;

	    /* Skip any entries that have been already filled in; they must
	       correspond to In Out parameters or previous Out parameters.  */
	    while (gnu_cico_entry && TREE_VALUE (gnu_cico_entry))
	      gnu_cico_entry = TREE_CHAIN (gnu_cico_entry);

	    /* Do any needed dereferences for by-ref objects.  */
	    gnu_decl = gnat_to_gnu_entity (gnat_param, NULL_TREE, true);
	    gcc_assert (DECL_P (gnu_decl));
	    if (DECL_BY_REF_P (gnu_decl))
	      gnu_decl = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_decl);

	    TREE_VALUE (gnu_cico_entry) = gnu_decl;
	  }

      /* Finally, ensure type consistency between TREE_PURPOSE and TREE_VALUE
	 so that the assignment of the latter to the former can be done.  */
      tree gnu_cico_entry = gnu_cico_list;
      while (gnu_cico_entry)
	{
	  if (!VOID_TYPE_P (TREE_VALUE (gnu_cico_entry)))
	    TREE_VALUE (gnu_cico_entry)
	      = convert (TREE_TYPE (TREE_PURPOSE (gnu_cico_entry)),
			 TREE_VALUE (gnu_cico_entry));
	  gnu_cico_entry = TREE_CHAIN (gnu_cico_entry);
	}
    }

  else
    vec_safe_push (gnu_return_label_stack, NULL_TREE);

  /* Get a tree corresponding to the code for the subprogram.  */
  start_stmt_group ();
  gnat_pushlevel ();

  /* First translate the declarations of the subprogram.  */
  process_decls (Declarations (gnat_node), Empty, true, true);

  /* Then generate the code of the subprogram itself.  A return statement will
     be present and any Out parameters will be handled there.  */
  add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node)));

  /* Process the At_End_Proc, if any.  */
  if (Present (At_End_Proc (gnat_node)))
    At_End_Proc_to_gnu (gnat_node);

  gnat_poplevel ();
  tree gnu_result = end_stmt_group ();

  /* Attempt setting the end_locus of our GCC body tree, typically a BIND_EXPR,
     then the end_locus of our GCC subprogram declaration tree.  */
  set_end_locus_from_node (gnu_result, gnat_node);
  set_end_locus_from_node (gnu_subprog, gnat_node);

  /* If we populated the parameter attributes cache, we need to make sure that
     the cached expressions are evaluated on all the possible paths leading to
     their uses.  So we force their evaluation on entry of the function.  */
  vec<parm_attr, va_gc> *cache = gnu_subprog_lang->parm_attr_cache;
  if (cache)
    {
      struct parm_attr_d *pa;
      int i;

      start_stmt_group ();

      FOR_EACH_VEC_ELT (*cache, i, pa)
	{
	  if (pa->first)
	    add_stmt_with_node_force (pa->first, gnat_node);
	  if (pa->last)
	    add_stmt_with_node_force (pa->last, gnat_node);
	  if (pa->length)
	    add_stmt_with_node_force (pa->length, gnat_node);
	}

      add_stmt (gnu_result);
      gnu_result = end_stmt_group ();

      gnu_subprog_lang->parm_attr_cache = NULL;
    }

  /* If we are dealing with a return from an Ada procedure with parameters
     passed by copy-in/copy-out, we need to return a record containing the
     final values of these parameters.  If the list contains only one entry,
     return just that entry though.

     For a full description of the copy-in/copy-out parameter mechanism, see
     the part of the gnat_to_gnu_entity routine dealing with the translation
     of subprograms.

     We need to make a block that contains the definition of that label and
     the copying of the return value.  It first contains the function, then
     the label and copy statement.  */
  if (gnu_cico_list)
    {
      const Node_Id gnat_end_label
	= End_Label (Handled_Statement_Sequence (gnat_node));

      gnu_return_var_stack->pop ();

      add_stmt (gnu_result);
      add_stmt (build1 (LABEL_EXPR, void_type_node,
			gnu_return_label_stack->last ()));

      /* If this is a function which returns by invisible reference, the
	 return value has already been dealt with at the return statements,
	 so we only need to indirectly copy out the parameters.  */
      if (TREE_ADDRESSABLE (gnu_subprog_type))
	{
	  tree gnu_ret_deref
	    = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result_decl);
	  tree t;

	  gcc_assert (TREE_VALUE (gnu_cico_list) == void_type_node);

	  for (t = TREE_CHAIN (gnu_cico_list); t; t = TREE_CHAIN (t))
	    {
	      tree gnu_field_deref
		= build_component_ref (gnu_ret_deref, TREE_PURPOSE (t), true);
	      gnu_result = build2 (MODIFY_EXPR, void_type_node,
				   gnu_field_deref, TREE_VALUE (t));
	      add_stmt_with_node (gnu_result, gnat_end_label);
	    }
	}

      /* Otherwise, if this is a procedure or a function that does not return
	 by invisible reference, we can do a direct block-copy out, but we do
	 not need to do it for a null initialization procedure when the _Init
	 parameter is not passed in since we would copy uninitialized bits.  */
      else if (!(Is_Null_Init_Proc (gnat_subprog)
		 && list_length (gnu_cico_list) == 1
		 && TREE_CODE (TREE_VALUE (gnu_cico_list)) == VAR_DECL))
	{
	  tree gnu_retval;

	  if (list_length (gnu_cico_list) == 1)
	    gnu_retval = TREE_VALUE (gnu_cico_list);
	  else
	    gnu_retval
	      = build_constructor_from_list (TREE_TYPE (gnu_subprog_type),
					     gnu_cico_list);

	  gnu_result = build_return_expr (gnu_result_decl, gnu_retval);
	  add_stmt_with_node (gnu_result, gnat_end_label);
	}

      gnat_poplevel ();
      gnu_result = end_stmt_group ();
    }

  gnu_return_label_stack->pop ();

  /* On SEH targets, install an exception handler around the main entry
     point to catch unhandled exceptions.  */
  if (DECL_NAME (gnu_subprog) == main_identifier_node
      && targetm_common.except_unwind_info (&global_options) == UI_SEH)
    {
      tree t;
      tree etype;

      t = build_call_expr (builtin_decl_explicit (BUILT_IN_EH_POINTER),
			   1, integer_zero_node);
      t = build_call_n_expr (unhandled_except_decl, 1, t);

      etype = build_unary_op (ADDR_EXPR, NULL_TREE, unhandled_others_decl);
      etype = tree_cons (NULL_TREE, etype, NULL_TREE);

      t = build2 (CATCH_EXPR, void_type_node, etype, t);
      gnu_result = build2 (TRY_CATCH_EXPR, TREE_TYPE (gnu_result),
			   gnu_result, t);
    }

  end_subprog_body (gnu_result);

  /* Finally annotate the parameters and disconnect the trees for parameters
     that we have turned into variables since they are now unusable.  */
  for (Entity_Id gnat_param = First_Formal_With_Extras (gnat_subprog);
       Present (gnat_param);
       gnat_param = Next_Formal_With_Extras (gnat_param))
    {
      tree gnu_param = get_gnu_tree (gnat_param);
      bool is_var_decl = VAR_P (gnu_param);

      annotate_object (gnat_param, TREE_TYPE (gnu_param), NULL_TREE,
		       DECL_BY_REF_P (gnu_param));

      if (is_var_decl)
	save_gnu_tree (gnat_param, NULL_TREE, false);
    }

  /* Disconnect the variable created for the return value.  */
  if (gnu_return_var_elmt)
    TREE_VALUE (gnu_return_var_elmt) = void_type_node;

  /* If the function returns an aggregate type and we have candidates for
     a Named Return Value, finalize the optimization.  */
  if (optimize && !optimize_debug && gnu_subprog_lang->named_ret_val)
    {
      finalize_nrv (gnu_subprog,
		    gnu_subprog_lang->named_ret_val,
		    gnu_subprog_lang->other_ret_val,
		    gnu_subprog_lang->gnat_ret);
      gnu_subprog_lang->named_ret_val = NULL;
      gnu_subprog_lang->other_ret_val = NULL;
    }

  /* If this is an inlined external function that has been marked uninlinable,
     drop the body and stop there.  Otherwise compile the body.  */
  if (DECL_EXTERNAL (gnu_subprog) && DECL_UNINLINABLE (gnu_subprog))
    DECL_SAVED_TREE (gnu_subprog) = NULL_TREE;
  else
    rest_of_subprog_body_compilation (gnu_subprog);
}

/* The type of an atomic access.  */

typedef enum { NOT_ATOMIC, SIMPLE_ATOMIC, OUTER_ATOMIC } atomic_acces_t;

/* Return true if GNAT_NODE references an Atomic entity.  This is modeled on
   the Is_Atomic_Object predicate of the front-end, but additionally handles
   explicit dereferences.  */

static bool
node_is_atomic (Node_Id gnat_node)
{
  Entity_Id gnat_entity;

  switch (Nkind (gnat_node))
    {
    case N_Identifier:
    case N_Expanded_Name:
      gnat_entity = Entity (gnat_node);
      if (!Is_Object (gnat_entity))
	break;
      return Is_Atomic (gnat_entity)
	     /* Disregard the flag on unconstrained arrays or simple constants
		since we cannot or need not generate an atomic access.  */
	     || (Is_Atomic (Etype (gnat_entity))
		 && Ekind (Etype (gnat_entity)) != E_Array_Type
		 && !simple_constant_p (gnat_entity));

    case N_Selected_Component:
      return Is_Atomic (Etype (gnat_node))
	     || Is_Atomic (Entity (Selector_Name (gnat_node)));

    case N_Indexed_Component:
      return Is_Atomic (Etype (gnat_node))
	     || Has_Atomic_Components (Etype (Prefix (gnat_node)))
	     || (Is_Entity_Name (Prefix (gnat_node))
		 && Has_Atomic_Components (Entity (Prefix (gnat_node))));

    case N_Explicit_Dereference:
      return Is_Atomic (Etype (gnat_node));

    default:
      break;
    }

  return false;
}

/* Return true if GNAT_NODE references a Volatile_Full_Access entity.  This is
   modeled on the Is_Volatile_Full_Access_Object predicate of the front-end,
   but additionally handles explicit dereferences.  */

static bool
node_is_volatile_full_access (Node_Id gnat_node)
{
  Entity_Id gnat_entity;

  switch (Nkind (gnat_node))
    {
    case N_Identifier:
    case N_Expanded_Name:
      gnat_entity = Entity (gnat_node);
      if (!Is_Object (gnat_entity))
	break;
      return Is_Volatile_Full_Access (gnat_entity)
	     /* Disregard the flag on unconstrained arrays or simple constants
		since we cannot or need not generate a full access.  */
	     || (Is_Volatile_Full_Access (Etype (gnat_entity))
		 && Ekind (Etype (gnat_entity)) != E_Array_Type
		 && !simple_constant_p (gnat_entity));

    case N_Selected_Component:
      return Is_Volatile_Full_Access (Etype (gnat_node))
	     || Is_Volatile_Full_Access (Entity (Selector_Name (gnat_node)));

    case N_Indexed_Component:
    case N_Explicit_Dereference:
      return Is_Volatile_Full_Access (Etype (gnat_node));

    default:
      break;
    }

  return false;
}

/* Return true if GNAT_NODE references a component of a larger object.  */

static inline bool
node_is_component (Node_Id gnat_node)
{
  const Node_Kind k = Nkind (gnat_node);
  return k == N_Indexed_Component || k == N_Selected_Component || k == N_Slice;
}

/* Return true if GNAT_NODE is a type conversion.  */

static inline bool
node_is_type_conversion (Node_Id gnat_node)
{
  const Node_Kind k = Nkind (gnat_node);
  return k == N_Type_Conversion || k == N_Unchecked_Type_Conversion;
}

/* Compute whether GNAT_NODE requires atomic access and set TYPE to the type
   of access and SYNC according to the associated synchronization setting.

   We implement 3 different semantics of atomicity in this function:

     1. the Ada 95/2005/2012 semantics of the Atomic aspect/pragma,
     2. the Ada 2022 semantics of the Atomic aspect/pragma,
     3. the semantics of the Volatile_Full_Access GNAT aspect/pragma.

  They are mutually exclusive and the FE should have rejected conflicts.  */

static void
get_atomic_access (Node_Id gnat_node, atomic_acces_t *type, bool *sync)
{
  Node_Id gnat_parent, gnat_temp;
  Attribute_Id attr_id;

  /* First, scan the parent to filter out irrelevant cases.  */
  gnat_parent = Parent (gnat_node);
  switch (Nkind (gnat_parent))
    {
    case N_Attribute_Reference:
      attr_id = Get_Attribute_Id (Attribute_Name (gnat_parent));
      /* Do not mess up machine code insertions.  */
      if (attr_id == Attr_Asm_Input || attr_id == Attr_Asm_Output)
	goto not_atomic;

      /* Nothing to do if we are the prefix of an attribute, since we do not
	 want an atomic access for things like 'Size.  */

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

    case N_Reference:
      /* The N_Reference node is like an attribute.  */
      if (Prefix (gnat_parent) == gnat_node)
	goto not_atomic;
      break;

    case N_Object_Renaming_Declaration:
      /* Nothing to do for the identifier in an object renaming declaration,
         the renaming itself does not need atomic access.  */
      goto not_atomic;

    default:
      break;
    }

  /* Now strip any type conversion from GNAT_NODE.  */
  if (node_is_type_conversion (gnat_node))
    gnat_node = Expression (gnat_node);

  /* Up to Ada 2012, for Atomic itself, only reads and updates of the object as
     a whole require atomic access (RM C.6(15)), unless the object is also VFA.
     But, starting with Ada 2022, reads of or writes to nonatomic subcomponents
     of the object also require atomic access (RM C.6(19)).  */
  if (node_is_atomic (gnat_node))
    {
      bool as_a_whole = true;

      /* If we are the prefix of the parent, then the access is partial.  */
      for (gnat_temp = gnat_node, gnat_parent = Parent (gnat_temp);
	   node_is_component (gnat_parent) && Prefix (gnat_parent) == gnat_temp;
	   gnat_temp = gnat_parent, gnat_parent = Parent (gnat_temp))
	if (Ada_Version < Ada_2022
	    ? !node_is_volatile_full_access (gnat_node)
	    : node_is_atomic (gnat_parent))
	  goto not_atomic;
	else
	  as_a_whole = false;

      /* We consider that partial accesses are not sequential actions and,
	 therefore, do not require synchronization.  */
      *type = SIMPLE_ATOMIC;
      *sync = as_a_whole ? Atomic_Sync_Required (gnat_node) : false;
      return;
    }

  /* Look for an outer atomic access of a nonatomic subcomponent.  Note that,
     for VFA, we do this before looking at the node itself because we need to
     access the outermost VFA object atomically, unlike for Atomic where it is
     the innermost atomic object (RM C.6(19)).  */
  for (gnat_temp = gnat_node;
       node_is_component (gnat_temp);
       gnat_temp = Prefix (gnat_temp))
    if ((Ada_Version >= Ada_2022 && node_is_atomic (Prefix (gnat_temp)))
	|| node_is_volatile_full_access (Prefix (gnat_temp)))
      {
	*type = OUTER_ATOMIC;
	*sync = false;
	return;
      }

  /* Unlike Atomic, accessing a VFA object always requires atomic access.  */
  if (node_is_volatile_full_access (gnat_node))
    {
      *type = SIMPLE_ATOMIC;
      *sync = false;
      return;
    }

not_atomic:
  *type = NOT_ATOMIC;
  *sync = false;
}

/* Return true if GNAT_NODE requires simple atomic access and, if so, set SYNC
   according to the associated synchronization setting.  */

static inline bool
simple_atomic_access_required_p (Node_Id gnat_node, bool *sync)
{
  atomic_acces_t type;
  get_atomic_access (gnat_node, &type, sync);
  return type == SIMPLE_ATOMIC;
}

/* Return the storage model specified by GNAT_NODE, or else Empty.  */

static Entity_Id
get_storage_model (Node_Id gnat_node)
{
  if (Nkind (gnat_node) == N_Explicit_Dereference
      && Has_Designated_Storage_Model_Aspect (Etype (Prefix (gnat_node))))
    return Storage_Model_Object (Etype (Prefix (gnat_node)));
  else
    return Empty;
}

/* Compute whether GNAT_NODE requires storage model access and set GNAT_SMO to
   the storage model object to be used for it if it does, or else Empty.  */

static void
get_storage_model_access (Node_Id gnat_node, Entity_Id *gnat_smo)
{
  const Node_Id gnat_parent = Parent (gnat_node);
  *gnat_smo = Empty;

  switch (Nkind (gnat_parent))
    {
    case N_Attribute_Reference:
      /* If the parent is an attribute reference that requires an lvalue and
         gnat_node is the Prefix (i.e. not a parameter), we do not need to
         actually access any storage. */
      if (lvalue_required_for_attribute_p (gnat_parent)
          && Prefix (gnat_parent) == gnat_node)
        return;
      break;

    case N_Object_Renaming_Declaration:
      /* Nothing to do for the identifier in an object renaming declaration,
         the renaming itself does not need storage model access. */
      return;

    default:
      break;
    }

  /* If we are the prefix of the parent, then the access is above us.  */
  if ((node_is_component (gnat_parent) && Prefix (gnat_parent) == gnat_node)
      || (node_is_type_conversion (gnat_parent)
	  && node_is_component (Parent (gnat_parent))
	  && Prefix (Parent (gnat_parent)) == gnat_parent))
    return;

  /* Find the innermost prefix in GNAT_NODE, stripping any type conversion.  */
  if (node_is_type_conversion (gnat_node))
    gnat_node = Expression (gnat_node);
  while (node_is_component (gnat_node))
    {
      gnat_node = Prefix (gnat_node);
      if (node_is_type_conversion (gnat_node))
	gnat_node = Expression (gnat_node);
    }

  *gnat_smo = get_storage_model (gnat_node);
}

/* Return true if GNAT_NODE requires storage model access and, if so, set
   GNAT_SMO to the storage model object to be used for it.  */

static bool
storage_model_access_required_p (Node_Id gnat_node, Entity_Id *gnat_smo)
{
  get_storage_model_access (gnat_node, gnat_smo);
  return Present (*gnat_smo);
}

/* Create a temporary variable with PREFIX and TYPE, and return it.  */

static tree
create_temporary (const char *prefix, tree type)
{
  if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type)))
    type = maybe_pad_type (type, max_size (TYPE_SIZE (type), true), 0,
			   Empty, false, false, true);
  tree gnu_temp
    = create_var_decl (create_tmp_var_name (prefix), NULL_TREE,
		      type, NULL_TREE,
		      false, false, false, false, false, false,
		      true, false, NULL, Empty);
  return gnu_temp;
}

/* Create a temporary variable with PREFIX and initialize it with GNU_INIT.
   Put the initialization statement into GNU_INIT_STMT and annotate it with
   the SLOC of GNAT_NODE.  Return the temporary variable.  */

static tree
create_init_temporary (const char *prefix, tree gnu_init, tree *gnu_init_stmt,
		       Node_Id gnat_node)
{
  tree gnu_temp = create_temporary (prefix, TREE_TYPE (gnu_init));

  *gnu_init_stmt = build_binary_op (INIT_EXPR, NULL_TREE, gnu_temp, gnu_init);
  set_expr_location_from_node (*gnu_init_stmt, gnat_node);

  return gnu_temp;
}

/* Return true if TYPE is an array of scalar type.  */

static bool
is_array_of_scalar_type (tree type)
{
  if (TREE_CODE (type) != ARRAY_TYPE)
    return false;

  type = TREE_TYPE (type);

  return !AGGREGATE_TYPE_P (type) && !POINTER_TYPE_P (type);
}

/* Helper function for walk_tree, used by return_slot_opt_for_pure_call_p.  */

static tree
find_decls_r (tree *tp, int *walk_subtrees, void *data)
{
  bitmap decls = (bitmap) data;

  if (TYPE_P (*tp))
    *walk_subtrees = 0;

  else if (DECL_P (*tp))
    bitmap_set_bit (decls, DECL_UID (*tp));

  return NULL_TREE;
}

/* Return whether the assignment TARGET = CALL can be subject to the return
   slot optimization, under the assumption that the called function be pure
   in the Ada sense and return an array of scalar type.  */

static bool
return_slot_opt_for_pure_call_p (tree target, tree call)
{
  /* Check that the target is a DECL.  */
  if (!DECL_P (target))
    return false;

  const bitmap decls = BITMAP_GGC_ALLOC ();
  call_expr_arg_iterator iter;
  tree arg;

  /* Check that all the arguments have either a scalar type (we assume that
     this means by-copy passing mechanism) or array of scalar type.  */
  FOR_EACH_CALL_EXPR_ARG (arg, iter, call)
    {
      tree arg_type = TREE_TYPE (arg);
      if (TREE_CODE (arg_type) == REFERENCE_TYPE)
	arg_type = TREE_TYPE (arg_type);

      if (is_array_of_scalar_type (arg_type))
	walk_tree_without_duplicates (&arg, find_decls_r, decls);

      else if (AGGREGATE_TYPE_P (arg_type) || POINTER_TYPE_P (arg_type))
	return false;
    }

  /* Check that the target is not referenced by the non-scalar arguments.  */
  return !bitmap_bit_p (decls, DECL_UID (target));
}

/* Elaborate types referenced in the profile (FIRST_FORMAL, RESULT_TYPE).  */

static void
elaborate_profile (Entity_Id first_formal, Entity_Id result_type)
{
  Entity_Id formal;

  for (formal = first_formal;
       Present (formal);
       formal = Next_Formal_With_Extras (formal))
    (void) gnat_to_gnu_type (Etype (formal));

  if (Present (result_type) && Ekind (result_type) != E_Void)
    (void) gnat_to_gnu_type (result_type);
}

/* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Function_Call
   or an N_Procedure_Call_Statement, to a GCC tree, which is returned.
   GNU_RESULT_TYPE_P is a pointer to where we should place the result type.
   If GNU_TARGET is non-null, this must be a function call on the RHS of a
   N_Assignment_Statement and the result is to be placed into that object.
   ATOMIC_ACCESS is the type of atomic access to be used for the assignment
   to GNU_TARGET.  If, in addition, ATOMIC_SYNC is true, then the assignment
   to GNU_TARGET requires atomic synchronization.  GNAT_SMO is the storage
   model object to be used for the assignment to GNU_TARGET or Empty if there
   is none.  */

static tree
Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target,
	     atomic_acces_t atomic_access, bool atomic_sync, Entity_Id gnat_smo)
{
  const bool function_call = (Nkind (gnat_node) == N_Function_Call);
  const bool returning_value = (function_call && !gnu_target);
  /* The GCC node corresponding to the GNAT subprogram name.  This can either
     be a FUNCTION_DECL node if we are dealing with a standard subprogram call,
     or an indirect reference expression (an INDIRECT_REF node) pointing to a
     subprogram.  */
  const Node_Id gnat_subprog = Name (gnat_node);
  tree gnu_subprog = gnat_to_gnu (gnat_subprog);
  /* The FUNCTION_TYPE node giving the GCC type of the subprogram.  */
  tree gnu_subprog_type = TREE_TYPE (gnu_subprog);
  /* The return type of the FUNCTION_TYPE.  */
  tree gnu_result_type;
  const bool frontend_builtin
    = (TREE_CODE (gnu_subprog) == FUNCTION_DECL
       && DECL_BUILT_IN_CLASS (gnu_subprog) == BUILT_IN_FRONTEND);
  auto_vec<tree, 16> gnu_actual_vec;
  tree gnu_name_list = NULL_TREE;
  tree gnu_stmt_list = NULL_TREE;
  tree gnu_after_list = NULL_TREE;
  tree gnu_retval = NULL_TREE;
  tree gnu_call, gnu_result;
  bool went_into_elab_proc;
  bool pushed_binding_level;
  bool variadic;
  bool by_descriptor;
  Entity_Id gnat_formal;
  Entity_Id gnat_result_type;
  Node_Id gnat_actual;
  atomic_acces_t aa_type;
  bool aa_sync;

  /* The only way we can make a call via an access type is if GNAT_NAME is an
     explicit dereference.  In that case, get the list of formal args from the
     type the access type is pointing to.  Otherwise, get the formals from the
     entity being called.  */
  if (Nkind (gnat_subprog) == N_Explicit_Dereference)
    {
      const Entity_Id gnat_prefix_type
	= Underlying_Type (Etype (Prefix (gnat_subprog)));

      gnat_formal = First_Formal_With_Extras (Etype (gnat_subprog));
      gnat_result_type = Etype (Etype (gnat_subprog));
      variadic = IN (Convention (gnat_prefix_type), Convention_C_Variadic);

      /* If the access type doesn't require foreign-compatible representation,
	 be prepared for descriptors.  */
      by_descriptor
	= targetm.calls.custom_function_descriptors > 0
	  && Can_Use_Internal_Rep (gnat_prefix_type);
    }

  else if (Nkind (gnat_subprog) == N_Attribute_Reference)
    {
      /* Assume here that this must be 'Elab_Body or 'Elab_Spec.  */
      gnat_formal = Empty;
      gnat_result_type = Empty;
      variadic = false;
      by_descriptor = false;
    }

  else
    {
      gcc_checking_assert (Is_Entity_Name (gnat_subprog));

      gnat_formal = First_Formal_With_Extras (Entity (gnat_subprog));
      gnat_result_type = Etype (Entity_Id (gnat_subprog));
      variadic = IN (Convention (Entity (gnat_subprog)), Convention_C_Variadic);
      by_descriptor = false;

      /* If we are calling a stubbed function, then raise Program_Error, but
	 elaborate all our args first.  */
      if (Convention (Entity (gnat_subprog)) == Convention_Stubbed)
	{
	  tree call_expr = build_call_raise (PE_Stubbed_Subprogram_Called,
					     gnat_node, N_Raise_Program_Error);

	  for (gnat_actual = First_Actual (gnat_node);
	       Present (gnat_actual);
	       gnat_actual = Next_Actual (gnat_actual))
	    add_stmt (gnat_to_gnu (gnat_actual));

	  if (returning_value)
	    {
	      gnu_result_type = TREE_TYPE (gnu_subprog_type);
	      *gnu_result_type_p = gnu_result_type;
	      return build1 (NULL_EXPR, gnu_result_type, call_expr);
	    }

	  return call_expr;
	}
    }

  /* We must elaborate the entire profile now because, if it references types
     that were initially incomplete, their elaboration changes the contents
     of GNU_SUBPROG_TYPE and, in particular, may change the result type.  */
  elaborate_profile (gnat_formal, gnat_result_type);

  gcc_assert (FUNC_OR_METHOD_TYPE_P (gnu_subprog_type));
  gnu_result_type = TREE_TYPE (gnu_subprog_type);

  if (TREE_CODE (gnu_subprog) == FUNCTION_DECL)
    {
      /* For a call to a nested function, check the inlining status.  */
      if (decl_function_context (gnu_subprog))
	check_inlining_for_nested_subprog (gnu_subprog);

      /* For a recursive call, avoid explosion due to recursive inlining.  */
      if (gnu_subprog == current_function_decl)
	DECL_DISREGARD_INLINE_LIMITS (gnu_subprog) = 0;
    }

  /* The lifetime of the temporaries created for the call ends right after the
     return value is copied, so we can give them the scope of the elaboration
     routine at top level.  */
  if (!current_function_decl)
    {
      current_function_decl = get_elaboration_procedure ();
      went_into_elab_proc = true;
    }
  else
    went_into_elab_proc = false;

  /* First, create the temporary for the return value when:

       1. There is no target and the function has copy-in/copy-out parameters,
	  because we need to preserve the return value before copying back the
	  parameters.

       2. There is no target and the call is made for neither the declaration
	  of an object (regular or renaming), nor a return statement, nor an
	  allocator, nor an aggregate, and the return type has variable size
	  because in this case the gimplifier cannot create the temporary, or
	  more generally is an aggregate type, because the gimplifier would
	  create the temporary in the outermost scope instead of locally here.
	  But there is an exception for an allocator of unconstrained record
	  type with default discriminant because we allocate the actual size
	  in this case, unlike in the other cases, so we need a temporary to
	  fetch the discriminant and we create it here.

       3. There is a target and it is a slice or an array with fixed size,
	  and the return type has variable size, because the gimplifier
	  doesn't handle these cases.

       4. There is a target which is a bit-field and the function returns an
	  unconstrained record type with default discriminant, because the
	  return may copy more data than the bit-field can contain.

       5. There is a target which needs to be accessed with a storage model.

       6. There is no target and we have misaligned In Out or Out parameters
	  passed by reference, because we need to preserve the return value
	  before copying back the parameters.  However, in this case, we'll
	  defer creating the temporary, see below.

     This must be done before we push a binding level around the call, since
     we will pop it before copying the return value.  */
  if (function_call
      && ((!gnu_target && TYPE_CI_CO_LIST (gnu_subprog_type))
	  || (!gnu_target
	      && Nkind (Parent (gnat_node)) != N_Object_Declaration
	      && Nkind (Parent (gnat_node)) != N_Object_Renaming_Declaration
	      && Nkind (Parent (gnat_node)) != N_Simple_Return_Statement
	      && (!(Nkind (Parent (gnat_node)) == N_Qualified_Expression
		    && Nkind (Parent (Parent (gnat_node))) == N_Allocator)
		  || type_is_padding_self_referential (gnu_result_type))
	      && Nkind (Parent (gnat_node)) != N_Aggregate
	      && AGGREGATE_TYPE_P (gnu_result_type)
	      && !TYPE_IS_FAT_POINTER_P (gnu_result_type))
	  || (gnu_target
	      && (TREE_CODE (gnu_target) == ARRAY_RANGE_REF
		  || (TREE_CODE (TREE_TYPE (gnu_target)) == ARRAY_TYPE
		      && TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_target)))
			 == INTEGER_CST))
	      && TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST)
	  || (gnu_target
	      && TREE_CODE (gnu_target) == COMPONENT_REF
	      && DECL_BIT_FIELD (TREE_OPERAND (gnu_target, 1))
	      && DECL_SIZE (TREE_OPERAND (gnu_target, 1))
		 != TYPE_SIZE (TREE_TYPE (gnu_target))
	      && type_is_padding_self_referential (gnu_result_type))
	  || (gnu_target
	      && Present (gnat_smo)
	      && Present (Storage_Model_Copy_To (gnat_smo)))))
    {
      gnu_retval = create_temporary ("R", gnu_result_type);
      DECL_RETURN_VALUE_P (gnu_retval) = 1;
    }

  /* If we don't need a value or have already created it, push a binding level
     around the call.  This will narrow the lifetime of the temporaries we may
     need to make when translating the parameters as much as possible.  */
  if (!returning_value || gnu_retval)
    {
      start_stmt_group ();
      gnat_pushlevel ();
      pushed_binding_level = true;
    }
  else
    pushed_binding_level = false;

  /* Create the list of the actual parameters as GCC expects it, namely a
     chain of TREE_LIST nodes in which the TREE_VALUE field of each node
     is an expression and the TREE_PURPOSE field is null.  But skip Out
     parameters not passed by reference and that need not be copied in.  */
  for (gnat_actual = First_Actual (gnat_node);
       Present (gnat_actual);
       gnat_formal = Next_Formal_With_Extras (gnat_formal),
       gnat_actual = Next_Actual (gnat_actual))
    {
      const Entity_Id gnat_formal_type = Etype (gnat_formal);
      tree gnu_formal_type = gnat_to_gnu_type (gnat_formal_type);
      tree gnu_formal = present_gnu_tree (gnat_formal)
			? get_gnu_tree (gnat_formal) : NULL_TREE;
      tree gnu_actual_type = gnat_to_gnu_type (Etype (gnat_actual));
      const bool is_init_proc
	= Is_Entity_Name (gnat_subprog) && Is_Init_Proc (Entity (gnat_subprog));
      const bool in_param = (Ekind (gnat_formal) == E_In_Parameter);
      const bool is_true_formal_parm
	= gnu_formal && TREE_CODE (gnu_formal) == PARM_DECL;
      const bool is_by_ref_formal_parm
	= is_true_formal_parm
	  && (DECL_BY_REF_P (gnu_formal)
	      || DECL_BY_COMPONENT_PTR_P (gnu_formal));
      /* In the In Out or Out case, we must suppress conversions that yield
	 an lvalue but can nevertheless cause the creation of a temporary,
	 because we need the real object in this case, either to pass its
	 address if it's passed by reference or as target of the back copy
	 done after the call if it uses the copy-in/copy-out mechanism.
	 We do it in the In case too, except for a formal passed by reference
	 and an actual which is an unchecked conversion to an elementary type
	 or constrained composite type because it itself can cause the actual
	 to be misaligned and the addressability test needs to be applied to
	 the real object.  */
      const bool suppress_type_conversion
	= ((Nkind (gnat_actual) == N_Unchecked_Type_Conversion
	    && (!in_param
		|| !is_by_ref_formal_parm
		|| (Is_Composite_Type (Underlying_Type (gnat_formal_type))
		    && !Is_Constrained (Underlying_Type (gnat_formal_type)))))
	   || (Nkind (gnat_actual) == N_Type_Conversion
	       && Is_Composite_Type (Underlying_Type (gnat_formal_type))));
      Node_Id gnat_name = suppress_type_conversion
			  ? Expression (gnat_actual) : gnat_actual;
      tree gnu_name = gnat_to_gnu (gnat_name), gnu_name_type;
      bool aliasing = false;

      /* If it's possible we may need to use this expression twice, make sure
	 that any side-effects are handled via SAVE_EXPRs; likewise if we need
	 to force side-effects before the call.  */
      if (!in_param && !is_by_ref_formal_parm)
	{
	  tree init = NULL_TREE;
	  gnu_name = gnat_stabilize_reference (gnu_name, true, &init);
	  if (init)
	    gnu_name
	      = build_compound_expr (TREE_TYPE (gnu_name), init, gnu_name);
	}

      /* If we are passing a non-addressable parameter by reference, pass the
	 address of a copy.  In the In Out or Out case, set up to copy back
	 out after the call.  Moreover, in the case of a conversion, if we
	 are passing a non-aliasable parameter, also pass the address of a
	 copy to avoid breaking strict aliasing rules.  */
      if (is_by_ref_formal_parm
	  && (gnu_name_type = gnat_to_gnu_type (Etype (gnat_name)))
	  && (!addressable_p (gnu_name, gnu_name_type, is_init_proc)
	      || (node_is_type_conversion (gnat_actual)
		  && (aliasing = !aliasable_p (gnu_name, gnu_actual_type)))))
	{
	  tree gnu_orig = gnu_name, gnu_temp, gnu_stmt;

	  /* Do not issue warnings for CONSTRUCTORs since this is not a copy
	     but sort of an instantiation for them.  */
	  if (TREE_CODE (remove_conversions (gnu_name, true)) == CONSTRUCTOR)
	    ;

	  /* Likewise for an atomic type, which is defined to be by-reference
	     if it is not by-copy but actually behaves more like a scalar.  */
	  else if (TYPE_ATOMIC (gnu_formal_type))
	    ;

	  /* If the formal is passed by reference, a copy is not allowed.  */
	  else if (TYPE_IS_BY_REFERENCE_P (gnu_formal_type)
		   || Is_Aliased (gnat_formal))
	    post_error ("misaligned actual cannot be passed by reference",
		        gnat_actual);

	  /* If the mechanism was forced to by-ref, a copy is not allowed but
	     we issue only a warning because this case is not strict Ada.  */
	  else if (DECL_FORCED_BY_REF_P (gnu_formal))
	    post_error ("misaligned actual cannot be passed by reference??",
			gnat_actual);

	  /* If the copy needs to be made because of aliasing considerations,
	     issue a warning because this was historically not necessary.  */
	  else if (aliasing)
	    {
	      if (Nkind (gnat_actual) == N_Unchecked_Type_Conversion)
		{
		  post_error
		    ("unchecked conversion implemented by copy??",
		     gnat_actual);
		  post_error
		    ("\\??use pragma Universal_Aliasing on either type",
		     gnat_actual);
		  post_error
		    ("\\??to enable RM 13.9(12) implementation permission",
		     gnat_actual);
		}

	      else
		{
		  post_error
		    ("value conversion implemented by copy??",
		     gnat_actual);
		  post_error
		    ("\\??use pair of types with same root type",
		     gnat_actual);
		  post_error
		    ("\\??to avoid new object in RM 4.6(58.5/5)",
		     gnat_actual);
		}
	    }

	  /* If the actual type of the object is already the nominal type,
	     we have nothing to do, except if the size is self-referential
	     in which case we'll remove the unpadding below.  */
	  if (TREE_TYPE (gnu_name) == gnu_name_type
	      && !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_name_type)))
	    ;

	  /* Otherwise remove the unpadding from all the objects.  */
	  else if (TREE_CODE (gnu_name) == COMPONENT_REF
		   && TYPE_IS_PADDING_P
		      (TREE_TYPE (TREE_OPERAND (gnu_name, 0))))
	    gnu_orig = gnu_name = TREE_OPERAND (gnu_name, 0);

	  /* Otherwise convert to the nominal type of the object if needed.
	     There are several cases in which we need to make the temporary
	     using this type instead of the actual type of the object when
	     they are distinct, because the expectations of the callee would
	     otherwise not be met:
	       - if it's a justified modular type,
	       - if the actual type is a smaller form of it,
	       - if it's a smaller form of the actual type.  */
	  else if ((TREE_CODE (gnu_name_type) == RECORD_TYPE
		    && (TYPE_JUSTIFIED_MODULAR_P (gnu_name_type)
		        || smaller_form_type_p (TREE_TYPE (gnu_name),
					        gnu_name_type)))
		   || (INTEGRAL_TYPE_P (gnu_name_type)
		       && smaller_form_type_p (gnu_name_type,
					       TREE_TYPE (gnu_name))))
	    gnu_name = convert (gnu_name_type, gnu_name);

	  /* If the temporary is created because of aliasing considerations,
	     or would have been so created if the actual was addressable,
	     it must be in the target type of the (unchecked) conversion.  */
	  if (aliasing
	      || (node_is_type_conversion (gnat_actual)
		  && !aliasable_p (gnu_name, gnu_actual_type)))
	    {
	      if (Nkind (gnat_actual) == N_Unchecked_Type_Conversion)
		gnu_name = unchecked_convert (gnu_actual_type, gnu_name,
					      No_Truncation (gnat_actual));
	      else
		gnu_name = convert (gnu_actual_type, gnu_name);
	    }

	  /* If this is an In Out or Out parameter and we're returning a value,
	     we need to create a temporary for the return value because we must
	     preserve it before copying back at the very end.  */
	  if (!in_param && returning_value && !gnu_retval)
	    {
	      gnu_retval = create_temporary ("R", gnu_result_type);
	      DECL_RETURN_VALUE_P (gnu_retval) = 1;
	    }

	  /* If we haven't pushed a binding level, push it now.  This will
	     narrow the lifetime of the temporary we are about to make as
	     much as possible.  */
	  if (!pushed_binding_level && (!returning_value || gnu_retval))
	    {
	      start_stmt_group ();
	      gnat_pushlevel ();
	      pushed_binding_level = true;
	    }

	  /* Create an explicit temporary holding the copy.  */

	  /* Do not initialize it for the _Init parameter of an initialization
	     procedure since no data is meant to be passed in.  */
	  if (Ekind (gnat_formal) == E_Out_Parameter && is_init_proc)
	    gnu_name = gnu_temp = create_temporary ("A", TREE_TYPE (gnu_name));

	  /* Initialize it on the fly like for an implicit temporary in the
	     other cases, as we don't necessarily have a statement list.  */
	  else
	    {
	      gnu_temp = create_init_temporary ("A", gnu_name, &gnu_stmt,
						gnat_actual);
	      gnu_name = build_compound_expr (TREE_TYPE (gnu_name), gnu_stmt,
					      gnu_temp);
	    }

	  /* Set up to move the copy back to the original if needed.  */
	  if (!in_param)
	    {
	      /* If the original is a COND_EXPR whose first arm isn't meant to
		 be further used, just deal with the second arm.  This is very
		 likely the conditional expression built for a check.  */
	      if (TREE_CODE (gnu_orig) == COND_EXPR
		  && TREE_CODE (TREE_OPERAND (gnu_orig, 1)) == COMPOUND_EXPR
		  && integer_zerop
		     (TREE_OPERAND (TREE_OPERAND (gnu_orig, 1), 1)))
		gnu_orig = TREE_OPERAND (gnu_orig, 2);

	      gnu_stmt
		= build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_orig, gnu_temp);
	      set_expr_location_from_node (gnu_stmt, gnat_node);

	      append_to_statement_list (gnu_stmt, &gnu_after_list);
	    }
	}

      /* Start from the real object and build the actual.  */
      tree gnu_unpadded_actual_type = get_unpadded_type (Etype (gnat_actual));
      tree gnu_actual = gnu_name;

      /* If atomic access is required for an In or In Out actual parameter,
	 build the atomic load.  */
      if (is_true_formal_parm
	  && !is_by_ref_formal_parm
	  && Ekind (gnat_formal) != E_Out_Parameter
	  && simple_atomic_access_required_p (gnat_actual, &aa_sync))
	gnu_actual = build_atomic_load (gnu_actual, aa_sync);

      /* If this was a procedure call, we may not have removed any padding.
	 So do it here for the part we will use as an input, if any.  */
      if (Ekind (gnat_formal) != E_Out_Parameter
	  && TYPE_IS_PADDING_P (TREE_TYPE (gnu_actual)))
	gnu_actual = convert (gnu_unpadded_actual_type, gnu_actual);

      /* Put back the conversion we suppressed above in the computation of the
	 real object.  And even if we didn't suppress any conversion there, we
	 may have suppressed a conversion to the Etype of the actual earlier,
	 since the parent is a procedure call, so put it back here.  Note that
	 we might have a dummy type here if the actual is the dereference of a
	 pointer to it, but that's OK when the formal is passed by reference.
	 We also do not put back a conversion between an actual and a formal
	 that are unconstrained array types to avoid creating local bounds.  */
      if (TYPE_IS_DUMMY_P (gnu_unpadded_actual_type))
	gcc_assert (is_true_formal_parm && DECL_BY_REF_P (gnu_formal));
      else if (suppress_type_conversion
	       && Nkind (gnat_actual) == N_Unchecked_Type_Conversion)
	gnu_actual = unchecked_convert (gnu_unpadded_actual_type, gnu_actual,
				        No_Truncation (gnat_actual));
      else if ((TREE_CODE (TREE_TYPE (gnu_actual)) == UNCONSTRAINED_ARRAY_TYPE
		|| (TREE_CODE (TREE_TYPE (gnu_actual)) == RECORD_TYPE
		    && TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (gnu_actual))))
	       && TREE_CODE (gnu_formal_type) == UNCONSTRAINED_ARRAY_TYPE)
	;
      else
	gnu_actual = convert (gnu_unpadded_actual_type, gnu_actual);

      /* If the formal parameter is passed by reference, check that building
	 the address of the actual parameter below will not end up violating
	 strict aliasing rules; that's the case for a VIEW_CONVERT_EXPR when
	 the source and target types may not alias each other.  */
      if (is_by_ref_formal_parm
	  && TREE_CODE (gnu_actual) == VIEW_CONVERT_EXPR
	  && (flag_checking || flag_strict_aliasing))
	gcc_assert (aliasable_p (gnu_actual, gnu_actual_type));

      gigi_checking_assert (!Do_Range_Check (gnat_actual));

      /* First see if the parameter is passed by reference.  */
      if (is_true_formal_parm && DECL_BY_REF_P (gnu_formal))
	{
	  if (!in_param)
	    {
	      /* In Out or Out parameters passed by reference don't use the
		 copy-in/copy-out mechanism so the address of the real object
		 must be passed to the function.  */
	      gnu_actual = gnu_name;

	      /* If we have a padded type, be sure we've removed padding.  */
	      if (TYPE_IS_PADDING_P (TREE_TYPE (gnu_actual)))
		gnu_actual = convert (gnu_unpadded_actual_type, gnu_actual);

	      /* If it is the constructed subtype of an array allocated with
		 its bounds, the type of the actual includes the template,
		 although it is formally constrained.  So we need to convert
		 it back to the real constructed subtype to retrieve the
		 constrained part and takes its address.  */
	      if (TREE_CODE (TREE_TYPE (gnu_actual)) == RECORD_TYPE
		  && TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (gnu_actual))
		  && Is_Constr_Array_Subt_With_Bounds (Etype (gnat_actual)))
		gnu_actual = convert (gnu_unpadded_actual_type, gnu_actual);
	    }

	  /* There is no need to convert the actual to the formal's type before
	     taking its address.  The only exception is for unconstrained array
	     types because of the way we build fat pointers.  */
	  if (TREE_CODE (gnu_formal_type) == UNCONSTRAINED_ARRAY_TYPE)
	    {
	      /* Put back the conversion we suppressed above for In Out or Out
		 parameters, since it may set the bounds of the actual.  */
	      if (!in_param && suppress_type_conversion)
		gnu_actual = convert (gnu_unpadded_actual_type, gnu_actual);
	      gnu_actual = convert (gnu_formal_type, gnu_actual);
	    }

	  /* Take the address of the object and convert to the proper pointer
	     type.  */
	  gnu_formal_type = TREE_TYPE (gnu_formal);
	  gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual);
	}

      /* Then see if the parameter is an array passed to a foreign convention
	 subprogram.  */
      else if (is_true_formal_parm && DECL_BY_COMPONENT_PTR_P (gnu_formal))
	{
	  gnu_actual = maybe_padded_object (gnu_actual);
	  gnu_actual = maybe_unconstrained_array (gnu_actual);

	  /* Take the address of the object and convert to the proper pointer
	     type.  We'd like to actually compute the address of the beginning
	     of the array using an ADDR_EXPR of an ARRAY_REF, but there's a
	     possibility that the ARRAY_REF might return a constant and we'd be
	     getting the wrong address.  Neither approach is exactly correct,
	     but this is the most likely to work in all cases.  */
	  gnu_formal_type = TREE_TYPE (gnu_formal);
	  gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual);
	}

      /* Then see if the parameter is passed by copy.  */
      else if (is_true_formal_parm)
	{
	  if (!in_param)
	    gnu_name_list = tree_cons (NULL_TREE, gnu_name, gnu_name_list);

	  gnu_actual = convert (gnu_formal_type, gnu_actual);

	  /* If this is a front-end built-in function, there is no need to
	     convert to the type used to pass the argument.  */
	  if (!frontend_builtin)
	    gnu_actual = convert (DECL_ARG_TYPE (gnu_formal), gnu_actual);
	}

      /* Then see if this is an unnamed parameter in a variadic C function.  */
      else if (variadic)
	{
	  /* This is based on the processing done in gnat_to_gnu_param, but
	     we expect the mechanism to be set in (almost) all cases.  */
	  const Mechanism_Type mech = Mechanism (gnat_formal);

	  /* Strip off possible padding type.  */
	  if (TYPE_IS_PADDING_P (gnu_formal_type))
	    gnu_formal_type = TREE_TYPE (TYPE_FIELDS (gnu_formal_type));

	  /* Arrays are passed as pointers to element type.  First check for
	     unconstrained array and get the underlying array.  */
	  if (TREE_CODE (gnu_formal_type) == UNCONSTRAINED_ARRAY_TYPE)
	    gnu_formal_type
	      = TREE_TYPE
		(TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_formal_type))));

	  /* Arrays are passed as pointers to element type.  */
	  if (mech != By_Copy && TREE_CODE (gnu_formal_type) == ARRAY_TYPE)
	    {
	      gnu_actual = maybe_padded_object (gnu_actual);
	      gnu_actual = maybe_unconstrained_array (gnu_actual);

	      /* Strip off any multi-dimensional entries, then strip
		 off the last array to get the component type.  */
	      while (TREE_CODE (TREE_TYPE (gnu_formal_type)) == ARRAY_TYPE
		     && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_formal_type)))
		gnu_formal_type = TREE_TYPE (gnu_formal_type);

	      gnu_formal_type = TREE_TYPE (gnu_formal_type);
	      gnu_formal_type = build_pointer_type (gnu_formal_type);
	      gnu_actual
		= build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual);
	    }

	  /* Fat pointers are passed as thin pointers.  */
	  else if (TYPE_IS_FAT_POINTER_P (gnu_formal_type))
	    gnu_formal_type
	      = make_type_from_size (gnu_formal_type,
				     size_int (POINTER_SIZE), 0);

	  /* If we were requested or muss pass by reference, do so.
	     If we were requested to pass by copy, do so.
	     Otherwise, pass In Out or Out parameters or aggregates by
	     reference.  */
	  else if (mech == By_Reference
		   || must_pass_by_ref (gnu_formal_type)
		   || (mech != By_Copy
		       && (!in_param || AGGREGATE_TYPE_P (gnu_formal_type))))
	    {
	      gnu_formal_type = build_reference_type (gnu_formal_type);
	      gnu_actual
		= build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual);
	    }

	  /* Otherwise pass by copy after applying default C promotions.  */
	  else
	    {
	      if (INTEGRAL_TYPE_P (gnu_formal_type)
		  && TYPE_PRECISION (gnu_formal_type)
		     < TYPE_PRECISION (integer_type_node))
		gnu_formal_type = integer_type_node;

	      else if (SCALAR_FLOAT_TYPE_P (gnu_formal_type)
		       && TYPE_PRECISION (gnu_formal_type)
			  < TYPE_PRECISION (double_type_node))
		gnu_formal_type = double_type_node;
	    }

	  gnu_actual = convert (gnu_formal_type, gnu_actual);
	}

      /* If we didn't create a PARM_DECL for the formal, this means that
	 it is an Out parameter not passed by reference and that need not
	 be copied in.  In this case, the value of the actual need not be
	 read.  However, we still need to make sure that its side-effects
	 are evaluated before the call, so we evaluate its address.  */
      else
	{
	  if (!in_param)
	    gnu_name_list = tree_cons (NULL_TREE, gnu_name, gnu_name_list);

	  if (TREE_SIDE_EFFECTS (gnu_name))
	    {
	      tree addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_name);
	      append_to_statement_list (addr, &gnu_stmt_list);
	    }

	  continue;
	}

      gnu_actual_vec.safe_push (gnu_actual);
    }

  if (frontend_builtin)
    {
      tree pred_cst = build_int_cst (integer_type_node, PRED_BUILTIN_EXPECT);
      enum internal_fn icode = IFN_BUILTIN_EXPECT;

      switch (DECL_FE_FUNCTION_CODE (gnu_subprog))
	{
	case BUILT_IN_EXPECT:
	  break;
	case BUILT_IN_LIKELY:
	  gnu_actual_vec.safe_push (boolean_true_node);
	  break;
	case BUILT_IN_UNLIKELY:
	  gnu_actual_vec.safe_push (boolean_false_node);
	  break;
	default:
	  gcc_unreachable ();
	}

      gnu_actual_vec.safe_push (pred_cst);

      gnu_call
	= build_call_expr_internal_loc_array (UNKNOWN_LOCATION,
					      icode,
					      gnu_result_type,
					      gnu_actual_vec.length (),
					      gnu_actual_vec.begin ());
    }
  else
    {
      gnu_call
        = build_call_array_loc (UNKNOWN_LOCATION,
				gnu_result_type,
				build_unary_op (ADDR_EXPR, NULL_TREE,
						gnu_subprog),
				gnu_actual_vec.length (),
			        gnu_actual_vec.begin ());
      CALL_EXPR_BY_DESCRIPTOR (gnu_call) = by_descriptor;
    }

  set_expr_location_from_node (gnu_call, gnat_node);

  /* If we have created a temporary for the return value, initialize it.  */
  if (gnu_retval)
    {
      tree gnu_stmt
	= build_binary_op (INIT_EXPR, NULL_TREE, gnu_retval, gnu_call);
      set_expr_location_from_node (gnu_stmt, gnat_node);
      append_to_statement_list (gnu_stmt, &gnu_stmt_list);
      gnu_call = gnu_retval;
    }

  /* If this is a subprogram with copy-in/copy-out parameters, we need to
     unpack the valued returned from the function into the In Out or Out
     parameters.  We deal with the function return (if this is an Ada
     function) below.  */
  if (TYPE_CI_CO_LIST (gnu_subprog_type))
    {
      /* List of FIELD_DECLs associated with the PARM_DECLs of the copy-in/
	 copy-out parameters.  */
      tree gnu_cico_list = TYPE_CI_CO_LIST (gnu_subprog_type);
      const int length = list_length (gnu_cico_list);

      /* The call sequence must contain one and only one call, even though the
	 function is pure.  Save the result into a temporary if needed.  */
      if (length > 1)
	{
	  if (!gnu_retval)
	    {
	      tree gnu_stmt;
	      gnu_call
		= create_init_temporary ("P", gnu_call, &gnu_stmt, gnat_node);
	      append_to_statement_list (gnu_stmt, &gnu_stmt_list);
	    }

	  gnu_name_list = nreverse (gnu_name_list);
	}

      /* The first entry is for the actual return value if this is a
	 function, so skip it.  */
      if (function_call)
	gnu_cico_list = TREE_CHAIN (gnu_cico_list);

      if (Nkind (gnat_subprog) == N_Explicit_Dereference)
	gnat_formal = First_Formal_With_Extras (Etype (gnat_subprog));
      else
	gnat_formal = First_Formal_With_Extras (Entity (gnat_subprog));

      for (gnat_actual = First_Actual (gnat_node);
	   Present (gnat_actual);
	   gnat_formal = Next_Formal_With_Extras (gnat_formal),
	   gnat_actual = Next_Actual (gnat_actual))
	/* If we are dealing with a copy-in/copy-out parameter, we must
	   retrieve its value from the record returned in the call.  */
	if (!(present_gnu_tree (gnat_formal)
	      && TREE_CODE (get_gnu_tree (gnat_formal)) == PARM_DECL
	      && (DECL_BY_REF_P (get_gnu_tree (gnat_formal))
		  || DECL_BY_COMPONENT_PTR_P (get_gnu_tree (gnat_formal))))
	    && Ekind (gnat_formal) != E_In_Parameter)
	  {
	    /* Get the value to assign to this In Out or Out parameter.  It is
	       either the result of the function if there is only a single such
	       parameter or the appropriate field from the record returned.  */
	    tree gnu_result
	      = length == 1
		? gnu_call
		: build_component_ref (gnu_call, TREE_PURPOSE (gnu_cico_list),
				       false);

	    /* If the actual is a conversion, get the inner expression, which
	       will be the real destination, and convert the result to the
	       type of the actual parameter.  */
	    tree gnu_actual
	      = maybe_unconstrained_array (TREE_VALUE (gnu_name_list));

	    /* If the result is padded, remove the padding.  */
	    gnu_result = maybe_padded_object (gnu_result);

	    /* If the actual is a type conversion, the real target object is
	       denoted by the inner Expression and we need to convert the
	       result to the associated type.
	       We also need to convert our gnu assignment target to this type
	       if the corresponding GNU_NAME was constructed from the GNAT
	       conversion node and not from the inner Expression.  */
	    if (Nkind (gnat_actual) == N_Type_Conversion)
	      {
		const Node_Id gnat_expr = Expression (gnat_actual);

		gigi_checking_assert (!Do_Range_Check (gnat_expr));

		gnu_result
		  = convert_with_check (Etype (gnat_expr), gnu_result,
					Do_Overflow_Check (gnat_actual),
					Float_Truncate (gnat_actual),
					gnat_actual);

		if (!Is_Composite_Type (Underlying_Type (Etype (gnat_formal))))
		  gnu_actual = convert (TREE_TYPE (gnu_result), gnu_actual);
	      }

	    /* Unchecked conversions as actuals for Out parameters are not
	       allowed in user code because they are not variables, but do
	       occur in front-end expansions.  The associated GNU_NAME is
	       always obtained from the inner expression in such cases.  */
	    else if (Nkind (gnat_actual) == N_Unchecked_Type_Conversion)
	      gnu_result = unchecked_convert (TREE_TYPE (gnu_actual),
					      gnu_result,
					      No_Truncation (gnat_actual));
	    else
	      {
		gigi_checking_assert (!Do_Range_Check (gnat_actual));

		if (!(!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_actual)))
		      && TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_result)))))
		  gnu_result = convert (TREE_TYPE (gnu_actual), gnu_result);
	      }

	    get_atomic_access (gnat_actual, &aa_type, &aa_sync);

	    /* If an outer atomic access is required for an actual parameter,
	       build the load-modify-store sequence.  */
	    if (aa_type == OUTER_ATOMIC)
	      gnu_result
		= build_load_modify_store (gnu_actual, gnu_result, gnat_node);

	    /* Or else, if a simple atomic access is required, build the atomic
	       store.  */
	    else if (aa_type == SIMPLE_ATOMIC)
	      gnu_result
		= build_atomic_store (gnu_actual, gnu_result, aa_sync);

	    /* Otherwise build a regular assignment.  */
	    else
	      gnu_result = build_binary_op (MODIFY_EXPR, NULL_TREE,
					    gnu_actual, gnu_result);

	    if (EXPR_P (gnu_result))
	      set_expr_location_from_node (gnu_result, gnat_node);
	    append_to_statement_list (gnu_result, &gnu_stmt_list);
	    gnu_cico_list = TREE_CHAIN (gnu_cico_list);
	    gnu_name_list = TREE_CHAIN (gnu_name_list);
	  }
    }

  /* If this is a function call, the result is the call expression unless a
     target is specified, in which case we copy the result into the target
     and return the assignment statement.  */
  if (function_call)
    {
      /* If this is a function with copy-in/copy-out parameters, extract the
	 return value from it and update the return type.  */
      if (TYPE_CI_CO_LIST (gnu_subprog_type))
	{
	  tree gnu_elmt = TYPE_CI_CO_LIST (gnu_subprog_type);
	  gnu_call
	    = build_component_ref (gnu_call, TREE_PURPOSE (gnu_elmt), false);
	  gnu_result_type = TREE_TYPE (gnu_call);
	}

      /* If the function returns by direct reference, we have to dereference
	 the pointer.  */
      if (TYPE_RETURN_BY_DIRECT_REF_P (gnu_subprog_type))
	gnu_call = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_call);

      if (gnu_target)
	{
	  Node_Id gnat_parent = Parent (gnat_node);
	  enum tree_code op_code;

	  gigi_checking_assert (!Do_Range_Check (gnat_node));

	  /* If the parent is an initialization statement, we can use the
	     return slot optimization.  */
	  if (Nkind (gnat_parent) == N_Assignment_Statement
	      && (No_Ctrl_Actions (gnat_parent)
		  || No_Finalize_Actions (gnat_parent)))
	    op_code = INIT_EXPR;

	  /* ??? If the return type has variable size, then force the return
	     slot optimization as we would not be able to create a temporary.
	     That's what has been done historically.  */
	  else if (return_type_with_variable_size_p (gnu_result_type))
	    op_code = INIT_EXPR;

	  /* If this is a call to a pure function returning an array of scalar
	     type, try to apply the return slot optimization.  */
	  else if ((TYPE_READONLY (gnu_subprog_type)
		    || TYPE_RESTRICT (gnu_subprog_type))
		   && is_array_of_scalar_type (gnu_result_type)
		   && TYPE_MODE (gnu_result_type) == BLKmode
		   && aggregate_value_p (gnu_result_type, gnu_subprog_type)
		   && return_slot_opt_for_pure_call_p (gnu_target, gnu_call))
	    op_code = INIT_EXPR;

	  /* If this is the initialization of a return object in a function
	     returning by invisible reference, we can always use the return
	     slot optimization.  */
	  else if (TREE_CODE (gnu_target) == INDIRECT_REF
		   && TREE_CODE (TREE_OPERAND (gnu_target, 0)) == RESULT_DECL
		   && current_function_decl
		   && TREE_ADDRESSABLE (TREE_TYPE (current_function_decl)))
	    op_code = INIT_EXPR;

	  else
	    op_code = MODIFY_EXPR;

	  /* Use the required method to move the result to the target.  */
	  if (atomic_access == OUTER_ATOMIC)
	    gnu_call
	      = build_load_modify_store (gnu_target, gnu_call, gnat_node);
	  else if (atomic_access == SIMPLE_ATOMIC)
	    gnu_call = build_atomic_store (gnu_target, gnu_call, atomic_sync);
	  else if (Present (gnat_smo)
		   && Present (Storage_Model_Copy_To (gnat_smo)))
	    gnu_call
	      = build_storage_model_store (gnat_smo, gnu_target, gnu_call);
	  else
	    gnu_call
	      = build_binary_op (op_code, NULL_TREE, gnu_target, gnu_call);

	  if (EXPR_P (gnu_call))
	    set_expr_location_from_node (gnu_call, gnat_parent);
	  append_to_statement_list (gnu_call, &gnu_stmt_list);
	}
      else
	*gnu_result_type_p = get_unpadded_type (Etype (gnat_node));
    }

  /* Otherwise, if this is a procedure call statement without copy-in/copy-out
     parameters, the result is just the call statement.  */
  else if (!TYPE_CI_CO_LIST (gnu_subprog_type))
    append_to_statement_list (gnu_call, &gnu_stmt_list);

  /* Finally, add the copy back statements, if any.  */
  append_to_statement_list (gnu_after_list, &gnu_stmt_list);

  if (went_into_elab_proc)
    current_function_decl = NULL_TREE;

  /* If we have pushed a binding level, pop it and finish up the enclosing
     statement group.  */
  if (pushed_binding_level)
    {
      add_stmt (gnu_stmt_list);
      gnat_poplevel ();
      gnu_result = end_stmt_group ();
    }

  /* Otherwise, retrieve the statement list, if any.  */
  else if (gnu_stmt_list)
    gnu_result = gnu_stmt_list;

  /* Otherwise, just return the call expression.  */
  else
    return gnu_call;

  /* If we nevertheless need a value, make a COMPOUND_EXPR to return it.
     But first simplify if we have only one statement in the list.  */
  if (returning_value)
    {
      tree first = expr_first (gnu_result), last = expr_last (gnu_result);
      if (first == last)
	gnu_result = first;
      gnu_result
	= build_compound_expr (TREE_TYPE (gnu_call), gnu_result, gnu_call);
    }

  return gnu_result;
}

/* Subroutine of gnat_to_gnu to translate GNAT_NODE, an
   N_Handled_Sequence_Of_Statements, to a GCC tree, which is returned.  */

static tree
Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
{
  /* If just annotating, ignore all EH and cleanups.  */
  const bool eh
    = !type_annotate_only && Present (Exception_Handlers (gnat_node));
  const bool at_end = !type_annotate_only && Present (At_End_Proc (gnat_node));
  tree gnu_result;
  Node_Id gnat_temp;

  /* The exception handling mechanism can handle both ZCX and SJLJ schemes, and
     is exposed through the TRY_CATCH_EXPR construct that we build manually.

     ??? The region level calls down there have been specifically put in place
     for a ZCX context and currently the order in which things are emitted
     (region/handlers) is different from the SJLJ case.  Instead of putting
     other calls with different conditions at other places for the SJLJ case,
     it seems cleaner to reorder things for the SJLJ case and generalize the
     condition to make it not ZCX specific.  */

  /* First build the tree for the statements inside the sequence.  */
  start_stmt_group ();

  for (gnat_temp = First (Statements (gnat_node));
       Present (gnat_temp);
       gnat_temp = Next (gnat_temp))
    add_stmt (gnat_to_gnu (gnat_temp));

  gnu_result = end_stmt_group ();

  /* Then process the exception handlers, if any.  */
  if (eh)
    {
      tree gnu_handlers;
      location_t locus;

      /* First make a group containing the handlers.  */
      start_stmt_group ();
      for (gnat_temp = First_Non_Pragma (Exception_Handlers (gnat_node));
	   Present (gnat_temp);
	   gnat_temp = Next_Non_Pragma (gnat_temp))
	add_stmt (gnat_to_gnu (gnat_temp));
      gnu_handlers = end_stmt_group ();

      /* Now make the TRY_CATCH_EXPR for the group.  */
      gnu_result
	= build2 (TRY_CATCH_EXPR, void_type_node, gnu_result, gnu_handlers);

      /* Set a location.  We need to find a unique location for the dispatching
	 code, otherwise we can get coverage or debugging issues.  Try with
	 the location of the end label.  */
      if (Present (End_Label (gnat_node))
	  && Sloc_to_locus (Sloc (End_Label (gnat_node)), &locus))
	SET_EXPR_LOCATION (gnu_result, locus);
      else
        /* Clear column information so that the exception handler of an
           implicit transient block does not incorrectly inherit the slocs
           of a decision, which would otherwise confuse control flow based
           coverage analysis tools.  */
	set_expr_location_from_node (gnu_result, gnat_node, true);
    }

  if (Present (Finally_Statements (gnat_node)))
    {
      tree finally_stmts;
      location_t locus;

      start_stmt_group ();
      for (gnat_temp = First_Non_Pragma (Finally_Statements (gnat_node));
           Present (gnat_temp);
           gnat_temp = Next_Non_Pragma (gnat_temp))
        add_stmt (gnat_to_gnu (gnat_temp));
      finally_stmts = end_stmt_group ();

      gnu_result
        = build2 (TRY_FINALLY_EXPR, void_type_node, gnu_result, finally_stmts);

      /* Do as above for the TRY_CATCH_EXPR case.  */
      if (Present (End_Label (gnat_node))
          && Sloc_to_locus (Sloc (End_Label (gnat_node)), &locus))
        SET_EXPR_LOCATION (gnu_result, locus);
      else
        set_expr_location_from_node (gnu_result, gnat_node, true);
    }

  /* Process the At_End_Proc, if any.  */
  if (at_end)
    {
      start_stmt_group ();
      add_stmt (gnu_result);
      At_End_Proc_to_gnu (gnat_node);
      gnu_result = end_stmt_group ();
    }

  return gnu_result;
}

/* Return true if no statement in GNAT_LIST can alter the control flow.  */

static bool
stmt_list_cannot_alter_control_flow_p (List_Id gnat_list)
{
  if (No (gnat_list))
    return true;

  /* This is very conservative, we reject everything except for simple
     assignments between identifiers or literals.  */
  for (Node_Id gnat_node = First (gnat_list);
       Present (gnat_node);
       gnat_node = Next (gnat_node))
    {
      if (Nkind (gnat_node) != N_Assignment_Statement)
	return false;

      if (Nkind (Name (gnat_node)) != N_Identifier)
	return false;

      Node_Kind nkind = Nkind (Expression (gnat_node));
      if (nkind != N_Identifier
	  && nkind != N_Integer_Literal
	  && nkind != N_Real_Literal)
	return false;
    }

  return true;
}

/* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Exception_Handler,
   to a GCC tree, which is returned.  */

static tree
Exception_Handler_to_gnu (Node_Id gnat_node)
{
  tree gnu_etypes_list = NULL_TREE;

  /* We build a TREE_LIST of nodes representing what exception types this
     handler can catch, with special cases for others and all others cases.

     Each exception type is actually identified by a pointer to the exception
     id, or to a dummy object for "others" and "all others".  */
  for (Node_Id gnat_temp = First (Exception_Choices (gnat_node));
       gnat_temp;
       gnat_temp = Next (gnat_temp))
    {
      tree gnu_expr, gnu_etype;

      if (Nkind (gnat_temp) == N_Others_Choice)
	{
	  gnu_expr = All_Others (gnat_temp) ? all_others_decl : others_decl;
	  gnu_etype = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr);
	}
      else if (Nkind (gnat_temp) == N_Identifier
	       || Nkind (gnat_temp) == N_Expanded_Name)
	{
	  Entity_Id gnat_ex_id = Entity (gnat_temp);

	  /* Exception may be a renaming.  Recover original exception which is
	     the one elaborated and registered.  */
	  if (Present (Renamed_Object (gnat_ex_id)))
	    gnat_ex_id = Renamed_Object (gnat_ex_id);

	  gnu_expr = gnat_to_gnu_entity (gnat_ex_id, NULL_TREE, false);
	  gnu_etype = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr);
	}
      else
	gcc_unreachable ();

      /* The GCC interface expects NULL to be passed for catch all handlers, so
	 it would be quite tempting to set gnu_etypes_list to NULL if gnu_etype
	 is integer_zero_node.  It would not work, however, because GCC's
	 notion of "catch all" is stronger than our notion of "others".  Until
	 we correctly use the cleanup interface as well, doing that would
	 prevent the "all others" handlers from being seen, because nothing
	 can be caught beyond a catch all from GCC's point of view.  */
      gnu_etypes_list = tree_cons (NULL_TREE, gnu_etype, gnu_etypes_list);
    }

  start_stmt_group ();

  /* Expand a call to the begin_handler hook at the beginning of the
     handler, and arrange for a call to the end_handler hook to occur
     on every possible exit path.  GDB sets a breakpoint in the
     begin_handler for catchpoints.

     A v1 begin handler saves the cleanup from the exception object,
     and marks the exception as in use, so that it will not be
     released by other handlers.  A v1 end handler restores the
     cleanup and releases the exception object, unless it is still
     claimed, or the exception is being propagated (reraised).

     __builtin_eh_pointer references the exception occurrence being
     handled or propagated.  Within the handler region, it is the
     former, but within the else branch of the EH_ELSE_EXPR, i.e. the
     exceptional cleanup path, it is the latter, so we must save the
     occurrence being handled early on, so that, should an exception
     be (re)raised, we can release the current exception, or figure
     out we're not to release it because we're propagating a reraise
     thereof.

     We use local variables to retrieve the incoming value at handler
     entry time (EXPTR), the saved cleanup (EXCLN) and the token
     (EXVTK), and reuse them to feed the end_handler hook's argument
     at exit.  */

  /* CODE: void *EXPTR = __builtin_eh_pointer (0); */
  tree gnu_current_exc_ptr
    = build_call_expr (builtin_decl_explicit (BUILT_IN_EH_POINTER),
		       1, integer_zero_node);
  tree exc_ptr
    = create_var_decl (get_identifier ("EXPTR"), NULL_TREE,
		       ptr_type_node, gnu_current_exc_ptr,
		       true, false, false, false, false, false, true, true,
		       NULL, gnat_node);

  tree prev_gnu_incoming_exc_ptr = gnu_incoming_exc_ptr;
  gnu_incoming_exc_ptr = exc_ptr;

  /* begin_handler_decl must not throw, so we can use it as an
     initializer for a variable used in cleanups.

     CODE: void *EXCLN = __gnat_begin_handler_v1 (EXPTR); */
  tree exc_cleanup
    = create_var_decl (get_identifier ("EXCLN"), NULL_TREE,
		       ptr_type_node,
		       build_call_n_expr (begin_handler_decl, 1,
					  exc_ptr),
		       true, false, false, false, false, false,
		       true, true, NULL, gnat_node);

  /* Declare and initialize the choice parameter, if present.  */
  if (Present (Choice_Parameter (gnat_node)))
    {
      tree gnu_param
	= gnat_to_gnu_entity (Choice_Parameter (gnat_node), NULL_TREE, true);

      /* CODE: __gnat_set_exception_parameter (&choice_param, EXPTR); */
      add_stmt (build_call_n_expr
		(set_exception_parameter_decl, 2,
		 build_unary_op (ADDR_EXPR, NULL_TREE, gnu_param),
		 gnu_incoming_exc_ptr));
    }

  /* CODE: <handler proper> */
  add_stmt_list (Statements (gnat_node));

  tree call = build_call_n_expr (end_handler_decl, 3,
				 exc_ptr,
				 exc_cleanup,
				 null_pointer_node);
  /* If the handler can only end by falling off the end, don't bother
     with cleanups.  */
  if (stmt_list_cannot_alter_control_flow_p (Statements (gnat_node)))
    /* CODE: __gnat_end_handler_v1 (EXPTR, EXCLN, NULL);  */
    add_stmt_with_node (call, gnat_node);
  /* Otherwise, all of the above is after
     CODE: try {

     The call above will appear after
     CODE: } finally {

     And the code below will appear after
     CODE: } else {

     The else block to a finally block is taken instead of the finally
     block when an exception propagates out of the try block.  */
  else
    {
      start_stmt_group ();

      /* CODE: void *EXPRP = __builtin_eh_handler (0); */
      tree prop_ptr
	= create_var_decl (get_identifier ("EXPRP"), NULL_TREE,
			   ptr_type_node,
			   build_call_expr (builtin_decl_explicit
					    (BUILT_IN_EH_POINTER),
					    1, integer_zero_node),
			   true, false, false, false, false, false,
			   true, true, NULL, gnat_node);

      /* CODE: __gnat_end_handler_v1 (EXPTR, EXCLN, EXPRP);  */
      tree ecall = build_call_n_expr (end_handler_decl, 3,
				      exc_ptr,
				      exc_cleanup,
				      prop_ptr);

      add_stmt_with_node (ecall, gnat_node);

      /* CODE: } */
      tree eblk = end_stmt_group ();
      tree ehls = build2 (EH_ELSE_EXPR, void_type_node, call, eblk);
      add_cleanup (ehls, gnat_node);
    }

  gnu_incoming_exc_ptr = prev_gnu_incoming_exc_ptr;

  return
    build2 (CATCH_EXPR, void_type_node, gnu_etypes_list, end_stmt_group ());
}

/* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Compilation_Unit.  */

static void
Compilation_Unit_to_gnu (Node_Id gnat_node)
{
  const Node_Id gnat_unit = Unit (gnat_node);
  const bool body_p = (Nkind (gnat_unit) == N_Package_Body
		       || Nkind (gnat_unit) == N_Subprogram_Body);
  const Entity_Id gnat_unit_entity = Defining_Entity (gnat_unit);
  Entity_Id gnat_entity;
  Node_Id gnat_pragma, gnat_iter;
  /* Make the decl for the elaboration procedure.  Emit debug info for it, so
     that users can break into their elaboration code in debuggers.  Kludge:
     don't consider it as a definition so that we have a line map for its
     body, but no subprogram description in debug info.  In addition, don't
     qualify it as artificial, even though it is not a user subprogram per se,
     in particular for specs.  Unlike, say, clones created internally by the
     compiler, this subprogram materializes specific user code and flagging it
     artificial would take elab code away from gcov's analysis.  */
  tree gnu_elab_proc_decl
    = create_subprog_decl
      (create_concat_name (gnat_unit_entity, body_p ? "elabb" : "elabs"),
       NULL_TREE, void_ftype, NULL_TREE,
       is_default, true, false, false, false, true, false, NULL, gnat_unit);
  struct elab_info *info;

  vec_safe_push (gnu_elab_proc_stack, gnu_elab_proc_decl);
  DECL_ELABORATION_PROC_P (gnu_elab_proc_decl) = 1;

  /* Initialize the information structure for the function.  */
  allocate_struct_function (gnu_elab_proc_decl, false);
  set_cfun (NULL);

  current_function_decl = NULL_TREE;

  start_stmt_group ();
  gnat_pushlevel ();

  /* For a body, first process the spec if there is one.  */
  if (Nkind (gnat_unit) == N_Package_Body
      || (Nkind (gnat_unit) == N_Subprogram_Body && !Acts_As_Spec (gnat_node)))
    add_stmt (gnat_to_gnu (Library_Unit (gnat_node)));

  if (type_annotate_only && gnat_node == Cunit (Main_Unit))
    {
      elaborate_all_entities (gnat_node);

      if (Nkind (gnat_unit) == N_Subprogram_Declaration
	  || Nkind (gnat_unit) == N_Generic_Package_Declaration
	  || Nkind (gnat_unit) == N_Generic_Subprogram_Declaration)
	return;
    }

  /* Then process any pragmas and declarations preceding the unit.  */
  for (gnat_pragma = First (Context_Items (gnat_node));
       Present (gnat_pragma);
       gnat_pragma = Next (gnat_pragma))
    if (Nkind (gnat_pragma) == N_Pragma
	|| Nkind (gnat_pragma) == N_With_Clause
	|| Nkind (gnat_pragma) == N_Use_Package_Clause)
      add_stmt (gnat_to_gnu (gnat_pragma));
  process_decls (Declarations (Aux_Decls_Node (gnat_node)), Empty,
		 true, true);

  /* Process the unit itself.  */
  add_stmt (gnat_to_gnu (gnat_unit));

  /* Generate code for all the inlined subprograms.  */
  for (gnat_entity = First_Inlined_Subprogram (gnat_node);
       Present (gnat_entity);
       gnat_entity = Next_Inlined_Subprogram (gnat_entity))
    {
      Node_Id gnat_body;

      /* Without optimization, process only the required subprograms.  */
      if (!optimize && !Has_Pragma_Inline_Always (gnat_entity))
	continue;

      /* The set of inlined subprograms is computed from data recorded early
	 during expansion and it can be a strict superset of the final set
	 computed after semantic analysis, for example if a call to such a
	 subprogram occurs in a pragma Assert and assertions are disabled.
	 In that case, semantic analysis resets Is_Public to false but the
	 entry for the subprogram in the inlining tables is stalled.  */
      if (!Is_Public (gnat_entity))
	continue;

      gnat_body = Parent (Declaration_Node (gnat_entity));
      if (Nkind (gnat_body) != N_Subprogram_Body)
	{
	  /* ??? This happens when only the spec of a package is provided.  */
	  if (No (Corresponding_Body (gnat_body)))
	    continue;

	  gnat_body
	    = Parent (Declaration_Node (Corresponding_Body (gnat_body)));
	}

      /* Define the entity first so we set DECL_EXTERNAL.  */
      gnat_to_gnu_entity (gnat_entity, NULL_TREE, false);
      add_stmt (gnat_to_gnu (gnat_body));
    }

  /* Process any pragmas and actions following the unit.  */
  add_stmt_list (Pragmas_After (Aux_Decls_Node (gnat_node)));
  add_stmt_list (Actions (Aux_Decls_Node (gnat_node)));
  finalize_from_limited_with ();

  /* Then process the expressions of pragma Compile_Time_{Error|Warning} to
     annotate types referenced therein if they have not been annotated.  */
  for (int i = 0; gnat_compile_time_expr_list.iterate (i, &gnat_iter); i++)
    (void) gnat_to_gnu_external (gnat_iter);
  gnat_compile_time_expr_list.release ();

  /* Save away what we've made so far and finish it up.  */
  set_current_block_context (gnu_elab_proc_decl);
  gnat_poplevel ();
  DECL_SAVED_TREE (gnu_elab_proc_decl) = end_stmt_group ();
  set_end_locus_from_node (gnu_elab_proc_decl, gnat_unit);
  gnu_elab_proc_stack->pop ();

  /* Record this potential elaboration procedure for later processing.  */
  info = ggc_alloc<elab_info> ();
  info->next = elab_info_list;
  info->elab_proc = gnu_elab_proc_decl;
  info->gnat_node = gnat_node;
  elab_info_list = info;

  /* Force the processing for all nodes that remain in the queue.  */
  process_deferred_decl_context (true);
}

/* Mark COND, a boolean expression, as predicating a call to a noreturn
   function, i.e. predict that it is very likely false, and return it.

   The compiler will automatically predict the last edge leading to a call
   to a noreturn function as very unlikely taken.  This function makes it
   possible to extend the prediction to predecessors in case the condition
   is made up of several short-circuit operators.  */

static tree
build_noreturn_cond (tree cond)
{
  tree pred_cst = build_int_cst (integer_type_node, PRED_NORETURN);
  return
    build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_BUILTIN_EXPECT,
				  boolean_type_node, 3, cond,
				  boolean_false_node, pred_cst);
}

/* Subroutine of gnat_to_gnu to translate GNAT_RANGE, a node representing a
   range of values, into GNU_LOW and GNU_HIGH bounds.  */

static void
Range_to_gnu (Node_Id gnat_range, tree *gnu_low, tree *gnu_high)
{
  /* GNAT_RANGE is either an N_Range or an identifier denoting a subtype.  */
  switch (Nkind (gnat_range))
    {
    case N_Range:
      *gnu_low = gnat_to_gnu (Low_Bound (gnat_range));
      *gnu_high = gnat_to_gnu (High_Bound (gnat_range));
      break;

    case N_Expanded_Name:
    case N_Identifier:
      {
	tree gnu_range_type = get_unpadded_type (Entity (gnat_range));
	tree gnu_range_base_type = get_base_type (gnu_range_type);

	*gnu_low
	  = convert (gnu_range_base_type, TYPE_MIN_VALUE (gnu_range_type));
	*gnu_high
	  = convert (gnu_range_base_type, TYPE_MAX_VALUE (gnu_range_type));
      }
      break;

    default:
      gcc_unreachable ();
    }
}

/* Subroutine of gnat_to_gnu to translate GNAT_NODE, an N_Raise_xxx_Error,
   to a GCC tree,  which is returned.  GNU_RESULT_TYPE_P is a pointer to
   where we should place the result type.  */

static tree
Raise_Error_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
{
  const Node_Kind kind = Nkind (gnat_node);
  const Node_Id gnat_cond = Condition (gnat_node);
  const int reason = UI_To_Int (Reason (gnat_node));
  const bool with_extra_info
    = Exception_Extra_Info
      && !No_Exception_Handlers_Set ()
      && No (get_exception_label (kind));
  tree gnu_result = NULL_TREE, gnu_cond = NULL_TREE;
  Node_Id gnat_rcond;

  /* The following processing is not required for correctness.  Its purpose is
     to give more precise error messages and to record some information.  */
  switch (reason)
    {
    case CE_Access_Check_Failed:
      if (with_extra_info)
	gnu_result = build_call_raise_column (reason, gnat_node, kind);
      break;

    case CE_Index_Check_Failed:
    case CE_Range_Check_Failed:
    case CE_Invalid_Data:
      if (No (gnat_cond) || Nkind (gnat_cond) != N_Op_Not)
	break;
      gnat_rcond = Right_Opnd (gnat_cond);
      if (Nkind (gnat_rcond) == N_In
	  || Nkind (gnat_rcond) == N_Op_Ge
	  || Nkind (gnat_rcond) == N_Op_Le)
	{
	  const Node_Id gnat_index = Left_Opnd (gnat_rcond);
	  const Node_Id gnat_type = Etype (gnat_index);
	  tree gnu_index = gnat_to_gnu (gnat_index);
	  tree gnu_type = get_unpadded_type (gnat_type);
	  tree gnu_low_bound, gnu_high_bound, disp;
	  struct loop_info_d *loop;
	  bool neg_p;

	  switch (Nkind (gnat_rcond))
	    {
	    case N_In:
	      Range_to_gnu (Right_Opnd (gnat_rcond),
			    &gnu_low_bound, &gnu_high_bound);
	      break;

	    case N_Op_Ge:
	      gnu_low_bound = gnat_to_gnu (Right_Opnd (gnat_rcond));
	      gnu_high_bound = TYPE_MAX_VALUE (gnu_type);
	      break;

	    case N_Op_Le:
	      gnu_low_bound = TYPE_MIN_VALUE (gnu_type);
	      gnu_high_bound = gnat_to_gnu (Right_Opnd (gnat_rcond));
	      break;

	    default:
	      gcc_unreachable ();
	    }

	  gnu_type = maybe_character_type (gnu_type);
	  if (TREE_TYPE (gnu_index) != gnu_type)
	    {
	      gnu_low_bound = convert (gnu_type, gnu_low_bound);
	      gnu_high_bound = convert (gnu_type, gnu_high_bound);
	      gnu_index = convert (gnu_type, gnu_index);
	    }

	  /* Do not print the range information for an enumeration type with
	     holes since it is meaningless.  */
	  if (with_extra_info
	      && !(Nkind (gnat_index) == N_Function_Call
		   && Is_Entity_Name (Name (gnat_index))
		   && Is_Rep_To_Pos (Entity (Name (gnat_index))))
	      && Known_Esize (gnat_type)
	      && UI_To_Int (Esize (gnat_type)) <= 32)
	    gnu_result
	      = build_call_raise_range (reason, gnat_node, kind, gnu_index,
					gnu_low_bound, gnu_high_bound);

	  /* If optimization is enabled and we are inside a loop, we try to
	     compute invariant conditions for checks applied to the iteration
	     variable, i.e. conditions that are independent of the variable
	     and necessary in order for the checks to fail in the course of
	     some iteration.  If we succeed, we consider an alternative:

	       1. If loop unswitching is enabled, we prepend these conditions
		  to the original conditions of the checks.  This will make it
		  possible for the loop unswitching pass to replace the loop
		  with two loops, one of which has the checks eliminated and
		  the other has the original checks reinstated, and a prologue
		  implementing a run-time selection.  The former loop will be
		  for example suitable for vectorization.

	       2. Otherwise, we instead append the conditions to the original
		  conditions of the checks.  At worse, if the conditions cannot
		  be evaluated at compile time, they will be evaluated as true
		  at run time only when the checks have already failed, thus
		  contributing negatively only to the size of the executable.
		  But the hope is that these invariant conditions be evaluated
		  at compile time to false, thus taking away the entire checks
		  with them.  */
	  if (optimize
	      && inside_loop_p ()
	      && (!gnu_low_bound
		  || (gnu_low_bound = gnat_invariant_expr (gnu_low_bound)))
	      && (!gnu_high_bound
		  || (gnu_high_bound = gnat_invariant_expr (gnu_high_bound)))
	      && (loop = find_loop_for (gnu_index, &disp, &neg_p)))
	    {
	      struct range_check_info_d *rci = ggc_alloc<range_check_info_d> ();
	      rci->low_bound = gnu_low_bound;
	      rci->high_bound = gnu_high_bound;
	      rci->disp = disp;
	      rci->neg_p = neg_p;
	      rci->type = gnu_type;
	      rci->inserted_cond
		= build1 (SAVE_EXPR, boolean_type_node, boolean_true_node);
	      vec_safe_push (loop->checks, rci);
	      gnu_cond = build_noreturn_cond (gnat_to_gnu (gnat_cond));
	      if (optimize >= 3)
		gnu_cond = build_binary_op (TRUTH_ANDIF_EXPR,
					    boolean_type_node,
					    rci->inserted_cond,
					    gnu_cond);
	      else
		gnu_cond = build_binary_op (TRUTH_ANDIF_EXPR,
					    boolean_type_node,
					    gnu_cond,
					    rci->inserted_cond);
	    }
	}
      break;

    default:
      break;
    }

  /* The following processing does the real work, but we must nevertheless make
     sure not to override the result of the previous processing.  */
  if (!gnu_result)
    gnu_result = build_call_raise (reason, gnat_node, kind);
  set_expr_location_from_node (gnu_result, gnat_node);

  *gnu_result_type_p = get_unpadded_type (Etype (gnat_node));

  /* If the type is VOID, this is a statement, so we need to generate the code
     for the call.  Handle a condition, if there is one.  */
  if (VOID_TYPE_P (*gnu_result_type_p))
    {
      if (Present (gnat_cond))
	{
	  if (!gnu_cond)
	    gnu_cond = gnat_to_gnu (gnat_cond);
	  if (integer_zerop (gnu_cond))
	    return alloc_stmt_list ();
	  gnu_result = build3 (COND_EXPR, void_type_node, gnu_cond, gnu_result,
			       alloc_stmt_list ());
	}
    }
  else
    {
      /* The condition field must not be present when the node is used as an
	 expression form.  */
      gigi_checking_assert (No (gnat_cond));
      gnu_result = build1 (NULL_EXPR, *gnu_result_type_p, gnu_result);
    }

  return gnu_result;
}

/* Return true if GNAT_NODE is on the LHS of an assignment or an actual
   parameter of a call.  */

static bool
lhs_or_actual_p (Node_Id gnat_node)
{
  const Node_Id gnat_parent = Parent (gnat_node);
  const Node_Kind kind = Nkind (gnat_parent);

  if (kind == N_Assignment_Statement && Name (gnat_parent) == gnat_node)
    return true;

  if ((kind == N_Procedure_Call_Statement || kind == N_Function_Call)
      && Name (gnat_parent) != gnat_node)
    return true;

  if (kind == N_Parameter_Association)
    return true;

  return false;
}

/* Return true if either GNAT_NODE or a view of GNAT_NODE is on the LHS
   of an assignment or an actual parameter of a call.  */

static bool
present_in_lhs_or_actual_p (Node_Id gnat_node)
{
  return lhs_or_actual_p (gnat_node)
	 || (node_is_type_conversion (Parent (gnat_node))
	     && lhs_or_actual_p (Parent (gnat_node)));
}

/* Return true if GNAT_NODE, an unchecked type conversion, is a no-op as far
   as gigi is concerned.  This is used to avoid conversions on the LHS.  */

static bool
unchecked_conversion_nop (Node_Id gnat_node)
{
  Entity_Id from_type, to_type;

  /* The conversion must be on the LHS of an assignment or an actual parameter
     of a call.  Otherwise, even if the conversion was essentially a no-op, it
     could de facto ensure type consistency and this should be preserved.  */
  if (!lhs_or_actual_p (gnat_node))
    return false;

  from_type = Etype (Expression (gnat_node));

  /* We're interested in artificial conversions generated by the front-end
     to make private types explicit, e.g. in Expand_Assign_Array.  */
  if (!Is_Private_Type (from_type))
    return false;

  from_type = Underlying_Type (from_type);
  to_type = Etype (gnat_node);

  /* The direct conversion to the underlying type is a no-op.  */
  if (to_type == from_type)
    return true;

  /* For an array subtype, the conversion to the PAIT is a no-op.  */
  if (Ekind (from_type) == E_Array_Subtype
      && to_type == Packed_Array_Impl_Type (from_type))
    return true;

  /* For a record subtype, the conversion to the type is a no-op.  */
  if (Ekind (from_type) == E_Record_Subtype
      && to_type == Etype (from_type))
    return true;

  return false;
}

/* Return true if GNAT_NODE represents a statement.  */

static bool
statement_node_p (Node_Id gnat_node)
{
  const Node_Kind kind = Nkind (gnat_node);

  if (kind == N_Label)
    return true;

  if (IN (kind, N_Statement_Other_Than_Procedure_Call))
    return true;

  if (kind == N_Procedure_Call_Statement)
    return true;

  if (IN (kind, N_Raise_xxx_Error) && Ekind (Etype (gnat_node)) == E_Void)
    return true;

  return false;
}

/* Get or create the namespace NAME.  FULL_NAME is the full name of
   the namespace, for instance "outer__inner" -- this is needed
   because there's only a single level hash table storing all
   namespaces.  GNAT_NODE is used for context and passed to
   gnat_pushdecl.  GNU_CONTEXT is the outer namespace, or NULL_TREE if
   there is not one.  */

static tree
get_or_create_namespace (const char *name, const char *full_name,
			 Node_Id gnat_node, tree gnu_context)
{
  if (namespace_map == nullptr)
    namespace_map = hash_map<tree, tree>::create_ggc ();
  tree full_id = get_identifier (full_name);
  tree *value = namespace_map->get (full_id);
  if (value != nullptr)
    return *value;

  tree id = get_identifier (name);
  tree result = build_decl (input_location, NAMESPACE_DECL, id,
			    void_type_node);
  namespace_map->put (full_id, result);
  gnat_pushdecl (result, gnat_node);
  DECL_CONTEXT (result) = gnu_context;
  return result;
}

/* Create namespace decls from GNAT_NAME.  GNAT_NODE is used for
   context and passed to gnat_pushdecl, if a new namespace decl is
   created.  GNAT_NAME can be a fully-qualified series of namespaces
   (e.g., "outer__inner"); the innermost decl is returned.

   If GNU_ORIG is non-NULL, then the new namespace will be a renaming
   of GNU_ORIG.  That is, the final "namespace" created will actually
   be an IMPORTED_DECL rather than a NAMESPACE_DECL.  */

static tree
get_namespace (Node_Id gnat_name, Node_Id gnat_node, tree gnu_orig = NULL_TREE)
{
  if (Is_Entity_Name (gnat_name))
    gnat_name = Entity (gnat_name);

  gcc_assert (Nkind (gnat_name) == N_Defining_Identifier);

  if (Ekind (gnat_name) == E_Void)
    return NULL_TREE;

  /* This loop takes an encoded name and then successively handles
     prefixes, making a namespace decl for each one.  E.g., for
     "outer__middle__inner", it will first handle "outer", then
     "outer__middle" (creating the namespace "middle" with a
     DECL_CONTEXT of "outer"), and then finally
     "outer__middle__inner".  FULL_STR always points to the start of
     the name, while STR points to just the final component.  */
  char *str = Get_Name_String (Chars (gnat_name));
  const char *full_str = str;
  tree outer = NULL_TREE;
  tree result = NULL_TREE;
  while (str != nullptr)
    {
      char *delim = strstr (str, "__");
      if (delim != nullptr)
	*delim = '\0';

      size_t len = strlen (str);
      char *e_ptr = nullptr;
      if (len > 2 && strcmp (str + len - 2, "_E") == 0)
	{
	  e_ptr = str + len - 2;
	  *e_ptr = '\0';
	}

      outer = result;
      if (delim == nullptr && gnu_orig != NULL_TREE)
	{
	  result = build_decl (input_location, IMPORTED_DECL,
			       get_identifier (str), void_type_node);
	  IMPORTED_DECL_ASSOCIATED_DECL (result) = gnu_orig;
	}
      else
	result = get_or_create_namespace (str, full_str, gnat_node, outer);

      /* Restore the text.  */
      if (e_ptr != nullptr)
	*e_ptr = '_';
      if (delim == nullptr)
	str = nullptr;
      else
	{
	  *delim = '_';
	  str = delim + 2;
	}
    }

  return result;
}


/* This function is the driver of the GNAT to GCC tree transformation process.
   It is the entry point of the tree transformer.  GNAT_NODE is the root of
   some GNAT tree.  Return the root of the corresponding GCC tree.  If this
   is an expression, return the GCC equivalent of the expression.  If this
   is a statement, return the statement or add it to the current statement
   group, in which case anything returned is to be interpreted as occurring
   after anything added.  */

tree
gnat_to_gnu (Node_Id gnat_node)
{
  const Node_Kind kind = Nkind (gnat_node);
  tree gnu_result = error_mark_node; /* Default to no value.  */
  tree gnu_result_type = void_type_node;
  tree gnu_expr, gnu_lhs, gnu_rhs;
  Node_Id gnat_temp;
  atomic_acces_t aa_type;
  bool went_into_elab_proc;
  bool aa_sync;
  Entity_Id gnat_smo;

  /* Save node number for error message and set location information.  */
  if (Sloc (gnat_node) > No_Location)
    Current_Error_Node = gnat_node;
  Sloc_to_locus (Sloc (gnat_node), &input_location);

  /* If we are only annotating types and this node is a statement, return
     an empty statement list.  */
  if (type_annotate_only && statement_node_p (gnat_node))
    return alloc_stmt_list ();

  /* If we are only annotating types and this node is a subexpression, return
     a NULL_EXPR, but filter out nodes appearing in the expressions attached
     to packed array implementation types.  */
  if (type_annotate_only
      && IN (kind, N_Subexpr)
      && !(((IN (kind, N_Op) && kind != N_Op_Expon)
	    || kind == N_Type_Conversion)
	   && Is_Integer_Type (Etype (gnat_node)))
      && !(kind == N_Attribute_Reference
	   && (Get_Attribute_Id (Attribute_Name (gnat_node)) == Attr_Length
	       || Get_Attribute_Id (Attribute_Name (gnat_node)) == Attr_Size)
	   && Is_Constrained (Etype (Prefix (gnat_node)))
	   && !Is_Constr_Subt_For_U_Nominal (Etype (Prefix (gnat_node))))
      && kind != N_Expanded_Name
      && kind != N_Identifier
      && !Compile_Time_Known_Value (gnat_node))
    return build1 (NULL_EXPR, get_unpadded_type (Etype (gnat_node)),
		   build_call_raise (CE_Range_Check_Failed, gnat_node,
				     N_Raise_Constraint_Error));

  /* If this is a statement and we are at top level, it must be part of the
     elaboration procedure, so mark us as being in that procedure.  */
  if ((statement_node_p (gnat_node)
       || kind == N_Handled_Sequence_Of_Statements
       || kind == N_Implicit_Label_Declaration)
      && !current_function_decl)
    {
      current_function_decl = get_elaboration_procedure ();
      went_into_elab_proc = true;
    }
  else
    went_into_elab_proc = false;

  switch (kind)
    {
      /********************************/
      /* Chapter 2: Lexical Elements  */
      /********************************/

    case N_Identifier:
    case N_Expanded_Name:
    case N_Operator_Symbol:
    case N_Defining_Identifier:
    case N_Defining_Operator_Symbol:
      gnu_result = Identifier_to_gnu (gnat_node, &gnu_result_type);

      /* If atomic access is required on the RHS, build the atomic load.  */
      if (simple_atomic_access_required_p (gnat_node, &aa_sync)
	  && !present_in_lhs_or_actual_p (gnat_node))
	gnu_result = build_atomic_load (gnu_result, aa_sync);
      break;

    case N_External_Initializer:
      {
	gnu_result_type = get_unpadded_type (Etype (gnat_node));
	struct c_array a = C_Source_Buffer (File_Index (gnat_node));

	gnu_result = build_string ((unsigned) a.length, a.pointer);

	TREE_TYPE (gnu_result) = gnu_result_type;
      }
      break;

    case N_Integer_Literal:
      {
	tree gnu_type;

	/* Get the type of the result, looking inside any padding and
	   justified modular types.  Then get the value in that type.  */
	gnu_type = gnu_result_type = get_unpadded_type (Etype (gnat_node));

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

	gnu_result = UI_To_gnu (Intval (gnat_node), gnu_type);

	/* If the result overflows (meaning it doesn't fit in its base type),
	   abort, unless this is for a named number because that's not fatal.
	   We would like to check that the value is within the range of the
	   subtype, but that causes problems with subtypes whose usage will
	   raise Constraint_Error and also with biased representation.  */
	if (TREE_OVERFLOW (gnu_result))
	  {
	    if (Nkind (Parent (gnat_node)) == N_Number_Declaration)
	      gnu_result = error_mark_node;
	    else
	      gcc_unreachable ();
	  }
      }
      break;

    case N_Character_Literal:
      /* If a Entity is present, it means that this was one of the
	 literals in a user-defined character type.  In that case,
	 just return the value in the CONST_DECL.  Otherwise, use the
	 character code.  In that case, the base type should be an
	 INTEGER_TYPE, but we won't bother checking for that.  */
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      if (Present (Entity (gnat_node)))
	gnu_result = DECL_INITIAL (get_gnu_tree (Entity (gnat_node)));
      else
	gnu_result
	  = build_int_cst (gnu_result_type,
			   UI_To_CC (Char_Literal_Value (gnat_node)));
      break;

    case N_Real_Literal:
      gnu_result_type = get_unpadded_type (Etype (gnat_node));

      /* If this is of a fixed-point type, the value we want is the value of
	 the corresponding integer.  */
      if (Is_Fixed_Point_Type (Underlying_Type (Etype (gnat_node))))
	{
	  gnu_result = UI_To_gnu (Corresponding_Integer_Value (gnat_node),
				  gnu_result_type);
	  gcc_assert (!TREE_OVERFLOW (gnu_result));
	}

      else
	{
	  Ureal ur_realval = Realval (gnat_node);

	  /* First convert the value to a machine number if it isn't already.
	     That will force the base to 2 for non-zero values and simplify
	     the rest of the logic.  */
	  if (!Is_Machine_Number (gnat_node))
	    ur_realval
	      = Machine (Base_Type (Underlying_Type (Etype (gnat_node))),
			 ur_realval, Round_Even, gnat_node);

	  if (UR_Is_Zero (ur_realval))
	    gnu_result = build_real (gnu_result_type, dconst0);
	  else
	    {
	      REAL_VALUE_TYPE tmp;

	      gnu_result = UI_To_gnu (Numerator (ur_realval), gnu_result_type);

	      /* The base must be 2 as Machine guarantees this, so we scale
		 the value, which we know can fit in the mantissa of the type
		 (hence the use of that type above).  */
	      gcc_assert (Rbase (ur_realval) == 2);
	      real_ldexp (&tmp, &TREE_REAL_CST (gnu_result),
			  - UI_To_Int (Denominator (ur_realval)));
	      gnu_result = build_real (gnu_result_type, tmp);
	    }

	  /* Now see if we need to negate the result.  Do it this way to
	     properly handle -0.  */
	  if (UR_Is_Negative (Realval (gnat_node)))
	    gnu_result
	      = build_unary_op (NEGATE_EXPR, get_base_type (gnu_result_type),
				gnu_result);
	}

      break;

    case N_String_Literal:
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      if (TYPE_PRECISION (TREE_TYPE (gnu_result_type)) == HOST_BITS_PER_CHAR)
	{
	  String_Id gnat_string = Strval (gnat_node);
	  int length = String_Length (gnat_string);
	  int i;
	  char *string;
	  if (length >= ALLOCA_THRESHOLD)
	    string = XNEWVEC (char, length);
	  else
	    string = (char *) alloca (length);

	  /* Build the string with the characters in the literal.  Note
	     that Ada strings are 1-origin.  */
	  for (i = 0; i < length; i++)
	    string[i] = Get_String_Char (gnat_string, i + 1);

	  gnu_result = build_string (length, string);

	  /* Strings in GCC don't normally have types, but we want
	     this to not be converted to the array type.  */
	  TREE_TYPE (gnu_result) = gnu_result_type;

	  if (length >= ALLOCA_THRESHOLD)
	    free (string);
	}
      else
	{
	  /* Build a list consisting of each character, then make
	     the aggregate.  */
	  String_Id gnat_string = Strval (gnat_node);
	  int length = String_Length (gnat_string);
	  int i;
	  tree gnu_idx = TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_result_type));
	  tree gnu_one_node = convert (TREE_TYPE (gnu_idx), integer_one_node);
	  vec<constructor_elt, va_gc> *gnu_vec;
	  vec_alloc (gnu_vec, length);

	  for (i = 0; i < length; i++)
	    {
	      tree t = build_int_cst (TREE_TYPE (gnu_result_type),
				      Get_String_Char (gnat_string, i + 1));

	      CONSTRUCTOR_APPEND_ELT (gnu_vec, gnu_idx, t);
	      gnu_idx = int_const_binop (PLUS_EXPR, gnu_idx, gnu_one_node);
	    }

	  gnu_result = gnat_build_constructor (gnu_result_type, gnu_vec);
	}
      break;

    case N_Pragma:
      gnu_result = Pragma_to_gnu (gnat_node);
      break;

    /**************************************/
    /* Chapter 3: Declarations and Types  */
    /**************************************/

    case N_Subtype_Declaration:
    case N_Full_Type_Declaration:
    case N_Incomplete_Type_Declaration:
    case N_Private_Type_Declaration:
    case N_Private_Extension_Declaration:
    case N_Task_Type_Declaration:
      process_type (Defining_Entity (gnat_node));
      gnu_result = alloc_stmt_list ();
      break;

    case N_Object_Declaration:
    case N_Number_Declaration:
    case N_Exception_Declaration:
      gnat_temp = Defining_Entity (gnat_node);
      gnu_result = alloc_stmt_list ();

      /* If we are just annotating types and this object has an unconstrained
	 or task type, don't elaborate it.   */
      if (type_annotate_only
	  && (((Is_Array_Type (Etype (gnat_temp))
		|| Is_Record_Type (Etype (gnat_temp)))
	       && !Is_Constrained (Etype (gnat_temp)))
	      || Is_Concurrent_Type (Etype (gnat_temp))))
	break;

      /* If this is a constant related to a return initialized by a reference
	 to a function call in a function returning by invisible reference:

	   type Ann is access all Result_Type;
	   Rnn : constant Ann := Func'reference;
	   [...]
	   return Rnn.all;

	 then elide the temporary by forwarding the return object to Func:

	   result_type *Rnn = (result_type *) <retval>;
	   *<retval> = Func (); [return slot optimization]
	   [...]
	   return Rnn;

	 That's necessary if the result type needs finalization because the
	 temporary would never be adjusted as Expand_Simple_Function_Return
	 also elides the temporary in this case.  */
      if (Ekind (gnat_temp) == E_Constant
	  && Is_Related_To_Func_Return (gnat_temp)
	  && Nkind (Expression (gnat_node)) == N_Reference
	  && Nkind (Prefix (Expression (gnat_node))) == N_Function_Call
	  && current_function_decl
	  && TREE_ADDRESSABLE (TREE_TYPE (current_function_decl)))
	{
	  gnat_to_gnu_entity (gnat_temp,
			      DECL_RESULT (current_function_decl),
			      true);
	  gnu_result
	    = build_unary_op (INDIRECT_REF, NULL_TREE,
			      DECL_RESULT (current_function_decl));
	  gnu_result
	    = Call_to_gnu (Prefix (Expression (gnat_node)),
			   &gnu_result_type, gnu_result,
			   NOT_ATOMIC, false, Empty);
	  break;
	}

      if (Present (Expression (gnat_node))
	  && !(kind == N_Object_Declaration && No_Initialization (gnat_node))
	  && (!type_annotate_only
	      || Compile_Time_Known_Value (Expression (gnat_node))))
	{
	  gigi_checking_assert (!Do_Range_Check (Expression (gnat_node)));

	  gnu_expr = gnat_to_gnu (Expression (gnat_node));

	  /* First deal with erroneous expressions.  */
	  if (TREE_CODE (gnu_expr) == ERROR_MARK)
	    {
	      /* If this is a named number for which we cannot manipulate
		 the value, just skip the declaration altogether.  */
	      if (kind == N_Number_Declaration)
		break;
	      else if (type_annotate_only)
		gnu_expr = NULL_TREE;
	    }

	  /* Then a special case: we do not want the SLOC of the expression
	     of the tag to pop up every time it is referenced somewhere.  */
	  else if (EXPR_P (gnu_expr) && Is_Tag (gnat_temp))
	    SET_EXPR_LOCATION (gnu_expr, UNKNOWN_LOCATION);
	}
      else
	gnu_expr = NULL_TREE;

      /* If this is a deferred constant with an address clause, we ignore the
	 full view since the clause is on the partial view and we cannot have
	 2 different GCC trees for the object.  The only bits of the full view
	 we will use is the initializer, but it will be directly fetched.  */
      if (Ekind (gnat_temp) == E_Constant
	  && Present (Address_Clause (gnat_temp))
	  && Present (Full_View (gnat_temp)))
	save_gnu_tree (Full_View (gnat_temp), error_mark_node, true);

      /* If this object has its elaboration delayed, we must force evaluation
	 of GNU_EXPR now and save it for the freeze point.  Note that we need
	 not do anything special at the global level since the lifetime of the
	 temporary is fully contained within the elaboration routine.  */
      if (Present (Freeze_Node (gnat_temp)))
	{
	  if (gnu_expr)
	    {
	      gnu_result = gnat_save_expr (gnu_expr);
	      save_gnu_tree (gnat_node, gnu_result, true);
	    }
	}
      else
	gnat_to_gnu_entity (gnat_temp, gnu_expr, true);
      break;

    case N_Object_Renaming_Declaration:
      gnat_temp = Defining_Entity (gnat_node);
      gnu_result = alloc_stmt_list ();

      /* Don't do anything if this renaming is handled by the front end and it
	 does not need debug info.  Note that we consider renamings don't need
	 debug info when optimizing: our way to describe them has a
	 memory/elaboration footprint.

	 Don't do anything neither if we are just annotating types and this
	 object has a composite or task type, don't elaborate it.  */
      if ((!Is_Renaming_Of_Object (gnat_temp)
	   || (Needs_Debug_Info (gnat_temp)
	       && !optimize
	       && can_materialize_object_renaming_p
		    (Renamed_Object (gnat_temp))))
	  && ! (type_annotate_only
		&& (Is_Array_Type (Etype (gnat_temp))
		    || Is_Record_Type (Etype (gnat_temp))
		    || Is_Concurrent_Type (Etype (gnat_temp)))))
	{
	  gnu_expr = gnat_to_gnu (Renamed_Object (gnat_temp));

	  /* The elaboration of object renamings present in the source code
	     never needs to be deferred.  But regular objects may be turned
	     into renamings during expansion and their elaboration may need
	     to be deferred, in which case we expect the renamed references
	     to have been stabilized, so we do not do it again here.  */
	  if (Present (Freeze_Node (gnat_temp)))
	    {
	      gcc_assert (!Comes_From_Source (gnat_node));
	      save_gnu_tree (gnat_node, gnu_expr, true);
	    }
	  else
	    gnat_to_gnu_entity (gnat_temp, gnu_expr, true);
	}
      break;

    case N_Exception_Renaming_Declaration:
      gnat_temp = Defining_Entity (gnat_node);
      gnu_result = alloc_stmt_list ();

      if (Present (Renamed_Entity (gnat_temp)))
	gnat_to_gnu_entity (gnat_temp,
			    gnat_to_gnu (Renamed_Entity (gnat_temp)),
			    true);
      break;

    case N_Subprogram_Renaming_Declaration:
      {
	const Node_Id gnat_renaming = Defining_Entity (gnat_node);
	const Node_Id gnat_renamed = Renamed_Entity (gnat_renaming);

	gnu_result = alloc_stmt_list ();

	/* Materializing renamed subprograms will only benefit the debugging
	   information as they aren't referenced in the generated code.  So
	   skip them when they aren't needed.  Avoid doing this if:

	     - there is a freeze node: in this case the renamed entity is not
	       elaborated yet,
	     - the renamed subprogram is intrinsic: it will not be available in
	       the debugging information (note that both or only one of the
	       renaming and the renamed subprograms can be intrinsic).  */
	if (!type_annotate_only
	    && Needs_Debug_Info (gnat_renaming)
	    && No (Freeze_Node (gnat_renaming))
	    && Present (gnat_renamed)
	    && (Ekind (gnat_renamed) == E_Function
		|| Ekind (gnat_renamed) == E_Procedure)
	    && !Is_Intrinsic_Subprogram (gnat_renaming)
	    && !Is_Intrinsic_Subprogram (gnat_renamed))
	  gnat_to_gnu_entity (gnat_renaming, gnat_to_gnu (gnat_renamed), true);
	break;
      }

    case N_Implicit_Label_Declaration:
      gnat_to_gnu_entity (Defining_Entity (gnat_node), NULL_TREE, true);
      gnu_result = alloc_stmt_list ();
      break;

    case N_Package_Renaming_Declaration:
      if (gnat_encodings == DWARF_GNAT_ENCODINGS_ALL)
	gnu_result = alloc_stmt_list ();
      else
	{
	  tree orig_ns = get_namespace (Entity (Name (gnat_node)),
					Name (gnat_node));
	  Node_Id name = Defining_Unit_Name (gnat_node);
	  if (Nkind (name) == N_Defining_Program_Unit_Name)
	    name = Defining_Identifier (name);
	  gnu_result = get_namespace (name, gnat_node, orig_ns);
	}
      break;

    /*************************************/
    /* Chapter 4: Names and Expressions  */
    /*************************************/

    case N_Explicit_Dereference:
      /* Make sure the designated type is complete before dereferencing.  */
      if (Is_Extended_Access_Type (Etype (Prefix (gnat_node)))
	  && !Is_Constrained (Etype (gnat_node)))
        gnu_result_type = get_unpadded_extended_type (Etype (gnat_node));
      else
        gnu_result_type = get_unpadded_type (Etype (gnat_node));

      gnu_result = gnat_to_gnu (Prefix (gnat_node));
      gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result);

      /* If atomic access is required on the RHS, build the atomic load.  */
      if (simple_atomic_access_required_p (gnat_node, &aa_sync)
	  && !present_in_lhs_or_actual_p (gnat_node))
	gnu_result = build_atomic_load (gnu_result, aa_sync);

      /* If storage model access is required on the RHS, build the load.  */
      else if (storage_model_access_required_p (gnat_node, &gnat_smo)
	       && Present (Storage_Model_Copy_From (gnat_smo))
	       && !present_in_lhs_or_actual_p (gnat_node))
	gnu_result = build_storage_model_load (gnat_smo, gnu_result);
      break;

    case N_Indexed_Component:
      {
	const Entity_Id gnat_array_object = Prefix (gnat_node);
	tree gnu_array_object = gnat_to_gnu (gnat_array_object);
	tree gnu_type;
	int ndim, i;
	Node_Id *gnat_expr_array;

	/* Get the storage model of the array.  */
	gnat_smo = get_storage_model (gnat_array_object);

	gnu_array_object = maybe_padded_object (gnu_array_object);
	gnu_array_object = maybe_unconstrained_array (gnu_array_object);

	/* Convert vector inputs to their representative array type, to fit
	   what the code below expects.  */
	if (VECTOR_TYPE_P (TREE_TYPE (gnu_array_object)))
	  {
	    if (present_in_lhs_or_actual_p (gnat_node))
	      gnat_mark_addressable (gnu_array_object);
	    gnu_array_object = maybe_vector_array (gnu_array_object);
	  }

	/* The failure of this assertion will very likely come from a missing
	   expansion for a packed array access.  */
	gcc_assert (TREE_CODE (TREE_TYPE (gnu_array_object)) == ARRAY_TYPE);

	/* First compute the number of dimensions of the array, then
	   fill the expression array, the order depending on whether
	   this is a Convention_Fortran array or not.  */
	for (ndim = 1, gnu_type = TREE_TYPE (gnu_array_object);
	     TREE_CODE (TREE_TYPE (gnu_type)) == ARRAY_TYPE
	     && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_type));
	     ndim++, gnu_type = TREE_TYPE (gnu_type))
	  ;

	gnat_expr_array = XALLOCAVEC (Node_Id, ndim);

	if (TYPE_CONVENTION_FORTRAN_P (TREE_TYPE (gnu_array_object)))
	  for (i = ndim - 1, gnat_temp = First (Expressions (gnat_node));
	       i >= 0;
	       i--, gnat_temp = Next (gnat_temp))
	    gnat_expr_array[i] = gnat_temp;
	else
	  for (i = 0, gnat_temp = First (Expressions (gnat_node));
	       i < ndim;
	       i++, gnat_temp = Next (gnat_temp))
	    gnat_expr_array[i] = gnat_temp;

	/* Start with the prefix and build the successive references.  */
	gnu_result = gnu_array_object;

	for (i = 0, gnu_type = TREE_TYPE (gnu_array_object);
	     i < ndim;
	     i++, gnu_type = TREE_TYPE (gnu_type))
	  {
	    gcc_assert (TREE_CODE (gnu_type) == ARRAY_TYPE);
	    gnat_temp = gnat_expr_array[i];
	    gnu_expr = maybe_character_value (gnat_to_gnu (gnat_temp));

	    gnu_result
	      = build_binary_op (ARRAY_REF, NULL_TREE, gnu_result, gnu_expr);

	    if (Present (gnat_smo)
	        && Present (Storage_Model_Copy_From (gnat_smo)))
	      instantiate_load_in_array_ref (gnu_result, gnat_smo);
	  }

	gnu_result_type = get_unpadded_type (Etype (gnat_node));

	/* If atomic access is required on the RHS, build the atomic load.  */
	if (simple_atomic_access_required_p (gnat_node, &aa_sync)
	    && !present_in_lhs_or_actual_p (gnat_node))
	  gnu_result = build_atomic_load (gnu_result, aa_sync);

	/* If storage model access is required on the RHS, build the load.  */
	else if (storage_model_access_required_p (gnat_node, &gnat_smo)
		 && Present (Storage_Model_Copy_From (gnat_smo))
		 && !present_in_lhs_or_actual_p (gnat_node))
	  gnu_result = build_storage_model_load (gnat_smo, gnu_result);
      }
      break;

    case N_Slice:
      {
	const Entity_Id gnat_array_object = Prefix (gnat_node);
	tree gnu_array_object = gnat_to_gnu (gnat_array_object);

	/* Get the storage model of the array.  */
	gnat_smo = get_storage_model (gnat_array_object);

	gnu_array_object = maybe_padded_object (gnu_array_object);
	gnu_array_object = maybe_unconstrained_array (gnu_array_object);

	gnu_result_type = get_unpadded_type (Etype (gnat_node));

	gnu_expr = TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_result_type));
	gnu_expr = maybe_character_value (gnu_expr);

	/* If this is a slice with non-constant size of an array with constant
	   size, set the maximum size for the allocation of temporaries.  */
	if (!TREE_CONSTANT (TYPE_SIZE_UNIT (gnu_result_type))
	    && TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (gnu_array_object))))
	  TYPE_ARRAY_MAX_SIZE (gnu_result_type)
	    = TYPE_SIZE_UNIT (TREE_TYPE (gnu_array_object));

	gnu_result = build_binary_op (ARRAY_RANGE_REF, gnu_result_type,
				      gnu_array_object, gnu_expr);

	if (Present (gnat_smo)
	    && Present (Storage_Model_Copy_From (gnat_smo)))
	  instantiate_load_in_array_ref (gnu_result, gnat_smo);

	/* If storage model access is required on the RHS, build the load.  */
	if (storage_model_access_required_p (gnat_node, &gnat_smo)
	    && Present (Storage_Model_Copy_From (gnat_smo))
	    && !present_in_lhs_or_actual_p (gnat_node))
	  gnu_result = build_storage_model_load (gnat_smo, gnu_result);
      }
      break;

    case N_Selected_Component:
      {
	const Entity_Id gnat_prefix = Prefix (gnat_node);
	Entity_Id gnat_field = Entity (Selector_Name (gnat_node));
	tree gnu_prefix = gnat_to_gnu (gnat_prefix);

	gnu_prefix = maybe_padded_object (gnu_prefix);

	/* gnat_to_gnu_entity does not save the GNU tree made for renamed
	   discriminants so avoid making recursive calls on each reference
	   to them by following the appropriate link directly here.  */
	if (Ekind (gnat_field) == E_Discriminant)
	  {
	    /* For discriminant references in tagged types always substitute
	       the corresponding discriminant as the actual component.  */
	    if (Is_Tagged_Type (Underlying_Type (Etype (gnat_prefix))))
	      while (Present (Corresponding_Discriminant (gnat_field)))
		gnat_field = Corresponding_Discriminant (gnat_field);

	    /* For discriminant references in untagged types always substitute
	       the corresponding stored discriminant.  */
	    else if (Present (Corresponding_Discriminant (gnat_field)))
	      gnat_field = Original_Record_Component (gnat_field);
	  }

	/* Handle extracting the real or imaginary part of a complex.
	   The real part is the first field and the imaginary the last.  */
	if (TREE_CODE (TREE_TYPE (gnu_prefix)) == COMPLEX_TYPE)
	  gnu_result = build_unary_op (Present (Next_Entity (gnat_field))
				       ? REALPART_EXPR : IMAGPART_EXPR,
				       NULL_TREE, gnu_prefix);
	else
	  {
	    tree gnu_field = gnat_to_gnu_field_decl (gnat_field);
	    tree gnu_offset;
	    struct loop_info_d *loop;

	    gnu_result
	      = build_component_ref (gnu_prefix, gnu_field,
				     (Nkind (Parent (gnat_node))
				      == N_Attribute_Reference)
				     && lvalue_required_for_attribute_p
					(Parent (gnat_node)));

	    /* If optimization is enabled and we are inside a loop, we try to
	       hoist nonconstant but invariant offset computations outside of
	       the loop, since they very likely contain loads that could turn
	       out to be hard to move if they end up in active EH regions.  */
	    if (optimize
		&& inside_loop_p ()
		&& TREE_CODE (gnu_result) == COMPONENT_REF
		&& (gnu_offset = component_ref_field_offset (gnu_result))
		&& !TREE_CONSTANT (gnu_offset)
		&& (gnu_offset = gnat_invariant_expr (gnu_offset))
		&& (loop = find_loop ()))
	      {
		tree invariant
		  = build1 (SAVE_EXPR, TREE_TYPE (gnu_offset), gnu_offset);
		vec_safe_push (loop->invariants, invariant);
		tree field = TREE_OPERAND (gnu_result, 1);
		tree factor
		  = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
		/* Divide the offset by its alignment.  */
		TREE_OPERAND (gnu_result, 2)
		  = size_binop (EXACT_DIV_EXPR, invariant, factor);
	      }
	  }

	gnu_result_type = get_unpadded_type (Etype (gnat_node));

	/* If atomic access is required on the RHS, build the atomic load.  */
	if (simple_atomic_access_required_p (gnat_node, &aa_sync)
	    && !present_in_lhs_or_actual_p (gnat_node))
	  gnu_result = build_atomic_load (gnu_result, aa_sync);

	/* If storage model access is required on the RHS, build the load.  */
	else if (storage_model_access_required_p (gnat_node, &gnat_smo)
		 && Present (Storage_Model_Copy_From (gnat_smo))
		 && !present_in_lhs_or_actual_p (gnat_node))
	  gnu_result = build_storage_model_load (gnat_smo, gnu_result);
      }
      break;

    case N_Attribute_Reference:
      {
	/* The attribute designator.  */
	const Attribute_Id attr = Get_Attribute_Id (Attribute_Name (gnat_node));

	/* The Elab_Spec and Elab_Body attributes are special in that Prefix
	   is a unit, not an object with a GCC equivalent.  */
	if (attr == Attr_Elab_Spec || attr == Attr_Elab_Body)
	  return
	    create_subprog_decl (create_concat_name
				 (Entity (Prefix (gnat_node)),
				  attr == Attr_Elab_Body ? "elabb" : "elabs"),
				 NULL_TREE, void_ftype, NULL_TREE, is_default,
				 true, false, true, true, true, false, NULL,
				 gnat_node);

	gnu_result = Attribute_to_gnu (gnat_node, &gnu_result_type, attr);
      }
      break;

    case N_Reference:
      /* Like 'Access as far as we are concerned.  */
      gnu_result = gnat_to_gnu (Prefix (gnat_node));
      gnu_result = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_result);
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      break;

    case N_Aggregate:
    case N_Extension_Aggregate:
      {
	tree gnu_aggr_type;

	/* Check that this aggregate has not slipped through the cracks.  */
	gcc_assert (!Expansion_Delayed (gnat_node));

	gnu_result_type = get_unpadded_type (Etype (gnat_node));

	if (TREE_CODE (gnu_result_type) == RECORD_TYPE
	    && TYPE_CONTAINS_TEMPLATE_P (gnu_result_type))
	  gnu_aggr_type
	    = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_result_type)));
	else if (VECTOR_TYPE_P (gnu_result_type))
	  gnu_aggr_type = TYPE_REPRESENTATIVE_ARRAY (gnu_result_type);
	else
	  gnu_aggr_type = gnu_result_type;

	if (Null_Record_Present (gnat_node))
	  gnu_result = gnat_build_constructor (gnu_aggr_type, NULL);

	else if (TREE_CODE (gnu_aggr_type) == RECORD_TYPE
		 || TREE_CODE (gnu_aggr_type) == UNION_TYPE)
	  gnu_result
	    = assoc_to_constructor (Etype (gnat_node),
				    First (Component_Associations (gnat_node)),
				    gnu_aggr_type);
	else if (TREE_CODE (gnu_aggr_type) == ARRAY_TYPE)
	  gnu_result = pos_to_constructor (First (Expressions (gnat_node)),
					   gnu_aggr_type);
	else if (TREE_CODE (gnu_aggr_type) == COMPLEX_TYPE)
	  gnu_result
	    = build_binary_op
	      (COMPLEX_EXPR, gnu_aggr_type,
	       gnat_to_gnu (Expression (First
					(Component_Associations (gnat_node)))),
	       gnat_to_gnu (Expression
			    (Next
			     (First (Component_Associations (gnat_node))))));
	else
	  gcc_unreachable ();

	gnu_result = convert (gnu_result_type, gnu_result);
      }
      break;

    case N_Null:
      if (TARGET_VTABLE_USES_DESCRIPTORS
	  && Ekind (Etype (gnat_node)) == E_Access_Subprogram_Type
	  && Is_Dispatch_Table_Entity (Etype (gnat_node)))
	gnu_result = null_fdesc_node;
      else
	gnu_result = null_pointer_node;
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      break;

    case N_Type_Conversion:
    case N_Qualified_Expression:
      gnu_expr = maybe_character_value (gnat_to_gnu (Expression (gnat_node)));
      gnu_result_type = get_unpadded_type (Etype (gnat_node));

      /* If this is a qualified expression for a tagged type, we mark the type
	 as used.  Because of polymorphism, this might be the only reference to
	 the tagged type in the program while objects have it as dynamic type.
	 The debugger needs to see it to display these objects properly.  */
      if (kind == N_Qualified_Expression && Is_Tagged_Type (Etype (gnat_node)))
	used_types_insert (gnu_result_type);

      gigi_checking_assert (!Do_Range_Check (Expression (gnat_node)));

      gnu_result
	= convert_with_check (Etype (gnat_node), gnu_expr,
			      Do_Overflow_Check (gnat_node),
			      kind == N_Type_Conversion
			      && Float_Truncate (gnat_node), gnat_node);
      break;

    case N_Unchecked_Type_Conversion:
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      gnu_expr = maybe_character_value (gnat_to_gnu (Expression (gnat_node)));

      /* Skip further processing if the conversion is deemed a no-op.  */
      if (unchecked_conversion_nop (gnat_node))
	{
	  gnu_result = gnu_expr;
	  gnu_result_type = TREE_TYPE (gnu_result);
	  break;
	}

      /* If the result is a pointer type, see if we are improperly
	 converting to a stricter alignment.  */
      if (STRICT_ALIGNMENT && POINTER_TYPE_P (gnu_result_type)
	  && Is_Access_Type (Etype (gnat_node)))
	{
	  unsigned int align = known_alignment (gnu_expr);
	  tree gnu_obj_type = TREE_TYPE (gnu_result_type);
	  unsigned int oalign = TYPE_ALIGN (gnu_obj_type);

	  /* Skip tagged types because conversions to the class-wide type are
	     translated into conversions to the root type, which may be less
	     aligned than some of its derived types.  */
	  if (align != 0
	      && align < oalign
	      && !type_is_tagged_or_cw_equivalent (gnu_obj_type))
	    post_error_ne_tree_2
	      ("??source alignment (^) '< alignment of & (^)",
	       gnat_node, Designated_Type (Etype (gnat_node)),
	       size_int (align / BITS_PER_UNIT), oalign / BITS_PER_UNIT);
	}

      /* If we are converting a descriptor to a function pointer, first
	 build the pointer.  */
      if (TARGET_VTABLE_USES_DESCRIPTORS
	  && TREE_TYPE (gnu_expr) == fdesc_type_node
	  && POINTER_TYPE_P (gnu_result_type))
	gnu_expr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr);

      gnu_result = unchecked_convert (gnu_result_type, gnu_expr,
				      No_Truncation (gnat_node));
      break;

    case N_In:
    case N_Not_In:
      {
	tree gnu_obj = gnat_to_gnu (Left_Opnd (gnat_node));
	tree gnu_low, gnu_high;

	Range_to_gnu (Right_Opnd (gnat_node), &gnu_low, &gnu_high);
	gnu_result_type = get_unpadded_type (Etype (gnat_node));

	tree gnu_op_type = maybe_character_type (TREE_TYPE (gnu_obj));
	if (TREE_TYPE (gnu_obj) != gnu_op_type)
	  {
	    gnu_obj = convert (gnu_op_type, gnu_obj);
	    gnu_low = convert (gnu_op_type, gnu_low);
	    gnu_high = convert (gnu_op_type, gnu_high);
	  }

	/* If LOW and HIGH are identical, perform an equality test.  Otherwise,
	   ensure that GNU_OBJ is evaluated only once and perform a full range
	   test.  */
	if (operand_equal_p (gnu_low, gnu_high, 0))
	  gnu_result
	    = build_binary_op (EQ_EXPR, gnu_result_type, gnu_obj, gnu_low);
	else
	  {
	    tree t1, t2;
	    gnu_obj = gnat_protect_expr (gnu_obj);
	    t1 = build_binary_op (GE_EXPR, gnu_result_type, gnu_obj, gnu_low);
	    if (EXPR_P (t1))
	      set_expr_location_from_node (t1, gnat_node);
	    t2 = build_binary_op (LE_EXPR, gnu_result_type, gnu_obj, gnu_high);
	    if (EXPR_P (t2))
	      set_expr_location_from_node (t2, gnat_node);
	    gnu_result
	      = build_binary_op (TRUTH_ANDIF_EXPR, gnu_result_type, t1, t2);
	  }

	if (kind == N_Not_In)
	  gnu_result
	    = invert_truthvalue_loc (EXPR_LOCATION (gnu_result), gnu_result);
      }
      break;

    case N_Op_Divide:
      gnu_lhs = gnat_to_gnu (Left_Opnd (gnat_node));
      gnu_rhs = gnat_to_gnu (Right_Opnd (gnat_node));
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      gnu_result = build_binary_op (FLOAT_TYPE_P (gnu_result_type)
				    ? RDIV_EXPR
				    : (Rounded_Result (gnat_node)
				       ? ROUND_DIV_EXPR : TRUNC_DIV_EXPR),
				    gnu_result_type, gnu_lhs, gnu_rhs);
      /* If the result type is larger than a word, then declare the dependence
	 on the libgcc routine.  */
      if (INTEGRAL_TYPE_P (gnu_result_type)
	  && TYPE_PRECISION (gnu_result_type) > BITS_PER_WORD)
	Check_Restriction_No_Dependence_On_System (Name_Gcc, gnat_node);
      break;

    case N_Op_Eq:
    case N_Op_Ne:
    case N_Op_Lt:
    case N_Op_Le:
    case N_Op_Gt:
    case N_Op_Ge:
    case N_Op_Add:
    case N_Op_Subtract:
    case N_Op_Multiply:
    case N_Op_Mod:
    case N_Op_Rem:
    case N_Op_Rotate_Left:
    case N_Op_Rotate_Right:
    case N_Op_Shift_Left:
    case N_Op_Shift_Right:
    case N_Op_Shift_Right_Arithmetic:
    case N_Op_And:
    case N_Op_Or:
    case N_Op_Xor:
    case N_And_Then:
    case N_Or_Else:
      {
	enum tree_code code = gnu_codes[kind];
	bool ignore_lhs_overflow = false;
	location_t saved_location = input_location;
	tree gnu_type, gnu_max_shift = NULL_TREE;

	/* Fix operations set up for boolean types in GNU_CODES above.  */
	if (Is_Modular_Integer_Type (Underlying_Type (Etype (gnat_node))))
	  switch (kind)
	    {
	    case N_Op_And:
	      code = BIT_AND_EXPR;
	      break;
	    case N_Op_Or:
	      code = BIT_IOR_EXPR;
	      break;
	    case N_Op_Xor:
	      code = BIT_XOR_EXPR;
	      break;
	    default:
	      break;
	    }

	gnu_lhs = gnat_to_gnu (Left_Opnd (gnat_node));
	gnu_rhs = gnat_to_gnu (Right_Opnd (gnat_node));
	gnu_type = gnu_result_type = get_unpadded_type (Etype (gnat_node));

	/* If this is a shift, take the count as unsigned since that is what
	   most machines do and will generate simpler adjustments below.  */
	if (IN (kind, N_Op_Shift))
	  {
	    tree gnu_count_type
	      = gnat_unsigned_type_for (get_base_type (TREE_TYPE (gnu_rhs)));
	    gnu_rhs = convert (gnu_count_type, gnu_rhs);
	    gnu_max_shift
	      = convert (TREE_TYPE (gnu_rhs), TYPE_SIZE (gnu_type));
	    /* If the result type is larger than a word, then declare the
	       dependence on the libgcc routine.  */
	    if (TYPE_PRECISION (gnu_type) > BITS_PER_WORD)
	      Check_Restriction_No_Dependence_On_System (Name_Gcc, gnat_node);
	  }

	/* If this is a comparison between (potentially) large aggregates, then
	   declare the dependence on the memcmp routine.  */
	else if ((kind == N_Op_Eq || kind == N_Op_Ne)
		 && AGGREGATE_TYPE_P (TREE_TYPE (gnu_lhs))
		 && (!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_lhs)))
		     || compare_tree_int (TYPE_SIZE (TREE_TYPE (gnu_lhs)),
					  2 * BITS_PER_WORD) > 0))
	  Check_Restriction_No_Dependence_On_System (Name_Memory_Compare,
						     gnat_node);

	/* If this is a modulo/remainder and the result type is larger than a
	   word, then declare the dependence on the libgcc routine.  */
	else if ((kind == N_Op_Mod ||kind == N_Op_Rem)
		 && TYPE_PRECISION (gnu_type) > BITS_PER_WORD)
	  Check_Restriction_No_Dependence_On_System (Name_Gcc, gnat_node);

	/* Pending generic support for efficient vector logical operations in
	   GCC, convert vectors to their representative array type view.  */
	gnu_lhs = maybe_vector_array (gnu_lhs);
	gnu_rhs = maybe_vector_array (gnu_rhs);

	/* If this is a comparison operator, convert any references to an
	   unconstrained array value into a reference to the actual array.  */
	if (TREE_CODE_CLASS (code) == tcc_comparison)
	  {
	    gnu_lhs = maybe_unconstrained_array (gnu_lhs);
	    gnu_rhs = maybe_unconstrained_array (gnu_rhs);

	    tree gnu_op_type = maybe_character_type (TREE_TYPE (gnu_lhs));
	    if (TREE_TYPE (gnu_lhs) != gnu_op_type)
	      {
		gnu_lhs = convert (gnu_op_type, gnu_lhs);
		gnu_rhs = convert (gnu_op_type, gnu_rhs);
	      }
	  }

	/* If this is a shift whose count is not guaranteed to be correct,
	   we need to adjust the shift count.  */
	if ((kind == N_Op_Rotate_Left || kind == N_Op_Rotate_Right)
	    && !Shift_Count_OK (gnat_node))
	  gnu_rhs = build_binary_op (TRUNC_MOD_EXPR, TREE_TYPE (gnu_rhs),
				     gnu_rhs, gnu_max_shift);
	else if (kind == N_Op_Shift_Right_Arithmetic
		 && !Shift_Count_OK (gnat_node))
	  gnu_rhs
	    = build_binary_op (MIN_EXPR, TREE_TYPE (gnu_rhs),
			       build_binary_op (MINUS_EXPR,
						TREE_TYPE (gnu_rhs),
						gnu_max_shift,
						build_int_cst
						(TREE_TYPE (gnu_rhs), 1)),
			       gnu_rhs);

	/* For right shifts, the type says what kind of shift to do,
	   so we may need to choose a different type.  In this case,
	   we have to ignore integer overflow lest it propagates all
	   the way down and causes a CE to be explicitly raised.  */
	if (kind == N_Op_Shift_Right && !TYPE_UNSIGNED (gnu_type))
	  {
	    gnu_type = gnat_unsigned_type_for (gnu_type);
	    ignore_lhs_overflow = true;
	  }
	else if (kind == N_Op_Shift_Right_Arithmetic
		 && TYPE_UNSIGNED (gnu_type))
	  {
	    gnu_type = gnat_signed_type_for (gnu_type);
	    ignore_lhs_overflow = true;
	  }

	if (gnu_type != gnu_result_type)
	  {
	    tree gnu_old_lhs = gnu_lhs;
	    gnu_lhs = convert (gnu_type, gnu_lhs);
	    if (TREE_CODE (gnu_lhs) == INTEGER_CST && ignore_lhs_overflow)
	      TREE_OVERFLOW (gnu_lhs) = TREE_OVERFLOW (gnu_old_lhs);
	    gnu_rhs = convert (gnu_type, gnu_rhs);
	    if (gnu_max_shift)
	      gnu_max_shift = convert (gnu_type, gnu_max_shift);
	  }

	/* For integer addition, subtraction and multiplication, perform an
	   overflow check if required.  */
	if ((code == PLUS_EXPR || code == MINUS_EXPR || code == MULT_EXPR)
	    && !FLOAT_TYPE_P (gnu_type)
	    && Do_Overflow_Check (gnat_node))
	  gnu_result
	    = build_binary_op_trapv (code, gnu_type, gnu_lhs, gnu_rhs,
				     gnat_node);

	  /* For an unsigned modulo operation with nonbinary constant modulus,
	     we first try to do a reduction by means of a (multiplier, shifter)
	     pair in the needed precision up to the word size.  But not when
	     optimizing for size, because it will be longer than a div+mul+sub
	     sequence.  */
	else if (!optimize_size
		 && (code == FLOOR_MOD_EXPR || code == TRUNC_MOD_EXPR)
		 && TYPE_UNSIGNED (gnu_type)
		 && TYPE_PRECISION (gnu_type) <= BITS_PER_WORD
		 && TREE_CODE (gnu_rhs) == INTEGER_CST
		 && !integer_pow2p (gnu_rhs)
		 && (gnu_expr
		     = fast_modulo_reduction (gnu_lhs, gnu_rhs,
					      TYPE_PRECISION (gnu_type))))
	  gnu_result = gnu_expr;

	else
	  {
	    /* Some operations, e.g. comparisons of arrays, generate complex
	       trees that need to be annotated while they are being built.  */
	    input_location = saved_location;
	    gnu_result = build_binary_op (code, gnu_type, gnu_lhs, gnu_rhs);
	  }

	/* If this is a logical shift with the shift count not verified,
	   we must return zero if it is too large.  We cannot compensate
	   beforehand in this case.  */
	if ((kind == N_Op_Shift_Left || kind == N_Op_Shift_Right)
	    && !Shift_Count_OK (gnat_node))
	  gnu_result
	    = build_cond_expr (gnu_type,
			       build_binary_op (GE_EXPR, boolean_type_node,
						gnu_rhs, gnu_max_shift),
			       build_int_cst (gnu_type, 0),
			       gnu_result);
      }
      break;

    case N_If_Expression:
      {
	tree gnu_cond = gnat_to_gnu (First (Expressions (gnat_node)));
	tree gnu_true = gnat_to_gnu (Next (First (Expressions (gnat_node))));
	tree gnu_false
	  = gnat_to_gnu (Next (Next (First (Expressions (gnat_node)))));

	gnu_result_type = get_unpadded_type (Etype (gnat_node));
	gnu_result
	  = build_cond_expr (gnu_result_type, gnu_cond, gnu_true, gnu_false);
      }
      break;

    case N_Op_Plus:
      gnu_result = gnat_to_gnu (Right_Opnd (gnat_node));
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      break;

    case N_Op_Not:
      /* This case can apply to a boolean or a modular type.
	 Fall through for a boolean operand since GNU_CODES is set
	 up to handle this.  */
      if (Is_Modular_Integer_Type (Underlying_Type (Etype (gnat_node))))
	{
	  gnu_expr = gnat_to_gnu (Right_Opnd (gnat_node));
	  gnu_result_type = get_unpadded_type (Etype (gnat_node));
	  gnu_result = build_unary_op (BIT_NOT_EXPR, gnu_result_type,
				       gnu_expr);
	  break;
	}

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

    case N_Op_Minus:
    case N_Op_Abs:
      gnu_expr = gnat_to_gnu (Right_Opnd (gnat_node));
      gnu_result_type = get_unpadded_type (Etype (gnat_node));

      /* For integer negation and absolute value, perform an overflow check
	 if required.  */
      if ((gnu_codes[kind] == NEGATE_EXPR || gnu_codes[kind] == ABS_EXPR)
	  && !FLOAT_TYPE_P (gnu_result_type)
	  && Do_Overflow_Check (gnat_node))
	gnu_result
	  = build_unary_op_trapv (gnu_codes[kind], gnu_result_type, gnu_expr,
				  gnat_node);
      else
	gnu_result
	  = build_unary_op (gnu_codes[kind], gnu_result_type, gnu_expr);
      break;

    case N_Allocator:
      {
	const Entity_Id gnat_desig_type
	  = Designated_Type (Underlying_Type (Etype (gnat_node)));
	const Entity_Id gnat_pool = Storage_Pool (gnat_node);

	tree gnu_type, gnu_init;
	bool ignore_init_type;

	gnat_temp = Expression (gnat_node);

	/* The expression can be either an N_Identifier or an Expanded_Name,
	   which must represent a type, or a N_Qualified_Expression, which
	   contains both the type and an initial value for the object.  */
	if (Nkind (gnat_temp) == N_Identifier
	    || Nkind (gnat_temp) == N_Expanded_Name)
	  {
	    ignore_init_type = false;
	    gnu_init = NULL_TREE;
	    gnu_type = gnat_to_gnu_type (Entity (gnat_temp));
	  }

	else if (Nkind (gnat_temp) == N_Qualified_Expression)
	  {
	    ignore_init_type = Has_Constrained_Partial_View (gnat_desig_type);

	    gnu_init = gnat_to_gnu (Expression (gnat_temp));
	    gnu_init = maybe_unconstrained_array (gnu_init);

	    gigi_checking_assert (!Do_Range_Check (Expression (gnat_temp)));

	    if (Is_Elementary_Type (gnat_desig_type)
		|| Is_Constrained (gnat_desig_type))
	      gnu_type = gnat_to_gnu_type (gnat_desig_type);
	    else
	      {
		gnu_type = gnat_to_gnu_type (Etype (Expression (gnat_temp)));
		if (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
		  gnu_type = TREE_TYPE (gnu_init);
	      }

	    /* See the N_Qualified_Expression case for the rationale.  */
	    if (Is_Tagged_Type (gnat_desig_type))
	      used_types_insert (gnu_type);

	    gnu_init = convert (gnu_type, gnu_init);
	  }
	else
	  gcc_unreachable ();

	/* If this is an array allocated with its bounds, use the thin pointer
	   as the result type to trigger the machinery in build_allocator, but
	   make sure not to do it for allocations on the return and secondary
	   stacks (see build_call_alloc_dealloc_proc for more details).  */
        if (Is_Constr_Array_Subt_With_Bounds (gnat_desig_type)
	    && Is_Record_Type (Underlying_Type (Etype (gnat_pool)))
	    && !type_annotate_only)
	  {
	    tree gnu_array = gnat_to_gnu_type (Base_Type (gnat_desig_type));
	    gnu_result_type
	      = build_pointer_type (TYPE_OBJECT_RECORD_TYPE (gnu_array));
	  }
	else
	  gnu_result_type = get_unpadded_type (Etype (gnat_node));

	return build_allocator (gnu_type, gnu_init, gnu_result_type,
				Procedure_To_Call (gnat_node),
				gnat_pool, gnat_node, ignore_init_type);
      }
      break;

    /**************************/
    /* Chapter 5: Statements  */
    /**************************/

    case N_Label:
      gnu_result = build1 (LABEL_EXPR, void_type_node,
			   gnat_to_gnu (Identifier (gnat_node)));
      break;

    case N_Null_Statement:
      /* When not optimizing, turn null statements from source into gotos to
	 the next statement that the middle-end knows how to preserve.  */
      if (!optimize && Comes_From_Source (gnat_node))
	{
	  tree stmt, label = create_label_decl (NULL_TREE, gnat_node);
	  DECL_IGNORED_P (label) = 1;
	  start_stmt_group ();
	  stmt = build1 (GOTO_EXPR, void_type_node, label);
	  set_expr_location_from_node (stmt, gnat_node);
	  add_stmt (stmt);
	  stmt = build1 (LABEL_EXPR, void_type_node, label);
	  set_expr_location_from_node (stmt, gnat_node);
	  add_stmt (stmt);
	  gnu_result = end_stmt_group ();
	}
      else
	gnu_result = alloc_stmt_list ();
      break;

    case N_Assignment_Statement:
      /* First get the LHS of the statement and convert any reference to an
	 unconstrained array into a reference to the underlying array.  */
      gnu_lhs = maybe_unconstrained_array (gnat_to_gnu (Name (gnat_node)));

      /* If the type has a size that overflows, convert this into raise of
	 Storage_Error: execution shouldn't have gotten here anyway.  */
      if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (gnu_lhs))) == INTEGER_CST
	   && !valid_constant_size_p (TYPE_SIZE_UNIT (TREE_TYPE (gnu_lhs))))
	gnu_result = build_call_raise (SE_Object_Too_Large, gnat_node,
				       N_Raise_Storage_Error);

      /* If the RHS is a function call, let Call_to_gnu do the entire work.  */
      else if (Nkind (Expression (gnat_node)) == N_Function_Call)
	{
	  get_atomic_access (Name (gnat_node), &aa_type, &aa_sync);
	  get_storage_model_access (Name (gnat_node), &gnat_smo);
	  gnu_result
	    = Call_to_gnu (Expression (gnat_node), &gnu_result_type, gnu_lhs,
			   aa_type, aa_sync, gnat_smo);
	}

      /* Otherwise we need to build the assignment statement manually.  */
      else
	{
	  const Node_Id gnat_name = Name (gnat_node);
	  const Node_Id gnat_expr = Expression (gnat_node);
	  const Node_Id gnat_inner
	    = Nkind (gnat_expr) == N_Qualified_Expression
	      ? Expression (gnat_expr)
	      : gnat_expr;
	  const Entity_Id gnat_type = Underlying_Type (Etype (gnat_name));
	  const bool use_memset_p
	    = Is_Array_Type (gnat_type)
	      && Nkind (gnat_inner) == N_Aggregate
	      && Is_Single_Aggregate (gnat_inner);

	  /* If we use memset, we need to find the innermost expression.  */
	  if (use_memset_p)
	    {
	      gnat_temp = gnat_inner;
	      do {
		gnat_temp
		  = Expression (First (Component_Associations (gnat_temp)));
	      } while (Nkind (gnat_temp) == N_Aggregate
		       && Is_Single_Aggregate (gnat_temp));
	      gnu_rhs = gnat_to_gnu (gnat_temp);
	    }

	  /* Otherwise get the RHS of the statement and do the same processing
	     as for the LHS above.  */
	  else
	    gnu_rhs = maybe_unconstrained_array (gnat_to_gnu (gnat_expr));

	  gigi_checking_assert (!Do_Range_Check (gnat_expr));

	  get_atomic_access (gnat_name, &aa_type, &aa_sync);
	  get_storage_model_access (gnat_name, &gnat_smo);

	  /* If an outer atomic access is required on the LHS, build the load-
	     modify-store sequence.  */
	  if (aa_type == OUTER_ATOMIC)
	    gnu_result = build_load_modify_store (gnu_lhs, gnu_rhs, gnat_node);

	  /* Or else, if a simple atomic access is required, build the atomic
	     store.  */
	  else if (aa_type == SIMPLE_ATOMIC)
	    gnu_result = build_atomic_store (gnu_lhs, gnu_rhs, aa_sync);

	  /* Or else, if a storage model access is required, build the special
	     store.  */
	  else if (Present (gnat_smo)
		   && Present (Storage_Model_Copy_To (gnat_smo)))
	    {
	      tree gnu_size;

	      /* We obviously cannot use memset in this case.  */
	      gcc_assert (!use_memset_p);

	      /* If this is a dereference with a special dynamic constrained
		 subtype on the node, use it to compute the size.  */
	      if (Nkind (gnat_name) == N_Explicit_Dereference
		  && Present (Actual_Designated_Subtype (gnat_name)))
		{
		  tree gnu_actual_obj_type
		    = gnat_to_gnu_type (Actual_Designated_Subtype (gnat_name));
		  gnu_size = TYPE_SIZE_UNIT (gnu_actual_obj_type);
		}
	      else
		gnu_size = NULL_TREE;

	      gnu_result
		= build_storage_model_store (gnat_smo, gnu_lhs, gnu_rhs,
					     gnu_size);
	    }

	  /* Or else, use memset when the conditions are met.  This has already
	     been validated by Aggr_Assignment_OK_For_Backend in the front-end
	     and the RHS is thus guaranteed to be of the appropriate form.  */
	  else if (use_memset_p)
	    {
	      tree value
		= real_zerop (gnu_rhs)
		  ? integer_zero_node
		  : fold_convert (integer_type_node, gnu_rhs);
	      tree dest = build_fold_addr_expr (gnu_lhs);
	      tree t = builtin_decl_explicit (BUILT_IN_MEMSET);
	      /* Be extra careful not to write too much data.  */
	      tree size;
	      if (TREE_CODE (gnu_lhs) == COMPONENT_REF)
		size = DECL_SIZE_UNIT (TREE_OPERAND (gnu_lhs, 1));
	      else if (DECL_P (gnu_lhs))
		size = DECL_SIZE_UNIT (gnu_lhs);
	      else
		size = TYPE_SIZE_UNIT (TREE_TYPE (gnu_lhs));
	      size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, gnu_lhs);
	      if (TREE_CODE (value) == INTEGER_CST && !integer_zerop (value))
		{
		  tree mask
		    = build_int_cst (integer_type_node,
				     ((HOST_WIDE_INT) 1 << BITS_PER_UNIT) - 1);
		  value = int_const_binop (BIT_AND_EXPR, value, mask);
		}
	      gnu_result = build_call_expr (t, 3, dest, value, size);
	      Check_Restriction_No_Dependence_On_System (Name_Memory_Set,
							 gnat_node);
	    }

	  else
	    {
	      tree t = remove_conversions (gnu_rhs, false);

	      /* If a storage model load is present on the RHS, then elide the
		 temporary associated with it.  */
	      if (TREE_CODE (t) == LOAD_EXPR)
		{
		  gnu_result = TREE_OPERAND (t, 1);
		  gcc_assert (TREE_CODE (gnu_result) == CALL_EXPR);

		  tree arg = CALL_EXPR_ARG (gnu_result, 1);
		  CALL_EXPR_ARG (gnu_result, 1)
		    = build_unary_op (ADDR_EXPR, TREE_TYPE (arg), gnu_lhs);
		}

	      /* If the statement is an initialization, build one too.  */
              else if (No_Ctrl_Actions (gnat_node)
		       || No_Finalize_Actions (gnat_node))
		gnu_result
		  = build_binary_op (INIT_EXPR, NULL_TREE, gnu_lhs, gnu_rhs);

	      /* Otherwise build a regular assignment.  */
	      else
		gnu_result
		  = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_lhs, gnu_rhs);
	    }

	  /* If the assignment type is a regular array and the two sides are
	     not completely disjoint, play safe and use memmove.  But don't do
	     it for a bit-packed array as it might not be byte-aligned.  */
	  if (TREE_CODE (gnu_result) == MODIFY_EXPR
	      && Is_Array_Type (gnat_type)
	      && !Is_Bit_Packed_Array (gnat_type)
	      && !(Forwards_OK (gnat_node) && Backwards_OK (gnat_node)))
	    {
	      tree to = TREE_OPERAND (gnu_result, 0);
	      tree from = TREE_OPERAND (gnu_result, 1);
	      tree type = TREE_TYPE (from);
	      tree size
	        = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (type), from);
	      tree to_ptr = build_fold_addr_expr (to);
	      tree from_ptr = build_fold_addr_expr (from);
	      tree t = builtin_decl_explicit (BUILT_IN_MEMMOVE);
	      gnu_result = build_call_expr (t, 3, to_ptr, from_ptr, size);
	      Check_Restriction_No_Dependence_On_System (Name_Memory_Move,
							 gnat_node);
	   }

	  /* If this is an assignment between (potentially) large aggregates,
	     then declare the dependence on the memcpy routine.  */
	  else if (AGGREGATE_TYPE_P (TREE_TYPE (gnu_lhs))
		   && (!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_lhs)))
		       || compare_tree_int (TYPE_SIZE (TREE_TYPE (gnu_lhs)),
					    2 * BITS_PER_WORD) > 0))
	    Check_Restriction_No_Dependence_On_System (Name_Memory_Copy,
						       gnat_node);
	}
      break;

    case N_If_Statement:
      {
	tree *gnu_else_ptr; /* Point to put next "else if" or "else".  */

	/* Make the outer COND_EXPR.  Avoid non-determinism.  */
	gnu_result = build3 (COND_EXPR, void_type_node,
			     gnat_to_gnu (Condition (gnat_node)),
			     NULL_TREE, NULL_TREE);
	COND_EXPR_THEN (gnu_result)
	  = build_stmt_group (Then_Statements (gnat_node), false);
	TREE_SIDE_EFFECTS (gnu_result) = 1;
	gnu_else_ptr = &COND_EXPR_ELSE (gnu_result);

	/* Now make a COND_EXPR for each of the "else if" parts.  Put each
	   into the previous "else" part and point to where to put any
	   outer "else".  Also avoid non-determinism.  */
	if (Present (Elsif_Parts (gnat_node)))
	  for (gnat_temp = First (Elsif_Parts (gnat_node));
	       Present (gnat_temp); gnat_temp = Next (gnat_temp))
	    {
	      gnu_expr = build3 (COND_EXPR, void_type_node,
				 gnat_to_gnu (Condition (gnat_temp)),
				 NULL_TREE, NULL_TREE);
	      COND_EXPR_THEN (gnu_expr)
		= build_stmt_group (Then_Statements (gnat_temp), false);
	      TREE_SIDE_EFFECTS (gnu_expr) = 1;
	      set_expr_location_from_node (gnu_expr, gnat_temp);
	      *gnu_else_ptr = gnu_expr;
	      gnu_else_ptr = &COND_EXPR_ELSE (gnu_expr);
	    }

	*gnu_else_ptr = build_stmt_group (Else_Statements (gnat_node), false);
      }
      break;

    case N_Case_Statement:
      gnu_result = Case_Statement_to_gnu (gnat_node);
      break;

    case N_Loop_Statement:
      gnu_result = Loop_Statement_to_gnu (gnat_node);
      break;

    case N_Block_Statement:
      /* The only way to enter the block is to fall through to it.  */
      if (stmt_group_may_fallthru ())
	{
	  start_stmt_group ();
	  gnat_pushlevel ();
	  process_decls (Declarations (gnat_node), Empty, true, true);
	  add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node)));
	  if (Present (At_End_Proc (gnat_node)))
	    At_End_Proc_to_gnu (gnat_node);
	  gnat_poplevel ();
	  gnu_result = end_stmt_group ();
	}
      else
	gnu_result = alloc_stmt_list ();
      break;

    case N_Exit_Statement:
      gnu_result
	= build2 (EXIT_STMT, void_type_node,
		  (Present (Condition (gnat_node))
		   ? gnat_to_gnu (Condition (gnat_node)) : NULL_TREE),
		  (Present (Name (gnat_node))
		   ? get_gnu_tree (Entity (Name (gnat_node)))
		   : LOOP_STMT_LABEL (gnu_loop_stack->last ()->stmt)));
      break;

    case N_Simple_Return_Statement:
      {
	tree gnu_ret_obj, gnu_ret_val;

	/* If the subprogram is a function, we must return the expression.  */
	if (Present (Expression (gnat_node)))
	  {
	    tree gnu_subprog_type = TREE_TYPE (current_function_decl);

	    /* If this function has copy-in/copy-out parameters parameters and
	       doesn't return by invisible reference, get the real object for
	       the return.  See Subprogram_Body_to_gnu.  */
	    if (TYPE_CI_CO_LIST (gnu_subprog_type)
		&& !TREE_ADDRESSABLE (gnu_subprog_type))
	      gnu_ret_obj = gnu_return_var_stack->last ();
	    else
	      gnu_ret_obj = DECL_RESULT (current_function_decl);

	    /* Get the GCC tree for the expression to be returned.  */
	    gnu_ret_val = gnat_to_gnu (Expression (gnat_node));

	    /* Do not remove the padding from GNU_RET_VAL if the inner type is
	       self-referential since we want to allocate the fixed size.  */
	    if (TREE_CODE (gnu_ret_val) == COMPONENT_REF
		&& type_is_padding_self_referential
		   (TREE_TYPE (TREE_OPERAND (gnu_ret_val, 0))))
	      gnu_ret_val = TREE_OPERAND (gnu_ret_val, 0);

	    /* If the function returns by direct reference, return a pointer
	       to the return value, possibly after allocating it.  */
	    if (TYPE_RETURN_BY_DIRECT_REF_P (gnu_subprog_type))
	      {
		if (Present (Storage_Pool (gnat_node)))
		  {
		    gnu_ret_val = maybe_unconstrained_array (gnu_ret_val);

		    /* And find out whether it is a candidate for Named Return
		       Value.  If so, record it.  */
		    if (optimize
			&& !optimize_debug
			&& !TYPE_CI_CO_LIST (gnu_subprog_type))
		      {
			tree ret_val = gnu_ret_val;

			/* Strip conversions around the return value.  */
			if (gnat_useless_type_conversion (ret_val))
			  ret_val = TREE_OPERAND (ret_val, 0);

			/* Strip unpadding around the return value.  */
			if (TREE_CODE (ret_val) == COMPONENT_REF
			    && TYPE_IS_PADDING_P
			      (TREE_TYPE (TREE_OPERAND (ret_val, 0))))
			  ret_val = TREE_OPERAND (ret_val, 0);

			/* Now apply the test to the return value.  */
			if (return_value_ok_for_nrv_p (NULL_TREE, ret_val))
			  {
			    if (!f_named_ret_val)
			      f_named_ret_val = BITMAP_GGC_ALLOC ();
			    bitmap_set_bit (f_named_ret_val,
					    DECL_UID (ret_val));
			    if (!f_gnat_ret)
			      f_gnat_ret = gnat_node;
			  }
		      }

		    gnu_ret_val
		      = build_allocator (TREE_TYPE (gnu_ret_val),
					 gnu_ret_val,
					 TREE_TYPE (gnu_ret_obj),
					 Procedure_To_Call (gnat_node),
					 Storage_Pool (gnat_node),
					 gnat_node,
					 false);
		  }

		else
		  gnu_ret_val
		    = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_ret_val);
	      }

	    /* Otherwise, if it returns by invisible reference, dereference
	       the pointer it is passed using the type of the return value
	       and build the copy operation manually.  This ensures that we
	       don't copy too much data, for example if the return type is
	       unconstrained with a maximum size.  */
	    else if (TREE_ADDRESSABLE (gnu_subprog_type))
	      {
		tree gnu_ret_deref
		  = build_unary_op (INDIRECT_REF, TREE_TYPE (gnu_ret_val),
				    gnu_ret_obj);
		gnu_result = build2 (INIT_EXPR, void_type_node,
				     gnu_ret_deref, gnu_ret_val);
		/* Avoid a useless copy with __builtin_return_slot.  */
		tree gnu_inner_val = remove_conversions (gnu_ret_val, false);
		if (INDIRECT_REF_P (gnu_inner_val))
		  gnu_result
		    = build3 (COND_EXPR, void_type_node,
			      fold_build2 (NE_EXPR, boolean_type_node,
					   TREE_OPERAND (gnu_inner_val, 0),
					   gnu_ret_obj),
			      gnu_result, NULL_TREE);
		add_stmt_with_node (gnu_result, gnat_node);
		gnu_ret_val = NULL_TREE;
	      }
	  }

	else
	  gnu_ret_obj = gnu_ret_val = NULL_TREE;

	/* If we have a return label defined, convert this into a branch to
	   that label.  The return proper will be handled elsewhere.  */
	if (gnu_return_label_stack->last ())
	  {
	    if (gnu_ret_val)
	      add_stmt_with_node (build_binary_op (MODIFY_EXPR,
						   NULL_TREE, gnu_ret_obj,
						   gnu_ret_val),
				  gnat_node);

	    gnu_result = build1 (GOTO_EXPR, void_type_node,
				 gnu_return_label_stack->last ());

	    /* When not optimizing, make sure the return is preserved.  */
	    if (!optimize && Comes_From_Source (gnat_node))
	      DECL_ARTIFICIAL (gnu_return_label_stack->last ()) = 0;
	  }

	/* Otherwise, build a regular return.  */
	else
	  gnu_result = build_return_expr (gnu_ret_obj, gnu_ret_val);
      }
      break;

    case N_Goto_Statement:
      gnu_expr = gnat_to_gnu (Name (gnat_node));
      gnu_result = build1 (GOTO_EXPR, void_type_node, gnu_expr);
      TREE_USED (gnu_expr) = 1;
      break;

    /***************************/
    /* Chapter 6: Subprograms  */
    /***************************/

    case N_Subprogram_Declaration:
      /* Unless there is a freeze node, declare the entity.  We consider
	 this a definition even though we're not generating code for the
	 subprogram because we will be making the corresponding GCC node.
	 When there is a freeze node, it is considered the definition of
	 the subprogram and we do nothing until after it is encountered.
	 That's an efficiency issue: the types involved in the profile
	 are far more likely to be frozen between the declaration and
	 the freeze node than before the declaration, so we save some
	 updates of the GCC node by waiting until the freeze node.
	 The counterpart is that we assume that there is no reference
	 to the subprogram between the declaration and the freeze node
	 in the expanded code; otherwise, it will be interpreted as an
	 external reference and very likely give rise to a link failure.  */
      if (No (Freeze_Node (Defining_Entity (Specification (gnat_node)))))
	gnat_to_gnu_entity (Defining_Entity (Specification (gnat_node)),
			    NULL_TREE, true);
      gnu_result = alloc_stmt_list ();
      break;

    case N_Abstract_Subprogram_Declaration:
      /* This subprogram doesn't exist for code generation purposes, but we
	 have to elaborate the types of any parameters and result, unless
	 they are imported types (nothing to generate in this case).

	 The parameter list may contain types with freeze nodes, e.g. not null
	 subtypes, so the subprogram itself may carry a freeze node, in which
	 case its elaboration must be deferred.  */

      /* Process the parameter types first.  */
      if (No (Freeze_Node (Defining_Entity (Specification (gnat_node)))))
      for (gnat_temp
	   = First_Formal_With_Extras
	      (Defining_Entity (Specification (gnat_node)));
	   Present (gnat_temp);
	   gnat_temp = Next_Formal_With_Extras (gnat_temp))
	if (Is_Itype (Etype (gnat_temp))
	    && !From_Limited_With (Etype (gnat_temp)))
	  gnat_to_gnu_entity (Etype (gnat_temp), NULL_TREE, false);

      /* Then the result type, set to Standard_Void_Type for procedures.  */
      {
	Entity_Id gnat_temp_type
	  = Etype (Defining_Entity (Specification (gnat_node)));

	if (Is_Itype (gnat_temp_type) && !From_Limited_With (gnat_temp_type))
	  gnat_to_gnu_entity (Etype (gnat_temp_type), NULL_TREE, false);
      }

      gnu_result = alloc_stmt_list ();
      break;

    case N_Defining_Program_Unit_Name:
      /* For a child unit identifier go up a level to get the specification.
	 We get this when we try to find the spec of a child unit package
	 that is the compilation unit being compiled.  */
      gnu_result = gnat_to_gnu (Parent (gnat_node));
      break;

    case N_Subprogram_Body:
      Subprogram_Body_to_gnu (gnat_node);
      gnu_result = alloc_stmt_list ();
      break;

    case N_Function_Call:
    case N_Procedure_Call_Statement:
      gnu_result = Call_to_gnu (gnat_node, &gnu_result_type, NULL_TREE,
				NOT_ATOMIC, false, Empty);
      break;

    /************************/
    /* Chapter 7: Packages  */
    /************************/

    case N_Package_Declaration:
      gnu_result = gnat_to_gnu (Specification (gnat_node));
      break;

    case N_Package_Specification:
      start_stmt_group ();
      process_decls (Visible_Declarations (gnat_node),
		     Private_Declarations (gnat_node),
		     true, true);
      gnu_result = end_stmt_group ();
      break;

    case N_Package_Body:
      /* If this is the body of a generic package - do nothing.  */
      if (Ekind (Corresponding_Spec (gnat_node)) == E_Generic_Package)
	{
	  gnu_result = alloc_stmt_list ();
	  break;
	}

      start_stmt_group ();
      process_decls (Declarations (gnat_node), Empty, true, true);
      if (Present (Handled_Statement_Sequence (gnat_node)))
	add_stmt (gnat_to_gnu (Handled_Statement_Sequence (gnat_node)));
      if (Present (At_End_Proc (gnat_node)))
	At_End_Proc_to_gnu (gnat_node);
      gnu_result = end_stmt_group ();
      break;

    /********************************/
    /* Chapter 8: Visibility Rules  */
    /********************************/

    case N_Use_Package_Clause:
      if (gnat_encodings == DWARF_GNAT_ENCODINGS_ALL)
	gnu_result = alloc_stmt_list ();
      else
	{
	  tree ns = get_namespace (Name (gnat_node), gnat_node);
	  gnu_result = build_decl (input_location, IMPORTED_DECL,
				   nullptr, void_type_node);
	  IMPORTED_DECL_ASSOCIATED_DECL (gnu_result) = ns;
	  gnat_pushdecl (gnu_result, gnat_node);
	}
      break;

    case N_Use_Type_Clause:
      /* Nothing to do here - but these may appear in list of declarations.  */
      gnu_result = alloc_stmt_list ();
      break;

    /*********************/
    /* Chapter 9: Tasks  */
    /*********************/

    case N_Protected_Type_Declaration:
      gnu_result = alloc_stmt_list ();
      break;

    case N_Single_Task_Declaration:
      gnat_to_gnu_entity (Defining_Entity (gnat_node), NULL_TREE, true);
      gnu_result = alloc_stmt_list ();
      break;

    /*********************************************************/
    /* Chapter 10: Program Structure and Compilation Issues  */
    /*********************************************************/

    case N_Compilation_Unit:
      /* This is not called for the main unit on which gigi is invoked.  */
      Compilation_Unit_to_gnu (gnat_node);
      gnu_result = alloc_stmt_list ();
      break;

    case N_Subunit:
      gnu_result = gnat_to_gnu (Proper_Body (gnat_node));
      break;

    case N_Entry_Body:
    case N_Protected_Body:
    case N_Task_Body:
      /* These nodes should only be present when annotating types.  */
      gcc_assert (type_annotate_only);
      process_decls (Declarations (gnat_node), Empty, true, true);
      gnu_result = alloc_stmt_list ();
      break;

    case N_Subprogram_Body_Stub:
    case N_Package_Body_Stub:
    case N_Protected_Body_Stub:
    case N_Task_Body_Stub:
      /* Simply process whatever unit is being inserted.  */
      if (Present (Library_Unit (gnat_node)))
	gnu_result = gnat_to_gnu (Unit (Library_Unit (gnat_node)));
      else
	{
	  gcc_assert (type_annotate_only);
	  gnu_result = alloc_stmt_list ();
	}
      break;

    case N_With_Clause:
      if (gnat_encodings == DWARF_GNAT_ENCODINGS_ALL
	  || Is_Implicit_With (gnat_node)
	  || Limited_Present (gnat_node))
	gnu_result = alloc_stmt_list ();
      else
	gnu_result = get_namespace (Name (gnat_node), gnat_node);
      break;

    /***************************/
    /* Chapter 11: Exceptions  */
    /***************************/

    case N_Handled_Sequence_Of_Statements:
      gnu_result = Handled_Sequence_Of_Statements_to_gnu (gnat_node);
      break;

    case N_Exception_Handler:
      gnu_result = Exception_Handler_to_gnu (gnat_node);
      break;

    case N_Raise_Statement:
      /* Only for reraise in back-end exceptions mode.  */
      gcc_assert (No (Name (gnat_node)));

      start_stmt_group ();

      add_stmt_with_node (build_call_n_expr (reraise_zcx_decl, 1,
					     gnu_incoming_exc_ptr),
			  gnat_node);

      gnu_result = end_stmt_group ();
      break;

    case N_Push_Constraint_Error_Label:
      gnu_constraint_error_label_stack.safe_push (Exception_Label (gnat_node));
      break;

    case N_Push_Storage_Error_Label:
      gnu_storage_error_label_stack.safe_push (Exception_Label (gnat_node));
      break;

    case N_Push_Program_Error_Label:
      gnu_program_error_label_stack.safe_push (Exception_Label (gnat_node));
      break;

    case N_Pop_Constraint_Error_Label:
      gnat_temp = gnu_constraint_error_label_stack.pop ();
      if (Present (gnat_temp)
	  && !TREE_USED (gnat_to_gnu_entity (gnat_temp, NULL_TREE, false))
	  && No_Exception_Propagation_Active ())
	Warn_If_No_Local_Raise (gnat_temp);
      break;

    case N_Pop_Storage_Error_Label:
      gnat_temp = gnu_storage_error_label_stack.pop ();
      if (Present (gnat_temp)
	  && !TREE_USED (gnat_to_gnu_entity (gnat_temp, NULL_TREE, false))
	  && No_Exception_Propagation_Active ())
	Warn_If_No_Local_Raise (gnat_temp);
      break;

    case N_Pop_Program_Error_Label:
      gnat_temp = gnu_program_error_label_stack.pop ();
      if (Present (gnat_temp)
	  && !TREE_USED (gnat_to_gnu_entity (gnat_temp, NULL_TREE, false))
	  && No_Exception_Propagation_Active ())
	Warn_If_No_Local_Raise (gnat_temp);
      break;

    /******************************/
    /* Chapter 12: Generic Units  */
    /******************************/

    case N_Generic_Function_Renaming_Declaration:
    case N_Generic_Package_Renaming_Declaration:
    case N_Generic_Procedure_Renaming_Declaration:
    case N_Generic_Package_Declaration:
    case N_Generic_Subprogram_Declaration:
    case N_Package_Instantiation:
    case N_Procedure_Instantiation:
    case N_Function_Instantiation:
      /* These nodes can appear on a declaration list but there is nothing to
	 to be done with them.  */
      gnu_result = alloc_stmt_list ();
      break;

    /**************************************************/
    /* Chapter 13: Representation Clauses and         */
    /*             Implementation-Dependent Features  */
    /**************************************************/

    case N_Attribute_Definition_Clause:
      gnu_result = alloc_stmt_list ();

      /* The only one we need to deal with is 'Address since, for the others,
	 the front-end puts the information elsewhere.  */
      if (Get_Attribute_Id (Chars (gnat_node)) != Attr_Address)
	break;

      /* And we only deal with 'Address if the object has a Freeze node.  */
      gnat_temp = Entity (Name (gnat_node));
      if (Freeze_Node (gnat_temp))
	{
	  tree gnu_address = gnat_to_gnu (Expression (gnat_node)), gnu_temp;

	  /* Get the value to use as the address and save it as the equivalent
	     for the object; when it is frozen, gnat_to_gnu_entity will do the
	     right thing.  For a subprogram, put the naked address but build a
	     meaningfull expression for an object in case its address is taken
	     before the Freeze node is encountered; this can happen if the type
	     of the object is limited and it is initialized with the result of
	     a function call.  */
	  if (Is_Subprogram (gnat_temp))
	    gnu_temp = gnu_address;
	  else
	    {
	      tree gnu_type = gnat_to_gnu_type (Etype (gnat_temp));
	      /* Drop atomic and volatile qualifiers for the expression.  */
	      gnu_type = TYPE_MAIN_VARIANT (gnu_type);
	      gnu_type
		= build_reference_type_for_mode (gnu_type, ptr_mode, true);
	      gnu_address = convert (gnu_type, gnu_address);
	      gnu_temp
		= build_unary_op (INDIRECT_REF, NULL_TREE, gnu_address);
	    }

	  save_gnu_tree (gnat_temp, gnu_temp, true);
	}
      break;

    case N_Enumeration_Representation_Clause:
    case N_Record_Representation_Clause:
    case N_At_Clause:
      /* We do nothing with these.  SEM puts the information elsewhere.  */
      gnu_result = alloc_stmt_list ();
      break;

    case N_Code_Statement:
      if (!type_annotate_only)
	{
	  tree gnu_template = gnat_to_gnu (Asm_Template (gnat_node));
	  tree gnu_inputs = NULL_TREE, gnu_outputs = NULL_TREE;
	  tree gnu_clobbers = NULL_TREE, tail;
	  bool allows_mem, allows_reg, fake;
	  int ninputs, noutputs, i;
	  const char **oconstraints;
	  const char *constraint;
	  char *clobber;

	  /* First retrieve the 3 operand lists built by the front-end.  */
	  Setup_Asm_Outputs (gnat_node);
	  while (Present (gnat_temp = Asm_Output_Variable ()))
	    {
	      tree gnu_value = gnat_to_gnu (gnat_temp);
	      tree gnu_constr = build_tree_list (NULL_TREE, gnat_to_gnu
						 (Asm_Output_Constraint ()));

	      gnu_outputs = tree_cons (gnu_constr, gnu_value, gnu_outputs);
	      Next_Asm_Output ();
	    }

	  Setup_Asm_Inputs (gnat_node);
	  while (Present (gnat_temp = Asm_Input_Value ()))
	    {
	      tree gnu_value = gnat_to_gnu (gnat_temp);
	      tree gnu_constr = build_tree_list (NULL_TREE, gnat_to_gnu
						 (Asm_Input_Constraint ()));

	      gnu_inputs = tree_cons (gnu_constr, gnu_value, gnu_inputs);
	      Next_Asm_Input ();
	    }

	  Clobber_Setup (gnat_node);
	  while ((clobber = (char *) Clobber_Get_Next ()))
	    gnu_clobbers
	      = tree_cons (NULL_TREE,
			   build_string (strlen (clobber) + 1, clobber),
			   gnu_clobbers);

	  /* Then perform some standard checking and processing on the
	     operands.  In particular, mark them addressable if needed.  */
	  gnu_outputs = nreverse (gnu_outputs);
	  noutputs = list_length (gnu_outputs);
	  gnu_inputs = nreverse (gnu_inputs);
	  ninputs = list_length (gnu_inputs);
	  oconstraints = XALLOCAVEC (const char *, noutputs);

	  for (i = 0, tail = gnu_outputs; tail; ++i, tail = TREE_CHAIN (tail))
	    {
	      tree output = TREE_VALUE (tail);
	      constraint
		= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
	      oconstraints[i] = constraint;

	      if (parse_output_constraint (&constraint, i, ninputs, noutputs,
					   &allows_mem, &allows_reg, &fake,
					   nullptr))
		{
		  /* If the operand is going to end up in memory,
		     mark it addressable.  Note that we don't test
		     allows_mem like in the input case below; this
		     is modeled on the C front-end.  */
		  if (!allows_reg)
		    {
		      output = remove_conversions (output, false);
		      if (TREE_CODE (output) == CONST_DECL
			  && DECL_CONST_CORRESPONDING_VAR (output))
			output = DECL_CONST_CORRESPONDING_VAR (output);
		      if (!gnat_mark_addressable (output))
			output = error_mark_node;
		    }
		}
	      else
		output = error_mark_node;

	      TREE_VALUE (tail) = output;
	    }

	  for (i = 0, tail = gnu_inputs; tail; ++i, tail = TREE_CHAIN (tail))
	    {
	      tree input = TREE_VALUE (tail);
	      constraint
		= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));

	      if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
					  oconstraints, &allows_mem,
					  &allows_reg, nullptr))
		{
		  /* If the operand is going to end up in memory,
		     mark it addressable.  */
		  if (!allows_reg && allows_mem)
		    {
		      input = remove_conversions (input, false);
		      if (TREE_CODE (input) == CONST_DECL
			  && DECL_CONST_CORRESPONDING_VAR (input))
			input = DECL_CONST_CORRESPONDING_VAR (input);
		      if (!gnat_mark_addressable (input))
			input = error_mark_node;
		    }
		}
	      else
		input = error_mark_node;

	      TREE_VALUE (tail) = input;
	    }

	  gnu_result = build5 (ASM_EXPR,  void_type_node,
			       gnu_template, gnu_outputs,
			       gnu_inputs, gnu_clobbers, NULL_TREE);
	  ASM_VOLATILE_P (gnu_result) = Is_Asm_Volatile (gnat_node);
	}
      else
	gnu_result = alloc_stmt_list ();

      break;

    /****************/
    /* Added Nodes  */
    /****************/

    /* Markers are created by the ABE mechanism to capture information which
       is either unavailable of expensive to recompute.  Markers do not have
       and runtime semantics, and should be ignored.  */

    case N_Call_Marker:
    case N_Variable_Reference_Marker:
      gnu_result = alloc_stmt_list ();
      break;

    case N_Expression_With_Actions:
      /* This construct doesn't define a scope so we don't push a binding
	 level around the statement list, but we wrap it in a SAVE_EXPR to
	 protect it from unsharing.  Elaborate the expression as part of the
	 same statement group as the actions so that the type declaration
	 gets inserted there as well.  This ensures that the type elaboration
	 code is issued past the actions computing values on which it might
	 depend.  */
      start_stmt_group ();
      add_stmt_list (Actions (gnat_node));
      gnu_expr = gnat_to_gnu (Expression (gnat_node));
      gnu_result = end_stmt_group ();

      gnu_result = build1 (SAVE_EXPR, void_type_node, gnu_result);
      TREE_SIDE_EFFECTS (gnu_result) = 1;

      gnu_result
	= build_compound_expr (TREE_TYPE (gnu_expr), gnu_result, gnu_expr);
      gnu_result_type = get_unpadded_type (Etype (gnat_node));
      break;

    case N_Freeze_Entity:
      start_stmt_group ();
      process_freeze_entity (gnat_node);
      process_decls (Actions (gnat_node), Empty, true, true);
      gnu_result = end_stmt_group ();
      break;

    case N_Freeze_Generic_Entity:
      gnu_result = alloc_stmt_list ();
      break;

    case N_Itype_Reference:
      if (!present_gnu_tree (Itype (gnat_node)))
	process_type (Itype (gnat_node));
      gnu_result = alloc_stmt_list ();
      break;

    case N_Free_Statement:
      gnat_temp = Expression (gnat_node);

      if (!type_annotate_only)
	{
	  const Entity_Id gnat_desig_type
	    = Designated_Type (Underlying_Type (Etype (gnat_temp)));
	  const Entity_Id gnat_pool = Storage_Pool (gnat_node);
	  const bool pool_is_storage_model
	    = Present (gnat_pool)
	      && Has_Storage_Model_Type_Aspect (Etype (gnat_pool))
	      && Present (Storage_Model_Copy_From (gnat_pool));
	  tree gnu_ptr, gnu_ptr_type, gnu_obj_type, gnu_actual_obj_type;

	  /* Make sure the designated type is complete before dereferencing,
	     in case it is a Taft Amendment type.  */
	  (void) gnat_to_gnu_entity (gnat_desig_type, NULL_TREE, false);

	  gnu_ptr = gnat_to_gnu (gnat_temp);

	  /* If this is an array allocated with its bounds, first convert to
	     the thin pointer to trigger the special machinery below.  */
	  if (Is_Constr_Array_Subt_With_Bounds (gnat_desig_type))
	    {
	      tree gnu_array = gnat_to_gnu_type (Base_Type (gnat_desig_type));
	      gnu_ptr
		= convert (build_pointer_type
			   (TYPE_OBJECT_RECORD_TYPE (gnu_array)),
			   gnu_ptr);
	    }

	  gnu_ptr_type = TREE_TYPE (gnu_ptr);

	  /* If this is a thin pointer, we must first dereference it to create
	     a fat pointer, then go back below to a thin pointer.  The reason
	     for this is that we need to have a fat pointer someplace in order
	     to properly compute the size.  */
	  if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr)))
	    gnu_ptr = build_unary_op (ADDR_EXPR, NULL_TREE,
				      build_unary_op (INDIRECT_REF, NULL_TREE,
						      gnu_ptr));

	  /* If this is a fat pointer, the object must have been allocated with
	     the template in front of the array.  So pass the template address,
	     and get the total size; do it by converting to a thin pointer.  */
	  if (TYPE_IS_FAT_POINTER_P (TREE_TYPE (gnu_ptr)))
	    gnu_ptr
	      = convert (build_pointer_type
			 (TYPE_OBJECT_RECORD_TYPE
			  (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (gnu_ptr)))),
			 gnu_ptr);

	  gnu_obj_type = TREE_TYPE (TREE_TYPE (gnu_ptr));

	  /* If this is a thin pointer, the object must have been allocated with
	     the template in front of the array.  So pass the template address,
	     and get the total size.  */
	  if (TYPE_IS_THIN_POINTER_P (TREE_TYPE (gnu_ptr)))
	    gnu_ptr
	      = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (gnu_ptr),
				 gnu_ptr,
				 fold_build1 (NEGATE_EXPR, sizetype,
					      byte_position
					      (DECL_CHAIN
					       TYPE_FIELDS ((gnu_obj_type)))));

	  /* If we have a special dynamic constrained subtype on the node, use
	     it to compute the size; otherwise, use the designated subtype.  */
	  if (Present (Actual_Designated_Subtype (gnat_node)))
	    {
	      gnu_actual_obj_type
		= gnat_to_gnu_type (Actual_Designated_Subtype (gnat_node));

	      if (TYPE_IS_FAT_OR_THIN_POINTER_P (gnu_ptr_type))
		gnu_actual_obj_type
		  = build_unc_object_type_from_ptr (gnu_ptr_type,
						    gnu_actual_obj_type,
						    get_identifier ("DEALLOC"),
						    false);
	    }
	  else
	    gnu_actual_obj_type = gnu_obj_type;

	  tree gnu_size = TYPE_SIZE_UNIT (gnu_actual_obj_type);
	  gnu_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_size, gnu_ptr);
	  if (pool_is_storage_model)
	    gnu_size = INSTANTIATE_LOAD_IN_EXPR (gnu_size, gnat_pool);

	  gnu_result
	      = build_call_alloc_dealloc (gnu_ptr, gnu_size, gnu_obj_type,
					  Procedure_To_Call (gnat_node),
					  gnat_pool, gnat_node);
	}
      break;

    case N_Raise_Constraint_Error:
    case N_Raise_Program_Error:
    case N_Raise_Storage_Error:
      if (type_annotate_only)
	gnu_result = alloc_stmt_list ();
      else
	gnu_result = Raise_Error_to_gnu (gnat_node, &gnu_result_type);
      break;

    case N_Validate_Unchecked_Conversion:
      /* The only validation we currently do on an unchecked conversion is
	 that of aliasing assumptions.  */
      if (flag_strict_aliasing)
	gnat_validate_uc_list.safe_push (gnat_node);
      gnu_result = alloc_stmt_list ();
      break;

    case N_Function_Specification:
    case N_Procedure_Specification:
    case N_Op_Concat:
    case N_Component_Association:
      /* These nodes should only be present when annotating types.  */
      gcc_assert (type_annotate_only);
      gnu_result = alloc_stmt_list ();
      break;

    default:
      /* Other nodes are not supposed to reach here.  */
      gcc_unreachable ();
    }

  /* If we are in the elaboration procedure, check if we are violating the
     No_Elaboration_Code restriction by having a non-empty statement.  */
  if (statement_node_p (gnat_node)
      && !(TREE_CODE (gnu_result) == STATEMENT_LIST
	   && empty_stmt_list_p (gnu_result))
      && current_function_decl == get_elaboration_procedure ())
    Check_Elaboration_Code_Allowed (gnat_node);

  /* If we pushed the processing of the elaboration routine, pop it back.  */
  if (went_into_elab_proc)
    current_function_decl = NULL_TREE;

  /* When not optimizing, turn boolean rvalues B into B != false tests
     so that we can put the location information of the reference to B on
     the inequality operator for better debug info.  */
  if (!optimize
      && TREE_CODE (gnu_result) != INTEGER_CST
      && TREE_CODE (gnu_result) != TYPE_DECL
      && (kind == N_Identifier
	  || kind == N_Expanded_Name
	  || kind == N_Explicit_Dereference
	  || kind == N_Indexed_Component
	  || kind == N_Selected_Component)
      && TREE_CODE (get_base_type (gnu_result_type)) == BOOLEAN_TYPE
      && Nkind (Parent (gnat_node)) != N_Attribute_Reference
      && Nkind (Parent (gnat_node)) != N_Pragma_Argument_Association
      && Nkind (Parent (gnat_node)) != N_Variant_Part
      && !lvalue_required_p (gnat_node, gnu_result_type, false, false))
    {
      gnu_result
	= build_binary_op (NE_EXPR, gnu_result_type,
			   convert (gnu_result_type, gnu_result),
			   convert (gnu_result_type, boolean_false_node));
      if (TREE_CODE (gnu_result) != INTEGER_CST)
	set_gnu_expr_location_from_node (gnu_result, gnat_node);
    }

  /* Set the location information on the result if it's not a simple name
     or something that contains a simple name, for example a tag, because
     we don't want all the references to get the location of the first use.
     Note that we may have no result if we tried to build a CALL_EXPR node
     to a procedure with no side-effects and optimization is enabled.  */
  else if (kind != N_Identifier
	   && !(kind == N_Selected_Component
		&& Chars (Selector_Name (gnat_node)) == Name_uTag)
	   && gnu_result
	   && EXPR_P (gnu_result))
    set_gnu_expr_location_from_node (gnu_result, gnat_node);

  /* If we're supposed to return something of void_type, it means we have
     something we're elaborating for effect, so just return.  */
  if (VOID_TYPE_P (gnu_result_type))
    return gnu_result;

  /* If the result is a constant that overflowed, raise Constraint_Error.  */
  if (TREE_CODE (gnu_result) == INTEGER_CST && TREE_OVERFLOW (gnu_result))
    {
      post_error ("??Constraint_Error will be raised at run time", gnat_node);
      gnu_result
	= build1 (NULL_EXPR, gnu_result_type,
		  build_call_raise (CE_Overflow_Check_Failed, gnat_node,
				    N_Raise_Constraint_Error));
    }

  /* If the result has side-effects and is of an unconstrained type, protect
     the expression in case it will be referenced multiple times, i.e. for
     its value and to compute the size of an object.  But do it neither for
     an object nor a renaming declaration, nor a return statement of a call
     to a function that returns an unconstrained record type with default
     discriminant, because there is no size to be computed in these cases
     and this will create a useless temporary.  We must do this before any
     conversions.  */
  if (TREE_SIDE_EFFECTS (gnu_result)
      && (TREE_CODE (gnu_result_type) == UNCONSTRAINED_ARRAY_TYPE
	  || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type)))
      && !(TREE_CODE (gnu_result) == CALL_EXPR
	   && type_is_padding_self_referential (TREE_TYPE (gnu_result))
	   && (Nkind (Parent (gnat_node)) == N_Object_Declaration
	       || Nkind (Parent (gnat_node)) == N_Object_Renaming_Declaration
	       || Nkind (Parent (gnat_node)) == N_Simple_Return_Statement)))
    gnu_result = gnat_protect_expr (gnu_result);

  /* Now convert the result to the result type, unless we are in one of the
     following cases:

       1. If this is the LHS of an assignment or an actual parameter of a
	  call, return the result almost unmodified since the RHS will have
	  to be converted to our type in that case, unless the result type
	  has a simpler size or for array types because this size might be
	  changed in-between. Likewise if there is just a no-op unchecked
	  conversion in-between.  Similarly, don't convert integral types
	  that are the operands of an unchecked conversion since we need
	  to ignore those conversions (for 'Valid).

       2. If we have a label (which doesn't have any well-defined type), a
	  field or an error, return the result almost unmodified.  Similarly,
	  if the two types are record types with the same name, don't convert.
	  This will be the case when we are converting from a packable version
	  of a type to its original type and we need those conversions to be
	  NOPs in order for assignments into these types to work properly.

       3. If the type is void or if we have no result, return error_mark_node
	  to show we have no result.

       4. If this is a call to a function that returns with variable size and
	  the call is used as the expression in either an object or a renaming
	  declaration, return the result unmodified because we want to use the
	  return slot optimization in this case.

       5. If this is a reference to an unconstrained array which is used either
	  as the prefix of an attribute reference for an access attribute or in
	  a return statement without storage pool, return the result unmodified
	  because we want to return the original bounds.

       6. Finally, if the type of the result is already correct.  */

  if (Present (Parent (gnat_node))
      && (lhs_or_actual_p (gnat_node)
	  || (Nkind (Parent (gnat_node)) == N_Unchecked_Type_Conversion
	      && unchecked_conversion_nop (Parent (gnat_node)))
	  || (Nkind (Parent (gnat_node)) == N_Unchecked_Type_Conversion
	      && !AGGREGATE_TYPE_P (gnu_result_type)
	      && !AGGREGATE_TYPE_P (TREE_TYPE (gnu_result))))
      && !(TYPE_SIZE (gnu_result_type)
	   && TYPE_SIZE (TREE_TYPE (gnu_result))
	   && AGGREGATE_TYPE_P (gnu_result_type)
	      == AGGREGATE_TYPE_P (TREE_TYPE (gnu_result))
	   && ((TREE_CODE (TYPE_SIZE (gnu_result_type)) == INTEGER_CST
		&& (TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_result)))
		    != INTEGER_CST))
	       || (TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST
		   && !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type))
		   && (CONTAINS_PLACEHOLDER_P
		       (TYPE_SIZE (TREE_TYPE (gnu_result)))))
	       || (TREE_CODE (gnu_result_type) == ARRAY_TYPE
		   && TREE_CODE (TREE_TYPE (gnu_result)) == ARRAY_TYPE))
	   && !(TREE_CODE (gnu_result_type) == RECORD_TYPE
		&& TYPE_JUSTIFIED_MODULAR_P (gnu_result_type))))
    {
      /* Remove padding only if the inner object is of self-referential
	 size: in that case it must be an object of unconstrained type
	 with a default discriminant and we want to avoid copying too
	 much data.  But do not remove it if it is already too small.  */
      if (type_is_padding_self_referential (TREE_TYPE (gnu_result))
	  && !(TREE_CODE (gnu_result) == COMPONENT_REF
	       && DECL_BIT_FIELD (TREE_OPERAND (gnu_result, 1))
	       && DECL_SIZE (TREE_OPERAND (gnu_result, 1))
		  != TYPE_SIZE (TREE_TYPE (gnu_result))))
	gnu_result = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result))),
			      gnu_result);
    }

  else if (TREE_CODE (gnu_result) == LABEL_DECL
	   || TREE_CODE (gnu_result) == FIELD_DECL
	   || TREE_CODE (gnu_result) == ERROR_MARK
	   || (TYPE_NAME (gnu_result_type)
	       == TYPE_NAME (TREE_TYPE (gnu_result))
	       && TREE_CODE (gnu_result_type) == RECORD_TYPE
	       && TREE_CODE (TREE_TYPE (gnu_result)) == RECORD_TYPE))
    {
      /* Remove any padding.  */
      gnu_result = maybe_padded_object (gnu_result);
    }

  else if (gnu_result == error_mark_node || gnu_result_type == void_type_node)
    gnu_result = error_mark_node;

  else if (TREE_CODE (gnu_result) == CALL_EXPR
	   && Present (Parent (gnat_node))
	   && (Nkind (Parent (gnat_node)) == N_Object_Declaration
	       || Nkind (Parent (gnat_node)) == N_Object_Renaming_Declaration)
	   && return_type_with_variable_size_p (TREE_TYPE (gnu_result)))
    ;

  else if (TREE_CODE (TREE_TYPE (gnu_result)) == UNCONSTRAINED_ARRAY_TYPE
	   && Present (Parent (gnat_node))
	   && ((Nkind (Parent (gnat_node)) == N_Attribute_Reference
	        && access_attribute_p (Parent (gnat_node)))
	       || (Nkind (Parent (gnat_node)) == N_Simple_Return_Statement
		   && No (Storage_Pool (Parent (gnat_node))))))
    ;

  else if (TREE_TYPE (gnu_result) != gnu_result_type)
    gnu_result = convert (gnu_result_type, gnu_result);

  /* We don't need any NOP_EXPR or NON_LVALUE_EXPR on the result.  */
  while ((TREE_CODE (gnu_result) == NOP_EXPR
	  || TREE_CODE (gnu_result) == NON_LVALUE_EXPR)
	 && TREE_TYPE (TREE_OPERAND (gnu_result, 0)) == TREE_TYPE (gnu_result))
    gnu_result = TREE_OPERAND (gnu_result, 0);

  return gnu_result;
}

/* Similar to gnat_to_gnu, but discard any object that might be created in
   the course of the translation of GNAT_NODE, which must be an "external"
   expression in the sense that it will be elaborated elsewhere.  */

tree
gnat_to_gnu_external (Node_Id gnat_node)
{
  const int save_force_global = force_global;
  bool went_into_elab_proc;

  /* Force the local context and create a fake scope that we zap
     at the end so declarations will not be stuck either in the
     global varpool or in the current scope.  */
  if (!current_function_decl)
    {
      current_function_decl = get_elaboration_procedure ();
      went_into_elab_proc = true;
    }
  else
    went_into_elab_proc = false;
  force_global = 0;
  gnat_pushlevel ();

  tree gnu_result = gnat_to_gnu (gnat_node);

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

  /* Do not import locations from external units.  */
  if (CAN_HAVE_LOCATION_P (gnu_result))
    SET_EXPR_LOCATION (gnu_result, UNKNOWN_LOCATION);

  return gnu_result;
}

/* Return true if the statement list STMT_LIST is empty.  */

static bool
empty_stmt_list_p (tree stmt_list)
{
  tree_stmt_iterator tsi;

  for (tsi = tsi_start (stmt_list); !tsi_end_p (tsi); tsi_next (&tsi))
    {
      tree stmt = tsi_stmt (tsi);

      /* Anything else than an empty STMT_STMT counts as something.  */
      if (TREE_CODE (stmt) != STMT_STMT || STMT_STMT_STMT (stmt))
	return false;
    }

  return true;
}

/* Record the current code position in GNAT_NODE.  */

static void
record_code_position (Node_Id gnat_node)
{
  tree stmt_stmt = build1 (STMT_STMT, void_type_node, NULL_TREE);

  add_stmt_with_node (stmt_stmt, gnat_node);
  save_gnu_tree (gnat_node, stmt_stmt, true);
}

/* Insert the code for GNAT_NODE at the position saved for that node.  */

static void
insert_code_for (Node_Id gnat_node)
{
  tree code = gnat_to_gnu (gnat_node);

  /* It's too late to remove the STMT_STMT itself at this point.  */
  if (!empty_stmt_list_p (code))
    STMT_STMT_STMT (get_gnu_tree (gnat_node)) = code;

  save_gnu_tree (gnat_node, NULL_TREE, true);
}

/* Start a new statement group chained to the previous group.  */

void
start_stmt_group (void)
{
  struct stmt_group *group = stmt_group_free_list;

  /* First see if we can get one from the free list.  */
  if (group)
    stmt_group_free_list = group->previous;
  else
    group = ggc_alloc<stmt_group> ();

  group->previous = current_stmt_group;
  group->stmt_list = group->block = group->cleanups = NULL_TREE;
  current_stmt_group = group;
}

/* Add GNU_STMT to the current statement group.  If it is an expression with
   no effects, it is ignored.  */

void
add_stmt (tree gnu_stmt)
{
  append_to_statement_list (gnu_stmt, &current_stmt_group->stmt_list);
}

/* Similar, but the statement is always added, regardless of side-effects.  */

void
add_stmt_force (tree gnu_stmt)
{
  append_to_statement_list_force (gnu_stmt, &current_stmt_group->stmt_list);
}

/* Like add_stmt, but set the location of GNU_STMT to that of GNAT_NODE.  */

void
add_stmt_with_node (tree gnu_stmt, Node_Id gnat_node)
{
  if (Present (gnat_node))
    set_expr_location_from_node (gnu_stmt, gnat_node);
  add_stmt (gnu_stmt);
}

/* Similar, but the statement is always added, regardless of side-effects.  */

void
add_stmt_with_node_force (tree gnu_stmt, Node_Id gnat_node)
{
  if (Present (gnat_node))
    set_expr_location_from_node (gnu_stmt, gnat_node);
  add_stmt_force (gnu_stmt);
}

/* Add a declaration statement for GNU_DECL to the current statement group.
   Get the SLOC to be put onto the statement from GNAT_NODE.  */

void
add_decl_expr (tree gnu_decl, Node_Id gnat_node)
{
  tree type = TREE_TYPE (gnu_decl);
  tree gnu_stmt, gnu_init;

  /* If this is a variable that Gigi is to ignore, we may have been given
     an ERROR_MARK.  So test for it.  We also might have been given a
     reference for a renaming.  So only do something for a decl.  Also
     ignore a TYPE_DECL for an UNCONSTRAINED_ARRAY_TYPE.  */
  if (!DECL_P (gnu_decl)
      || (TREE_CODE (gnu_decl) == TYPE_DECL
	  && TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE))
    return;

  gnu_stmt = build1 (DECL_EXPR, void_type_node, gnu_decl);

  /* If we are external or global, we don't want to output the DECL_EXPR for
     this DECL node since we already have evaluated the expressions in the
     sizes and positions as globals and doing it again would be wrong.  */
  if (DECL_EXTERNAL (gnu_decl) || global_bindings_p ())
    {
      /* Mark everything as used to prevent node sharing with subprograms.
	 Note that walk_tree knows how to deal with TYPE_DECL, but neither
	 VAR_DECL nor CONST_DECL.  This appears to be somewhat arbitrary.  */
      MARK_VISITED (gnu_stmt);
      if (VAR_P (gnu_decl)
	  || TREE_CODE (gnu_decl) == CONST_DECL)
	{
	  MARK_VISITED (DECL_SIZE (gnu_decl));
	  MARK_VISITED (DECL_SIZE_UNIT (gnu_decl));
	  MARK_VISITED (DECL_INITIAL (gnu_decl));
	}
    }
  else
    add_stmt_with_node (gnu_stmt, gnat_node);

  /* Mark our TYPE_ADA_SIZE field now since it will not be gimplified.  */
  if (TREE_CODE (gnu_decl) == TYPE_DECL
      && RECORD_OR_UNION_TYPE_P (type)
      && !TYPE_FAT_POINTER_P (type))
    MARK_VISITED (TYPE_ADA_SIZE (type));

  if (VAR_P (gnu_decl) && (gnu_init = DECL_INITIAL (gnu_decl)))
    {
      /* If this is a variable and an initializer is attached to it, it must be
	 valid for the context.  Similar to init_const in create_var_decl.  */
      if (!gnat_types_compatible_p (type, TREE_TYPE (gnu_init))
	  || (TREE_STATIC (gnu_decl)
	      && !initializer_constant_valid_p (gnu_init,
						TREE_TYPE (gnu_init))))
	{
	  DECL_INITIAL (gnu_decl) = NULL_TREE;
	  if (TREE_READONLY (gnu_decl))
	    {
	      TREE_READONLY (gnu_decl) = 0;
	      DECL_READONLY_ONCE_ELAB (gnu_decl) = 1;
	    }

	  /* Remove any padding so the assignment is done properly.  */
	  gnu_decl = maybe_padded_object (gnu_decl);

	  gnu_stmt
	    = build_binary_op (INIT_EXPR, NULL_TREE, gnu_decl, gnu_init);
	  add_stmt_with_node (gnu_stmt, gnat_node);
	}

      /* If this is the initialization of a (potentially) large aggregate, then
	 declare the dependence on the memcpy routine.  */
      if (AGGREGATE_TYPE_P (type)
	  && (!TREE_CONSTANT (TYPE_SIZE (type))
	      || compare_tree_int (TYPE_SIZE (type), 2 * BITS_PER_WORD) > 0))
	Check_Restriction_No_Dependence_On_System (Name_Memory_Copy,
						   gnat_node);
    }
}

/* Callback for walk_tree to mark the visited trees rooted at *TP.  */

static tree
mark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
  tree t = *tp;

  if (TREE_VISITED (t))
    *walk_subtrees = 0;

  /* Don't mark a dummy type as visited because we want to mark its sizes
     and fields once it's filled in.  */
  else if (!TYPE_IS_DUMMY_P (t))
    TREE_VISITED (t) = 1;

  /* The test in gimplify_type_sizes is on the main variant.  */
  if (TYPE_P (t))
    TYPE_SIZES_GIMPLIFIED (TYPE_MAIN_VARIANT (t)) = 1;

  return NULL_TREE;
}

/* Mark nodes rooted at T with TREE_VISITED and types as having their
   sized gimplified.  We use this to indicate all variable sizes and
   positions in global types may not be shared by any subprogram.  */

void
mark_visited (tree t)
{
  walk_tree (&t, mark_visited_r, NULL, NULL);
}

/* Add GNU_CLEANUP, a cleanup action, to the current code group and
   set its location to that of GNAT_NODE if present, but with column info
   cleared so that conditional branches generated as part of the cleanup
   code do not interfere with coverage analysis tools.  */

static void
add_cleanup (tree gnu_cleanup, Node_Id gnat_node)
{
  if (Present (gnat_node))
    set_expr_location_from_node (gnu_cleanup, gnat_node, true);

  /* An EH_ELSE_EXPR must be by itself, and that's all we need when we
     use it.  The assert below makes sure that is so.  Should we ever
     need more than that, we could combine EH_ELSE_EXPRs, and copy
     non-EH_ELSE_EXPR stmts into both cleanup paths of an
     EH_ELSE_EXPR.  */
  if (TREE_CODE (gnu_cleanup) == EH_ELSE_EXPR)
    {
      gcc_assert (!current_stmt_group->cleanups);
      current_stmt_group->cleanups = gnu_cleanup;
    }
  else
    {
      gcc_assert (!current_stmt_group->cleanups
		  || (TREE_CODE (current_stmt_group->cleanups)
		      != EH_ELSE_EXPR));
      append_to_statement_list (gnu_cleanup, &current_stmt_group->cleanups);
    }
}

/* Set the BLOCK node corresponding to the current code group to GNU_BLOCK.  */

void
set_block_for_group (tree gnu_block)
{
  gcc_assert (!current_stmt_group->block);
  current_stmt_group->block = gnu_block;
}

/* Return code corresponding to the current code group.  It is normally
   a STATEMENT_LIST, but may also be a BIND_EXPR or TRY_FINALLY_EXPR if
   BLOCK or cleanups were set.  */

tree
end_stmt_group (void)
{
  struct stmt_group *group = current_stmt_group;
  tree gnu_retval = group->stmt_list;

  /* If this is a null list, allocate a new STATEMENT_LIST.  Then, if there
     are cleanups, make a TRY_FINALLY_EXPR.  Last, if there is a BLOCK,
     make a BIND_EXPR.  Note that we nest in that because the cleanup may
     reference variables in the block.  */
  if (!gnu_retval)
    gnu_retval = alloc_stmt_list ();

  if (group->cleanups)
    gnu_retval = build2 (TRY_FINALLY_EXPR, void_type_node, gnu_retval,
			 group->cleanups);

  if (current_stmt_group->block)
    gnu_retval = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (group->block),
			 gnu_retval, group->block);

  /* Remove this group from the stack and add it to the free list.  */
  current_stmt_group = group->previous;
  group->previous = stmt_group_free_list;
  stmt_group_free_list = group;

  return gnu_retval;
}

/* Return whether the current statement group may fall through.  */

static inline bool
stmt_group_may_fallthru (void)
{
  if (current_stmt_group->stmt_list)
    return block_may_fallthru (current_stmt_group->stmt_list);
  else
    return true;
}

/* Add a list of statements from GNAT_LIST, a possibly-empty list of
   statements.*/

static void
add_stmt_list (List_Id gnat_list)
{
  Node_Id gnat_node;

  if (Present (gnat_list))
    for (gnat_node = First (gnat_list); Present (gnat_node);
	 gnat_node = Next (gnat_node))
      add_stmt (gnat_to_gnu (gnat_node));
}

/* Build a tree from GNAT_LIST, a possibly-empty list of statements.
   If BINDING_P is true, push and pop a binding level around the list.  */

static tree
build_stmt_group (List_Id gnat_list, bool binding_p)
{
  start_stmt_group ();

  if (binding_p)
    gnat_pushlevel ();

  add_stmt_list (gnat_list);

  if (binding_p)
    gnat_poplevel ();

  return end_stmt_group ();
}

/* Generate GIMPLE in place for the expression at *EXPR_P.  */

int
gnat_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
		    gimple_seq *post_p ATTRIBUTE_UNUSED)
{
  tree expr = *expr_p;
  tree type = TREE_TYPE (expr);
  tree op;

  if (IS_ADA_STMT (expr))
    return gnat_gimplify_stmt (expr_p);

  switch (TREE_CODE (expr))
    {
    case ADDR_EXPR:
      op = TREE_OPERAND (expr, 0);

      /* If we are taking the address of a constant CONSTRUCTOR, make sure it
	 is put into static memory.  We know that it's going to be read-only
	 given the semantics we have and it must be in static memory when the
	 reference is in an elaboration procedure.  */
      if (TREE_CODE (op) == CONSTRUCTOR && TREE_CONSTANT (op))
	{
	  tree addr = build_fold_addr_expr (tree_output_constant_def (op));
	  *expr_p = fold_convert (type, addr);
	  return GS_ALL_DONE;
	}

      /* Replace atomic loads with their first argument.  That's necessary
	 because the gimplifier would create a temporary otherwise.  */
      if (TREE_SIDE_EFFECTS (op))
	while (handled_component_p (op) || CONVERT_EXPR_P (op))
	  {
	    tree inner = TREE_OPERAND (op, 0);
	    if (TREE_CODE (inner) == CALL_EXPR && call_is_atomic_load (inner))
	      {
		tree t = CALL_EXPR_ARG (inner, 0);
		if (TREE_CODE (t) == NOP_EXPR)
		  t = TREE_OPERAND (t, 0);
		if (TREE_CODE (t) == ADDR_EXPR)
		  TREE_OPERAND (op, 0) = TREE_OPERAND (t, 0);
		else
		  TREE_OPERAND (op, 0) = build_fold_indirect_ref (t);
	      }
	    else
	      op = inner;
	  }
      break;

    case DECL_EXPR:
      op = DECL_EXPR_DECL (expr);

      /* The expressions for the RM bounds must be gimplified to ensure that
	 they are properly elaborated.  See gimplify_decl_expr.  */
      if ((TREE_CODE (op) == TYPE_DECL || VAR_P (op))
	  && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (op))
	  && (INTEGRAL_TYPE_P (TREE_TYPE (op))
	      || SCALAR_FLOAT_TYPE_P (TREE_TYPE (op))))
	{
	  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (op)), t, val;

	  val = TYPE_RM_MIN_VALUE (type);
	  if (val)
	    {
	      gimplify_one_sizepos (&val, pre_p);
	      for (t = type; t; t = TYPE_NEXT_VARIANT (t))
		SET_TYPE_RM_MIN_VALUE (t, val);
	    }

	  val = TYPE_RM_MAX_VALUE (type);
	  if (val)
	    {
	      gimplify_one_sizepos (&val, pre_p);
	      for (t = type; t; t = TYPE_NEXT_VARIANT (t))
		SET_TYPE_RM_MAX_VALUE (t, val);
	    }
	}
      break;

    case NULL_EXPR:
      /* If this is an aggregate type, build a null pointer of the appropriate
	 type and dereference it.  */
      if (AGGREGATE_TYPE_P (type)
	  || TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
	*expr_p = build_unary_op (INDIRECT_REF, NULL_TREE,
				  convert (build_pointer_type (type),
					   null_pointer_node));

      /* Otherwise, just make a VAR_DECL.  */
      else
	{
	  *expr_p = create_tmp_var (type, NULL);
	   suppress_warning (*expr_p);
	}

      gimplify_and_add (TREE_OPERAND (expr, 0), pre_p);
      return GS_OK;

    case SAVE_EXPR:
      op = TREE_OPERAND (expr, 0);

      /* Propagate TREE_NO_WARNING from expression to temporary by using the
	 SAVE_EXPR itself as an intermediate step.  See gimplify_save_expr.  */
      if (type == void_type_node)
	;
      else if (SAVE_EXPR_RESOLVED_P (expr))
	TREE_NO_WARNING (op) = TREE_NO_WARNING (expr);
      else
	TREE_NO_WARNING (expr) = TREE_NO_WARNING (op);
      break;

    case LOAD_EXPR:
      {
	tree new_var = create_tmp_var (type, "L");
	TREE_ADDRESSABLE (new_var) = 1;

	tree init = TREE_OPERAND (expr, 1);
	gcc_assert (TREE_CODE (init) == CALL_EXPR);
	tree arg = CALL_EXPR_ARG (init, 1);
	CALL_EXPR_ARG (init, 1)
	  = build_unary_op (ADDR_EXPR, TREE_TYPE (arg), new_var);
	gimplify_and_add (init, pre_p);

	*expr_p = new_var;
	return GS_OK;
      }

    case VIEW_CONVERT_EXPR:
      op = TREE_OPERAND (expr, 0);

      /* If we are view-converting a CONSTRUCTOR or a call from an aggregate
	 type to a scalar one, explicitly create the local temporary.  That's
	 required if the type is passed by reference.  */
      if ((TREE_CODE (op) == CONSTRUCTOR || TREE_CODE (op) == CALL_EXPR)
	  && AGGREGATE_TYPE_P (TREE_TYPE (op))
	  && !AGGREGATE_TYPE_P (type))
	{
	  tree new_var = create_tmp_var_raw (TREE_TYPE (op), "C");
	  gimple_add_tmp_var (new_var);

	  tree mod = build2 (INIT_EXPR, TREE_TYPE (new_var), new_var, op);
	  gimplify_and_add (mod, pre_p);

	  TREE_OPERAND (expr, 0) = new_var;
	  return GS_OK;
	}
      break;

    case UNCONSTRAINED_ARRAY_REF:
      /* We should only do this if we are just elaborating for side effects,
	 but we can't know that yet.  */
      *expr_p = TREE_OPERAND (expr, 0);
      return GS_OK;

    default:
      break;
    }

  return GS_UNHANDLED;
}

/* Generate GIMPLE in place for the statement at *STMT_P.  */

static enum gimplify_status
gnat_gimplify_stmt (tree *stmt_p)
{
  tree stmt = *stmt_p;

  switch (TREE_CODE (stmt))
    {
    case STMT_STMT:
      *stmt_p = STMT_STMT_STMT (stmt);
      return GS_OK;

    case LOOP_STMT:
      {
	tree gnu_start_label = create_artificial_label (input_location);
	tree gnu_cond = LOOP_STMT_COND (stmt);
	tree gnu_update = LOOP_STMT_UPDATE (stmt);
	tree gnu_end_label = LOOP_STMT_LABEL (stmt);

	/* Build the condition expression from the test, if any.  */
	if (gnu_cond)
	  {
	    /* Deal with the optimization hints.  */
	    if (LOOP_STMT_IVDEP (stmt))
	      gnu_cond = build3 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond,
				 build_int_cst (integer_type_node,
						annot_expr_ivdep_kind),
				 integer_zero_node);
	    if (LOOP_STMT_NO_UNROLL (stmt))
	      gnu_cond = build3 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond,
				 build_int_cst (integer_type_node,
						annot_expr_unroll_kind),
				 integer_one_node);
	    if (LOOP_STMT_UNROLL (stmt))
	      gnu_cond = build3 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond,
				 build_int_cst (integer_type_node,
						annot_expr_unroll_kind),
				 build_int_cst (NULL_TREE, USHRT_MAX));
	    if (LOOP_STMT_NO_VECTOR (stmt))
	      gnu_cond = build3 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond,
				 build_int_cst (integer_type_node,
						annot_expr_no_vector_kind),
				 integer_zero_node);
	    if (LOOP_STMT_VECTOR (stmt))
	      gnu_cond = build3 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond,
				 build_int_cst (integer_type_node,
						annot_expr_vector_kind),
				 integer_zero_node);

	    gnu_cond
	      = build3 (COND_EXPR, void_type_node, gnu_cond, NULL_TREE,
			build1 (GOTO_EXPR, void_type_node, gnu_end_label));
	  }

	/* Set to emit the statements of the loop.  */
	*stmt_p = NULL_TREE;

	/* We first emit the start label and then a conditional jump to the
	   end label if there's a top condition, then the update if it's at
	   the top, then the body of the loop, then a conditional jump to
	   the end label if there's a bottom condition, then the update if
	   it's at the bottom, and finally a jump to the start label and the
	   definition of the end label.  */
	append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
					  gnu_start_label),
				  stmt_p);

        if (gnu_cond && !LOOP_STMT_BOTTOM_COND_P (stmt))
	  append_to_statement_list (gnu_cond, stmt_p);

        if (gnu_update && LOOP_STMT_TOP_UPDATE_P (stmt))
	  append_to_statement_list (gnu_update, stmt_p);

	append_to_statement_list (LOOP_STMT_BODY (stmt), stmt_p);

        if (gnu_cond && LOOP_STMT_BOTTOM_COND_P (stmt))
	  append_to_statement_list (gnu_cond, stmt_p);

        if (gnu_update && !LOOP_STMT_TOP_UPDATE_P (stmt))
	  append_to_statement_list (gnu_update, stmt_p);

	tree t = build1 (GOTO_EXPR, void_type_node, gnu_start_label);
	SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (gnu_end_label));
	append_to_statement_list (t, stmt_p);

	append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
					  gnu_end_label),
				  stmt_p);
	return GS_OK;
      }

    case EXIT_STMT:
      /* Build a statement to jump to the corresponding end label, then
	 see if it needs to be conditional.  */
      *stmt_p = build1 (GOTO_EXPR, void_type_node, EXIT_STMT_LABEL (stmt));
      if (EXIT_STMT_COND (stmt))
	*stmt_p = build3 (COND_EXPR, void_type_node,
			  EXIT_STMT_COND (stmt), *stmt_p, alloc_stmt_list ());
      return GS_OK;

    default:
      gcc_unreachable ();
    }
}

/* Force a reference to each of the entities in GNAT_PACKAGE recursively.

   This routine is exclusively called in type_annotate mode, to compute DDA
   information for types in withed units, for ASIS use.  */

static void
elaborate_all_entities_for_package (Entity_Id gnat_package)
{
  Entity_Id gnat_entity;

  for (gnat_entity = First_Entity (gnat_package);
       Present (gnat_entity);
       gnat_entity = Next_Entity (gnat_entity))
    {
      const Entity_Kind kind = Ekind (gnat_entity);

      /* We are interested only in entities visible from the main unit.  */
      if (!Is_Public (gnat_entity))
	continue;

      /* Skip stuff internal to the compiler.  */
      if (Is_Intrinsic_Subprogram (gnat_entity))
	continue;
      if (kind == E_Operator)
	continue;
      if (IN (kind, Subprogram_Kind)
	  && (Present (Alias (gnat_entity))
	      || Is_Intrinsic_Subprogram (gnat_entity)))
	continue;
      if (Is_Itype (gnat_entity))
	continue;

      /* Skip named numbers.  */
      if (IN (kind, Named_Kind))
	continue;

      /* Skip generic declarations.  */
      if (IN (kind, Generic_Unit_Kind))
	continue;

      /* Skip formal objects.  */
      if (IN (kind, Formal_Object_Kind))
	continue;

      /* Skip package bodies.  */
      if (kind == E_Package_Body)
	continue;

      /* Skip subprogram bodies.  */
      if (kind == E_Subprogram_Body)
	continue;

      /* Skip limited views that point back to the main unit.  */
      if (IN (kind, Incomplete_Kind)
	  && From_Limited_With (gnat_entity)
	  && In_Extended_Main_Code_Unit (Non_Limited_View (gnat_entity)))
	continue;

      /* Skip types that aren't frozen.  */
      if (IN (kind, Type_Kind) && !Is_Frozen (gnat_entity))
	continue;

      /* Recurse on real packages that aren't in the main unit.  */
      if (kind == E_Package)
	{
	  if (No (Renamed_Entity (gnat_entity))
	      && !In_Extended_Main_Code_Unit (gnat_entity))
	    elaborate_all_entities_for_package (gnat_entity);
	}
      else
	gnat_to_gnu_entity (gnat_entity, NULL_TREE, false);
    }
}

/* Force a reference to each of the entities in packages withed by GNAT_NODE.
   Operate recursively but check that we aren't elaborating something more
   than once.

   This routine is exclusively called in type_annotate mode, to compute DDA
   information for types in withed units, for ASIS use.  */

static void
elaborate_all_entities (Node_Id gnat_node)
{
  Entity_Id gnat_with_clause;

  /* Process each unit only once.  As we trace the context of all relevant
     units transitively, including generic bodies, we may encounter the
     same generic unit repeatedly.  */
  if (!present_gnu_tree (gnat_node))
     save_gnu_tree (gnat_node, integer_zero_node, true);

  /* Save entities in all context units.  A body may have an implicit with
     on its own spec, if the context includes a child unit, so don't save
     the spec twice.  */
  for (gnat_with_clause = First (Context_Items (gnat_node));
       Present (gnat_with_clause);
       gnat_with_clause = Next (gnat_with_clause))
    if (Nkind (gnat_with_clause) == N_With_Clause
	&& !present_gnu_tree (Library_Unit (gnat_with_clause))
	&& Library_Unit (gnat_with_clause) != Library_Unit (Cunit (Main_Unit)))
      {
	Node_Id gnat_unit = Library_Unit (gnat_with_clause);
	Entity_Id gnat_entity = Entity (Name (gnat_with_clause));

	elaborate_all_entities (gnat_unit);

	if (Ekind (gnat_entity) == E_Package
	    && No (Renamed_Entity (gnat_entity)))
	  elaborate_all_entities_for_package (gnat_entity);

	else if (Ekind (gnat_entity) == E_Generic_Package)
	  {
	    Node_Id gnat_body = Corresponding_Body (Unit (gnat_unit));

	    /* Retrieve compilation unit node of generic body.  */
	    while (Present (gnat_body)
		   && Nkind (gnat_body) != N_Compilation_Unit)
	      gnat_body = Parent (gnat_body);

	    /* If body is available, elaborate its context.  */
	    if (Present (gnat_body))
	      elaborate_all_entities (gnat_body);
	  }
      }

  if (Nkind (Unit (gnat_node)) == N_Package_Body)
    elaborate_all_entities (Library_Unit (gnat_node));
}

/* Do the processing of GNAT_NODE, an N_Freeze_Entity.  */

static void
process_freeze_entity (Node_Id gnat_node)
{
  const Entity_Id gnat_entity = Entity (gnat_node);
  const Entity_Kind kind = Ekind (gnat_entity);
  tree gnu_old, gnu_new;

  /* If this is a package, generate code for the package body, if any.  */
  if (kind == E_Package)
    {
      const Node_Id gnat_decl = Parent (Declaration_Node (gnat_entity));
      if (Present (Corresponding_Body (gnat_decl)))
	insert_code_for (Parent (Corresponding_Body (gnat_decl)));
      return;
    }

  /* Don't do anything for class-wide types as they are always transformed
     into their root type.  */
  if (kind == E_Class_Wide_Type)
    return;

  /* Likewise for the entities internally used by the front-end to register
     primitives covering abstract interfaces, see Expand_N_Freeze_Entity.  */
  if (Is_Subprogram (gnat_entity) && Present (Interface_Alias (gnat_entity)))
    return;

  /* Skip subprogram bodies.  */
  if (kind == E_Subprogram_Body)
    return;

  /* Check for an old definition if this isn't an object with address clause,
     since the saved GCC tree is the address expression in that case.  */
  gnu_old
    = present_gnu_tree (gnat_entity) && No (Address_Clause (gnat_entity))
      ? get_gnu_tree (gnat_entity) : NULL_TREE;

  /* Don't do anything for subprograms that may have been elaborated before
     their freeze nodes.  This can happen, for example, because of an inner
     call in an instance body or because of previous compilation of a spec
     for inlining purposes.  */
  if (gnu_old
      && ((TREE_CODE (gnu_old) == FUNCTION_DECL
	   && (kind == E_Function || kind == E_Procedure))
	  || (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (gnu_old))
	      && kind == E_Subprogram_Type)))
    return;

  /* If we have a non-dummy type old tree, we have nothing to do, except for
     aborting, since this node was never delayed as it should have been.  We
     let this happen for concurrent types and their Corresponding_Record_Type,
     however, because each might legitimately be elaborated before its own
     freeze node, e.g. while processing the other.  */
  if (gnu_old
      && !(TREE_CODE (gnu_old) == TYPE_DECL
	   && TYPE_IS_DUMMY_P (TREE_TYPE (gnu_old))))
    {
      gcc_assert (Is_Concurrent_Type (gnat_entity)
		  || (Is_Record_Type (gnat_entity)
		      && Is_Concurrent_Record_Type (gnat_entity)));
      return;
    }

  /* Reset the saved tree, if any, and elaborate the object or type for real.
     If there is a full view, elaborate it and use the result.  And, if this
     is the root type of a class-wide type, reuse it for the latter.  */
  if (gnu_old)
    {
      save_gnu_tree (gnat_entity, NULL_TREE, false);

      if (Is_Incomplete_Or_Private_Type (gnat_entity)
	  && Present (Full_View (gnat_entity)))
	{
	  Entity_Id full_view = Full_View (gnat_entity);

	  save_gnu_tree (full_view, NULL_TREE, false);

          if (Is_Private_Type (full_view)
	      && Present (Underlying_Full_View (full_view)))
	    {
	      full_view = Underlying_Full_View (full_view);
	      save_gnu_tree (full_view, NULL_TREE, false);
	    }
	}

      if (Is_Type (gnat_entity)
	  && Present (Class_Wide_Type (gnat_entity))
	  && Root_Type (Class_Wide_Type (gnat_entity)) == gnat_entity)
	save_gnu_tree (Class_Wide_Type (gnat_entity), NULL_TREE, false);
    }

  if (Is_Incomplete_Or_Private_Type (gnat_entity)
      && Present (Full_View (gnat_entity)))
    {
      Entity_Id full_view = Full_View (gnat_entity);

      if (Is_Private_Type (full_view)
	  && Present (Underlying_Full_View (full_view)))
	full_view = Underlying_Full_View (full_view);

      gnu_new = gnat_to_gnu_entity (full_view, NULL_TREE, true);

      /* Propagate back-annotations from full view to partial view.  */
      if (!Known_Alignment (gnat_entity))
	Copy_Alignment (gnat_entity, full_view);

      if (!Known_Esize (gnat_entity))
	Copy_Esize (gnat_entity, full_view);

      if (!Known_RM_Size (gnat_entity))
	Copy_RM_Size (gnat_entity, full_view);

      /* The above call may have defined this entity (the simplest example
	 of this is when we have a private enumeral type since the bounds
	 will have the public view).  */
      if (!present_gnu_tree (gnat_entity))
	save_gnu_tree (gnat_entity, gnu_new, false);
    }
  else
    {
      /* For an object whose elaboration is deferred, the GCC tree of the
	 declaration, if any, is the initialization expression.  */
      const Node_Id gnat_decl = Declaration_Node (gnat_entity);
      tree gnu_init
	= (Nkind (gnat_decl) == N_Object_Declaration
	   || Nkind (gnat_decl) == N_Object_Renaming_Declaration)
	  && Present (Freeze_Node (gnat_entity))
	  && present_gnu_tree (gnat_decl)
	  ? get_gnu_tree (gnat_decl) : NULL_TREE;

      gnu_new = gnat_to_gnu_entity (gnat_entity, gnu_init, true);
    }

  if (Is_Type (gnat_entity)
      && Present (Class_Wide_Type (gnat_entity))
      && Root_Type (Class_Wide_Type (gnat_entity)) == gnat_entity)
    save_gnu_tree (Class_Wide_Type (gnat_entity), gnu_new, false);

  /* If we have an old type and we've made pointers to this type, update those
     pointers.  If this is a Taft amendment type in the main unit, we need to
     mark the type as used since other units referencing it don't see the full
     declaration and, therefore, cannot mark it as used themselves.  */
  if (gnu_old)
    {
      update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
			 TREE_TYPE (gnu_new));
      if (TYPE_DUMMY_IN_PROFILE_P (TREE_TYPE (gnu_old)))
	update_profiles_with (TREE_TYPE (gnu_old));
      if (DECL_TAFT_TYPE_P (gnu_old))
	used_types_insert (TREE_TYPE (gnu_new));
    }
}

/* Elaborate decls in the lists GNAT_DECLS and GNAT_DECLS2, if present.
   We make two passes, one to elaborate anything other than bodies (but
   we declare a function if there was no spec).  The second pass
   elaborates the bodies.

   We make a complete pass through both lists if PASS1P is true, then make
   the second pass over both lists if PASS2P is true.  The lists usually
   correspond to the public and private parts of a package.  */

static void
process_decls (List_Id gnat_decls, List_Id gnat_decls2,
	       bool pass1p, bool pass2p)
{
  List_Id gnat_decl_array[2];
  Node_Id gnat_decl;
  int i;

  gnat_decl_array[0] = gnat_decls, gnat_decl_array[1] = gnat_decls2;

  if (pass1p)
    for (i = 0; i <= 1; i++)
      if (Present (gnat_decl_array[i]))
	for (gnat_decl = First (gnat_decl_array[i]);
	     Present (gnat_decl);
	     gnat_decl = Next (gnat_decl))
	  {
	    /* For package specs, we recurse inside the declarations,
	       thus taking the two pass approach inside the boundary.  */
	    if (Nkind (gnat_decl) == N_Package_Declaration)
	      process_decls (Visible_Declarations (Specification (gnat_decl)),
			     Private_Declarations (Specification (gnat_decl)),
			     true, false);

	    /* Similarly for any declarations in the actions of a
	       freeze node.  */
	    else if (Nkind (gnat_decl) == N_Freeze_Entity)
	      {
		process_freeze_entity (gnat_decl);
		process_decls (Actions (gnat_decl), Empty, true, false);
	      }

	    /* Package bodies with freeze nodes get their elaboration deferred
	       until the freeze node, but the code must be placed in the right
	       place, so record the code position now.  */
	    else if (Nkind (gnat_decl) == N_Package_Body
		     && Present (Freeze_Node (Corresponding_Spec (gnat_decl))))
	      record_code_position (gnat_decl);

	    else if (Nkind (gnat_decl) == N_Package_Body_Stub
		     && Present (Library_Unit (gnat_decl))
		     && Present (Freeze_Node
				 (Corresponding_Spec
				  (Proper_Body (Unit
						(Library_Unit (gnat_decl)))))))
	      record_code_position
		(Proper_Body (Unit (Library_Unit (gnat_decl))));

	    /* We defer most subprogram bodies to the second pass.  For bodies
	       that act as their own specs and stubs, the entity itself must be
	       elaborated in the first pass, because it may be used in other
	       declarations.  */
	    else if (Nkind (gnat_decl) == N_Subprogram_Body)
	      {
		if (Acts_As_Spec (gnat_decl))
		  {
		    Entity_Id gnat_subprog = Defining_Entity (gnat_decl);

		    if (!Is_Generic_Subprogram (gnat_subprog))
		      gnat_to_gnu_entity (gnat_subprog, NULL_TREE, true);
		  }
	      }

	    else if (Nkind (gnat_decl) == N_Subprogram_Body_Stub)
	      {
		Entity_Id gnat_subprog
		  = Defining_Entity (Specification (gnat_decl));

		if (!Is_Generic_Subprogram (gnat_subprog)
		    && Ekind (gnat_subprog) != E_Subprogram_Body)
		  gnat_to_gnu_entity (gnat_subprog, NULL_TREE, true);
	      }

	    /* Concurrent stubs stand for the corresponding subprogram bodies,
	       which are deferred like other bodies.  */
	    else if (Nkind (gnat_decl) == N_Task_Body_Stub
		     || Nkind (gnat_decl) == N_Protected_Body_Stub)
	      ;

	    /* Renamed subprograms may not be elaborated yet at this point
	       since renamings do not trigger freezing.  Wait for the second
	       pass to take care of them.  */
	    else if (Nkind (gnat_decl) == N_Subprogram_Renaming_Declaration)
	      ;

	    else
	      add_stmt (gnat_to_gnu (gnat_decl));
	  }

  /* Here we elaborate everything we deferred above except for package bodies,
     which are elaborated at their freeze nodes.  Note that we must also
     go inside things (package specs and freeze nodes) the first pass did.  */
  if (pass2p)
    for (i = 0; i <= 1; i++)
      if (Present (gnat_decl_array[i]))
	for (gnat_decl = First (gnat_decl_array[i]);
	     Present (gnat_decl);
	     gnat_decl = Next (gnat_decl))
	  {
	    if (Nkind (gnat_decl) == N_Subprogram_Body
		|| Nkind (gnat_decl) == N_Subprogram_Body_Stub
		|| Nkind (gnat_decl) == N_Task_Body_Stub
		|| Nkind (gnat_decl) == N_Protected_Body_Stub)
	      add_stmt (gnat_to_gnu (gnat_decl));

	    else if (Nkind (gnat_decl) == N_Package_Declaration)
	      process_decls (Visible_Declarations (Specification (gnat_decl)),
			     Private_Declarations (Specification (gnat_decl)),
			     false, true);

	    else if (Nkind (gnat_decl) == N_Freeze_Entity)
	      process_decls (Actions (gnat_decl), Empty, false, true);

	    else if (Nkind (gnat_decl) == N_Subprogram_Renaming_Declaration)
	      add_stmt (gnat_to_gnu (gnat_decl));
	  }
}

/* Make a unary operation of kind CODE using build_unary_op, but guard
   the operation by an overflow check.  CODE can be one of NEGATE_EXPR
   or ABS_EXPR.  GNU_TYPE is the type desired for the result.  Usually
   the operation is to be performed in that type.  GNAT_NODE is the gnat
   node conveying the source location for which the error should be
   signaled.  */

static tree
build_unary_op_trapv (enum tree_code code, tree gnu_type, tree operand,
		      Node_Id gnat_node)
{
  gcc_assert (code == NEGATE_EXPR || code == ABS_EXPR);

  tree gnu_expr, check;

  operand = gnat_protect_expr (operand);

  gnu_expr = build_unary_op (code, gnu_type, operand);

  if (TYPE_UNSIGNED (gnu_type))
    {
      if (code == ABS_EXPR)
	return gnu_expr;
      else
	check = build_binary_op (NE_EXPR, boolean_type_node,
				 operand, TYPE_MIN_VALUE (gnu_type));
    }
  else
    check = build_binary_op (EQ_EXPR, boolean_type_node,
			     operand, TYPE_MIN_VALUE (gnu_type));

  return emit_check (check, gnu_expr, CE_Overflow_Check_Failed, gnat_node);
}

/* Make a binary operation of kind CODE using build_binary_op, but guard
   the operation by an overflow check.  CODE can be one of PLUS_EXPR,
   MINUS_EXPR or MULT_EXPR.  GNU_TYPE is the type desired for the result.
   Usually the operation is to be performed in that type.  GNAT_NODE is
   the GNAT node conveying the source location for which the error should
   be signaled.  */

static tree
build_binary_op_trapv (enum tree_code code, tree gnu_type, tree left,
		       tree right, Node_Id gnat_node)
{
  const unsigned int precision = TYPE_PRECISION (gnu_type);
  tree lhs = gnat_protect_expr (left);
  tree rhs = gnat_protect_expr (right);
  tree type_max = TYPE_MAX_VALUE (gnu_type);
  tree type_min = TYPE_MIN_VALUE (gnu_type);
  tree gnu_expr, check;
  int sgn;

  /* Assert that the precision is a power of 2.  */
  gcc_assert ((precision & (precision - 1)) == 0);

  /* Prefer a constant on the RHS to simplify checks.  */
  if (TREE_CODE (rhs) != INTEGER_CST
      && TREE_CODE (lhs) == INTEGER_CST
      && (code == PLUS_EXPR || code == MULT_EXPR))
    {
      tree tmp = lhs;
      lhs = rhs;
      rhs = tmp;
    }

  gnu_expr = build_binary_op (code, gnu_type, lhs, rhs);

  /* If we can fold the expression to a constant, just return it.
     The caller will deal with overflow, no need to generate a check.  */
  if (TREE_CODE (gnu_expr) == INTEGER_CST)
    return gnu_expr;

  /* If no operand is a constant, we use the generic implementation.  */
  if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (rhs) != INTEGER_CST)
    {
      /* First convert the operands to the result type like build_binary_op.
	 This is where the bias is made explicit for biased types.  */
      lhs = convert (gnu_type, lhs);
      rhs = convert (gnu_type, rhs);

      /* Never inline a 64-bit mult for a 32-bit target, it's way too long.  */
      if (code == MULT_EXPR && precision == 64 && BITS_PER_WORD < 64)
	{
	  tree int64 = gnat_type_for_size (64, TYPE_UNSIGNED (gnu_type));
	  Check_Restriction_No_Dependence_On_System (Name_Arith_64, gnat_node);
	  return
	    convert (gnu_type, build_call_n_expr (TYPE_UNSIGNED (gnu_type)
						  ? uns_mulv64_decl
						  : mulv64_decl,
						  2,
						  convert (int64, lhs),
						  convert (int64, rhs)));
	}

      /* Likewise for a 128-bit mult and a 64-bit target.  */
      else if (code == MULT_EXPR && precision == 128 && BITS_PER_WORD < 128)
	{
	  tree int128 = gnat_type_for_size (128, TYPE_UNSIGNED (gnu_type));
	  Check_Restriction_No_Dependence_On_System (Name_Arith_128, gnat_node);
	  return
	    convert (gnu_type, build_call_n_expr (TYPE_UNSIGNED (gnu_type)
						  ? uns_mulv128_decl
						  : mulv128_decl,
						  2,
						  convert (int128, lhs),
						  convert (int128, rhs)));
	}

      enum internal_fn icode;

      switch (code)
	{
	case PLUS_EXPR:
	  icode = IFN_ADD_OVERFLOW;
	  break;
	case MINUS_EXPR:
	  icode = IFN_SUB_OVERFLOW;
	  break;
	case MULT_EXPR:
	  icode = IFN_MUL_OVERFLOW;
	  break;
	default:
	  gcc_unreachable ();
	}

      tree gnu_ctype = build_complex_type (gnu_type);
      tree call
	= build_call_expr_internal_loc (UNKNOWN_LOCATION, icode, gnu_ctype, 2,
					lhs, rhs);
      tree tgt = save_expr (call);
      gnu_expr = build1 (REALPART_EXPR, gnu_type, tgt);
      check = fold_build2 (NE_EXPR, boolean_type_node,
			   build1 (IMAGPART_EXPR, gnu_type, tgt),
			   build_int_cst (gnu_type, 0));
      return
	emit_check (check, gnu_expr, CE_Overflow_Check_Failed, gnat_node);
   }

  /* If one operand is a constant, we expose the overflow condition to enable
     a subsequent simplification or even elimination.  */
  switch (code)
    {
    case PLUS_EXPR:
      sgn = tree_int_cst_sgn (rhs);
      if (sgn > 0)
	/* When rhs > 0, overflow when lhs > type_max - rhs.  */
	check = build_binary_op (GT_EXPR, boolean_type_node, lhs,
				 build_binary_op (MINUS_EXPR, gnu_type,
						  type_max, rhs));
      else if (sgn < 0)
	/* When rhs < 0, overflow when lhs < type_min - rhs.  */
	check = build_binary_op (LT_EXPR, boolean_type_node, lhs,
				 build_binary_op (MINUS_EXPR, gnu_type,
						  type_min, rhs));
      else
	return gnu_expr;
      break;

    case MINUS_EXPR:
      if (TREE_CODE (lhs) == INTEGER_CST && TYPE_UNSIGNED (gnu_type))
	/* In the unsigned case, overflow when rhs > lhs - type_min.  */
	check = build_binary_op (GT_EXPR, boolean_type_node, rhs,
				 build_binary_op (MINUS_EXPR, gnu_type,
						  lhs, type_min));
      else if (TREE_CODE (lhs) == INTEGER_CST)
	{
	  sgn = tree_int_cst_sgn (lhs);
	  if (sgn >= 0)
	    /* When lhs >= 0, overflow when rhs < lhs - type_max.  */
	    check = build_binary_op (LT_EXPR, boolean_type_node, rhs,
				     build_binary_op (MINUS_EXPR, gnu_type,
						      lhs, type_max));
	  else
	    /* When lhs < 0, overflow when rhs > lhs - type_min.  */
	    check = build_binary_op (GT_EXPR, boolean_type_node, rhs,
				     build_binary_op (MINUS_EXPR, gnu_type,
						      lhs, type_min));
	}
      else
	{
	  sgn = tree_int_cst_sgn (rhs);
	  if (sgn > 0)
	    /* When rhs > 0, overflow when lhs < type_min + rhs.  */
	    check = build_binary_op (LT_EXPR, boolean_type_node, lhs,
				     build_binary_op (PLUS_EXPR, gnu_type,
						      type_min, rhs));
	  else if (sgn < 0)
	    /* When rhs < 0, overflow when lhs > type_max + rhs.  */
	    check = build_binary_op (GT_EXPR, boolean_type_node, lhs,
				     build_binary_op (PLUS_EXPR, gnu_type,
						      type_max, rhs));
	  else
	    return gnu_expr;
	}
      break;

    case MULT_EXPR:
      sgn = tree_int_cst_sgn (rhs);
      if (sgn > 0)
	{
	  if (integer_onep (rhs))
	    return gnu_expr;

	  tree lb = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_min, rhs);
	  tree ub = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_max, rhs);

	  /* When rhs > 1, overflow outside [type_min/rhs; type_max/rhs].  */
	  check
	    = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node,
			       build_binary_op (LT_EXPR, boolean_type_node,
						lhs, lb),
			       build_binary_op (GT_EXPR, boolean_type_node,
						lhs, ub));
	}
      else if (sgn < 0)
	{
	  tree lb = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_max, rhs);
	  tree ub = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_min, rhs);

	  if (integer_minus_onep (rhs))
	    /* When rhs == -1, overflow if lhs == type_min.  */
	    check
	      = build_binary_op (EQ_EXPR, boolean_type_node, lhs, type_min);
	  else
	    /* When rhs < -1, overflow outside [type_max/rhs; type_min/rhs].  */
	    check
	      = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node,
				 build_binary_op (LT_EXPR, boolean_type_node,
						  lhs, lb),
				 build_binary_op (GT_EXPR, boolean_type_node,
						  lhs, ub));
	}
      else
	return gnu_expr;
      break;

    default:
      gcc_unreachable ();
    }

  return emit_check (check, gnu_expr, CE_Overflow_Check_Failed, gnat_node);
}

/* GNU_COND contains the condition corresponding to an index, overflow or
   range check of value GNU_EXPR.  Build a COND_EXPR that returns GNU_EXPR
   if GNU_COND is false and raises a CONSTRAINT_ERROR if GNU_COND is true.
   REASON is the code that says why the exception is raised.  GNAT_NODE is
   the node conveying the source location for which the error should be
   signaled.

   We used to propagate TREE_SIDE_EFFECTS from GNU_EXPR to the COND_EXPR,
   overwriting the setting inherited from the call statement, on the ground
   that the expression need not be evaluated just for the check.  However
   that's incorrect because, in the GCC type system, its value is presumed
   to be valid so its comparison against the type bounds always yields true
   and, therefore, could be done without evaluating it; given that it can
   be a computation that overflows the bounds, the language may require the
   check to fail and thus the expression to be evaluated in this case.  */

static tree
emit_check (tree gnu_cond, tree gnu_expr, int reason, Node_Id gnat_node)
{
  tree gnu_call
    = build_call_raise (reason, gnat_node, N_Raise_Constraint_Error);
  return
    fold_build3 (COND_EXPR, TREE_TYPE (gnu_expr), gnu_cond,
		 build2 (COMPOUND_EXPR, TREE_TYPE (gnu_expr), gnu_call,
			 SCALAR_FLOAT_TYPE_P (TREE_TYPE (gnu_expr))
			 ? build_real (TREE_TYPE (gnu_expr), dconst0)
			 : build_int_cst (TREE_TYPE (gnu_expr), 0)),
		 gnu_expr);
}

/* Return an expression that converts GNU_EXPR to GNAT_TYPE, doing overflow
   checks if OVERFLOW_P is true.  If TRUNCATE_P is true, do a fp-to-integer
   conversion with truncation, otherwise round.  GNAT_NODE is the GNAT node
   conveying the source location for which the error should be signaled.  */

static tree
convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflow_p,
		    bool truncate_p, Node_Id gnat_node)
{
  tree gnu_type = get_unpadded_type (gnat_type);
  tree gnu_base_type = get_base_type (gnu_type);
  tree gnu_in_type = TREE_TYPE (gnu_expr);
  tree gnu_in_base_type = get_base_type (gnu_in_type);
  tree gnu_result = gnu_expr;

  /* If we are not doing any checks, the output is an integral type and the
     input is not a floating-point type, just do the conversion.  This is
     required for packed array types and is simpler in all cases anyway.   */
  if (!overflow_p
      && INTEGRAL_TYPE_P (gnu_base_type)
      && !FLOAT_TYPE_P (gnu_in_base_type))
    return convert (gnu_type, gnu_expr);

  /* If the mode of the input base type is larger, then converting to it below
     may pessimize the final conversion step, for example generate a libcall
     instead of a simple instruction, so use a narrower type in this case.  */
  if (TYPE_MODE (gnu_in_base_type) != TYPE_MODE (gnu_in_type)
      && !(TREE_CODE (gnu_in_type) == INTEGER_TYPE
	   && TYPE_BIASED_REPRESENTATION_P (gnu_in_type)))
    gnu_in_base_type = gnat_type_for_mode (TYPE_MODE (gnu_in_type),
					   TYPE_UNSIGNED (gnu_in_type));

  /* First convert the expression to the base type.  This will never generate
     code, but makes the tests below simpler.  But don't do this if converting
     from an integer type to an unconstrained array type since then we need to
     get the bounds from the original (unpacked) type.  */
  if (TREE_CODE (gnu_type) != UNCONSTRAINED_ARRAY_TYPE)
    gnu_result = convert (gnu_in_base_type, gnu_result);

  /* If overflow checks are requested,  we need to be sure the result will fit
     in the output base type.  But don't do this if the input is integer and
     the output floating-point.  */
  if (overflow_p
      && !(FLOAT_TYPE_P (gnu_base_type) && INTEGRAL_TYPE_P (gnu_in_base_type)))
    {
      /* Ensure GNU_EXPR only gets evaluated once.  */
      tree gnu_input = gnat_protect_expr (gnu_result);
      tree gnu_cond = boolean_false_node;
      tree gnu_in_lb = TYPE_MIN_VALUE (gnu_in_base_type);
      tree gnu_in_ub = TYPE_MAX_VALUE (gnu_in_base_type);
      tree gnu_out_lb = TYPE_MIN_VALUE (gnu_base_type);
      tree gnu_out_ub
	= (TREE_CODE (gnu_base_type) == INTEGER_TYPE
	   && TYPE_MODULAR_P (gnu_base_type))
	  ? fold_build2 (MINUS_EXPR, gnu_base_type,
			 TYPE_MODULUS (gnu_base_type),
			 build_int_cst (gnu_base_type, 1))
	  : TYPE_MAX_VALUE (gnu_base_type);

      /* Convert the lower bounds to signed types, so we're sure we're
	 comparing them properly.  Likewise, convert the upper bounds
	 to unsigned types.  */
      if (INTEGRAL_TYPE_P (gnu_in_base_type)
	  && TYPE_UNSIGNED (gnu_in_base_type))
	gnu_in_lb
	  = convert (gnat_signed_type_for (gnu_in_base_type), gnu_in_lb);

      if (INTEGRAL_TYPE_P (gnu_in_base_type)
	  && !TYPE_UNSIGNED (gnu_in_base_type))
	gnu_in_ub
	  = convert (gnat_unsigned_type_for (gnu_in_base_type), gnu_in_ub);

      if (INTEGRAL_TYPE_P (gnu_base_type) && TYPE_UNSIGNED (gnu_base_type))
	gnu_out_lb
	  = convert (gnat_signed_type_for (gnu_base_type), gnu_out_lb);

      if (INTEGRAL_TYPE_P (gnu_base_type) && !TYPE_UNSIGNED (gnu_base_type))
	gnu_out_ub
	  = convert (gnat_unsigned_type_for (gnu_base_type), gnu_out_ub);

      /* Check each bound separately and only if the result bound
	 is tighter than the bound on the input type.  Note that all the
	 types are base types, so the bounds must be constant. Also,
	 the comparison is done in the base type of the input, which
	 always has the proper signedness.  First check for input
	 integer (which means output integer), output float (which means
	 both float), or mixed, in which case we always compare.
	 Note that we have to do the comparison which would *fail* in the
	 case of an error since if it's an FP comparison and one of the
	 values is a NaN or Inf, the comparison will fail.  */
      if (INTEGRAL_TYPE_P (gnu_in_base_type)
	  ? tree_int_cst_lt (gnu_in_lb, gnu_out_lb)
	  : (FLOAT_TYPE_P (gnu_base_type)
	     ? real_less (&TREE_REAL_CST (gnu_in_lb),
			  &TREE_REAL_CST (gnu_out_lb))
	     : 1))
	gnu_cond
	  = invert_truthvalue
	    (build_binary_op (GE_EXPR, boolean_type_node,
			      gnu_input, convert (gnu_in_base_type,
						  gnu_out_lb)));

      if (INTEGRAL_TYPE_P (gnu_in_base_type)
	  ? tree_int_cst_lt (gnu_out_ub, gnu_in_ub)
	  : (FLOAT_TYPE_P (gnu_base_type)
	     ? real_less (&TREE_REAL_CST (gnu_out_ub),
			  &TREE_REAL_CST (gnu_in_ub))
	     : 1))
	gnu_cond
	  = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, gnu_cond,
			     invert_truthvalue
			     (build_binary_op (LE_EXPR, boolean_type_node,
					       gnu_input,
					       convert (gnu_in_base_type,
							gnu_out_ub))));

      if (!integer_zerop (gnu_cond))
	gnu_result = emit_check (gnu_cond, gnu_input,
				 CE_Overflow_Check_Failed, gnat_node);
    }

  /* Now convert to the result base type.  If this is a non-truncating
     float-to-integer conversion, round.  */
  if (INTEGRAL_TYPE_P (gnu_base_type)
      && FLOAT_TYPE_P (gnu_in_base_type)
      && !truncate_p)
    {
      REAL_VALUE_TYPE half_minus_pred_half, pred_half;
      tree gnu_conv, gnu_zero, gnu_comp, calc_type;
      tree gnu_pred_half, gnu_add_pred_half, gnu_subtract_pred_half;
      const struct real_format *fmt;

      /* The following calculations depend on proper rounding to even
	 of each arithmetic operation.  In order to prevent excess
	 precision from spoiling this property, use the widest hardware
	 floating-point type if FP_ARITH_MAY_WIDEN is true.  */
      calc_type
	= fp_arith_may_widen ? longest_float_type_node : gnu_in_base_type;

      /* Compute the exact value calc_type'Pred (0.5) at compile time.  */
      fmt = REAL_MODE_FORMAT (TYPE_MODE (calc_type));
      real_2expN (&half_minus_pred_half, -(fmt->p) - 1, TYPE_MODE (calc_type));
      real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf,
		       &half_minus_pred_half);
      gnu_pred_half = build_real (calc_type, pred_half);

      /* If the input is strictly negative, subtract this value
	 and otherwise add it from the input.  For 0.5, the result
	 is exactly between 1.0 and the machine number preceding 1.0
	 (for calc_type).  Since the last bit of 1.0 is even, this 0.5
	 will round to 1.0, while all other number with an absolute
	 value less than 0.5 round to 0.0.  For larger numbers exactly
	 halfway between integers, rounding will always be correct as
	 the true mathematical result will be closer to the higher
	 integer compared to the lower one.  So, this constant works
	 for all floating-point numbers.

	 The reason to use the same constant with subtract/add instead
	 of a positive and negative constant is to allow the comparison
	 to be scheduled in parallel with retrieval of the constant and
	 conversion of the input to the calc_type (if necessary).  */

      gnu_zero = build_real (gnu_in_base_type, dconst0);
      gnu_result = gnat_protect_expr (gnu_result);
      gnu_conv = convert (calc_type, gnu_result);
      gnu_comp
	= fold_build2 (GE_EXPR, boolean_type_node, gnu_result, gnu_zero);
      gnu_add_pred_half
	= fold_build2 (PLUS_EXPR, calc_type, gnu_conv, gnu_pred_half);
      gnu_subtract_pred_half
	= fold_build2 (MINUS_EXPR, calc_type, gnu_conv, gnu_pred_half);
      gnu_result = fold_build3 (COND_EXPR, calc_type, gnu_comp,
				gnu_add_pred_half, gnu_subtract_pred_half);
    }

  if (TREE_CODE (gnu_base_type) == INTEGER_TYPE
      && TYPE_HAS_ACTUAL_BOUNDS_P (gnu_base_type)
      && TREE_CODE (gnu_result) == UNCONSTRAINED_ARRAY_REF)
    gnu_result = unchecked_convert (gnu_base_type, gnu_result, false);
  else
    gnu_result = convert (gnu_base_type, gnu_result);

  /* If this is a conversion between an integer type larger than a word and a
     floating-point type, then declare the dependence on the libgcc routine.  */
  if ((INTEGRAL_TYPE_P (gnu_in_base_type)
       && TYPE_PRECISION (gnu_in_base_type) > BITS_PER_WORD
       && FLOAT_TYPE_P (gnu_base_type))
      || (FLOAT_TYPE_P (gnu_in_base_type)
	  && INTEGRAL_TYPE_P (gnu_base_type)
	  && TYPE_PRECISION (gnu_base_type) > BITS_PER_WORD))
    Check_Restriction_No_Dependence_On_System (Name_Gcc, gnat_node);

  return convert (gnu_type, gnu_result);
}

/* Return true if GNU_EXPR may be directly addressed.  This is the case
   unless it is an expression involving computation or if it involves a
   reference to a bitfield or to an object not sufficiently aligned for
   its type.  If GNU_TYPE is non-null, return true only if GNU_EXPR can
   be directly addressed as an object of this type.  COMPG is true when
   the predicate is invoked for compiler-generated code.

   *** Notes on addressability issues in the Ada compiler ***

   This predicate is necessary in order to bridge the gap between Gigi
   and the middle-end about addressability of GENERIC trees.  A tree
   is said to be addressable if it can be directly addressed, i.e. if
   its address can be taken, is a multiple of the type's alignment on
   strict-alignment architectures and returns the first storage unit
   assigned to the object represented by the tree.

   In the C family of languages, everything is in practice addressable
   at the language level, except for bit-fields.  This means that these
   compilers will take the address of any tree that doesn't represent
   a bit-field reference and expect the result to be the first storage
   unit assigned to the object.  Even in cases where this will result
   in unaligned accesses at run time, nothing is supposed to be done
   and the program is considered as erroneous instead (see PR c/18287).

   The implicit assumptions made in the middle-end are in keeping with
   the C viewpoint described above:
     - the address of a bit-field reference is supposed to be never
       taken; the compiler (generally) will stop on such a construct,
     - any other tree is addressable if it is formally addressable,
       i.e. if it is formally allowed to be the operand of ADDR_EXPR.

   In Ada, the viewpoint is the opposite one: nothing is addressable
   at the language level unless explicitly declared so.  This means
   that the compiler will both make sure that the trees representing
   references to addressable ("aliased" in Ada parlance) objects are
   addressable and make no real attempts at ensuring that the trees
   representing references to non-addressable objects are addressable.

   In the first case, Ada is effectively equivalent to C and handing
   down the direct result of applying ADDR_EXPR to these trees to the
   middle-end works flawlessly.  In the second case, Ada cannot afford
   to consider the program as erroneous if the address of trees that
   are not addressable is requested for technical reasons, unlike C;
   as a consequence, the Ada compiler must arrange for either making
   sure that this address is not requested in the middle-end or for
   compensating by inserting temporaries if it is requested in Gigi.

   The first goal can be achieved because the middle-end should not
   request the address of non-addressable trees on its own; the only
   exception is for the invocation of low-level block operations like
   memcpy, for which the addressability requirements are lower since
   the type's alignment can be disregarded.  In practice, this means
   that Gigi must make sure that such operations cannot be applied to
   non-BLKmode bit-fields.

   The second goal is achieved by means of the addressable_p predicate,
   which computes whether a temporary must be inserted by Gigi when the
   address of a tree is requested; if so, the address of the temporary
   will be used in lieu of that of the original tree and some glue code
   generated to connect everything together.  */

static bool
addressable_p (tree gnu_expr, tree gnu_type, bool compg)
{
  /* For an integral type, the size of the actual type of the object may not
     be greater than that of the expected type, otherwise an indirect access
     in the latter type wouldn't correctly set all the bits of the object.  */
  if (gnu_type
      && INTEGRAL_TYPE_P (gnu_type)
      && smaller_form_type_p (gnu_type, TREE_TYPE (gnu_expr)))
    return false;

  /* The size of the actual type of the object may not be smaller than that
     of the expected type, otherwise an indirect access in the latter type
     would be larger than the object.  But only record types need to be
     considered in practice for this case.  */
  if (gnu_type
      && TREE_CODE (gnu_type) == RECORD_TYPE
      && smaller_form_type_p (TREE_TYPE (gnu_expr), gnu_type))
    return false;

  switch (TREE_CODE (gnu_expr))
    {
    case VAR_DECL:
    case PARM_DECL:
    case FUNCTION_DECL:
    case RESULT_DECL:
      /* All DECLs are addressable: if they are in a register, we can force
	 them to memory.  */
      return true;

    case UNCONSTRAINED_ARRAY_REF:
    case INDIRECT_REF:
      /* Taking the address of a dereference yields the original pointer.  */
      return true;

    case STRING_CST:
    case INTEGER_CST:
    case REAL_CST:
      /* Taking the address yields a pointer to the constant pool.  */
      return true;

    case CONSTRUCTOR:
      /* Taking the address of a static constructor yields a pointer to the
	 tree constant pool.  */
      return TREE_STATIC (gnu_expr) ? true : false;

    case NULL_EXPR:
    case ADDR_EXPR:
    case SAVE_EXPR:
    case CALL_EXPR:
    case PLUS_EXPR:
    case MINUS_EXPR:
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
    case BIT_AND_EXPR:
    case BIT_NOT_EXPR:
      /* All rvalues are deemed addressable since taking their address will
	 force a temporary to be created by the middle-end.  */
      return true;

    case COMPOUND_EXPR:
      /* The address of a compound expression is that of its 2nd operand.  */
      return addressable_p (TREE_OPERAND (gnu_expr, 1), gnu_type, compg);

    case COND_EXPR:
      /* We accept &COND_EXPR as soon as both operands are addressable and
	 expect the outcome to be the address of the selected operand.  */
      return (addressable_p (TREE_OPERAND (gnu_expr, 1), NULL_TREE, compg)
	      && addressable_p (TREE_OPERAND (gnu_expr, 2), NULL_TREE, compg));

    case COMPONENT_REF:
      return (((!DECL_BIT_FIELD (TREE_OPERAND (gnu_expr, 1))
		/* Even with DECL_BIT_FIELD cleared, we have to ensure that
		   the field is sufficiently aligned, in case it is subject
		   to a pragma Component_Alignment.  But we don't need to
		   check the alignment of the containing record, since it
		   is guaranteed to be not smaller than that of its most
		   aligned field that is not a bit-field.  However, we need
		   to cope with quirks of ABIs that may misalign fields.  */
		&& (DECL_ALIGN (TREE_OPERAND (gnu_expr, 1))
		    >= default_field_alignment (TREE_OPERAND (gnu_expr, 1),
						TREE_TYPE (gnu_expr))
		    /* But this was historically not enforced for targets that
		       do not require strict alignment, so we keep not doing
		       it for 1) internal fields in order to keep supporting
		       misalignment of tagged types and 2) compiler-generated
		       code in order to avoid creating useless temporaries.  */
		    || (!STRICT_ALIGNMENT
			&& (DECL_INTERNAL_P (TREE_OPERAND (gnu_expr, 1))
			    || compg))))
	       /* The field of a padding record is always addressable.  */
	       || TYPE_IS_PADDING_P (TREE_TYPE (TREE_OPERAND (gnu_expr, 0))))
	      && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE, compg));

    case ARRAY_REF:  case ARRAY_RANGE_REF:
    case REALPART_EXPR:  case IMAGPART_EXPR:
    case NOP_EXPR:
      return addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE, compg);

    case CONVERT_EXPR:
      return (AGGREGATE_TYPE_P (TREE_TYPE (gnu_expr))
	      && addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE, compg));

    case VIEW_CONVERT_EXPR:
      {
	/* This is addressable only if a copy need not be made downstream.  */
	tree type = TREE_TYPE (gnu_expr);
	tree inner_type = TREE_TYPE (TREE_OPERAND (gnu_expr, 0));
	return (((TYPE_MODE (type) == TYPE_MODE (inner_type)
		  && (!STRICT_ALIGNMENT
		      || TYPE_ALIGN (type) <= TYPE_ALIGN (inner_type)
		      || TYPE_ALIGN (inner_type) >= BIGGEST_ALIGNMENT))
		 || ((TYPE_MODE (type) == BLKmode
		      || TYPE_MODE (inner_type) == BLKmode)
		     && (!STRICT_ALIGNMENT
			 || TYPE_ALIGN (type) <= TYPE_ALIGN (inner_type)
			 || TYPE_ALIGN (inner_type) >= BIGGEST_ALIGNMENT
			 || type_is_tagged_or_cw_equivalent (type)
			 || type_is_tagged_or_cw_equivalent (inner_type))))
		&& addressable_p (TREE_OPERAND (gnu_expr, 0), NULL_TREE,
				  compg));
      }

    default:
      return false;
    }
}

/* Return true if GNU_EXPR may be aliased by an object of GNU_TYPE in the
   context of by-reference parameter passing.  This is the case when the
   object (ultimately) referenced through GNU_EXPR has a type whose alias
   set is either effectively 0, or equal to, or a subset of the alias set
   of GNU_TYPE.

   When the predicate returns true, it is possible to take the address of
   GNU_EXPR without violating strict aliasing rules.  When it does not, no
   such guarantee holds, so a temporary with GNU_TYPE needs to be created
   and its address passed instead (provided that this be legal of course).  */

static bool
aliasable_p (tree gnu_expr, tree gnu_type)
{
  /* This is the source of the possible violation: taking the address of an
     object in a type that does not correspond to its declared type.  */
  if (TREE_CODE (gnu_expr) == VIEW_CONVERT_EXPR)
    gnu_expr = TREE_OPERAND (gnu_expr, 0);

  /* Work around get_deref_alias_set and alias_set_subset_of being disabled
     when flag_strict_aliasing is 0.  */
  const bool saved_flag_strict_aliasing = flag_strict_aliasing;

  flag_strict_aliasing = 1;

  /* Call get_deref_alias_set to catch ref-all and void* pointers.  */
  const alias_set_type set1
    = TREE_CODE (gnu_expr) == INDIRECT_REF
      ? get_deref_alias_set (TREE_OPERAND (gnu_expr, 0))
      : get_alias_set (TREE_TYPE (gnu_expr));
  const alias_set_type set2 = get_alias_set (gnu_type);

  bool ret = set1 == 0 || set1 == set2 || alias_set_subset_of (set1, set2);

  flag_strict_aliasing = saved_flag_strict_aliasing;

  return ret;
}

/* Do the processing for the declaration of a GNAT_ENTITY, a type or subtype.
   If a Freeze node exists for the entity, delay the bulk of the processing.
   Otherwise make a GCC type for GNAT_ENTITY and set up the correspondence.  */

void
process_type (Entity_Id gnat_entity)
{
  tree gnu_old
    = present_gnu_tree (gnat_entity) ? get_gnu_tree (gnat_entity) : NULL_TREE;

  /* If we are to delay elaboration of this type, just do any elaboration
     needed for expressions within the declaration and make a dummy node
     for it and its Full_View (if any), in case something points to it.
     Do not do this if it has already been done (the only way that can
     happen is if the private completion is also delayed).  */
  if (Present (Freeze_Node (gnat_entity)))
    {
      elaborate_entity (gnat_entity);

      if (!gnu_old)
	{
	  tree gnu_decl = TYPE_STUB_DECL (make_dummy_type (gnat_entity));
	  save_gnu_tree (gnat_entity, gnu_decl, false);
	  if (Is_Incomplete_Or_Private_Type (gnat_entity)
	      && Present (Full_View (gnat_entity)))
	    {
	      if (Has_Completion_In_Body (gnat_entity))
		DECL_TAFT_TYPE_P (gnu_decl) = 1;
	      save_gnu_tree (Full_View (gnat_entity), gnu_decl, false);
	    }
	}

      return;
    }

  /* If we saved away a dummy type for this node, it means that this made the
     type that corresponds to the full type of an incomplete type.  Clear that
     type for now and then update the type in the pointers below.  But, if the
     saved type is not dummy, it very likely means that we have a use before
     declaration for the type in the tree, what we really cannot handle.  */
  if (gnu_old)
    {
      gcc_assert (TREE_CODE (gnu_old) == TYPE_DECL
		  && TYPE_IS_DUMMY_P (TREE_TYPE (gnu_old)));

      save_gnu_tree (gnat_entity, NULL_TREE, false);
    }

  /* Now fully elaborate the type.  */
  tree gnu_new = gnat_to_gnu_entity (gnat_entity, NULL_TREE, true);
  gcc_assert (TREE_CODE (gnu_new) == TYPE_DECL);

  /* If we have an old type and we've made pointers to this type, update those
     pointers.  If this is a Taft amendment type in the main unit, we need to
     mark the type as used since other units referencing it don't see the full
     declaration and, therefore, cannot mark it as used themselves.  */
  if (gnu_old)
    {
      update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
			 TREE_TYPE (gnu_new));
      if (DECL_TAFT_TYPE_P (gnu_old))
	used_types_insert (TREE_TYPE (gnu_new));
    }

  /* If this is a record type corresponding to a task or protected type
     that is a completion of an incomplete type, perform a similar update
     on the type.  ??? Including protected types here is a guess.  */
  if (Is_Record_Type (gnat_entity)
      && Is_Concurrent_Record_Type (gnat_entity)
      && present_gnu_tree (Corresponding_Concurrent_Type (gnat_entity)))
    {
      tree gnu_task_old
	= get_gnu_tree (Corresponding_Concurrent_Type (gnat_entity));

      save_gnu_tree (Corresponding_Concurrent_Type (gnat_entity),
		     NULL_TREE, false);
      save_gnu_tree (Corresponding_Concurrent_Type (gnat_entity),
		     gnu_new, false);

      update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_task_old)),
			 TREE_TYPE (gnu_new));
    }
}

/* Subroutine of assoc_to_constructor: VALUES is a list of field associations,
   some of which are from RECORD_TYPE.  Return a CONSTRUCTOR consisting of the
   associations that are from RECORD_TYPE.  If we see an internal record, make
   a recursive call to fill it in as well.  */

static tree
extract_values (tree values, tree record_type)
{
  vec<constructor_elt, va_gc> *v = NULL;
  tree field;

  for (field = TYPE_FIELDS (record_type); field; field = DECL_CHAIN (field))
    {
      tree tem, value = NULL_TREE;

      /* _Parent is an internal field, but may have values in the aggregate,
	 so check for values first.  */
      if ((tem = purpose_member (field, values)))
	{
	  value = TREE_VALUE (tem);
	  TREE_ADDRESSABLE (tem) = 1;
	}

      else if (DECL_INTERNAL_P (field))
	{
	  value = extract_values (values, TREE_TYPE (field));
	  if (TREE_CODE (value) == CONSTRUCTOR
	      && vec_safe_is_empty (CONSTRUCTOR_ELTS (value)))
	    value = NULL_TREE;
	}
      else
	/* If we have a record subtype, the names will match, but not the
	   actual FIELD_DECLs.  */
	for (tem = values; tem; tem = TREE_CHAIN (tem))
	  if (DECL_NAME (TREE_PURPOSE (tem)) == DECL_NAME (field))
	    {
	      value = convert (TREE_TYPE (field), TREE_VALUE (tem));
	      TREE_ADDRESSABLE (tem) = 1;
	    }

      if (!value)
	continue;

      CONSTRUCTOR_APPEND_ELT (v, field, value);
    }

  return gnat_build_constructor (record_type, v);
}

/* GNAT_ENTITY is the type of the resulting constructor, GNAT_ASSOC is the
   front of the Component_Associations of an N_Aggregate and GNU_TYPE is the
   GCC type of the corresponding record type.  Return the CONSTRUCTOR.  */

static tree
assoc_to_constructor (Entity_Id gnat_entity, Node_Id gnat_assoc, tree gnu_type)
{
  tree gnu_list = NULL_TREE, gnu_result;

  /* We test for GNU_FIELD being empty in the case where a variant
     was the last thing since we don't take things off GNAT_ASSOC in
     that case.  We check GNAT_ASSOC in case we have a variant, but it
     has no fields.  */

  for (; Present (gnat_assoc); gnat_assoc = Next (gnat_assoc))
    {
      const Node_Id gnat_field = First (Choices (gnat_assoc));
      const Node_Id gnat_expr = Expression (gnat_assoc);
      tree gnu_field = gnat_to_gnu_field_decl (Entity (gnat_field));
      tree gnu_expr = gnat_to_gnu (Expression (gnat_assoc));

      /* The expander is supposed to put a single component selector name
	 in every record component association.  */
      gcc_assert (No (Next (gnat_field)));

      /* Ignore discriminants that have Corresponding_Discriminants in tagged
	 types since we'll be setting those fields in the parent subtype.  */
      if (Ekind (Entity (gnat_field)) == E_Discriminant
	  && Present (Corresponding_Discriminant (Entity (gnat_field)))
	  && Is_Tagged_Type (Scope (Entity (gnat_field))))
	continue;

      /* Also ignore discriminants of Unchecked_Unions.  */
      if (Ekind (Entity (gnat_field)) == E_Discriminant
	  && Is_Unchecked_Union (gnat_entity))
	continue;

      gigi_checking_assert (!Do_Range_Check (gnat_expr));

      /* Convert to the type of the field.  */
      gnu_expr = convert (TREE_TYPE (gnu_field), gnu_expr);

      /* Add the field and expression to the list.  */
      gnu_list = tree_cons (gnu_field, gnu_expr, gnu_list);
    }

  gnu_result = extract_values (gnu_list, gnu_type);

  if (flag_checking)
    {
      /* Verify that every entry in GNU_LIST was used.  */
      for (; gnu_list; gnu_list = TREE_CHAIN (gnu_list))
	gcc_assert (TREE_ADDRESSABLE (gnu_list));
    }

  return gnu_result;
}

/* Build a possibly nested constructor for array aggregates.  GNAT_EXPR is
   the first element of an array aggregate.  It may itself be an aggregate.
   GNU_ARRAY_TYPE is the GCC type corresponding to the array aggregate.  */

static tree
pos_to_constructor (Node_Id gnat_expr, tree gnu_array_type)
{
  tree gnu_index = TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_array_type));
  vec<constructor_elt, va_gc> *gnu_expr_vec = NULL;

  for (; Present (gnat_expr); gnat_expr = Next (gnat_expr))
    {
      tree gnu_expr;

      /* If the expression is itself an array aggregate then first build the
	 innermost constructor if it is part of our array (multi-dimensional
	 case).  */
      if (Nkind (gnat_expr) == N_Aggregate
	  && TREE_CODE (TREE_TYPE (gnu_array_type)) == ARRAY_TYPE
	  && TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_array_type)))
	gnu_expr = pos_to_constructor (First (Expressions (gnat_expr)),
				       TREE_TYPE (gnu_array_type));
      else
	{
	  /* If the expression is a conversion to an unconstrained array type,
	     skip it to avoid spilling to memory.  */
	  if (Nkind (gnat_expr) == N_Type_Conversion
	      && Is_Array_Type (Etype (gnat_expr))
	      && !Is_Constrained (Etype (gnat_expr)))
	    gnu_expr = gnat_to_gnu (Expression (gnat_expr));
	  else
	    gnu_expr = gnat_to_gnu (gnat_expr);

	  gigi_checking_assert (!Do_Range_Check (gnat_expr));
	}

      CONSTRUCTOR_APPEND_ELT (gnu_expr_vec, gnu_index,
			      convert (TREE_TYPE (gnu_array_type), gnu_expr));

      gnu_index = int_const_binop (PLUS_EXPR, gnu_index,
				   convert (TREE_TYPE (gnu_index),
					    integer_one_node));
    }

  return gnat_build_constructor (gnu_array_type, gnu_expr_vec);
}

/* Process a N_Validate_Unchecked_Conversion node.  */

static void
validate_unchecked_conversion (Node_Id gnat_node)
{
  tree gnu_source_type = gnat_to_gnu_type (Source_Type (gnat_node));
  tree gnu_target_type = gnat_to_gnu_type (Target_Type (gnat_node));

  /* If the target is a pointer type, see if we are either converting from a
     non-pointer or from a pointer to a type with a different alias set and
     warn if so, unless the pointer has been marked to alias everything.  */
  if (POINTER_TYPE_P (gnu_target_type)
      && !TYPE_REF_CAN_ALIAS_ALL (gnu_target_type))
    {
      tree gnu_source_desig_type = POINTER_TYPE_P (gnu_source_type)
				   ? TREE_TYPE (gnu_source_type)
				   : NULL_TREE;
      tree gnu_target_desig_type = TREE_TYPE (gnu_target_type);
      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type);

      if (target_alias_set != 0
	  && (!POINTER_TYPE_P (gnu_source_type)
	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type),
					 target_alias_set)))
	{
	  post_error_ne ("??possible aliasing problem for type&",
			 gnat_node, Target_Type (gnat_node));
	  post_error ("\\??use -fno-strict-aliasing switch for references",
		      gnat_node);
	  post_error_ne ("\\??or use `pragma No_Strict_Aliasing (&);`",
			 gnat_node, Target_Type (gnat_node));
	}
    }

  /* Likewise if the target is a fat pointer type, but we have no mechanism to
     mitigate the problem in this case, so we unconditionally warn.  */
  else if (TYPE_IS_FAT_POINTER_P (gnu_target_type))
    {
      tree gnu_source_desig_type
	= TYPE_IS_FAT_POINTER_P (gnu_source_type)
	  ? TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_source_type)))
	  : NULL_TREE;
      tree gnu_target_desig_type
	= TREE_TYPE (TREE_TYPE (TYPE_FIELDS (gnu_target_type)));
      alias_set_type target_alias_set = get_alias_set (gnu_target_desig_type);

      if (target_alias_set != 0
	  && (!TYPE_IS_FAT_POINTER_P (gnu_source_type)
	      || !alias_sets_conflict_p (get_alias_set (gnu_source_desig_type),
					 target_alias_set)))
	{
	  post_error_ne ("??possible aliasing problem for type&",
			 gnat_node, Target_Type (gnat_node));
	  post_error ("\\??use -fno-strict-aliasing switch for references",
		      gnat_node);
	}
    }
}

/* Convert SLOC into LOCUS.  Return true if SLOC corresponds to a
   source code location and false if it doesn't.  If CLEAR_COLUMN is
   true, set the column information to 0.  If DECL is given and SLOC
   refers to a File with an instance, map DECL to that instance.  */

bool
Sloc_to_locus (Source_Ptr Sloc, location_t *locus, bool clear_column,
	       const_tree decl)
{
  if (Sloc == No_Location)
    return false;

  if (Sloc <= Standard_Location)
    {
      *locus = BUILTINS_LOCATION;
      return false;
    }

  Source_File_Index file = Get_Source_File_Index (Sloc);
  Line_Number_Type line = Get_Logical_Line_Number (Sloc);
  Column_Number_Type column = (clear_column ? 0 : Get_Column_Number (Sloc));
  line_map_ordinary *map = LINEMAPS_ORDINARY_MAP_AT (line_table, file - 1);

  /* We can have zero if pragma Source_Reference is in effect.  */
  if (line < 1)
    line = 1;

  /* Translate the location.  */
  *locus
    = linemap_position_for_line_and_column (line_table, map, line, column);

  if (decl && file_map && file_map[file - 1].Instance)
    decl_to_instance_map->put (decl, file_map[file - 1].Instance);

  return true;
}

/* Return whether GNAT_NODE is a defining identifier for a renaming that comes
   from the parameter association for the instantiation of a generic.  We do
   not want to emit source location for them: the code generated for their
   initialization is likely to disturb debugging.  */

bool
renaming_from_instantiation_p (Node_Id gnat_node)
{
  if (Nkind (gnat_node) != N_Defining_Identifier
      || !Is_Object (gnat_node)
      || Comes_From_Source (gnat_node)
      || !Present (Renamed_Object (gnat_node)))
    return false;

  /* Get the object declaration of the renamed object, if any and if the
     renamed object is a mere identifier.  */
  gnat_node = Renamed_Object (gnat_node);
  if (Nkind (gnat_node) != N_Identifier)
    return false;

  gnat_node = Parent (Entity (gnat_node));
  return (Present (gnat_node)
	  && Nkind (gnat_node) == N_Object_Declaration
	  && Present (Corresponding_Generic_Association (gnat_node)));
}

/* Similar to set_expr_location, but start with the Sloc of GNAT_NODE and
   don't do anything if it doesn't correspond to a source location.  And,
   if CLEAR_COLUMN is true, set the column information to 0.  */

static void
set_expr_location_from_node (tree node, Node_Id gnat_node, bool clear_column)
{
  location_t locus;

  /* Do not set a location for constructs likely to disturb debugging.  */
  if (Nkind (gnat_node) == N_Defining_Identifier)
    {
      if (Is_Type (gnat_node) && Is_Actual_Subtype (gnat_node))
	return;

      if (renaming_from_instantiation_p (gnat_node))
	return;
    }

  if (!Sloc_to_locus (Sloc (gnat_node), &locus, clear_column))
    return;

  SET_EXPR_LOCATION (node, locus);
}

/* More elaborate version of set_expr_location_from_node to be used in more
   general contexts, for example the result of the translation of a generic
   GNAT node.  */

static void
set_gnu_expr_location_from_node (tree node, Node_Id gnat_node)
{
  /* Set the location information on the node if it is a real expression.
     References can be reused for multiple GNAT nodes and they would get
     the location information of their last use.  Also make sure not to
     overwrite an existing location as it is probably more precise.  */

  switch (TREE_CODE (node))
    {
    CASE_CONVERT:
    case NON_LVALUE_EXPR:
    case SAVE_EXPR:
      break;

    case COMPOUND_EXPR:
      if (EXPR_P (TREE_OPERAND (node, 1)))
	set_gnu_expr_location_from_node (TREE_OPERAND (node, 1), gnat_node);

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

    default:
      if (!REFERENCE_CLASS_P (node) && !EXPR_HAS_LOCATION (node))
	{
	  set_expr_location_from_node (node, gnat_node);
	  set_end_locus_from_node (node, gnat_node);
	}
      break;
    }
}

/* Set the end_locus information for GNU_NODE, if any, from an explicit end
   location associated with GNAT_NODE or GNAT_NODE itself, whichever makes
   most sense.  Return true if a sensible assignment was performed.  */

static bool
set_end_locus_from_node (tree gnu_node, Node_Id gnat_node)
{
  Node_Id gnat_end_label;
  location_t end_locus;

  /* Pick the GNAT node of which we'll take the sloc to assign to the GCC node
     end_locus when there is one.  We consider only GNAT nodes with a possible
     End_Label attached.  If the End_Label actually was unassigned, fallback
     on the original node.  We'd better assign an explicit sloc associated with
     the outer construct in any case.  */

  switch (Nkind (gnat_node))
    {
    case N_Package_Body:
    case N_Subprogram_Body:
    case N_Block_Statement:
      if (Present (Handled_Statement_Sequence (gnat_node)))
	gnat_end_label = End_Label (Handled_Statement_Sequence (gnat_node));
      else
	gnat_end_label = Empty;
      break;

    case N_Package_Declaration:
      gcc_checking_assert (Present (Specification (gnat_node)));
      gnat_end_label = End_Label (Specification (gnat_node));
      break;

    default:
      return false;
    }

  if (Present (gnat_end_label))
    gnat_node = gnat_end_label;

  /* Some expanded subprograms have neither an End_Label nor a Sloc
     attached.  Notify that to callers.  For a block statement with no
     End_Label, clear column information, so that the tree for a
     transient block does not receive the sloc of a source condition.  */
  if (!Sloc_to_locus (Sloc (gnat_node), &end_locus,
                      No (gnat_end_label)
                      && Nkind (gnat_node) == N_Block_Statement))
    return false;

  switch (TREE_CODE (gnu_node))
    {
    case BIND_EXPR:
      BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (gnu_node)) = end_locus;
      return true;

    case FUNCTION_DECL:
      DECL_STRUCT_FUNCTION (gnu_node)->function_end_locus = end_locus;
      return true;

    default:
      return false;
    }
}

/* Post an error message.  MSG is the error message, properly annotated.
   NODE is the node at which to post the error and the node to use for the
   '&' substitution.  */

void
post_error (const char *msg, Node_Id node)
{
  String_Template temp;
  String_Pointer sp;

  if (No (node))
    return;

  temp.Low_Bound = 1;
  temp.High_Bound = strlen (msg);
  sp.Bounds = &temp;
  sp.Array = msg;
  Error_Msg_N (sp, node);
}

/* Similar to post_error, but NODE is the node at which to post the error and
   ENT is the node to use for the '&' substitution.  */

void
post_error_ne (const char *msg, Node_Id node, Entity_Id ent)
{
  String_Template temp;
  String_Pointer sp;

  if (No (node))
    return;

  temp.Low_Bound = 1;
  temp.High_Bound = strlen (msg);
  sp.Bounds = &temp;
  sp.Array = msg;
  Error_Msg_NE (sp, node, ent);
}

/* Similar to post_error_ne, but NUM is the number to use for the '^'.  */

void
post_error_ne_num (const char *msg, Node_Id node, Entity_Id ent, int num)
{
  Error_Msg_Uint_1 = UI_From_Int (num);
  post_error_ne (msg, node, ent);
}

/* Similar to post_error_ne, but T is a GCC tree representing the number to
   write.  If T represents a constant, the text inside curly brackets in
   MSG will be output (presumably including a '^').  Otherwise it will not
   be output and the text inside square brackets will be output instead.  */

void
post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t)
{
  char *new_msg = XALLOCAVEC (char, strlen (msg) + 1);
  char start_yes, end_yes, start_no, end_no;
  const char *p;
  char *q;

  if (TREE_CODE (t) == INTEGER_CST)
    {
      Error_Msg_Uint_1 = UI_From_gnu (t);
      start_yes = '{', end_yes = '}', start_no = '[', end_no = ']';
    }
  else
    start_yes = '[', end_yes = ']', start_no = '{', end_no = '}';

  for (p = msg, q = new_msg; *p; p++)
    {
      if (*p == start_yes)
	for (p++; *p != end_yes; p++)
	  *q++ = *p;
      else if (*p == start_no)
	for (p++; *p != end_no; p++)
	  ;
      else
	*q++ = *p;
    }

  *q = 0;

  post_error_ne (new_msg, node, ent);
}

/* Similar to post_error_ne_tree, but NUM is a second integer to write.  */

void
post_error_ne_tree_2 (const char *msg, Node_Id node, Entity_Id ent, tree t,
		      int num)
{
  Error_Msg_Uint_2 = UI_From_Int (num);
  post_error_ne_tree (msg, node, ent, t);
}

/* Return a label to branch to for the exception type in KIND or Empty
   if none.  */

Entity_Id
get_exception_label (char kind)
{
  switch (kind)
    {
    case N_Raise_Constraint_Error:
      return gnu_constraint_error_label_stack.last ();

    case N_Raise_Storage_Error:
      return gnu_storage_error_label_stack.last ();

    case N_Raise_Program_Error:
      return gnu_program_error_label_stack.last ();

    default:
      return Empty;
    }

  gcc_unreachable ();
}

/* Return the decl for the current elaboration procedure.  */

static tree
get_elaboration_procedure (void)
{
  return gnu_elab_proc_stack->last ();
}

/* Return the controlling type of a dispatching subprogram.  */

static Entity_Id
get_controlling_type (Entity_Id subprog)
{
  /* This is modeled on Expand_Interface_Thunk.  */
  Entity_Id controlling_type = Etype (First_Formal (subprog));
  if (Is_Access_Type (controlling_type))
    controlling_type = Directly_Designated_Type (controlling_type);
  controlling_type = Underlying_Type (controlling_type);
  if (Is_Concurrent_Type (controlling_type))
    controlling_type = Corresponding_Record_Type (controlling_type);
  controlling_type = Base_Type (controlling_type);
  return controlling_type;
}

/* Return whether we should use an alias for the TARGET of a thunk
   in order to make the call generated in the thunk local.  */

static bool
use_alias_for_thunk_p (tree target)
{
  /* We cannot generate a local call in this case.  */
  if (DECL_EXTERNAL (target) || DECL_ONE_ONLY (target))
    return false;

  /* The call is already local in this case.  */
  if (TREE_CODE (DECL_CONTEXT (target)) == FUNCTION_DECL)
    return false;

  return TARGET_USE_LOCAL_THUNK_ALIAS_P (target);
}

static GTY(()) unsigned long thunk_labelno = 0;

/* Create an alias for TARGET to be used as the target of a thunk.  */

static tree
make_alias_for_thunk (tree target)
{
  char buf[64];
  targetm.asm_out.generate_internal_label (buf, "LTHUNK", thunk_labelno++);

  tree alias = build_decl (DECL_SOURCE_LOCATION (target), TREE_CODE (target),
			   get_identifier (buf), TREE_TYPE (target));

  DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (target);
  DECL_CONTEXT (alias) = DECL_CONTEXT (target);
  TREE_READONLY (alias) = TREE_READONLY (target);
  TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (target);
  DECL_ARTIFICIAL (alias) = 1;
  DECL_INITIAL (alias) = error_mark_node;
  DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (target));
  TREE_ADDRESSABLE (alias) = 1;
  SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));

  cgraph_node *n = cgraph_node::create_same_body_alias (alias, target);
  gcc_assert (n);

  return alias;
}

/* Create the local covariant part of {GNAT,GNU}_THUNK.  */

static tree
make_covariant_thunk (Entity_Id gnat_thunk, tree gnu_thunk)
{
  tree gnu_name = create_concat_name (gnat_thunk, "CV");
  tree gnu_cv_thunk
    = build_decl (DECL_SOURCE_LOCATION (gnu_thunk), TREE_CODE (gnu_thunk),
		  gnu_name, TREE_TYPE (gnu_thunk));

  DECL_ARGUMENTS (gnu_cv_thunk) = copy_list (DECL_ARGUMENTS (gnu_thunk));
  for (tree param_decl = DECL_ARGUMENTS (gnu_cv_thunk);
       param_decl;
       param_decl = DECL_CHAIN (param_decl))
    DECL_CONTEXT (param_decl) = gnu_cv_thunk;

  DECL_RESULT (gnu_cv_thunk) = copy_node (DECL_RESULT (gnu_thunk));
  DECL_CONTEXT (DECL_RESULT (gnu_cv_thunk)) = gnu_cv_thunk;

  DECL_LANG_SPECIFIC (gnu_cv_thunk) = DECL_LANG_SPECIFIC (gnu_thunk);
  DECL_CONTEXT (gnu_cv_thunk) = DECL_CONTEXT (gnu_thunk);
  TREE_READONLY (gnu_cv_thunk) = TREE_READONLY (gnu_thunk);
  TREE_THIS_VOLATILE (gnu_cv_thunk) = TREE_THIS_VOLATILE (gnu_thunk);
  DECL_ARTIFICIAL (gnu_cv_thunk) = 1;

  return gnu_cv_thunk;
}

/* Try to create a GNU thunk for {GNAT,GNU}_THUNK and return true on success.

   GNU thunks are more efficient than GNAT thunks because they don't call into
   the runtime to retrieve the offset used in the displacement operation, but
   they are tailored to C++ and thus too limited to support the full range of
   thunks generated in Ada.  Here's the complete list of limitations:

     1. Multi-controlling thunks, i.e thunks with more than one controlling
	parameter, are simply not supported.

     2. Covariant thunks, i.e. thunks for which the result is also controlling,
	are split into a pair of (this, covariant-only) thunks.

     3. Variable-offset thunks, i.e. thunks for which the offset depends on the
	object and not only on its type, are supported as 2nd class citizens.

     4. External thunks, i.e. thunks for which the target is not declared in
	the same unit as the thunk, are supported as 2nd class citizens.

     5. Local thunks, i.e. thunks generated for a local type, are supported as
	2nd class citizens.  */

static bool
maybe_make_gnu_thunk (Entity_Id gnat_thunk, tree gnu_thunk)
{
  /* We use the Thunk_Target to compute the properties of the thunk.  */
  const Entity_Id gnat_target = Thunk_Target (gnat_thunk);

  /* Check that the first formal of the target is the only controlling one.  */
  Entity_Id gnat_formal = First_Formal (gnat_target);
  if (!Is_Controlling_Formal (gnat_formal))
    return false;
  for (gnat_formal = Next_Formal (gnat_formal);
       Present (gnat_formal);
       gnat_formal = Next_Formal (gnat_formal))
    if (Is_Controlling_Formal (gnat_formal))
      return false;

  /* Look for the types that control the target and the thunk.  */
  const Entity_Id gnat_controlling_type = get_controlling_type (gnat_target);
  const Entity_Id gnat_interface_type = get_controlling_type (gnat_thunk);

  /* We must have an interface type at this point.  */
  gcc_assert (Is_Interface (gnat_interface_type));

  /* Now compute whether the former covers the latter.  */
  const Entity_Id gnat_interface_tag
    = Find_Interface_Tag (gnat_controlling_type, gnat_interface_type);
  tree gnu_interface_tag
    = Present (gnat_interface_tag)
      ? gnat_to_gnu_field_decl (gnat_interface_tag)
      : NULL_TREE;
  tree gnu_interface_offset
    = gnu_interface_tag ? byte_position (gnu_interface_tag) : NULL_TREE;

  /* But we generate a call to the Thunk_Entity in the thunk.  */
  tree gnu_target
    = gnat_to_gnu_entity (Thunk_Entity (gnat_thunk), NULL_TREE, false);

  /* If the target is local, then thunk and target must have the same context
     because cgraph_node::expand_thunk can only forward the static chain.  */
  if (DECL_STATIC_CHAIN (gnu_target)
      && DECL_CONTEXT (gnu_thunk) != DECL_CONTEXT (gnu_target))
    return false;

  /* There are three ways to retrieve the offset between the interface view
     and the base object.  Either the controlling type covers the interface
     type and the offset of the corresponding tag is fixed, in which case it
     can be statically encoded in the thunk (see FIXED_OFFSET below).  Or the
     controlling type doesn't cover the interface type but is of fixed size,
     in which case the offset is stored in the dispatch table, two pointers
     above the dispatch table address (see VIRTUAL_VALUE below).  Otherwise,
     the offset is variable and is stored right after the tag in every object
     (see INDIRECT_OFFSET below).  See also a-tags.ads for more details.  */
  HOST_WIDE_INT fixed_offset, virtual_value, indirect_offset;
  tree virtual_offset;

  if (gnu_interface_offset && TREE_CODE (gnu_interface_offset) == INTEGER_CST)
    {
      fixed_offset = - tree_to_shwi (gnu_interface_offset);
      virtual_value = 0;
      virtual_offset = NULL_TREE;
      indirect_offset = 0;

      /* Do not create a null thunk, instead make it an alias.  */
      if (fixed_offset == 0)
	{
	  SET_DECL_ASSEMBLER_NAME (gnu_thunk, DECL_ASSEMBLER_NAME (gnu_target));
	  (void) cgraph_node::get_create (gnu_target);
	  (void) cgraph_node::create_alias (gnu_thunk, gnu_target);
	  return true;
	}
    }
  else if (!gnu_interface_offset
	   && !Is_Variable_Size_Record (gnat_controlling_type))
    {
      fixed_offset = 0;
      virtual_value = - 2 * (HOST_WIDE_INT) (POINTER_SIZE / BITS_PER_UNIT);
      virtual_offset = build_int_cst (integer_type_node, virtual_value);
      indirect_offset = 0;
    }
  else
    {
      /* Covariant thunks with variable offset are not supported.  */
      if (Has_Controlling_Result (gnat_target))
	return false;

      fixed_offset = 0;
      virtual_value = 0;
      virtual_offset = NULL_TREE;
      indirect_offset = (HOST_WIDE_INT) (POINTER_SIZE / BITS_PER_UNIT);
    }

  /* If the target returns by invisible reference and is external, apply the
     same transformation as Subprogram_Body_to_gnu here.  */
  if (TREE_ADDRESSABLE (TREE_TYPE (gnu_target))
      && DECL_EXTERNAL (gnu_target)
      && TREE_CODE (TREE_TYPE (DECL_RESULT (gnu_target))) != REFERENCE_TYPE)
    {
      TREE_TYPE (DECL_RESULT (gnu_target))
	= build_reference_type (TREE_TYPE (DECL_RESULT (gnu_target)));
      relayout_decl (DECL_RESULT (gnu_target));
    }

  /* The thunk expander requires the return types of thunk and target to be
     compatible, which is not fully the case with the CICO mechanism.  */
  if (TYPE_CI_CO_LIST (TREE_TYPE (gnu_thunk)))
    {
      tree gnu_target_type = TREE_TYPE (gnu_target);
      gcc_assert (TYPE_CI_CO_LIST (gnu_target_type));
      TYPE_CANONICAL (TREE_TYPE (TREE_TYPE (gnu_thunk)))
	= TYPE_CANONICAL (TREE_TYPE (gnu_target_type));
    }

  cgraph_node *target_node = cgraph_node::get_create (gnu_target);

  /* We may also need to create an alias for the target in order to make
     the call local, depending on the linkage of the target.  */
  tree gnu_alias = use_alias_for_thunk_p (gnu_target)
		  ? make_alias_for_thunk (gnu_target)
		  : gnu_target;

  /* If the return type of the target is a controlling type, then we need
     both an usual this thunk and a covariant thunk in this order:

       this thunk  -->  covariant thunk  -->  target

     For covariant thunks, we can only handle a fixed offset.  */
  if (Has_Controlling_Result (gnat_target))
    {
      gcc_assert (fixed_offset < 0);
      tree gnu_cv_thunk = make_covariant_thunk (gnat_thunk, gnu_thunk);
      target_node->create_thunk (gnu_cv_thunk, gnu_target, false,
				 - fixed_offset, 0, 0,
				 NULL_TREE, gnu_alias);

      gnu_alias = gnu_target = gnu_cv_thunk;
    }

  target_node->create_thunk (gnu_thunk, gnu_target, true,
			     fixed_offset, virtual_value, indirect_offset,
			     virtual_offset, gnu_alias);

  return true;
}

/* Initialize the table that maps GNAT codes to GCC codes for simple
   binary and unary operations.  */

static void
init_code_table (void)
{
  gnu_codes[N_Op_And] = TRUTH_AND_EXPR;
  gnu_codes[N_Op_Or] = TRUTH_OR_EXPR;
  gnu_codes[N_Op_Xor] = TRUTH_XOR_EXPR;
  gnu_codes[N_Op_Eq] = EQ_EXPR;
  gnu_codes[N_Op_Ne] = NE_EXPR;
  gnu_codes[N_Op_Lt] = LT_EXPR;
  gnu_codes[N_Op_Le] = LE_EXPR;
  gnu_codes[N_Op_Gt] = GT_EXPR;
  gnu_codes[N_Op_Ge] = GE_EXPR;
  gnu_codes[N_Op_Add] = PLUS_EXPR;
  gnu_codes[N_Op_Subtract] = MINUS_EXPR;
  gnu_codes[N_Op_Multiply] = MULT_EXPR;
  gnu_codes[N_Op_Mod] = FLOOR_MOD_EXPR;
  gnu_codes[N_Op_Rem] = TRUNC_MOD_EXPR;
  gnu_codes[N_Op_Minus] = NEGATE_EXPR;
  gnu_codes[N_Op_Abs] = ABS_EXPR;
  gnu_codes[N_Op_Not] = TRUTH_NOT_EXPR;
  gnu_codes[N_Op_Rotate_Left] = LROTATE_EXPR;
  gnu_codes[N_Op_Rotate_Right] = RROTATE_EXPR;
  gnu_codes[N_Op_Shift_Left] = LSHIFT_EXPR;
  gnu_codes[N_Op_Shift_Right] = RSHIFT_EXPR;
  gnu_codes[N_Op_Shift_Right_Arithmetic] = RSHIFT_EXPR;
  gnu_codes[N_And_Then] = TRUTH_ANDIF_EXPR;
  gnu_codes[N_Or_Else] = TRUTH_ORIF_EXPR;
}

#include "gt-ada-trans.h"
