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