/* expr.cc -- Lower D frontend expressions to GCC trees.
   Copyright (C) 2015-2021 Free Software Foundation, Inc.

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

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

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"

#include "dmd/aggregate.h"
#include "dmd/ctfe.h"
#include "dmd/declaration.h"
#include "dmd/expression.h"
#include "dmd/identifier.h"
#include "dmd/init.h"
#include "dmd/module.h"
#include "dmd/mtype.h"
#include "dmd/template.h"

#include "tree.h"
#include "fold-const.h"
#include "diagnostic.h"
#include "langhooks.h"
#include "tm.h"
#include "function.h"
#include "toplev.h"
#include "varasm.h"
#include "predict.h"
#include "stor-layout.h"

#include "d-tree.h"


/* Determine if type T is a struct that has a postblit.  */

static bool
needs_postblit (Type *t)
{
  t = t->baseElemOf ();

  if (TypeStruct *ts = t->isTypeStruct ())
    {
      if (ts->sym->postblit)
	return true;
    }

  return false;
}

/* Determine if type T is a struct that has a destructor.  */

static bool
needs_dtor (Type *t)
{
  t = t->baseElemOf ();

  if (TypeStruct *ts = t->isTypeStruct ())
    {
      if (ts->sym->dtor)
	return true;
    }

  return false;
}

/* Determine if expression E is a suitable lvalue.  */

static bool
lvalue_p (Expression *e)
{
  SliceExp *se = e->isSliceExp ();
  if (se != NULL && se->e1->isLvalue ())
    return true;

  CastExp *ce = e->isCastExp ();
  if (ce != NULL && ce->e1->isLvalue ())
    return true;

  return (e->op != TOKslice && e->isLvalue ());
}

/* Build an expression of code CODE, data type TYPE, and operands ARG0 and
   ARG1.  Perform relevant conversions needed for correct code operations.  */

static tree
binary_op (tree_code code, tree type, tree arg0, tree arg1)
{
  tree t0 = TREE_TYPE (arg0);
  tree t1 = TREE_TYPE (arg1);
  tree ret = NULL_TREE;

  /* Deal with float mod expressions immediately.  */
  if (code == FLOAT_MOD_EXPR)
    return build_float_modulus (type, arg0, arg1);

  if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
    return build_nop (type, build_offset_op (code, arg0, arg1));

  if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
    return build_nop (type, build_offset_op (code, arg1, arg0));

  if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
    {
      gcc_assert (code == MINUS_EXPR);
      tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);

      /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
	 pointers.  If some platform cannot provide that, or has a larger
	 ptrdiff_type to support differences larger than half the address
	 space, cast the pointers to some larger integer type and do the
	 computations in that type.  */
      if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
	ret = fold_build2 (MINUS_EXPR, ptrtype,
			   d_convert (ptrtype, arg0),
			   d_convert (ptrtype, arg1));
      else
	ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
    }
  else
    {
      /* If the operation needs excess precision.  */
      tree eptype = excess_precision_type (type);
      if (eptype != NULL_TREE)
	{
	  arg0 = d_convert (eptype, arg0);
	  arg1 = d_convert (eptype, arg1);
	}
      else
	{
	  /* Front-end does not do this conversion and GCC does not
	     always do it right.  */
	  if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
	    arg1 = d_convert (t0, arg1);
	  else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
	    arg0 = d_convert (t1, arg0);

	  eptype = type;
	}

      ret = build2 (code, eptype, arg0, arg1);
    }

  return d_convert (type, ret);
}

/* Build a binary expression of code CODE, assigning the result into E1.  */

static tree
binop_assignment (tree_code code, Expression *e1, Expression *e2)
{
  /* Skip casts for lhs assignment.  */
  Expression *e1b = e1;
  while (e1b->op == TOKcast)
    {
      CastExp *ce = e1b->isCastExp ();
      gcc_assert (same_type_p (ce->type, ce->to));
      e1b = ce->e1;
    }

  /* Stabilize LHS for assignment.  */
  tree lhs = build_expr (e1b);
  tree lexpr = stabilize_expr (&lhs);

  /* The LHS expression could be an assignment, to which its operation gets
     lost during gimplification.  */
  if (TREE_CODE (lhs) == MODIFY_EXPR)
    {
      /* If LHS has side effects, call stabilize_reference on it, so it can
	 be evaluated multiple times.  */
      if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
	lhs = build_assign (MODIFY_EXPR,
			    stabilize_reference (TREE_OPERAND (lhs, 0)),
			    TREE_OPERAND (lhs, 1));

      lexpr = compound_expr (lexpr, lhs);
      lhs = TREE_OPERAND (lhs, 0);
    }

  lhs = stabilize_reference (lhs);

  /* Save RHS, to ensure that the expression is evaluated before LHS.  */
  tree rhs = build_expr (e2);
  tree rexpr = d_save_expr (rhs);

  rhs = binary_op (code, build_ctype (e1->type),
		   convert_expr (lhs, e1b->type, e1->type), rexpr);
  if (TREE_SIDE_EFFECTS (rhs))
    rhs = compound_expr (rexpr, rhs);

  tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
  return compound_expr (lexpr, expr);
}

/* Implements the visitor interface to build the GCC trees of all Expression
   AST classes emitted from the D Front-end.
   All visit methods accept one parameter E, which holds the frontend AST
   of the expression to compile.  They also don't return any value, instead
   generated code is cached in RESULT_ and returned from the caller.  */

class ExprVisitor : public Visitor
{
  using Visitor::visit;

  tree result_;
  bool constp_;
  bool literalp_;

public:
  ExprVisitor (bool constp, bool literalp)
  {
    this->result_ = NULL_TREE;
    this->constp_ = constp;
    this->literalp_ = literalp;
  }

  tree result (void)
  {
    return this->result_;
  }

  /* Visitor interfaces, each Expression class should have
     overridden the default.  */

  void visit (Expression *)
  {
    gcc_unreachable ();
  }

  /* Build a conditional expression.  If either the second or third
     expression is void, then the resulting type is void.  Otherwise
     they are implicitly converted to a common type.  */

  void visit (CondExp *e)
  {
    tree cond = convert_for_condition (build_expr (e->econd),
				       e->econd->type);
    tree t1 = build_expr (e->e1);
    tree t2 = build_expr (e->e2);

    if (e->type->ty != Tvoid)
      {
	t1 = convert_expr (t1, e->e1->type, e->type);
	t2 = convert_expr (t2, e->e2->type, e->type);
      }

    this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
  }

  /* Build an identity comparison expression.  Operands go through the
     usual conversions to bring them to a common type before comparison.
     The result type is bool.  */

  void visit (IdentityExp *e)
  {
    tree_code code = (e->op == TOKidentity) ? EQ_EXPR : NE_EXPR;
    Type *tb1 = e->e1->type->toBasetype ();
    Type *tb2 = e->e2->type->toBasetype ();

    if ((tb1->ty == Tsarray || tb1->ty == Tarray)
	&& (tb2->ty == Tsarray || tb2->ty == Tarray))
      {
	/* For static and dynamic arrays, identity is defined as referring to
	   the same array elements and the same number of elements.  */
	tree t1 = d_array_convert (e->e1);
	tree t2 = d_array_convert (e->e2);
	this->result_ = d_convert (build_ctype (e->type),
				   build_boolop (code, t1, t2));
      }
    else if (tb1->isfloating () && tb1->ty != Tvector)
      {
	/* For floating-point values, identity is defined as the bits in the
	   operands being identical.  */
	tree t1 = d_save_expr (build_expr (e->e1));
	tree t2 = d_save_expr (build_expr (e->e2));

	if (!tb1->iscomplex ())
	  this->result_ = build_float_identity (code, t1, t2);
	else
	  {
	    /* Compare the real and imaginary parts separately.  */
	    tree req = build_float_identity (code, real_part (t1),
					     real_part (t2));
	    tree ieq = build_float_identity (code, imaginary_part (t1),
					     imaginary_part (t2));

	    if (code == EQ_EXPR)
	      this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
	    else
	      this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
	  }
      }
    else if (TypeStruct *ts = tb1->isTypeStruct ())
      {
	/* For struct objects, identity is defined as bits in operands being
	   identical also.  Alignment holes in structs are ignored.  */
	tree t1 = build_expr (e->e1);
	tree t2 = build_expr (e->e2);

	gcc_assert (same_type_p (tb1, tb2));

	this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
      }
    else
      {
	/* For operands of other types, identity is defined as being the
	   same as equality expressions.  */
	tree t1 = build_expr (e->e1);
	tree t2 = build_expr (e->e2);
	this->result_ = d_convert (build_ctype (e->type),
				   build_boolop (code, t1, t2));
      }
  }

  /* Build an equality expression, which compare the two operands for either
     equality or inequality.  Operands go through the usual conversions to bring
     them to a common type before comparison.  The result type is bool.  */

  void visit (EqualExp *e)
  {
    Type *tb1 = e->e1->type->toBasetype ();
    Type *tb2 = e->e2->type->toBasetype ();
    tree_code code = (e->op == TOKequal) ? EQ_EXPR : NE_EXPR;

    if ((tb1->ty == Tsarray || tb1->ty == Tarray)
	&& (tb2->ty == Tsarray || tb2->ty == Tarray))
      {
	/* For static and dynamic arrays, equality is defined as the lengths of
	   the arrays matching, and all the elements are equal.  */
	Type *t1elem = tb1->nextOf ()->toBasetype ();
	Type *t2elem = tb1->nextOf ()->toBasetype ();

	/* Check if comparisons of arrays can be optimized using memcmp.
	   This will inline EQ expressions as:
		e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
	    Or when generating a NE expression:
		e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0;  */
	if ((t1elem->isintegral () || t1elem->ty == Tvoid
	     || (t1elem->ty == Tstruct && !t1elem->isTypeStruct ()->sym->xeq))
	    && t1elem->ty == t2elem->ty)
	  {
	    tree t1 = d_array_convert (e->e1);
	    tree t2 = d_array_convert (e->e2);
	    tree result;

	    /* Make temporaries to prevent multiple evaluations.  */
	    tree t1saved = d_save_expr (t1);
	    tree t2saved = d_save_expr (t2);

	    /* Length of arrays, for comparisons done before calling memcmp.  */
	    tree t1len = d_array_length (t1saved);
	    tree t2len = d_array_length (t2saved);

	    /* Reference to array data.  */
	    tree t1ptr = d_array_ptr (t1saved);
	    tree t2ptr = d_array_ptr (t2saved);

	    /* Compare arrays using memcmp if possible, otherwise for structs,
	       each field is compared inline.  */
	    if (t1elem->ty != Tstruct
		|| identity_compare_p (t1elem->isTypeStruct ()->sym))
	      {
		tree size = size_mult_expr (t1len, size_int (t1elem->size ()));

		result = build_memcmp_call (t1ptr, t2ptr, size);
		result = build_boolop (code, result, integer_zero_node);
	      }
	    else
	      {
		StructDeclaration *sd = t1elem->isTypeStruct ()->sym;

		result = build_array_struct_comparison (code, sd, t1len,
							t1ptr, t2ptr);
	      }

	    /* Check array length first before passing to memcmp.
	       For equality expressions, this becomes:
		    (e1.length == 0 || memcmp);
	       Otherwise for inequality:
		    (e1.length != 0 && memcmp);  */
	    tree tsizecmp = build_boolop (code, t1len, size_zero_node);
	    if (e->op == TOKequal)
	      result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
	    else
	      result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);

	    /* Finally, check if lengths of both arrays match if dynamic.
	       The frontend should have already guaranteed that static arrays
	       have same size.  */
	    if (tb1->ty == Tsarray && tb2->ty == Tsarray)
	      gcc_assert (tb1->size () == tb2->size ());
	    else
	      {
		tree tlencmp = build_boolop (code, t1len, t2len);
		if (e->op == TOKequal)
		  result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
		else
		  result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
	      }

	    /* Ensure left-to-right order of evaluation.  */
	    if (TREE_SIDE_EFFECTS (t2))
	      result = compound_expr (t2saved, result);

	    if (TREE_SIDE_EFFECTS (t1))
	      result = compound_expr (t1saved, result);

	    this->result_ = result;
	  }
	else
	  {
	    /* Use _adEq2() to compare each element.  */
	    Type *t1array = t1elem->arrayOf ();
	    tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
					 d_array_convert (e->e1),
					 d_array_convert (e->e2),
					 build_typeinfo (e->loc, t1array));

	    if (e->op == TOKnotequal)
	      result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);

	    this->result_ = result;
	  }
      }
    else if (TypeStruct *ts = tb1->isTypeStruct ())
      {
	/* Equality for struct objects means the logical product of all
	   equality results of the corresponding object fields.  */
	tree t1 = build_expr (e->e1);
	tree t2 = build_expr (e->e2);

	gcc_assert (same_type_p (tb1, tb2));

	this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
      }
    else if (tb1->ty == Taarray && tb2->ty == Taarray)
      {
	/* Use _aaEqual() for associative arrays.  */
	tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
				     build_typeinfo (e->loc, tb1),
				     build_expr (e->e1),
				     build_expr (e->e2));

	if (e->op == TOKnotequal)
	  result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);

	this->result_ = result;
      }
    else
      {
	/* For operands of other types, equality is defined as the bit pattern
	   of the type matches exactly.  */
	tree t1 = build_expr (e->e1);
	tree t2 = build_expr (e->e2);

	this->result_ = d_convert (build_ctype (e->type),
				   build_boolop (code, t1, t2));
      }
  }

  /* Build an `in' expression.  This is a condition to see if an element
     exists in an associative array.  The result is a pointer to the
     element, or null if false.  */

  void visit (InExp *e)
  {
    Type *tb2 = e->e2->type->toBasetype ();
    Type *tkey = tb2->isTypeAArray ()->index->toBasetype ();
    tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);

    /* Build a call to _aaInX().  */
    this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
				   build_expr (e->e2),
				   build_typeinfo (e->loc, tkey),
				   build_address (key));
  }

  /* Build a relational expression.  The result type is bool.  */

  void visit (CmpExp *e)
  {
    Type *tb1 = e->e1->type->toBasetype ();
    Type *tb2 = e->e2->type->toBasetype ();

    tree result;
    tree_code code;

    switch (e->op)
      {
      case TOKle:
	code = LE_EXPR;
	break;

      case TOKlt:
	code = LT_EXPR;
	break;

      case TOKge:
	code = GE_EXPR;
	break;

      case TOKgt:
	code = GT_EXPR;
	break;

      default:
	gcc_unreachable ();
      }

    if ((tb1->ty == Tsarray || tb1->ty == Tarray)
	&& (tb2->ty == Tsarray || tb2->ty == Tarray))
      {
	/* For static and dynamic arrays, the result of the relational op is
	   the result of the operator applied to the first non-equal element
	   of the array.  If two arrays compare equal, but are of different
	   lengths, the shorter array compares as less than the longer.  */
	Type *telem = tb1->nextOf ()->toBasetype ();

	tree call = build_libcall (LIBCALL_ADCMP2, Type::tint32, 3,
				   d_array_convert (e->e1),
				   d_array_convert (e->e2),
				   build_typeinfo (e->loc, telem->arrayOf ()));
	result = build_boolop (code, call, integer_zero_node);

	this->result_ = d_convert (build_ctype (e->type), result);
	return;
      }

    /* Simple comparison.  */
    result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
    this->result_ = d_convert (build_ctype (e->type), result);
  }

  /* Build a logical `and if' or `or if' expression.  If the right operand
     expression is void, then the resulting type is void.  Otherwise the
     result is bool.  */

  void visit (LogicalExp *e)
  {
    tree_code code = (e->op == TOKandand) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;

    if (e->e2->type->toBasetype ()->ty != Tvoid)
      {
	tree t1 = build_expr (e->e1);
	tree t2 = build_expr (e->e2);

	t1 = convert_for_condition (t1, e->e1->type);
	t2 = convert_for_condition (t2, e->e2->type);

	this->result_ = d_convert (build_ctype (e->type),
				   build_boolop (code, t1, t2));
      }
    else
      {
	tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
	tree t2 = build_expr_dtor (e->e2);

	/* Invert condition for logical or if expression.  */
	if (e->op == TOKoror)
	  t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);

	this->result_ = build_condition (build_ctype (e->type),
					 t1, t2, void_node);
      }
  }

  /* Build a binary operand expression.  Operands go through usual arithmetic
     conversions to bring them to a common type before evaluating.  */

  void visit (BinExp *e)
  {
    tree_code code;

    switch (e->op)
      {
      case TOKadd:
      case TOKmin:
	if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
	    || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
	  {
	    /* If the result is complex, then we can shortcut binary_op.
	       Frontend should have already validated types and sizes.  */
	    tree t1 = build_expr (e->e1);
	    tree t2 = build_expr (e->e2);

	    if (e->op == TOKmin)
	      t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);

	    if (e->e1->type->isreal ())
	      this->result_ = complex_expr (build_ctype (e->type), t1, t2);
	    else
	      this->result_ = complex_expr (build_ctype (e->type), t2, t1);

	    return;
	  }
	else
	  code = (e->op == TOKadd)
	    ? PLUS_EXPR : MINUS_EXPR;
	break;

      case TOKmul:
	code = MULT_EXPR;
	break;

      case TOKdiv:
	/* Determine if the div expression is a lowered pointer diff operation.
	   The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'.  */
	if (MinExp *me = e->e1->isMinExp ())
	  {
	    if (me->e1->type->ty == Tpointer && me->e2->type->ty == Tpointer
		&& e->e2->op == TOKint64)
	      {
		code = EXACT_DIV_EXPR;
		break;
	      }
	  }

	code = e->e1->type->isintegral ()
	  ? TRUNC_DIV_EXPR : RDIV_EXPR;
	break;

      case TOKmod:
	code = e->e1->type->isfloating ()
	  ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
	break;

      case TOKand:
	code = BIT_AND_EXPR;
	break;

      case TOKor:
	code = BIT_IOR_EXPR;
	break;

      case TOKxor:
	code = BIT_XOR_EXPR;
	break;

      case TOKshl:
	code = LSHIFT_EXPR;
	  break;

      case TOKshr:
	code = RSHIFT_EXPR;
	break;

      case TOKushr:
	code = UNSIGNED_RSHIFT_EXPR;
	break;

      default:
	gcc_unreachable ();
      }

    this->result_ = binary_op (code, build_ctype (e->type),
			       build_expr (e->e1), build_expr (e->e2));
  }


  /* Build a concat expression, which concatenates two or more arrays of the
     same type, producing a dynamic array with the result.  If one operand
     is an element type, that element is converted to an array of length 1.  */

  void visit (CatExp *e)
  {
    Type *tb1 = e->e1->type->toBasetype ();
    Type *tb2 = e->e2->type->toBasetype ();
    Type *etype;

    if (tb1->ty == Tarray || tb1->ty == Tsarray)
      etype = tb1->nextOf ();
    else
      etype = tb2->nextOf ();

    tree result;

    if (e->e1->op == TOKcat)
      {
	/* Flatten multiple concatenations to an array.
	   So the expression ((a ~ b) ~ c) becomes [a, b, c]  */
	int ndims = 2;

	for (Expression *ex = e->e1; ex->op == TOKcat;)
	  {
	    if (ex->op == TOKcat)
	      {
		ex = ex->isCatExp ()->e1;
		ndims++;
	      }
	  }

	/* Store all concatenation args to a temporary byte[][ndims] array.  */
	Type *targselem = Type::tint8->arrayOf ();
	tree var = build_local_temp (make_array_type (targselem, ndims));

	/* Loop through each concatenation from right to left.  */
	vec <constructor_elt, va_gc> *elms = NULL;
	CatExp *ce = e;
	int dim = ndims - 1;

	for (Expression *oe = ce->e2; oe != NULL;
	     (ce->e1->op != TOKcat
	      ? (oe = ce->e1)
	      : (ce = ce->e1->isCatExp (), oe = ce->e2)))
	  {
	    tree arg = d_array_convert (etype, oe);
	    tree index = size_int (dim);
	    CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));

	    /* Finished pushing all arrays.  */
	    if (oe == ce->e1)
	      break;

	    dim -= 1;
	  }

	/* Check there is no logic bug in constructing byte[][] of arrays.  */
	gcc_assert (dim == 0);
	tree init = build_constructor (TREE_TYPE (var), elms);
	var = compound_expr (modify_expr (var, init), var);

	tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
				   size_int (ndims), build_address (var));

	result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
				build_typeinfo (e->loc, e->type), arrs);
      }
    else
      {
	/* Handle single concatenation (a ~ b).  */
	result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
				build_typeinfo (e->loc, e->type),
				d_array_convert (etype, e->e1),
				d_array_convert (etype, e->e2));
      }

    this->result_ = result;
  }

  /* Build an assignment operator expression.  The right operand is implicitly
     converted to the type of the left operand, and assigned to it.  */

  void visit (BinAssignExp *e)
  {
    tree_code code;
    Expression *e1b = e->e1;

    switch (e->op)
      {
      case TOKaddass:
	code = PLUS_EXPR;
	break;

      case TOKminass:
	code = MINUS_EXPR;
	break;

      case TOKmulass:
	code = MULT_EXPR;
	break;

      case TOKdivass:
	code = e->e1->type->isintegral ()
	  ? TRUNC_DIV_EXPR : RDIV_EXPR;
	break;

      case TOKmodass:
	code = e->e1->type->isfloating ()
	  ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
	break;

      case TOKandass:
	code = BIT_AND_EXPR;
	break;

      case TOKorass:
	code = BIT_IOR_EXPR;
	break;

      case TOKxorass:
	code = BIT_XOR_EXPR;
	break;

      case TOKpowass:
	gcc_unreachable ();

      case TOKshlass:
	code = LSHIFT_EXPR;
	break;

      case TOKshrass:
      case TOKushrass:
	/* Use the original lhs type before it was promoted.  The left operand
	   of `>>>=' does not undergo integral promotions before shifting.
	   Strip off casts just incase anyway.  */
	while (e1b->op == TOKcast)
	  {
	    CastExp *ce = e1b->isCastExp ();
	    gcc_assert (same_type_p (ce->type, ce->to));
	    e1b = ce->e1;
	  }
	code = (e->op == TOKshrass) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
	break;

      default:
	gcc_unreachable ();
      }

    tree exp = binop_assignment (code, e1b, e->e2);
    this->result_ = convert_expr (exp, e1b->type, e->type);
  }

  /* Build a concat assignment expression.  The right operand is appended
     to the left operand.  */

  void visit (CatAssignExp *e)
  {
    Type *tb1 = e->e1->type->toBasetype ();
    Type *tb2 = e->e2->type->toBasetype ();
    Type *etype = tb1->nextOf ()->toBasetype ();

    /* Save the address of `e1', so it can be evaluated first.
       As all D run-time library functions for concat assignments update `e1'
       in-place and then return its value, the saved address can also be used as
       the result of this expression as well.  */
    tree lhs = build_expr (e->e1);
    tree lexpr = stabilize_expr (&lhs);
    tree ptr = d_save_expr (build_address (lhs));
    tree result = NULL_TREE;

    if (tb1->ty == Tarray && tb2->ty == Tdchar
	&& (etype->ty == Tchar || etype->ty == Twchar))
      {
	/* Append a dchar to a char[] or wchar[]:
	   The assignment is handled by the D run-time library, so only
	   need to call `_d_arrayappend[cw]d(&e1, e2)'  */
	libcall_fn libcall = (etype->ty == Tchar)
	  ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;

	result = build_libcall (libcall, e->type, 2,
				ptr, build_expr (e->e2));
      }
    else
      {
	gcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray);

	if ((tb2->ty == Tarray || tb2->ty == Tsarray)
	    && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
	  {
	    /* Append an array to another array:
	       The assignment is handled by the D run-time library, so only
	       need to call `_d_arrayappendT(ti, &e1, e2)'  */
	    result = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
				    build_typeinfo (e->loc, e->type),
				    ptr, d_array_convert (e->e2));
	  }
	else if (same_type_p (etype, tb2))
	  {
	    /* Append an element to an array:
	       The assignment is generated inline, so need to handle temporaries
	       here, and ensure that they are evaluated in the correct order.

	       The generated code should end up being equivalent to:
		    _d_arrayappendcTX(ti, &e1, 1)[e1.length - 1] = e2
	     */
	    tree callexp = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
					  build_typeinfo (e->loc, e->type),
					  ptr, size_one_node);
	    callexp = d_save_expr (callexp);

	    /* Assign e2 to last element.  */
	    tree offexp = d_array_length (callexp);
	    offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
			     offexp, size_one_node);

	    tree ptrexp = d_array_ptr (callexp);
	    ptrexp = void_okay_p (ptrexp);
	    ptrexp = build_array_index (ptrexp, offexp);

	    /* Evaluate expression before appending.  */
	    tree rhs = build_expr (e->e2);
	    tree rexpr = stabilize_expr (&rhs);

	    if (TREE_CODE (rhs) == CALL_EXPR)
	      rhs = force_target_expr (rhs);

	    result = modify_expr (build_deref (ptrexp), rhs);
	    result = compound_expr (rexpr, result);
	  }
	else
	  gcc_unreachable ();
      }

    /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr;  */
    result = compound_expr (compound_expr (lexpr, ptr), result);
    this->result_ = compound_expr (result, build_deref (ptr));
  }

  /* Build an assignment expression.  The right operand is implicitly
     converted to the type of the left operand, and assigned to it.  */

  void visit (AssignExp *e)
  {
    /* First, handle special assignment semantics.  */

    /* Look for array.length = n;  */
    if (e->e1->op == TOKarraylength)
      {
	/* Assignment to an array's length property; resize the array.  */
	ArrayLengthExp *ale = e->e1->isArrayLengthExp ();
	tree newlength = convert_expr (build_expr (e->e2), e->e2->type,
				       Type::tsize_t);
	tree ptr = build_address (build_expr (ale->e1));

	/* Don't want the basetype for the element type.  */
	Type *etype = ale->e1->type->toBasetype ()->nextOf ();
	libcall_fn libcall = etype->isZeroInit ()
	  ? LIBCALL_ARRAYSETLENGTHT : LIBCALL_ARRAYSETLENGTHIT;

	tree result = build_libcall (libcall, ale->e1->type, 3,
				     build_typeinfo (ale->loc, ale->e1->type),
				     newlength, ptr);

	this->result_ = d_array_length (result);
	return;
      }

    /* Look for array[] = n;  */
    if (e->e1->op == TOKslice)
      {
	SliceExp *se = e->e1->isSliceExp ();
	Type *stype = se->e1->type->toBasetype ();
	Type *etype = stype->nextOf ()->toBasetype ();

	/* Determine if we need to run postblit or dtor.  */
	bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
	bool destructor = needs_dtor (etype);

	if (e->memset & blockAssign)
	  {
	    /* Set a range of elements to one value.  */
	    tree t1 = d_save_expr (build_expr (e->e1));
	    tree t2 = build_expr (e->e2);
	    tree result;

	    if ((postblit || destructor) && e->op != TOKblit)
	      {
		libcall_fn libcall = (e->op == TOKconstruct)
		  ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN;
		/* So we can call postblits on const/immutable objects.  */
		Type *tm = etype->unSharedOf ()->mutableOf ();
		tree ti = build_typeinfo (e->loc, tm);

		tree result = build_libcall (libcall, Type::tvoid, 4,
					     d_array_ptr (t1),
					     build_address (t2),
					     d_array_length (t1), ti);
		this->result_ = compound_expr (result, t1);
		return;
	      }

	    if (integer_zerop (t2))
	      {
		tree size = size_mult_expr (d_array_length (t1),
					    size_int (etype->size ()));
		result = build_memset_call (d_array_ptr (t1), size);
	      }
	    else
	      result = build_array_set (d_array_ptr (t1),
					d_array_length (t1), t2);

	    this->result_ = compound_expr (result, t1);
	  }
	else
	  {
	    /* Perform a memcpy operation.  */
	    gcc_assert (e->e2->type->ty != Tpointer);

	    if (!postblit && !destructor)
	      {
		tree t1 = d_save_expr (d_array_convert (e->e1));
		tree t2 = d_save_expr (d_array_convert (e->e2));

		/* References to array data.  */
		tree t1ptr = d_array_ptr (t1);
		tree t1len = d_array_length (t1);
		tree t2ptr = d_array_ptr (t2);

		/* Generate: memcpy(to, from, size)  */
		tree size = size_mult_expr (t1len, size_int (etype->size ()));
		tree result = build_memcpy_call (t1ptr, t2ptr, size);

		/* Insert check that array lengths match and do not overlap.  */
		if (array_bounds_check ())
		  {
		    /* tlencmp = (t1len == t2len)  */
		    tree t2len = d_array_length (t2);
		    tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len);

		    /* toverlap = (t1ptr + size <= t2ptr
				   || t2ptr + size <= t1ptr)  */
		    tree t1ptrcmp = build_boolop (LE_EXPR,
						  build_offset (t1ptr, size),
						  t2ptr);
		    tree t2ptrcmp = build_boolop (LE_EXPR,
						  build_offset (t2ptr, size),
						  t1ptr);
		    tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp,
						  t2ptrcmp);

		    /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds()  */
		    tree tassert = build_array_bounds_call (e->loc);
		    tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR,
						      tlencmp, toverlap);

		    result = build_condition (void_type_node, tboundscheck,
					      result, tassert);
		  }

		this->result_ = compound_expr (result, t1);
	      }
	    else if ((postblit || destructor) && e->op != TOKblit)
	      {
		/* Generate: _d_arrayassign(ti, from, to)
			 or: _d_arrayctor(ti, from, to)  */
		libcall_fn libcall = (e->op == TOKconstruct)
		  ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN;

		this->result_ = build_libcall (libcall, e->type, 3,
					       build_typeinfo (e->loc, etype),
					       d_array_convert (e->e2),
					       d_array_convert (e->e1));
	      }
	    else
	      {
		/* Generate: _d_arraycopy()  */
		this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
					       size_int (etype->size ()),
					       d_array_convert (e->e2),
					       d_array_convert (e->e1));
	      }
	  }

	return;
      }

    /* Look for reference initializations.  */
    if (e->memset & referenceInit)
      {
	gcc_assert (e->op == TOKconstruct || e->op == TOKblit);
	gcc_assert (e->e1->op == TOKvar);

	Declaration *decl = e->e1->isVarExp ()->var;
	if (decl->storage_class & (STCout | STCref))
	  {
	    tree t2 = convert_for_assignment (build_expr (e->e2),
					      e->e2->type, e->e1->type);
	    tree t1 = build_expr (e->e1);
	    /* Want reference to lhs, not indirect ref.  */
	    t1 = TREE_OPERAND (t1, 0);
	    t2 = build_address (t2);

	    this->result_ = indirect_ref (build_ctype (e->type),
					  build_assign (INIT_EXPR, t1, t2));
	    return;
	  }
      }

    /* Other types of assignments that may require post construction.  */
    Type *tb1 = e->e1->type->toBasetype ();
    tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR;

    /* Look for struct assignment.  */
    if (tb1->ty == Tstruct)
      {
	tree t1 = build_expr (e->e1);
	tree t2 = convert_for_assignment (build_expr (e->e2, false, true),
					  e->e2->type, e->e1->type);
	StructDeclaration *sd = tb1->isTypeStruct ()->sym;

	/* Look for struct = 0.  */
	if (e->e2->op == TOKint64)
	  {
	    /* Use memset to fill struct.  */
	    gcc_assert (e->op == TOKblit);
	    tree result = build_memset_call (t1);

	    /* Maybe set-up hidden pointer to outer scope context.  */
	    if (sd->isNested ())
	      {
		tree field = get_symbol_decl (sd->vthis);
		tree value = build_vthis (sd);

		tree vthis_exp = modify_expr (component_ref (t1, field), value);
		result = compound_expr (result, vthis_exp);
	      }

	    this->result_ = compound_expr (result, t1);
	  }
	else
	  {
	    /* Simple struct literal assignment.  */
	    tree init = NULL_TREE;

	    /* Fill any alignment holes in the struct using memset.  */
	    if ((e->op == TOKconstruct
		 || (e->e2->op == TOKstructliteral && e->op == TOKblit))
		&& (sd->isUnionDeclaration () || !identity_compare_p (sd)))
	      {
		t1 = stabilize_reference (t1);
		init = build_memset_call (t1);
	      }

	    /* Elide generating assignment if init is all zeroes.  */
	    if (init != NULL_TREE && initializer_zerop (t2))
	      this->result_ = compound_expr (init, t1);
	    else
	      {
		tree result = build_assign (modifycode, t1, t2);
		this->result_ = compound_expr (init, result);
	      }
	  }

	return;
      }

    /* Look for static array assignment.  */
    if (tb1->ty == Tsarray)
      {
	/* Look for array = 0.  */
	if (e->e2->op == TOKint64)
	  {
	    /* Use memset to fill the array.  */
	    gcc_assert (e->op == TOKblit);
	    this->result_ = build_memset_call (build_expr (e->e1));
	    return;
	  }

	Type *etype = tb1->nextOf ();
	gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);

	/* Determine if we need to run postblit.  */
	bool postblit = needs_postblit (etype);
	bool destructor = needs_dtor (etype);
	bool lvalue = lvalue_p (e->e2);

	/* Optimize static array assignment with array literal.  Even if the
	   elements in rhs are all rvalues and don't have to call postblits,
	   this assignment should call dtors on old assigned elements.  */
	if ((!postblit && !destructor)
	    || (e->op == TOKconstruct && e->e2->op == TOKarrayliteral)
	    || (e->op == TOKconstruct && !lvalue && postblit)
	    || (e->op == TOKblit || e->e1->type->size () == 0))
	  {
	    tree t1 = build_expr (e->e1);
	    tree t2 = convert_for_assignment (build_expr (e->e2),
					      e->e2->type, e->e1->type);

	    this->result_ = build_assign (modifycode, t1, t2);
	    return;
	  }

	Type *arrtype = (e->type->ty == Tsarray) ? etype->arrayOf () : e->type;
	tree result;

	if (e->op == TOKconstruct)
	  {
	    /* Generate: _d_arrayctor(ti, from, to)  */
	    result = build_libcall (LIBCALL_ARRAYCTOR, arrtype, 3,
				    build_typeinfo (e->loc, etype),
				    d_array_convert (e->e2),
				    d_array_convert (e->e1));
	  }
	else
	  {
	    /* Generate: _d_arrayassign_l()
		     or: _d_arrayassign_r()  */
	    libcall_fn libcall = (lvalue)
	      ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
	    tree elembuf = build_local_temp (build_ctype (etype));

	    result = build_libcall (libcall, arrtype, 4,
				    build_typeinfo (e->loc, etype),
				    d_array_convert (e->e2),
				    d_array_convert (e->e1),
				    build_address (elembuf));
	  }

	/* Cast the libcall result back to a static array.  */
	if (e->type->ty == Tsarray)
	  result = indirect_ref (build_ctype (e->type),
				 d_array_ptr (result));

	this->result_ = result;
	return;
      }

    /* Simple assignment.  */
    tree t1 = build_expr (e->e1);
    tree t2 = convert_for_assignment (build_expr (e->e2),
				      e->e2->type, e->e1->type);

    this->result_ = build_assign (modifycode, t1, t2);
  }

  /* Build a postfix expression.  */

  void visit (PostExp *e)
  {
    tree result;

    if (e->op == TOKplusplus)
      {
	result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
			 build_expr (e->e1), build_expr (e->e2));
      }
    else if (e->op == TOKminusminus)
      {
	result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
			 build_expr (e->e1), build_expr (e->e2));
      }
    else
      gcc_unreachable ();

    TREE_SIDE_EFFECTS (result) = 1;
    this->result_ = result;
  }

  /* Build an index expression.  */

  void visit (IndexExp *e)
  {
    Type *tb1 = e->e1->type->toBasetype ();

    if (tb1->ty == Taarray)
      {
	/* Get the key for the associative array.  */
	Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
	tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
	libcall_fn libcall;
	tree tinfo, ptr;

	if (e->modifiable)
	  {
	    libcall = LIBCALL_AAGETY;
	    ptr = build_address (build_expr (e->e1));
	    tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());
	  }
	else
	  {
	    libcall = LIBCALL_AAGETRVALUEX;
	    ptr = build_expr (e->e1);
	    tinfo = build_typeinfo (e->loc, tkey);
	  }

	/* Index the associative array.  */
	tree result = build_libcall (libcall, e->type->pointerTo (), 4,
				     ptr, tinfo,
				     size_int (tb1->nextOf ()->size ()),
				     build_address (key));

	if (!e->indexIsInBounds && array_bounds_check ())
	  {
	    tree tassert = build_array_bounds_call (e->loc);

	    result = d_save_expr (result);
	    result = build_condition (TREE_TYPE (result),
				      d_truthvalue_conversion (result),
				      result, tassert);
	  }

	this->result_ = indirect_ref (build_ctype (e->type), result);
      }
    else
      {
	/* Get the data pointer and length for static and dynamic arrays.  */
	tree array = d_save_expr (build_expr (e->e1));
	tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());

	tree length = NULL_TREE;
	if (tb1->ty != Tpointer)
	  length = get_array_length (array, tb1);
	else
	  gcc_assert (e->lengthVar == NULL);

	/* The __dollar variable just becomes a placeholder for the
	   actual length.  */
	if (e->lengthVar)
	  e->lengthVar->csym = length;

	/* Generate the index.  */
	tree index = build_expr (e->e2);

	/* If it's a static array and the index is constant, the front end has
	   already checked the bounds.  */
	if (tb1->ty != Tpointer)
	  index = build_bounds_index_condition (e, index, length);

	/* Index the .ptr.  */
	ptr = void_okay_p (ptr);
	this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
				      build_array_index (ptr, index));
      }
  }

  /* Build a comma expression.  The type is the type of the right operand.  */

  void visit (CommaExp *e)
  {
    tree t1 = build_expr (e->e1);
    tree t2 = build_expr (e->e2);
    tree type = e->type ? build_ctype (e->type) : void_type_node;

    this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
  }

  /* Build an array length expression.  Returns the number of elements
     in the array.  The result is of type size_t.  */

  void visit (ArrayLengthExp *e)
  {
    if (e->e1->type->toBasetype ()->ty == Tarray)
      this->result_ = d_array_length (build_expr (e->e1));
    else
      {
	/* Static arrays have already been handled by the front-end.  */
	error ("unexpected type for array length: %qs", e->type->toChars ());
	this->result_ = error_mark_node;
      }
  }

  /* Build a delegate pointer expression.  This will return the frame
     pointer value as a type void*.  */

  void visit (DelegatePtrExp *e)
  {
    tree t1 = build_expr (e->e1);
    this->result_ = delegate_object (t1);
  }

  /* Build a delegate function pointer expression.  This will return the
     function pointer value as a function type.  */

  void visit (DelegateFuncptrExp *e)
  {
    tree t1 = build_expr (e->e1);
    this->result_ = delegate_method (t1);
  }

  /* Build a slice expression.  */

  void visit (SliceExp *e)
  {
    Type *tb = e->type->toBasetype ();
    Type *tb1 = e->e1->type->toBasetype ();
    gcc_assert (tb->ty == Tarray || tb->ty == Tsarray);

    /* Use convert-to-dynamic-array code if possible.  */
    if (!e->lwr)
      {
	tree result = build_expr (e->e1);
	if (e->e1->type->toBasetype ()->ty == Tsarray)
	  result = convert_expr (result, e->e1->type, e->type);

	this->result_ = result;
	return;
      }
    else
      gcc_assert (e->upr != NULL);

    /* Get the data pointer and length for static and dynamic arrays.  */
    tree array = d_save_expr (build_expr (e->e1));
    tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
    tree length = NULL_TREE;

    /* Our array is already a SAVE_EXPR if necessary, so we don't make length
       a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array.  */
    if (tb1->ty != Tpointer)
      length = get_array_length (array, tb1);
    else
      gcc_assert (e->lengthVar == NULL);

    /* The __dollar variable just becomes a placeholder for the
       actual length.  */
    if (e->lengthVar)
      e->lengthVar->csym = length;

    /* Generate upper and lower bounds.  */
    tree lwr_tree = d_save_expr (build_expr (e->lwr));
    tree upr_tree = d_save_expr (build_expr (e->upr));

    /* If the upper bound has any side effects, then the lower bound should be
       copied to a temporary always.  */
    if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
      lwr_tree = save_expr (lwr_tree);

    /* Adjust the .ptr offset.  */
    if (!integer_zerop (lwr_tree))
      {
	tree ptrtype = TREE_TYPE (ptr);
	ptr = build_array_index (void_okay_p (ptr), lwr_tree);
	ptr = build_nop (ptrtype, ptr);
      }

    /* Nothing more to do for static arrays, their bounds checking has been
       done at compile-time.  */
    if (tb->ty == Tsarray)
      {
	this->result_ = indirect_ref (build_ctype (e->type), ptr);
	return;
      }
    else
      gcc_assert (tb->ty == Tarray);

    /* Generate bounds checking code.  */
    tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree,
						   length);
    tree result = d_array_value (build_ctype (e->type), newlength, ptr);
    this->result_ = compound_expr (array, result);
  }

  /* Build a cast expression, which converts the given unary expression to the
     type of result.  */

  void visit (CastExp *e)
  {
    Type *ebtype = e->e1->type->toBasetype ();
    Type *tbtype = e->to->toBasetype ();
    tree result = build_expr (e->e1, this->constp_, this->literalp_);

    /* Just evaluate e1 if it has any side effects.  */
    if (tbtype->ty == Tvoid)
      this->result_ = build_nop (build_ctype (tbtype), result);
    else
      this->result_ = convert_for_rvalue (result, ebtype, tbtype);
  }

  /* Build a delete expression.  */

  void visit (DeleteExp *e)
  {
    tree t1 = build_expr (e->e1);
    Type *tb1 = e->e1->type->toBasetype ();

    if (tb1->ty == Tclass)
      {
	/* For class object references, if there is a destructor for that class,
	   the destructor is called for the object instance.  */
	libcall_fn libcall;

	if (e->e1->op == TOKvar)
	  {
	    VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
	    if (v && v->onstack)
	      {
		libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
		  ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;

		this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
		return;
	      }
	  }

	/* Otherwise, the garbage collector is called to immediately free the
	   memory allocated for the class instance.  */
	libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
	  ? LIBCALL_DELINTERFACE : LIBCALL_DELCLASS;

	t1 = build_address (t1);
	this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
      }
    else if (tb1->ty == Tarray)
      {
	/* For dynamic arrays, the garbage collector is called to immediately
	   release the memory.  */
	Type *telem = tb1->nextOf ()->baseElemOf ();
	tree ti = null_pointer_node;

	if (TypeStruct *ts = telem->isTypeStruct ())
	  {
	    /* Might need to run destructor on array contents.  */
	    if (ts->sym->dtor)
	      ti = build_typeinfo (e->loc, tb1->nextOf ());
	  }

	/* Generate: _delarray_t (&t1, ti);  */
	this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,
				       build_address (t1), ti);
      }
    else if (tb1->ty == Tpointer)
      {
	/* For pointers to a struct instance, if the struct has overloaded
	   operator delete, then that operator is called.  */
	t1 = build_address (t1);
	Type *tnext = tb1->isTypePointer ()->next->toBasetype ();

	if (TypeStruct *ts = tnext->isTypeStruct ())
	  {
	    if (ts->sym->dtor)
	      {
		tree ti = build_typeinfo (e->loc, tnext);
		this->result_ = build_libcall (LIBCALL_DELSTRUCT, Type::tvoid,
					       2, t1, ti);
		return;
	      }
	  }

	/* Otherwise, the garbage collector is called to immediately free the
	   memory allocated for the pointer.  */
	this->result_ = build_libcall (LIBCALL_DELMEMORY, Type::tvoid, 1, t1);
      }
    else
      {
	error ("don%'t know how to delete %qs", e->e1->toChars ());
	this->result_ = error_mark_node;
      }
  }

  /* Build a remove expression, which removes a particular key from an
     associative array.  */

  void visit (RemoveExp *e)
  {
    /* Check that the array is actually an associative array.  */
    if (e->e1->type->toBasetype ()->ty == Taarray)
      {
	Type *tb = e->e1->type->toBasetype ();
	Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
	tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);

	this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
				       build_expr (e->e1),
				       build_typeinfo (e->loc, tkey),
				       build_address (index));
      }
    else
      {
	error ("%qs is not an associative array", e->e1->toChars ());
	this->result_ = error_mark_node;
      }
  }

  /* Build an unary not expression.  */

  void visit (NotExp *e)
  {
    tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
    /* Need to convert to boolean type or this will fail.  */
    result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);

    this->result_ = d_convert (build_ctype (e->type), result);
  }

  /* Build a compliment expression, where all the bits in the value are
     complemented.  Note: unlike in C, the usual integral promotions
     are not performed prior to the complement operation.  */

  void visit (ComExp *e)
  {
    TY ty1 = e->e1->type->toBasetype ()->ty;
    gcc_assert (ty1 != Tarray && ty1 != Tsarray);

    this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
				 build_expr (e->e1));
  }

  /* Build an unary negation expression.  */

  void visit (NegExp *e)
  {
    TY ty1 = e->e1->type->toBasetype ()->ty;
    gcc_assert (ty1 != Tarray && ty1 != Tsarray);

    tree type = build_ctype (e->type);
    tree expr = build_expr (e->e1);

    /* If the operation needs excess precision.  */
    tree eptype = excess_precision_type (type);
    if (eptype != NULL_TREE)
      expr = d_convert (eptype, expr);
    else
      eptype = type;

    tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
    this->result_ = d_convert (type, ret);
  }

  /* Build a pointer index expression.  */

  void visit (PtrExp *e)
  {
    Type *tnext = NULL;
    size_t offset;
    tree result;

    if (e->e1->op == TOKadd)
      {
	AddExp *ae = e->e1->isAddExp ();
	if (ae->e1->op == TOKaddress
	    && ae->e2->isConst () && ae->e2->type->isintegral ())
	  {
	    Expression *ex = ae->e1->isAddrExp ()->e1;
	    tnext = ex->type->toBasetype ();
	    result = build_expr (ex);
	    offset = ae->e2->toUInteger ();
	  }
      }
    else if (e->e1->op == TOKsymoff)
      {
	SymOffExp *se = e->e1->isSymOffExp ();
	if (!declaration_reference_p (se->var))
	  {
	    tnext = se->var->type->toBasetype ();
	    result = get_decl_tree (se->var);
	    offset = se->offset;
	  }
      }

    /* Produce better code by converting *(#record + n) to
       COMPONENT_REFERENCE.  Otherwise, the variable will always be
       allocated in memory because its address is taken.  */
    if (tnext && tnext->ty == Tstruct)
      {
	StructDeclaration *sd = tnext->isTypeStruct ()->sym;

	for (size_t i = 0; i < sd->fields.length; i++)
	  {
	    VarDeclaration *field = sd->fields[i];

	    if (field->offset == offset
		&& same_type_p (field->type, e->type))
	      {
		/* Catch errors, backend will ICE otherwise.  */
		if (error_operand_p (result))
		  this->result_ = result;
		else
		  {
		    result  = component_ref (result, get_symbol_decl (field));
		    this->result_ = result;
		  }
		return;
	      }
	    else if (field->offset > offset)
	      break;
	  }
      }

    this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
  }

  /* Build an unary address expression.  */

  void visit (AddrExp *e)
  {
    tree type = build_ctype (e->type);
    tree exp;

    /* The frontend optimizer can convert const symbol into a struct literal.
       Taking the address of a struct literal is otherwise illegal.  */
    if (e->e1->op == TOKstructliteral)
      {
	StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
	gcc_assert (sle != NULL);

	/* Build the reference symbol, the decl is built first as the
	   initializer may have recursive references.  */
	if (!sle->sym)
	  {
	    sle->sym = build_artificial_decl (build_ctype (sle->type),
					      NULL_TREE, "S");
	    DECL_INITIAL (sle->sym) = build_expr (sle, true);
	    d_pushdecl (sle->sym);
	    rest_of_decl_compilation (sle->sym, 1, 0);
	  }

	exp = sle->sym;
      }
    else
      exp = build_expr (e->e1, this->constp_, this->literalp_);

    TREE_CONSTANT (exp) = 0;
    this->result_ = d_convert (type, build_address (exp));
  }

  /* Build a function call expression.  */

  void visit (CallExp *e)
  {
    Type *tb = e->e1->type->toBasetype ();
    Expression *e1b = e->e1;

    tree callee = NULL_TREE;
    tree object = NULL_TREE;
    tree cleanup = NULL_TREE;
    tree returnvalue = NULL_TREE;
    TypeFunction *tf = NULL;

    /* Calls to delegates can sometimes look like this.  */
    if (e1b->op == TOKcomma)
      {
	e1b = e1b->isCommaExp ()->e2;
	gcc_assert (e1b->op == TOKvar);

	Declaration *var = e1b->isVarExp ()->var;
	gcc_assert (var->isFuncDeclaration () && !var->needThis ());
      }

    if (e1b->op == TOKdotvar && tb->ty != Tdelegate)
      {
	DotVarExp *dve = e1b->isDotVarExp ();

	/* Don't modify the static initializer for struct literals.  */
	if (dve->e1->op == TOKstructliteral)
	  {
	    StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
	    sle->useStaticInit = false;
	  }

	FuncDeclaration *fd = dve->var->isFuncDeclaration ();
	if (fd != NULL)
	  {
	    /* Get the correct callee from the DotVarExp object.  */
	    tree fndecl = get_symbol_decl (fd);
	    AggregateDeclaration *ad = fd->isThis ();

	    /* Static method; ignore the object instance.  */
	    if (!ad)
	      callee = build_address (fndecl);
	    else
	      {
		tree thisexp = build_expr (dve->e1);

		/* When constructing temporaries, if the constructor throws,
		   then the object is destructed even though it is not a fully
		   constructed object yet.  And so this call will need to be
		   moved inside the TARGET_EXPR_INITIAL slot.  */
		if (fd->isCtorDeclaration ()
		    && TREE_CODE (thisexp) == COMPOUND_EXPR
		    && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
		    && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
		  {
		    cleanup = TREE_OPERAND (thisexp, 0);
		    thisexp = TREE_OPERAND (thisexp, 1);
		  }

		if (TREE_CODE (thisexp) == CONSTRUCTOR)
		  thisexp = force_target_expr (thisexp);

		/* Want reference to `this' object.  */
		if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
		  thisexp = build_address (thisexp);

		/* Make the callee a virtual call.  */
		if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
		  {
		    tree fntype = build_pointer_type (TREE_TYPE (fndecl));
		    tree thistype = build_ctype (ad->handleType ());
		    thisexp = build_nop (thistype, d_save_expr (thisexp));
		    fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
		  }
		else
		  fndecl = build_address (fndecl);

		/* C++ constructors return void, even though front-end semantic
		   treats them as implicitly returning `this'.  Set returnvalue
		   to override the result of this expression.  */
		if (fd->isCtorDeclaration () && fd->linkage == LINKcpp)
		  {
		    thisexp = d_save_expr (thisexp);
		    returnvalue = thisexp;
		  }

		callee = build_method_call (fndecl, thisexp, fd->type);
	      }
	  }
      }

    if (callee == NULL_TREE)
      callee = build_expr (e1b);

    if (METHOD_CALL_EXPR (callee))
      {
	/* This could be a delegate expression (TY == Tdelegate), but not
	   actually a delegate variable.  */
	if (e1b->op == TOKdotvar)
	  {
	    /* This gets the true function type, getting the function type
	       from e1->type can sometimes be incorrect, such as when calling
	       a `ref' return function.  */
	    tf = get_function_type (e1b->isDotVarExp ()->var->type);
	  }
	else
	  tf = get_function_type (tb);

	extract_from_method_call (callee, callee, object);
      }
    else if (tb->ty == Tdelegate)
      {
	/* Delegate call, extract .object and .funcptr from var.  */
	callee = d_save_expr (callee);
	tf = get_function_type (tb);
	object = delegate_object (callee);
	callee = delegate_method (callee);
      }
    else if (e1b->op == TOKvar)
      {
	FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
	gcc_assert (fd != NULL);
	tf = get_function_type (fd->type);

	if (fd->isNested ())
	  {
	    /* Maybe re-evaluate symbol storage treating `fd' as public.  */
	    if (call_by_alias_p (d_function_chain->function, fd))
	      TREE_PUBLIC (callee) = 1;

	    object = get_frame_for_symbol (fd);
	  }
	else if (fd->needThis ())
	  {
	    error_at (make_location_t (e1b->loc),
		      "need %<this%> to access member %qs", fd->toChars ());
	    /* Continue compiling...  */
	    object = null_pointer_node;
	  }
      }
    else
      {
	/* Normal direct function call.  */
	tf = get_function_type (tb);
      }

    gcc_assert (tf != NULL);

    /* Now we have the type, callee and maybe object reference,
       build the call expression.  */
    tree exp = d_build_call (tf, callee, object, e->arguments);

    if (returnvalue != NULL_TREE)
      exp = compound_expr (exp, returnvalue);

    if (tf->isref)
      exp = build_deref (exp);

    /* Some library calls are defined to return a generic type.
       this->type is the real type we want to return.  */
    if (e->type->isTypeBasic ())
      exp = d_convert (build_ctype (e->type), exp);

    /* If this call was found to be a constructor for a temporary with a
       cleanup, then move the call inside the TARGET_EXPR.  */
    if (cleanup != NULL_TREE)
      {
	tree init = TARGET_EXPR_INITIAL (cleanup);
	TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
	exp = cleanup;
      }

    this->result_ = exp;
  }

  /* Build a delegate expression.  */

  void visit (DelegateExp *e)
  {
    if (e->func->semanticRun == PASSsemantic3done)
      {
	/* Add the function as nested function if it belongs to this module.
	   ie: it is a member of this module, or it is a template instance.  */
	Dsymbol *owner = e->func->toParent ();
	while (!owner->isTemplateInstance () && owner->toParent ())
	  owner = owner->toParent ();
	if (owner->isTemplateInstance () || owner == d_function_chain->module)
	  build_decl_tree (e->func);
      }

    tree fndecl;
    tree object;

    if (e->func->isNested ())
      {
	if (e->e1->op == TOKnull)
	  object = build_expr (e->e1);
	else
	  object = get_frame_for_symbol (e->func);

	fndecl = build_address (get_symbol_decl (e->func));
      }
    else
      {
	if (!e->func->isThis ())
	  {
	    error ("delegates are only for non-static functions");
	    this->result_ = error_mark_node;
	    return;
	  }

	object = build_expr (e->e1);

	/* Want reference to `this' object.  */
	if (e->e1->type->ty != Tclass && e->e1->type->ty != Tpointer)
	  object = build_address (object);

	/* Object reference could be the outer `this' field of a class or
	   closure of type `void*'.  Cast it to the right type.  */
	if (e->e1->type->ty == Tclass)
	  object = d_convert (build_ctype (e->e1->type), object);

	fndecl = get_symbol_decl (e->func);

	/* Get pointer to function out of the virtual table.  */
	if (e->func->isVirtual () && !e->func->isFinalFunc ()
	    && e->e1->op != TOKsuper && e->e1->op != TOKdottype)
	  {
	    tree fntype = build_pointer_type (TREE_TYPE (fndecl));
	    object = d_save_expr (object);
	    fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
	  }
	else
	  fndecl = build_address (fndecl);
      }

    this->result_ = build_method_call (fndecl, object, e->type);
  }

  /* Build a type component expression.  */

  void visit (DotTypeExp *e)
  {
    /* Just a pass through to underlying expression.  */
    this->result_ = build_expr (e->e1);
  }

  /* Build a component reference expression.  */

  void visit (DotVarExp *e)
  {
    VarDeclaration *vd = e->var->isVarDeclaration ();

    /* This could also be a function, but relying on that being taken
       care of by the visitor interface for CallExp.  */
    if (vd != NULL)
      {
	if (!vd->isField ())
	  this->result_ = get_decl_tree (vd);
	else
	  {
	    tree object = build_expr (e->e1);

	    if (e->e1->type->toBasetype ()->ty != Tstruct)
	      object = build_deref (object);

	    this->result_ = component_ref (object, get_symbol_decl (vd));
	  }
      }
    else
      {
	error ("%qs is not a field, but a %qs",
	       e->var->toChars (), e->var->kind ());
	this->result_ = error_mark_node;
      }
  }

  /* Build an assert expression, used to declare conditions that must hold at
     that a given point in the program.  */

  void visit (AssertExp *e)
  {
    Type *tb1 = e->e1->type->toBasetype ();
    tree arg = build_expr (e->e1);
    tree tmsg = NULL_TREE;
    tree assert_pass = void_node;
    tree assert_fail;

    if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ())
      {
	/* Generate: ((bool) e1  ? (void)0 : _d_assert (...))
		 or: (e1 != null ? e1._invariant() : _d_assert (...))  */
	bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
	libcall_fn libcall;

	if (e->msg)
	  {
	    tmsg = build_expr_dtor (e->msg);
	    libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
	  }
	else
	  libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP;

	/* Build a call to _d_assert().  */
	assert_fail = build_assert_call (e->loc, libcall, tmsg);

	if (global.params.useInvariants == CHECKENABLEon)
	  {
	    /* If the condition is a D class or struct object with an invariant,
	       call it if the condition result is true.  */
	    if (tb1->ty == Tclass)
	      {
		ClassDeclaration *cd = tb1->isClassHandle ();
		if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
		  {
		    arg = d_save_expr (arg);
		    assert_pass = build_libcall (LIBCALL_INVARIANT,
						 Type::tvoid, 1, arg);
		  }
	      }
	    else if (tb1->ty == Tpointer && tb1->nextOf ()->ty == Tstruct)
	      {
		StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
		if (sd->inv != NULL)
		  {
		    Expressions args;
		    arg = d_save_expr (arg);
		    assert_pass = d_build_call_expr (sd->inv, arg, &args);
		  }
	      }
	  }
      }
    else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
      {
	/* Generate: __builtin_trap()  */
	tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
	assert_fail = build_call_expr (fn, 0);
      }
    else
      {
	/* Assert contracts are turned off.  */
	this->result_ = void_node;
	return;
      }

    /* Build condition that we are asserting in this contract.  */
    tree condition = convert_for_condition (arg, e->e1->type);

    /* We expect the condition to always be true, as what happens if an assert
       contract is false is undefined behavior.  */
    tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
    tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
    tree pred_type = TREE_VALUE (arg_types);
    tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));

    condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
				 build_int_cst (expected_type, 1));
    condition = d_truthvalue_conversion (condition);

    this->result_ = build_vcondition (condition, assert_pass, assert_fail);
  }

  /* Build a declaration expression.  */

  void visit (DeclarationExp *e)
  {
    /* Compile the declaration.  */
    push_stmt_list ();
    build_decl_tree (e->declaration);
    tree result = pop_stmt_list ();

    /* Construction of an array for typesafe-variadic function arguments
       can cause an empty STMT_LIST here.  This can causes problems
       during gimplification.  */
    if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
      result = build_empty_stmt (input_location);

    this->result_ = result;
  }

  /* Build a typeid expression.  Returns an instance of class TypeInfo
     corresponding to.  */

  void visit (TypeidExp *e)
  {
    if (Type *tid = isType (e->obj))
      {
	tree ti = build_typeinfo (e->loc, tid);

	/* If the typeinfo is at an offset.  */
	if (tid->vtinfo->offset)
	  ti = build_offset (ti, size_int (tid->vtinfo->offset));

	this->result_ = build_nop (build_ctype (e->type), ti);
      }
    else if (Expression *tid = isExpression (e->obj))
      {
	Type *type = tid->type->toBasetype ();
	assert (type->ty == Tclass);

	/* Generate **classptr to get the classinfo.  */
	tree ci = build_expr (tid);
	ci = indirect_ref (ptr_type_node, ci);
	ci = indirect_ref (ptr_type_node, ci);

	/* Add extra indirection for interfaces.  */
	if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
	  ci = indirect_ref (ptr_type_node, ci);

	this->result_ = build_nop (build_ctype (e->type), ci);
      }
    else
      gcc_unreachable ();
  }

  /* Build a function/lambda expression.  */

  void visit (FuncExp *e)
  {
    Type *ftype = e->type->toBasetype ();

    /* This check is for lambda's, remove `vthis' as function isn't nested.  */
    if (e->fd->tok == TOKreserved && ftype->ty == Tpointer)
      {
	e->fd->tok = TOKfunction;
	e->fd->vthis = NULL;
      }

    /* Compile the function literal body.  */
    build_decl_tree (e->fd);

    /* If nested, this will be a trampoline.  */
    if (e->fd->isNested ())
      {
	tree func = build_address (get_symbol_decl (e->fd));
	tree object;

	if (this->constp_)
	  {
	    /* Static delegate variables have no context pointer.  */
	    object = null_pointer_node;
	    this->result_ = build_method_call (func, object, e->fd->type);
	    TREE_CONSTANT (this->result_) = 1;
	  }
	else
	  {
	    object = get_frame_for_symbol (e->fd);
	    this->result_ = build_method_call (func, object, e->fd->type);
	  }
      }
    else
      {
	this->result_ = build_nop (build_ctype (e->type),
				   build_address (get_symbol_decl (e->fd)));
      }
  }

  /* Build a halt expression.  */

  void visit (HaltExp *)
  {
    /* Should we use trap() or abort()?  */
    tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
    this->result_ = build_call_expr (ttrap, 0);
  }

  /* Build a symbol pointer offset expression.  */

  void visit (SymOffExp *e)
  {
    /* Build the address and offset of the symbol.  */
    size_t soffset = e->isSymOffExp ()->offset;
    tree result = get_decl_tree (e->var);
    TREE_USED (result) = 1;

    if (declaration_reference_p (e->var))
      gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
    else
      result = build_address (result);

    if (!soffset)
      result = d_convert (build_ctype (e->type), result);
    else
      {
	tree offset = size_int (soffset);
	result = build_nop (build_ctype (e->type),
			    build_offset (result, offset));
      }

    this->result_ = result;
  }

  /* Build a variable expression.  */

  void visit (VarExp *e)
  {
    if (e->var->needThis ())
      {
	error ("need %<this%> to access member %qs", e->var->ident->toChars ());
	this->result_ = error_mark_node;
	return;
      }
    else if (e->var->ident == Identifier::idPool ("__ctfe"))
      {
	/* __ctfe is always false at run-time.  */
	this->result_ = integer_zero_node;
	return;
      }

    /* This check is same as is done in FuncExp for lambdas.  */
    FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
    if (fld != NULL)
      {
	if (fld->tok == TOKreserved)
	  {
	    fld->tok = TOKfunction;
	    fld->vthis = NULL;
	  }

	/* Compiler the function literal body.  */
	build_decl_tree (fld);
      }

    if (this->constp_)
      {
	/* Want the initializer, not the expression.  */
	VarDeclaration *var = e->var->isVarDeclaration ();
	SymbolDeclaration *sd = e->var->isSymbolDeclaration ();
	tree init = NULL_TREE;

	if (var && (var->isConst () || var->isImmutable ())
	    && e->type->toBasetype ()->ty != Tsarray && var->_init)
	  {
	    if (var->inuse)
	      error_at (make_location_t (e->loc), "recursive reference %qs",
			e->toChars ());
	    else
	      {
		var->inuse++;
		init = build_expr (initializerToExpression (var->_init), true);
		var->inuse--;
	      }
	  }
	else if (sd && sd->dsym)
	  init = layout_struct_initializer (sd->dsym);
	else
	  error_at (make_location_t (e->loc), "non-constant expression %qs",
		    e->toChars ());

	if (init != NULL_TREE)
	  this->result_ = init;
	else
	  this->result_ = error_mark_node;
      }
    else
      {
	tree result = get_decl_tree (e->var);
	TREE_USED (result) = 1;

	/* For variables that are references - currently only out/inout
	   arguments; objects don't count - evaluating the variable means
	   we want what it refers to.  */
	if (declaration_reference_p (e->var))
	  result = indirect_ref (build_ctype (e->var->type), result);

	this->result_ = result;
      }
  }

  /* Build a this variable expression.  */

  void visit (ThisExp *e)
  {
    FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
    tree result = NULL_TREE;

    if (e->var)
      result = get_decl_tree (e->var);
    else
      {
	gcc_assert (fd && fd->vthis);
	result = get_decl_tree (fd->vthis);
      }

    if (e->type->ty == Tstruct)
      result = build_deref (result);

    this->result_ = result;
  }

  /* Build a new expression, which allocates memory either on the garbage
     collected heap or by using a class or struct specific allocator.  */

  void visit (NewExp *e)
  {
    Type *tb = e->type->toBasetype ();
    tree result;

    if (e->allocator)
      gcc_assert (e->newargs);

    if (tb->ty == Tclass)
      {
	/* Allocating a new class.  */
	tb = e->newtype->toBasetype ();

	ClassDeclaration *cd = tb->isTypeClass ()->sym;
	tree type = build_ctype (tb);
	tree setup_exp = NULL_TREE;
	tree new_call;

	if (e->onstack)
	  {
	    /* If being used as an initializer for a local variable with scope
	       storage class, then the instance is allocated on the stack
	       rather than the heap or using the class specific allocator.  */
	    tree var = build_local_temp (TREE_TYPE (type));
	    new_call = build_nop (type, build_address (var));
	    setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
	  }
	else if (e->allocator)
	  {
	    /* Call class allocator, and copy the initializer into memory.  */
	    new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
	    new_call = d_save_expr (new_call);
	    new_call = build_nop (type, new_call);
	    setup_exp = modify_expr (build_deref (new_call),
				     aggregate_initializer_decl (cd));
	  }
	else
	  {
	    /* Generate: _d_newclass()  */
	    tree arg = build_address (get_classinfo_decl (cd));
	    new_call = build_libcall (LIBCALL_NEWCLASS, tb, 1, arg);
	  }

	/* Set the context pointer for nested classes.  */
	if (cd->isNested ())
	  {
	    tree field = get_symbol_decl (cd->vthis);
	    tree value = NULL_TREE;

	    if (e->thisexp)
	      {
		ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
		Dsymbol *outer = cd->toParent2 ();
		int offset = 0;

		value = build_expr (e->thisexp);
		if (outer != tcd)
		  {
		    ClassDeclaration *ocd = outer->isClassDeclaration ();
		    gcc_assert (ocd->isBaseOf (tcd, &offset));
		    /* Could just add offset...  */
		    value = convert_expr (value, e->thisexp->type, ocd->type);
		  }
	      }
	    else
	      value = build_vthis (cd);

	    if (value != NULL_TREE)
	      {
		/* Generate: (new())->vthis = this;  */
		new_call = d_save_expr (new_call);
		field = component_ref (build_deref (new_call), field);
		setup_exp = compound_expr (setup_exp,
					   modify_expr (field, value));
	      }
	  }
	new_call = compound_expr (setup_exp, new_call);

	/* Call the class constructor.  */
	if (e->member)
	  result = d_build_call_expr (e->member, new_call, e->arguments);
	else
	  result = new_call;

	if (e->argprefix)
	  result = compound_expr (build_expr (e->argprefix), result);
      }
    else if (tb->ty == Tpointer && tb->nextOf ()->toBasetype ()->ty == Tstruct)
      {
	/* Allocating memory for a new struct.  */
	Type *htype = e->newtype->toBasetype ();
	gcc_assert (!e->onstack);

	TypeStruct *stype = htype->isTypeStruct ();
	StructDeclaration *sd = stype->sym;
	tree new_call;

	/* Cannot new an opaque struct.  */
	if (sd->size (e->loc) == 0)
	  {
	    this->result_ = d_convert (build_ctype (e->type),
				       integer_zero_node);
	    return;
	  }

	if (e->allocator)
	  {
	    /* Call struct allocator.  */
	    new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
	    new_call = build_nop (build_ctype (tb), new_call);
	  }
	else
	  {
	    /* Generate: _d_newitemT()  */
	    libcall_fn libcall = htype->isZeroInit ()
	      ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
	    tree arg = build_typeinfo (e->loc, e->newtype);
	    new_call = build_libcall (libcall, tb, 1, arg);
	  }

	if (e->member || !e->arguments)
	  {
	    /* Set the context pointer for nested structs.  */
	    if (sd->isNested ())
	      {
		tree value = build_vthis (sd);
		tree field = get_symbol_decl (sd->vthis);
		tree type = build_ctype (stype);

		new_call = d_save_expr (new_call);
		field = component_ref (indirect_ref (type, new_call), field);
		new_call = compound_expr (modify_expr (field, value), new_call);
	      }

	    /* Call the struct constructor.  */
	    if (e->member)
	      result = d_build_call_expr (e->member, new_call, e->arguments);
	    else
	      result = new_call;
	  }
	else
	  {
	    /* If we have a user supplied initializer, then set-up with a
	       struct literal.  */
	    if (e->arguments != NULL && sd->fields.length != 0)
	      {
		StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
								 e->arguments,
								 htype);
		new_call = d_save_expr (new_call);
		se->type = sd->type;
		se->sym = new_call;
		result = compound_expr (build_expr (se), new_call);
	      }
	    else
	      result = new_call;
	  }

	if (e->argprefix)
	  result = compound_expr (build_expr (e->argprefix), result);
      }
    else if (tb->ty == Tarray)
      {
	/* Allocating memory for a new D array.  */
	tb = e->newtype->toBasetype ();
	TypeDArray *tarray = tb->isTypeDArray ();

	gcc_assert (!e->allocator);
	gcc_assert (e->arguments && e->arguments->length >= 1);

	if (e->arguments->length == 1)
	  {
	    /* Single dimension array allocations.  */
	    Expression *arg = (*e->arguments)[0];

	    if (tarray->next->size () == 0)
	      {
		/* Array element size is unknown.  */
		this->result_ = d_array_value (build_ctype (e->type),
					       size_int (0), null_pointer_node);
		return;
	      }

	    libcall_fn libcall = tarray->next->isZeroInit ()
	      ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
	    result = build_libcall (libcall, tb, 2,
				    build_typeinfo (e->loc, e->type),
				    build_expr (arg));
	  }
	else
	  {
	    /* Multidimensional array allocations.  */
	    tree tarray = make_array_type (Type::tsize_t, e->arguments->length);
	    tree var = build_local_temp (tarray);
	    vec <constructor_elt, va_gc> *elms = NULL;

	    /* Get the base element type for the array, generating the
	       initializer for the dims parameter along the way.  */
	    Type *telem = e->newtype->toBasetype ();
	    for (size_t i = 0; i < e->arguments->length; i++)
	      {
		Expression *arg = (*e->arguments)[i];
		CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));

		gcc_assert (telem->ty == Tarray);
		telem = telem->toBasetype ()->nextOf ();
		gcc_assert (telem);
	      }

	    /* Initialize the temporary.  */
	    tree init = modify_expr (var, build_constructor (tarray, elms));
	    var = compound_expr (init, var);

	    /* Generate: _d_newarraymTX(ti, dims)
		     or: _d_newarraymiTX(ti, dims)  */
	    libcall_fn libcall = telem->isZeroInit ()
	      ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;

	    tree tinfo = build_typeinfo (e->loc, e->type);
	    tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
				       size_int (e->arguments->length),
				       build_address (var));

	    result = build_libcall (libcall, tb, 2, tinfo, dims);
	  }

	if (e->argprefix)
	  result = compound_expr (build_expr (e->argprefix), result);
      }
    else if (tb->ty == Tpointer)
      {
	/* Allocating memory for a new pointer.  */
	TypePointer *tpointer = tb->isTypePointer ();

	if (tpointer->next->size () == 0)
	  {
	    /* Pointer element size is unknown.  */
	    this->result_ = d_convert (build_ctype (e->type),
				       integer_zero_node);
	    return;
	  }

	libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
	  ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;

	tree arg = build_typeinfo (e->loc, e->newtype);
	result = build_libcall (libcall, tb, 1, arg);

	if (e->arguments && e->arguments->length == 1)
	  {
	    result = d_save_expr (result);
	    tree init = modify_expr (build_deref (result),
				     build_expr ((*e->arguments)[0]));
	    result = compound_expr (init, result);
	  }

	if (e->argprefix)
	  result = compound_expr (build_expr (e->argprefix), result);
      }
    else
      gcc_unreachable ();

    this->result_ = convert_expr (result, tb, e->type);
  }

  /* Build an integer literal.  */

  void visit (IntegerExp *e)
  {
    tree ctype = build_ctype (e->type->toBasetype ());
    this->result_ = build_integer_cst (e->value, ctype);
  }

  /* Build a floating-point literal.  */

  void visit (RealExp *e)
  {
    this->result_ = build_float_cst (e->value, e->type->toBasetype ());
  }

  /* Build a complex literal.  */

  void visit (ComplexExp *e)
  {
    Type *tnext;

    switch (e->type->toBasetype ()->ty)
      {
      case Tcomplex32:
	tnext = (TypeBasic *) Type::tfloat32;
	break;

      case Tcomplex64:
	tnext = (TypeBasic *) Type::tfloat64;
	break;

      case Tcomplex80:
	tnext = (TypeBasic *) Type::tfloat80;
	break;

      default:
	gcc_unreachable ();
      }

    this->result_ = build_complex (build_ctype (e->type),
				   build_float_cst (creall (e->value), tnext),
				   build_float_cst (cimagl (e->value), tnext));
  }

  /* Build a string literal, all strings are null terminated except for
     static arrays.  */

  void visit (StringExp *e)
  {
    Type *tb = e->type->toBasetype ();
    tree type = build_ctype (e->type);

    if (tb->ty == Tsarray)
      {
	/* Turn the string into a constructor for the static array.  */
	vec <constructor_elt, va_gc> *elms = NULL;
	vec_safe_reserve (elms, e->len);
	tree etype = TREE_TYPE (type);

	for (size_t i = 0; i < e->len; i++)
	  {
	    tree value = build_integer_cst (e->charAt (i), etype);
	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
	  }

	tree ctor = build_constructor (type, elms);
	TREE_CONSTANT (ctor) = 1;
	this->result_ = ctor;
      }
    else
      {
	/* Copy the string contents to a null terminated string.  */
	dinteger_t length = (e->len * e->sz);
	char *string = XALLOCAVEC (char, length + 1);
	memcpy (string, e->string, length);
	string[length] = '\0';

	/* String value and type includes the null terminator.  */
	tree value = build_string (length, string);
	TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
	value = build_address (value);

	if (tb->ty == Tarray)
	  value = d_array_value (type, size_int (e->len), value);

	TREE_CONSTANT (value) = 1;
	this->result_ = d_convert (type, value);
      }
  }

  /* Build a tuple literal.  Just an argument list that may have
     side effects that need evaluation.  */

  void visit (TupleExp *e)
  {
    tree result = NULL_TREE;

    if (e->e0)
      result = build_expr (e->e0, this->constp_, true);

    for (size_t i = 0; i < e->exps->length; ++i)
      {
	Expression *exp = (*e->exps)[i];
	result = compound_expr (result, build_expr (exp, this->constp_, true));
      }

    if (result == NULL_TREE)
      result = void_node;

    this->result_ = result;
  }

  /* Build an array literal.  The common type of the all elements is taken to
     be the type of the array element, and all elements are implicitly
     converted to that type.  */

  void visit (ArrayLiteralExp *e)
  {
    Type *tb = e->type->toBasetype ();

    /* Implicitly convert void[n] to ubyte[n].  */
    if (tb->ty == Tsarray && tb->nextOf ()->toBasetype ()->ty == Tvoid)
      tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());

    gcc_assert (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tpointer);

    /* Handle empty array literals.  */
    if (e->elements->length == 0)
      {
	if (tb->ty == Tarray)
	  this->result_ = d_array_value (build_ctype (e->type),
					 size_int (0), null_pointer_node);
	else
	  this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
					     NULL);

	return;
      }

    /* Build an expression that assigns the expressions in ELEMENTS to
       a constructor.  */
    vec <constructor_elt, va_gc> *elms = NULL;
    vec_safe_reserve (elms, e->elements->length);
    bool constant_p = true;
    tree saved_elems = NULL_TREE;

    Type *etype = tb->nextOf ();
    tree satype = make_array_type (etype, e->elements->length);

    for (size_t i = 0; i < e->elements->length; i++)
      {
	Expression *expr = e->getElement (i);
	tree value = build_expr (expr, this->constp_, true);

	/* Only append nonzero values, the backend will zero out the rest
	   of the constructor as we don't set CONSTRUCTOR_NO_CLEARING.  */
	if (!initializer_zerop (value))
	  {
	    if (!TREE_CONSTANT (value))
	      constant_p = false;

	    /* Split construction of values out of the constructor if there
	       may be side effects.  */
	    tree init = stabilize_expr (&value);
	    if (init != NULL_TREE)
	      saved_elems = compound_expr (saved_elems, init);

	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
				    convert_expr (value, expr->type, etype));
	  }
      }

    /* Now return the constructor as the correct type.  For static arrays there
       is nothing else to do.  For dynamic arrays, return a two field struct.
       For pointers, return the address.  */
    tree ctor = build_constructor (satype, elms);
    tree type = build_ctype (e->type);

    /* Nothing else to do for static arrays.  */
    if (tb->ty == Tsarray || this->constp_)
      {
	/* Can't take the address of the constructor, so create an anonymous
	   static symbol, and then refer to it.  */
	if (tb->ty != Tsarray)
	  {
	    tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
	    ctor = build_address (decl);
	    if (tb->ty == Tarray)
	      ctor = d_array_value (type, size_int (e->elements->length), ctor);

	    d_pushdecl (decl);
	    rest_of_decl_compilation (decl, 1, 0);
	  }

	/* If the array literal is readonly or static.  */
	if (constant_p)
	  TREE_CONSTANT (ctor) = 1;
	if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
	  TREE_STATIC (ctor) = 1;

	/* Use memset to fill any alignment holes in the array.  */
	if (!this->constp_ && !this->literalp_)
	  {
	    TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();

	    if (ts != NULL && (!identity_compare_p (ts->sym)
			       || ts->sym->isUnionDeclaration ()))
	      {
		tree var = build_local_temp (TREE_TYPE (ctor));
		tree init = build_memset_call (var);
		/* Evaluate memset() first, then any saved elements.  */
		saved_elems = compound_expr (init, saved_elems);
		ctor = compound_expr (modify_expr (var, ctor), var);
	      }
	  }

	this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
      }
    else
      {
	/* Allocate space on the memory managed heap.  */
	tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
				  etype->pointerTo (), 2,
				  build_typeinfo (e->loc, etype->arrayOf ()),
				  size_int (e->elements->length));
	mem = d_save_expr (mem);

	/* Now copy the constructor into memory.  */
	tree size = size_mult_expr (size_int (e->elements->length),
				    size_int (tb->nextOf ()->size ()));

	tree result = build_memcpy_call (mem, build_address (ctor), size);

	/* Return the array pointed to by MEM.  */
	result = compound_expr (result, mem);

	if (tb->ty == Tarray)
	  result = d_array_value (type, size_int (e->elements->length), result);

	this->result_ = compound_expr (saved_elems, result);
      }
  }

  /* Build an associative array literal.  The common type of the all keys is
     taken to be the key type, and common type of all values the value type.
     All keys and values are then implicitly converted as needed.  */

  void visit (AssocArrayLiteralExp *e)
  {
    /* Want the mutable type for typeinfo reference.  */
    Type *tb = e->type->toBasetype ()->mutableOf ();

    /* Handle empty assoc array literals.  */
    TypeAArray *ta = tb->isTypeAArray ();
    if (e->keys->length == 0)
      {
	this->result_ = build_constructor (build_ctype (ta), NULL);
	return;
      }

    /* Build an expression that assigns all expressions in KEYS
       to a constructor.  */
    tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
					 e->keys, this->constp_);
    tree init = stabilize_expr (&akeys);

    /* Do the same with all expressions in VALUES.  */
    tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
					 e->values, this->constp_);
    init = compound_expr (init, stabilize_expr (&avals));

    /* Generate: _d_assocarrayliteralTX (ti, keys, vals);  */
    tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
			       size_int (e->keys->length),
			       build_address (akeys));
    tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
			       size_int (e->values->length),
			       build_address (avals));

    tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
			      build_typeinfo (e->loc, ta), keys, vals);

    /* Return an associative array pointed to by MEM.  */
    tree aatype = build_ctype (ta);
    vec <constructor_elt, va_gc> *ce = NULL;
    CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);

    tree result = build_nop (build_ctype (e->type),
			     build_constructor (aatype, ce));
    this->result_ = compound_expr (init, result);
  }

  /* Build a struct literal.  */

  void visit (StructLiteralExp *e)
  {
    /* Handle empty struct literals.  */
    if (e->elements == NULL || e->sd->fields.length == 0)
      {
	this->result_ = build_constructor (build_ctype (e->type), NULL);
	return;
      }

    /* Building sinit trees are delayed until after frontend semantic
       processing has complete.  Build the static initializer now.  */
    if (e->useStaticInit && !this->constp_)
      {
	tree init = aggregate_initializer_decl (e->sd);

	/* If initializing a symbol, don't forget to set it.  */
	if (e->sym != NULL)
	  {
	    tree var = build_deref (e->sym);
	    init = compound_expr (modify_expr (var, init), var);
	  }

	this->result_ = init;
	return;
      }

    /* Build a constructor that assigns the expressions in ELEMENTS
       at each field index that has been filled in.  */
    vec <constructor_elt, va_gc> *ve = NULL;
    tree saved_elems = NULL_TREE;

    /* CTFE may fill the hidden pointer by NullExp.  */
    gcc_assert (e->elements->length <= e->sd->fields.length);

    Type *tb = e->type->toBasetype ();
    gcc_assert (tb->ty == Tstruct);

    for (size_t i = 0; i < e->elements->length; i++)
      {
	Expression *exp = (*e->elements)[i];
	if (!exp)
	  continue;

	VarDeclaration *field = e->sd->fields[i];
	Type *type = exp->type->toBasetype ();
	Type *ftype = field->type->toBasetype ();
	tree value = NULL_TREE;

	if (ftype->ty == Tsarray && !same_type_p (type, ftype))
	  {
	    /* Initialize a static array with a single element.  */
	    tree elem = build_expr (exp, this->constp_, true);
	    saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
	    elem = d_save_expr (elem);

	    if (initializer_zerop (elem))
	      value = build_constructor (build_ctype (ftype), NULL);
	    else
	      value = build_array_from_val (ftype, elem);
	  }
	else
	  {
	    value = convert_expr (build_expr (exp, this->constp_, true),
				  exp->type, field->type);
	  }

	/* Split construction of values out of the constructor.  */
	saved_elems = compound_expr (saved_elems, stabilize_expr (&value));

	CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
      }

    /* Maybe setup hidden pointer to outer scope context.  */
    if (e->sd->isNested () && e->elements->length != e->sd->fields.length
	&& this->constp_ == false)
      {
	tree field = get_symbol_decl (e->sd->vthis);
	tree value = build_vthis (e->sd);
	CONSTRUCTOR_APPEND_ELT (ve, field, value);
	gcc_assert (e->useStaticInit == false);
      }

    /* Build a constructor in the correct shape of the aggregate type.  */
    tree ctor = build_struct_literal (build_ctype (e->type), ve);

    /* Nothing more to do for constant literals.  */
    if (this->constp_)
      {
	/* If the struct literal is a valid for static data.  */
	if (TREE_CONSTANT (ctor)
	    && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
	  TREE_STATIC (ctor) = 1;

	this->result_ = compound_expr (saved_elems, ctor);
	return;
      }

    /* Construct the struct literal for run-time.  */
    if (e->sym != NULL)
      {
	/* Store the result in a symbol to initialize the literal.  */
	tree var = build_deref (e->sym);
	ctor = compound_expr (modify_expr (var, ctor), var);
      }
    else if (!this->literalp_)
      {
	/* Use memset to fill any alignment holes in the object.  */
	if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
	  {
	    tree var = build_local_temp (TREE_TYPE (ctor));
	    tree init = build_memset_call (var);
	    /* Evaluate memset() first, then any saved element constructors.  */
	    saved_elems = compound_expr (init, saved_elems);
	    ctor = compound_expr (modify_expr (var, ctor), var);
	  }
      }

    this->result_ = compound_expr (saved_elems, ctor);
  }

  /* Build a null literal.  */

  void visit (NullExp *e)
  {
    this->result_ = build_typeof_null_value (e->type);
  }

  /* Build a vector literal.  */

  void visit (VectorExp *e)
  {
    tree type = build_ctype (e->type);

    /* First handle array literal expressions.  */
    if (e->e1->op == TOKarrayliteral)
      {
	ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
	vec <constructor_elt, va_gc> *elms = NULL;
	bool constant_p = true;

	vec_safe_reserve (elms, ale->elements->length);
	for (size_t i = 0; i < ale->elements->length; i++)
	  {
	    Expression *expr = ale->getElement (i);
	    tree value = d_convert (TREE_TYPE (type),
				    build_expr (expr, this->constp_, true));
	    if (!CONSTANT_CLASS_P (value))
	      constant_p = false;

	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
	  }

	/* Build a VECTOR_CST from a constant vector constructor.  */
	if (constant_p)
	  this->result_ = build_vector_from_ctor (type, elms);
	else
	  this->result_ = build_constructor (type, elms);
      }
    else
      {
	/* Build constructor from single value.  */
	tree value = d_convert (TREE_TYPE (type),
				build_expr (e->e1, this->constp_, true));
	this->result_ = build_vector_from_val (type, value);
      }
  }

  /* Build a static array representation of a vector expression.  */

  void visit (VectorArrayExp *e)
  {
    this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
				  e->e1->type, e->type);
  }

  /* Build a static class literal, return its reference.  */

  void visit (ClassReferenceExp *e)
  {
    /* The result of build_new_class_expr is a RECORD_TYPE, we want
       the reference.  */
    tree var = build_address (build_new_class_expr (e));

    /* If the type of this literal is an interface, the we must add the
       interface offset to symbol.  */
    if (this->constp_)
      {
	TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
	InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();

	if (to != NULL)
	  {
	    ClassDeclaration *from = e->originalClass ();
	    int offset = 0;

	    gcc_assert (to->isBaseOf (from, &offset) != 0);

	    if (offset != 0)
	      var = build_offset (var, size_int (offset));
	  }
      }

    this->result_ = var;
  }

  /* These expressions are mainly just a placeholders in the frontend.
     We shouldn't see them here.  */

  void visit (ScopeExp *e)
  {
    error_at (make_location_t (e->loc), "%qs is not an expression",
	      e->toChars ());
    this->result_ = error_mark_node;
  }

  void visit (TypeExp *e)
  {
    error_at (make_location_t (e->loc), "type %qs is not an expression",
	      e->toChars ());
    this->result_ = error_mark_node;
  }
};


/* Main entry point for ExprVisitor interface to generate code for
   the Expression AST class E.  If CONST_P is true, then E is a
   constant expression.  If LITERAL_P is true, then E is a value used
   in the initialization of another literal.  */

tree
build_expr (Expression *e, bool const_p, bool literal_p)
{
  ExprVisitor v = ExprVisitor (const_p, literal_p);
  location_t saved_location = input_location;

  input_location = make_location_t (e->loc);
  e->accept (&v);
  tree expr = v.result ();
  input_location = saved_location;

  /* Check if initializer expression is valid constant.  */
  if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
    {
      error_at (make_location_t (e->loc), "non-constant expression %qs",
		e->toChars ());
      return error_mark_node;
    }

  return expr;
}

/* Same as build_expr, but also calls destructors on any temporaries.  */

tree
build_expr_dtor (Expression *e)
{
  /* Codegen can be improved by determining if no exceptions can be thrown
     between the ctor and dtor, and eliminating the ctor and dtor.  */
  size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
  tree result = build_expr (e);

  if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
    {
      result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
      vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
    }

  return result;
}

/* Same as build_expr_dtor, but handles the result of E as a return value.  */

tree
build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
{
  size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
  tree result = build_expr (e);

  /* Convert for initializing the DECL_RESULT.  */
  if (tf->isref)
    {
      /* If we are returning a reference, take the address.  */
      result = convert_expr (result, e->type, type);
      result = build_address (result);
    }
  else
    result = convert_for_rvalue (result, e->type, type);

  /* The decl to store the return expression.  */
  tree decl = DECL_RESULT (cfun->decl);

  /* Split comma expressions, so that the result is returned directly.  */
  tree expr = stabilize_expr (&result);
  result = build_assign (INIT_EXPR, decl, result);
  result = compound_expr (expr, return_expr (result));

  /* May nest the return expression inside the try/finally expression.  */
  if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
    {
      result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
      vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
    }

  return result;
}

