Home | History | Annotate | Line # | Download | only in d
      1 /* expr.cc -- Lower D frontend expressions to GCC trees.
      2    Copyright (C) 2015-2022 Free Software Foundation, Inc.
      3 
      4 GCC is free software; you can redistribute it and/or modify
      5 it under the terms of the GNU General Public License as published by
      6 the Free Software Foundation; either version 3, or (at your option)
      7 any later version.
      8 
      9 GCC is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 GNU General Public License for more details.
     13 
     14 You should have received a copy of the GNU General Public License
     15 along with GCC; see the file COPYING3.  If not see
     16 <http://www.gnu.org/licenses/>.  */
     17 
     18 #include "config.h"
     19 #include "system.h"
     20 #include "coretypes.h"
     21 
     22 #include "dmd/aggregate.h"
     23 #include "dmd/ctfe.h"
     24 #include "dmd/declaration.h"
     25 #include "dmd/enum.h"
     26 #include "dmd/expression.h"
     27 #include "dmd/identifier.h"
     28 #include "dmd/init.h"
     29 #include "dmd/module.h"
     30 #include "dmd/mtype.h"
     31 #include "dmd/template.h"
     32 
     33 #include "tree.h"
     34 #include "fold-const.h"
     35 #include "diagnostic.h"
     36 #include "langhooks.h"
     37 #include "tm.h"
     38 #include "function.h"
     39 #include "toplev.h"
     40 #include "varasm.h"
     41 #include "predict.h"
     42 #include "stor-layout.h"
     43 
     44 #include "d-tree.h"
     45 
     46 
     47 /* Determine if type T is a struct that has a postblit.  */
     48 
     49 static bool
     50 needs_postblit (Type *t)
     51 {
     52   t = t->baseElemOf ();
     53 
     54   if (TypeStruct *ts = t->isTypeStruct ())
     55     {
     56       if (ts->sym->postblit)
     57 	return true;
     58     }
     59 
     60   return false;
     61 }
     62 
     63 /* Determine if type T is a struct that has a destructor.  */
     64 
     65 static bool
     66 needs_dtor (Type *t)
     67 {
     68   t = t->baseElemOf ();
     69 
     70   if (TypeStruct *ts = t->isTypeStruct ())
     71     {
     72       if (ts->sym->dtor)
     73 	return true;
     74     }
     75 
     76   return false;
     77 }
     78 
     79 /* Determine if expression E is a suitable lvalue.  */
     80 
     81 static bool
     82 lvalue_p (Expression *e)
     83 {
     84   SliceExp *se = e->isSliceExp ();
     85   if (se != NULL && se->e1->isLvalue ())
     86     return true;
     87 
     88   CastExp *ce = e->isCastExp ();
     89   if (ce != NULL && ce->e1->isLvalue ())
     90     return true;
     91 
     92   return (e->op != EXP::slice && e->isLvalue ());
     93 }
     94 
     95 /* Build an expression of code CODE, data type TYPE, and operands ARG0 and
     96    ARG1.  Perform relevant conversions needed for correct code operations.  */
     97 
     98 static tree
     99 binary_op (tree_code code, tree type, tree arg0, tree arg1)
    100 {
    101   tree t0 = TREE_TYPE (arg0);
    102   tree t1 = TREE_TYPE (arg1);
    103   tree ret = NULL_TREE;
    104 
    105   /* Deal with float mod expressions immediately.  */
    106   if (code == FLOAT_MOD_EXPR)
    107     return build_float_modulus (type, arg0, arg1);
    108 
    109   if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
    110     return build_nop (type, build_offset_op (code, arg0, arg1));
    111 
    112   if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
    113     return build_nop (type, build_offset_op (code, arg1, arg0));
    114 
    115   if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
    116     {
    117       gcc_assert (code == MINUS_EXPR);
    118       tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
    119 
    120       /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
    121 	 pointers.  If some platform cannot provide that, or has a larger
    122 	 ptrdiff_type to support differences larger than half the address
    123 	 space, cast the pointers to some larger integer type and do the
    124 	 computations in that type.  */
    125       if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
    126 	ret = fold_build2 (MINUS_EXPR, ptrtype,
    127 			   d_convert (ptrtype, arg0),
    128 			   d_convert (ptrtype, arg1));
    129       else
    130 	ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
    131     }
    132   else
    133     {
    134       /* If the operation needs excess precision.  */
    135       tree eptype = excess_precision_type (type);
    136       if (eptype != NULL_TREE)
    137 	{
    138 	  arg0 = d_convert (eptype, arg0);
    139 	  arg1 = d_convert (eptype, arg1);
    140 	}
    141       else
    142 	{
    143 	  /* Front-end does not do this conversion and GCC does not
    144 	     always do it right.  */
    145 	  if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
    146 	    arg1 = d_convert (t0, arg1);
    147 	  else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
    148 	    arg0 = d_convert (t1, arg0);
    149 
    150 	  eptype = type;
    151 	}
    152 
    153       ret = build2 (code, eptype, arg0, arg1);
    154     }
    155 
    156   return d_convert (type, ret);
    157 }
    158 
    159 /* Build a binary expression of code CODE, assigning the result into E1.  */
    160 
    161 static tree
    162 binop_assignment (tree_code code, Expression *e1, Expression *e2)
    163 {
    164   /* Skip casts for lhs assignment.  */
    165   Expression *e1b = e1;
    166   while (e1b->op == EXP::cast_)
    167     {
    168       CastExp *ce = e1b->isCastExp ();
    169       gcc_assert (same_type_p (ce->type, ce->to));
    170       e1b = ce->e1;
    171     }
    172 
    173   /* Stabilize LHS for assignment.  */
    174   tree lhs = build_expr (e1b);
    175   tree lexpr = stabilize_expr (&lhs);
    176 
    177   /* The LHS expression could be an assignment, to which its operation gets
    178      lost during gimplification.  */
    179   if (TREE_CODE (lhs) == MODIFY_EXPR)
    180     {
    181       /* If LHS has side effects, call stabilize_reference on it, so it can
    182 	 be evaluated multiple times.  */
    183       if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
    184 	lhs = build_assign (MODIFY_EXPR,
    185 			    stabilize_reference (TREE_OPERAND (lhs, 0)),
    186 			    TREE_OPERAND (lhs, 1));
    187 
    188       lexpr = compound_expr (lexpr, lhs);
    189       lhs = TREE_OPERAND (lhs, 0);
    190     }
    191 
    192   lhs = stabilize_reference (lhs);
    193 
    194   /* Save RHS, to ensure that the expression is evaluated before LHS.  */
    195   tree rhs = build_expr (e2);
    196   tree rexpr = d_save_expr (rhs);
    197 
    198   rhs = binary_op (code, build_ctype (e1->type),
    199 		   convert_expr (lhs, e1b->type, e1->type), rexpr);
    200   if (TREE_SIDE_EFFECTS (rhs))
    201     rhs = compound_expr (rexpr, rhs);
    202 
    203   tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
    204   return compound_expr (lexpr, expr);
    205 }
    206 
    207 /* Implements the visitor interface to build the GCC trees of all Expression
    208    AST classes emitted from the D Front-end.
    209    All visit methods accept one parameter E, which holds the frontend AST
    210    of the expression to compile.  They also don't return any value, instead
    211    generated code is cached in RESULT_ and returned from the caller.  */
    212 
    213 class ExprVisitor : public Visitor
    214 {
    215   using Visitor::visit;
    216 
    217   tree result_;
    218   bool constp_;
    219   bool literalp_;
    220 
    221 public:
    222   ExprVisitor (bool constp, bool literalp)
    223   {
    224     this->result_ = NULL_TREE;
    225     this->constp_ = constp;
    226     this->literalp_ = literalp;
    227   }
    228 
    229   tree result (void)
    230   {
    231     return this->result_;
    232   }
    233 
    234   /* Visitor interfaces, each Expression class should have
    235      overridden the default.  */
    236 
    237   void visit (Expression *)
    238   {
    239     gcc_unreachable ();
    240   }
    241 
    242   /* Build a conditional expression.  If either the second or third
    243      expression is void, then the resulting type is void.  Otherwise
    244      they are implicitly converted to a common type.  */
    245 
    246   void visit (CondExp *e)
    247   {
    248     tree cond = convert_for_condition (build_expr (e->econd),
    249 				       e->econd->type);
    250     tree t1 = build_expr (e->e1);
    251     tree t2 = build_expr (e->e2);
    252 
    253     if (e->type->ty != TY::Tvoid)
    254       {
    255 	t1 = convert_expr (t1, e->e1->type, e->type);
    256 	t2 = convert_expr (t2, e->e2->type, e->type);
    257       }
    258 
    259     this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
    260   }
    261 
    262   /* Build an identity comparison expression.  Operands go through the
    263      usual conversions to bring them to a common type before comparison.
    264      The result type is bool.  */
    265 
    266   void visit (IdentityExp *e)
    267   {
    268     tree_code code = (e->op == EXP::identity) ? EQ_EXPR : NE_EXPR;
    269     Type *tb1 = e->e1->type->toBasetype ();
    270     Type *tb2 = e->e2->type->toBasetype ();
    271 
    272     if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
    273 	&& (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
    274       {
    275 	/* For static and dynamic arrays, identity is defined as referring to
    276 	   the same array elements and the same number of elements.  */
    277 	tree t1 = d_array_convert (e->e1);
    278 	tree t2 = d_array_convert (e->e2);
    279 	this->result_ = d_convert (build_ctype (e->type),
    280 				   build_boolop (code, t1, t2));
    281       }
    282     else if (tb1->isfloating () && tb1->ty != TY::Tvector)
    283       {
    284 	/* For floating-point values, identity is defined as the bits in the
    285 	   operands being identical.  */
    286 	tree t1 = d_save_expr (build_expr (e->e1));
    287 	tree t2 = d_save_expr (build_expr (e->e2));
    288 
    289 	if (!tb1->iscomplex ())
    290 	  this->result_ = build_float_identity (code, t1, t2);
    291 	else
    292 	  {
    293 	    /* Compare the real and imaginary parts separately.  */
    294 	    tree req = build_float_identity (code, real_part (t1),
    295 					     real_part (t2));
    296 	    tree ieq = build_float_identity (code, imaginary_part (t1),
    297 					     imaginary_part (t2));
    298 
    299 	    if (code == EQ_EXPR)
    300 	      this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
    301 	    else
    302 	      this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
    303 	  }
    304       }
    305     else if (TypeStruct *ts = tb1->isTypeStruct ())
    306       {
    307 	/* For struct objects, identity is defined as bits in operands being
    308 	   identical also.  Alignment holes in structs are ignored.  */
    309 	tree t1 = build_expr (e->e1);
    310 	tree t2 = build_expr (e->e2);
    311 
    312 	gcc_assert (same_type_p (tb1, tb2));
    313 
    314 	this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
    315       }
    316     else
    317       {
    318 	/* For operands of other types, identity is defined as being the
    319 	   same as equality expressions.  */
    320 	tree t1 = build_expr (e->e1);
    321 	tree t2 = build_expr (e->e2);
    322 	this->result_ = d_convert (build_ctype (e->type),
    323 				   build_boolop (code, t1, t2));
    324       }
    325   }
    326 
    327   /* Build an equality expression, which compare the two operands for either
    328      equality or inequality.  Operands go through the usual conversions to bring
    329      them to a common type before comparison.  The result type is bool.  */
    330 
    331   void visit (EqualExp *e)
    332   {
    333     Type *tb1 = e->e1->type->toBasetype ();
    334     Type *tb2 = e->e2->type->toBasetype ();
    335     tree_code code = (e->op == EXP::equal) ? EQ_EXPR : NE_EXPR;
    336 
    337     if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
    338 	&& (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
    339       {
    340 	/* For static and dynamic arrays, equality is defined as the lengths of
    341 	   the arrays matching, and all the elements are equal.  */
    342 	Type *t1elem = tb1->nextOf ()->toBasetype ();
    343 	Type *t2elem = tb1->nextOf ()->toBasetype ();
    344 
    345 	/* Check if comparisons of arrays can be optimized using memcmp.
    346 	   This will inline EQ expressions as:
    347 		e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
    348 	    Or when generating a NE expression:
    349 		e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0;  */
    350 	if ((t1elem->isintegral () || t1elem->ty == TY::Tvoid
    351 	     || (t1elem->ty == TY::Tstruct
    352 		 && !t1elem->isTypeStruct ()->sym->xeq))
    353 	    && t1elem->ty == t2elem->ty)
    354 	  {
    355 	    tree t1 = d_array_convert (e->e1);
    356 	    tree t2 = d_array_convert (e->e2);
    357 	    tree result;
    358 
    359 	    /* Make temporaries to prevent multiple evaluations.  */
    360 	    tree t1saved = d_save_expr (t1);
    361 	    tree t2saved = d_save_expr (t2);
    362 
    363 	    /* Length of arrays, for comparisons done before calling memcmp.  */
    364 	    tree t1len = d_array_length (t1saved);
    365 	    tree t2len = d_array_length (t2saved);
    366 
    367 	    /* Reference to array data.  */
    368 	    tree t1ptr = d_array_ptr (t1saved);
    369 	    tree t2ptr = d_array_ptr (t2saved);
    370 
    371 	    /* Compare arrays using memcmp if possible, otherwise for structs,
    372 	       each field is compared inline.  */
    373 	    if (t1elem->ty != TY::Tstruct
    374 		|| identity_compare_p (t1elem->isTypeStruct ()->sym))
    375 	      {
    376 		tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
    377 
    378 		result = build_memcmp_call (t1ptr, t2ptr, size);
    379 		result = build_boolop (code, result, integer_zero_node);
    380 	      }
    381 	    else
    382 	      {
    383 		StructDeclaration *sd = t1elem->isTypeStruct ()->sym;
    384 
    385 		result = build_array_struct_comparison (code, sd, t1len,
    386 							t1ptr, t2ptr);
    387 	      }
    388 
    389 	    /* Check array length first before passing to memcmp.
    390 	       For equality expressions, this becomes:
    391 		    (e1.length == 0 || memcmp);
    392 	       Otherwise for inequality:
    393 		    (e1.length != 0 && memcmp);  */
    394 	    tree tsizecmp = build_boolop (code, t1len, size_zero_node);
    395 	    if (e->op == EXP::equal)
    396 	      result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
    397 	    else
    398 	      result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
    399 
    400 	    /* Finally, check if lengths of both arrays match if dynamic.
    401 	       The frontend should have already guaranteed that static arrays
    402 	       have same size.  */
    403 	    if (tb1->ty == TY::Tsarray && tb2->ty == TY::Tsarray)
    404 	      gcc_assert (tb1->size () == tb2->size ());
    405 	    else
    406 	      {
    407 		tree tlencmp = build_boolop (code, t1len, t2len);
    408 		if (e->op == EXP::equal)
    409 		  result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
    410 		else
    411 		  result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
    412 	      }
    413 
    414 	    /* Ensure left-to-right order of evaluation.  */
    415 	    if (TREE_SIDE_EFFECTS (t2))
    416 	      result = compound_expr (t2saved, result);
    417 
    418 	    if (TREE_SIDE_EFFECTS (t1))
    419 	      result = compound_expr (t1saved, result);
    420 
    421 	    this->result_ = result;
    422 	  }
    423 	else
    424 	  {
    425 	    /* Use _adEq2() to compare each element.  */
    426 	    Type *t1array = t1elem->arrayOf ();
    427 	    tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
    428 					 d_array_convert (e->e1),
    429 					 d_array_convert (e->e2),
    430 					 build_typeinfo (e, t1array));
    431 
    432 	    if (e->op == EXP::notEqual)
    433 	      result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
    434 
    435 	    this->result_ = result;
    436 	  }
    437       }
    438     else if (TypeStruct *ts = tb1->isTypeStruct ())
    439       {
    440 	/* Equality for struct objects means the logical product of all
    441 	   equality results of the corresponding object fields.  */
    442 	tree t1 = build_expr (e->e1);
    443 	tree t2 = build_expr (e->e2);
    444 
    445 	gcc_assert (same_type_p (tb1, tb2));
    446 
    447 	this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
    448       }
    449     else if (tb1->ty == TY::Taarray && tb2->ty == TY::Taarray)
    450       {
    451 	/* Use _aaEqual() for associative arrays.  */
    452 	tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
    453 				     build_typeinfo (e, tb1),
    454 				     build_expr (e->e1),
    455 				     build_expr (e->e2));
    456 
    457 	if (e->op == EXP::notEqual)
    458 	  result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
    459 
    460 	this->result_ = result;
    461       }
    462     else
    463       {
    464 	/* For operands of other types, equality is defined as the bit pattern
    465 	   of the type matches exactly.  */
    466 	tree t1 = build_expr (e->e1);
    467 	tree t2 = build_expr (e->e2);
    468 
    469 	this->result_ = d_convert (build_ctype (e->type),
    470 				   build_boolop (code, t1, t2));
    471       }
    472   }
    473 
    474   /* Build an `in' expression.  This is a condition to see if an element
    475      exists in an associative array.  The result is a pointer to the
    476      element, or null if false.  */
    477 
    478   void visit (InExp *e)
    479   {
    480     Type *tb2 = e->e2->type->toBasetype ();
    481     Type *tkey = tb2->isTypeAArray ()->index->toBasetype ();
    482     tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
    483 
    484     /* Build a call to _aaInX().  */
    485     this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
    486 				   build_expr (e->e2),
    487 				   build_typeinfo (e, tkey),
    488 				   build_address (key));
    489   }
    490 
    491   /* Build a relational expression.  The result type is bool.  */
    492 
    493   void visit (CmpExp *e)
    494   {
    495     Type *tb1 = e->e1->type->toBasetype ();
    496     Type *tb2 = e->e2->type->toBasetype ();
    497 
    498     tree result;
    499     tree_code code;
    500 
    501     switch (e->op)
    502       {
    503       case EXP::lessOrEqual:
    504 	code = LE_EXPR;
    505 	break;
    506 
    507       case EXP::lessThan:
    508 	code = LT_EXPR;
    509 	break;
    510 
    511       case EXP::greaterOrEqual:
    512 	code = GE_EXPR;
    513 	break;
    514 
    515       case EXP::greaterThan:
    516 	code = GT_EXPR;
    517 	break;
    518 
    519       default:
    520 	gcc_unreachable ();
    521       }
    522 
    523     /* For static and dynamic arrays, the relational op is turned into a
    524        library call.  It is not lowered during codegen.  */
    525     if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
    526 	&& (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
    527       {
    528 	error ("cannot handle comparison of type %<%s == %s%>",
    529 	       tb1->toChars (), tb2->toChars ());
    530 	gcc_unreachable ();
    531       }
    532 
    533     /* Simple comparison.  */
    534     result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
    535     this->result_ = d_convert (build_ctype (e->type), result);
    536   }
    537 
    538   /* Build a logical `and if' or `or if' expression.  If the right operand
    539      expression is void, then the resulting type is void.  Otherwise the
    540      result is bool.  */
    541 
    542   void visit (LogicalExp *e)
    543   {
    544     tree_code code = (e->op == EXP::andAnd) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
    545 
    546     if (e->e2->type->toBasetype ()->ty != TY::Tvoid)
    547       {
    548 	tree t1 = build_expr (e->e1);
    549 	tree t2 = build_expr (e->e2);
    550 
    551 	t1 = convert_for_condition (t1, e->e1->type);
    552 	t2 = convert_for_condition (t2, e->e2->type);
    553 
    554 	this->result_ = d_convert (build_ctype (e->type),
    555 				   build_boolop (code, t1, t2));
    556       }
    557     else
    558       {
    559 	tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
    560 	tree t2 = build_expr_dtor (e->e2);
    561 
    562 	/* Invert condition for logical or if expression.  */
    563 	if (e->op == EXP::orOr)
    564 	  t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);
    565 
    566 	this->result_ = build_condition (build_ctype (e->type),
    567 					 t1, t2, void_node);
    568       }
    569   }
    570 
    571   /* Build a binary operand expression.  Operands go through usual arithmetic
    572      conversions to bring them to a common type before evaluating.  */
    573 
    574   void visit (BinExp *e)
    575   {
    576     tree_code code;
    577 
    578     switch (e->op)
    579       {
    580       case EXP::add:
    581       case EXP::min:
    582 	if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
    583 	    || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
    584 	  {
    585 	    /* If the result is complex, then we can shortcut binary_op.
    586 	       Frontend should have already validated types and sizes.  */
    587 	    tree t1 = build_expr (e->e1);
    588 	    tree t2 = build_expr (e->e2);
    589 
    590 	    if (e->op == EXP::min)
    591 	      t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
    592 
    593 	    if (e->e1->type->isreal ())
    594 	      this->result_ = complex_expr (build_ctype (e->type), t1, t2);
    595 	    else
    596 	      this->result_ = complex_expr (build_ctype (e->type), t2, t1);
    597 
    598 	    return;
    599 	  }
    600 	else
    601 	  code = (e->op == EXP::add)
    602 	    ? PLUS_EXPR : MINUS_EXPR;
    603 	break;
    604 
    605       case EXP::mul:
    606 	code = MULT_EXPR;
    607 	break;
    608 
    609       case EXP::div:
    610 	/* Determine if the div expression is a lowered pointer diff operation.
    611 	   The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'.  */
    612 	if (MinExp *me = e->e1->isMinExp ())
    613 	  {
    614 	    if (me->e1->type->ty == TY::Tpointer
    615 		&& me->e2->type->ty == TY::Tpointer
    616 		&& e->e2->op == EXP::int64)
    617 	      {
    618 		code = EXACT_DIV_EXPR;
    619 		break;
    620 	      }
    621 	  }
    622 
    623 	code = e->e1->type->isintegral ()
    624 	  ? TRUNC_DIV_EXPR : RDIV_EXPR;
    625 	break;
    626 
    627       case EXP::mod:
    628 	code = e->e1->type->isfloating ()
    629 	  ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
    630 	break;
    631 
    632       case EXP::and_:
    633 	code = BIT_AND_EXPR;
    634 	break;
    635 
    636       case EXP::or_:
    637 	code = BIT_IOR_EXPR;
    638 	break;
    639 
    640       case EXP::xor_:
    641 	code = BIT_XOR_EXPR;
    642 	break;
    643 
    644       case EXP::leftShift:
    645 	code = LSHIFT_EXPR;
    646 	  break;
    647 
    648       case EXP::rightShift:
    649 	code = RSHIFT_EXPR;
    650 	break;
    651 
    652       case EXP::unsignedRightShift:
    653 	code = UNSIGNED_RSHIFT_EXPR;
    654 	break;
    655 
    656       default:
    657 	gcc_unreachable ();
    658       }
    659 
    660     this->result_ = binary_op (code, build_ctype (e->type),
    661 			       build_expr (e->e1), build_expr (e->e2));
    662   }
    663 
    664 
    665   /* Build a concat expression, which concatenates two or more arrays of the
    666      same type, producing a dynamic array with the result.  If one operand
    667      is an element type, that element is converted to an array of length 1.  */
    668 
    669   void visit (CatExp *e)
    670   {
    671     Type *tb1 = e->e1->type->toBasetype ();
    672     Type *tb2 = e->e2->type->toBasetype ();
    673     Type *etype;
    674 
    675     if (tb1->ty == TY::Tarray || tb1->ty == TY::Tsarray)
    676       etype = tb1->nextOf ();
    677     else
    678       etype = tb2->nextOf ();
    679 
    680     tree result;
    681 
    682     if (e->e1->op == EXP::concatenate)
    683       {
    684 	/* Flatten multiple concatenations to an array.
    685 	   So the expression ((a ~ b) ~ c) becomes [a, b, c]  */
    686 	int ndims = 2;
    687 
    688 	for (Expression *ex = e->e1; ex->op == EXP::concatenate;)
    689 	  {
    690 	    if (ex->op == EXP::concatenate)
    691 	      {
    692 		ex = ex->isCatExp ()->e1;
    693 		ndims++;
    694 	      }
    695 	  }
    696 
    697 	/* Store all concatenation args to a temporary byte[][ndims] array.  */
    698 	Type *targselem = Type::tint8->arrayOf ();
    699 	tree var = build_local_temp (make_array_type (targselem, ndims));
    700 
    701 	/* Loop through each concatenation from right to left.  */
    702 	vec <constructor_elt, va_gc> *elms = NULL;
    703 	CatExp *ce = e;
    704 	int dim = ndims - 1;
    705 
    706 	for (Expression *oe = ce->e2; oe != NULL;
    707 	     (ce->e1->op != EXP::concatenate
    708 	      ? (oe = ce->e1)
    709 	      : (ce = ce->e1->isCatExp (), oe = ce->e2)))
    710 	  {
    711 	    tree arg = d_array_convert (etype, oe);
    712 	    tree index = size_int (dim);
    713 	    CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));
    714 
    715 	    /* Finished pushing all arrays.  */
    716 	    if (oe == ce->e1)
    717 	      break;
    718 
    719 	    dim -= 1;
    720 	  }
    721 
    722 	/* Check there is no logic bug in constructing byte[][] of arrays.  */
    723 	gcc_assert (dim == 0);
    724 	tree init = build_constructor (TREE_TYPE (var), elms);
    725 	var = compound_expr (modify_expr (var, init), var);
    726 
    727 	tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
    728 				   size_int (ndims), build_address (var));
    729 
    730 	result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
    731 				build_typeinfo (e, e->type), arrs);
    732       }
    733     else
    734       {
    735 	/* Handle single concatenation (a ~ b).  */
    736 	result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
    737 				build_typeinfo (e, e->type),
    738 				d_array_convert (etype, e->e1),
    739 				d_array_convert (etype, e->e2));
    740       }
    741 
    742     this->result_ = result;
    743   }
    744 
    745   /* Build an assignment operator expression.  The right operand is implicitly
    746      converted to the type of the left operand, and assigned to it.  */
    747 
    748   void visit (BinAssignExp *e)
    749   {
    750     tree_code code;
    751     Expression *e1b = e->e1;
    752 
    753     switch (e->op)
    754       {
    755       case EXP::addAssign:
    756 	code = PLUS_EXPR;
    757 	break;
    758 
    759       case EXP::minAssign:
    760 	code = MINUS_EXPR;
    761 	break;
    762 
    763       case EXP::mulAssign:
    764 	code = MULT_EXPR;
    765 	break;
    766 
    767       case EXP::divAssign:
    768 	code = e->e1->type->isintegral ()
    769 	  ? TRUNC_DIV_EXPR : RDIV_EXPR;
    770 	break;
    771 
    772       case EXP::modAssign:
    773 	code = e->e1->type->isfloating ()
    774 	  ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
    775 	break;
    776 
    777       case EXP::andAssign:
    778 	code = BIT_AND_EXPR;
    779 	break;
    780 
    781       case EXP::orAssign:
    782 	code = BIT_IOR_EXPR;
    783 	break;
    784 
    785       case EXP::xorAssign:
    786 	code = BIT_XOR_EXPR;
    787 	break;
    788 
    789       case EXP::powAssign:
    790 	gcc_unreachable ();
    791 
    792       case EXP::leftShiftAssign:
    793 	code = LSHIFT_EXPR;
    794 	break;
    795 
    796       case EXP::rightShiftAssign:
    797       case EXP::unsignedRightShiftAssign:
    798 	/* Use the original lhs type before it was promoted.  The left operand
    799 	   of `>>>=' does not undergo integral promotions before shifting.
    800 	   Strip off casts just incase anyway.  */
    801 	while (e1b->op == EXP::cast_)
    802 	  {
    803 	    CastExp *ce = e1b->isCastExp ();
    804 	    gcc_assert (same_type_p (ce->type, ce->to));
    805 	    e1b = ce->e1;
    806 	  }
    807 	code = (e->op == EXP::rightShiftAssign) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
    808 	break;
    809 
    810       default:
    811 	gcc_unreachable ();
    812       }
    813 
    814     tree exp = binop_assignment (code, e1b, e->e2);
    815     this->result_ = convert_expr (exp, e1b->type, e->type);
    816   }
    817 
    818   /* Build a concat assignment expression.  The right operand is appended
    819      to the left operand.  */
    820 
    821   void visit (CatAssignExp *e)
    822   {
    823     Type *tb1 = e->e1->type->toBasetype ();
    824     Type *tb2 = e->e2->type->toBasetype ();
    825     Type *etype = tb1->nextOf ()->toBasetype ();
    826 
    827     /* Save the address of `e1', so it can be evaluated first.
    828        As all D run-time library functions for concat assignments update `e1'
    829        in-place and then return its value, the saved address can also be used as
    830        the result of this expression as well.  */
    831     tree lhs = build_expr (e->e1);
    832     tree lexpr = stabilize_expr (&lhs);
    833     tree ptr = d_save_expr (build_address (lhs));
    834     tree result = NULL_TREE;
    835 
    836     if (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar
    837 	&& (etype->ty == TY::Tchar || etype->ty == TY::Twchar))
    838       {
    839 	/* Append a dchar to a char[] or wchar[]:
    840 	   The assignment is handled by the D run-time library, so only
    841 	   need to call `_d_arrayappend[cw]d(&e1, e2)'  */
    842 	libcall_fn libcall = (etype->ty == TY::Tchar)
    843 	  ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
    844 
    845 	result = build_libcall (libcall, e->type, 2,
    846 				ptr, build_expr (e->e2));
    847       }
    848     else
    849       {
    850 	gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray);
    851 
    852 	if ((tb2->ty == TY::Tarray || tb2->ty == TY::Tsarray)
    853 	    && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
    854 	  {
    855 	    /* Append an array to another array:
    856 	       The assignment is handled by the D run-time library, so only
    857 	       need to call `_d_arrayappendT(ti, &e1, e2)'  */
    858 	    result = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
    859 				    build_typeinfo (e->loc, e->type),
    860 				    ptr, d_array_convert (e->e2));
    861 	  }
    862 	else if (same_type_p (etype, tb2))
    863 	  {
    864 	    /* Append an element to an array:
    865 	       The assignment is generated inline, so need to handle temporaries
    866 	       here, and ensure that they are evaluated in the correct order.
    867 
    868 	       The generated code should end up being equivalent to:
    869 		    _d_arrayappendcTX(ti, &e1, 1)[e1.length - 1] = e2
    870 	     */
    871 	    tree callexp = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
    872 					  build_typeinfo (e->loc, e->type),
    873 					  ptr, size_one_node);
    874 	    callexp = d_save_expr (callexp);
    875 
    876 	    /* Assign e2 to last element.  */
    877 	    tree offexp = d_array_length (callexp);
    878 	    offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
    879 			     offexp, size_one_node);
    880 
    881 	    tree ptrexp = d_array_ptr (callexp);
    882 	    ptrexp = void_okay_p (ptrexp);
    883 	    ptrexp = build_array_index (ptrexp, offexp);
    884 
    885 	    /* Evaluate expression before appending.  */
    886 	    tree rhs = build_expr (e->e2);
    887 	    tree rexpr = stabilize_expr (&rhs);
    888 
    889 	    if (TREE_CODE (rhs) == CALL_EXPR)
    890 	      rhs = force_target_expr (rhs);
    891 
    892 	    result = modify_expr (build_deref (ptrexp), rhs);
    893 	    result = compound_expr (rexpr, result);
    894 	  }
    895 	else
    896 	  gcc_unreachable ();
    897       }
    898 
    899     /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr;  */
    900     result = compound_expr (compound_expr (lexpr, ptr), result);
    901     this->result_ = compound_expr (result, build_deref (ptr));
    902   }
    903 
    904   /* Build an assignment expression.  The right operand is implicitly
    905      converted to the type of the left operand, and assigned to it.  */
    906 
    907   void visit (AssignExp *e)
    908   {
    909     /* First, handle special assignment semantics.  */
    910 
    911     /* Look for array.length = n;  */
    912     if (e->e1->op == EXP::arrayLength)
    913       {
    914 	/* This case should have been rewritten to `_d_arraysetlengthT` in the
    915 	   semantic phase.  */
    916 	gcc_unreachable ();
    917       }
    918 
    919     /* Look for exp = noreturn;  */
    920     if (e->e2->type->isTypeNoreturn ())
    921       {
    922 	/* If the RHS is a `noreturn' expression, there is no point generating
    923 	   any code for the assignment, just evaluate side effects.  */
    924 	tree t1 = build_expr (e->e1);
    925 	tree t2 = build_expr (e->e2);
    926 	this->result_ = compound_expr (t1, t2);
    927 	return;
    928       }
    929 
    930     /* Look for array[] = n;  */
    931     if (e->e1->op == EXP::slice)
    932       {
    933 	SliceExp *se = e->e1->isSliceExp ();
    934 	Type *stype = se->e1->type->toBasetype ();
    935 	Type *etype = stype->nextOf ()->toBasetype ();
    936 
    937 	/* Determine if we need to run postblit or dtor.  */
    938 	bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
    939 	bool destructor = needs_dtor (etype);
    940 
    941 	if (e->memset == MemorySet::blockAssign)
    942 	  {
    943 	    /* Set a range of elements to one value.  */
    944 	    tree t1 = build_expr (e->e1);
    945 	    tree t2 = build_expr (e->e2);
    946 	    tree result;
    947 
    948 	    /* Extract any array bounds checks from the slice expression.  */
    949 	    tree init = stabilize_expr (&t1);
    950 	    t1 = d_save_expr (t1);
    951 
    952 	    if ((postblit || destructor) && e->op != EXP::blit)
    953 	      {
    954 		/* Need to call postblit/destructor as part of assignment.
    955 		   Construction has already been handled by the front-end.  */
    956 		gcc_assert (e->op != EXP::construct);
    957 
    958 		/* So we can call postblits on const/immutable objects.  */
    959 		Type *tm = etype->unSharedOf ()->mutableOf ();
    960 		tree ti = build_typeinfo (e, tm);
    961 
    962 		/* Generate: _d_arraysetassign (t1.ptr, &t2, t1.length, ti);  */
    963 		result = build_libcall (LIBCALL_ARRAYSETASSIGN, Type::tvoid, 4,
    964 					d_array_ptr (t1),
    965 					build_address (t2),
    966 					d_array_length (t1), ti);
    967 	      }
    968 	    else if (integer_zerop (t2))
    969 	      {
    970 		tree size = size_mult_expr (d_array_length (t1),
    971 					    size_int (etype->size ()));
    972 		result = build_memset_call (d_array_ptr (t1), size);
    973 	      }
    974 	    else
    975 	      result = build_array_set (d_array_ptr (t1),
    976 					d_array_length (t1), t2);
    977 
    978 	    result = compound_expr (init, result);
    979 	    this->result_ = compound_expr (result, t1);
    980 	  }
    981 	else
    982 	  {
    983 	    /* Perform a memcpy operation.  */
    984 	    gcc_assert (e->e2->type->ty != TY::Tpointer);
    985 
    986 	    if (!postblit && !destructor)
    987 	      {
    988 		tree t1 = d_save_expr (d_array_convert (e->e1));
    989 		tree t2 = d_save_expr (d_array_convert (e->e2));
    990 
    991 		/* References to array data.  */
    992 		tree t1ptr = d_array_ptr (t1);
    993 		tree t1len = d_array_length (t1);
    994 		tree t2ptr = d_array_ptr (t2);
    995 
    996 		/* Generate: memcpy(to, from, size)  */
    997 		tree size = size_mult_expr (t1len, size_int (etype->size ()));
    998 		tree result = build_memcpy_call (t1ptr, t2ptr, size);
    999 
   1000 		/* Insert check that array lengths match and do not overlap.  */
   1001 		if (array_bounds_check ())
   1002 		  {
   1003 		    /* tlencmp = (t1len == t2len)  */
   1004 		    tree t2len = d_array_length (t2);
   1005 		    tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len);
   1006 
   1007 		    /* toverlap = (t1ptr + size <= t2ptr
   1008 				   || t2ptr + size <= t1ptr)  */
   1009 		    tree t1ptrcmp = build_boolop (LE_EXPR,
   1010 						  build_offset (t1ptr, size),
   1011 						  t2ptr);
   1012 		    tree t2ptrcmp = build_boolop (LE_EXPR,
   1013 						  build_offset (t2ptr, size),
   1014 						  t1ptr);
   1015 		    tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp,
   1016 						  t2ptrcmp);
   1017 
   1018 		    /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds()  */
   1019 		    tree tassert = build_array_bounds_call (e->loc);
   1020 		    tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR,
   1021 						      tlencmp, toverlap);
   1022 
   1023 		    result = build_condition (void_type_node, tboundscheck,
   1024 					      result, tassert);
   1025 		  }
   1026 
   1027 		this->result_ = compound_expr (result, t1);
   1028 	      }
   1029 	    else if ((postblit || destructor)
   1030 		     && e->op != EXP::blit && e->op != EXP::construct)
   1031 	      {
   1032 		/* Generate: _d_arrayassign(ti, from, to);  */
   1033 		this->result_ = build_libcall (LIBCALL_ARRAYASSIGN, e->type, 3,
   1034 					       build_typeinfo (e, etype),
   1035 					       d_array_convert (e->e2),
   1036 					       d_array_convert (e->e1));
   1037 	      }
   1038 	    else
   1039 	      {
   1040 		/* Generate: _d_arraycopy()  */
   1041 		this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
   1042 					       size_int (etype->size ()),
   1043 					       d_array_convert (e->e2),
   1044 					       d_array_convert (e->e1));
   1045 	      }
   1046 	  }
   1047 
   1048 	return;
   1049       }
   1050 
   1051     /* Look for reference initializations.  */
   1052     if (e->memset == MemorySet::referenceInit)
   1053       {
   1054 	gcc_assert (e->op == EXP::construct || e->op == EXP::blit);
   1055 	gcc_assert (e->e1->op == EXP::variable);
   1056 
   1057 	Declaration *decl = e->e1->isVarExp ()->var;
   1058 	if (decl->storage_class & (STCout | STCref))
   1059 	  {
   1060 	    tree t2 = convert_for_assignment (e->e2, e->e1->type);
   1061 	    tree t1 = build_expr (e->e1);
   1062 	    /* Want reference to lhs, not indirect ref.  */
   1063 	    t1 = TREE_OPERAND (t1, 0);
   1064 	    t2 = build_address (t2);
   1065 
   1066 	    this->result_ = indirect_ref (build_ctype (e->type),
   1067 					  build_assign (INIT_EXPR, t1, t2));
   1068 	    return;
   1069 	  }
   1070       }
   1071 
   1072     /* Other types of assignments that may require post construction.  */
   1073     Type *tb1 = e->e1->type->toBasetype ();
   1074     tree_code modifycode = (e->op == EXP::construct) ? INIT_EXPR : MODIFY_EXPR;
   1075 
   1076     /* Look for struct assignment.  */
   1077     if (tb1->ty == TY::Tstruct)
   1078       {
   1079 	tree t1 = build_expr (e->e1);
   1080 	tree t2 = convert_for_assignment (e->e2, e->e1->type, true);
   1081 	StructDeclaration *sd = tb1->isTypeStruct ()->sym;
   1082 
   1083 	/* Look for struct = 0.  */
   1084 	if (e->e2->op == EXP::int64)
   1085 	  {
   1086 	    /* Use memset to fill struct.  */
   1087 	    gcc_assert (e->op == EXP::blit);
   1088 	    tree result = build_memset_call (t1);
   1089 
   1090 	    /* Maybe set-up hidden pointer to outer scope context.  */
   1091 	    if (sd->isNested ())
   1092 	      {
   1093 		tree field = get_symbol_decl (sd->vthis);
   1094 		tree value = build_vthis (sd);
   1095 
   1096 		tree vthis_exp = modify_expr (component_ref (t1, field), value);
   1097 		result = compound_expr (result, vthis_exp);
   1098 	      }
   1099 
   1100 	    this->result_ = compound_expr (result, t1);
   1101 	  }
   1102 	else
   1103 	  {
   1104 	    /* Simple struct literal assignment.  */
   1105 	    tree init = NULL_TREE;
   1106 
   1107 	    /* Fill any alignment holes in the struct using memset.  */
   1108 	    if ((e->op == EXP::construct
   1109 		 || (e->e2->op == EXP::structLiteral && e->op == EXP::blit))
   1110 		&& (sd->isUnionDeclaration () || !identity_compare_p (sd)))
   1111 	      {
   1112 		t1 = stabilize_reference (t1);
   1113 		init = build_memset_call (t1);
   1114 	      }
   1115 
   1116 	    /* Elide generating assignment if init is all zeroes.  */
   1117 	    if (init != NULL_TREE && initializer_zerop (t2))
   1118 	      this->result_ = compound_expr (init, t1);
   1119 	    else
   1120 	      {
   1121 		tree result = build_assign (modifycode, t1, t2);
   1122 		this->result_ = compound_expr (init, result);
   1123 	      }
   1124 	  }
   1125 
   1126 	return;
   1127       }
   1128 
   1129     /* Look for static array assignment.  */
   1130     if (tb1->ty == TY::Tsarray)
   1131       {
   1132 	/* Look for array = 0.  */
   1133 	if (e->e2->op == EXP::int64)
   1134 	  {
   1135 	    /* Use memset to fill the array.  */
   1136 	    gcc_assert (e->op == EXP::blit);
   1137 	    this->result_ = build_memset_call (build_expr (e->e1));
   1138 	    return;
   1139 	  }
   1140 
   1141 	Type *etype = tb1->nextOf ();
   1142 	gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray);
   1143 
   1144 	/* Determine if we need to run postblit.  */
   1145 	const bool postblit = needs_postblit (etype);
   1146 	const bool destructor = needs_dtor (etype);
   1147 	const bool lvalue = lvalue_p (e->e2);
   1148 
   1149 	/* Optimize static array assignment with array literal.  Even if the
   1150 	   elements in rhs are all rvalues and don't have to call postblits,
   1151 	   this assignment should call dtors on old assigned elements.  */
   1152 	if ((!postblit && !destructor)
   1153 	    || (e->op == EXP::construct && e->e2->op == EXP::arrayLiteral)
   1154 	    || (e->op == EXP::construct && !lvalue && postblit)
   1155 	    || (e->op == EXP::blit || e->e1->type->size () == 0))
   1156 	  {
   1157 	    tree t1 = build_expr (e->e1);
   1158 	    tree t2 = convert_for_assignment (e->e2, e->e1->type);
   1159 
   1160 	    this->result_ = build_assign (modifycode, t1, t2);
   1161 	    return;
   1162 	  }
   1163 
   1164 	/* All other kinds of lvalue or rvalue static array assignment.
   1165 	   Array construction has already been handled by the front-end.  */
   1166 	gcc_assert (e->op != EXP::construct);
   1167 
   1168 	/* Generate: _d_arrayassign_l()
   1169 		 or: _d_arrayassign_r()  */
   1170 	libcall_fn libcall = (lvalue)
   1171 	  ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
   1172 	tree elembuf = build_local_temp (build_ctype (etype));
   1173 	Type *arrtype = (e->type->ty == TY::Tsarray)
   1174 	  ? etype->arrayOf () : e->type;
   1175 	tree result = build_libcall (libcall, arrtype, 4,
   1176 				     build_typeinfo (e, etype),
   1177 				     d_array_convert (e->e2),
   1178 				     d_array_convert (e->e1),
   1179 				     build_address (elembuf));
   1180 
   1181 	/* Cast the libcall result back to a static array.  */
   1182 	if (e->type->ty == TY::Tsarray)
   1183 	  result = indirect_ref (build_ctype (e->type),
   1184 				 d_array_ptr (result));
   1185 
   1186 	this->result_ = result;
   1187 	return;
   1188       }
   1189 
   1190     /* Simple assignment.  */
   1191     tree t1 = build_expr (e->e1);
   1192     tree t2 = convert_for_assignment (e->e2, e->e1->type);
   1193 
   1194     this->result_ = build_assign (modifycode, t1, t2);
   1195   }
   1196 
   1197   /* Build a throw expression.  */
   1198 
   1199   void visit (ThrowExp *e)
   1200   {
   1201     tree arg = build_expr_dtor (e->e1);
   1202     this->result_ = build_libcall (LIBCALL_THROW, Type::tvoid, 1, arg);
   1203   }
   1204 
   1205   /* Build a postfix expression.  */
   1206 
   1207   void visit (PostExp *e)
   1208   {
   1209     tree result;
   1210 
   1211     if (e->op == EXP::plusPlus)
   1212       {
   1213 	result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
   1214 			 build_expr (e->e1), build_expr (e->e2));
   1215       }
   1216     else if (e->op == EXP::minusMinus)
   1217       {
   1218 	result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
   1219 			 build_expr (e->e1), build_expr (e->e2));
   1220       }
   1221     else
   1222       gcc_unreachable ();
   1223 
   1224     TREE_SIDE_EFFECTS (result) = 1;
   1225     this->result_ = result;
   1226   }
   1227 
   1228   /* Build an index expression.  */
   1229 
   1230   void visit (IndexExp *e)
   1231   {
   1232     Type *tb1 = e->e1->type->toBasetype ();
   1233 
   1234     if (tb1->ty == TY::Taarray)
   1235       {
   1236 	/* Get the key for the associative array.  */
   1237 	Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
   1238 	tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
   1239 	libcall_fn libcall;
   1240 	tree tinfo, ptr;
   1241 
   1242 	if (e->modifiable)
   1243 	  {
   1244 	    libcall = LIBCALL_AAGETY;
   1245 	    ptr = build_address (build_expr (e->e1));
   1246 	    tinfo = build_typeinfo (e, tb1->unSharedOf ()->mutableOf ());
   1247 	  }
   1248 	else
   1249 	  {
   1250 	    libcall = LIBCALL_AAGETRVALUEX;
   1251 	    ptr = build_expr (e->e1);
   1252 	    tinfo = build_typeinfo (e, tkey);
   1253 	  }
   1254 
   1255 	/* Index the associative array.  */
   1256 	tree result = build_libcall (libcall, e->type->pointerTo (), 4,
   1257 				     ptr, tinfo,
   1258 				     size_int (tb1->nextOf ()->size ()),
   1259 				     build_address (key));
   1260 
   1261 	if (!e->indexIsInBounds && array_bounds_check ())
   1262 	  {
   1263 	    tree tassert = build_array_bounds_call (e->loc);
   1264 
   1265 	    result = d_save_expr (result);
   1266 	    result = build_condition (TREE_TYPE (result),
   1267 				      d_truthvalue_conversion (result),
   1268 				      result, tassert);
   1269 	  }
   1270 
   1271 	this->result_ = indirect_ref (build_ctype (e->type), result);
   1272       }
   1273     else
   1274       {
   1275 	/* Get the data pointer and length for static and dynamic arrays.  */
   1276 	tree array = d_save_expr (build_expr (e->e1));
   1277 	tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
   1278 
   1279 	tree length = NULL_TREE;
   1280 	if (tb1->ty != TY::Tpointer)
   1281 	  length = get_array_length (array, tb1);
   1282 	else
   1283 	  gcc_assert (e->lengthVar == NULL);
   1284 
   1285 	/* The __dollar variable just becomes a placeholder for the
   1286 	   actual length.  */
   1287 	if (e->lengthVar)
   1288 	  e->lengthVar->csym = length;
   1289 
   1290 	/* Generate the index.  */
   1291 	tree index = build_expr (e->e2);
   1292 
   1293 	/* If it's a static array and the index is constant, the front end has
   1294 	   already checked the bounds.  */
   1295 	if (tb1->ty != TY::Tpointer)
   1296 	  index = build_bounds_index_condition (e, index, length);
   1297 
   1298 	/* Index the .ptr.  */
   1299 	ptr = void_okay_p (ptr);
   1300 	this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
   1301 				      build_array_index (ptr, index));
   1302       }
   1303   }
   1304 
   1305   /* Build a comma expression.  The type is the type of the right operand.  */
   1306 
   1307   void visit (CommaExp *e)
   1308   {
   1309     tree t1 = build_expr (e->e1);
   1310     tree t2 = build_expr (e->e2);
   1311     tree type = e->type ? build_ctype (e->type) : void_type_node;
   1312 
   1313     this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
   1314   }
   1315 
   1316   /* Build an array length expression.  Returns the number of elements
   1317      in the array.  The result is of type size_t.  */
   1318 
   1319   void visit (ArrayLengthExp *e)
   1320   {
   1321     if (e->e1->type->toBasetype ()->ty == TY::Tarray)
   1322       this->result_ = d_array_length (build_expr (e->e1));
   1323     else
   1324       {
   1325 	/* Static arrays have already been handled by the front-end.  */
   1326 	error ("unexpected type for array length: %qs", e->type->toChars ());
   1327 	this->result_ = error_mark_node;
   1328       }
   1329   }
   1330 
   1331   /* Build a delegate pointer expression.  This will return the frame
   1332      pointer value as a type void*.  */
   1333 
   1334   void visit (DelegatePtrExp *e)
   1335   {
   1336     tree t1 = build_expr (e->e1);
   1337     this->result_ = delegate_object (t1);
   1338   }
   1339 
   1340   /* Build a delegate function pointer expression.  This will return the
   1341      function pointer value as a function type.  */
   1342 
   1343   void visit (DelegateFuncptrExp *e)
   1344   {
   1345     tree t1 = build_expr (e->e1);
   1346     this->result_ = delegate_method (t1);
   1347   }
   1348 
   1349   /* Build a slice expression.  */
   1350 
   1351   void visit (SliceExp *e)
   1352   {
   1353     Type *tb = e->type->toBasetype ();
   1354     Type *tb1 = e->e1->type->toBasetype ();
   1355     gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray);
   1356 
   1357     /* Use convert-to-dynamic-array code if possible.  */
   1358     if (!e->lwr)
   1359       {
   1360 	tree result = build_expr (e->e1);
   1361 	if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
   1362 	  result = convert_expr (result, e->e1->type, e->type);
   1363 
   1364 	this->result_ = result;
   1365 	return;
   1366       }
   1367     else
   1368       gcc_assert (e->upr != NULL);
   1369 
   1370     /* Get the data pointer and length for static and dynamic arrays.  */
   1371     tree array = d_save_expr (build_expr (e->e1));
   1372     tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
   1373     tree length = NULL_TREE;
   1374 
   1375     /* Our array is already a SAVE_EXPR if necessary, so we don't make length
   1376        a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array.  */
   1377     if (tb1->ty != TY::Tpointer)
   1378       length = get_array_length (array, tb1);
   1379     else
   1380       gcc_assert (e->lengthVar == NULL);
   1381 
   1382     /* The __dollar variable just becomes a placeholder for the
   1383        actual length.  */
   1384     if (e->lengthVar)
   1385       e->lengthVar->csym = length;
   1386 
   1387     /* Generate upper and lower bounds.  */
   1388     tree lwr_tree = d_save_expr (build_expr (e->lwr));
   1389     tree upr_tree = d_save_expr (build_expr (e->upr));
   1390 
   1391     /* If the upper bound has any side effects, then the lower bound should be
   1392        copied to a temporary always.  */
   1393     if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
   1394       lwr_tree = save_expr (lwr_tree);
   1395 
   1396     /* Adjust the .ptr offset.  */
   1397     if (!integer_zerop (lwr_tree))
   1398       {
   1399 	tree ptrtype = TREE_TYPE (ptr);
   1400 	ptr = build_array_index (void_okay_p (ptr), lwr_tree);
   1401 	ptr = build_nop (ptrtype, ptr);
   1402       }
   1403 
   1404     /* Nothing more to do for static arrays, their bounds checking has been
   1405        done at compile-time.  */
   1406     if (tb->ty == TY::Tsarray)
   1407       {
   1408 	this->result_ = indirect_ref (build_ctype (e->type), ptr);
   1409 	return;
   1410       }
   1411     else
   1412       gcc_assert (tb->ty == TY::Tarray);
   1413 
   1414     /* Generate bounds checking code.  */
   1415     tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree,
   1416 						   length);
   1417     tree result = d_array_value (build_ctype (e->type), newlength, ptr);
   1418     this->result_ = compound_expr (array, result);
   1419   }
   1420 
   1421   /* Build a cast expression, which converts the given unary expression to the
   1422      type of result.  */
   1423 
   1424   void visit (CastExp *e)
   1425   {
   1426     Type *ebtype = e->e1->type->toBasetype ();
   1427     Type *tbtype = e->to->toBasetype ();
   1428     tree result = build_expr (e->e1, this->constp_, this->literalp_);
   1429 
   1430     /* Just evaluate e1 if it has any side effects.  */
   1431     if (tbtype->ty == TY::Tvoid)
   1432       this->result_ = build_nop (build_ctype (tbtype), result);
   1433     else
   1434       this->result_ = convert_for_rvalue (result, ebtype, tbtype);
   1435   }
   1436 
   1437   /* Build a delete expression.  */
   1438 
   1439   void visit (DeleteExp *e)
   1440   {
   1441     tree t1 = build_expr (e->e1);
   1442     Type *tb1 = e->e1->type->toBasetype ();
   1443 
   1444     if (tb1->ty == TY::Tclass)
   1445       {
   1446 	/* For class object references, if there is a destructor for that class,
   1447 	   the destructor is called for the object instance.  */
   1448 	gcc_assert (e->e1->op == EXP::variable);
   1449 
   1450 	VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
   1451 	gcc_assert (v && v->onstack ());
   1452 
   1453 	libcall_fn libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
   1454 	  ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
   1455 
   1456 	this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
   1457 	return;
   1458       }
   1459     else
   1460       {
   1461 	error ("don%'t know how to delete %qs", e->e1->toChars ());
   1462 	this->result_ = error_mark_node;
   1463       }
   1464   }
   1465 
   1466   /* Build a remove expression, which removes a particular key from an
   1467      associative array.  */
   1468 
   1469   void visit (RemoveExp *e)
   1470   {
   1471     /* Check that the array is actually an associative array.  */
   1472     if (e->e1->type->toBasetype ()->ty == TY::Taarray)
   1473       {
   1474 	Type *tb = e->e1->type->toBasetype ();
   1475 	Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
   1476 	tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
   1477 
   1478 	this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
   1479 				       build_expr (e->e1),
   1480 				       build_typeinfo (e, tkey),
   1481 				       build_address (index));
   1482       }
   1483     else
   1484       {
   1485 	error ("%qs is not an associative array", e->e1->toChars ());
   1486 	this->result_ = error_mark_node;
   1487       }
   1488   }
   1489 
   1490   /* Build an unary not expression.  */
   1491 
   1492   void visit (NotExp *e)
   1493   {
   1494     tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
   1495     /* Need to convert to boolean type or this will fail.  */
   1496     result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
   1497 
   1498     this->result_ = d_convert (build_ctype (e->type), result);
   1499   }
   1500 
   1501   /* Build a compliment expression, where all the bits in the value are
   1502      complemented.  Note: unlike in C, the usual integral promotions
   1503      are not performed prior to the complement operation.  */
   1504 
   1505   void visit (ComExp *e)
   1506   {
   1507     TY ty1 = e->e1->type->toBasetype ()->ty;
   1508     gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
   1509 
   1510     this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
   1511 				 build_expr (e->e1));
   1512   }
   1513 
   1514   /* Build an unary negation expression.  */
   1515 
   1516   void visit (NegExp *e)
   1517   {
   1518     TY ty1 = e->e1->type->toBasetype ()->ty;
   1519     gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
   1520 
   1521     tree type = build_ctype (e->type);
   1522     tree expr = build_expr (e->e1);
   1523 
   1524     /* If the operation needs excess precision.  */
   1525     tree eptype = excess_precision_type (type);
   1526     if (eptype != NULL_TREE)
   1527       expr = d_convert (eptype, expr);
   1528     else
   1529       eptype = type;
   1530 
   1531     tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
   1532     this->result_ = d_convert (type, ret);
   1533   }
   1534 
   1535   /* Build a pointer index expression.  */
   1536 
   1537   void visit (PtrExp *e)
   1538   {
   1539     Type *tnext = NULL;
   1540     dinteger_t offset;
   1541     tree result;
   1542 
   1543     if (e->e1->op == EXP::add)
   1544       {
   1545 	AddExp *ae = e->e1->isAddExp ();
   1546 	if (ae->e1->op == EXP::address
   1547 	    && ae->e2->isConst () && ae->e2->type->isintegral ())
   1548 	  {
   1549 	    Expression *ex = ae->e1->isAddrExp ()->e1;
   1550 	    tnext = ex->type->toBasetype ();
   1551 	    result = build_expr (ex);
   1552 	    offset = ae->e2->toUInteger ();
   1553 	  }
   1554       }
   1555     else if (e->e1->op == EXP::symbolOffset)
   1556       {
   1557 	SymOffExp *se = e->e1->isSymOffExp ();
   1558 	if (!declaration_reference_p (se->var))
   1559 	  {
   1560 	    tnext = se->var->type->toBasetype ();
   1561 	    result = get_decl_tree (se->var);
   1562 	    offset = se->offset;
   1563 	  }
   1564       }
   1565 
   1566     /* Produce better code by converting *(#record + n) to
   1567        COMPONENT_REFERENCE.  Otherwise, the variable will always be
   1568        allocated in memory because its address is taken.  */
   1569     if (tnext && tnext->ty == TY::Tstruct)
   1570       {
   1571 	StructDeclaration *sd = tnext->isTypeStruct ()->sym;
   1572 
   1573 	for (size_t i = 0; i < sd->fields.length; i++)
   1574 	  {
   1575 	    VarDeclaration *field = sd->fields[i];
   1576 
   1577 	    if (field->offset == offset
   1578 		&& same_type_p (field->type, e->type))
   1579 	      {
   1580 		/* Catch errors, backend will ICE otherwise.  */
   1581 		if (error_operand_p (result))
   1582 		  this->result_ = result;
   1583 		else
   1584 		  {
   1585 		    result  = component_ref (result, get_symbol_decl (field));
   1586 		    this->result_ = result;
   1587 		  }
   1588 		return;
   1589 	      }
   1590 	    else if (field->offset > offset)
   1591 	      break;
   1592 	  }
   1593       }
   1594 
   1595     this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
   1596   }
   1597 
   1598   /* Build an unary address expression.  */
   1599 
   1600   void visit (AddrExp *e)
   1601   {
   1602     tree type = build_ctype (e->type);
   1603     tree exp;
   1604 
   1605     /* The frontend optimizer can convert const symbol into a struct literal.
   1606        Taking the address of a struct literal is otherwise illegal.  */
   1607     if (e->e1->op == EXP::structLiteral)
   1608       {
   1609 	StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
   1610 	gcc_assert (sle != NULL);
   1611 
   1612 	/* Build the reference symbol, the decl is built first as the
   1613 	   initializer may have recursive references.  */
   1614 	if (!sle->sym)
   1615 	  {
   1616 	    sle->sym = build_artificial_decl (build_ctype (sle->type),
   1617 					      NULL_TREE, "S");
   1618 	    DECL_INITIAL (sle->sym) = build_expr (sle, true);
   1619 	    d_pushdecl (sle->sym);
   1620 	    rest_of_decl_compilation (sle->sym, 1, 0);
   1621 	  }
   1622 
   1623 	exp = sle->sym;
   1624       }
   1625     else
   1626       exp = build_expr (e->e1, this->constp_, this->literalp_);
   1627 
   1628     TREE_CONSTANT (exp) = 0;
   1629     this->result_ = d_convert (type, build_address (exp));
   1630   }
   1631 
   1632   /* Build a function call expression.  */
   1633 
   1634   void visit (CallExp *e)
   1635   {
   1636     Type *tb = e->e1->type->toBasetype ();
   1637     Expression *e1b = e->e1;
   1638 
   1639     tree callee = NULL_TREE;
   1640     tree object = NULL_TREE;
   1641     tree cleanup = NULL_TREE;
   1642     tree returnvalue = NULL_TREE;
   1643     TypeFunction *tf = NULL;
   1644 
   1645     /* Calls to delegates can sometimes look like this.  */
   1646     if (e1b->op == EXP::comma)
   1647       {
   1648 	e1b = e1b->isCommaExp ()->e2;
   1649 	gcc_assert (e1b->op == EXP::variable);
   1650 
   1651 	Declaration *var = e1b->isVarExp ()->var;
   1652 	gcc_assert (var->isFuncDeclaration () && !var->needThis ());
   1653       }
   1654 
   1655     if (e1b->op == EXP::dotVariable && tb->ty != TY::Tdelegate)
   1656       {
   1657 	DotVarExp *dve = e1b->isDotVarExp ();
   1658 
   1659 	/* Don't modify the static initializer for struct literals.  */
   1660 	if (dve->e1->op == EXP::structLiteral)
   1661 	  {
   1662 	    StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
   1663 	    sle->useStaticInit = false;
   1664 	  }
   1665 
   1666 	FuncDeclaration *fd = dve->var->isFuncDeclaration ();
   1667 	if (fd != NULL)
   1668 	  {
   1669 	    /* Get the correct callee from the DotVarExp object.  */
   1670 	    tree fndecl = get_symbol_decl (fd);
   1671 	    AggregateDeclaration *ad = fd->isThis ();
   1672 
   1673 	    /* Static method; ignore the object instance.  */
   1674 	    if (!ad)
   1675 	      callee = build_address (fndecl);
   1676 	    else
   1677 	      {
   1678 		tree thisexp = build_expr (dve->e1);
   1679 
   1680 		/* When constructing temporaries, if the constructor throws,
   1681 		   then the object is destructed even though it is not a fully
   1682 		   constructed object yet.  And so this call will need to be
   1683 		   moved inside the TARGET_EXPR_INITIAL slot.  */
   1684 		if (fd->isCtorDeclaration ()
   1685 		    && TREE_CODE (thisexp) == COMPOUND_EXPR
   1686 		    && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
   1687 		    && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
   1688 		  {
   1689 		    cleanup = TREE_OPERAND (thisexp, 0);
   1690 		    thisexp = TREE_OPERAND (thisexp, 1);
   1691 		  }
   1692 
   1693 		if (TREE_CODE (thisexp) == CONSTRUCTOR)
   1694 		  thisexp = force_target_expr (thisexp);
   1695 
   1696 		/* Want reference to `this' object.  */
   1697 		if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
   1698 		  thisexp = build_address (thisexp);
   1699 
   1700 		/* Make the callee a virtual call.  */
   1701 		if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
   1702 		  {
   1703 		    tree fntype = build_pointer_type (TREE_TYPE (fndecl));
   1704 		    tree thistype = build_ctype (ad->handleType ());
   1705 		    thisexp = build_nop (thistype, d_save_expr (thisexp));
   1706 		    fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
   1707 		  }
   1708 		else
   1709 		  fndecl = build_address (fndecl);
   1710 
   1711 		/* C++ constructors return void, even though front-end semantic
   1712 		   treats them as implicitly returning `this'.  Set returnvalue
   1713 		   to override the result of this expression.  */
   1714 		if (fd->isCtorDeclaration ())
   1715 		  {
   1716 		    thisexp = d_save_expr (thisexp);
   1717 		    returnvalue = thisexp;
   1718 		  }
   1719 
   1720 		callee = build_method_call (fndecl, thisexp, fd->type);
   1721 	      }
   1722 	  }
   1723       }
   1724 
   1725     if (callee == NULL_TREE)
   1726       callee = build_expr (e1b);
   1727 
   1728     if (METHOD_CALL_EXPR (callee))
   1729       {
   1730 	/* This could be a delegate expression (TY == Tdelegate), but not
   1731 	   actually a delegate variable.  */
   1732 	if (e1b->op == EXP::dotVariable)
   1733 	  {
   1734 	    /* This gets the true function type, getting the function type
   1735 	       from e1->type can sometimes be incorrect, such as when calling
   1736 	       a `ref' return function.  */
   1737 	    tf = get_function_type (e1b->isDotVarExp ()->var->type);
   1738 	  }
   1739 	else
   1740 	  tf = get_function_type (tb);
   1741 
   1742 	extract_from_method_call (callee, callee, object);
   1743       }
   1744     else if (tb->ty == TY::Tdelegate)
   1745       {
   1746 	/* Delegate call, extract .object and .funcptr from var.  */
   1747 	callee = d_save_expr (callee);
   1748 	tf = get_function_type (tb);
   1749 	object = delegate_object (callee);
   1750 	callee = delegate_method (callee);
   1751       }
   1752     else if (e1b->op == EXP::variable)
   1753       {
   1754 	FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
   1755 	gcc_assert (fd != NULL);
   1756 	tf = get_function_type (fd->type);
   1757 
   1758 	if (fd->isNested ())
   1759 	  {
   1760 	    /* Maybe re-evaluate symbol storage treating `fd' as public.  */
   1761 	    if (call_by_alias_p (d_function_chain->function, fd))
   1762 	      TREE_PUBLIC (callee) = 1;
   1763 
   1764 	    object = get_frame_for_symbol (fd);
   1765 	  }
   1766 	else if (fd->needThis ())
   1767 	  {
   1768 	    error_at (make_location_t (e1b->loc),
   1769 		      "need %<this%> to access member %qs", fd->toChars ());
   1770 	    /* Continue compiling...  */
   1771 	    object = null_pointer_node;
   1772 	  }
   1773       }
   1774     else
   1775       {
   1776 	/* Normal direct function call.  */
   1777 	tf = get_function_type (tb);
   1778       }
   1779 
   1780     gcc_assert (tf != NULL);
   1781 
   1782     /* Now we have the type, callee and maybe object reference,
   1783        build the call expression.  */
   1784     tree exp = d_build_call (tf, callee, object, e->arguments);
   1785 
   1786     if (returnvalue != NULL_TREE)
   1787       exp = compound_expr (exp, returnvalue);
   1788 
   1789     if (tf->isref ())
   1790       exp = build_deref (exp);
   1791 
   1792     /* Some library calls are defined to return a generic type.
   1793        this->type is the real type we want to return.  */
   1794     if (e->type->isTypeBasic ())
   1795       exp = d_convert (build_ctype (e->type), exp);
   1796 
   1797     /* If this call was found to be a constructor for a temporary with a
   1798        cleanup, then move the call inside the TARGET_EXPR.  */
   1799     if (cleanup != NULL_TREE)
   1800       {
   1801 	tree init = TARGET_EXPR_INITIAL (cleanup);
   1802 	TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
   1803 
   1804 	/* Keep the return value outside the TARGET_EXPR.  */
   1805 	if (returnvalue != NULL_TREE)
   1806 	  cleanup = compound_expr (cleanup, TREE_OPERAND (exp, 1));
   1807 
   1808 	exp = cleanup;
   1809       }
   1810 
   1811     this->result_ = exp;
   1812   }
   1813 
   1814   /* Build a delegate expression.  */
   1815 
   1816   void visit (DelegateExp *e)
   1817   {
   1818     if (e->func->semanticRun == PASS::semantic3done)
   1819       {
   1820 	/* Add the function as nested function if it belongs to this module.
   1821 	   ie: it is a member of this module, or it is a template instance.  */
   1822 	Dsymbol *owner = e->func->toParent ();
   1823 	while (!owner->isTemplateInstance () && owner->toParent ())
   1824 	  owner = owner->toParent ();
   1825 	if (owner->isTemplateInstance () || owner == d_function_chain->module)
   1826 	  build_decl_tree (e->func);
   1827       }
   1828 
   1829     tree fndecl;
   1830     tree object;
   1831 
   1832     if (e->func->isNested () && !e->func->isThis ())
   1833       {
   1834 	if (e->e1->op == EXP::null_)
   1835 	  object = build_expr (e->e1);
   1836 	else
   1837 	  object = get_frame_for_symbol (e->func);
   1838 
   1839 	fndecl = build_address (get_symbol_decl (e->func));
   1840       }
   1841     else
   1842       {
   1843 	if (!e->func->isThis ())
   1844 	  {
   1845 	    error ("delegates are only for non-static functions");
   1846 	    this->result_ = error_mark_node;
   1847 	    return;
   1848 	  }
   1849 
   1850 	object = build_expr (e->e1);
   1851 
   1852 	/* Want reference to `this' object.  */
   1853 	if (e->e1->type->ty != TY::Tclass && e->e1->type->ty != TY::Tpointer)
   1854 	  object = build_address (object);
   1855 
   1856 	/* Object reference could be the outer `this' field of a class or
   1857 	   closure of type `void*'.  Cast it to the right type.  */
   1858 	if (e->e1->type->ty == TY::Tclass)
   1859 	  object = d_convert (build_ctype (e->e1->type), object);
   1860 
   1861 	fndecl = get_symbol_decl (e->func);
   1862 
   1863 	/* Get pointer to function out of the virtual table.  */
   1864 	if (e->func->isVirtual () && !e->func->isFinalFunc ()
   1865 	    && e->e1->op != EXP::super_ && e->e1->op != EXP::dotType)
   1866 	  {
   1867 	    tree fntype = build_pointer_type (TREE_TYPE (fndecl));
   1868 	    object = d_save_expr (object);
   1869 	    fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
   1870 	  }
   1871 	else
   1872 	  fndecl = build_address (fndecl);
   1873       }
   1874 
   1875     this->result_ = build_method_call (fndecl, object, e->type);
   1876   }
   1877 
   1878   /* Build a type component expression.  */
   1879 
   1880   void visit (DotTypeExp *e)
   1881   {
   1882     /* Just a pass through to underlying expression.  */
   1883     this->result_ = build_expr (e->e1);
   1884   }
   1885 
   1886   /* Build a component reference expression.  */
   1887 
   1888   void visit (DotVarExp *e)
   1889   {
   1890     VarDeclaration *vd = e->var->isVarDeclaration ();
   1891 
   1892     /* This could also be a function, but relying on that being taken
   1893        care of by the visitor interface for CallExp.  */
   1894     if (vd != NULL)
   1895       {
   1896 	if (!vd->isField ())
   1897 	  this->result_ = get_decl_tree (vd);
   1898 	else
   1899 	  {
   1900 	    tree object = build_expr (e->e1);
   1901 	    Type *tb = e->e1->type->toBasetype ();
   1902 
   1903 	    if (tb->ty != TY::Tstruct)
   1904 	      object = build_deref (object);
   1905 
   1906 	    /* __complex is represented as a struct in the front-end, but
   1907 	       underlying is really a complex type.  */
   1908 	    if (e->e1->type->ty == TY::Tenum
   1909 		&& e->e1->type->isTypeEnum ()->sym->isSpecial ())
   1910 	      object = underlying_complex_expr (build_ctype (tb), object);
   1911 
   1912 	    this->result_ = component_ref (object, get_symbol_decl (vd));
   1913 	  }
   1914       }
   1915     else
   1916       {
   1917 	error ("%qs is not a field, but a %qs",
   1918 	       e->var->toChars (), e->var->kind ());
   1919 	this->result_ = error_mark_node;
   1920       }
   1921   }
   1922 
   1923   /* Build an assert expression, used to declare conditions that must hold at
   1924      that a given point in the program.  */
   1925 
   1926   void visit (AssertExp *e)
   1927   {
   1928     Type *tb1 = e->e1->type->toBasetype ();
   1929     tree arg = build_expr (e->e1);
   1930     tree tmsg = NULL_TREE;
   1931     tree assert_pass = void_node;
   1932     tree assert_fail;
   1933 
   1934     if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ())
   1935       {
   1936 	/* Generate: ((bool) e1  ? (void)0 : _d_assert (...))
   1937 		 or: (e1 != null ? e1._invariant() : _d_assert (...))  */
   1938 	bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
   1939 	libcall_fn libcall;
   1940 
   1941 	if (e->msg)
   1942 	  {
   1943 	    tmsg = build_expr_dtor (e->msg);
   1944 	    libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
   1945 	  }
   1946 	else
   1947 	  libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP;
   1948 
   1949 	/* Build a call to _d_assert().  */
   1950 	assert_fail = build_assert_call (e->loc, libcall, tmsg);
   1951 
   1952 	if (global.params.useInvariants == CHECKENABLEon)
   1953 	  {
   1954 	    /* If the condition is a D class or struct object with an invariant,
   1955 	       call it if the condition result is true.  */
   1956 	    if (tb1->ty == TY::Tclass)
   1957 	      {
   1958 		ClassDeclaration *cd = tb1->isClassHandle ();
   1959 		if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
   1960 		  {
   1961 		    arg = d_save_expr (arg);
   1962 		    assert_pass = build_libcall (LIBCALL_INVARIANT,
   1963 						 Type::tvoid, 1, arg);
   1964 		  }
   1965 	      }
   1966 	    else if (tb1->ty == TY::Tpointer
   1967 		     && tb1->nextOf ()->ty == TY::Tstruct)
   1968 	      {
   1969 		StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
   1970 		if (sd->inv != NULL)
   1971 		  {
   1972 		    Expressions args;
   1973 		    arg = d_save_expr (arg);
   1974 		    assert_pass = d_build_call_expr (sd->inv, arg, &args);
   1975 		  }
   1976 	      }
   1977 	  }
   1978       }
   1979     else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
   1980       {
   1981 	/* Generate: __builtin_trap()  */
   1982 	tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
   1983 	assert_fail = build_call_expr (fn, 0);
   1984       }
   1985     else
   1986       {
   1987 	/* Assert contracts are turned off.  */
   1988 	this->result_ = void_node;
   1989 	return;
   1990       }
   1991 
   1992     /* Build condition that we are asserting in this contract.  */
   1993     tree condition = convert_for_condition (arg, e->e1->type);
   1994 
   1995     /* We expect the condition to always be true, as what happens if an assert
   1996        contract is false is undefined behavior.  */
   1997     tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
   1998     tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
   1999     tree pred_type = TREE_VALUE (arg_types);
   2000     tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
   2001 
   2002     condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
   2003 				 build_int_cst (expected_type, 1));
   2004     condition = d_truthvalue_conversion (condition);
   2005 
   2006     this->result_ = build_vcondition (condition, assert_pass, assert_fail);
   2007   }
   2008 
   2009   /* Build a declaration expression.  */
   2010 
   2011   void visit (DeclarationExp *e)
   2012   {
   2013     /* Compile the declaration.  */
   2014     push_stmt_list ();
   2015     build_decl_tree (e->declaration);
   2016     tree result = pop_stmt_list ();
   2017 
   2018     /* Construction of an array for typesafe-variadic function arguments
   2019        can cause an empty STMT_LIST here.  This can causes problems
   2020        during gimplification.  */
   2021     if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
   2022       result = build_empty_stmt (input_location);
   2023 
   2024     this->result_ = result;
   2025   }
   2026 
   2027   /* Build a typeid expression.  Returns an instance of class TypeInfo
   2028      corresponding to.  */
   2029 
   2030   void visit (TypeidExp *e)
   2031   {
   2032     if (Type *tid = isType (e->obj))
   2033       {
   2034 	tree ti = build_typeinfo (e, tid);
   2035 
   2036 	/* If the typeinfo is at an offset.  */
   2037 	if (tid->vtinfo->offset)
   2038 	  ti = build_offset (ti, size_int (tid->vtinfo->offset));
   2039 
   2040 	this->result_ = build_nop (build_ctype (e->type), ti);
   2041       }
   2042     else if (Expression *tid = isExpression (e->obj))
   2043       {
   2044 	Type *type = tid->type->toBasetype ();
   2045 	assert (type->ty == TY::Tclass);
   2046 
   2047 	/* Generate **classptr to get the classinfo.  */
   2048 	tree ci = build_expr (tid);
   2049 	ci = indirect_ref (ptr_type_node, ci);
   2050 	ci = indirect_ref (ptr_type_node, ci);
   2051 
   2052 	/* Add extra indirection for interfaces.  */
   2053 	if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
   2054 	  ci = indirect_ref (ptr_type_node, ci);
   2055 
   2056 	this->result_ = build_nop (build_ctype (e->type), ci);
   2057       }
   2058     else
   2059       gcc_unreachable ();
   2060   }
   2061 
   2062   /* Build a function/lambda expression.  */
   2063 
   2064   void visit (FuncExp *e)
   2065   {
   2066     Type *ftype = e->type->toBasetype ();
   2067 
   2068     /* This check is for lambda's, remove `vthis' as function isn't nested.  */
   2069     if (e->fd->tok == TOK::reserved && ftype->ty == TY::Tpointer)
   2070       {
   2071 	e->fd->tok = TOK::function_;
   2072 	e->fd->vthis = NULL;
   2073       }
   2074 
   2075     /* Compile the function literal body.  */
   2076     build_decl_tree (e->fd);
   2077 
   2078     /* If nested, this will be a trampoline.  */
   2079     if (e->fd->isNested ())
   2080       {
   2081 	tree func = build_address (get_symbol_decl (e->fd));
   2082 	tree object;
   2083 
   2084 	if (this->constp_)
   2085 	  {
   2086 	    /* Static delegate variables have no context pointer.  */
   2087 	    object = null_pointer_node;
   2088 	    this->result_ = build_method_call (func, object, e->fd->type);
   2089 	    TREE_CONSTANT (this->result_) = 1;
   2090 	  }
   2091 	else
   2092 	  {
   2093 	    object = get_frame_for_symbol (e->fd);
   2094 	    this->result_ = build_method_call (func, object, e->fd->type);
   2095 	  }
   2096       }
   2097     else
   2098       {
   2099 	this->result_ = build_nop (build_ctype (e->type),
   2100 				   build_address (get_symbol_decl (e->fd)));
   2101       }
   2102   }
   2103 
   2104   /* Build a halt expression.  */
   2105 
   2106   void visit (HaltExp *)
   2107   {
   2108     /* Should we use trap() or abort()?  */
   2109     tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
   2110     this->result_ = build_call_expr (ttrap, 0);
   2111   }
   2112 
   2113   /* Build a symbol pointer offset expression.  */
   2114 
   2115   void visit (SymOffExp *e)
   2116   {
   2117     /* Build the address and offset of the symbol.  */
   2118     dinteger_t soffset = e->isSymOffExp ()->offset;
   2119     tree result = get_decl_tree (e->var);
   2120     TREE_USED (result) = 1;
   2121 
   2122     if (declaration_reference_p (e->var))
   2123       gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
   2124     else
   2125       result = build_address (result);
   2126 
   2127     if (!soffset)
   2128       result = d_convert (build_ctype (e->type), result);
   2129     else
   2130       {
   2131 	tree offset = size_int (soffset);
   2132 	result = build_nop (build_ctype (e->type),
   2133 			    build_offset (result, offset));
   2134       }
   2135 
   2136     this->result_ = result;
   2137   }
   2138 
   2139   /* Build a variable expression.  */
   2140 
   2141   void visit (VarExp *e)
   2142   {
   2143     if (e->var->needThis ())
   2144       {
   2145 	error ("need %<this%> to access member %qs", e->var->ident->toChars ());
   2146 	this->result_ = error_mark_node;
   2147 	return;
   2148       }
   2149     else if (e->var->ident == Identifier::idPool ("__ctfe"))
   2150       {
   2151 	/* __ctfe is always false at run-time.  */
   2152 	this->result_ = integer_zero_node;
   2153 	return;
   2154       }
   2155 
   2156     /* This check is same as is done in FuncExp for lambdas.  */
   2157     FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
   2158     if (fld != NULL)
   2159       {
   2160 	if (fld->tok == TOK::reserved)
   2161 	  {
   2162 	    fld->tok = TOK::function_;
   2163 	    fld->vthis = NULL;
   2164 	  }
   2165 
   2166 	/* Compiler the function literal body.  */
   2167 	build_decl_tree (fld);
   2168       }
   2169 
   2170     if (this->constp_)
   2171       {
   2172 	/* Want the initializer, not the expression.  */
   2173 	VarDeclaration *var = e->var->isVarDeclaration ();
   2174 	SymbolDeclaration *sdecl = e->var->isSymbolDeclaration ();
   2175 	tree init = NULL_TREE;
   2176 
   2177 	if (var && (var->isConst () || var->isImmutable ())
   2178 	    && e->type->toBasetype ()->ty != TY::Tsarray && var->_init)
   2179 	  {
   2180 	    if (var->inuse)
   2181 	      error_at (make_location_t (e->loc), "recursive reference %qs",
   2182 			e->toChars ());
   2183 	    else
   2184 	      {
   2185 		var->inuse++;
   2186 		init = build_expr (initializerToExpression (var->_init), true);
   2187 		var->inuse--;
   2188 	      }
   2189 	  }
   2190 	else if (sdecl && sdecl->dsym)
   2191 	  {
   2192 	    if (StructDeclaration *sd = sdecl->dsym->isStructDeclaration ())
   2193 	      init = layout_struct_initializer (sd);
   2194 	    else if (ClassDeclaration *cd = sdecl->dsym->isClassDeclaration ())
   2195 	      init = layout_class_initializer (cd);
   2196 	    else
   2197 	      gcc_unreachable ();
   2198 	  }
   2199 	else
   2200 	  error_at (make_location_t (e->loc), "non-constant expression %qs",
   2201 		    e->toChars ());
   2202 
   2203 	if (init != NULL_TREE)
   2204 	  this->result_ = init;
   2205 	else
   2206 	  this->result_ = error_mark_node;
   2207       }
   2208     else
   2209       {
   2210 	tree result = get_decl_tree (e->var);
   2211 	TREE_USED (result) = 1;
   2212 
   2213 	/* The variable expression generated for `__traits(initSymbol)'.  */
   2214 	if (SymbolDeclaration *sd = e->var->isSymbolDeclaration ())
   2215 	  {
   2216 	    if (e->type->isTypeDArray ())
   2217 	      {
   2218 		/* Generate a slice for non-zero initialized aggregates,
   2219 		   otherwise create an empty array.  */
   2220 		gcc_assert (e->type == Type::tvoid->arrayOf ()->constOf ());
   2221 
   2222 		tree type = build_ctype (e->type);
   2223 		tree length = size_int (sd->dsym->structsize);
   2224 		tree ptr = (sd->dsym->isStructDeclaration ()
   2225 			    && sd->dsym->type->isZeroInit (e->loc))
   2226 		  ? null_pointer_node : build_address (result);
   2227 
   2228 		this->result_ = d_array_value (type, length, ptr);
   2229 		return;
   2230 	      }
   2231 	  }
   2232 
   2233 	/* For variables that are references - currently only out/inout
   2234 	   arguments; objects don't count - evaluating the variable means
   2235 	   we want what it refers to.  */
   2236 	if (declaration_reference_p (e->var))
   2237 	  result = indirect_ref (build_ctype (e->var->type), result);
   2238 
   2239 	this->result_ = result;
   2240       }
   2241   }
   2242 
   2243   /* Build a this variable expression.  */
   2244 
   2245   void visit (ThisExp *e)
   2246   {
   2247     FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
   2248     tree result = NULL_TREE;
   2249 
   2250     if (e->var)
   2251       result = get_decl_tree (e->var);
   2252     else
   2253       {
   2254 	gcc_assert (fd && fd->vthis);
   2255 	result = get_decl_tree (fd->vthis);
   2256       }
   2257 
   2258     if (e->type->ty == TY::Tstruct)
   2259       result = build_deref (result);
   2260 
   2261     this->result_ = result;
   2262   }
   2263 
   2264   /* Build a new expression, which allocates memory either on the garbage
   2265      collected heap or by using a class or struct specific allocator.  */
   2266 
   2267   void visit (NewExp *e)
   2268   {
   2269     Type *tb = e->type->toBasetype ();
   2270     tree result;
   2271 
   2272     if (tb->ty == TY::Tclass)
   2273       {
   2274 	/* Allocating a new class.  */
   2275 	tb = e->newtype->toBasetype ();
   2276 
   2277 	ClassDeclaration *cd = tb->isTypeClass ()->sym;
   2278 	tree type = build_ctype (tb);
   2279 	tree setup_exp = NULL_TREE;
   2280 	tree new_call;
   2281 
   2282 	if (e->onstack)
   2283 	  {
   2284 	    /* If being used as an initializer for a local variable with scope
   2285 	       storage class, then the instance is allocated on the stack
   2286 	       rather than the heap or using the class specific allocator.  */
   2287 	    tree var = build_local_temp (TREE_TYPE (type));
   2288 	    new_call = build_nop (type, build_address (var));
   2289 	    setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
   2290 	  }
   2291 	else
   2292 	  {
   2293 	    /* Generate: _d_newclass()  */
   2294 	    tree arg = build_address (get_classinfo_decl (cd));
   2295 	    libcall_fn libcall = (global.params.ehnogc && e->thrownew)
   2296 	      ? LIBCALL_NEWTHROW : LIBCALL_NEWCLASS;
   2297 	    new_call = build_libcall (libcall, tb, 1, arg);
   2298 	  }
   2299 
   2300 	/* Set the context pointer for nested classes.  */
   2301 	if (cd->isNested ())
   2302 	  {
   2303 	    tree field = get_symbol_decl (cd->vthis);
   2304 	    tree value = NULL_TREE;
   2305 
   2306 	    if (e->thisexp)
   2307 	      {
   2308 		ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
   2309 		/* The class or function we're nested in.  */
   2310 		Dsymbol *outer = cd->toParentLocal ();
   2311 
   2312 		value = build_expr (e->thisexp);
   2313 
   2314 		if (outer != tcd)
   2315 		  {
   2316 		    ClassDeclaration *ocd = outer->isClassDeclaration ();
   2317 		    int offset = 0;
   2318 		    gcc_assert (ocd->isBaseOf (tcd, &offset));
   2319 		    /* Could just add offset...  */
   2320 		    value = convert_expr (value, e->thisexp->type, ocd->type);
   2321 		  }
   2322 	      }
   2323 	    else
   2324 	      value = build_vthis (cd);
   2325 
   2326 	    if (value != NULL_TREE)
   2327 	      {
   2328 		/* Generate: (new())->vthis = this;  */
   2329 		new_call = d_save_expr (new_call);
   2330 		field = component_ref (build_deref (new_call), field);
   2331 		setup_exp = compound_expr (setup_exp,
   2332 					   modify_expr (field, value));
   2333 	      }
   2334 	  }
   2335 	new_call = compound_expr (setup_exp, new_call);
   2336 
   2337 	/* Call the class constructor.  */
   2338 	if (e->member)
   2339 	  result = d_build_call_expr (e->member, new_call, e->arguments);
   2340 	else
   2341 	  result = new_call;
   2342 
   2343 	if (e->argprefix)
   2344 	  result = compound_expr (build_expr (e->argprefix), result);
   2345       }
   2346     else if (tb->ty == TY::Tpointer
   2347 	     && tb->nextOf ()->toBasetype ()->ty == TY::Tstruct)
   2348       {
   2349 	/* Allocating memory for a new struct.  */
   2350 	Type *htype = e->newtype->toBasetype ();
   2351 	gcc_assert (!e->onstack);
   2352 
   2353 	TypeStruct *stype = htype->isTypeStruct ();
   2354 	StructDeclaration *sd = stype->sym;
   2355 	tree new_call;
   2356 
   2357 	/* Cannot new an opaque struct.  */
   2358 	if (sd->size (e->loc) == 0)
   2359 	  {
   2360 	    this->result_ = d_convert (build_ctype (e->type),
   2361 				       integer_zero_node);
   2362 	    return;
   2363 	  }
   2364 
   2365 	/* Generate: _d_newitemT()  */
   2366 	libcall_fn libcall = htype->isZeroInit ()
   2367 	  ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
   2368 	tree arg = build_typeinfo (e, e->newtype);
   2369 	new_call = build_libcall (libcall, tb, 1, arg);
   2370 
   2371 	if (e->member || !e->arguments)
   2372 	  {
   2373 	    /* Set the context pointer for nested structs.  */
   2374 	    if (sd->isNested ())
   2375 	      {
   2376 		tree value = build_vthis (sd);
   2377 		tree field = get_symbol_decl (sd->vthis);
   2378 		tree type = build_ctype (stype);
   2379 
   2380 		new_call = d_save_expr (new_call);
   2381 		field = component_ref (indirect_ref (type, new_call), field);
   2382 		new_call = compound_expr (modify_expr (field, value), new_call);
   2383 	      }
   2384 
   2385 	    /* Call the struct constructor.  */
   2386 	    if (e->member)
   2387 	      result = d_build_call_expr (e->member, new_call, e->arguments);
   2388 	    else
   2389 	      result = new_call;
   2390 	  }
   2391 	else
   2392 	  {
   2393 	    /* If we have a user supplied initializer, then set-up with a
   2394 	       struct literal.  */
   2395 	    if (e->arguments != NULL && sd->fields.length != 0)
   2396 	      {
   2397 		StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
   2398 								 e->arguments,
   2399 								 htype);
   2400 		new_call = d_save_expr (new_call);
   2401 		se->type = sd->type;
   2402 		se->sym = new_call;
   2403 		result = compound_expr (build_expr (se), new_call);
   2404 	      }
   2405 	    else
   2406 	      result = new_call;
   2407 	  }
   2408 
   2409 	if (e->argprefix)
   2410 	  result = compound_expr (build_expr (e->argprefix), result);
   2411       }
   2412     else if (tb->ty == TY::Tarray)
   2413       {
   2414 	/* Allocating memory for a new D array.  */
   2415 	tb = e->newtype->toBasetype ();
   2416 	TypeDArray *tarray = tb->isTypeDArray ();
   2417 
   2418 	gcc_assert (e->arguments && e->arguments->length >= 1);
   2419 
   2420 	if (e->arguments->length == 1)
   2421 	  {
   2422 	    /* Single dimension array allocations.  */
   2423 	    Expression *arg = (*e->arguments)[0];
   2424 
   2425 	    if (tarray->next->size () == 0)
   2426 	      {
   2427 		/* Array element size is unknown.  */
   2428 		this->result_ = d_array_value (build_ctype (e->type),
   2429 					       size_int (0), null_pointer_node);
   2430 		return;
   2431 	      }
   2432 
   2433 	    libcall_fn libcall = tarray->next->isZeroInit ()
   2434 	      ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
   2435 	    result = build_libcall (libcall, tb, 2,
   2436 				    build_typeinfo (e, e->type),
   2437 				    build_expr (arg));
   2438 	  }
   2439 	else
   2440 	  {
   2441 	    /* Multidimensional array allocations.  */
   2442 	    tree tarray = make_array_type (Type::tsize_t, e->arguments->length);
   2443 	    tree var = build_local_temp (tarray);
   2444 	    vec <constructor_elt, va_gc> *elms = NULL;
   2445 
   2446 	    /* Get the base element type for the array, generating the
   2447 	       initializer for the dims parameter along the way.  */
   2448 	    Type *telem = e->newtype->toBasetype ();
   2449 	    for (size_t i = 0; i < e->arguments->length; i++)
   2450 	      {
   2451 		Expression *arg = (*e->arguments)[i];
   2452 		CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
   2453 
   2454 		gcc_assert (telem->ty == TY::Tarray);
   2455 		telem = telem->toBasetype ()->nextOf ();
   2456 		gcc_assert (telem);
   2457 	      }
   2458 
   2459 	    /* Initialize the temporary.  */
   2460 	    tree init = modify_expr (var, build_constructor (tarray, elms));
   2461 	    var = compound_expr (init, var);
   2462 
   2463 	    /* Generate: _d_newarraymTX(ti, dims)
   2464 		     or: _d_newarraymiTX(ti, dims)  */
   2465 	    libcall_fn libcall = telem->isZeroInit ()
   2466 	      ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
   2467 
   2468 	    tree tinfo = build_typeinfo (e, e->type);
   2469 	    tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
   2470 				       size_int (e->arguments->length),
   2471 				       build_address (var));
   2472 
   2473 	    result = build_libcall (libcall, tb, 2, tinfo, dims);
   2474 	  }
   2475 
   2476 	if (e->argprefix)
   2477 	  result = compound_expr (build_expr (e->argprefix), result);
   2478       }
   2479     else if (tb->ty == TY::Tpointer)
   2480       {
   2481 	/* Allocating memory for a new pointer.  */
   2482 	TypePointer *tpointer = tb->isTypePointer ();
   2483 
   2484 	if (tpointer->next->size () == 0)
   2485 	  {
   2486 	    /* Pointer element size is unknown.  */
   2487 	    this->result_ = d_convert (build_ctype (e->type),
   2488 				       integer_zero_node);
   2489 	    return;
   2490 	  }
   2491 
   2492 	libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
   2493 	  ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
   2494 
   2495 	tree arg = build_typeinfo (e, e->newtype);
   2496 	result = build_libcall (libcall, tb, 1, arg);
   2497 
   2498 	if (e->arguments && e->arguments->length == 1)
   2499 	  {
   2500 	    result = d_save_expr (result);
   2501 	    tree init = modify_expr (build_deref (result),
   2502 				     build_expr ((*e->arguments)[0]));
   2503 	    result = compound_expr (init, result);
   2504 	  }
   2505 
   2506 	if (e->argprefix)
   2507 	  result = compound_expr (build_expr (e->argprefix), result);
   2508       }
   2509     else
   2510       gcc_unreachable ();
   2511 
   2512     this->result_ = convert_expr (result, tb, e->type);
   2513   }
   2514 
   2515   /* Build an integer literal.  */
   2516 
   2517   void visit (IntegerExp *e)
   2518   {
   2519     tree ctype = build_ctype (e->type->toBasetype ());
   2520     this->result_ = build_integer_cst (e->value, ctype);
   2521   }
   2522 
   2523   /* Build a floating-point literal.  */
   2524 
   2525   void visit (RealExp *e)
   2526   {
   2527     this->result_ = build_float_cst (e->value, e->type->toBasetype ());
   2528   }
   2529 
   2530   /* Build a complex literal.  */
   2531 
   2532   void visit (ComplexExp *e)
   2533   {
   2534     Type *tnext;
   2535 
   2536     switch (e->type->toBasetype ()->ty)
   2537       {
   2538       case TY::Tcomplex32:
   2539 	tnext = (TypeBasic *) Type::tfloat32;
   2540 	break;
   2541 
   2542       case TY::Tcomplex64:
   2543 	tnext = (TypeBasic *) Type::tfloat64;
   2544 	break;
   2545 
   2546       case TY::Tcomplex80:
   2547 	tnext = (TypeBasic *) Type::tfloat80;
   2548 	break;
   2549 
   2550       default:
   2551 	gcc_unreachable ();
   2552       }
   2553 
   2554     this->result_ = build_complex (build_ctype (e->type),
   2555 				   build_float_cst (creall (e->value), tnext),
   2556 				   build_float_cst (cimagl (e->value), tnext));
   2557   }
   2558 
   2559   /* Build a string literal, all strings are null terminated except for
   2560      static arrays.  */
   2561 
   2562   void visit (StringExp *e)
   2563   {
   2564     Type *tb = e->type->toBasetype ();
   2565     tree type = build_ctype (e->type);
   2566 
   2567     if (tb->ty == TY::Tsarray)
   2568       {
   2569 	/* Turn the string into a constructor for the static array.  */
   2570 	vec <constructor_elt, va_gc> *elms = NULL;
   2571 	vec_safe_reserve (elms, e->len);
   2572 	tree etype = TREE_TYPE (type);
   2573 
   2574 	for (size_t i = 0; i < e->len; i++)
   2575 	  {
   2576 	    tree value = build_integer_cst (e->getCodeUnit (i), etype);
   2577 	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
   2578 	  }
   2579 
   2580 	tree ctor = build_constructor (type, elms);
   2581 	TREE_CONSTANT (ctor) = 1;
   2582 	this->result_ = ctor;
   2583       }
   2584     else
   2585       {
   2586 	/* Copy the string contents to a null terminated string.  */
   2587 	dinteger_t length = (e->len * e->sz);
   2588 	char *string = XALLOCAVEC (char, length + 1);
   2589 	if (length > 0)
   2590 	  memcpy (string, e->string, length);
   2591 	string[length] = '\0';
   2592 
   2593 	/* String value and type includes the null terminator.  */
   2594 	tree value = build_string (length, string);
   2595 	TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
   2596 	value = build_address (value);
   2597 
   2598 	if (tb->ty == TY::Tarray)
   2599 	  value = d_array_value (type, size_int (e->len), value);
   2600 
   2601 	TREE_CONSTANT (value) = 1;
   2602 	this->result_ = d_convert (type, value);
   2603       }
   2604   }
   2605 
   2606   /* Build a tuple literal.  Just an argument list that may have
   2607      side effects that need evaluation.  */
   2608 
   2609   void visit (TupleExp *e)
   2610   {
   2611     tree result = NULL_TREE;
   2612 
   2613     if (e->e0)
   2614       result = build_expr (e->e0, this->constp_, true);
   2615 
   2616     for (size_t i = 0; i < e->exps->length; ++i)
   2617       {
   2618 	Expression *exp = (*e->exps)[i];
   2619 	result = compound_expr (result, build_expr (exp, this->constp_, true));
   2620       }
   2621 
   2622     if (result == NULL_TREE)
   2623       result = void_node;
   2624 
   2625     this->result_ = result;
   2626   }
   2627 
   2628   /* Build an array literal.  The common type of the all elements is taken to
   2629      be the type of the array element, and all elements are implicitly
   2630      converted to that type.  */
   2631 
   2632   void visit (ArrayLiteralExp *e)
   2633   {
   2634     Type *tb = e->type->toBasetype ();
   2635 
   2636     /* Implicitly convert void[n] to ubyte[n].  */
   2637     if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid)
   2638       tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());
   2639 
   2640     gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray
   2641 		|| tb->ty == TY::Tpointer);
   2642 
   2643     /* Handle empty array literals.  */
   2644     if (e->elements->length == 0)
   2645       {
   2646 	if (tb->ty == TY::Tarray)
   2647 	  this->result_ = d_array_value (build_ctype (e->type),
   2648 					 size_int (0), null_pointer_node);
   2649 	else
   2650 	  this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
   2651 					     NULL);
   2652 
   2653 	return;
   2654       }
   2655 
   2656     /* Build an expression that assigns the expressions in ELEMENTS to
   2657        a constructor.  */
   2658     vec <constructor_elt, va_gc> *elms = NULL;
   2659     vec_safe_reserve (elms, e->elements->length);
   2660     bool constant_p = true;
   2661     tree saved_elems = NULL_TREE;
   2662 
   2663     Type *etype = tb->nextOf ();
   2664     tree satype = make_array_type (etype, e->elements->length);
   2665 
   2666     for (size_t i = 0; i < e->elements->length; i++)
   2667       {
   2668 	Expression *expr = e->getElement (i);
   2669 	tree value = build_expr (expr, this->constp_, true);
   2670 
   2671 	/* Only append nonzero values, the backend will zero out the rest
   2672 	   of the constructor as we don't set CONSTRUCTOR_NO_CLEARING.  */
   2673 	if (!initializer_zerop (value))
   2674 	  {
   2675 	    if (!TREE_CONSTANT (value))
   2676 	      constant_p = false;
   2677 
   2678 	    /* Split construction of values out of the constructor if there
   2679 	       may be side effects.  */
   2680 	    tree init = stabilize_expr (&value);
   2681 	    if (init != NULL_TREE)
   2682 	      saved_elems = compound_expr (saved_elems, init);
   2683 
   2684 	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
   2685 				    convert_expr (value, expr->type, etype));
   2686 	  }
   2687       }
   2688 
   2689     /* Now return the constructor as the correct type.  For static arrays there
   2690        is nothing else to do.  For dynamic arrays, return a two field struct.
   2691        For pointers, return the address.  */
   2692     tree ctor = build_constructor (satype, elms);
   2693     tree type = build_ctype (e->type);
   2694 
   2695     /* Nothing else to do for static arrays.  */
   2696     if (tb->ty == TY::Tsarray || this->constp_)
   2697       {
   2698 	/* Can't take the address of the constructor, so create an anonymous
   2699 	   static symbol, and then refer to it.  */
   2700 	if (tb->ty != TY::Tsarray)
   2701 	  {
   2702 	    tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
   2703 	    ctor = build_address (decl);
   2704 	    if (tb->ty == TY::Tarray)
   2705 	      ctor = d_array_value (type, size_int (e->elements->length), ctor);
   2706 
   2707 	    /* Immutable literals can be placed in rodata.  */
   2708 	    if (tb->isImmutable ())
   2709 	      TREE_READONLY (decl) = 1;
   2710 
   2711 	    d_pushdecl (decl);
   2712 	    rest_of_decl_compilation (decl, 1, 0);
   2713 	  }
   2714 
   2715 	/* If the array literal is readonly or static.  */
   2716 	if (constant_p)
   2717 	  TREE_CONSTANT (ctor) = 1;
   2718 	if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
   2719 	  TREE_STATIC (ctor) = 1;
   2720 
   2721 	/* Use memset to fill any alignment holes in the array.  */
   2722 	if (!this->constp_ && !this->literalp_)
   2723 	  {
   2724 	    TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
   2725 
   2726 	    if (ts != NULL && (!identity_compare_p (ts->sym)
   2727 			       || ts->sym->isUnionDeclaration ()))
   2728 	      {
   2729 		tree var = build_local_temp (TREE_TYPE (ctor));
   2730 		tree init = build_memset_call (var);
   2731 		/* Evaluate memset() first, then any saved elements.  */
   2732 		saved_elems = compound_expr (init, saved_elems);
   2733 		ctor = compound_expr (modify_expr (var, ctor), var);
   2734 	      }
   2735 	  }
   2736 
   2737 	this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
   2738       }
   2739     else
   2740       {
   2741 	/* Allocate space on the memory managed heap.  */
   2742 	tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
   2743 				  etype->pointerTo (), 2,
   2744 				  build_typeinfo (e, etype->arrayOf ()),
   2745 				  size_int (e->elements->length));
   2746 	mem = d_save_expr (mem);
   2747 
   2748 	/* Now copy the constructor into memory.  */
   2749 	tree size = size_mult_expr (size_int (e->elements->length),
   2750 				    size_int (tb->nextOf ()->size ()));
   2751 
   2752 	tree result = build_memcpy_call (mem, build_address (ctor), size);
   2753 
   2754 	/* Return the array pointed to by MEM.  */
   2755 	result = compound_expr (result, mem);
   2756 
   2757 	if (tb->ty == TY::Tarray)
   2758 	  result = d_array_value (type, size_int (e->elements->length), result);
   2759 
   2760 	this->result_ = compound_expr (saved_elems, result);
   2761       }
   2762   }
   2763 
   2764   /* Build an associative array literal.  The common type of the all keys is
   2765      taken to be the key type, and common type of all values the value type.
   2766      All keys and values are then implicitly converted as needed.  */
   2767 
   2768   void visit (AssocArrayLiteralExp *e)
   2769   {
   2770     /* Want the mutable type for typeinfo reference.  */
   2771     Type *tb = e->type->toBasetype ()->mutableOf ();
   2772 
   2773     /* Handle empty assoc array literals.  */
   2774     TypeAArray *ta = tb->isTypeAArray ();
   2775     if (e->keys->length == 0)
   2776       {
   2777 	this->result_ = build_constructor (build_ctype (ta), NULL);
   2778 	return;
   2779       }
   2780 
   2781     /* Build an expression that assigns all expressions in KEYS
   2782        to a constructor.  */
   2783     tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
   2784 					 e->keys, this->constp_);
   2785     tree init = stabilize_expr (&akeys);
   2786 
   2787     /* Do the same with all expressions in VALUES.  */
   2788     tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
   2789 					 e->values, this->constp_);
   2790     init = compound_expr (init, stabilize_expr (&avals));
   2791 
   2792     /* Generate: _d_assocarrayliteralTX (ti, keys, vals);  */
   2793     tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
   2794 			       size_int (e->keys->length),
   2795 			       build_address (akeys));
   2796     tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
   2797 			       size_int (e->values->length),
   2798 			       build_address (avals));
   2799 
   2800     tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
   2801 			      build_typeinfo (e, ta), keys, vals);
   2802 
   2803     /* Return an associative array pointed to by MEM.  */
   2804     tree aatype = build_ctype (ta);
   2805     vec <constructor_elt, va_gc> *ce = NULL;
   2806     CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
   2807 
   2808     tree result = build_nop (build_ctype (e->type),
   2809 			     build_constructor (aatype, ce));
   2810     this->result_ = compound_expr (init, result);
   2811   }
   2812 
   2813   /* Build a struct literal.  */
   2814 
   2815   void visit (StructLiteralExp *e)
   2816   {
   2817     /* Handle empty struct literals.  */
   2818     if (e->elements == NULL || e->sd->fields.length == 0)
   2819       {
   2820 	this->result_ = build_constructor (build_ctype (e->type), NULL);
   2821 	return;
   2822       }
   2823 
   2824     /* Building sinit trees are delayed until after frontend semantic
   2825        processing has complete.  Build the static initializer now.  */
   2826     if (e->useStaticInit && !this->constp_)
   2827       {
   2828 	tree init = aggregate_initializer_decl (e->sd);
   2829 
   2830 	/* If initializing a symbol, don't forget to set it.  */
   2831 	if (e->sym != NULL)
   2832 	  {
   2833 	    tree var = build_deref (e->sym);
   2834 	    init = compound_expr (modify_expr (var, init), var);
   2835 	  }
   2836 
   2837 	this->result_ = init;
   2838 	return;
   2839       }
   2840 
   2841     /* Build a constructor that assigns the expressions in ELEMENTS
   2842        at each field index that has been filled in.  */
   2843     vec <constructor_elt, va_gc> *ve = NULL;
   2844     tree saved_elems = NULL_TREE;
   2845 
   2846     /* CTFE may fill the hidden pointer by NullExp.  */
   2847     gcc_assert (e->elements->length <= e->sd->fields.length);
   2848 
   2849     Type *tb = e->type->toBasetype ();
   2850     gcc_assert (tb->ty == TY::Tstruct);
   2851 
   2852     for (size_t i = 0; i < e->elements->length; i++)
   2853       {
   2854 	Expression *exp = (*e->elements)[i];
   2855 	if (!exp)
   2856 	  continue;
   2857 
   2858 	VarDeclaration *field = e->sd->fields[i];
   2859 	Type *type = exp->type->toBasetype ();
   2860 	Type *ftype = field->type->toBasetype ();
   2861 	tree value = NULL_TREE;
   2862 
   2863 	if (ftype->ty == TY::Tsarray && !same_type_p (type, ftype))
   2864 	  {
   2865 	    /* Initialize a static array with a single element.  */
   2866 	    tree elem = build_expr (exp, this->constp_, true);
   2867 	    saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
   2868 	    elem = d_save_expr (elem);
   2869 
   2870 	    if (initializer_zerop (elem))
   2871 	      value = build_constructor (build_ctype (ftype), NULL);
   2872 	    else
   2873 	      value = build_array_from_val (ftype, elem);
   2874 	  }
   2875 	else
   2876 	  {
   2877 	    value = convert_expr (build_expr (exp, this->constp_, true),
   2878 				  exp->type, field->type);
   2879 	  }
   2880 
   2881 	/* Split construction of values out of the constructor.  */
   2882 	saved_elems = compound_expr (saved_elems, stabilize_expr (&value));
   2883 
   2884 	CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
   2885       }
   2886 
   2887     /* Maybe setup hidden pointer to outer scope context.  */
   2888     if (e->sd->isNested () && e->elements->length != e->sd->fields.length
   2889 	&& this->constp_ == false)
   2890       {
   2891 	tree field = get_symbol_decl (e->sd->vthis);
   2892 	tree value = build_vthis (e->sd);
   2893 	CONSTRUCTOR_APPEND_ELT (ve, field, value);
   2894 	gcc_assert (e->useStaticInit == false);
   2895       }
   2896 
   2897     /* Build a constructor in the correct shape of the aggregate type.  */
   2898     tree ctor = build_struct_literal (build_ctype (e->type), ve);
   2899 
   2900     /* Nothing more to do for constant literals.  */
   2901     if (this->constp_)
   2902       {
   2903 	/* If the struct literal is a valid for static data.  */
   2904 	if (TREE_CONSTANT (ctor)
   2905 	    && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
   2906 	  TREE_STATIC (ctor) = 1;
   2907 
   2908 	this->result_ = compound_expr (saved_elems, ctor);
   2909 	return;
   2910       }
   2911 
   2912     /* Construct the struct literal for run-time.  */
   2913     if (e->sym != NULL)
   2914       {
   2915 	/* Store the result in a symbol to initialize the literal.  */
   2916 	tree var = build_deref (e->sym);
   2917 	ctor = compound_expr (modify_expr (var, ctor), var);
   2918       }
   2919     else if (!this->literalp_)
   2920       {
   2921 	/* Use memset to fill any alignment holes in the object.  */
   2922 	if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
   2923 	  {
   2924 	    tree var = build_local_temp (TREE_TYPE (ctor));
   2925 	    tree init = build_memset_call (var);
   2926 	    /* Evaluate memset() first, then any saved element constructors.  */
   2927 	    saved_elems = compound_expr (init, saved_elems);
   2928 	    ctor = compound_expr (modify_expr (var, ctor), var);
   2929 	  }
   2930       }
   2931 
   2932     this->result_ = compound_expr (saved_elems, ctor);
   2933   }
   2934 
   2935   /* Build a null literal.  */
   2936 
   2937   void visit (NullExp *e)
   2938   {
   2939     this->result_ = build_typeof_null_value (e->type);
   2940   }
   2941 
   2942   /* Build a vector literal.  */
   2943 
   2944   void visit (VectorExp *e)
   2945   {
   2946     /* First handle array literal expressions.  */
   2947     if (e->e1->op == EXP::arrayLiteral)
   2948       {
   2949 	ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
   2950 	vec <constructor_elt, va_gc> *elms = NULL;
   2951 	bool constant_p = true;
   2952 	tree type = build_ctype (e->type);
   2953 
   2954 	vec_safe_reserve (elms, ale->elements->length);
   2955 	for (size_t i = 0; i < ale->elements->length; i++)
   2956 	  {
   2957 	    Expression *expr = ale->getElement (i);
   2958 	    tree value = d_convert (TREE_TYPE (type),
   2959 				    build_expr (expr, this->constp_, true));
   2960 	    if (!CONSTANT_CLASS_P (value))
   2961 	      constant_p = false;
   2962 
   2963 	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
   2964 	  }
   2965 
   2966 	/* Build a VECTOR_CST from a constant vector constructor.  */
   2967 	if (constant_p)
   2968 	  this->result_ = build_vector_from_ctor (type, elms);
   2969 	else
   2970 	  this->result_ = build_constructor (type, elms);
   2971       }
   2972     else if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
   2973       {
   2974 	/* Build a vector representation from a static array.  */
   2975 	this->result_ = convert_expr (build_expr (e->e1, this->constp_),
   2976 				      e->e1->type, e->type);
   2977       }
   2978     else
   2979       {
   2980 	/* Build constructor from single value.  */
   2981 	tree type = build_ctype (e->type);
   2982 	tree value = d_convert (TREE_TYPE (type),
   2983 				build_expr (e->e1, this->constp_, true));
   2984 	this->result_ = build_vector_from_val (type, value);
   2985       }
   2986   }
   2987 
   2988   /* Build a static array representation of a vector expression.  */
   2989 
   2990   void visit (VectorArrayExp *e)
   2991   {
   2992     this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
   2993 				  e->e1->type, e->type);
   2994   }
   2995 
   2996   /* Build a static class literal, return its reference.  */
   2997 
   2998   void visit (ClassReferenceExp *e)
   2999   {
   3000     /* The result of build_new_class_expr is a RECORD_TYPE, we want
   3001        the reference.  */
   3002     tree var = build_address (build_new_class_expr (e));
   3003 
   3004     /* If the type of this literal is an interface, the we must add the
   3005        interface offset to symbol.  */
   3006     if (this->constp_)
   3007       {
   3008 	TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
   3009 	InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
   3010 
   3011 	if (to != NULL)
   3012 	  {
   3013 	    ClassDeclaration *from = e->originalClass ();
   3014 	    int offset = 0;
   3015 
   3016 	    gcc_assert (to->isBaseOf (from, &offset) != 0);
   3017 
   3018 	    if (offset != 0)
   3019 	      var = build_offset (var, size_int (offset));
   3020 	  }
   3021       }
   3022 
   3023     this->result_ = var;
   3024   }
   3025 
   3026   /* Build an uninitialized value, generated from void initializers.  */
   3027 
   3028   void visit (VoidInitExp *e)
   3029   {
   3030     /* The front-end only generates these for the initializer of globals.
   3031        Represent `void' as zeroes, regardless of the type's default value.  */
   3032     gcc_assert (this->constp_);
   3033     this->result_ = build_zero_cst (build_ctype (e->type));
   3034   }
   3035 
   3036   /* These expressions are mainly just a placeholders in the frontend.
   3037      We shouldn't see them here.  */
   3038 
   3039   void visit (ScopeExp *e)
   3040   {
   3041     error_at (make_location_t (e->loc), "%qs is not an expression",
   3042 	      e->toChars ());
   3043     this->result_ = error_mark_node;
   3044   }
   3045 
   3046   void visit (TypeExp *e)
   3047   {
   3048     error_at (make_location_t (e->loc), "type %qs is not an expression",
   3049 	      e->toChars ());
   3050     this->result_ = error_mark_node;
   3051   }
   3052 };
   3053 
   3054 
   3055 /* Main entry point for ExprVisitor interface to generate code for
   3056    the Expression AST class E.  If CONST_P is true, then E is a
   3057    constant expression.  If LITERAL_P is true, then E is a value used
   3058    in the initialization of another literal.  */
   3059 
   3060 tree
   3061 build_expr (Expression *e, bool const_p, bool literal_p)
   3062 {
   3063   ExprVisitor v = ExprVisitor (const_p, literal_p);
   3064   location_t saved_location = input_location;
   3065 
   3066   input_location = make_location_t (e->loc);
   3067   e->accept (&v);
   3068   tree expr = v.result ();
   3069   input_location = saved_location;
   3070 
   3071   /* Check if initializer expression is valid constant.  */
   3072   if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
   3073     {
   3074       error_at (make_location_t (e->loc), "non-constant expression %qs",
   3075 		e->toChars ());
   3076       return error_mark_node;
   3077     }
   3078 
   3079   return expr;
   3080 }
   3081 
   3082 /* Same as build_expr, but also calls destructors on any temporaries.  */
   3083 
   3084 tree
   3085 build_expr_dtor (Expression *e)
   3086 {
   3087   /* Codegen can be improved by determining if no exceptions can be thrown
   3088      between the ctor and dtor, and eliminating the ctor and dtor.  */
   3089   size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
   3090   tree result = build_expr (e);
   3091 
   3092   if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
   3093     {
   3094       result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
   3095       vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
   3096     }
   3097 
   3098   return result;
   3099 }
   3100 
   3101 /* Same as build_expr_dtor, but handles the result of E as a return value.  */
   3102 
   3103 tree
   3104 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
   3105 {
   3106   size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
   3107   tree result = build_expr (e);
   3108 
   3109   /* Convert for initializing the DECL_RESULT.  */
   3110   if (tf->isref ())
   3111     {
   3112       /* If we are returning a reference, take the address.  */
   3113       result = convert_expr (result, e->type, type);
   3114       result = build_address (result);
   3115     }
   3116   else
   3117     result = convert_for_rvalue (result, e->type, type);
   3118 
   3119   /* The decl to store the return expression.  */
   3120   tree decl = DECL_RESULT (cfun->decl);
   3121 
   3122   /* Split comma expressions, so that the result is returned directly.  */
   3123   tree expr = stabilize_expr (&result);
   3124   result = build_assign (INIT_EXPR, decl, result);
   3125   result = compound_expr (expr, return_expr (result));
   3126 
   3127   /* May nest the return expression inside the try/finally expression.  */
   3128   if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
   3129     {
   3130       result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
   3131       vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
   3132     }
   3133 
   3134   return result;
   3135 }
   3136 
   3137