/****************************************************************************
 *                                                                          *
 *                         GNAT COMPILER COMPONENTS                         *
 *                                                                          *
 *                               U T I L S 2                                *
 *                                                                          *
 *                          C Implementation File                           *
 *                                                                          *
 *          Copyright (C) 1992-2006, Free Software Foundation, Inc.         *
 *                                                                          *
 * GNAT is free software;  you can  redistribute it  and/or modify it under *
 * terms of the  GNU General Public License as published  by the Free Soft- *
 * ware  Foundation;  either version 2,  or (at your option) any later ver- *
 * sion.  GNAT is distributed in the hope that it will be useful, but WITH- *
 * OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY *
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License *
 * for  more details.  You should have  received  a copy of the GNU General *
 * Public License  distributed with GNAT;  see file COPYING.  If not, write *
 * to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, *
 * Boston, MA 02110-1301, USA.                                              *
 *                                                                          *
 * GNAT was originally developed  by the GNAT team at  New York University. *
 * Extensive contributions were provided by Ada Core Technologies Inc.      *
 *                                                                          *
 ****************************************************************************/

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "ggc.h"
#include "flags.h"
#include "output.h"
#include "ada.h"
#include "types.h"
#include "atree.h"
#include "stringt.h"
#include "namet.h"
#include "uintp.h"
#include "fe.h"
#include "elists.h"
#include "nlists.h"
#include "sinfo.h"
#include "einfo.h"
#include "ada-tree.h"
#include "gigi.h"

static tree find_common_type (tree, tree);
static bool contains_save_expr_p (tree);
static tree contains_null_expr (tree);
static tree compare_arrays (tree, tree, tree);
static tree nonbinary_modular_operation (enum tree_code, tree, tree, tree);
static tree build_simple_component_ref (tree, tree, tree, bool);

/* Prepare expr to be an argument of a TRUTH_NOT_EXPR or other logical
   operation.

   This preparation consists of taking the ordinary representation of
   an expression expr and producing a valid tree boolean expression
   describing whether expr is nonzero. We could simply always do

      build_binary_op (NE_EXPR, expr, integer_zero_node, 1),

   but we optimize comparisons, &&, ||, and !.

   The resulting type should always be the same as the input type.
   This function is simpler than the corresponding C version since
   the only possible operands will be things of Boolean type.  */

tree
gnat_truthvalue_conversion (tree expr)
{
  tree type = TREE_TYPE (expr);

  switch (TREE_CODE (expr))
    {
    case EQ_EXPR:  case NE_EXPR: case LE_EXPR: case GE_EXPR:
    case LT_EXPR:  case GT_EXPR:
    case TRUTH_ANDIF_EXPR:
    case TRUTH_ORIF_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_XOR_EXPR:
    case ERROR_MARK:
      return expr;

    case INTEGER_CST:
      return (integer_zerop (expr) ? convert (type, integer_zero_node)
	      : convert (type, integer_one_node));

    case REAL_CST:
      return (real_zerop (expr) ? convert (type, integer_zero_node)
	      : convert (type, integer_one_node));

    case COND_EXPR:
      /* Distribute the conversion into the arms of a COND_EXPR.  */
      return fold
	(build3 (COND_EXPR, type, TREE_OPERAND (expr, 0),
		 gnat_truthvalue_conversion (TREE_OPERAND (expr, 1)),
		 gnat_truthvalue_conversion (TREE_OPERAND (expr, 2))));

    default:
      return build_binary_op (NE_EXPR, type, expr,
			      convert (type, integer_zero_node));
    }
}

/* Return the base type of TYPE.  */

tree
get_base_type (tree type)
{
  if (TREE_CODE (type) == RECORD_TYPE
      && TYPE_JUSTIFIED_MODULAR_P (type))
    type = TREE_TYPE (TYPE_FIELDS (type));

  while (TREE_TYPE (type)
	 && (TREE_CODE (type) == INTEGER_TYPE
	     || TREE_CODE (type) == REAL_TYPE))
    type = TREE_TYPE (type);

  return type;
}

/* EXP is a GCC tree representing an address.  See if we can find how
   strictly the object at that address is aligned.   Return that alignment
   in bits.  If we don't know anything about the alignment, return 0.  */

unsigned int
known_alignment (tree exp)
{
  unsigned int this_alignment;
  unsigned int lhs, rhs;
  unsigned int type_alignment;

  /* For pointer expressions, we know that the designated object is always at
     least as strictly aligned as the designated subtype, so we account for
     both type and expression information in this case.

     Beware that we can still get a dummy designated subtype here (e.g. Taft
     Amendement types), in which the alignment information is meaningless and
     should be ignored.

     We always compute a type_alignment value and return the MAX of it
     compared with what we get from the expression tree. Just set the
     type_alignment value to 0 when the type information is to be ignored.  */
  type_alignment
    = ((POINTER_TYPE_P (TREE_TYPE (exp))
	&& !TYPE_IS_DUMMY_P (TREE_TYPE (TREE_TYPE (exp))))
       ? TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))) : 0);

  switch (TREE_CODE (exp))
    {
    case CONVERT_EXPR:
    case NOP_EXPR:
    case NON_LVALUE_EXPR:
      /* Conversions between pointers and integers don't change the alignment
	 of the underlying object.  */
      this_alignment = known_alignment (TREE_OPERAND (exp, 0));
      break;

    case PLUS_EXPR:
    case MINUS_EXPR:
      /* If two address are added, the alignment of the result is the
	 minimum of the two alignments.  */
      lhs = known_alignment (TREE_OPERAND (exp, 0));
      rhs = known_alignment (TREE_OPERAND (exp, 1));
      this_alignment = MIN (lhs, rhs);
      break;

    case INTEGER_CST:
      /* The first part of this represents the lowest bit in the constant,
	 but is it in bytes, not bits.  */
      this_alignment
	= MIN (BITS_PER_UNIT
		  * (TREE_INT_CST_LOW (exp) & - TREE_INT_CST_LOW (exp)),
		  BIGGEST_ALIGNMENT);
      break;

    case MULT_EXPR:
      /* If we know the alignment of just one side, use it.  Otherwise,
	 use the product of the alignments.  */
      lhs = known_alignment (TREE_OPERAND (exp, 0));
      rhs = known_alignment (TREE_OPERAND (exp, 1));

      if (lhs == 0 || rhs == 0)
	this_alignment = MIN (BIGGEST_ALIGNMENT, MAX (lhs, rhs));
      else
	this_alignment = MIN (BIGGEST_ALIGNMENT, lhs * rhs);
      break;

    case ADDR_EXPR:
      this_alignment = expr_align (TREE_OPERAND (exp, 0));
      break;

    default:
      this_alignment = 0;
      break;
    }

  return MAX (type_alignment, this_alignment);
}

/* We have a comparison or assignment operation on two types, T1 and T2,
   which are both either array types or both record types.
   Return the type that both operands should be converted to, if any.
   Otherwise return zero.  */

static tree
find_common_type (tree t1, tree t2)
{
  /* If either type is non-BLKmode, use it.  Note that we know that we will
     not have any alignment problems since if we did the non-BLKmode
     type could not have been used.  */
  if (TYPE_MODE (t1) != BLKmode)
    return t1;
  else if (TYPE_MODE (t2) != BLKmode)
    return t2;

  /* If both types have constant size, use the smaller one.  Keep returning
     T1 if we have a tie, to be consistent with the other cases.  */
  if (TREE_CONSTANT (TYPE_SIZE (t1)) && TREE_CONSTANT (TYPE_SIZE (t2)))
    return tree_int_cst_lt (TYPE_SIZE (t2), TYPE_SIZE (t1)) ? t2 : t1;

  /* Otherwise, if either type has a constant size, use it.  */
  else if (TREE_CONSTANT (TYPE_SIZE (t1)))
    return t1;
  else if (TREE_CONSTANT (TYPE_SIZE (t2)))
    return t2;

  /* In this case, both types have variable size.  It's probably
     best to leave the "type mismatch" because changing it could
     case a bad self-referential reference.  */
  return 0;
}

/* See if EXP contains a SAVE_EXPR in a position where we would
   normally put it.

   ??? This is a real kludge, but is probably the best approach short
   of some very general solution.  */

static bool
contains_save_expr_p (tree exp)
{
  switch (TREE_CODE (exp))
    {
    case SAVE_EXPR:
      return true;

    case ADDR_EXPR:  case INDIRECT_REF:
    case COMPONENT_REF:
    case NOP_EXPR:  case CONVERT_EXPR: case VIEW_CONVERT_EXPR:
      return contains_save_expr_p (TREE_OPERAND (exp, 0));

    case CONSTRUCTOR:
      {
	tree value;
	unsigned HOST_WIDE_INT ix;

	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), ix, value)
	  if (contains_save_expr_p (value))
	    return true;
	return false;
      }

    default:
      return false;
    }
}

/* See if EXP contains a NULL_EXPR in an expression we use for sizes. Return
   it if so.  This is used to detect types whose sizes involve computations
   that are known to raise Constraint_Error.  */

static tree
contains_null_expr (tree exp)
{
  tree tem;

  if (TREE_CODE (exp) == NULL_EXPR)
    return exp;

  switch (TREE_CODE_CLASS (TREE_CODE (exp)))
    {
    case tcc_unary:
      return contains_null_expr (TREE_OPERAND (exp, 0));

    case tcc_comparison:
    case tcc_binary:
      tem = contains_null_expr (TREE_OPERAND (exp, 0));
      if (tem)
	return tem;

      return contains_null_expr (TREE_OPERAND (exp, 1));

    case tcc_expression:
      switch (TREE_CODE (exp))
	{
	case SAVE_EXPR:
	  return contains_null_expr (TREE_OPERAND (exp, 0));

	case COND_EXPR:
	  tem = contains_null_expr (TREE_OPERAND (exp, 0));
	  if (tem)
	    return tem;

	  tem = contains_null_expr (TREE_OPERAND (exp, 1));
	  if (tem)
	    return tem;

	  return contains_null_expr (TREE_OPERAND (exp, 2));

	default:
	  return 0;
	}

    default:
      return 0;
    }
}

/* Return an expression tree representing an equality comparison of
   A1 and A2, two objects of ARRAY_TYPE.  The returned expression should
   be of type RESULT_TYPE

   Two arrays are equal in one of two ways: (1) if both have zero length
   in some dimension (not necessarily the same dimension) or (2) if the
   lengths in each dimension are equal and the data is equal.  We perform the
   length tests in as efficient a manner as possible.  */

static tree
compare_arrays (tree result_type, tree a1, tree a2)
{
  tree t1 = TREE_TYPE (a1);
  tree t2 = TREE_TYPE (a2);
  tree result = convert (result_type, integer_one_node);
  tree a1_is_null = convert (result_type, integer_zero_node);
  tree a2_is_null = convert (result_type, integer_zero_node);
  bool length_zero_p = false;

  /* Process each dimension separately and compare the lengths.  If any
     dimension has a size known to be zero, set SIZE_ZERO_P to 1 to
     suppress the comparison of the data.  */
  while (TREE_CODE (t1) == ARRAY_TYPE && TREE_CODE (t2) == ARRAY_TYPE)
    {
      tree lb1 = TYPE_MIN_VALUE (TYPE_DOMAIN (t1));
      tree ub1 = TYPE_MAX_VALUE (TYPE_DOMAIN (t1));
      tree lb2 = TYPE_MIN_VALUE (TYPE_DOMAIN (t2));
      tree ub2 = TYPE_MAX_VALUE (TYPE_DOMAIN (t2));
      tree bt = get_base_type (TREE_TYPE (lb1));
      tree length1 = fold (build2 (MINUS_EXPR, bt, ub1, lb1));
      tree length2 = fold (build2 (MINUS_EXPR, bt, ub2, lb2));
      tree nbt;
      tree tem;
      tree comparison, this_a1_is_null, this_a2_is_null;

      /* If the length of the first array is a constant, swap our operands
	 unless the length of the second array is the constant zero.
	 Note that we have set the `length' values to the length - 1.  */
      if (TREE_CODE (length1) == INTEGER_CST
	  && !integer_zerop (fold (build2 (PLUS_EXPR, bt, length2,
					   convert (bt, integer_one_node)))))
	{
	  tem = a1, a1 = a2, a2 = tem;
	  tem = t1, t1 = t2, t2 = tem;
	  tem = lb1, lb1 = lb2, lb2 = tem;
	  tem = ub1, ub1 = ub2, ub2 = tem;
	  tem = length1, length1 = length2, length2 = tem;
	  tem = a1_is_null, a1_is_null = a2_is_null, a2_is_null = tem;
	}

      /* If the length of this dimension in the second array is the constant
	 zero, we can just go inside the original bounds for the first
	 array and see if last < first.  */
      if (integer_zerop (fold (build2 (PLUS_EXPR, bt, length2,
				       convert (bt, integer_one_node)))))
	{
	  tree ub = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
	  tree lb = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));

	  comparison = build_binary_op (LT_EXPR, result_type, ub, lb);
	  comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
	  length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);

	  length_zero_p = true;
	  this_a1_is_null = comparison;
	  this_a2_is_null = convert (result_type, integer_one_node);
	}

      /* If the length is some other constant value, we know that the
	 this dimension in the first array cannot be superflat, so we
	 can just use its length from the actual stored bounds.  */
      else if (TREE_CODE (length2) == INTEGER_CST)
	{
	  ub1 = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
	  lb1 = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
	  ub2 = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t2)));
	  lb2 = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t2)));
	  nbt = get_base_type (TREE_TYPE (ub1));

	  comparison
	    = build_binary_op (EQ_EXPR, result_type,
			       build_binary_op (MINUS_EXPR, nbt, ub1, lb1),
			       build_binary_op (MINUS_EXPR, nbt, ub2, lb2));

	  /* Note that we know that UB2 and LB2 are constant and hence
	     cannot contain a PLACEHOLDER_EXPR.  */

	  comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
	  length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);

	  this_a1_is_null = build_binary_op (LT_EXPR, result_type, ub1, lb1);
	  this_a2_is_null = convert (result_type, integer_zero_node);
	}

      /* Otherwise compare the computed lengths.  */
      else
	{
	  length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
	  length2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length2, a2);

	  comparison
	    = build_binary_op (EQ_EXPR, result_type, length1, length2);

	  this_a1_is_null
	    = build_binary_op (LT_EXPR, result_type, length1,
			       convert (bt, integer_zero_node));
	  this_a2_is_null
	    = build_binary_op (LT_EXPR, result_type, length2,
			       convert (bt, integer_zero_node));
	}

      result = build_binary_op (TRUTH_ANDIF_EXPR, result_type,
				result, comparison);

      a1_is_null = build_binary_op (TRUTH_ORIF_EXPR, result_type,
				    this_a1_is_null, a1_is_null);
      a2_is_null = build_binary_op (TRUTH_ORIF_EXPR, result_type,
				    this_a2_is_null, a2_is_null);

      t1 = TREE_TYPE (t1);
      t2 = TREE_TYPE (t2);
    }

  /* Unless the size of some bound is known to be zero, compare the
     data in the array.  */
  if (!length_zero_p)
    {
      tree type = find_common_type (TREE_TYPE (a1), TREE_TYPE (a2));

      if (type)
	a1 = convert (type, a1), a2 = convert (type, a2);

      result = build_binary_op (TRUTH_ANDIF_EXPR, result_type, result,
				fold (build2 (EQ_EXPR, result_type, a1, a2)));

    }

  /* The result is also true if both sizes are zero.  */
  result = build_binary_op (TRUTH_ORIF_EXPR, result_type,
			    build_binary_op (TRUTH_ANDIF_EXPR, result_type,
					     a1_is_null, a2_is_null),
			    result);

  /* If either operand contains SAVE_EXPRs, they have to be evaluated before
     starting the comparison above since the place it would be otherwise
     evaluated would be wrong.  */

  if (contains_save_expr_p (a1))
    result = build2 (COMPOUND_EXPR, result_type, a1, result);

  if (contains_save_expr_p (a2))
    result = build2 (COMPOUND_EXPR, result_type, a2, result);

  return result;
}

/* Compute the result of applying OP_CODE to LHS and RHS, where both are of
   type TYPE.  We know that TYPE is a modular type with a nonbinary
   modulus.  */

static tree
nonbinary_modular_operation (enum tree_code op_code, tree type, tree lhs,
                             tree rhs)
{
  tree modulus = TYPE_MODULUS (type);
  unsigned int needed_precision = tree_floor_log2 (modulus) + 1;
  unsigned int precision;
  bool unsignedp = true;
  tree op_type = type;
  tree result;

  /* If this is an addition of a constant, convert it to a subtraction
     of a constant since we can do that faster.  */
  if (op_code == PLUS_EXPR && TREE_CODE (rhs) == INTEGER_CST)
    rhs = fold (build2 (MINUS_EXPR, type, modulus, rhs)), op_code = MINUS_EXPR;

  /* For the logical operations, we only need PRECISION bits.  For
     addition and subtraction, we need one more and for multiplication we
     need twice as many.  But we never want to make a size smaller than
     our size. */
  if (op_code == PLUS_EXPR || op_code == MINUS_EXPR)
    needed_precision += 1;
  else if (op_code == MULT_EXPR)
    needed_precision *= 2;

  precision = MAX (needed_precision, TYPE_PRECISION (op_type));

  /* Unsigned will do for everything but subtraction.  */
  if (op_code == MINUS_EXPR)
    unsignedp = false;

  /* If our type is the wrong signedness or isn't wide enough, make a new
     type and convert both our operands to it.  */
  if (TYPE_PRECISION (op_type) < precision
      || TYPE_UNSIGNED (op_type) != unsignedp)
    {
      /* Copy the node so we ensure it can be modified to make it modular.  */
      op_type = copy_node (gnat_type_for_size (precision, unsignedp));
      modulus = convert (op_type, modulus);
      SET_TYPE_MODULUS (op_type, modulus);
      TYPE_MODULAR_P (op_type) = 1;
      lhs = convert (op_type, lhs);
      rhs = convert (op_type, rhs);
    }

  /* Do the operation, then we'll fix it up.  */
  result = fold (build2 (op_code, op_type, lhs, rhs));

  /* For multiplication, we have no choice but to do a full modulus
     operation.  However, we want to do this in the narrowest
     possible size.  */
  if (op_code == MULT_EXPR)
    {
      tree div_type = copy_node (gnat_type_for_size (needed_precision, 1));
      modulus = convert (div_type, modulus);
      SET_TYPE_MODULUS (div_type, modulus);
      TYPE_MODULAR_P (div_type) = 1;
      result = convert (op_type,
			fold (build2 (TRUNC_MOD_EXPR, div_type,
				      convert (div_type, result), modulus)));
    }

  /* For subtraction, add the modulus back if we are negative.  */
  else if (op_code == MINUS_EXPR)
    {
      result = save_expr (result);
      result = fold (build3 (COND_EXPR, op_type,
			     build2 (LT_EXPR, integer_type_node, result,
				     convert (op_type, integer_zero_node)),
			     fold (build2 (PLUS_EXPR, op_type,
					   result, modulus)),
			     result));
    }

  /* For the other operations, subtract the modulus if we are >= it.  */
  else
    {
      result = save_expr (result);
      result = fold (build3 (COND_EXPR, op_type,
			     build2 (GE_EXPR, integer_type_node,
				     result, modulus),
			     fold (build2 (MINUS_EXPR, op_type,
					   result, modulus)),
			     result));
    }

  return convert (type, result);
}

/* Make a binary operation of kind OP_CODE.  RESULT_TYPE is the type
   desired for the result.  Usually the operation is to be performed
   in that type.  For MODIFY_EXPR and ARRAY_REF, RESULT_TYPE may be 0
   in which case the type to be used will be derived from the operands.

   This function is very much unlike the ones for C and C++ since we
   have already done any type conversion and matching required.  All we
   have to do here is validate the work done by SEM and handle subtypes.  */

tree
build_binary_op (enum tree_code op_code, tree result_type,
                 tree left_operand, tree right_operand)
{
  tree left_type  = TREE_TYPE (left_operand);
  tree right_type = TREE_TYPE (right_operand);
  tree left_base_type = get_base_type (left_type);
  tree right_base_type = get_base_type (right_type);
  tree operation_type = result_type;
  tree best_type = NULL_TREE;
  tree modulus;
  tree result;
  bool has_side_effects = false;

  if (operation_type
      && TREE_CODE (operation_type) == RECORD_TYPE
      && TYPE_JUSTIFIED_MODULAR_P (operation_type))
    operation_type = TREE_TYPE (TYPE_FIELDS (operation_type));

  if (operation_type
      && !AGGREGATE_TYPE_P (operation_type)
      && TYPE_EXTRA_SUBTYPE_P (operation_type))
    operation_type = get_base_type (operation_type);

  modulus = (operation_type && TREE_CODE (operation_type) == INTEGER_TYPE
	     && TYPE_MODULAR_P (operation_type)
	     ? TYPE_MODULUS (operation_type) : 0);

  switch (op_code)
    {
    case MODIFY_EXPR:
      /* If there were any integral or pointer conversions on LHS, remove
	 them; we'll be putting them back below if needed.  Likewise for
	 conversions between array and record types.  But don't do this if
	 the right operand is not BLKmode (for packed arrays)
	 unless we are not changing the mode.  */
      while ((TREE_CODE (left_operand) == CONVERT_EXPR
	      || TREE_CODE (left_operand) == NOP_EXPR
	      || TREE_CODE (left_operand) == VIEW_CONVERT_EXPR)
	     && (((INTEGRAL_TYPE_P (left_type)
		   || POINTER_TYPE_P (left_type))
		  && (INTEGRAL_TYPE_P (TREE_TYPE
				       (TREE_OPERAND (left_operand, 0)))
		      || POINTER_TYPE_P (TREE_TYPE
					 (TREE_OPERAND (left_operand, 0)))))
		 || (((TREE_CODE (left_type) == RECORD_TYPE
		       /* Don't remove conversions to justified modular
			  types. */
		       && !TYPE_JUSTIFIED_MODULAR_P (left_type))
		      || TREE_CODE (left_type) == ARRAY_TYPE)
		     && ((TREE_CODE (TREE_TYPE
				     (TREE_OPERAND (left_operand, 0)))
			  == RECORD_TYPE)
			 || (TREE_CODE (TREE_TYPE
					(TREE_OPERAND (left_operand, 0)))
			     == ARRAY_TYPE))
		     && (TYPE_MODE (right_type) == BLKmode
			 || (TYPE_MODE (left_type)
			     == TYPE_MODE (TREE_TYPE
					   (TREE_OPERAND
					    (left_operand, 0))))))))
	{
	  left_operand = TREE_OPERAND (left_operand, 0);
	  left_type = TREE_TYPE (left_operand);
	}

      if (!operation_type)
	operation_type = left_type;

      /* If we are copying one array or record to another, find the best type
	 to use.  */
      if (((TREE_CODE (left_type) == ARRAY_TYPE
	    && TREE_CODE (right_type) == ARRAY_TYPE)
	   || (TREE_CODE (left_type) == RECORD_TYPE
	       && TREE_CODE (right_type) == RECORD_TYPE))
	  && (best_type = find_common_type (left_type, right_type)))
	operation_type = best_type;

      /* If a class-wide type may be involved, force use of the RHS type.  */
      if ((TREE_CODE (right_type) == RECORD_TYPE
	   || TREE_CODE (right_type) == UNION_TYPE)
	  && TYPE_ALIGN_OK (right_type))
	operation_type = right_type;

      /* Ensure everything on the LHS is valid.  If we have a field reference,
	 strip anything that get_inner_reference can handle.  Then remove any
	 conversions with type types having the same code and mode.  Mark
	 VIEW_CONVERT_EXPRs with TREE_ADDRESSABLE.  When done, we must have
	 either an INDIRECT_REF or a decl.  */
      result = left_operand;
      while (1)
	{
	  tree restype = TREE_TYPE (result);

	  if (TREE_CODE (result) == COMPONENT_REF
	      || TREE_CODE (result) == ARRAY_REF
	      || TREE_CODE (result) == ARRAY_RANGE_REF)
	    while (handled_component_p (result))
	      result = TREE_OPERAND (result, 0);
	  else if (TREE_CODE (result) == REALPART_EXPR
		   || TREE_CODE (result) == IMAGPART_EXPR
		   || ((TREE_CODE (result) == NOP_EXPR
			|| TREE_CODE (result) == CONVERT_EXPR)
		       && (((TREE_CODE (restype)
			     == TREE_CODE (TREE_TYPE
					   (TREE_OPERAND (result, 0))))
			     && (TYPE_MODE (TREE_TYPE
					    (TREE_OPERAND (result, 0)))
				 == TYPE_MODE (restype)))
			   || TYPE_ALIGN_OK (restype))))
	    result = TREE_OPERAND (result, 0);
	  else if (TREE_CODE (result) == VIEW_CONVERT_EXPR)
	    {
	      TREE_ADDRESSABLE (result) = 1;
	      result = TREE_OPERAND (result, 0);
	    }
	  else
	    break;
	}

      gcc_assert (TREE_CODE (result) == INDIRECT_REF
		  || TREE_CODE (result) == NULL_EXPR || DECL_P (result));

      /* Convert the right operand to the operation type unless
	 it is either already of the correct type or if the type
	 involves a placeholder, since the RHS may not have the same
	 record type.  */
      if (operation_type != right_type
	  && (!CONTAINS_PLACEHOLDER_P (TYPE_SIZE (operation_type))))
	{
	  right_operand = convert (operation_type, right_operand);
	  right_type = operation_type;
	}

      /* If the left operand is not the same type as the operation type,
	 surround it in a VIEW_CONVERT_EXPR.  */
      if (left_type != operation_type)
	left_operand = unchecked_convert (operation_type, left_operand, false);

      has_side_effects = true;
      modulus = NULL_TREE;
      break;

    case ARRAY_REF:
      if (!operation_type)
	operation_type = TREE_TYPE (left_type);

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

    case ARRAY_RANGE_REF:

      /* First convert the right operand to its base type.  This will
	 prevent unneeded signedness conversions when sizetype is wider than
	 integer.  */
      right_operand = convert (right_base_type, right_operand);
      right_operand = convert (TYPE_DOMAIN (left_type), right_operand);

      if (!TREE_CONSTANT (right_operand)
	  || !TREE_CONSTANT (TYPE_MIN_VALUE (right_type)))
	gnat_mark_addressable (left_operand);

      modulus = NULL_TREE;
      break;

    case GE_EXPR:
    case LE_EXPR:
    case GT_EXPR:
    case LT_EXPR:
      gcc_assert (!POINTER_TYPE_P (left_type));

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

    case EQ_EXPR:
    case NE_EXPR:
      /* If either operand is a NULL_EXPR, just return a new one.  */
      if (TREE_CODE (left_operand) == NULL_EXPR)
	return build2 (op_code, result_type,
		       build1 (NULL_EXPR, integer_type_node,
			       TREE_OPERAND (left_operand, 0)),
		       integer_zero_node);

      else if (TREE_CODE (right_operand) == NULL_EXPR)
	return build2 (op_code, result_type,
		       build1 (NULL_EXPR, integer_type_node,
			       TREE_OPERAND (right_operand, 0)),
		       integer_zero_node);

      /* If either object is a justified modular types, get the
	 fields from within.  */
      if (TREE_CODE (left_type) == RECORD_TYPE
	  && TYPE_JUSTIFIED_MODULAR_P (left_type))
	{
	  left_operand = convert (TREE_TYPE (TYPE_FIELDS (left_type)),
				  left_operand);
	  left_type = TREE_TYPE (left_operand);
	  left_base_type = get_base_type (left_type);
	}

      if (TREE_CODE (right_type) == RECORD_TYPE
	  && TYPE_JUSTIFIED_MODULAR_P (right_type))
	{
	  right_operand = convert (TREE_TYPE (TYPE_FIELDS (right_type)),
				  right_operand);
	  right_type = TREE_TYPE (right_operand);
	  right_base_type = get_base_type (right_type);
	}

      /* If both objects are arrays, compare them specially.  */
      if ((TREE_CODE (left_type) == ARRAY_TYPE
	   || (TREE_CODE (left_type) == INTEGER_TYPE
	       && TYPE_HAS_ACTUAL_BOUNDS_P (left_type)))
	  && (TREE_CODE (right_type) == ARRAY_TYPE
	      || (TREE_CODE (right_type) == INTEGER_TYPE
		  && TYPE_HAS_ACTUAL_BOUNDS_P (right_type))))
	{
	  result = compare_arrays (result_type, left_operand, right_operand);

	  if (op_code == NE_EXPR)
	    result = invert_truthvalue (result);
	  else
	    gcc_assert (op_code == EQ_EXPR);

	  return result;
	}

      /* Otherwise, the base types must be the same unless the objects are
	 records.  If we have records, use the best type and convert both
	 operands to that type.  */
      if (left_base_type != right_base_type)
	{
	  if (TREE_CODE (left_base_type) == RECORD_TYPE
	      && TREE_CODE (right_base_type) == RECORD_TYPE)
	    {
	      /* The only way these are permitted to be the same is if both
		 types have the same name.  In that case, one of them must
		 not be self-referential.  Use that one as the best type.
		 Even better is if one is of fixed size.  */
	      best_type = NULL_TREE;

	      gcc_assert (TYPE_NAME (left_base_type)
			  && (TYPE_NAME (left_base_type)
			      == TYPE_NAME (right_base_type)));

	      if (TREE_CONSTANT (TYPE_SIZE (left_base_type)))
		best_type = left_base_type;
	      else if (TREE_CONSTANT (TYPE_SIZE (right_base_type)))
		best_type = right_base_type;
	      else if (!CONTAINS_PLACEHOLDER_P (TYPE_SIZE (left_base_type)))
		best_type = left_base_type;
	      else if (!CONTAINS_PLACEHOLDER_P (TYPE_SIZE (right_base_type)))
		best_type = right_base_type;
	      else
		gcc_unreachable ();

	      left_operand = convert (best_type, left_operand);
	      right_operand = convert (best_type, right_operand);
	    }
	  else
	    gcc_unreachable ();
	}

      /* If we are comparing a fat pointer against zero, we need to
	 just compare the data pointer.  */
      else if (TYPE_FAT_POINTER_P (left_base_type)
	       && TREE_CODE (right_operand) == CONSTRUCTOR
	       && integer_zerop (VEC_index (constructor_elt,
					    CONSTRUCTOR_ELTS (right_operand),
					    0)
				 ->value))
	{
	  right_operand = build_component_ref (left_operand, NULL_TREE,
					       TYPE_FIELDS (left_base_type),
					       false);
	  left_operand = convert (TREE_TYPE (right_operand),
				  integer_zero_node);
	}
      else
	{
	  left_operand = convert (left_base_type, left_operand);
	  right_operand = convert (right_base_type, right_operand);
	}

      modulus = NULL_TREE;
      break;

    case PREINCREMENT_EXPR:
    case PREDECREMENT_EXPR:
    case POSTINCREMENT_EXPR:
    case POSTDECREMENT_EXPR:
      /* In these, the result type and the left operand type should be the
	 same.  Do the operation in the base type of those and convert the
	 right operand (which is an integer) to that type.

	 Note that these operations are only used in loop control where
	 we guarantee that no overflow can occur.  So nothing special need
	 be done for modular types.  */

      gcc_assert (left_type == result_type);
      operation_type = get_base_type (result_type);
      left_operand = convert (operation_type, left_operand);
      right_operand = convert (operation_type, right_operand);
      has_side_effects = true;
      modulus = NULL_TREE;
      break;

    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case LROTATE_EXPR:
    case RROTATE_EXPR:
       /* The RHS of a shift can be any type.  Also, ignore any modulus
	 (we used to abort, but this is needed for unchecked conversion
	 to modular types).  Otherwise, processing is the same as normal.  */
      gcc_assert (operation_type == left_base_type);
      modulus = NULL_TREE;
      left_operand = convert (operation_type, left_operand);
      break;

    case TRUTH_ANDIF_EXPR:
    case TRUTH_ORIF_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_XOR_EXPR:
      left_operand = gnat_truthvalue_conversion (left_operand);
      right_operand = gnat_truthvalue_conversion (right_operand);
      goto common;

    case BIT_AND_EXPR:
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
      /* For binary modulus, if the inputs are in range, so are the
	 outputs.  */
      if (modulus && integer_pow2p (modulus))
	modulus = NULL_TREE;

      goto common;

    case COMPLEX_EXPR:
      gcc_assert (TREE_TYPE (result_type) == left_base_type
		  && TREE_TYPE (result_type) == right_base_type);
      left_operand = convert (left_base_type, left_operand);
      right_operand = convert (right_base_type, right_operand);
      break;

    case TRUNC_DIV_EXPR:   case TRUNC_MOD_EXPR:
    case CEIL_DIV_EXPR:    case CEIL_MOD_EXPR:
    case FLOOR_DIV_EXPR:   case FLOOR_MOD_EXPR:
    case ROUND_DIV_EXPR:   case ROUND_MOD_EXPR:
      /* These always produce results lower than either operand.  */
      modulus = NULL_TREE;
      goto common;

    default:
    common:
      /* The result type should be the same as the base types of the
	 both operands (and they should be the same).  Convert
	 everything to the result type.  */

      gcc_assert (operation_type == left_base_type
		  && left_base_type == right_base_type);
      left_operand = convert (operation_type, left_operand);
      right_operand = convert (operation_type, right_operand);
    }

  if (modulus && !integer_pow2p (modulus))
    {
      result = nonbinary_modular_operation (op_code, operation_type,
					    left_operand, right_operand);
      modulus = NULL_TREE;
    }
  /* If either operand is a NULL_EXPR, just return a new one.  */
  else if (TREE_CODE (left_operand) == NULL_EXPR)
    return build1 (NULL_EXPR, operation_type, TREE_OPERAND (left_operand, 0));
  else if (TREE_CODE (right_operand) == NULL_EXPR)
    return build1 (NULL_EXPR, operation_type, TREE_OPERAND (right_operand, 0));
  else if (op_code == ARRAY_REF || op_code == ARRAY_RANGE_REF)
    result = fold (build4 (op_code, operation_type, left_operand,
			   right_operand, NULL_TREE, NULL_TREE));
  else
    result
      = fold (build2 (op_code, operation_type, left_operand, right_operand));

  TREE_SIDE_EFFECTS (result) |= has_side_effects;
  TREE_CONSTANT (result)
    |= (TREE_CONSTANT (left_operand) & TREE_CONSTANT (right_operand)
	&& op_code != ARRAY_REF && op_code != ARRAY_RANGE_REF);

  if ((op_code == ARRAY_REF || op_code == ARRAY_RANGE_REF)
      && TYPE_VOLATILE (operation_type))
    TREE_THIS_VOLATILE (result) = 1;

  /* If we are working with modular types, perform the MOD operation
     if something above hasn't eliminated the need for it.  */
  if (modulus)
    result = fold (build2 (FLOOR_MOD_EXPR, operation_type, result,
			   convert (operation_type, modulus)));

  if (result_type && result_type != operation_type)
    result = convert (result_type, result);

  return result;
}

/* Similar, but for unary operations.  */

tree
build_unary_op (enum tree_code op_code, tree result_type, tree operand)
{
  tree type = TREE_TYPE (operand);
  tree base_type = get_base_type (type);
  tree operation_type = result_type;
  tree result;
  bool side_effects = false;

  if (operation_type
      && TREE_CODE (operation_type) == RECORD_TYPE
      && TYPE_JUSTIFIED_MODULAR_P (operation_type))
    operation_type = TREE_TYPE (TYPE_FIELDS (operation_type));

  if (operation_type
      && !AGGREGATE_TYPE_P (operation_type)
      && TYPE_EXTRA_SUBTYPE_P (operation_type))
    operation_type = get_base_type (operation_type);

  switch (op_code)
    {
    case REALPART_EXPR:
    case IMAGPART_EXPR:
      if (!operation_type)
	result_type = operation_type = TREE_TYPE (type);
      else
	gcc_assert (result_type == TREE_TYPE (type));

      result = fold (build1 (op_code, operation_type, operand));
      break;

    case TRUTH_NOT_EXPR:
      gcc_assert (result_type == base_type);
      result = invert_truthvalue (gnat_truthvalue_conversion (operand));
      break;

    case ATTR_ADDR_EXPR:
    case ADDR_EXPR:
      switch (TREE_CODE (operand))
	{
	case INDIRECT_REF:
	case UNCONSTRAINED_ARRAY_REF:
	  result = TREE_OPERAND (operand, 0);

	  /* Make sure the type here is a pointer, not a reference.
	     GCC wants pointer types for function addresses.  */
	  if (!result_type)
	    result_type = build_pointer_type (type);
	  break;

	case NULL_EXPR:
	  result = operand;
	  TREE_TYPE (result) = type = build_pointer_type (type);
	  break;

	case ARRAY_REF:
	case ARRAY_RANGE_REF:
	case COMPONENT_REF:
	case BIT_FIELD_REF:
	    /* If this is for 'Address, find the address of the prefix and
	       add the offset to the field.  Otherwise, do this the normal
	       way.  */
	  if (op_code == ATTR_ADDR_EXPR)
	    {
	      HOST_WIDE_INT bitsize;
	      HOST_WIDE_INT bitpos;
	      tree offset, inner;
	      enum machine_mode mode;
	      int unsignedp, volatilep;

	      inner = get_inner_reference (operand, &bitsize, &bitpos, &offset,
					   &mode, &unsignedp, &volatilep,
					   false);

	      /* If INNER is a padding type whose field has a self-referential
		 size, convert to that inner type.  We know the offset is zero
		 and we need to have that type visible.  */
	      if (TREE_CODE (TREE_TYPE (inner)) == RECORD_TYPE
		  && TYPE_IS_PADDING_P (TREE_TYPE (inner))
		  && (CONTAINS_PLACEHOLDER_P
		      (TYPE_SIZE (TREE_TYPE (TYPE_FIELDS
					     (TREE_TYPE (inner)))))))
		inner = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (inner))),
				 inner);

	      /* Compute the offset as a byte offset from INNER.  */
	      if (!offset)
		offset = size_zero_node;

	      if (bitpos % BITS_PER_UNIT != 0)
		post_error
		  ("taking address of object not aligned on storage unit?",
		   error_gnat_node);

	      offset = size_binop (PLUS_EXPR, offset,
				   size_int (bitpos / BITS_PER_UNIT));

	      /* Take the address of INNER, convert the offset to void *, and
		 add then.  It will later be converted to the desired result
		 type, if any.  */
	      inner = build_unary_op (ADDR_EXPR, NULL_TREE, inner);
	      inner = convert (ptr_void_type_node, inner);
	      offset = convert (ptr_void_type_node, offset);
	      result = build_binary_op (PLUS_EXPR, ptr_void_type_node,
					inner, offset);
	      result = convert (build_pointer_type (TREE_TYPE (operand)),
				result);
	      break;
	    }
	  goto common;

	case CONSTRUCTOR:
	  /* If this is just a constructor for a padded record, we can
	     just take the address of the single field and convert it to
	     a pointer to our type.  */
	  if (TREE_CODE (type) == RECORD_TYPE && TYPE_IS_PADDING_P (type))
	    {
	      result = (VEC_index (constructor_elt,
				   CONSTRUCTOR_ELTS (operand),
				   0)
			->value);

	      result = convert (build_pointer_type (TREE_TYPE (operand)),
				build_unary_op (ADDR_EXPR, NULL_TREE, result));
	      break;
	    }

	  goto common;

	case NOP_EXPR:
	  if (AGGREGATE_TYPE_P (type)
	      && AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (operand, 0))))
	    return build_unary_op (ADDR_EXPR, result_type,
				   TREE_OPERAND (operand, 0));

	  /* ... fallthru ... */

	case VIEW_CONVERT_EXPR:
	  /* If this just a variant conversion or if the conversion doesn't
	     change the mode, get the result type from this type and go down.
	     This is needed for conversions of CONST_DECLs, to eventually get
	     to the address of their CORRESPONDING_VARs.  */
	  if ((TYPE_MAIN_VARIANT (type)
	       == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (operand, 0))))
	      || (TYPE_MODE (type) != BLKmode
		  && (TYPE_MODE (type)
		      == TYPE_MODE (TREE_TYPE (TREE_OPERAND (operand, 0))))))
	    return build_unary_op (ADDR_EXPR,
				   (result_type ? result_type
				    : build_pointer_type (type)),
				   TREE_OPERAND (operand, 0));
	  goto common;

	case CONST_DECL:
	  operand = DECL_CONST_CORRESPONDING_VAR (operand);

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

	default:
	common:

	  /* If we are taking the address of a padded record whose field is
	     contains a template, take the address of the template.  */
	  if (TREE_CODE (type) == RECORD_TYPE
	      && TYPE_IS_PADDING_P (type)
	      && TREE_CODE (TREE_TYPE (TYPE_FIELDS (type))) == RECORD_TYPE
	      && TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (TYPE_FIELDS (type))))
	    {
	      type = TREE_TYPE (TYPE_FIELDS (type));
	      operand = convert (type, operand);
	    }

	  if (type != error_mark_node)
	    operation_type = build_pointer_type (type);

	  gnat_mark_addressable (operand);
	  result = fold (build1 (ADDR_EXPR, operation_type, operand));
	}

      TREE_CONSTANT (result) |= staticp (operand) || TREE_CONSTANT (operand);
      break;

    case INDIRECT_REF:
      /* If we want to refer to an entire unconstrained array,
	 make up an expression to do so.  This will never survive to
	 the backend.  If TYPE is a thin pointer, first convert the
	 operand to a fat pointer.  */
      if (TYPE_THIN_POINTER_P (type)
	  && TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type)))
	{
	  operand
	    = convert (TREE_TYPE (TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (type))),
		       operand);
	  type = TREE_TYPE (operand);
	}

      if (TYPE_FAT_POINTER_P (type))
	{
	  result = build1 (UNCONSTRAINED_ARRAY_REF,
			   TYPE_UNCONSTRAINED_ARRAY (type), operand);
	  TREE_READONLY (result) = TREE_STATIC (result)
	    = TYPE_READONLY (TYPE_UNCONSTRAINED_ARRAY (type));
	}
      else if (TREE_CODE (operand) == ADDR_EXPR)
	result = TREE_OPERAND (operand, 0);

      else
	{
	  result = fold (build1 (op_code, TREE_TYPE (type), operand));
	  TREE_READONLY (result) = TYPE_READONLY (TREE_TYPE (type));
	}

      side_effects
	=  (!TYPE_FAT_POINTER_P (type) && TYPE_VOLATILE (TREE_TYPE (type)));
      break;

    case NEGATE_EXPR:
    case BIT_NOT_EXPR:
      {
	tree modulus = ((operation_type
			 && TREE_CODE (operation_type) == INTEGER_TYPE
			 && TYPE_MODULAR_P (operation_type))
			? TYPE_MODULUS (operation_type) : 0);
	int mod_pow2 = modulus && integer_pow2p (modulus);

	/* If this is a modular type, there are various possibilities
	   depending on the operation and whether the modulus is a
	   power of two or not.  */

	if (modulus)
	  {
	    gcc_assert (operation_type == base_type);
	    operand = convert (operation_type, operand);

	    /* The fastest in the negate case for binary modulus is
	       the straightforward code; the TRUNC_MOD_EXPR below
	       is an AND operation.  */
	    if (op_code == NEGATE_EXPR && mod_pow2)
	      result = fold (build2 (TRUNC_MOD_EXPR, operation_type,
				     fold (build1 (NEGATE_EXPR, operation_type,
						   operand)),
				     modulus));

	    /* For nonbinary negate case, return zero for zero operand,
	       else return the modulus minus the operand.  If the modulus
	       is a power of two minus one, we can do the subtraction
	       as an XOR since it is equivalent and faster on most machines. */
	    else if (op_code == NEGATE_EXPR && !mod_pow2)
	      {
		if (integer_pow2p (fold (build2 (PLUS_EXPR, operation_type,
						 modulus,
						 convert (operation_type,
							  integer_one_node)))))
		  result = fold (build2 (BIT_XOR_EXPR, operation_type,
					 operand, modulus));
		else
		  result = fold (build2 (MINUS_EXPR, operation_type,
					modulus, operand));

		result = fold (build3 (COND_EXPR, operation_type,
				       fold (build2 (NE_EXPR,
						     integer_type_node,
						     operand,
						     convert
						     (operation_type,
						      integer_zero_node))),
				       result, operand));
	      }
	    else
	      {
		/* For the NOT cases, we need a constant equal to
		   the modulus minus one.  For a binary modulus, we
		   XOR against the constant and subtract the operand from
		   that constant for nonbinary modulus.  */

		tree cnst = fold (build2 (MINUS_EXPR, operation_type, modulus,
					  convert (operation_type,
						   integer_one_node)));

		if (mod_pow2)
		  result = fold (build2 (BIT_XOR_EXPR, operation_type,
					 operand, cnst));
		else
		  result = fold (build2 (MINUS_EXPR, operation_type,
					 cnst, operand));
	      }

	    break;
	  }
      }

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

    default:
      gcc_assert (operation_type == base_type);
      result = fold (build1 (op_code, operation_type, convert (operation_type,
							       operand)));
    }

  if (side_effects)
    {
      TREE_SIDE_EFFECTS (result) = 1;
      if (TREE_CODE (result) == INDIRECT_REF)
	TREE_THIS_VOLATILE (result) = TYPE_VOLATILE (TREE_TYPE (result));
    }

  if (result_type && TREE_TYPE (result) != result_type)
    result = convert (result_type, result);

  return result;
}

/* Similar, but for COND_EXPR.  */

tree
build_cond_expr (tree result_type, tree condition_operand,
                 tree true_operand, tree false_operand)
{
  tree result;
  bool addr_p = false;

  /* The front-end verifies that result, true and false operands have same base
     type.  Convert everything to the result type.  */

  true_operand  = convert (result_type, true_operand);
  false_operand = convert (result_type, false_operand);

  /* If the result type is unconstrained, take the address of
     the operands and then dereference our result.  */
  if (TREE_CODE (result_type) == UNCONSTRAINED_ARRAY_TYPE
      || CONTAINS_PLACEHOLDER_P (TYPE_SIZE (result_type)))
    {
      addr_p = true;
      result_type = build_pointer_type (result_type);
      true_operand = build_unary_op (ADDR_EXPR, result_type, true_operand);
      false_operand = build_unary_op (ADDR_EXPR, result_type, false_operand);
    }

  result = fold (build3 (COND_EXPR, result_type, condition_operand,
			 true_operand, false_operand));

  /* If either operand is a SAVE_EXPR (possibly surrounded by
     arithmetic, make sure it gets done.  */
  true_operand  = skip_simple_arithmetic (true_operand);
  false_operand = skip_simple_arithmetic (false_operand);

  if (TREE_CODE (true_operand) == SAVE_EXPR)
    result = build2 (COMPOUND_EXPR, result_type, true_operand, result);

  if (TREE_CODE (false_operand) == SAVE_EXPR)
    result = build2 (COMPOUND_EXPR, result_type, false_operand, result);

  /* ??? Seems the code above is wrong, as it may move ahead of the COND
     SAVE_EXPRs with side effects and not shared by both arms.  */

 if (addr_p)
    result = build_unary_op (INDIRECT_REF, NULL_TREE, result);

  return result;
}

/* Similar, but for RETURN_EXPR.  If RESULT_DECL is non-zero, build
   a RETURN_EXPR around the assignment of RET_VAL to RESULT_DECL.
   If RESULT_DECL is zero, build a bare RETURN_EXPR.  */

tree
build_return_expr (tree result_decl, tree ret_val)
{
  tree result_expr;

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

           RETURN_EXPR
               |
           MODIFY_EXPR
           /        \
          /          \
      RESULT_DECL    ...

      As a consequence, type-homogeneity dictates that we use the type
      of the RESULT_DECL as the operation type.  */

      tree operation_type = TREE_TYPE (result_decl);

      /* Convert the right operand to the operation type.  Note that
         it's the same transformation as in the MODIFY_EXPR case of
         build_binary_op with the additional guarantee that the type
         cannot involve a placeholder, since otherwise the function
         would use the "target pointer" return mechanism.  */

      if (operation_type != TREE_TYPE (ret_val))
	ret_val = convert (operation_type, ret_val);

      result_expr
	= build2 (MODIFY_EXPR, operation_type, result_decl, ret_val);
    }
  else
    result_expr = NULL_TREE;

  return build1 (RETURN_EXPR, void_type_node, result_expr);
}

/* Build a CALL_EXPR to call FUNDECL with one argument, ARG.  Return
   the CALL_EXPR.  */

tree
build_call_1_expr (tree fundecl, tree arg)
{
  tree call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fundecl)),
		      build_unary_op (ADDR_EXPR, NULL_TREE, fundecl),
		      chainon (NULL_TREE, build_tree_list (NULL_TREE, arg)),
		      NULL_TREE);

  TREE_SIDE_EFFECTS (call) = 1;

  return call;
}

/* Build a CALL_EXPR to call FUNDECL with two arguments, ARG1 & ARG2.  Return
   the CALL_EXPR.  */

tree
build_call_2_expr (tree fundecl, tree arg1, tree arg2)
{
  tree call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fundecl)),
		      build_unary_op (ADDR_EXPR, NULL_TREE, fundecl),
		      chainon (chainon (NULL_TREE,
					build_tree_list (NULL_TREE, arg1)),
			       build_tree_list (NULL_TREE, arg2)),
		     NULL_TREE);

  TREE_SIDE_EFFECTS (call) = 1;

  return call;
}

/* Likewise to call FUNDECL with no arguments.  */

tree
build_call_0_expr (tree fundecl)
{
  tree call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fundecl)),
		      build_unary_op (ADDR_EXPR, NULL_TREE, fundecl),
		      NULL_TREE, NULL_TREE);

  /* We rely on build3 to compute TREE_SIDE_EFFECTS.  This makes it possible
     to propagate the DECL_IS_PURE flag on parameterless functions.  */

  return call;
}

/* Call a function that raises an exception and pass the line number and file
   name, if requested.  MSG says which exception function to call.

   GNAT_NODE is the gnat node conveying the source location for which the
   error should be signaled, or Empty in which case the error is signaled on
   the current ref_file_name/input_line.  */

tree
build_call_raise (int msg, Node_Id gnat_node)
{
  tree fndecl = gnat_raise_decls[msg];

  const char *str
    = (Debug_Flag_NN || Exception_Locations_Suppressed)
      ? ""
      : (gnat_node != Empty)
        ? IDENTIFIER_POINTER
          (get_identifier (Get_Name_String
			   (Debug_Source_Name
			    (Get_Source_File_Index (Sloc (gnat_node))))))
        : ref_filename;

  int len = strlen (str) + 1;
  tree filename = build_string (len, str);

  int line_number
    = (gnat_node != Empty)
      ? Get_Logical_Line_Number (Sloc(gnat_node)) : input_line;

  TREE_TYPE (filename)
    = build_array_type (char_type_node,
			build_index_type (build_int_cst (NULL_TREE, len)));

  return
    build_call_2_expr (fndecl,
		       build1 (ADDR_EXPR, build_pointer_type (char_type_node),
			       filename),
		       build_int_cst (NULL_TREE, line_number));
}

/* qsort comparer for the bit positions of two constructor elements
   for record components.  */

static int
compare_elmt_bitpos (const PTR rt1, const PTR rt2)
{
  tree elmt1 = * (tree *) rt1;
  tree elmt2 = * (tree *) rt2;

  tree pos_field1 = bit_position (TREE_PURPOSE (elmt1));
  tree pos_field2 = bit_position (TREE_PURPOSE (elmt2));

  if (tree_int_cst_equal (pos_field1, pos_field2))
    return 0;
  else if (tree_int_cst_lt (pos_field1, pos_field2))
    return -1;
  else
    return 1;
}

/* Return a CONSTRUCTOR of TYPE whose list is LIST.  */

tree
gnat_build_constructor (tree type, tree list)
{
  tree elmt;
  int n_elmts;
  bool allconstant = (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST);
  bool side_effects = false;
  tree result;

  /* Scan the elements to see if they are all constant or if any has side
     effects, to let us set global flags on the resulting constructor.  Count
     the elements along the way for possible sorting purposes below.  */
  for (n_elmts = 0, elmt = list; elmt; elmt = TREE_CHAIN (elmt), n_elmts ++)
    {
      if (!TREE_CONSTANT (TREE_VALUE (elmt))
	  || (TREE_CODE (type) == RECORD_TYPE
	      && DECL_BIT_FIELD (TREE_PURPOSE (elmt))
	      && TREE_CODE (TREE_VALUE (elmt)) != INTEGER_CST)
	  || !initializer_constant_valid_p (TREE_VALUE (elmt),
					    TREE_TYPE (TREE_VALUE (elmt))))
	allconstant = false;

      if (TREE_SIDE_EFFECTS (TREE_VALUE (elmt)))
	side_effects = true;

      /* Propagate an NULL_EXPR from the size of the type.  We won't ever
	 be executing the code we generate here in that case, but handle it
	 specially to avoid the cmpiler blowing up.  */
      if (TREE_CODE (type) == RECORD_TYPE
	  && (0 != (result
		    = contains_null_expr (DECL_SIZE (TREE_PURPOSE (elmt))))))
	return build1 (NULL_EXPR, type, TREE_OPERAND (result, 0));
    }

  /* For record types with constant components only, sort field list
     by increasing bit position.  This is necessary to ensure the
     constructor can be output as static data, which the gimplifier
     might force in various circumstances. */
  if (allconstant && TREE_CODE (type) == RECORD_TYPE && n_elmts > 1)
    {
      /* Fill an array with an element tree per index, and ask qsort to order
	 them according to what a bitpos comparison function says.  */

      tree *gnu_arr = (tree *) alloca (sizeof (tree) * n_elmts);
      int i;

      for (i = 0, elmt = list; elmt; elmt = TREE_CHAIN (elmt), i++)
	gnu_arr[i] = elmt;

      qsort (gnu_arr, n_elmts, sizeof (tree), compare_elmt_bitpos);

      /* Then reconstruct the list from the sorted array contents.  */

      list = NULL_TREE;
      for (i = n_elmts - 1; i >= 0; i--)
	{
	  TREE_CHAIN (gnu_arr[i]) = list;
	  list = gnu_arr[i];
	}
    }

  result = build_constructor_from_list (type, list);
  TREE_CONSTANT (result) = TREE_INVARIANT (result)
    = TREE_STATIC (result) = allconstant;
  TREE_SIDE_EFFECTS (result) = side_effects;
  TREE_READONLY (result) = TYPE_READONLY (type) || allconstant;
  return result;
}

/* Return a COMPONENT_REF to access a field that is given by COMPONENT,
   an IDENTIFIER_NODE giving the name of the field, or FIELD, a FIELD_DECL,
   for the field.  Don't fold the result if NO_FOLD_P is true.

   We also handle the fact that we might have been passed a pointer to the
   actual record and know how to look for fields in variant parts.  */

static tree
build_simple_component_ref (tree record_variable, tree component,
                            tree field, bool no_fold_p)
{
  tree record_type = TYPE_MAIN_VARIANT (TREE_TYPE (record_variable));
  tree ref;

  gcc_assert ((TREE_CODE (record_type) == RECORD_TYPE
	       || TREE_CODE (record_type) == UNION_TYPE
	       || TREE_CODE (record_type) == QUAL_UNION_TYPE)
	      && TYPE_SIZE (record_type)
	      && (component != 0) != (field != 0));

  /* If no field was specified, look for a field with the specified name
     in the current record only.  */
  if (!field)
    for (field = TYPE_FIELDS (record_type); field;
	 field = TREE_CHAIN (field))
      if (DECL_NAME (field) == component)
	break;

  if (!field)
    return NULL_TREE;

  /* If this field is not in the specified record, see if we can find
     something in the record whose original field is the same as this one. */
  if (DECL_CONTEXT (field) != record_type)
    /* Check if there is a field with name COMPONENT in the record.  */
    {
      tree new_field;

      /* First loop thru normal components.  */

      for (new_field = TYPE_FIELDS (record_type); new_field;
	   new_field = TREE_CHAIN (new_field))
	if (field == new_field
	    || DECL_ORIGINAL_FIELD (new_field) == field
	    || new_field == DECL_ORIGINAL_FIELD (field)
	    || (DECL_ORIGINAL_FIELD (field)
		&& (DECL_ORIGINAL_FIELD (field)
		    == DECL_ORIGINAL_FIELD (new_field))))
	  break;

      /* Next, loop thru DECL_INTERNAL_P components if we haven't found
         the component in the first search. Doing this search in 2 steps
         is required to avoiding hidden homonymous fields in the
         _Parent field.  */

      if (!new_field)
	for (new_field = TYPE_FIELDS (record_type); new_field;
	     new_field = TREE_CHAIN (new_field))
	  if (DECL_INTERNAL_P (new_field))
	    {
	      tree field_ref
		= build_simple_component_ref (record_variable,
					      NULL_TREE, new_field, no_fold_p);
	      ref = build_simple_component_ref (field_ref, NULL_TREE, field,
						no_fold_p);

	      if (ref)
		return ref;
	    }

      field = new_field;
    }

  if (!field)
    return NULL_TREE;

  /* If the field's offset has overflowed, do not attempt to access it
     as doing so may trigger sanity checks deeper in the back-end.
     Note that we don't need to warn since this will be done on trying
     to declare the object.  */
  if (TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST
      && TREE_CONSTANT_OVERFLOW (DECL_FIELD_OFFSET (field)))
    return NULL_TREE;

  /* It would be nice to call "fold" here, but that can lose a type
     we need to tag a PLACEHOLDER_EXPR with, so we can't do it.  */
  ref = build3 (COMPONENT_REF, TREE_TYPE (field), record_variable, field,
		NULL_TREE);

  if (TREE_READONLY (record_variable) || TREE_READONLY (field))
    TREE_READONLY (ref) = 1;
  if (TREE_THIS_VOLATILE (record_variable) || TREE_THIS_VOLATILE (field)
      || TYPE_VOLATILE (record_type))
    TREE_THIS_VOLATILE (ref) = 1;

  return no_fold_p ? ref : fold (ref);
}

/* Like build_simple_component_ref, except that we give an error if the
   reference could not be found.  */

tree
build_component_ref (tree record_variable, tree component,
                     tree field, bool no_fold_p)
{
  tree ref = build_simple_component_ref (record_variable, component, field,
					 no_fold_p);

  if (ref)
    return ref;

  /* If FIELD was specified, assume this is an invalid user field so
     raise constraint error.  Otherwise, we can't find the type to return, so
     abort.  */
  gcc_assert (field);
  return build1 (NULL_EXPR, TREE_TYPE (field),
		 build_call_raise (CE_Discriminant_Check_Failed, Empty));
}

/* Build a GCC tree to call an allocation or deallocation function.
   If GNU_OBJ is nonzero, it is an object to deallocate.  Otherwise,
   generate an allocator.

   GNU_SIZE is the size of the object in bytes and ALIGN is the alignment in
   bits.  GNAT_PROC, if present, is a procedure to call and GNAT_POOL is the
   storage pool to use.  If not preset, malloc and free will be used except
   if GNAT_PROC is the "fake" value of -1, in which case we allocate the
   object dynamically on the stack frame.  */

tree
build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, unsigned align,
                          Entity_Id gnat_proc, Entity_Id gnat_pool,
                          Node_Id gnat_node)
{
  tree gnu_align = size_int (align / BITS_PER_UNIT);

  gnu_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_size, gnu_obj);

  if (Present (gnat_proc))
    {
      /* The storage pools are obviously always tagged types, but the
	 secondary stack uses the same mechanism and is not tagged */
      if (Is_Tagged_Type (Etype (gnat_pool)))
	{
	  /* The size is the third parameter; the alignment is the
             same type.  */
	  Entity_Id gnat_size_type
	    = Etype (Next_Formal (Next_Formal (First_Formal (gnat_proc))));
	  tree gnu_size_type = gnat_to_gnu_type (gnat_size_type);
	  tree gnu_proc = gnat_to_gnu (gnat_proc);
	  tree gnu_proc_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_proc);
	  tree gnu_pool = gnat_to_gnu (gnat_pool);
	  tree gnu_pool_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_pool);
	  tree gnu_args = NULL_TREE;
	  tree gnu_call;

	  /* The first arg is always the address of the storage pool; next
	     comes the address of the object, for a deallocator, then the
	     size and alignment.  */
	  gnu_args
	    = chainon (gnu_args, build_tree_list (NULL_TREE, gnu_pool_addr));

	  if (gnu_obj)
	    gnu_args
	      = chainon (gnu_args, build_tree_list (NULL_TREE, gnu_obj));

	  gnu_args
	    = chainon (gnu_args,
		       build_tree_list (NULL_TREE,
					convert (gnu_size_type, gnu_size)));
	  gnu_args
	    = chainon (gnu_args,
		       build_tree_list (NULL_TREE,
					convert (gnu_size_type, gnu_align)));

	  gnu_call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (gnu_proc)),
			     gnu_proc_addr, gnu_args, NULL_TREE);
	  TREE_SIDE_EFFECTS (gnu_call) = 1;
	  return gnu_call;
	}

      /* Secondary stack case.  */
      else
	{
	  /* The size is the second parameter */
	  Entity_Id gnat_size_type
	    = Etype (Next_Formal (First_Formal (gnat_proc)));
	  tree gnu_size_type = gnat_to_gnu_type (gnat_size_type);
	  tree gnu_proc = gnat_to_gnu (gnat_proc);
	  tree gnu_proc_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_proc);
	  tree gnu_args = NULL_TREE;
	  tree gnu_call;

	  /* The first arg is the address of the object, for a
	     deallocator, then the size */
	  if (gnu_obj)
	    gnu_args
	      = chainon (gnu_args, build_tree_list (NULL_TREE, gnu_obj));

	  gnu_args
	    = chainon (gnu_args,
		       build_tree_list (NULL_TREE,
					convert (gnu_size_type, gnu_size)));

	  gnu_call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (gnu_proc)),
			     gnu_proc_addr, gnu_args, NULL_TREE);
	  TREE_SIDE_EFFECTS (gnu_call) = 1;
	  return gnu_call;
	}
    }

  else if (gnu_obj)
    return build_call_1_expr (free_decl, gnu_obj);

  /* ??? For now, disable variable-sized allocators in the stack since
     we can't yet gimplify an ALLOCATE_EXPR.  */
  else if (gnat_pool == -1
	   && TREE_CODE (gnu_size) == INTEGER_CST && !flag_stack_check)
    {
      /* If the size is a constant, we can put it in the fixed portion of
	 the stack frame to avoid the need to adjust the stack pointer.  */
      if (TREE_CODE (gnu_size) == INTEGER_CST && !flag_stack_check)
	{
	  tree gnu_range
	    = build_range_type (NULL_TREE, size_one_node, gnu_size);
	  tree gnu_array_type = build_array_type (char_type_node, gnu_range);
	  tree gnu_decl
	    = create_var_decl (get_identifier ("RETVAL"), NULL_TREE,
			       gnu_array_type, NULL_TREE, false, false, false,
			       false, NULL, gnat_node);

	  return convert (ptr_void_type_node,
			  build_unary_op (ADDR_EXPR, NULL_TREE, gnu_decl));
	}
      else
	gcc_unreachable ();
#if 0
	return build2 (ALLOCATE_EXPR, ptr_void_type_node, gnu_size, gnu_align);
#endif
    }
  else
    {
      if (Nkind (gnat_node) != N_Allocator || !Comes_From_Source (gnat_node))
        Check_No_Implicit_Heap_Alloc (gnat_node);
      return build_call_1_expr (malloc_decl, gnu_size);
    }
}

/* Build a GCC tree to correspond to allocating an object of TYPE whose
   initial value is INIT, if INIT is nonzero.  Convert the expression to
   RESULT_TYPE, which must be some type of pointer.  Return the tree.
   GNAT_PROC and GNAT_POOL optionally give the procedure to call and
   the storage pool to use.  GNAT_NODE is used to provide an error
   location for restriction violations messages.  If IGNORE_INIT_TYPE is
   true, ignore the type of INIT for the purpose of determining the size;
   this will cause the maximum size to be allocated if TYPE is of
   self-referential size.  */

tree
build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
                 Entity_Id gnat_pool, Node_Id gnat_node, bool ignore_init_type)
{
  tree size = TYPE_SIZE_UNIT (type);
  tree result;

  /* If the initializer, if present, is a NULL_EXPR, just return a new one.  */
  if (init && TREE_CODE (init) == NULL_EXPR)
    return build1 (NULL_EXPR, result_type, TREE_OPERAND (init, 0));

  /* If RESULT_TYPE is a fat or thin pointer, set SIZE to be the sum of the
     sizes of the object and its template.  Allocate the whole thing and
     fill in the parts that are known.  */
  else if (TYPE_FAT_OR_THIN_POINTER_P (result_type))
    {
      tree storage_type
	= build_unc_object_type_from_ptr (result_type, type,
					  get_identifier ("ALLOC"));
      tree template_type = TREE_TYPE (TYPE_FIELDS (storage_type));
      tree storage_ptr_type = build_pointer_type (storage_type);
      tree storage;
      tree template_cons = NULL_TREE;

      size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (storage_type),
					     init);

      /* If the size overflows, pass -1 so the allocator will raise
	 storage error.  */
      if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size))
	size = ssize_int (-1);

      storage = build_call_alloc_dealloc (NULL_TREE, size,
					  TYPE_ALIGN (storage_type),
					  gnat_proc, gnat_pool, gnat_node);
      storage = convert (storage_ptr_type, protect_multiple_eval (storage));

      if (TREE_CODE (type) == RECORD_TYPE && TYPE_IS_PADDING_P (type))
	{
	  type = TREE_TYPE (TYPE_FIELDS (type));

	  if (init)
	    init = convert (type, init);
	}

      /* If there is an initializing expression, make a constructor for
	 the entire object including the bounds and copy it into the
	 object.  If there is no initializing expression, just set the
	 bounds.  */
      if (init)
	{
	  template_cons = tree_cons (TREE_CHAIN (TYPE_FIELDS (storage_type)),
				     init, NULL_TREE);
	  template_cons = tree_cons (TYPE_FIELDS (storage_type),
				     build_template (template_type, type,
						     init),
				     template_cons);

	  return convert
	    (result_type,
	     build2 (COMPOUND_EXPR, storage_ptr_type,
		     build_binary_op
		     (MODIFY_EXPR, storage_type,
		      build_unary_op (INDIRECT_REF, NULL_TREE,
				      convert (storage_ptr_type, storage)),
		      gnat_build_constructor (storage_type, template_cons)),
		     convert (storage_ptr_type, storage)));
	}
      else
	return build2
	  (COMPOUND_EXPR, result_type,
	   build_binary_op
	   (MODIFY_EXPR, template_type,
	    build_component_ref
	    (build_unary_op (INDIRECT_REF, NULL_TREE,
			     convert (storage_ptr_type, storage)),
	     NULL_TREE, TYPE_FIELDS (storage_type), 0),
	    build_template (template_type, type, NULL_TREE)),
	   convert (result_type, convert (storage_ptr_type, storage)));
    }

  /* If we have an initializing expression, see if its size is simpler
     than the size from the type.  */
  if (!ignore_init_type && init && TYPE_SIZE_UNIT (TREE_TYPE (init))
      && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (init))) == INTEGER_CST
	  || CONTAINS_PLACEHOLDER_P (size)))
    size = TYPE_SIZE_UNIT (TREE_TYPE (init));

  /* If the size is still self-referential, reference the initializing
     expression, if it is present.  If not, this must have been a
     call to allocate a library-level object, in which case we use
     the maximum size.  */
  if (CONTAINS_PLACEHOLDER_P (size))
    {
      if (!ignore_init_type && init)
	size = substitute_placeholder_in_expr (size, init);
      else
	size = max_size (size, true);
    }

  /* If the size overflows, pass -1 so the allocator will raise
     storage error.  */
  if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size))
    size = ssize_int (-1);

  /* If this is a type whose alignment is larger than the
     biggest we support in normal alignment and this is in
     the default storage pool, make an "aligning type", allocate
     it, point to the field we need, and return that.  */
  if (TYPE_ALIGN (type) > BIGGEST_ALIGNMENT
      && No (gnat_proc))
    {
      tree new_type = make_aligning_type (type, TYPE_ALIGN (type), size);

      result = build_call_alloc_dealloc (NULL_TREE, TYPE_SIZE_UNIT (new_type),
					 BIGGEST_ALIGNMENT, Empty,
					 Empty, gnat_node);
      result = save_expr (result);
      result = convert (build_pointer_type (new_type), result);
      result = build_unary_op (INDIRECT_REF, NULL_TREE, result);
      result = build_component_ref (result, NULL_TREE,
				    TYPE_FIELDS (new_type), 0);
      result = convert (result_type,
			build_unary_op (ADDR_EXPR, NULL_TREE, result));
    }
  else
    result = convert (result_type,
		      build_call_alloc_dealloc (NULL_TREE, size,
						TYPE_ALIGN (type),
						gnat_proc,
						gnat_pool,
						gnat_node));

  /* If we have an initial value, put the new address into a SAVE_EXPR, assign
     the value, and return the address.  Do this with a COMPOUND_EXPR.  */

  if (init)
    {
      result = save_expr (result);
      result
	= build2 (COMPOUND_EXPR, TREE_TYPE (result),
		  build_binary_op
		  (MODIFY_EXPR, NULL_TREE,
		   build_unary_op (INDIRECT_REF,
				   TREE_TYPE (TREE_TYPE (result)), result),
		   init),
		  result);
    }

  return convert (result_type, result);
}

/* Fill in a VMS descriptor for EXPR and return a constructor for it.
   GNAT_FORMAL is how we find the descriptor record.  */

tree
fill_vms_descriptor (tree expr, Entity_Id gnat_formal)
{
  tree record_type = TREE_TYPE (TREE_TYPE (get_gnu_tree (gnat_formal)));
  tree field;
  tree const_list = NULL_TREE;

  expr = maybe_unconstrained_array (expr);
  gnat_mark_addressable (expr);

  for (field = TYPE_FIELDS (record_type); field; field = TREE_CHAIN (field))
    const_list
      = tree_cons (field,
		   convert (TREE_TYPE (field),
			    SUBSTITUTE_PLACEHOLDER_IN_EXPR
			    (DECL_INITIAL (field), expr)),
		   const_list);

  return gnat_build_constructor (record_type, nreverse (const_list));
}

/* Indicate that we need to make the address of EXPR_NODE and it therefore
   should not be allocated in a register.  Returns true if successful.  */

bool
gnat_mark_addressable (tree expr_node)
{
  while (1)
    switch (TREE_CODE (expr_node))
      {
      case ADDR_EXPR:
      case COMPONENT_REF:
      case ARRAY_REF:
      case ARRAY_RANGE_REF:
      case REALPART_EXPR:
      case IMAGPART_EXPR:
      case VIEW_CONVERT_EXPR:
      case CONVERT_EXPR:
      case NON_LVALUE_EXPR:
      case NOP_EXPR:
	expr_node = TREE_OPERAND (expr_node, 0);
	break;

      case CONSTRUCTOR:
	TREE_ADDRESSABLE (expr_node) = 1;
	return true;

      case VAR_DECL:
      case PARM_DECL:
      case RESULT_DECL:
	TREE_ADDRESSABLE (expr_node) = 1;
	return true;

      case FUNCTION_DECL:
	TREE_ADDRESSABLE (expr_node) = 1;
	return true;

      case CONST_DECL:
	return (DECL_CONST_CORRESPONDING_VAR (expr_node)
		&& (gnat_mark_addressable
		    (DECL_CONST_CORRESPONDING_VAR (expr_node))));
      default:
	return true;
    }
}
