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