1 /* expr.cc -- Lower D frontend expressions to GCC trees.
2    Copyright (C) 2015-2020 Free Software Foundation, Inc.
3 
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8 
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3.  If not see
16 <http://www.gnu.org/licenses/>.  */
17 
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
21 
22 #include "dmd/aggregate.h"
23 #include "dmd/ctfe.h"
24 #include "dmd/declaration.h"
25 #include "dmd/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 
52 class 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 
needs_postblit(Type * t)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 
needs_dtor(Type * t)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 
lvalue_p(Expression * e)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 
binary_op(tree_code code,tree type,tree arg0,tree arg1)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 = fold_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 
binop_assignment(tree_code code,Expression * e1,Expression * e2)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 
218 public:
ExprVisitor(bool constp)219   ExprVisitor (bool constp)
220   {
221     this->result_ = NULL_TREE;
222     this->constp_ = constp;
223   }
224 
result(void)225   tree result (void)
226   {
227     return this->result_;
228   }
229 
230   /* Visitor interfaces, each Expression class should have
231      overridden the default.  */
232 
visit(Expression *)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 
visit(CondExp * e)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 
visit(IdentityExp * e)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 
visit(EqualExp * e)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 
visit(InExp * e)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 
visit(CmpExp * e)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 
visit(AndAndExp * e)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 
visit(OrOrExp * e)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 
visit(BinExp * e)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 
visit(CatExp * e)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 
visit(BinAssignExp * e)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 
visit(CatAssignExp * e)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     if (tb1->ty == Tarray && tb2->ty == Tdchar
842 	&& (etype->ty == Tchar || etype->ty == Twchar))
843       {
844 	/* Append a dchar to a char[] or wchar[]  */
845 	libcall_fn libcall = (etype->ty == Tchar)
846 	  ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
847 
848 	this->result_ = build_libcall (libcall, e->type, 2,
849 				       build_address (build_expr (e->e1)),
850 				       build_expr (e->e2));
851       }
852     else
853       {
854 	gcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray);
855 
856 	tree tinfo = build_typeinfo (e->loc, e->type);
857 	tree ptr = build_address (build_expr (e->e1));
858 
859 	if ((tb2->ty == Tarray || tb2->ty == Tsarray)
860 	    && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
861 	  {
862 	    /* Append an array.  */
863 	    this->result_ = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
864 					   tinfo, ptr, d_array_convert (e->e2));
865 
866 	  }
867 	else if (same_type_p (etype, tb2))
868 	  {
869 	    /* Append an element.  */
870 	    tree result = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
871 					 tinfo, ptr, size_one_node);
872 	    result = d_save_expr (result);
873 
874 	    /* Assign e2 to last element.  */
875 	    tree offexp = d_array_length (result);
876 	    offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
877 			     offexp, size_one_node);
878 	    offexp = d_save_expr (offexp);
879 
880 	    tree ptrexp = d_array_ptr (result);
881 	    ptrexp = void_okay_p (ptrexp);
882 	    ptrexp = build_array_index (ptrexp, offexp);
883 
884 	    /* Evaluate expression before appending.  */
885 	    tree t2 = build_expr (e->e2);
886 	    tree expr = stabilize_expr (&t2);
887 
888 	    t2 = d_save_expr (t2);
889 	    result = modify_expr (build_deref (ptrexp), t2);
890 	    result = compound_expr (t2, result);
891 
892 	    this->result_ = compound_expr (expr, result);
893 	  }
894 	else
895 	  gcc_unreachable ();
896       }
897   }
898 
899   /* Build an assignment expression.  The right operand is implicitly
900      converted to the type of the left operand, and assigned to it.  */
901 
visit(AssignExp * e)902   void visit (AssignExp *e)
903   {
904     /* First, handle special assignment semantics.  */
905 
906     /* Look for array.length = n;  */
907     if (e->e1->op == TOKarraylength)
908       {
909 	/* Assignment to an array's length property; resize the array.  */
910 	ArrayLengthExp *ale = (ArrayLengthExp *) e->e1;
911 	tree newlength = convert_expr (build_expr (e->e2), e->e2->type,
912 				       Type::tsize_t);
913 	tree ptr = build_address (build_expr (ale->e1));
914 
915 	/* Don't want the basetype for the element type.  */
916 	Type *etype = ale->e1->type->toBasetype ()->nextOf ();
917 	libcall_fn libcall = etype->isZeroInit ()
918 	  ? LIBCALL_ARRAYSETLENGTHT : LIBCALL_ARRAYSETLENGTHIT;
919 
920 	tree result = build_libcall (libcall, ale->e1->type, 3,
921 				     build_typeinfo (ale->loc, ale->e1->type),
922 				     newlength, ptr);
923 
924 	this->result_ = d_array_length (result);
925 	return;
926       }
927 
928     /* Look for array[] = n;  */
929     if (e->e1->op == TOKslice)
930       {
931 	SliceExp *se = (SliceExp *) e->e1;
932 	Type *stype = se->e1->type->toBasetype ();
933 	Type *etype = stype->nextOf ()->toBasetype ();
934 
935 	/* Determine if we need to run postblit or dtor.  */
936 	bool postblit = this->needs_postblit (etype) && this->lvalue_p (e->e2);
937 	bool destructor = this->needs_dtor (etype);
938 
939 	if (e->memset & blockAssign)
940 	  {
941 	    /* Set a range of elements to one value.  */
942 	    tree t1 = d_save_expr (build_expr (e->e1));
943 	    tree t2 = build_expr (e->e2);
944 	    tree result;
945 
946 	    if ((postblit || destructor) && e->op != TOKblit)
947 	      {
948 		libcall_fn libcall = (e->op == TOKconstruct)
949 		  ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN;
950 		/* So we can call postblits on const/immutable objects.  */
951 		Type *tm = etype->unSharedOf ()->mutableOf ();
952 		tree ti = build_typeinfo (e->loc, tm);
953 
954 		tree result = build_libcall (libcall, Type::tvoid, 4,
955 					     d_array_ptr (t1),
956 					     build_address (t2),
957 					     d_array_length (t1), ti);
958 		this->result_ = compound_expr (result, t1);
959 		return;
960 	      }
961 
962 	    if (integer_zerop (t2))
963 	      {
964 		tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
965 		tree size = size_mult_expr (d_array_length (t1),
966 					    size_int (etype->size ()));
967 
968 		result = build_call_expr (tmemset, 3, d_array_ptr (t1),
969 					  integer_zero_node, size);
970 	      }
971 	    else
972 	      result = build_array_set (d_array_ptr (t1),
973 					d_array_length (t1), t2);
974 
975 	    this->result_ = compound_expr (result, t1);
976 	  }
977 	else
978 	  {
979 	    /* Perform a memcpy operation.  */
980 	    gcc_assert (e->e2->type->ty != Tpointer);
981 
982 	    if (!postblit && !destructor && !array_bounds_check ())
983 	      {
984 		tree t1 = d_save_expr (d_array_convert (e->e1));
985 		tree t2 = d_array_convert (e->e2);
986 		tree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);
987 		tree size = size_mult_expr (d_array_length (t1),
988 					    size_int (etype->size ()));
989 
990 		tree result = build_call_expr (tmemcpy, 3, d_array_ptr (t1),
991 					       d_array_ptr (t2), size);
992 		this->result_ = compound_expr (result, t1);
993 	      }
994 	    else if ((postblit || destructor) && e->op != TOKblit)
995 	      {
996 		/* Generate: _d_arrayassign(ti, from, to)
997 			 or: _d_arrayctor(ti, from, to)  */
998 		libcall_fn libcall = (e->op == TOKconstruct)
999 		  ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN;
1000 
1001 		this->result_ = build_libcall (libcall, e->type, 3,
1002 					       build_typeinfo (e->loc, etype),
1003 					       d_array_convert (e->e2),
1004 					       d_array_convert (e->e1));
1005 	      }
1006 	    else
1007 	      {
1008 		/* Generate: _d_arraycopy()  */
1009 		this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
1010 					       size_int (etype->size ()),
1011 					       d_array_convert (e->e2),
1012 					       d_array_convert (e->e1));
1013 	      }
1014 	  }
1015 
1016 	return;
1017       }
1018 
1019     /* Look for reference initializations.  */
1020     if (e->memset & referenceInit)
1021       {
1022 	gcc_assert (e->op == TOKconstruct || e->op == TOKblit);
1023 	gcc_assert (e->e1->op == TOKvar);
1024 
1025 	Declaration *decl = ((VarExp *) e->e1)->var;
1026 	if (decl->storage_class & (STCout | STCref))
1027 	  {
1028 	    tree t2 = convert_for_assignment (build_expr (e->e2),
1029 					      e->e2->type, e->e1->type);
1030 	    tree t1 = build_expr (e->e1);
1031 	    /* Want reference to lhs, not indirect ref.  */
1032 	    t1 = TREE_OPERAND (t1, 0);
1033 	    t2 = build_address (t2);
1034 
1035 	    this->result_ = indirect_ref (build_ctype (e->type),
1036 					  build_assign (INIT_EXPR, t1, t2));
1037 	    return;
1038 	  }
1039       }
1040 
1041     /* Other types of assignments that may require post construction.  */
1042     Type *tb1 = e->e1->type->toBasetype ();
1043     tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR;
1044 
1045     /* Look for struct assignment.  */
1046     if (tb1->ty == Tstruct)
1047       {
1048 	tree t1 = build_expr (e->e1);
1049 	tree t2 = convert_for_assignment (build_expr (e->e2),
1050 					  e->e2->type, e->e1->type);
1051 	StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
1052 
1053 	/* Look for struct = 0.  */
1054 	if (e->e2->op == TOKint64)
1055 	  {
1056 	    /* Use memset to fill struct.  */
1057 	    gcc_assert (e->op == TOKblit);
1058 	    tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1059 	    tree result = build_call_expr (tmemset, 3, build_address (t1),
1060 					   t2, size_int (sd->structsize));
1061 
1062 	    /* Maybe set-up hidden pointer to outer scope context.  */
1063 	    if (sd->isNested ())
1064 	      {
1065 		tree field = get_symbol_decl (sd->vthis);
1066 		tree value = build_vthis (sd);
1067 
1068 		tree vthis_exp = modify_expr (component_ref (t1, field), value);
1069 		result = compound_expr (result, vthis_exp);
1070 	      }
1071 
1072 	    this->result_ = compound_expr (result, t1);
1073 	  }
1074 	else
1075 	  {
1076 	    /* Simple struct literal assignment.  */
1077 	    tree init = NULL_TREE;
1078 
1079 	    /* Fill any alignment holes in the struct using memset.  */
1080 	    if (e->op == TOKconstruct && !identity_compare_p (sd))
1081 	      {
1082 		tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1083 		init = build_call_expr (tmemset, 3, build_address (t1),
1084 					integer_zero_node,
1085 					size_int (sd->structsize));
1086 	      }
1087 
1088 	    tree result = build_assign (modifycode, t1, t2);
1089 	    this->result_ = compound_expr (init, result);
1090 	  }
1091 
1092 	return;
1093       }
1094 
1095     /* Look for static array assignment.  */
1096     if (tb1->ty == Tsarray)
1097       {
1098 	/* Look for array = 0.  */
1099 	if (e->e2->op == TOKint64)
1100 	  {
1101 	    /* Use memset to fill the array.  */
1102 	    gcc_assert (e->op == TOKblit);
1103 
1104 	    tree t1 = build_expr (e->e1);
1105 	    tree t2 = convert_for_assignment (build_expr (e->e2),
1106 					      e->e2->type, e->e1->type);
1107 	    tree size = size_int (e->e1->type->size ());
1108 
1109 	    tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1110 	    this->result_ = build_call_expr (tmemset, 3, build_address (t1),
1111 					     t2, size);
1112 	    return;
1113 	  }
1114 
1115 	Type *etype = tb1->nextOf ();
1116 	gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);
1117 
1118 	/* Determine if we need to run postblit.  */
1119 	bool postblit = this->needs_postblit (etype);
1120 	bool destructor = this->needs_dtor (etype);
1121 	bool lvalue_p = this->lvalue_p (e->e2);
1122 
1123 	/* Even if the elements in rhs are all rvalues and don't have
1124 	   to call postblits, this assignment should call dtors on old
1125 	   assigned elements.  */
1126 	if ((!postblit && !destructor)
1127 	    || (e->op == TOKconstruct && !lvalue_p && postblit)
1128 	    || (e->op == TOKblit || e->e1->type->size () == 0))
1129 	  {
1130 	    tree t1 = build_expr (e->e1);
1131 	    tree t2 = convert_for_assignment (build_expr (e->e2),
1132 					      e->e2->type, e->e1->type);
1133 
1134 	    this->result_ = build_assign (modifycode, t1, t2);
1135 	    return;
1136 	  }
1137 
1138 	Type *arrtype = (e->type->ty == Tsarray) ? etype->arrayOf () : e->type;
1139 	tree result;
1140 
1141 	if (e->op == TOKconstruct)
1142 	  {
1143 	    /* Generate: _d_arrayctor(ti, from, to)  */
1144 	    result = build_libcall (LIBCALL_ARRAYCTOR, arrtype, 3,
1145 				    build_typeinfo (e->loc, etype),
1146 				    d_array_convert (e->e2),
1147 				    d_array_convert (e->e1));
1148 	  }
1149 	else
1150 	  {
1151 	    /* Generate: _d_arrayassign_l()
1152 		     or: _d_arrayassign_r()  */
1153 	    libcall_fn libcall = (lvalue_p)
1154 	      ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
1155 	    tree elembuf = build_local_temp (build_ctype (etype));
1156 
1157 	    result = build_libcall (libcall, arrtype, 4,
1158 				    build_typeinfo (e->loc, etype),
1159 				    d_array_convert (e->e2),
1160 				    d_array_convert (e->e1),
1161 				    build_address (elembuf));
1162 	  }
1163 
1164 	/* Cast the libcall result back to a static array.  */
1165 	if (e->type->ty == Tsarray)
1166 	  result = indirect_ref (build_ctype (e->type),
1167 				 d_array_ptr (result));
1168 
1169 	this->result_ = result;
1170 	return;
1171       }
1172 
1173     /* Simple assignment.  */
1174     tree t1 = build_expr (e->e1);
1175     tree t2 = convert_for_assignment (build_expr (e->e2),
1176 				      e->e2->type, e->e1->type);
1177 
1178     this->result_ = build_assign (modifycode, t1, t2);
1179   }
1180 
1181   /* Build a postfix expression.  */
1182 
visit(PostExp * e)1183   void visit (PostExp *e)
1184   {
1185     tree result;
1186 
1187     if (e->op == TOKplusplus)
1188       {
1189 	result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1190 			 build_expr (e->e1), build_expr (e->e2));
1191       }
1192     else if (e->op == TOKminusminus)
1193       {
1194 	result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1195 			 build_expr (e->e1), build_expr (e->e2));
1196       }
1197     else
1198       gcc_unreachable ();
1199 
1200     TREE_SIDE_EFFECTS (result) = 1;
1201     this->result_ = result;
1202   }
1203 
1204   /* Build an index expression.  */
1205 
visit(IndexExp * e)1206   void visit (IndexExp *e)
1207   {
1208     Type *tb1 = e->e1->type->toBasetype ();
1209 
1210     if (tb1->ty == Taarray)
1211       {
1212 	/* Get the key for the associative array.  */
1213 	Type *tkey = ((TypeAArray *) tb1)->index->toBasetype ();
1214 	tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1215 	libcall_fn libcall;
1216 	tree tinfo, ptr;
1217 
1218 	if (e->modifiable)
1219 	  {
1220 	    libcall = LIBCALL_AAGETY;
1221 	    ptr = build_address (build_expr (e->e1));
1222 	    tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());
1223 	  }
1224 	else
1225 	  {
1226 	    libcall = LIBCALL_AAGETRVALUEX;
1227 	    ptr = build_expr (e->e1);
1228 	    tinfo = build_typeinfo (e->loc, tkey);
1229 	  }
1230 
1231 	/* Index the associative array.  */
1232 	tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1233 				     ptr, tinfo,
1234 				     size_int (tb1->nextOf ()->size ()),
1235 				     build_address (key));
1236 
1237 	if (!e->indexIsInBounds && array_bounds_check ())
1238 	  {
1239 	    tree tassert = (global.params.checkAction == CHECKACTION_D)
1240 	      ? d_assert_call (e->loc, LIBCALL_ARRAY_BOUNDS)
1241 	      : build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1242 
1243 	    result = d_save_expr (result);
1244 	    result = build_condition (TREE_TYPE (result),
1245 				      d_truthvalue_conversion (result),
1246 				      result, tassert);
1247 	  }
1248 
1249 	this->result_ = indirect_ref (build_ctype (e->type), result);
1250       }
1251     else
1252       {
1253 	/* Get the data pointer and length for static and dynamic arrays.  */
1254 	tree array = d_save_expr (build_expr (e->e1));
1255 	tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1256 
1257 	tree length = NULL_TREE;
1258 	if (tb1->ty != Tpointer)
1259 	  length = get_array_length (array, tb1);
1260 	else
1261 	  gcc_assert (e->lengthVar == NULL);
1262 
1263 	/* The __dollar variable just becomes a placeholder for the
1264 	   actual length.  */
1265 	if (e->lengthVar)
1266 	  e->lengthVar->csym = length;
1267 
1268 	/* Generate the index.  */
1269 	tree index = build_expr (e->e2);
1270 
1271 	/* If it's a static array and the index is constant, the front end has
1272 	   already checked the bounds.  */
1273 	if (tb1->ty != Tpointer && !e->indexIsInBounds)
1274 	  index = build_bounds_condition (e->e2->loc, index, length, false);
1275 
1276 	/* Index the .ptr.  */
1277 	ptr = void_okay_p (ptr);
1278 	this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1279 				      build_array_index (ptr, index));
1280       }
1281   }
1282 
1283   /* Build a comma expression.  The type is the type of the right operand.  */
1284 
visit(CommaExp * e)1285   void visit (CommaExp *e)
1286   {
1287     tree t1 = build_expr (e->e1);
1288     tree t2 = build_expr (e->e2);
1289     tree type = e->type ? build_ctype (e->type) : void_type_node;
1290 
1291     this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1292   }
1293 
1294   /* Build an array length expression.  Returns the number of elements
1295      in the array.  The result is of type size_t.  */
1296 
visit(ArrayLengthExp * e)1297   void visit (ArrayLengthExp *e)
1298   {
1299     if (e->e1->type->toBasetype ()->ty == Tarray)
1300       this->result_ = d_array_length (build_expr (e->e1));
1301     else
1302       {
1303 	/* Static arrays have already been handled by the front-end.  */
1304 	error ("unexpected type for array length: %qs", e->type->toChars ());
1305 	this->result_ = error_mark_node;
1306       }
1307   }
1308 
1309   /* Build a delegate pointer expression.  This will return the frame
1310      pointer value as a type void*.  */
1311 
visit(DelegatePtrExp * e)1312   void visit (DelegatePtrExp *e)
1313   {
1314     tree t1 = build_expr (e->e1);
1315     this->result_ = delegate_object (t1);
1316   }
1317 
1318   /* Build a delegate function pointer expression.  This will return the
1319      function pointer value as a function type.  */
1320 
visit(DelegateFuncptrExp * e)1321   void visit (DelegateFuncptrExp *e)
1322   {
1323     tree t1 = build_expr (e->e1);
1324     this->result_ = delegate_method (t1);
1325   }
1326 
1327   /* Build a slice expression.  */
1328 
visit(SliceExp * e)1329   void visit (SliceExp *e)
1330   {
1331     Type *tb = e->type->toBasetype ();
1332     Type *tb1 = e->e1->type->toBasetype ();
1333     gcc_assert (tb->ty == Tarray || tb->ty == Tsarray);
1334 
1335     /* Use convert-to-dynamic-array code if possible.  */
1336     if (!e->lwr)
1337       {
1338 	tree result = build_expr (e->e1);
1339 	if (e->e1->type->toBasetype ()->ty == Tsarray)
1340 	  result = convert_expr (result, e->e1->type, e->type);
1341 
1342 	this->result_ = result;
1343 	return;
1344       }
1345     else
1346       gcc_assert (e->upr != NULL);
1347 
1348     /* Get the data pointer and length for static and dynamic arrays.  */
1349     tree array = d_save_expr (build_expr (e->e1));
1350     tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1351     tree length = NULL_TREE;
1352 
1353     /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1354        a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array.  */
1355     if (tb1->ty != Tpointer)
1356       length = get_array_length (array, tb1);
1357     else
1358       gcc_assert (e->lengthVar == NULL);
1359 
1360     /* The __dollar variable just becomes a placeholder for the
1361        actual length.  */
1362     if (e->lengthVar)
1363       e->lengthVar->csym = length;
1364 
1365     /* Generate upper and lower bounds.  */
1366     tree lwr_tree = d_save_expr (build_expr (e->lwr));
1367     tree upr_tree = d_save_expr (build_expr (e->upr));
1368 
1369     /* If the upper bound has any side effects, then the lower bound should be
1370        copied to a temporary always.  */
1371     if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1372       lwr_tree = save_expr (lwr_tree);
1373 
1374     /* Adjust the .ptr offset.  */
1375     if (!integer_zerop (lwr_tree))
1376       {
1377 	tree ptrtype = TREE_TYPE (ptr);
1378 	ptr = build_array_index (void_okay_p (ptr), lwr_tree);
1379 	ptr = build_nop (ptrtype, ptr);
1380       }
1381     else
1382       lwr_tree = NULL_TREE;
1383 
1384     /* Nothing more to do for static arrays, their bounds checking has been
1385        done at compile-time.  */
1386     if (tb->ty == Tsarray)
1387       {
1388 	this->result_ = indirect_ref (build_ctype (e->type), ptr);
1389 	return;
1390       }
1391     else
1392       gcc_assert (tb->ty == Tarray);
1393 
1394     /* Generate bounds checking code.  */
1395     tree newlength;
1396 
1397     if (!e->upperIsInBounds)
1398       {
1399 	if (length)
1400 	  {
1401 	    newlength = build_bounds_condition (e->upr->loc, upr_tree,
1402 						length, true);
1403 	  }
1404 	else
1405 	  {
1406 	    /* Still need to check bounds lwr <= upr for pointers.  */
1407 	    gcc_assert (tb1->ty == Tpointer);
1408 	    newlength = upr_tree;
1409 	  }
1410       }
1411     else
1412       newlength = upr_tree;
1413 
1414     if (lwr_tree)
1415       {
1416 	/* Enforces lwr <= upr.  No need to check lwr <= length as
1417 	   we've already ensured that upr <= length.  */
1418 	if (!e->lowerIsLessThanUpper)
1419 	  {
1420 	    tree cond = build_bounds_condition (e->lwr->loc, lwr_tree,
1421 						upr_tree, true);
1422 
1423 	    /* When bounds checking is off, the index value is
1424 	       returned directly.  */
1425 	    if (cond != lwr_tree)
1426 	      newlength = compound_expr (cond, newlength);
1427 	  }
1428 
1429 	/* Need to ensure lwr always gets evaluated first, as it may be a
1430 	   function call.  Generates (lwr, upr) - lwr.  */
1431 	newlength = fold_build2 (MINUS_EXPR, TREE_TYPE (newlength),
1432 				 compound_expr (lwr_tree, newlength), lwr_tree);
1433       }
1434 
1435     tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1436     this->result_ = compound_expr (array, result);
1437   }
1438 
1439   /* Build a cast expression, which converts the given unary expression to the
1440      type of result.  */
1441 
visit(CastExp * e)1442   void visit (CastExp *e)
1443   {
1444     Type *ebtype = e->e1->type->toBasetype ();
1445     Type *tbtype = e->to->toBasetype ();
1446     tree result = build_expr (e->e1, this->constp_);
1447 
1448     /* Just evaluate e1 if it has any side effects.  */
1449     if (tbtype->ty == Tvoid)
1450       this->result_ = build_nop (build_ctype (tbtype), result);
1451     else
1452       this->result_ = convert_expr (result, ebtype, tbtype);
1453   }
1454 
1455   /* Build a delete expression.  */
1456 
visit(DeleteExp * e)1457   void visit (DeleteExp *e)
1458   {
1459     tree t1 = build_expr (e->e1);
1460     Type *tb1 = e->e1->type->toBasetype ();
1461 
1462     if (tb1->ty == Tclass)
1463       {
1464 	/* For class object references, if there is a destructor for that class,
1465 	   the destructor is called for the object instance.  */
1466 	libcall_fn libcall;
1467 
1468 	if (e->e1->op == TOKvar)
1469 	  {
1470 	    VarDeclaration *v = ((VarExp *) e->e1)->var->isVarDeclaration ();
1471 	    if (v && v->onstack)
1472 	      {
1473 		libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1474 		  ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1475 
1476 		this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1477 		return;
1478 	      }
1479 	  }
1480 
1481 	/* Otherwise, the garbage collector is called to immediately free the
1482 	   memory allocated for the class instance.  */
1483 	libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1484 	  ? LIBCALL_DELINTERFACE : LIBCALL_DELCLASS;
1485 
1486 	t1 = build_address (t1);
1487 	this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1488       }
1489     else if (tb1->ty == Tarray)
1490       {
1491 	/* For dynamic arrays, the garbage collector is called to immediately
1492 	   release the memory.  */
1493 	Type *telem = tb1->nextOf ()->baseElemOf ();
1494 	tree ti = null_pointer_node;
1495 
1496 	if (telem->ty == Tstruct)
1497 	  {
1498 	    /* Might need to run destructor on array contents.  */
1499 	    TypeStruct *ts = (TypeStruct *) telem;
1500 	    if (ts->sym->dtor)
1501 	      ti = build_typeinfo (e->loc, tb1->nextOf ());
1502 	  }
1503 
1504 	/* Generate: _delarray_t (&t1, ti);  */
1505 	this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,
1506 				       build_address (t1), ti);
1507       }
1508     else if (tb1->ty == Tpointer)
1509       {
1510 	/* For pointers to a struct instance, if the struct has overloaded
1511 	   operator delete, then that operator is called.  */
1512 	t1 = build_address (t1);
1513 	Type *tnext = ((TypePointer *)tb1)->next->toBasetype ();
1514 
1515 	if (tnext->ty == Tstruct)
1516 	  {
1517 	    TypeStruct *ts = (TypeStruct *)tnext;
1518 	    if (ts->sym->dtor)
1519 	      {
1520 		tree ti = build_typeinfo (e->loc, tnext);
1521 		this->result_ = build_libcall (LIBCALL_DELSTRUCT, Type::tvoid,
1522 					       2, t1, ti);
1523 		return;
1524 	      }
1525 	  }
1526 
1527 	/* Otherwise, the garbage collector is called to immediately free the
1528 	   memory allocated for the pointer.  */
1529 	this->result_ = build_libcall (LIBCALL_DELMEMORY, Type::tvoid, 1, t1);
1530       }
1531     else
1532       {
1533 	error ("don%'t know how to delete %qs", e->e1->toChars ());
1534 	this->result_ = error_mark_node;
1535       }
1536   }
1537 
1538   /* Build a remove expression, which removes a particular key from an
1539      associative array.  */
1540 
visit(RemoveExp * e)1541   void visit (RemoveExp *e)
1542   {
1543     /* Check that the array is actually an associative array.  */
1544     if (e->e1->type->toBasetype ()->ty == Taarray)
1545       {
1546 	Type *tb = e->e1->type->toBasetype ();
1547 	Type *tkey = ((TypeAArray *) tb)->index->toBasetype ();
1548 	tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1549 
1550 	this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1551 				       build_expr (e->e1),
1552 				       build_typeinfo (e->loc, tkey),
1553 				       build_address (index));
1554       }
1555     else
1556       {
1557 	error ("%qs is not an associative array", e->e1->toChars ());
1558 	this->result_ = error_mark_node;
1559       }
1560   }
1561 
1562   /* Build an unary not expression.  */
1563 
visit(NotExp * e)1564   void visit (NotExp *e)
1565   {
1566     tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1567     /* Need to convert to boolean type or this will fail.  */
1568     result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1569 
1570     this->result_ = d_convert (build_ctype (e->type), result);
1571   }
1572 
1573   /* Build a compliment expression, where all the bits in the value are
1574      complemented.  Note: unlike in C, the usual integral promotions
1575      are not performed prior to the complement operation.  */
1576 
visit(ComExp * e)1577   void visit (ComExp *e)
1578   {
1579     TY ty1 = e->e1->type->toBasetype ()->ty;
1580     gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1581 
1582     this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1583 				 build_expr (e->e1));
1584   }
1585 
1586   /* Build an unary negation expression.  */
1587 
visit(NegExp * e)1588   void visit (NegExp *e)
1589   {
1590     TY ty1 = e->e1->type->toBasetype ()->ty;
1591     gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1592 
1593     tree type = build_ctype (e->type);
1594     tree expr = build_expr (e->e1);
1595 
1596     /* If the operation needs excess precision.  */
1597     tree eptype = excess_precision_type (type);
1598     if (eptype != NULL_TREE)
1599       expr = d_convert (eptype, expr);
1600     else
1601       eptype = type;
1602 
1603     tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1604     this->result_ = d_convert (type, ret);
1605   }
1606 
1607   /* Build a pointer index expression.  */
1608 
visit(PtrExp * e)1609   void visit (PtrExp *e)
1610   {
1611     Type *tnext = NULL;
1612     size_t offset;
1613     tree result;
1614 
1615     if (e->e1->op == TOKadd)
1616       {
1617 	BinExp *be = (BinExp *) e->e1;
1618 	if (be->e1->op == TOKaddress
1619 	    && be->e2->isConst () && be->e2->type->isintegral ())
1620 	  {
1621 	    Expression *ae = ((AddrExp *) be->e1)->e1;
1622 	    tnext = ae->type->toBasetype ();
1623 	    result = build_expr (ae);
1624 	    offset = be->e2->toUInteger ();
1625 	  }
1626       }
1627     else if (e->e1->op == TOKsymoff)
1628       {
1629 	SymOffExp *se = (SymOffExp *) e->e1;
1630 	if (!declaration_reference_p (se->var))
1631 	  {
1632 	    tnext = se->var->type->toBasetype ();
1633 	    result = get_decl_tree (se->var);
1634 	    offset = se->offset;
1635 	  }
1636       }
1637 
1638     /* Produce better code by converting *(#record + n) to
1639        COMPONENT_REFERENCE.  Otherwise, the variable will always be
1640        allocated in memory because its address is taken.  */
1641     if (tnext && tnext->ty == Tstruct)
1642       {
1643 	StructDeclaration *sd = ((TypeStruct *) tnext)->sym;
1644 
1645 	for (size_t i = 0; i < sd->fields.dim; i++)
1646 	  {
1647 	    VarDeclaration *field = sd->fields[i];
1648 
1649 	    if (field->offset == offset
1650 		&& same_type_p (field->type, e->type))
1651 	      {
1652 		/* Catch errors, backend will ICE otherwise.  */
1653 		if (error_operand_p (result))
1654 		  this->result_ = result;
1655 		else
1656 		  {
1657 		    result  = component_ref (result, get_symbol_decl (field));
1658 		    this->result_ = result;
1659 		  }
1660 		return;
1661 	      }
1662 	    else if (field->offset > offset)
1663 	      break;
1664 	  }
1665       }
1666 
1667     this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1668   }
1669 
1670   /* Build an unary address expression.  */
1671 
visit(AddrExp * e)1672   void visit (AddrExp *e)
1673   {
1674     tree type = build_ctype (e->type);
1675     tree exp;
1676 
1677     /* The frontend optimizer can convert const symbol into a struct literal.
1678        Taking the address of a struct literal is otherwise illegal.  */
1679     if (e->e1->op == TOKstructliteral)
1680       {
1681 	StructLiteralExp *sle = ((StructLiteralExp *) e->e1)->origin;
1682 	gcc_assert (sle != NULL);
1683 
1684 	/* Build the reference symbol, the decl is built first as the
1685 	   initializer may have recursive references.  */
1686 	if (!sle->sym)
1687 	  {
1688 	    sle->sym = build_artificial_decl (build_ctype (sle->type),
1689 					      NULL_TREE, "S");
1690 	    DECL_INITIAL (sle->sym) = build_expr (sle, true);
1691 	    d_pushdecl (sle->sym);
1692 	    rest_of_decl_compilation (sle->sym, 1, 0);
1693 	  }
1694 
1695 	exp = sle->sym;
1696       }
1697     else
1698       exp = build_expr (e->e1, this->constp_);
1699 
1700     TREE_CONSTANT (exp) = 0;
1701     this->result_ = d_convert (type, build_address (exp));
1702   }
1703 
1704   /* Build a function call expression.  */
1705 
visit(CallExp * e)1706   void visit (CallExp *e)
1707   {
1708     Type *tb = e->e1->type->toBasetype ();
1709     Expression *e1b = e->e1;
1710 
1711     tree callee = NULL_TREE;
1712     tree object = NULL_TREE;
1713     tree cleanup = NULL_TREE;
1714     TypeFunction *tf = NULL;
1715 
1716     /* Calls to delegates can sometimes look like this.  */
1717     if (e1b->op == TOKcomma)
1718       {
1719 	e1b = ((CommaExp *) e1b)->e2;
1720 	gcc_assert (e1b->op == TOKvar);
1721 
1722 	Declaration *var = ((VarExp *) e1b)->var;
1723 	gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1724       }
1725 
1726     if (e1b->op == TOKdotvar && tb->ty != Tdelegate)
1727       {
1728 	DotVarExp *dve = (DotVarExp *) e1b;
1729 
1730 	/* Don't modify the static initializer for struct literals.  */
1731 	if (dve->e1->op == TOKstructliteral)
1732 	  {
1733 	    StructLiteralExp *sle = (StructLiteralExp *) dve->e1;
1734 	    sle->useStaticInit = false;
1735 	  }
1736 
1737 	FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1738 	if (fd != NULL)
1739 	  {
1740 	    /* Get the correct callee from the DotVarExp object.  */
1741 	    tree fndecl = get_symbol_decl (fd);
1742 	    AggregateDeclaration *ad = fd->isThis ();
1743 
1744 	    /* Static method; ignore the object instance.  */
1745 	    if (!ad)
1746 	      callee = build_address (fndecl);
1747 	    else
1748 	      {
1749 		tree thisexp = build_expr (dve->e1);
1750 
1751 		/* When constructing temporaries, if the constructor throws,
1752 		   then the object is destructed even though it is not a fully
1753 		   constructed object yet.  And so this call will need to be
1754 		   moved inside the TARGET_EXPR_INITIAL slot.  */
1755 		if (fd->isCtorDeclaration ()
1756 		    && TREE_CODE (thisexp) == COMPOUND_EXPR
1757 		    && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1758 		    && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1759 		  {
1760 		    cleanup = TREE_OPERAND (thisexp, 0);
1761 		    thisexp = TREE_OPERAND (thisexp, 1);
1762 		  }
1763 
1764 		/* Want reference to 'this' object.  */
1765 		if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1766 		  thisexp = build_address (thisexp);
1767 
1768 		/* Make the callee a virtual call.  */
1769 		if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1770 		  {
1771 		    tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1772 		    tree thistype = build_ctype (ad->handleType ());
1773 		    thisexp = build_nop (thistype, d_save_expr (thisexp));
1774 		    fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1775 		  }
1776 		else
1777 		  fndecl = build_address (fndecl);
1778 
1779 		callee = build_method_call (fndecl, thisexp, fd->type);
1780 	      }
1781 	  }
1782       }
1783 
1784     if (callee == NULL_TREE)
1785       callee = build_expr (e1b);
1786 
1787     if (METHOD_CALL_EXPR (callee))
1788       {
1789 	/* This could be a delegate expression (TY == Tdelegate), but not
1790 	   actually a delegate variable.  */
1791 	if (e1b->op == TOKdotvar)
1792 	  {
1793 	    /* This gets the true function type, getting the function type
1794 	       from e1->type can sometimes be incorrect, such as when calling
1795 	       a 'ref' return function.  */
1796 	    tf = get_function_type (((DotVarExp *) e1b)->var->type);
1797 	  }
1798 	else
1799 	  tf = get_function_type (tb);
1800 
1801 	extract_from_method_call (callee, callee, object);
1802       }
1803     else if (tb->ty == Tdelegate)
1804       {
1805 	/* Delegate call, extract .object and .funcptr from var.  */
1806 	callee = d_save_expr (callee);
1807 	tf = get_function_type (tb);
1808 	object = delegate_object (callee);
1809 	callee = delegate_method (callee);
1810       }
1811     else if (e1b->op == TOKvar)
1812       {
1813 	FuncDeclaration *fd = ((VarExp *) e1b)->var->isFuncDeclaration ();
1814 	gcc_assert (fd != NULL);
1815 	tf = get_function_type (fd->type);
1816 
1817 	if (fd->isNested ())
1818 	  {
1819 	    /* Maybe re-evaluate symbol storage treating 'fd' as public.  */
1820 	    if (call_by_alias_p (d_function_chain->function, fd))
1821 	      TREE_PUBLIC (callee) = 1;
1822 
1823 	    object = get_frame_for_symbol (fd);
1824 	  }
1825 	else if (fd->needThis ())
1826 	  {
1827 	    error_at (make_location_t (e1b->loc),
1828 		      "need %<this%> to access member %qs", fd->toChars ());
1829 	    /* Continue compiling...  */
1830 	    object = null_pointer_node;
1831 	  }
1832       }
1833     else
1834       {
1835 	/* Normal direct function call.  */
1836 	tf = get_function_type (tb);
1837       }
1838 
1839     gcc_assert (tf != NULL);
1840 
1841     /* Now we have the type, callee and maybe object reference,
1842        build the call expression.  */
1843     tree exp = d_build_call (tf, callee, object, e->arguments);
1844 
1845     if (tf->isref)
1846       exp = build_deref (exp);
1847 
1848     /* Some library calls are defined to return a generic type.
1849        this->type is the real type we want to return.  */
1850     if (e->type->isTypeBasic ())
1851       exp = d_convert (build_ctype (e->type), exp);
1852 
1853     /* If this call was found to be a constructor for a temporary with a
1854        cleanup, then move the call inside the TARGET_EXPR.  The original
1855        initializer is turned into an assignment, to keep its side effect.  */
1856     if (cleanup != NULL_TREE)
1857       {
1858 	tree init = TARGET_EXPR_INITIAL (cleanup);
1859 	tree slot = TARGET_EXPR_SLOT (cleanup);
1860 	d_mark_addressable (slot);
1861 	init = build_assign (INIT_EXPR, slot, init);
1862 
1863 	TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1864 	exp = cleanup;
1865       }
1866 
1867     this->result_ = exp;
1868   }
1869 
1870   /* Build a delegate expression.  */
1871 
visit(DelegateExp * e)1872   void visit (DelegateExp *e)
1873   {
1874     if (e->func->semanticRun == PASSsemantic3done)
1875       {
1876 	/* Add the function as nested function if it belongs to this module.
1877 	   ie: it is a member of this module, or it is a template instance.  */
1878 	Dsymbol *owner = e->func->toParent ();
1879 	while (!owner->isTemplateInstance () && owner->toParent ())
1880 	  owner = owner->toParent ();
1881 	if (owner->isTemplateInstance () || owner == d_function_chain->module)
1882 	  build_decl_tree (e->func);
1883       }
1884 
1885     tree fndecl;
1886     tree object;
1887 
1888     if (e->func->isNested ())
1889       {
1890 	if (e->e1->op == TOKnull)
1891 	  object = build_expr (e->e1);
1892 	else
1893 	  object = get_frame_for_symbol (e->func);
1894 
1895 	fndecl = build_address (get_symbol_decl (e->func));
1896       }
1897     else
1898       {
1899 	if (!e->func->isThis ())
1900 	  {
1901 	    error ("delegates are only for non-static functions");
1902 	    this->result_ = error_mark_node;
1903 	    return;
1904 	  }
1905 
1906 	object = build_expr (e->e1);
1907 
1908 	/* Want reference to `this' object.  */
1909 	if (e->e1->type->ty != Tclass && e->e1->type->ty != Tpointer)
1910 	  object = build_address (object);
1911 
1912 	/* Object reference could be the outer `this' field of a class or
1913 	   closure of type `void*'.  Cast it to the right type.  */
1914 	if (e->e1->type->ty == Tclass)
1915 	  object = d_convert (build_ctype (e->e1->type), object);
1916 
1917 	fndecl = get_symbol_decl (e->func);
1918 
1919 	/* Get pointer to function out of the virtual table.  */
1920 	if (e->func->isVirtual () && !e->func->isFinalFunc ()
1921 	    && e->e1->op != TOKsuper && e->e1->op != TOKdottype)
1922 	  {
1923 	    tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1924 	    object = d_save_expr (object);
1925 	    fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1926 	  }
1927 	else
1928 	  fndecl = build_address (fndecl);
1929       }
1930 
1931     this->result_ = build_method_call (fndecl, object, e->type);
1932   }
1933 
1934   /* Build a type component expression.  */
1935 
visit(DotTypeExp * e)1936   void visit (DotTypeExp *e)
1937   {
1938     /* Just a pass through to underlying expression.  */
1939     this->result_ = build_expr (e->e1);
1940   }
1941 
1942   /* Build a component reference expression.  */
1943 
visit(DotVarExp * e)1944   void visit (DotVarExp *e)
1945   {
1946     VarDeclaration *vd = e->var->isVarDeclaration ();
1947 
1948     /* This could also be a function, but relying on that being taken
1949        care of by the visitor interface for CallExp.  */
1950     if (vd != NULL)
1951       {
1952 	if (!vd->isField ())
1953 	  this->result_ = get_decl_tree (vd);
1954 	else
1955 	  {
1956 	    tree object = build_expr (e->e1);
1957 
1958 	    if (e->e1->type->toBasetype ()->ty != Tstruct)
1959 	      object = build_deref (object);
1960 
1961 	    this->result_ = component_ref (object, get_symbol_decl (vd));
1962 	  }
1963       }
1964     else
1965       {
1966 	error ("%qs is not a field, but a %qs",
1967 	       e->var->toChars (), e->var->kind ());
1968 	this->result_ = error_mark_node;
1969       }
1970   }
1971 
1972   /* Build an assert expression, used to declare conditions that must hold at
1973      that a given point in the program.  */
1974 
visit(AssertExp * e)1975   void visit (AssertExp *e)
1976   {
1977     Type *tb1 = e->e1->type->toBasetype ();
1978     tree arg = build_expr (e->e1);
1979     tree tmsg = NULL_TREE;
1980     tree assert_pass = void_node;
1981     tree assert_fail;
1982 
1983     if (global.params.useAssert
1984 	&& global.params.checkAction == CHECKACTION_D)
1985       {
1986 	/* Generate: ((bool) e1  ? (void)0 : _d_assert (...))
1987 		 or: (e1 != null ? e1._invariant() : _d_assert (...))  */
1988 	bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1989 	libcall_fn libcall;
1990 
1991 	if (e->msg)
1992 	  {
1993 	    tmsg = build_expr_dtor (e->msg);
1994 	    libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1995 	  }
1996 	else
1997 	  libcall = unittest_p ? LIBCALL_UNITTEST : LIBCALL_ASSERT;
1998 
1999 	/* Build a call to _d_assert().  */
2000 	assert_fail = d_assert_call (e->loc, libcall, tmsg);
2001 
2002 	if (global.params.useInvariants)
2003 	  {
2004 	    /* If the condition is a D class or struct object with an invariant,
2005 	       call it if the condition result is true.  */
2006 	    if (tb1->ty == Tclass)
2007 	      {
2008 		ClassDeclaration *cd = tb1->isClassHandle ();
2009 		if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
2010 		  {
2011 		    arg = d_save_expr (arg);
2012 		    assert_pass = build_libcall (LIBCALL_INVARIANT,
2013 						 Type::tvoid, 1, arg);
2014 		  }
2015 	      }
2016 	    else if (tb1->ty == Tpointer && tb1->nextOf ()->ty == Tstruct)
2017 	      {
2018 		StructDeclaration *sd = ((TypeStruct *) tb1->nextOf ())->sym;
2019 		if (sd->inv != NULL)
2020 		  {
2021 		    Expressions args;
2022 		    arg = d_save_expr (arg);
2023 		    assert_pass = d_build_call_expr (sd->inv, arg, &args);
2024 		  }
2025 	      }
2026 	  }
2027       }
2028     else if (global.params.useAssert
2029 	     && global.params.checkAction == CHECKACTION_C)
2030       {
2031 	/* Generate: __builtin_trap()  */
2032 	tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
2033 	assert_fail = build_call_expr (fn, 0);
2034       }
2035     else
2036       {
2037 	/* Assert contracts are turned off, if the contract condition has no
2038 	   side effects can still use it as a predicate for the optimizer.  */
2039 	if (TREE_SIDE_EFFECTS (arg))
2040 	  {
2041 	    this->result_ = void_node;
2042 	    return;
2043 	  }
2044 
2045 	assert_fail = build_predict_expr (PRED_NORETURN, NOT_TAKEN);
2046       }
2047 
2048     /* Build condition that we are asserting in this contract.  */
2049     tree condition = convert_for_condition (arg, e->e1->type);
2050 
2051     /* We expect the condition to always be true, as what happens if an assert
2052        contract is false is undefined behavior.  */
2053     tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
2054     tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
2055     tree pred_type = TREE_VALUE (arg_types);
2056     tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
2057 
2058     condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
2059 				 build_int_cst (expected_type, 1));
2060     condition = d_truthvalue_conversion (condition);
2061 
2062     this->result_ = build_vcondition (condition, assert_pass, assert_fail);
2063   }
2064 
2065   /* Build a declaration expression.  */
2066 
visit(DeclarationExp * e)2067   void visit (DeclarationExp *e)
2068   {
2069     /* Compile the declaration.  */
2070     push_stmt_list ();
2071     build_decl_tree (e->declaration);
2072     tree result = pop_stmt_list ();
2073 
2074     /* Construction of an array for typesafe-variadic function arguments
2075        can cause an empty STMT_LIST here.  This can causes problems
2076        during gimplification.  */
2077     if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
2078       result = build_empty_stmt (input_location);
2079 
2080     this->result_ = result;
2081   }
2082 
2083   /* Build a typeid expression.  Returns an instance of class TypeInfo
2084      corresponding to.  */
2085 
visit(TypeidExp * e)2086   void visit (TypeidExp *e)
2087   {
2088     if (Type *tid = isType (e->obj))
2089       {
2090 	tree ti = build_typeinfo (e->loc, tid);
2091 
2092 	/* If the typeinfo is at an offset.  */
2093 	if (tid->vtinfo->offset)
2094 	  ti = build_offset (ti, size_int (tid->vtinfo->offset));
2095 
2096 	this->result_ = build_nop (build_ctype (e->type), ti);
2097       }
2098     else if (Expression *tid = isExpression (e->obj))
2099       {
2100 	Type *type = tid->type->toBasetype ();
2101 	assert (type->ty == Tclass);
2102 
2103 	/* Generate **classptr to get the classinfo.  */
2104 	tree ci = build_expr (tid);
2105 	ci = indirect_ref (ptr_type_node, ci);
2106 	ci = indirect_ref (ptr_type_node, ci);
2107 
2108 	/* Add extra indirection for interfaces.  */
2109 	if (((TypeClass *) type)->sym->isInterfaceDeclaration ())
2110 	  ci = indirect_ref (ptr_type_node, ci);
2111 
2112 	this->result_ = build_nop (build_ctype (e->type), ci);
2113       }
2114     else
2115       gcc_unreachable ();
2116   }
2117 
2118   /* Build a function/lambda expression.  */
2119 
visit(FuncExp * e)2120   void visit (FuncExp *e)
2121   {
2122     Type *ftype = e->type->toBasetype ();
2123 
2124     /* This check is for lambda's, remove 'vthis' as function isn't nested.  */
2125     if (e->fd->tok == TOKreserved && ftype->ty == Tpointer)
2126       {
2127 	e->fd->tok = TOKfunction;
2128 	e->fd->vthis = NULL;
2129       }
2130 
2131     /* Compile the function literal body.  */
2132     build_decl_tree (e->fd);
2133 
2134     /* If nested, this will be a trampoline.  */
2135     if (e->fd->isNested ())
2136       {
2137 	tree func = build_address (get_symbol_decl (e->fd));
2138 	tree object;
2139 
2140 	if (this->constp_)
2141 	  {
2142 	    /* Static delegate variables have no context pointer.  */
2143 	    object = null_pointer_node;
2144 	    this->result_ = build_method_call (func, object, e->fd->type);
2145 	    TREE_CONSTANT (this->result_) = 1;
2146 	  }
2147 	else
2148 	  {
2149 	    object = get_frame_for_symbol (e->fd);
2150 	    this->result_ = build_method_call (func, object, e->fd->type);
2151 	  }
2152       }
2153     else
2154       {
2155 	this->result_ = build_nop (build_ctype (e->type),
2156 				   build_address (get_symbol_decl (e->fd)));
2157       }
2158   }
2159 
2160   /* Build a halt expression.  */
2161 
visit(HaltExp *)2162   void visit (HaltExp *)
2163   {
2164     /* Should we use trap() or abort()?  */
2165     tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2166     this->result_ = build_call_expr (ttrap, 0);
2167   }
2168 
2169   /* Build a symbol pointer offset expression.  */
2170 
visit(SymOffExp * e)2171   void visit (SymOffExp *e)
2172   {
2173     /* Build the address and offset of the symbol.  */
2174     size_t soffset = ((SymOffExp *) e)->offset;
2175     tree result = get_decl_tree (e->var);
2176     TREE_USED (result) = 1;
2177 
2178     if (declaration_reference_p (e->var))
2179       gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2180     else
2181       result = build_address (result);
2182 
2183     if (!soffset)
2184       result = d_convert (build_ctype (e->type), result);
2185     else
2186       {
2187 	tree offset = size_int (soffset);
2188 	result = build_nop (build_ctype (e->type),
2189 			    build_offset (result, offset));
2190       }
2191 
2192     this->result_ = result;
2193   }
2194 
2195   /* Build a variable expression.  */
2196 
visit(VarExp * e)2197   void visit (VarExp *e)
2198   {
2199     if (e->var->needThis ())
2200       {
2201 	error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2202 	this->result_ = error_mark_node;
2203 	return;
2204       }
2205     else if (e->var->ident == Identifier::idPool ("__ctfe"))
2206       {
2207 	/* __ctfe is always false at run-time.  */
2208 	this->result_ = integer_zero_node;
2209 	return;
2210       }
2211 
2212     /* This check is same as is done in FuncExp for lambdas.  */
2213     FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2214     if (fld != NULL)
2215       {
2216 	if (fld->tok == TOKreserved)
2217 	  {
2218 	    fld->tok = TOKfunction;
2219 	    fld->vthis = NULL;
2220 	  }
2221 
2222 	/* Compiler the function literal body.  */
2223 	build_decl_tree (fld);
2224       }
2225 
2226     if (this->constp_)
2227       {
2228 	/* Want the initializer, not the expression.  */
2229 	VarDeclaration *var = e->var->isVarDeclaration ();
2230 	SymbolDeclaration *sd = e->var->isSymbolDeclaration ();
2231 	tree init = NULL_TREE;
2232 
2233 	if (var && (var->isConst () || var->isImmutable ())
2234 	    && e->type->toBasetype ()->ty != Tsarray && var->_init)
2235 	  {
2236 	    if (var->inuse)
2237 	      error_at (make_location_t (e->loc), "recursive reference %qs",
2238 			e->toChars ());
2239 	    else
2240 	      {
2241 		var->inuse++;
2242 		init = build_expr (initializerToExpression (var->_init), true);
2243 		var->inuse--;
2244 	      }
2245 	  }
2246 	else if (sd && sd->dsym)
2247 	  init = layout_struct_initializer (sd->dsym);
2248 	else
2249 	  error_at (make_location_t (e->loc), "non-constant expression %qs",
2250 		    e->toChars ());
2251 
2252 	if (init != NULL_TREE)
2253 	  this->result_ = init;
2254 	else
2255 	  this->result_ = error_mark_node;
2256       }
2257     else
2258       {
2259 	tree result = get_decl_tree (e->var);
2260 	TREE_USED (result) = 1;
2261 
2262 	/* For variables that are references - currently only out/inout
2263 	   arguments; objects don't count - evaluating the variable means
2264 	   we want what it refers to.  */
2265 	if (declaration_reference_p (e->var))
2266 	  result = indirect_ref (build_ctype (e->var->type), result);
2267 
2268 	this->result_ = result;
2269       }
2270   }
2271 
2272   /* Build a this variable expression.  */
2273 
visit(ThisExp * e)2274   void visit (ThisExp *e)
2275   {
2276     FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2277     tree result = NULL_TREE;
2278 
2279     if (e->var)
2280       result = get_decl_tree (e->var);
2281     else
2282       {
2283 	gcc_assert (fd && fd->vthis);
2284 	result = get_decl_tree (fd->vthis);
2285       }
2286 
2287     if (e->type->ty == Tstruct)
2288       result = build_deref (result);
2289 
2290     this->result_ = result;
2291   }
2292 
2293   /* Build a new expression, which allocates memory either on the garbage
2294      collected heap or by using a class or struct specific allocator.  */
2295 
visit(NewExp * e)2296   void visit (NewExp *e)
2297   {
2298     Type *tb = e->type->toBasetype ();
2299     tree result;
2300 
2301     if (e->allocator)
2302       gcc_assert (e->newargs);
2303 
2304     if (tb->ty == Tclass)
2305       {
2306 	/* Allocating a new class.  */
2307 	tb = e->newtype->toBasetype ();
2308 	gcc_assert (tb->ty == Tclass);
2309 
2310 	ClassDeclaration *cd = ((TypeClass *) tb)->sym;
2311 	tree type = build_ctype (tb);
2312 	tree setup_exp = NULL_TREE;
2313 	tree new_call;
2314 
2315 	if (e->onstack)
2316 	  {
2317 	    /* If being used as an initializer for a local variable with scope
2318 	       storage class, then the instance is allocated on the stack
2319 	       rather than the heap or using the class specific allocator.  */
2320 	    tree var = build_local_temp (TREE_TYPE (type));
2321 	    new_call = build_nop (type, build_address (var));
2322 	    setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2323 	  }
2324 	else if (e->allocator)
2325 	  {
2326 	    /* Call class allocator, and copy the initializer into memory.  */
2327 	    new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
2328 	    new_call = d_save_expr (new_call);
2329 	    new_call = build_nop (type, new_call);
2330 	    setup_exp = modify_expr (build_deref (new_call),
2331 				     aggregate_initializer_decl (cd));
2332 	  }
2333 	else
2334 	  {
2335 	    /* Generate: _d_newclass()  */
2336 	    tree arg = build_address (get_classinfo_decl (cd));
2337 	    new_call = build_libcall (LIBCALL_NEWCLASS, tb, 1, arg);
2338 	  }
2339 
2340 	/* Set the context pointer for nested classes.  */
2341 	if (cd->isNested ())
2342 	  {
2343 	    tree field = get_symbol_decl (cd->vthis);
2344 	    tree value = NULL_TREE;
2345 
2346 	    if (e->thisexp)
2347 	      {
2348 		ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2349 		Dsymbol *outer = cd->toParent2 ();
2350 		int offset = 0;
2351 
2352 		value = build_expr (e->thisexp);
2353 		if (outer != tcd)
2354 		  {
2355 		    ClassDeclaration *ocd = outer->isClassDeclaration ();
2356 		    gcc_assert (ocd->isBaseOf (tcd, &offset));
2357 		    /* Could just add offset...  */
2358 		    value = convert_expr (value, e->thisexp->type, ocd->type);
2359 		  }
2360 	      }
2361 	    else
2362 	      value = build_vthis (cd);
2363 
2364 	    if (value != NULL_TREE)
2365 	      {
2366 		/* Generate: (new())->vthis = this;  */
2367 		new_call = d_save_expr (new_call);
2368 		field = component_ref (build_deref (new_call), field);
2369 		setup_exp = compound_expr (setup_exp,
2370 					   modify_expr (field, value));
2371 	      }
2372 	  }
2373 	new_call = compound_expr (setup_exp, new_call);
2374 
2375 	/* Call the class constructor.  */
2376 	if (e->member)
2377 	  result = d_build_call_expr (e->member, new_call, e->arguments);
2378 	else
2379 	  result = new_call;
2380 
2381 	if (e->argprefix)
2382 	  result = compound_expr (build_expr (e->argprefix), result);
2383       }
2384     else if (tb->ty == Tpointer && tb->nextOf ()->toBasetype ()->ty == Tstruct)
2385       {
2386 	/* Allocating memory for a new struct.  */
2387 	Type *htype = e->newtype->toBasetype ();
2388 	gcc_assert (htype->ty == Tstruct);
2389 	gcc_assert (!e->onstack);
2390 
2391 	TypeStruct *stype = (TypeStruct *) htype;
2392 	StructDeclaration *sd = stype->sym;
2393 	tree new_call;
2394 
2395 	/* Cannot new an opaque struct.  */
2396 	if (sd->size (e->loc) == 0)
2397 	  {
2398 	    this->result_ = d_convert (build_ctype (e->type),
2399 				       integer_zero_node);
2400 	    return;
2401 	  }
2402 
2403 	if (e->allocator)
2404 	  {
2405 	    /* Call struct allocator.  */
2406 	    new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
2407 	    new_call = build_nop (build_ctype (tb), new_call);
2408 	  }
2409 	else
2410 	  {
2411 	    /* Generate: _d_newitemT()  */
2412 	    libcall_fn libcall = htype->isZeroInit ()
2413 	      ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2414 	    tree arg = build_typeinfo (e->loc, e->newtype);
2415 	    new_call = build_libcall (libcall, tb, 1, arg);
2416 	  }
2417 
2418 	if (e->member || !e->arguments)
2419 	  {
2420 	    /* Set the context pointer for nested structs.  */
2421 	    if (sd->isNested ())
2422 	      {
2423 		tree value = build_vthis (sd);
2424 		tree field = get_symbol_decl (sd->vthis);
2425 		tree type = build_ctype (stype);
2426 
2427 		new_call = d_save_expr (new_call);
2428 		field = component_ref (indirect_ref (type, new_call), field);
2429 		new_call = compound_expr (modify_expr (field, value), new_call);
2430 	      }
2431 
2432 	    /* Call the struct constructor.  */
2433 	    if (e->member)
2434 	      result = d_build_call_expr (e->member, new_call, e->arguments);
2435 	    else
2436 	      result = new_call;
2437 	  }
2438 	else
2439 	  {
2440 	    /* If we have a user supplied initializer, then set-up with a
2441 	       struct literal.  */
2442 	    if (e->arguments != NULL && sd->fields.dim != 0)
2443 	      {
2444 		StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2445 								 e->arguments,
2446 								 htype);
2447 		new_call = d_save_expr (new_call);
2448 		se->type = sd->type;
2449 		se->sym = new_call;
2450 		result = compound_expr (build_expr (se), new_call);
2451 	      }
2452 	    else
2453 	      result = new_call;
2454 	  }
2455 
2456 	if (e->argprefix)
2457 	  result = compound_expr (build_expr (e->argprefix), result);
2458       }
2459     else if (tb->ty == Tarray)
2460       {
2461 	/* Allocating memory for a new D array.  */
2462 	tb = e->newtype->toBasetype ();
2463 	gcc_assert (tb->ty == Tarray);
2464 	TypeDArray *tarray = (TypeDArray *) tb;
2465 
2466 	gcc_assert (!e->allocator);
2467 	gcc_assert (e->arguments && e->arguments->dim >= 1);
2468 
2469 	if (e->arguments->dim == 1)
2470 	  {
2471 	    /* Single dimension array allocations.  */
2472 	    Expression *arg = (*e->arguments)[0];
2473 
2474 	    if (tarray->next->size () == 0)
2475 	      {
2476 		/* Array element size is unknown.  */
2477 		this->result_ = d_array_value (build_ctype (e->type),
2478 					       size_int (0), null_pointer_node);
2479 		return;
2480 	      }
2481 
2482 	    libcall_fn libcall = tarray->next->isZeroInit ()
2483 	      ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
2484 	    result = build_libcall (libcall, tb, 2,
2485 				    build_typeinfo (e->loc, e->type),
2486 				    build_expr (arg));
2487 	  }
2488 	else
2489 	  {
2490 	    /* Multidimensional array allocations.  */
2491 	    tree tarray = make_array_type (Type::tsize_t, e->arguments->dim);
2492 	    tree var = build_local_temp (tarray);
2493 	    vec<constructor_elt, va_gc> *elms = NULL;
2494 
2495 	    /* Get the base element type for the array, generating the
2496 	       initializer for the dims parameter along the way.  */
2497 	    Type *telem = e->newtype->toBasetype ();
2498 	    for (size_t i = 0; i < e->arguments->dim; i++)
2499 	      {
2500 		Expression *arg = (*e->arguments)[i];
2501 		CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2502 
2503 		gcc_assert (telem->ty == Tarray);
2504 		telem = telem->toBasetype ()->nextOf ();
2505 		gcc_assert (telem);
2506 	      }
2507 
2508 	    /* Initialize the temporary.  */
2509 	    tree init = modify_expr (var, build_constructor (tarray, elms));
2510 	    var = compound_expr (init, var);
2511 
2512 	    /* Generate: _d_newarraymTX(ti, dims)
2513 		     or: _d_newarraymiTX(ti, dims)  */
2514 	    libcall_fn libcall = telem->isZeroInit ()
2515 	      ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2516 
2517 	    tree tinfo = build_typeinfo (e->loc, e->type);
2518 	    tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2519 				       size_int (e->arguments->dim),
2520 				       build_address (var));
2521 
2522 	    result = build_libcall (libcall, tb, 2, tinfo, dims);
2523 	  }
2524 
2525 	if (e->argprefix)
2526 	  result = compound_expr (build_expr (e->argprefix), result);
2527       }
2528     else if (tb->ty == Tpointer)
2529       {
2530 	/* Allocating memory for a new pointer.  */
2531 	TypePointer *tpointer = (TypePointer *) tb;
2532 
2533 	if (tpointer->next->size () == 0)
2534 	  {
2535 	    /* Pointer element size is unknown.  */
2536 	    this->result_ = d_convert (build_ctype (e->type),
2537 				       integer_zero_node);
2538 	    return;
2539 	  }
2540 
2541 	libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
2542 	  ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2543 
2544 	tree arg = build_typeinfo (e->loc, e->newtype);
2545 	result = build_libcall (libcall, tb, 1, arg);
2546 
2547 	if (e->arguments && e->arguments->dim == 1)
2548 	  {
2549 	    result = d_save_expr (result);
2550 	    tree init = modify_expr (build_deref (result),
2551 				     build_expr ((*e->arguments)[0]));
2552 	    result = compound_expr (init, result);
2553 	  }
2554 
2555 	if (e->argprefix)
2556 	  result = compound_expr (build_expr (e->argprefix), result);
2557       }
2558     else
2559       gcc_unreachable ();
2560 
2561     this->result_ = convert_expr (result, tb, e->type);
2562   }
2563 
2564   /* Build an integer literal.  */
2565 
visit(IntegerExp * e)2566   void visit (IntegerExp *e)
2567   {
2568     tree ctype = build_ctype (e->type->toBasetype ());
2569     this->result_ = build_integer_cst (e->value, ctype);
2570   }
2571 
2572   /* Build a floating-point literal.  */
2573 
visit(RealExp * e)2574   void visit (RealExp *e)
2575   {
2576     this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2577   }
2578 
2579   /* Build a complex literal.  */
2580 
visit(ComplexExp * e)2581   void visit (ComplexExp *e)
2582   {
2583     Type *tnext;
2584 
2585     switch (e->type->toBasetype ()->ty)
2586       {
2587       case Tcomplex32:
2588 	tnext = (TypeBasic *) Type::tfloat32;
2589 	break;
2590 
2591       case Tcomplex64:
2592 	tnext = (TypeBasic *) Type::tfloat64;
2593 	break;
2594 
2595       case Tcomplex80:
2596 	tnext = (TypeBasic *) Type::tfloat80;
2597 	break;
2598 
2599       default:
2600 	gcc_unreachable ();
2601       }
2602 
2603     this->result_ = build_complex (build_ctype (e->type),
2604 				   build_float_cst (creall (e->value), tnext),
2605 				   build_float_cst (cimagl (e->value), tnext));
2606   }
2607 
2608   /* Build a string literal, all strings are null terminated except for
2609      static arrays.  */
2610 
visit(StringExp * e)2611   void visit (StringExp *e)
2612   {
2613     Type *tb = e->type->toBasetype ();
2614     tree type = build_ctype (e->type);
2615 
2616     if (tb->ty == Tsarray)
2617       {
2618 	/* Turn the string into a constructor for the static array.  */
2619 	vec<constructor_elt, va_gc> *elms = NULL;
2620 	vec_safe_reserve (elms, e->len);
2621 	tree etype = TREE_TYPE (type);
2622 
2623 	for (size_t i = 0; i < e->len; i++)
2624 	  {
2625 	    tree value = build_integer_cst (e->charAt (i), etype);
2626 	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2627 	  }
2628 
2629 	tree ctor = build_constructor (type, elms);
2630 	TREE_CONSTANT (ctor) = 1;
2631 	this->result_ = ctor;
2632       }
2633     else
2634       {
2635 	/* Copy the string contents to a null terminated string.  */
2636 	dinteger_t length = (e->len * e->sz);
2637 	char *string = XALLOCAVEC (char, length + 1);
2638 	memcpy (string, e->string, length);
2639 	string[length] = '\0';
2640 
2641 	/* String value and type includes the null terminator.  */
2642 	tree value = build_string (length, string);
2643 	TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2644 	value = build_address (value);
2645 
2646 	if (tb->ty == Tarray)
2647 	  value = d_array_value (type, size_int (e->len), value);
2648 
2649 	TREE_CONSTANT (value) = 1;
2650 	this->result_ = d_convert (type, value);
2651       }
2652   }
2653 
2654   /* Build a tuple literal.  Just an argument list that may have
2655      side effects that need evaluation.  */
2656 
visit(TupleExp * e)2657   void visit (TupleExp *e)
2658   {
2659     tree result = NULL_TREE;
2660 
2661     if (e->e0)
2662       result = build_expr (e->e0);
2663 
2664     for (size_t i = 0; i < e->exps->dim; ++i)
2665       {
2666 	Expression *exp = (*e->exps)[i];
2667 	result = compound_expr (result, build_expr (exp));
2668       }
2669 
2670     if (result == NULL_TREE)
2671       result = void_node;
2672 
2673     this->result_ = result;
2674   }
2675 
2676   /* Build an array literal.  The common type of the all elements is taken to
2677      be the type of the array element, and all elements are implicitly
2678      converted to that type.  */
2679 
visit(ArrayLiteralExp * e)2680   void visit (ArrayLiteralExp *e)
2681   {
2682     Type *tb = e->type->toBasetype ();
2683 
2684     /* Implicitly convert void[n] to ubyte[n].  */
2685     if (tb->ty == Tsarray && tb->nextOf ()->toBasetype ()->ty == Tvoid)
2686       tb = Type::tuns8->sarrayOf (((TypeSArray *) tb)->dim->toUInteger ());
2687 
2688     gcc_assert (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tpointer);
2689 
2690     /* Handle empty array literals.  */
2691     if (e->elements->dim == 0)
2692       {
2693 	if (tb->ty == Tarray)
2694 	  this->result_ = d_array_value (build_ctype (e->type),
2695 					 size_int (0), null_pointer_node);
2696 	else
2697 	  this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2698 					     NULL);
2699 
2700 	return;
2701       }
2702 
2703     /* Build an expression that assigns the expressions in ELEMENTS to
2704        a constructor.  */
2705     vec<constructor_elt, va_gc> *elms = NULL;
2706     vec_safe_reserve (elms, e->elements->dim);
2707     bool constant_p = true;
2708     tree saved_elems = NULL_TREE;
2709 
2710     Type *etype = tb->nextOf ();
2711     tree satype = make_array_type (etype, e->elements->dim);
2712 
2713     for (size_t i = 0; i < e->elements->dim; i++)
2714       {
2715 	Expression *expr = e->getElement (i);
2716 	tree value = build_expr (expr, this->constp_);
2717 
2718 	/* Only append nonzero values, the backend will zero out the rest
2719 	   of the constructor as we don't set CONSTRUCTOR_NO_CLEARING.  */
2720 	if (!initializer_zerop (value))
2721 	  {
2722 	    if (!TREE_CONSTANT (value))
2723 	      constant_p = false;
2724 
2725 	    /* Split construction of values out of the constructor if there
2726 	       may be side effects.  */
2727 	    tree init = stabilize_expr (&value);
2728 	    if (init != NULL_TREE)
2729 	      saved_elems = compound_expr (saved_elems, init);
2730 
2731 	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2732 				    convert_expr (value, expr->type, etype));
2733 	  }
2734       }
2735 
2736     /* Now return the constructor as the correct type.  For static arrays there
2737        is nothing else to do.  For dynamic arrays, return a two field struct.
2738        For pointers, return the address.  */
2739     tree ctor = build_constructor (satype, elms);
2740     tree type = build_ctype (e->type);
2741 
2742     /* Nothing else to do for static arrays.  */
2743     if (tb->ty == Tsarray || this->constp_)
2744       {
2745 	/* Can't take the address of the constructor, so create an anonymous
2746 	   static symbol, and then refer to it.  */
2747 	if (tb->ty != Tsarray)
2748 	  {
2749 	    tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2750 	    ctor = build_address (decl);
2751 	    if (tb->ty == Tarray)
2752 	      ctor = d_array_value (type, size_int (e->elements->dim), ctor);
2753 
2754 	    d_pushdecl (decl);
2755 	    rest_of_decl_compilation (decl, 1, 0);
2756 	  }
2757 
2758 	/* If the array literal is readonly or static.  */
2759 	if (constant_p)
2760 	  TREE_CONSTANT (ctor) = 1;
2761 	if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2762 	  TREE_STATIC (ctor) = 1;
2763 
2764 	this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2765       }
2766     else
2767       {
2768 	/* Allocate space on the memory managed heap.  */
2769 	tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2770 				  etype->pointerTo (), 2,
2771 				  build_typeinfo (e->loc, etype->arrayOf ()),
2772 				  size_int (e->elements->dim));
2773 	mem = d_save_expr (mem);
2774 
2775 	/* Now copy the constructor into memory.  */
2776 	tree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);
2777 	tree size = size_mult_expr (size_int (e->elements->dim),
2778 				    size_int (tb->nextOf ()->size ()));
2779 
2780 	tree result = build_call_expr (tmemcpy, 3, mem,
2781 				       build_address (ctor), size);
2782 
2783 	/* Return the array pointed to by MEM.  */
2784 	result = compound_expr (result, mem);
2785 
2786 	if (tb->ty == Tarray)
2787 	  result = d_array_value (type, size_int (e->elements->dim), result);
2788 
2789 	this->result_ = compound_expr (saved_elems, result);
2790       }
2791   }
2792 
2793   /* Build an associative array literal.  The common type of the all keys is
2794      taken to be the key type, and common type of all values the value type.
2795      All keys and values are then implicitly converted as needed.  */
2796 
visit(AssocArrayLiteralExp * e)2797   void visit (AssocArrayLiteralExp *e)
2798   {
2799     /* Want the mutable type for typeinfo reference.  */
2800     Type *tb = e->type->toBasetype ()->mutableOf ();
2801     gcc_assert (tb->ty == Taarray);
2802 
2803     /* Handle empty assoc array literals.  */
2804     TypeAArray *ta = (TypeAArray *) tb;
2805     if (e->keys->dim == 0)
2806       {
2807 	this->result_ = build_constructor (build_ctype (ta), NULL);
2808 	return;
2809       }
2810 
2811     /* Build an expression that assigns all expressions in KEYS
2812        to a constructor.  */
2813     vec<constructor_elt, va_gc> *kelts = NULL;
2814     vec_safe_reserve (kelts, e->keys->dim);
2815     for (size_t i = 0; i < e->keys->dim; i++)
2816       {
2817 	Expression *key = (*e->keys)[i];
2818 	tree t = build_expr (key);
2819 	CONSTRUCTOR_APPEND_ELT (kelts, size_int (i),
2820 				convert_expr (t, key->type, ta->index));
2821       }
2822     tree tkeys = make_array_type (ta->index, e->keys->dim);
2823     tree akeys = build_constructor (tkeys, kelts);
2824 
2825     /* Do the same with all expressions in VALUES.  */
2826     vec<constructor_elt, va_gc> *velts = NULL;
2827     vec_safe_reserve (velts, e->values->dim);
2828     for (size_t i = 0; i < e->values->dim; i++)
2829       {
2830 	Expression *value = (*e->values)[i];
2831 	tree t = build_expr (value);
2832 	CONSTRUCTOR_APPEND_ELT (velts, size_int (i),
2833 				convert_expr (t, value->type, ta->next));
2834       }
2835     tree tvals = make_array_type (ta->next, e->values->dim);
2836     tree avals = build_constructor (tvals, velts);
2837 
2838     /* Generate: _d_assocarrayliteralTX (ti, keys, vals);  */
2839     tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2840 			       size_int (e->keys->dim), build_address (akeys));
2841     tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2842 			       size_int (e->values->dim),
2843 			       build_address (avals));
2844 
2845     tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2846 			      build_typeinfo (e->loc, ta), keys, vals);
2847 
2848     /* Return an associative array pointed to by MEM.  */
2849     tree aatype = build_ctype (ta);
2850     vec<constructor_elt, va_gc> *ce = NULL;
2851     CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2852 
2853     this->result_ = build_nop (build_ctype (e->type),
2854 			       build_constructor (aatype, ce));
2855   }
2856 
2857   /* Build a struct literal.  */
2858 
visit(StructLiteralExp * e)2859   void visit (StructLiteralExp *e)
2860   {
2861     /* Handle empty struct literals.  */
2862     if (e->elements == NULL || e->sd->fields.dim == 0)
2863       {
2864 	this->result_ = build_constructor (build_ctype (e->type), NULL);
2865 	return;
2866       }
2867 
2868     /* Building sinit trees are delayed until after frontend semantic
2869        processing has complete.  Build the static initializer now.  */
2870     if (e->useStaticInit && !this->constp_)
2871       {
2872 	this->result_ = aggregate_initializer_decl (e->sd);
2873 	return;
2874       }
2875 
2876     /* Build a constructor that assigns the expressions in ELEMENTS
2877        at each field index that has been filled in.  */
2878     vec<constructor_elt, va_gc> *ve = NULL;
2879     tree saved_elems = NULL_TREE;
2880 
2881     /* CTFE may fill the hidden pointer by NullExp.  */
2882     gcc_assert (e->elements->dim <= e->sd->fields.dim);
2883 
2884     Type *tb = e->type->toBasetype ();
2885     gcc_assert (tb->ty == Tstruct);
2886 
2887     for (size_t i = 0; i < e->elements->dim; i++)
2888       {
2889 	Expression *exp = (*e->elements)[i];
2890 	if (!exp)
2891 	  continue;
2892 
2893 	VarDeclaration *field = e->sd->fields[i];
2894 	Type *type = exp->type->toBasetype ();
2895 	Type *ftype = field->type->toBasetype ();
2896 	tree value = NULL_TREE;
2897 
2898 	if (ftype->ty == Tsarray && !same_type_p (type, ftype))
2899 	  {
2900 	    /* Initialize a static array with a single element.  */
2901 	    tree elem = build_expr (exp, this->constp_);
2902 	    elem = d_save_expr (elem);
2903 
2904 	    if (initializer_zerop (elem))
2905 	      value = build_constructor (build_ctype (ftype), NULL);
2906 	    else
2907 	      value = build_array_from_val (ftype, elem);
2908 	  }
2909 	else
2910 	  {
2911 	    value = convert_expr (build_expr (exp, this->constp_),
2912 				  exp->type, field->type);
2913 	  }
2914 
2915 	/* Split construction of values out of the constructor.  */
2916 	tree init = stabilize_expr (&value);
2917 	if (init != NULL_TREE)
2918 	  saved_elems = compound_expr (saved_elems, init);
2919 
2920 	CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2921       }
2922 
2923     /* Maybe setup hidden pointer to outer scope context.  */
2924     if (e->sd->isNested () && e->elements->dim != e->sd->fields.dim
2925 	&& this->constp_ == false)
2926       {
2927 	tree field = get_symbol_decl (e->sd->vthis);
2928 	tree value = build_vthis (e->sd);
2929 	CONSTRUCTOR_APPEND_ELT (ve, field, value);
2930 	gcc_assert (e->useStaticInit == false);
2931       }
2932 
2933     /* Build a constructor in the correct shape of the aggregate type.  */
2934     tree ctor = build_struct_literal (build_ctype (e->type), ve);
2935 
2936     /* Nothing more to do for constant literals.  */
2937     if (this->constp_)
2938       {
2939 	/* If the struct literal is a valid for static data.  */
2940 	if (TREE_CONSTANT (ctor)
2941 	    && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2942 	  TREE_STATIC (ctor) = 1;
2943 
2944 	this->result_ = compound_expr (saved_elems, ctor);
2945 	return;
2946       }
2947 
2948     if (e->sym != NULL)
2949       {
2950 	tree var = build_deref (e->sym);
2951 	ctor = compound_expr (modify_expr (var, ctor), var);
2952 	this->result_ = compound_expr (saved_elems, ctor);
2953       }
2954     else if (e->sd->isUnionDeclaration ())
2955       {
2956 	/* For unions, use memset to fill holes in the object.  */
2957 	tree var = build_local_temp (TREE_TYPE (ctor));
2958 	tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
2959 	tree init = build_call_expr (tmemset, 3, build_address (var),
2960 				     size_zero_node,
2961 				     size_int (e->sd->structsize));
2962 
2963 	init = compound_expr (init, saved_elems);
2964 	init = compound_expr (init, modify_expr (var, ctor));
2965 	this->result_  = compound_expr (init, var);
2966       }
2967     else
2968       this->result_ = compound_expr (saved_elems, ctor);
2969   }
2970 
2971   /* Build a null literal.  */
2972 
visit(NullExp * e)2973   void visit (NullExp *e)
2974   {
2975     this->result_ = build_typeof_null_value (e->type);
2976   }
2977 
2978   /* Build a vector literal.  */
2979 
visit(VectorExp * e)2980   void visit (VectorExp *e)
2981   {
2982     tree type = build_ctype (e->type);
2983     tree etype = TREE_TYPE (type);
2984 
2985     /* First handle array literal expressions.  */
2986     if (e->e1->op == TOKarrayliteral)
2987       {
2988 	ArrayLiteralExp *ale = ((ArrayLiteralExp *) e->e1);
2989 	vec<constructor_elt, va_gc> *elms = NULL;
2990 	bool constant_p = true;
2991 
2992 	vec_safe_reserve (elms, ale->elements->dim);
2993 	for (size_t i = 0; i < ale->elements->dim; i++)
2994 	  {
2995 	    Expression *expr = ale->getElement (i);
2996 	    tree value = d_convert (etype, build_expr (expr, this->constp_));
2997 	    if (!CONSTANT_CLASS_P (value))
2998 	      constant_p = false;
2999 
3000 	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
3001 	  }
3002 
3003 	/* Build a VECTOR_CST from a constant vector constructor.  */
3004 	if (constant_p)
3005 	  this->result_ = build_vector_from_ctor (type, elms);
3006 	else
3007 	  this->result_ = build_constructor (type, elms);
3008       }
3009     else
3010       {
3011 	/* Build constructor from single value.  */
3012 	tree val = d_convert (etype, build_expr (e->e1, this->constp_));
3013 	this->result_ = build_vector_from_val (type, val);
3014       }
3015   }
3016 
3017   /* Build a static array representation of a vector expression.  */
3018 
visit(VectorArrayExp * e)3019   void visit (VectorArrayExp *e)
3020   {
3021     this->result_ = convert_expr (build_expr (e->e1, this->constp_),
3022 				  e->e1->type, e->type);
3023   }
3024 
3025   /* Build a static class literal, return its reference.  */
3026 
visit(ClassReferenceExp * e)3027   void visit (ClassReferenceExp *e)
3028   {
3029     /* The result of build_new_class_expr is a RECORD_TYPE, we want
3030        the reference.  */
3031     tree var = build_address (build_new_class_expr (e));
3032 
3033     /* If the type of this literal is an interface, the we must add the
3034        interface offset to symbol.  */
3035     if (this->constp_)
3036       {
3037 	TypeClass *tc = (TypeClass *) e->type;
3038 	InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
3039 
3040 	if (to != NULL)
3041 	  {
3042 	    ClassDeclaration *from = e->originalClass ();
3043 	    int offset = 0;
3044 
3045 	    gcc_assert (to->isBaseOf (from, &offset) != 0);
3046 
3047 	    if (offset != 0)
3048 	      var = build_offset (var, size_int (offset));
3049 	  }
3050       }
3051 
3052     this->result_ = var;
3053   }
3054 
3055   /* These expressions are mainly just a placeholders in the frontend.
3056      We shouldn't see them here.  */
3057 
visit(ScopeExp * e)3058   void visit (ScopeExp *e)
3059   {
3060     error_at (make_location_t (e->loc), "%qs is not an expression",
3061 	      e->toChars ());
3062     this->result_ = error_mark_node;
3063   }
3064 
visit(TypeExp * e)3065   void visit (TypeExp *e)
3066   {
3067     error_at (make_location_t (e->loc), "type %qs is not an expression",
3068 	      e->toChars ());
3069     this->result_ = error_mark_node;
3070   }
3071 };
3072 
3073 
3074 /* Main entry point for ExprVisitor interface to generate code for
3075    the Expression AST class E.  If CONST_P is true, then E is a
3076    constant expression.  */
3077 
3078 tree
build_expr(Expression * e,bool const_p)3079 build_expr (Expression *e, bool const_p)
3080 {
3081   ExprVisitor v = ExprVisitor (const_p);
3082   location_t saved_location = input_location;
3083 
3084   input_location = make_location_t (e->loc);
3085   e->accept (&v);
3086   tree expr = v.result ();
3087   input_location = saved_location;
3088 
3089   /* Check if initializer expression is valid constant.  */
3090   if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3091     {
3092       error_at (make_location_t (e->loc), "non-constant expression %qs",
3093 		e->toChars ());
3094       return error_mark_node;
3095     }
3096 
3097   return expr;
3098 }
3099 
3100 /* Same as build_expr, but also calls destructors on any temporaries.  */
3101 
3102 tree
build_expr_dtor(Expression * e)3103 build_expr_dtor (Expression *e)
3104 {
3105   /* Codegen can be improved by determining if no exceptions can be thrown
3106      between the ctor and dtor, and eliminating the ctor and dtor.  */
3107   size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3108   tree result = build_expr (e);
3109 
3110   if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3111     {
3112       result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3113       vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3114     }
3115 
3116   return result;
3117 }
3118 
3119 /* Same as build_expr_dtor, but handles the result of E as a return value.  */
3120 
3121 tree
build_return_dtor(Expression * e,Type * type,TypeFunction * tf)3122 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3123 {
3124   size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3125   tree result = build_expr (e);
3126 
3127   /* Convert for initializing the DECL_RESULT.  */
3128   result = convert_expr (result, e->type, type);
3129 
3130   /* If we are returning a reference, take the address.  */
3131   if (tf->isref)
3132     result = build_address (result);
3133 
3134   /* The decl to store the return expression.  */
3135   tree decl = DECL_RESULT (cfun->decl);
3136 
3137   /* Split comma expressions, so that the result is returned directly.  */
3138   tree expr = stabilize_expr (&result);
3139   result = build_assign (INIT_EXPR, decl, result);
3140   result = compound_expr (expr, return_expr (result));
3141 
3142   /* May nest the return expression inside the try/finally expression.  */
3143   if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3144     {
3145       result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3146       vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3147     }
3148 
3149   return result;
3150 }
3151 
3152