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