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