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