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