d: Merge upstream dmd ff57fec515, druntime ff57fec515, phobos 17bafda79.
[official-gcc.git] / gcc / d / expr.cc
bloba907979ba04a0859016113ca4b4e9e8468fa7e96
1 /* expr.cc -- Lower D frontend expressions to GCC trees.
2 Copyright (C) 2015-2023 Free Software Foundation, Inc.
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.
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.
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/>. */
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
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"
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"
44 #include "d-tree.h"
47 /* Determine if type T is a struct that has a postblit. */
49 static bool
50 needs_postblit (Type *t)
52 t = t->baseElemOf ();
54 if (TypeStruct *ts = t->isTypeStruct ())
56 if (ts->sym->postblit)
57 return true;
60 return false;
63 /* Determine if type T is a struct that has a destructor. */
65 static bool
66 needs_dtor (Type *t)
68 t = t->baseElemOf ();
70 if (TypeStruct *ts = t->isTypeStruct ())
72 if (ts->sym->dtor)
73 return true;
76 return false;
79 /* Determine if expression E is a suitable lvalue. */
81 static bool
82 lvalue_p (Expression *e)
84 SliceExp *se = e->isSliceExp ();
85 if (se != NULL && se->e1->isLvalue ())
86 return true;
88 CastExp *ce = e->isCastExp ();
89 if (ce != NULL && ce->e1->isLvalue ())
90 return true;
92 return (e->op != EXP::slice && e->isLvalue ());
95 /* Build an expression of code CODE, data type TYPE, and operands ARG0 and
96 ARG1. Perform relevant conversions needed for correct code operations. */
98 static tree
99 binary_op (tree_code code, tree type, tree arg0, tree arg1)
101 tree t0 = TREE_TYPE (arg0);
102 tree t1 = TREE_TYPE (arg1);
103 tree ret = NULL_TREE;
105 /* Deal with float mod expressions immediately. */
106 if (code == FLOAT_MOD_EXPR)
107 return build_float_modulus (type, arg0, arg1);
109 if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
110 return build_nop (type, build_offset_op (code, arg0, arg1));
112 if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
113 return build_nop (type, build_offset_op (code, arg1, arg0));
115 if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
117 gcc_assert (code == MINUS_EXPR);
118 tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
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);
132 else
134 /* If the operation needs excess precision. */
135 tree eptype = excess_precision_type (type);
136 if (eptype != NULL_TREE)
138 arg0 = d_convert (eptype, arg0);
139 arg1 = d_convert (eptype, arg1);
141 else
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);
150 eptype = type;
153 ret = build2 (code, eptype, arg0, arg1);
156 return d_convert (type, ret);
159 /* Build a binary expression of code CODE, assigning the result into E1. */
161 static tree
162 binop_assignment (tree_code code, Expression *e1, Expression *e2)
164 /* Skip casts for lhs assignment. */
165 Expression *e1b = e1;
166 while (e1b->op == EXP::cast_)
168 CastExp *ce = e1b->isCastExp ();
169 gcc_assert (same_type_p (ce->type, ce->to));
170 e1b = ce->e1;
173 /* Stabilize LHS for assignment. */
174 tree lhs = build_expr (e1b);
175 tree lexpr = stabilize_expr (&lhs);
177 /* The LHS expression could be an assignment, to which its operation gets
178 lost during gimplification. */
179 if (TREE_CODE (lhs) == MODIFY_EXPR)
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));
188 lexpr = compound_expr (lexpr, lhs);
189 lhs = TREE_OPERAND (lhs, 0);
192 lhs = stabilize_reference (lhs);
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);
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);
203 tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
204 return compound_expr (lexpr, expr);
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. */
213 class ExprVisitor : public Visitor
215 using Visitor::visit;
217 tree result_;
218 bool constp_;
219 bool literalp_;
221 public:
222 ExprVisitor (bool constp, bool literalp)
224 this->result_ = NULL_TREE;
225 this->constp_ = constp;
226 this->literalp_ = literalp;
229 tree result (void)
231 return this->result_;
234 /* Visitor interfaces, each Expression class should have
235 overridden the default. */
237 void visit (Expression *) final override
239 gcc_unreachable ();
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. */
246 void visit (CondExp *e) final override
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);
253 if (e->type->ty != TY::Tvoid)
255 t1 = convert_expr (t1, e->e1->type, e->type);
256 t2 = convert_expr (t2, e->e2->type, e->type);
259 this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
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. */
266 void visit (IdentityExp *e) final override
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 ();
272 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
273 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
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));
282 else if (tb1->isfloating () && tb1->ty != TY::Tvector)
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));
289 if (!tb1->iscomplex ())
290 this->result_ = build_float_identity (code, t1, t2);
291 else
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));
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);
305 else if (TypeStruct *ts = tb1->isTypeStruct ())
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);
312 gcc_assert (same_type_p (tb1, tb2));
314 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
316 else if (tb1->ty == TY::Tvector && tb2->ty == TY::Tvector)
318 /* For vectors, identity is defined as all values being equal. */
319 tree t1 = build_expr (e->e1);
320 tree t2 = build_expr (e->e2);
321 tree mask = build_boolop (code, t1, t2);
323 /* To reinterpret the vector comparison as a boolean expression, bitcast
324 the bitmask result and generate an additional integer comparison. */
325 opt_scalar_int_mode mode =
326 int_mode_for_mode (TYPE_MODE (TREE_TYPE (mask)));
327 gcc_assert (mode.exists ());
329 tree type = lang_hooks.types.type_for_mode (mode.require (), 1);
330 if (type == NULL_TREE)
331 type = make_unsigned_type (GET_MODE_BITSIZE (mode.require ()));
333 /* In `t1 is t2', all mask bits must be set for vectors to be equal.
334 Otherwise any bit set is enough for vectors to be not-equal. */
335 tree mask_eq = (code == EQ_EXPR)
336 ? build_all_ones_cst (type) : build_zero_cst (type);
338 this->result_ = build_boolop (code, mask_eq,
339 build_vconvert (type, mask));
341 else
343 /* For operands of other types, identity is defined as being the
344 same as equality expressions. */
345 tree t1 = build_expr (e->e1);
346 tree t2 = build_expr (e->e2);
347 this->result_ = d_convert (build_ctype (e->type),
348 build_boolop (code, t1, t2));
352 /* Build an equality expression, which compare the two operands for either
353 equality or inequality. Operands go through the usual conversions to bring
354 them to a common type before comparison. The result type is bool. */
356 void visit (EqualExp *e) final override
358 Type *tb1 = e->e1->type->toBasetype ();
359 Type *tb2 = e->e2->type->toBasetype ();
360 tree_code code = (e->op == EXP::equal) ? EQ_EXPR : NE_EXPR;
362 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
363 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
365 /* For static and dynamic arrays, equality is defined as the lengths of
366 the arrays matching, and all the elements are equal. */
367 Type *t1elem = tb1->nextOf ()->toBasetype ();
368 Type *t2elem = tb1->nextOf ()->toBasetype ();
370 /* Check if comparisons of arrays can be optimized using memcmp.
371 This will inline EQ expressions as:
372 e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
373 Or when generating a NE expression:
374 e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */
375 if ((t1elem->isintegral () || t1elem->ty == TY::Tvoid
376 || (t1elem->ty == TY::Tstruct
377 && !t1elem->isTypeStruct ()->sym->xeq))
378 && t1elem->ty == t2elem->ty)
380 tree t1 = d_array_convert (e->e1);
381 tree t2 = d_array_convert (e->e2);
382 tree result;
384 /* Make temporaries to prevent multiple evaluations. */
385 tree t1saved = d_save_expr (t1);
386 tree t2saved = d_save_expr (t2);
388 /* Length of arrays, for comparisons done before calling memcmp. */
389 tree t1len = d_array_length (t1saved);
390 tree t2len = d_array_length (t2saved);
392 /* Reference to array data. */
393 tree t1ptr = d_array_ptr (t1saved);
394 tree t2ptr = d_array_ptr (t2saved);
396 /* Compare arrays using memcmp if possible, otherwise for structs,
397 each field is compared inline. */
398 if (t1elem->ty != TY::Tstruct
399 || identity_compare_p (t1elem->isTypeStruct ()->sym))
401 tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
403 result = build_memcmp_call (t1ptr, t2ptr, size);
404 result = build_boolop (code, result, integer_zero_node);
406 else
408 StructDeclaration *sd = t1elem->isTypeStruct ()->sym;
410 result = build_array_struct_comparison (code, sd, t1len,
411 t1ptr, t2ptr);
414 /* Check array length first before passing to memcmp.
415 For equality expressions, this becomes:
416 (e1.length == 0 || memcmp);
417 Otherwise for inequality:
418 (e1.length != 0 && memcmp); */
419 tree tsizecmp = build_boolop (code, t1len, size_zero_node);
420 if (e->op == EXP::equal)
421 result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
422 else
423 result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
425 /* Finally, check if lengths of both arrays match if dynamic.
426 The frontend should have already guaranteed that static arrays
427 have same size. */
428 if (tb1->ty == TY::Tsarray && tb2->ty == TY::Tsarray)
429 gcc_assert (tb1->size () == tb2->size ());
430 else
432 tree tlencmp = build_boolop (code, t1len, t2len);
433 if (e->op == EXP::equal)
434 result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
435 else
436 result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
439 /* Ensure left-to-right order of evaluation. */
440 if (TREE_SIDE_EFFECTS (t2))
441 result = compound_expr (t2saved, result);
443 if (TREE_SIDE_EFFECTS (t1))
444 result = compound_expr (t1saved, result);
446 this->result_ = result;
448 else
450 /* Use _adEq2() to compare each element. */
451 Type *t1array = t1elem->arrayOf ();
452 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
453 d_array_convert (e->e1),
454 d_array_convert (e->e2),
455 build_typeinfo (e, t1array));
457 if (e->op == EXP::notEqual)
458 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
460 this->result_ = result;
463 else if (TypeStruct *ts = tb1->isTypeStruct ())
465 /* Equality for struct objects means the logical product of all
466 equality results of the corresponding object fields. */
467 tree t1 = build_expr (e->e1);
468 tree t2 = build_expr (e->e2);
470 gcc_assert (same_type_p (tb1, tb2));
472 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
474 else if (tb1->ty == TY::Taarray && tb2->ty == TY::Taarray)
476 /* Use _aaEqual() for associative arrays. */
477 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
478 build_typeinfo (e, tb1),
479 build_expr (e->e1),
480 build_expr (e->e2));
482 if (e->op == EXP::notEqual)
483 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
485 this->result_ = result;
487 else
489 /* For operands of other types, equality is defined as the bit pattern
490 of the type matches exactly. */
491 tree t1 = build_expr (e->e1);
492 tree t2 = build_expr (e->e2);
494 this->result_ = d_convert (build_ctype (e->type),
495 build_boolop (code, t1, t2));
499 /* Build an `in' expression. This is a condition to see if an element
500 exists in an associative array. The result is a pointer to the
501 element, or null if false. */
503 void visit (InExp *e) final override
505 Type *tb2 = e->e2->type->toBasetype ();
506 Type *tkey = tb2->isTypeAArray ()->index->toBasetype ();
507 tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
509 /* Build a call to _aaInX(). */
510 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
511 build_expr (e->e2),
512 build_typeinfo (e, tkey),
513 build_address (key));
516 /* Build a relational expression. The result type is bool. */
518 void visit (CmpExp *e) final override
520 Type *tb1 = e->e1->type->toBasetype ();
521 Type *tb2 = e->e2->type->toBasetype ();
523 tree result;
524 tree_code code;
526 switch (e->op)
528 case EXP::lessOrEqual:
529 code = LE_EXPR;
530 break;
532 case EXP::lessThan:
533 code = LT_EXPR;
534 break;
536 case EXP::greaterOrEqual:
537 code = GE_EXPR;
538 break;
540 case EXP::greaterThan:
541 code = GT_EXPR;
542 break;
544 default:
545 gcc_unreachable ();
548 /* For static and dynamic arrays, the relational op is turned into a
549 library call. It is not lowered during codegen. */
550 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
551 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
553 error ("cannot handle comparison of type %<%s == %s%>",
554 tb1->toChars (), tb2->toChars ());
555 gcc_unreachable ();
558 /* Simple comparison. */
559 result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
560 this->result_ = d_convert (build_ctype (e->type), result);
563 /* Build a logical `and if' or `or if' expression. If the right operand
564 expression is void, then the resulting type is void. Otherwise the
565 result is bool. */
567 void visit (LogicalExp *e) final override
569 tree_code code = (e->op == EXP::andAnd) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
571 if (e->e2->type->toBasetype ()->ty != TY::Tvoid)
573 tree t1 = build_expr (e->e1);
574 tree t2 = build_expr (e->e2);
576 t1 = convert_for_condition (t1, e->e1->type);
577 t2 = convert_for_condition (t2, e->e2->type);
579 this->result_ = d_convert (build_ctype (e->type),
580 build_boolop (code, t1, t2));
582 else
584 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
585 tree t2 = build_expr_dtor (e->e2);
587 /* Invert condition for logical or if expression. */
588 if (e->op == EXP::orOr)
589 t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);
591 this->result_ = build_condition (build_ctype (e->type),
592 t1, t2, void_node);
596 /* Build a binary operand expression. Operands go through usual arithmetic
597 conversions to bring them to a common type before evaluating. */
599 void visit (BinExp *e) final override
601 tree_code code;
603 switch (e->op)
605 case EXP::add:
606 case EXP::min:
607 if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
608 || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
610 /* If the result is complex, then we can shortcut binary_op.
611 Frontend should have already validated types and sizes. */
612 tree t1 = build_expr (e->e1);
613 tree t2 = build_expr (e->e2);
615 if (e->op == EXP::min)
616 t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
618 if (e->e1->type->isreal ())
619 this->result_ = complex_expr (build_ctype (e->type), t1, t2);
620 else
621 this->result_ = complex_expr (build_ctype (e->type), t2, t1);
623 return;
625 else
626 code = (e->op == EXP::add)
627 ? PLUS_EXPR : MINUS_EXPR;
628 break;
630 case EXP::mul:
631 code = MULT_EXPR;
632 break;
634 case EXP::div:
635 /* Determine if the div expression is a lowered pointer diff operation.
636 The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */
637 if (MinExp *me = e->e1->isMinExp ())
639 if (me->e1->type->ty == TY::Tpointer
640 && me->e2->type->ty == TY::Tpointer
641 && e->e2->op == EXP::int64)
643 code = EXACT_DIV_EXPR;
644 break;
648 code = e->e1->type->isintegral ()
649 ? TRUNC_DIV_EXPR : RDIV_EXPR;
650 break;
652 case EXP::mod:
653 code = e->e1->type->isfloating ()
654 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
655 break;
657 case EXP::and_:
658 code = BIT_AND_EXPR;
659 break;
661 case EXP::or_:
662 code = BIT_IOR_EXPR;
663 break;
665 case EXP::xor_:
666 code = BIT_XOR_EXPR;
667 break;
669 case EXP::leftShift:
670 code = LSHIFT_EXPR;
671 break;
673 case EXP::rightShift:
674 code = RSHIFT_EXPR;
675 break;
677 case EXP::unsignedRightShift:
678 code = UNSIGNED_RSHIFT_EXPR;
679 break;
681 default:
682 gcc_unreachable ();
685 this->result_ = binary_op (code, build_ctype (e->type),
686 build_expr (e->e1), build_expr (e->e2));
690 /* Build a concat expression, which concatenates two or more arrays of the
691 same type, producing a dynamic array with the result. If one operand
692 is an element type, that element is converted to an array of length 1. */
694 void visit (CatExp *e) final override
696 /* This error is only emitted during the code generation pass because
697 concatentation is allowed in CTFE. */
698 if (!global.params.useGC)
700 error_at (make_location_t (e->loc),
701 "array concatenation of expression %qs requires the GC and "
702 "cannot be used with %<-fno-druntime%>", e->toChars ());
703 this->result_ = error_mark_node;
704 return;
707 /* All concat expressions should have been rewritten to `_d_arraycatnTX` in
708 the semantic phase. */
709 gcc_assert (e->lowering);
711 this->result_ = build_expr (e->lowering);
714 /* Build an assignment operator expression. The right operand is implicitly
715 converted to the type of the left operand, and assigned to it. */
717 void visit (BinAssignExp *e) final override
719 tree_code code;
720 Expression *e1b = e->e1;
722 switch (e->op)
724 case EXP::addAssign:
725 code = PLUS_EXPR;
726 break;
728 case EXP::minAssign:
729 code = MINUS_EXPR;
730 break;
732 case EXP::mulAssign:
733 code = MULT_EXPR;
734 break;
736 case EXP::divAssign:
737 code = e->e1->type->isintegral ()
738 ? TRUNC_DIV_EXPR : RDIV_EXPR;
739 break;
741 case EXP::modAssign:
742 code = e->e1->type->isfloating ()
743 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
744 break;
746 case EXP::andAssign:
747 code = BIT_AND_EXPR;
748 break;
750 case EXP::orAssign:
751 code = BIT_IOR_EXPR;
752 break;
754 case EXP::xorAssign:
755 code = BIT_XOR_EXPR;
756 break;
758 case EXP::powAssign:
759 gcc_unreachable ();
761 case EXP::leftShiftAssign:
762 code = LSHIFT_EXPR;
763 break;
765 case EXP::rightShiftAssign:
766 case EXP::unsignedRightShiftAssign:
767 /* Use the original lhs type before it was promoted. The left operand
768 of `>>>=' does not undergo integral promotions before shifting.
769 Strip off casts just incase anyway. */
770 while (e1b->op == EXP::cast_)
772 CastExp *ce = e1b->isCastExp ();
773 gcc_assert (same_type_p (ce->type, ce->to));
774 e1b = ce->e1;
776 code = (e->op == EXP::rightShiftAssign) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
777 break;
779 default:
780 gcc_unreachable ();
783 tree exp = binop_assignment (code, e1b, e->e2);
784 this->result_ = convert_expr (exp, e1b->type, e->type);
787 /* Build a concat assignment expression. The right operand is appended
788 to the left operand. */
790 void visit (CatAssignExp *e) final override
792 if (!global.params.useGC)
794 error_at (make_location_t (e->loc),
795 "appending to array in %qs requires the GC and cannot be "
796 "used with %<-fno-druntime%>", e->toChars ());
797 this->result_ = error_mark_node;
798 return;
801 Type *tb1 = e->e1->type->toBasetype ();
802 Type *tb2 = e->e2->type->toBasetype ();
804 if (e->op == EXP::concatenateDcharAssign)
806 /* Append a dchar to a char[] or wchar[]:
807 The assignment is handled by the D run-time library, so only
808 need to call `_d_arrayappend[cw]d(&e1, e2)' */
809 Type *etype = tb1->nextOf ()->toBasetype ();
811 /* Save the address of `e1', so it can be evaluated first.
812 As all D run-time library functions for concat assignments update
813 `e1' in-place and then return its value, the saved address can also
814 be used as the result of this expression as well. */
815 tree lhs = build_expr (e->e1);
816 tree lexpr = stabilize_expr (&lhs);
817 tree ptr = d_save_expr (build_address (lhs));
818 tree result = NULL_TREE;
820 gcc_assert (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar
821 && (etype->ty == TY::Tchar || etype->ty == TY::Twchar));
823 libcall_fn libcall = (etype->ty == TY::Tchar)
824 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
826 result = build_libcall (libcall, e->type, 2,
827 ptr, build_expr (e->e2));
829 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
830 result = compound_expr (compound_expr (lexpr, ptr), result);
831 this->result_ = compound_expr (result, build_deref (ptr));
833 else
835 gcc_assert (e->op == EXP::concatenateAssign
836 || e->op == EXP::concatenateElemAssign);
837 gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray);
838 /* Appending an element or array to another array has already been
839 handled by the front-end. */
840 gcc_assert (e->lowering);
842 this->result_ = build_expr (e->lowering);
846 /* Build an assignment expression. The right operand is implicitly
847 converted to the type of the left operand, and assigned to it. */
849 void visit (AssignExp *e) final override
851 /* First, handle special assignment semantics. */
853 /* Look for array.length = n; */
854 if (e->e1->op == EXP::arrayLength)
856 /* This case should have been rewritten to `_d_arraysetlengthT` in the
857 semantic phase. */
858 gcc_unreachable ();
861 /* Look for exp = noreturn; */
862 if (e->e2->type->isTypeNoreturn ())
864 /* If the RHS is a `noreturn' expression, there is no point generating
865 any code for the assignment, just evaluate side effects. */
866 tree t1 = build_expr (e->e1);
867 tree t2 = build_expr (e->e2);
868 this->result_ = compound_expr (t1, t2);
869 return;
872 /* Look for array[] = n; */
873 if (e->e1->op == EXP::slice)
875 SliceExp *se = e->e1->isSliceExp ();
876 Type *stype = se->e1->type->toBasetype ();
877 Type *etype = stype->nextOf ()->toBasetype ();
879 /* Determine if we need to run postblit or dtor. */
880 bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
881 bool destructor = needs_dtor (etype);
883 if (e->memset == MemorySet::blockAssign)
885 /* Set a range of elements to one value. */
886 tree t1 = build_expr (e->e1);
887 tree t2 = build_expr (e->e2);
888 tree result;
890 /* Extract any array bounds checks from the slice expression. */
891 tree init = stabilize_expr (&t1);
892 t1 = d_save_expr (t1);
894 if ((postblit || destructor) && e->op != EXP::blit)
896 /* This case should have been rewritten to `_d_arraysetassign`
897 in the semantic phase. */
898 gcc_unreachable ();
901 if (integer_zerop (t2))
903 tree size = size_mult_expr (d_array_length (t1),
904 size_int (etype->size ()));
905 result = build_memset_call (d_array_ptr (t1), size);
907 else
908 result = build_array_set (d_array_ptr (t1),
909 d_array_length (t1), t2);
911 result = compound_expr (init, result);
912 this->result_ = compound_expr (result, t1);
914 else
916 /* Perform a memcpy operation. */
917 gcc_assert (e->e2->type->ty != TY::Tpointer);
919 if (!postblit && !destructor)
921 tree t1 = d_save_expr (d_array_convert (e->e1));
922 tree t2 = d_save_expr (d_array_convert (e->e2));
924 /* References to array data. */
925 tree t1ptr = d_array_ptr (t1);
926 tree t1len = d_array_length (t1);
927 tree t2ptr = d_array_ptr (t2);
929 /* Generate: memcpy(to, from, size) */
930 tree size = size_mult_expr (t1len, size_int (etype->size ()));
931 tree result = build_memcpy_call (t1ptr, t2ptr, size);
933 /* Insert check that array lengths match and do not overlap. */
934 if (array_bounds_check ())
936 /* tlencmp = (t1len == t2len) */
937 tree t2len = d_array_length (t2);
938 tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len);
940 /* toverlap = (t1ptr + size <= t2ptr
941 || t2ptr + size <= t1ptr) */
942 tree t1ptrcmp = build_boolop (LE_EXPR,
943 build_offset (t1ptr, size),
944 t2ptr);
945 tree t2ptrcmp = build_boolop (LE_EXPR,
946 build_offset (t2ptr, size),
947 t1ptr);
948 tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp,
949 t2ptrcmp);
951 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */
952 tree tassert = build_array_bounds_call (e->loc);
953 tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR,
954 tlencmp, toverlap);
956 result = build_condition (void_type_node, tboundscheck,
957 result, tassert);
960 this->result_ = compound_expr (result, t1);
962 else if ((postblit || destructor)
963 && e->op != EXP::blit && e->op != EXP::construct)
965 /* Assigning to a non-trivially copyable array has already been
966 handled by the front-end. */
967 gcc_unreachable ();
969 else
971 /* Generate: _d_arraycopy() */
972 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
973 size_int (etype->size ()),
974 d_array_convert (e->e2),
975 d_array_convert (e->e1));
979 return;
982 /* Look for reference initializations. */
983 if (e->memset == MemorySet::referenceInit)
985 gcc_assert (e->op == EXP::construct || e->op == EXP::blit);
986 gcc_assert (e->e1->op == EXP::variable);
988 Declaration *decl = e->e1->isVarExp ()->var;
989 if (decl->storage_class & (STCout | STCref))
991 tree t2 = convert_for_assignment (e->e2, e->e1->type);
992 tree t1 = build_expr (e->e1);
993 /* Want reference to lhs, not indirect ref. */
994 t1 = TREE_OPERAND (t1, 0);
995 t2 = build_address (t2);
997 this->result_ = indirect_ref (build_ctype (e->type),
998 build_assign (INIT_EXPR, t1, t2));
999 return;
1003 /* Other types of assignments that may require post construction. */
1004 Type *tb1 = e->e1->type->toBasetype ();
1005 tree_code modifycode = (e->op == EXP::construct) ? INIT_EXPR : MODIFY_EXPR;
1007 /* Look for struct assignment. */
1008 if (tb1->ty == TY::Tstruct)
1010 tree t1 = build_expr (e->e1);
1011 tree t2 = convert_for_assignment (e->e2, e->e1->type, true);
1012 StructDeclaration *sd = tb1->isTypeStruct ()->sym;
1014 /* Look for struct = 0. */
1015 if (e->e2->op == EXP::int64)
1017 /* Use memset to fill struct. */
1018 gcc_assert (e->op == EXP::blit);
1019 tree result = build_memset_call (t1);
1021 /* Maybe set-up hidden pointer to outer scope context. */
1022 if (sd->isNested ())
1024 tree field = get_symbol_decl (sd->vthis);
1025 tree value = build_vthis (sd);
1027 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1028 result = compound_expr (result, vthis_exp);
1031 this->result_ = compound_expr (result, t1);
1033 else
1035 /* Simple struct literal assignment. */
1036 tree init = NULL_TREE;
1038 /* Fill any alignment holes in the struct using memset. */
1039 if ((e->op == EXP::construct
1040 || (e->e2->op == EXP::structLiteral && e->op == EXP::blit))
1041 && (sd->isUnionDeclaration () || !identity_compare_p (sd)))
1043 t1 = stabilize_reference (t1);
1044 init = build_memset_call (t1);
1047 /* Elide generating assignment if init is all zeroes. */
1048 if (init != NULL_TREE && initializer_zerop (t2))
1049 this->result_ = compound_expr (init, t1);
1050 else
1052 tree result = build_assign (modifycode, t1, t2);
1053 this->result_ = compound_expr (init, result);
1057 return;
1060 /* Look for static array assignment. */
1061 if (tb1->ty == TY::Tsarray)
1063 /* Look for array = 0. */
1064 if (e->e2->op == EXP::int64)
1066 /* Use memset to fill the array. */
1067 gcc_assert (e->op == EXP::blit);
1068 this->result_ = build_memset_call (build_expr (e->e1));
1069 return;
1072 Type *etype = tb1->nextOf ();
1073 gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray);
1075 /* Determine if we need to run postblit. */
1076 const bool postblit = needs_postblit (etype);
1077 const bool destructor = needs_dtor (etype);
1078 const bool lvalue = lvalue_p (e->e2);
1080 /* Optimize static array assignment with array literal. Even if the
1081 elements in rhs are all rvalues and don't have to call postblits,
1082 this assignment should call dtors on old assigned elements. */
1083 if ((!postblit && !destructor)
1084 || (e->op == EXP::construct && e->e2->op == EXP::arrayLiteral)
1085 || (e->op == EXP::construct && e->e2->op == EXP::call)
1086 || (e->op == EXP::construct && !lvalue && postblit)
1087 || (e->op == EXP::blit || e->e1->type->size () == 0))
1089 tree t1 = build_expr (e->e1);
1090 tree t2 = convert_for_assignment (e->e2, e->e1->type);
1092 this->result_ = build_assign (modifycode, t1, t2);
1093 return;
1096 /* All other kinds of lvalue or rvalue static array assignment.
1097 Array construction has already been handled by the front-end. */
1098 gcc_assert (e->op != EXP::construct);
1099 gcc_unreachable ();
1102 /* Simple assignment. */
1103 tree t1 = build_expr (e->e1);
1104 tree t2 = convert_for_assignment (e->e2, e->e1->type);
1106 this->result_ = build_assign (modifycode, t1, t2);
1109 /* Build an assignment expression that has been lowered in the front-end. */
1111 void visit (LoweredAssignExp *e) final override
1113 this->result_ = build_expr (e->lowering);
1116 /* Build a throw expression. */
1118 void visit (ThrowExp *e) final override
1120 tree arg = build_expr_dtor (e->e1);
1121 this->result_ = build_libcall (LIBCALL_THROW, Type::tvoid, 1, arg);
1124 /* Build a postfix expression. */
1126 void visit (PostExp *e) final override
1128 tree result;
1130 if (e->op == EXP::plusPlus)
1132 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1133 build_expr (e->e1), build_expr (e->e2));
1135 else if (e->op == EXP::minusMinus)
1137 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1138 build_expr (e->e1), build_expr (e->e2));
1140 else
1141 gcc_unreachable ();
1143 TREE_SIDE_EFFECTS (result) = 1;
1144 this->result_ = result;
1147 /* Build an index expression. */
1149 void visit (IndexExp *e) final override
1151 Type *tb1 = e->e1->type->toBasetype ();
1153 if (tb1->ty == TY::Taarray)
1155 /* Get the key for the associative array. */
1156 Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
1157 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1158 libcall_fn libcall;
1159 tree tinfo, ptr;
1161 if (e->modifiable)
1163 libcall = LIBCALL_AAGETY;
1164 ptr = build_address (build_expr (e->e1));
1165 tinfo = build_typeinfo (e, tb1->unSharedOf ()->mutableOf ());
1167 else
1169 libcall = LIBCALL_AAGETRVALUEX;
1170 ptr = build_expr (e->e1);
1171 tinfo = build_typeinfo (e, tkey);
1174 /* Index the associative array. */
1175 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1176 ptr, tinfo,
1177 size_int (tb1->nextOf ()->size ()),
1178 build_address (key));
1180 if (!e->indexIsInBounds && array_bounds_check ())
1182 tree tassert = build_array_bounds_call (e->loc);
1184 result = d_save_expr (result);
1185 result = build_condition (TREE_TYPE (result),
1186 d_truthvalue_conversion (result),
1187 result, tassert);
1190 this->result_ = indirect_ref (build_ctype (e->type), result);
1192 else
1194 /* Get the array and length for static and dynamic arrays. */
1195 tree array = d_save_expr (build_expr (e->e1));
1197 tree length = NULL_TREE;
1198 if (tb1->ty != TY::Tpointer)
1199 length = get_array_length (array, tb1);
1200 else
1201 gcc_assert (e->lengthVar == NULL);
1203 /* The __dollar variable just becomes a placeholder for the
1204 actual length. */
1205 if (e->lengthVar)
1206 e->lengthVar->csym = length;
1208 /* Generate the index. */
1209 tree index = build_expr (e->e2);
1211 /* If it's a static array and the index is constant, the front end has
1212 already checked the bounds. */
1213 if (tb1->ty != TY::Tpointer)
1214 index = build_bounds_index_condition (e, index, length);
1216 /* Convert vectors to their underlying array type. */
1217 if (VECTOR_TYPE_P (TREE_TYPE (array)))
1219 tree array_type =
1220 build_array_type_nelts (TREE_TYPE (TREE_TYPE (array)),
1221 TYPE_VECTOR_SUBPARTS (TREE_TYPE (array)));
1222 d_mark_addressable (array, false);
1223 array = build1 (VIEW_CONVERT_EXPR, array_type, array);
1226 if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
1228 /* Generate `array[index]'. When the index is non-constant, we must
1229 mark the array as addressable because we'll need to do pointer
1230 arithmetic on its address. */
1231 if (TREE_CODE (index) != INTEGER_CST)
1232 d_mark_addressable (array);
1234 this->result_ = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
1235 array, index, NULL_TREE, NULL_TREE);
1237 else
1239 /* Generate `array.ptr[index]'. */
1240 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1241 ptr = void_okay_p (ptr);
1242 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1243 build_pointer_index (ptr, index));
1248 /* Build a comma expression. The type is the type of the right operand. */
1250 void visit (CommaExp *e) final override
1252 tree t1 = build_expr (e->e1);
1253 tree t2 = build_expr (e->e2);
1254 tree type = e->type ? build_ctype (e->type) : void_type_node;
1256 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1259 /* Build an array length expression. Returns the number of elements
1260 in the array. The result is of type size_t. */
1262 void visit (ArrayLengthExp *e) final override
1264 if (e->e1->type->toBasetype ()->ty == TY::Tarray)
1265 this->result_ = d_array_length (build_expr (e->e1));
1266 else
1268 /* Static arrays have already been handled by the front-end. */
1269 error ("unexpected type for array length: %qs", e->type->toChars ());
1270 this->result_ = error_mark_node;
1274 /* Build a delegate pointer expression. This will return the frame
1275 pointer value as a type void*. */
1277 void visit (DelegatePtrExp *e) final override
1279 tree t1 = build_expr (e->e1);
1280 this->result_ = delegate_object (t1);
1283 /* Build a delegate function pointer expression. This will return the
1284 function pointer value as a function type. */
1286 void visit (DelegateFuncptrExp *e) final override
1288 tree t1 = build_expr (e->e1);
1289 this->result_ = delegate_method (t1);
1292 /* Build a slice expression. */
1294 void visit (SliceExp *e) final override
1296 Type *tb = e->type->toBasetype ();
1297 Type *tb1 = e->e1->type->toBasetype ();
1298 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray);
1300 /* Use convert-to-dynamic-array code if possible. */
1301 if (!e->lwr)
1303 tree result = build_expr (e->e1);
1304 if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
1305 result = convert_expr (result, e->e1->type, e->type);
1307 this->result_ = result;
1308 return;
1310 else
1311 gcc_assert (e->upr != NULL);
1313 /* Get the data pointer and length for static and dynamic arrays. */
1314 tree array = d_save_expr (build_expr (e->e1));
1315 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1316 tree length = NULL_TREE;
1318 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1319 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1320 if (tb1->ty != TY::Tpointer)
1321 length = get_array_length (array, tb1);
1322 else
1323 gcc_assert (e->lengthVar == NULL);
1325 /* The __dollar variable just becomes a placeholder for the
1326 actual length. */
1327 if (e->lengthVar)
1328 e->lengthVar->csym = length;
1330 /* Generate upper and lower bounds. */
1331 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1332 tree upr_tree = d_save_expr (build_expr (e->upr));
1334 /* If the upper bound has any side effects, then the lower bound should be
1335 copied to a temporary always. */
1336 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1337 lwr_tree = save_expr (lwr_tree);
1339 /* Adjust the .ptr offset. */
1340 if (!integer_zerop (lwr_tree))
1342 tree ptrtype = TREE_TYPE (ptr);
1343 ptr = build_pointer_index (void_okay_p (ptr), lwr_tree);
1344 ptr = build_nop (ptrtype, ptr);
1347 /* Nothing more to do for static arrays, their bounds checking has been
1348 done at compile-time. */
1349 if (tb->ty == TY::Tsarray)
1351 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1352 return;
1354 else
1355 gcc_assert (tb->ty == TY::Tarray);
1357 /* Generate bounds checking code. */
1358 tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree,
1359 length);
1360 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1361 this->result_ = compound_expr (array, result);
1364 /* Build a cast expression, which converts the given unary expression to the
1365 type of result. */
1367 void visit (CastExp *e) final override
1369 Type *ebtype = e->e1->type->toBasetype ();
1370 Type *tbtype = e->to->toBasetype ();
1371 tree result = build_expr (e->e1, this->constp_, this->literalp_);
1373 /* Just evaluate e1 if it has any side effects. */
1374 if (tbtype->ty == TY::Tvoid)
1375 this->result_ = build_nop (build_ctype (tbtype), result);
1376 else
1377 this->result_ = convert_for_rvalue (result, ebtype, tbtype);
1380 /* Build a delete expression. */
1382 void visit (DeleteExp *e) final override
1384 tree t1 = build_expr (e->e1);
1385 Type *tb1 = e->e1->type->toBasetype ();
1387 if (tb1->ty == TY::Tclass)
1389 /* For class object references, if there is a destructor for that class,
1390 the destructor is called for the object instance. */
1391 gcc_assert (e->e1->op == EXP::variable);
1393 VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
1394 gcc_assert (v && v->onstack ());
1396 libcall_fn libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1397 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1399 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1400 return;
1402 else
1404 error ("don%'t know how to delete %qs", e->e1->toChars ());
1405 this->result_ = error_mark_node;
1409 /* Build a remove expression, which removes a particular key from an
1410 associative array. */
1412 void visit (RemoveExp *e) final override
1414 /* Check that the array is actually an associative array. */
1415 if (e->e1->type->toBasetype ()->ty == TY::Taarray)
1417 Type *tb = e->e1->type->toBasetype ();
1418 Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
1419 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1421 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1422 build_expr (e->e1),
1423 build_typeinfo (e, tkey),
1424 build_address (index));
1426 else
1428 error ("%qs is not an associative array", e->e1->toChars ());
1429 this->result_ = error_mark_node;
1433 /* Build an unary not expression. */
1435 void visit (NotExp *e) final override
1437 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1438 /* Need to convert to boolean type or this will fail. */
1439 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1441 this->result_ = d_convert (build_ctype (e->type), result);
1444 /* Build a compliment expression, where all the bits in the value are
1445 complemented. Note: unlike in C, the usual integral promotions
1446 are not performed prior to the complement operation. */
1448 void visit (ComExp *e) final override
1450 TY ty1 = e->e1->type->toBasetype ()->ty;
1451 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1453 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1454 build_expr (e->e1));
1457 /* Build an unary negation expression. */
1459 void visit (NegExp *e) final override
1461 TY ty1 = e->e1->type->toBasetype ()->ty;
1462 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1464 tree type = build_ctype (e->type);
1465 tree expr = build_expr (e->e1);
1467 /* If the operation needs excess precision. */
1468 tree eptype = excess_precision_type (type);
1469 if (eptype != NULL_TREE)
1470 expr = d_convert (eptype, expr);
1471 else
1472 eptype = type;
1474 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1475 this->result_ = d_convert (type, ret);
1478 /* Build a pointer index expression. */
1480 void visit (PtrExp *e) final override
1482 Type *tnext = NULL;
1483 size_t offset;
1484 tree result;
1486 if (e->e1->op == EXP::add)
1488 AddExp *ae = e->e1->isAddExp ();
1489 if (ae->e1->op == EXP::address
1490 && ae->e2->isConst () && ae->e2->type->isintegral ())
1492 Expression *ex = ae->e1->isAddrExp ()->e1;
1493 tnext = ex->type->toBasetype ();
1494 result = build_expr (ex);
1495 offset = ae->e2->toUInteger ();
1498 else if (e->e1->op == EXP::symbolOffset)
1500 SymOffExp *se = e->e1->isSymOffExp ();
1501 if (!declaration_reference_p (se->var))
1503 tnext = se->var->type->toBasetype ();
1504 result = get_decl_tree (se->var);
1505 offset = se->offset;
1509 /* Produce better code by converting *(#record + n) to
1510 COMPONENT_REFERENCE. Otherwise, the variable will always be
1511 allocated in memory because its address is taken. */
1512 if (tnext && tnext->ty == TY::Tstruct)
1514 StructDeclaration *sd = tnext->isTypeStruct ()->sym;
1516 for (size_t i = 0; i < sd->fields.length; i++)
1518 VarDeclaration *field = sd->fields[i];
1520 if (field->offset == offset
1521 && same_type_p (field->type, e->type))
1523 /* Catch errors, backend will ICE otherwise. */
1524 if (error_operand_p (result))
1525 this->result_ = result;
1526 else
1528 result = component_ref (result, get_symbol_decl (field));
1529 this->result_ = result;
1531 return;
1533 else if (field->offset > offset)
1534 break;
1538 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1541 /* Build an unary address expression. */
1543 void visit (AddrExp *e) final override
1545 tree type = build_ctype (e->type);
1546 tree exp;
1548 /* The frontend optimizer can convert const symbol into a struct literal.
1549 Taking the address of a struct literal is otherwise illegal. */
1550 if (e->e1->op == EXP::structLiteral)
1552 StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
1553 gcc_assert (sle != NULL);
1555 /* Build the reference symbol, the decl is built first as the
1556 initializer may have recursive references. */
1557 if (!sle->sym)
1559 sle->sym = build_artificial_decl (build_ctype (sle->type),
1560 NULL_TREE, "S");
1561 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1562 d_pushdecl (sle->sym);
1563 rest_of_decl_compilation (sle->sym, 1, 0);
1566 exp = sle->sym;
1568 else
1569 exp = build_expr (e->e1, this->constp_, this->literalp_);
1571 TREE_CONSTANT (exp) = 0;
1572 this->result_ = d_convert (type, build_address (exp));
1575 /* Build a function call expression. */
1577 void visit (CallExp *e) final override
1579 Type *tb = e->e1->type->toBasetype ();
1580 Expression *e1b = e->e1;
1582 tree callee = NULL_TREE;
1583 tree object = NULL_TREE;
1584 tree cleanup = NULL_TREE;
1585 tree returnvalue = NULL_TREE;
1586 TypeFunction *tf = NULL;
1588 /* Calls to delegates can sometimes look like this. */
1589 if (e1b->op == EXP::comma)
1591 e1b = e1b->isCommaExp ()->e2;
1592 gcc_assert (e1b->op == EXP::variable);
1594 Declaration *var = e1b->isVarExp ()->var;
1595 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1598 if (e1b->op == EXP::dotVariable && tb->ty != TY::Tdelegate)
1600 DotVarExp *dve = e1b->isDotVarExp ();
1602 /* Don't modify the static initializer for struct literals. */
1603 if (dve->e1->op == EXP::structLiteral)
1605 StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
1606 sle->useStaticInit = false;
1609 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1610 if (fd != NULL)
1612 /* Get the correct callee from the DotVarExp object. */
1613 tree fndecl = get_symbol_decl (fd);
1614 AggregateDeclaration *ad = fd->isThis ();
1616 /* Static method; ignore the object instance. */
1617 if (!ad)
1618 callee = build_address (fndecl);
1619 else
1621 tree thisexp = build_expr (dve->e1);
1623 /* When constructing temporaries, if the constructor throws,
1624 then the object is destructed even though it is not a fully
1625 constructed object yet. And so this call will need to be
1626 moved inside the TARGET_EXPR_INITIAL slot. */
1627 if (fd->isCtorDeclaration ()
1628 && TREE_CODE (thisexp) == COMPOUND_EXPR
1629 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1630 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1632 cleanup = TREE_OPERAND (thisexp, 0);
1633 thisexp = TREE_OPERAND (thisexp, 1);
1636 if (TREE_CODE (thisexp) == CONSTRUCTOR)
1637 thisexp = force_target_expr (thisexp);
1639 /* Want reference to `this' object. */
1640 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1641 thisexp = build_address (thisexp);
1643 /* Make the callee a virtual call. */
1644 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1646 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1647 tree thistype = build_ctype (ad->handleType ());
1648 thisexp = build_nop (thistype, d_save_expr (thisexp));
1649 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1651 else
1652 fndecl = build_address (fndecl);
1654 /* C++ constructors return void, even though front-end semantic
1655 treats them as implicitly returning `this'. Set returnvalue
1656 to override the result of this expression. */
1657 if (fd->isCtorDeclaration ())
1659 thisexp = d_save_expr (thisexp);
1660 returnvalue = thisexp;
1663 callee = build_method_call (fndecl, thisexp, fd->type);
1668 if (callee == NULL_TREE)
1669 callee = build_expr (e1b);
1671 if (METHOD_CALL_EXPR (callee))
1673 /* This could be a delegate expression (TY == Tdelegate), but not
1674 actually a delegate variable. */
1675 if (e1b->op == EXP::dotVariable)
1677 /* This gets the true function type, getting the function type
1678 from e1->type can sometimes be incorrect, such as when calling
1679 a `ref' return function. */
1680 tf = get_function_type (e1b->isDotVarExp ()->var->type);
1682 else
1683 tf = get_function_type (tb);
1685 extract_from_method_call (callee, callee, object);
1687 else if (tb->ty == TY::Tdelegate)
1689 /* Delegate call, extract .object and .funcptr from var. */
1690 callee = d_save_expr (callee);
1691 tf = get_function_type (tb);
1692 object = delegate_object (callee);
1693 callee = delegate_method (callee);
1695 else if (e1b->op == EXP::variable)
1697 FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
1698 gcc_assert (fd != NULL);
1699 tf = get_function_type (fd->type);
1701 if (fd->isNested ())
1703 /* Maybe re-evaluate symbol storage treating `fd' as public. */
1704 if (call_by_alias_p (d_function_chain->function, fd))
1705 TREE_PUBLIC (callee) = 1;
1707 object = get_frame_for_symbol (fd);
1709 else if (fd->needThis ())
1711 error_at (make_location_t (e1b->loc),
1712 "need %<this%> to access member %qs", fd->toChars ());
1713 /* Continue compiling... */
1714 object = null_pointer_node;
1717 else
1719 /* Normal direct function call. */
1720 tf = get_function_type (tb);
1723 gcc_assert (tf != NULL);
1725 /* Now we have the type, callee and maybe object reference,
1726 build the call expression. */
1727 tree exp = d_build_call (tf, callee, object, e->arguments);
1729 /* Record whether the call expression has no side effects, so we can check
1730 for an unused return value later. */
1731 if (TREE_CODE (exp) == CALL_EXPR && CALL_EXPR_FN (exp) != NULL_TREE
1732 && call_side_effect_free_p (e->f, e->e1->type))
1733 CALL_EXPR_WARN_IF_UNUSED (exp) = 1;
1735 if (returnvalue != NULL_TREE)
1736 exp = compound_expr (exp, returnvalue);
1738 if (tf->isref ())
1739 exp = build_deref (exp);
1741 /* Some library calls are defined to return a generic type.
1742 this->type is the real type we want to return. */
1743 if (e->type->isTypeBasic ())
1744 exp = d_convert (build_ctype (e->type), exp);
1746 /* If this call was found to be a constructor for a temporary with a
1747 cleanup, then move the call inside the TARGET_EXPR. */
1748 if (cleanup != NULL_TREE)
1750 tree init = TARGET_EXPR_INITIAL (cleanup);
1751 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1753 /* Keep the return value outside the TARGET_EXPR. */
1754 if (returnvalue != NULL_TREE)
1755 cleanup = compound_expr (cleanup, TREE_OPERAND (exp, 1));
1757 exp = cleanup;
1760 this->result_ = exp;
1763 /* Build a delegate expression. */
1765 void visit (DelegateExp *e) final override
1767 if (e->func->semanticRun == PASS::semantic3done)
1769 /* Add the function as nested function if it belongs to this module.
1770 ie: it is a member of this module, or it is a template instance. */
1771 Dsymbol *owner = e->func->toParent ();
1772 while (!owner->isTemplateInstance () && owner->toParent ())
1773 owner = owner->toParent ();
1774 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1775 build_decl_tree (e->func);
1778 tree fndecl;
1779 tree object;
1781 if (e->func->isNested () && !e->func->isThis ())
1783 if (e->e1->op == EXP::null_)
1784 object = build_expr (e->e1);
1785 else
1786 object = get_frame_for_symbol (e->func);
1788 fndecl = build_address (get_symbol_decl (e->func));
1790 else
1792 if (!e->func->isThis ())
1794 error ("delegates are only for non-static functions");
1795 this->result_ = error_mark_node;
1796 return;
1799 object = build_expr (e->e1);
1801 /* Want reference to `this' object. */
1802 if (e->e1->type->ty != TY::Tclass && e->e1->type->ty != TY::Tpointer)
1803 object = build_address (object);
1805 /* Object reference could be the outer `this' field of a class or
1806 closure of type `void*'. Cast it to the right type. */
1807 if (e->e1->type->ty == TY::Tclass)
1808 object = d_convert (build_ctype (e->e1->type), object);
1810 fndecl = get_symbol_decl (e->func);
1812 /* Get pointer to function out of the virtual table. */
1813 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1814 && e->e1->op != EXP::super_ && e->e1->op != EXP::dotType)
1816 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1817 object = d_save_expr (object);
1818 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1820 else
1821 fndecl = build_address (fndecl);
1824 this->result_ = build_method_call (fndecl, object, e->type);
1827 /* Build a type component expression. */
1829 void visit (DotTypeExp *e) final override
1831 /* Just a pass through to underlying expression. */
1832 this->result_ = build_expr (e->e1);
1835 /* Build a component reference expression. */
1837 void visit (DotVarExp *e) final override
1839 VarDeclaration *vd = e->var->isVarDeclaration ();
1841 /* This could also be a function, but relying on that being taken
1842 care of by the visitor interface for CallExp. */
1843 if (vd != NULL)
1845 if (!vd->isField ())
1846 this->result_ = get_decl_tree (vd);
1847 else
1849 tree object = build_expr (e->e1);
1850 Type *tb = e->e1->type->toBasetype ();
1852 if (tb->ty != TY::Tstruct)
1853 object = build_deref (object);
1855 /* __complex is represented as a struct in the front-end, but
1856 underlying is really a complex type. */
1857 if (e->e1->type->ty == TY::Tenum
1858 && e->e1->type->isTypeEnum ()->sym->isSpecial ())
1859 object = underlying_complex_expr (build_ctype (tb), object);
1861 this->result_ = component_ref (object, get_symbol_decl (vd));
1864 else
1866 error ("%qs is not a field, but a %qs",
1867 e->var->toChars (), e->var->kind ());
1868 this->result_ = error_mark_node;
1872 /* Build an assert expression, used to declare conditions that must hold at
1873 that a given point in the program. */
1875 void visit (AssertExp *e) final override
1877 Type *tb1 = e->e1->type->toBasetype ();
1878 tree arg = build_expr (e->e1);
1879 tree tmsg = NULL_TREE;
1880 tree assert_pass = void_node;
1881 tree assert_fail;
1883 if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ())
1885 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1886 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1887 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1888 libcall_fn libcall;
1890 if (e->msg)
1892 tmsg = build_expr_dtor (e->msg);
1893 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1895 else
1896 libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP;
1898 /* Build a call to _d_assert(). */
1899 assert_fail = build_assert_call (e->loc, libcall, tmsg);
1901 if (global.params.useInvariants == CHECKENABLEon)
1903 /* If the condition is a D class or struct object with an invariant,
1904 call it if the condition result is true. */
1905 if (tb1->ty == TY::Tclass)
1907 ClassDeclaration *cd = tb1->isClassHandle ();
1908 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
1910 arg = d_save_expr (arg);
1911 assert_pass = build_libcall (LIBCALL_INVARIANT,
1912 Type::tvoid, 1, arg);
1915 else if (tb1->ty == TY::Tpointer
1916 && tb1->nextOf ()->ty == TY::Tstruct)
1918 StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
1919 if (sd->inv != NULL)
1921 Expressions args;
1922 arg = d_save_expr (arg);
1923 assert_pass = d_build_call_expr (sd->inv, arg, &args);
1928 else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
1930 /* Generate: __builtin_trap() */
1931 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
1932 assert_fail = build_call_expr (fn, 0);
1934 else
1936 /* Assert contracts are turned off. */
1937 this->result_ = void_node;
1938 return;
1941 /* Build condition that we are asserting in this contract. */
1942 tree condition = convert_for_condition (arg, e->e1->type);
1944 /* We expect the condition to always be true, as what happens if an assert
1945 contract is false is undefined behavior. */
1946 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
1947 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
1948 tree pred_type = TREE_VALUE (arg_types);
1949 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
1951 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
1952 build_int_cst (expected_type, 1));
1953 condition = d_truthvalue_conversion (condition);
1955 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
1958 /* Build a declaration expression. */
1960 void visit (DeclarationExp *e) final override
1962 /* Compile the declaration. */
1963 push_stmt_list ();
1964 build_decl_tree (e->declaration);
1965 tree result = pop_stmt_list ();
1967 /* Construction of an array for typesafe-variadic function arguments
1968 can cause an empty STMT_LIST here. This can causes problems
1969 during gimplification. */
1970 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
1971 result = build_empty_stmt (input_location);
1973 this->result_ = result;
1976 /* Build a typeid expression. Returns an instance of class TypeInfo
1977 corresponding to. */
1979 void visit (TypeidExp *e) final override
1981 if (Type *tid = isType (e->obj))
1983 tree ti = build_typeinfo (e, tid);
1985 /* If the typeinfo is at an offset. */
1986 if (tid->vtinfo->offset)
1987 ti = build_offset (ti, size_int (tid->vtinfo->offset));
1989 this->result_ = build_nop (build_ctype (e->type), ti);
1991 else if (Expression *tid = isExpression (e->obj))
1993 Type *type = tid->type->toBasetype ();
1994 assert (type->ty == TY::Tclass);
1996 /* Generate **classptr to get the classinfo. */
1997 tree ci = build_expr (tid);
1998 ci = indirect_ref (ptr_type_node, ci);
1999 ci = indirect_ref (ptr_type_node, ci);
2001 /* Add extra indirection for interfaces. */
2002 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
2003 ci = indirect_ref (ptr_type_node, ci);
2005 this->result_ = build_nop (build_ctype (e->type), ci);
2007 else
2008 gcc_unreachable ();
2011 /* Build a function/lambda expression. */
2013 void visit (FuncExp *e) final override
2015 Type *ftype = e->type->toBasetype ();
2017 /* This check is for lambda's, remove `vthis' as function isn't nested. */
2018 if (e->fd->tok == TOK::reserved && ftype->ty == TY::Tpointer)
2020 e->fd->tok = TOK::function_;
2021 e->fd->vthis = NULL;
2024 /* Compile the function literal body. */
2025 build_decl_tree (e->fd);
2027 /* If nested, this will be a trampoline. */
2028 if (e->fd->isNested ())
2030 tree func = build_address (get_symbol_decl (e->fd));
2031 tree object;
2033 if (this->constp_)
2035 /* Static delegate variables have no context pointer. */
2036 object = null_pointer_node;
2037 this->result_ = build_method_call (func, object, e->fd->type);
2038 TREE_CONSTANT (this->result_) = 1;
2040 else
2042 object = get_frame_for_symbol (e->fd);
2043 this->result_ = build_method_call (func, object, e->fd->type);
2046 else
2048 this->result_ = build_nop (build_ctype (e->type),
2049 build_address (get_symbol_decl (e->fd)));
2053 /* Build a halt expression. */
2055 void visit (HaltExp *) final override
2057 /* Should we use trap() or abort()? */
2058 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2059 this->result_ = build_call_expr (ttrap, 0);
2062 /* Build a symbol pointer offset expression. */
2064 void visit (SymOffExp *e) final override
2066 /* Build the address and offset of the symbol. */
2067 size_t soffset = e->isSymOffExp ()->offset;
2068 tree result = get_decl_tree (e->var);
2069 TREE_USED (result) = 1;
2071 if (e->var->isFuncDeclaration ())
2072 result = maybe_reject_intrinsic (result);
2074 if (declaration_reference_p (e->var))
2075 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2076 else
2077 result = build_address (result);
2079 if (!soffset)
2080 result = d_convert (build_ctype (e->type), result);
2081 else
2083 tree offset = size_int (soffset);
2084 result = build_nop (build_ctype (e->type),
2085 build_offset (result, offset));
2088 this->result_ = result;
2091 /* Build a variable expression. */
2093 void visit (VarExp *e) final override
2095 if (e->var->needThis ())
2097 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2098 this->result_ = error_mark_node;
2099 return;
2101 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2103 /* __ctfe is always false at run-time. */
2104 this->result_ = integer_zero_node;
2105 return;
2108 /* This check is same as is done in FuncExp for lambdas. */
2109 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2110 if (fld != NULL)
2112 if (fld->tok == TOK::reserved)
2114 fld->tok = TOK::function_;
2115 fld->vthis = NULL;
2118 /* Compiler the function literal body. */
2119 build_decl_tree (fld);
2122 if (this->constp_)
2124 /* Want the initializer, not the expression. */
2125 VarDeclaration *var = e->var->isVarDeclaration ();
2126 SymbolDeclaration *sdecl = e->var->isSymbolDeclaration ();
2127 tree init = NULL_TREE;
2129 if (var && (var->isConst () || var->isImmutable ())
2130 && e->type->toBasetype ()->ty != TY::Tsarray && var->_init)
2132 if (var->inuse)
2133 error_at (make_location_t (e->loc), "recursive reference %qs",
2134 e->toChars ());
2135 else
2137 var->inuse++;
2138 init = build_expr (initializerToExpression (var->_init), true);
2139 var->inuse--;
2142 else if (sdecl && sdecl->dsym)
2144 if (StructDeclaration *sd = sdecl->dsym->isStructDeclaration ())
2145 init = layout_struct_initializer (sd);
2146 else if (ClassDeclaration *cd = sdecl->dsym->isClassDeclaration ())
2147 init = layout_class_initializer (cd);
2148 else
2149 gcc_unreachable ();
2151 else
2152 error_at (make_location_t (e->loc), "non-constant expression %qs",
2153 e->toChars ());
2155 if (init != NULL_TREE)
2156 this->result_ = init;
2157 else
2158 this->result_ = error_mark_node;
2160 else
2162 tree result = get_decl_tree (e->var);
2163 TREE_USED (result) = 1;
2165 /* The variable expression generated for `__traits(initSymbol)'. */
2166 if (SymbolDeclaration *sd = e->var->isSymbolDeclaration ())
2168 if (e->type->isTypeDArray ())
2170 /* Generate a slice for non-zero initialized aggregates,
2171 otherwise create an empty array. */
2172 gcc_assert (e->type == Type::tvoid->arrayOf ()->constOf ());
2174 tree type = build_ctype (e->type);
2175 tree length = size_int (sd->dsym->structsize);
2176 tree ptr = (sd->dsym->isStructDeclaration ()
2177 && sd->dsym->type->isZeroInit (e->loc))
2178 ? null_pointer_node : build_address (result);
2180 this->result_ = d_array_value (type, length, ptr);
2181 return;
2185 /* For variables that are references - currently only out/inout
2186 arguments; objects don't count - evaluating the variable means
2187 we want what it refers to. */
2188 if (declaration_reference_p (e->var))
2189 result = indirect_ref (build_ctype (e->var->type), result);
2191 this->result_ = result;
2195 /* Build a this variable expression. */
2197 void visit (ThisExp *e) final override
2199 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2200 tree result = NULL_TREE;
2202 if (e->var)
2203 result = get_decl_tree (e->var);
2204 else
2206 gcc_assert (fd && fd->vthis);
2207 result = get_decl_tree (fd->vthis);
2210 if (e->type->ty == TY::Tstruct)
2211 result = build_deref (result);
2213 this->result_ = result;
2216 /* Build a new expression, which allocates memory either on the garbage
2217 collected heap or by using a class or struct specific allocator. */
2219 void visit (NewExp *e) final override
2221 Type *tb = e->type->toBasetype ();
2222 tree result;
2224 if (tb->ty == TY::Tclass)
2226 /* Allocating a new class. */
2227 tb = e->newtype->toBasetype ();
2229 ClassDeclaration *cd = tb->isTypeClass ()->sym;
2230 tree type = build_ctype (tb);
2231 tree setup_exp = NULL_TREE;
2232 tree new_call;
2234 if (e->onstack)
2236 /* If being used as an initializer for a local variable with scope
2237 storage class, then the instance is allocated on the stack
2238 rather than the heap or using the class specific allocator. */
2239 tree var = build_local_temp (TREE_TYPE (type));
2240 new_call = build_nop (type, build_address (var));
2241 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2243 else if (global.params.ehnogc && e->thrownew)
2245 /* Allocating a `@nogc' Exception with `_d_newThrowable' has already
2246 been handled by the front-end. */
2247 gcc_unreachable ();
2249 else
2251 /* Generate: _d_newclass() */
2252 new_call = build_expr (e->lowering);
2255 /* Set the context pointer for nested classes. */
2256 if (cd->isNested ())
2258 tree field = get_symbol_decl (cd->vthis);
2259 tree value = NULL_TREE;
2261 if (e->thisexp)
2263 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2264 /* The class or function we're nested in. */
2265 Dsymbol *outer = cd->toParentLocal ();
2267 value = build_expr (e->thisexp);
2269 if (outer != tcd)
2271 ClassDeclaration *ocd = outer->isClassDeclaration ();
2272 int offset = 0;
2273 gcc_assert (ocd->isBaseOf (tcd, &offset));
2274 /* Could just add offset... */
2275 value = convert_expr (value, e->thisexp->type, ocd->type);
2278 else
2279 value = build_vthis (cd);
2281 if (value != NULL_TREE)
2283 /* Generate: (new())->vthis = this; */
2284 new_call = d_save_expr (new_call);
2285 field = component_ref (build_deref (new_call), field);
2286 setup_exp = compound_expr (setup_exp,
2287 modify_expr (field, value));
2290 new_call = compound_expr (setup_exp, new_call);
2292 /* Call the class constructor. */
2293 if (e->member)
2294 result = d_build_call_expr (e->member, new_call, e->arguments);
2295 else
2296 result = new_call;
2298 if (e->argprefix)
2299 result = compound_expr (build_expr (e->argprefix), result);
2301 else if (tb->ty == TY::Tpointer
2302 && tb->nextOf ()->toBasetype ()->ty == TY::Tstruct)
2304 /* Allocating memory for a new struct. */
2305 Type *htype = e->newtype->toBasetype ();
2306 gcc_assert (!e->onstack);
2308 TypeStruct *stype = htype->isTypeStruct ();
2309 StructDeclaration *sd = stype->sym;
2310 tree new_call;
2312 /* Cannot new an opaque struct. */
2313 if (sd->size (e->loc) == 0)
2315 this->result_ = d_convert (build_ctype (e->type),
2316 integer_zero_node);
2317 return;
2320 /* This case should have been rewritten to `_d_newitemT' during the
2321 semantic phase. */
2322 gcc_assert (e->lowering);
2324 /* Generate: _d_newitemT() */
2325 new_call = build_expr (e->lowering);
2327 if (e->member || !e->arguments)
2329 /* Set the context pointer for nested structs. */
2330 if (sd->isNested ())
2332 tree value = build_vthis (sd);
2333 tree field = get_symbol_decl (sd->vthis);
2334 tree type = build_ctype (stype);
2336 new_call = d_save_expr (new_call);
2337 field = component_ref (indirect_ref (type, new_call), field);
2338 new_call = compound_expr (modify_expr (field, value), new_call);
2341 /* Call the struct constructor. */
2342 if (e->member)
2343 result = d_build_call_expr (e->member, new_call, e->arguments);
2344 else
2345 result = new_call;
2347 else
2349 /* If we have a user supplied initializer, then set-up with a
2350 struct literal. */
2351 if (e->arguments != NULL && sd->fields.length != 0)
2353 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2354 e->arguments,
2355 htype);
2356 new_call = d_save_expr (new_call);
2357 se->type = sd->type;
2358 se->sym = new_call;
2360 /* Setting `se->sym' would mean that the result of the
2361 constructed struct literal expression is `*(new_call)'.
2362 Strip off the indirect reference, as we don't mean to
2363 compute the value yet. */
2364 result = build_address (build_expr (se));
2366 else
2367 result = new_call;
2370 if (e->argprefix)
2371 result = compound_expr (build_expr (e->argprefix), result);
2373 else if (tb->ty == TY::Tarray)
2375 /* Allocating memory for a new D array. */
2376 gcc_assert (e->arguments && e->arguments->length >= 1);
2378 /* Array allocations have already been handled by the front-end. */
2379 gcc_assert (e->lowering != NULL);
2380 result = build_expr (e->lowering);
2382 if (e->argprefix)
2383 result = compound_expr (build_expr (e->argprefix), result);
2385 else if (tb->ty == TY::Tpointer)
2387 /* Allocating memory for a new pointer. */
2388 TypePointer *tpointer = tb->isTypePointer ();
2390 if (tpointer->next->size () == 0)
2392 /* Pointer element size is unknown. */
2393 this->result_ = d_convert (build_ctype (e->type),
2394 integer_zero_node);
2395 return;
2398 /* This case should have been rewritten to `_d_newitemT' during the
2399 semantic phase. */
2400 gcc_assert (e->lowering);
2402 /* Generate: _d_newitemT() */
2403 result = build_expr (e->lowering);
2405 if (e->arguments && e->arguments->length == 1)
2407 result = d_save_expr (result);
2408 tree init = modify_expr (build_deref (result),
2409 build_expr ((*e->arguments)[0]));
2410 result = compound_expr (init, result);
2413 if (e->argprefix)
2414 result = compound_expr (build_expr (e->argprefix), result);
2416 else if (tb->ty == TY::Taarray)
2418 /* Allocating memory for a new associative array. */
2419 tree arg = build_typeinfo (e, e->newtype);
2420 tree mem = build_libcall (LIBCALL_AANEW, Type::tvoidptr, 1, arg);
2422 /* Return an associative array pointed to by MEM. */
2423 tree aatype = build_ctype (tb);
2424 vec <constructor_elt, va_gc> *ce = NULL;
2425 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2427 result = build_nop (build_ctype (e->type),
2428 build_constructor (aatype, ce));
2430 else
2431 gcc_unreachable ();
2433 this->result_ = convert_expr (result, tb, e->type);
2436 /* Build an integer literal. */
2438 void visit (IntegerExp *e) final override
2440 tree ctype = build_ctype (e->type->toBasetype ());
2441 this->result_ = build_integer_cst (e->value, ctype);
2444 /* Build a floating-point literal. */
2446 void visit (RealExp *e) final override
2448 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2451 /* Build a complex literal. */
2453 void visit (ComplexExp *e) final override
2455 Type *tnext;
2457 switch (e->type->toBasetype ()->ty)
2459 case TY::Tcomplex32:
2460 tnext = (TypeBasic *) Type::tfloat32;
2461 break;
2463 case TY::Tcomplex64:
2464 tnext = (TypeBasic *) Type::tfloat64;
2465 break;
2467 case TY::Tcomplex80:
2468 tnext = (TypeBasic *) Type::tfloat80;
2469 break;
2471 default:
2472 gcc_unreachable ();
2475 this->result_ = build_complex (build_ctype (e->type),
2476 build_float_cst (creall (e->value), tnext),
2477 build_float_cst (cimagl (e->value), tnext));
2480 /* Build a string literal, all strings are null terminated except for
2481 static arrays. */
2483 void visit (StringExp *e) final override
2485 Type *tb = e->type->toBasetype ();
2486 tree type = build_ctype (e->type);
2488 if (tb->ty == TY::Tsarray)
2490 /* Turn the string into a constructor for the static array. */
2491 vec <constructor_elt, va_gc> *elms = NULL;
2492 vec_safe_reserve (elms, e->len);
2493 tree etype = TREE_TYPE (type);
2495 for (size_t i = 0; i < e->len; i++)
2497 tree value = build_integer_cst (e->getCodeUnit (i), etype);
2498 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2501 tree ctor = build_constructor (type, elms);
2502 TREE_CONSTANT (ctor) = 1;
2503 this->result_ = ctor;
2505 else
2507 /* Copy the string contents to a null terminated string. */
2508 dinteger_t length = (e->len * e->sz);
2509 char *string = XALLOCAVEC (char, length + e->sz);
2510 memset (string, 0, length + e->sz);
2511 if (length > 0)
2512 memcpy (string, e->string, length);
2514 /* String value and type includes the null terminator. */
2515 tree value = build_string (length + e->sz, string);
2516 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2517 value = build_address (value);
2519 if (tb->ty == TY::Tarray)
2520 value = d_array_value (type, size_int (e->len), value);
2522 TREE_CONSTANT (value) = 1;
2523 this->result_ = d_convert (type, value);
2527 /* Build a tuple literal. Just an argument list that may have
2528 side effects that need evaluation. */
2530 void visit (TupleExp *e) final override
2532 tree result = NULL_TREE;
2534 if (e->e0)
2535 result = build_expr (e->e0, this->constp_, true);
2537 for (size_t i = 0; i < e->exps->length; ++i)
2539 Expression *exp = (*e->exps)[i];
2540 result = compound_expr (result, build_expr (exp, this->constp_, true));
2543 if (result == NULL_TREE)
2544 result = void_node;
2546 this->result_ = result;
2549 /* Build an array literal. The common type of the all elements is taken to
2550 be the type of the array element, and all elements are implicitly
2551 converted to that type. */
2553 void visit (ArrayLiteralExp *e) final override
2555 Type *tb = e->type->toBasetype ();
2557 /* Implicitly convert void[n] to ubyte[n]. */
2558 if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid)
2559 tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());
2561 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray
2562 || tb->ty == TY::Tpointer);
2564 /* Handle empty array literals. */
2565 if (e->elements->length == 0)
2567 if (tb->ty == TY::Tarray)
2568 this->result_ = d_array_value (build_ctype (e->type),
2569 size_int (0), null_pointer_node);
2570 else
2571 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2572 NULL);
2574 return;
2577 /* Build an expression that assigns the expressions in ELEMENTS to
2578 a constructor. */
2579 vec <constructor_elt, va_gc> *elms = NULL;
2580 vec_safe_reserve (elms, e->elements->length);
2581 bool constant_p = true;
2582 tree saved_elems = NULL_TREE;
2584 Type *etype = tb->nextOf ();
2585 tree satype = make_array_type (etype, e->elements->length);
2587 for (size_t i = 0; i < e->elements->length; i++)
2589 Expression *expr = e->getElement (i);
2590 tree value = build_expr (expr, this->constp_, true);
2592 /* Only append nonzero values, the backend will zero out the rest
2593 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2594 if (!initializer_zerop (value))
2596 if (!TREE_CONSTANT (value))
2597 constant_p = false;
2599 /* Split construction of values out of the constructor if there
2600 may be side effects. */
2601 tree init = stabilize_expr (&value);
2602 if (init != NULL_TREE)
2603 saved_elems = compound_expr (saved_elems, init);
2605 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2606 convert_expr (value, expr->type, etype));
2610 /* Now return the constructor as the correct type. For static arrays there
2611 is nothing else to do. For dynamic arrays, return a two field struct.
2612 For pointers, return the address. */
2613 tree ctor = build_constructor (satype, elms);
2614 tree type = build_ctype (e->type);
2616 /* Nothing else to do for static arrays. */
2617 if (tb->ty == TY::Tsarray || this->constp_)
2619 /* Can't take the address of the constructor, so create an anonymous
2620 static symbol, and then refer to it. */
2621 if (tb->ty != TY::Tsarray)
2623 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2624 ctor = build_address (decl);
2625 if (tb->ty == TY::Tarray)
2626 ctor = d_array_value (type, size_int (e->elements->length), ctor);
2628 /* Immutable literals can be placed in rodata. */
2629 if (tb->isImmutable ())
2630 TREE_READONLY (decl) = 1;
2632 d_pushdecl (decl);
2633 rest_of_decl_compilation (decl, 1, 0);
2636 /* If the array literal is readonly or static. */
2637 if (constant_p)
2638 TREE_CONSTANT (ctor) = 1;
2639 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2640 TREE_STATIC (ctor) = 1;
2642 /* Use memset to fill any alignment holes in the array. */
2643 if (!this->constp_ && !this->literalp_)
2645 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
2647 if (ts != NULL && (!identity_compare_p (ts->sym)
2648 || ts->sym->isUnionDeclaration ()))
2650 tree var = build_local_temp (TREE_TYPE (ctor));
2651 tree init = build_memset_call (var);
2652 /* Evaluate memset() first, then any saved elements. */
2653 saved_elems = compound_expr (init, saved_elems);
2654 ctor = compound_expr (modify_expr (var, ctor), var);
2658 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2660 else if (e->onstack)
2662 /* Array literal for a `scope' dynamic array. */
2663 gcc_assert (tb->ty == TY::Tarray);
2664 ctor = force_target_expr (ctor);
2665 this->result_ = d_array_value (type, size_int (e->elements->length),
2666 build_address (ctor));
2668 else
2670 /* Allocate space on the memory managed heap. */
2671 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2672 etype->pointerTo (), 2,
2673 build_typeinfo (e, etype->arrayOf ()),
2674 size_int (e->elements->length));
2675 mem = d_save_expr (mem);
2677 /* Now copy the constructor into memory. */
2678 tree size = size_mult_expr (size_int (e->elements->length),
2679 size_int (tb->nextOf ()->size ()));
2681 tree result = build_memcpy_call (mem, build_address (ctor), size);
2683 /* Return the array pointed to by MEM. */
2684 result = compound_expr (result, mem);
2686 if (tb->ty == TY::Tarray)
2687 result = d_array_value (type, size_int (e->elements->length), result);
2689 this->result_ = compound_expr (saved_elems, result);
2693 /* Build an associative array literal. The common type of the all keys is
2694 taken to be the key type, and common type of all values the value type.
2695 All keys and values are then implicitly converted as needed. */
2697 void visit (AssocArrayLiteralExp *e) final override
2699 if (e->lowering != NULL)
2701 /* When an associative array literal gets lowered, it's converted into a
2702 struct literal suitable for static initialization. */
2703 gcc_assert (this->constp_);
2704 this->result_ = build_expr (e->lowering, this->constp_, true);
2705 return ;
2708 /* Want the mutable type for typeinfo reference. */
2709 Type *tb = e->type->toBasetype ()->mutableOf ();
2711 /* Handle empty assoc array literals. */
2712 TypeAArray *ta = tb->isTypeAArray ();
2713 if (e->keys->length == 0)
2715 this->result_ = build_constructor (build_ctype (ta), NULL);
2716 return;
2719 /* Build an expression that assigns all expressions in KEYS
2720 to a constructor. */
2721 tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
2722 e->keys, this->constp_);
2723 tree init = stabilize_expr (&akeys);
2725 /* Do the same with all expressions in VALUES. */
2726 tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
2727 e->values, this->constp_);
2728 init = compound_expr (init, stabilize_expr (&avals));
2730 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2731 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2732 size_int (e->keys->length),
2733 build_address (akeys));
2734 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2735 size_int (e->values->length),
2736 build_address (avals));
2738 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2739 build_typeinfo (e, ta), keys, vals);
2741 /* Return an associative array pointed to by MEM. */
2742 tree aatype = build_ctype (ta);
2743 vec <constructor_elt, va_gc> *ce = NULL;
2744 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2746 tree result = build_nop (build_ctype (e->type),
2747 build_constructor (aatype, ce));
2748 this->result_ = compound_expr (init, result);
2751 /* Build a struct literal. */
2753 void visit (StructLiteralExp *e) final override
2755 /* Handle empty struct literals. */
2756 if (e->elements == NULL || e->sd->fields.length == 0)
2758 this->result_ = build_constructor (build_ctype (e->type), NULL);
2759 return;
2762 /* Building sinit trees are delayed until after frontend semantic
2763 processing has complete. Build the static initializer now. */
2764 if (e->useStaticInit && !this->constp_ && !e->sd->isCsymbol ())
2766 tree init = aggregate_initializer_decl (e->sd);
2768 /* If initializing a symbol, don't forget to set it. */
2769 if (e->sym != NULL)
2771 tree var = build_deref (e->sym);
2772 init = compound_expr (modify_expr (var, init), var);
2775 this->result_ = init;
2776 return;
2779 /* Build a constructor that assigns the expressions in ELEMENTS
2780 at each field index that has been filled in. */
2781 vec <constructor_elt, va_gc> *ve = NULL;
2782 tree saved_elems = NULL_TREE;
2784 /* CTFE may fill the hidden pointer by NullExp. */
2785 gcc_assert (e->elements->length <= e->sd->fields.length);
2787 Type *tb = e->type->toBasetype ();
2788 gcc_assert (tb->ty == TY::Tstruct);
2790 for (size_t i = 0; i < e->elements->length; i++)
2792 Expression *exp = (*e->elements)[i];
2793 if (!exp)
2794 continue;
2796 VarDeclaration *field = e->sd->fields[i];
2797 Type *type = exp->type->toBasetype ();
2798 Type *ftype = field->type->toBasetype ();
2799 tree value = NULL_TREE;
2801 if (ftype->ty == TY::Tsarray && !same_type_p (type, ftype))
2803 /* Initialize a static array with a single element. */
2804 tree elem = build_expr (exp, this->constp_, true);
2805 saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
2806 elem = d_save_expr (elem);
2808 if (initializer_zerop (elem))
2809 value = build_constructor (build_ctype (ftype), NULL);
2810 else
2811 value = build_array_from_val (ftype, elem);
2813 else
2815 value = convert_expr (build_expr (exp, this->constp_, true),
2816 exp->type, field->type);
2819 /* Split construction of values out of the constructor. */
2820 saved_elems = compound_expr (saved_elems, stabilize_expr (&value));
2822 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2825 /* Maybe setup hidden pointer to outer scope context. */
2826 if (e->sd->isNested () && e->elements->length != e->sd->fields.length
2827 && this->constp_ == false)
2829 tree field = get_symbol_decl (e->sd->vthis);
2830 tree value = build_vthis (e->sd);
2831 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2832 gcc_assert (e->useStaticInit == false);
2835 /* Build a constructor in the correct shape of the aggregate type. */
2836 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2838 /* Nothing more to do for constant literals. */
2839 if (this->constp_)
2841 /* If the struct literal is a valid for static data. */
2842 if (TREE_CONSTANT (ctor)
2843 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2844 TREE_STATIC (ctor) = 1;
2846 this->result_ = compound_expr (saved_elems, ctor);
2847 return;
2850 /* Construct the struct literal for run-time. */
2851 if (e->sym != NULL)
2853 /* Store the result in a symbol to initialize the literal. */
2854 tree var = build_deref (e->sym);
2855 ctor = compound_expr (modify_expr (var, ctor), var);
2857 else if (!this->literalp_)
2859 /* Use memset to fill any alignment holes in the object. */
2860 if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
2862 tree var = build_local_temp (TREE_TYPE (ctor));
2863 tree init = build_memset_call (var);
2864 /* Evaluate memset() first, then any saved element constructors. */
2865 saved_elems = compound_expr (init, saved_elems);
2866 ctor = compound_expr (modify_expr (var, ctor), var);
2870 this->result_ = compound_expr (saved_elems, ctor);
2873 /* Build a null literal. */
2875 void visit (NullExp *e) final override
2877 this->result_ = build_typeof_null_value (e->type);
2880 /* Build a vector literal. */
2882 void visit (VectorExp *e) final override
2884 /* First handle array literal expressions. */
2885 if (e->e1->op == EXP::arrayLiteral)
2887 ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
2888 vec <constructor_elt, va_gc> *elms = NULL;
2889 bool constant_p = true;
2890 tree type = build_ctype (e->type);
2892 vec_safe_reserve (elms, ale->elements->length);
2893 for (size_t i = 0; i < ale->elements->length; i++)
2895 Expression *expr = ale->getElement (i);
2896 tree value = d_convert (TREE_TYPE (type),
2897 build_expr (expr, this->constp_, true));
2898 if (!CONSTANT_CLASS_P (value))
2899 constant_p = false;
2901 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2904 /* Build a VECTOR_CST from a constant vector constructor. */
2905 if (constant_p)
2906 this->result_ = build_vector_from_ctor (type, elms);
2907 else
2908 this->result_ = build_constructor (type, elms);
2910 else if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
2912 /* Build a vector representation from a static array. */
2913 this->result_ = convert_expr (build_expr (e->e1, this->constp_),
2914 e->e1->type, e->type);
2916 else
2918 /* Build constructor from single value. */
2919 tree type = build_ctype (e->type);
2920 tree value = d_convert (TREE_TYPE (type),
2921 build_expr (e->e1, this->constp_, true));
2922 this->result_ = build_vector_from_val (type, value);
2926 /* Build a static array representation of a vector expression. */
2928 void visit (VectorArrayExp *e) final override
2930 this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
2931 e->e1->type, e->type);
2934 /* Build a static class literal, return its reference. */
2936 void visit (ClassReferenceExp *e) final override
2938 /* The result of build_new_class_expr is a RECORD_TYPE, we want
2939 the reference. */
2940 tree var = build_address (build_new_class_expr (e));
2942 /* If the type of this literal is an interface, the we must add the
2943 interface offset to symbol. */
2944 if (this->constp_)
2946 TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
2947 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
2949 if (to != NULL)
2951 ClassDeclaration *from = e->originalClass ();
2952 int offset = 0;
2954 gcc_assert (to->isBaseOf (from, &offset) != 0);
2956 if (offset != 0)
2957 var = build_offset (var, size_int (offset));
2961 this->result_ = var;
2964 /* Build an uninitialized value, generated from void initializers. */
2966 void visit (VoidInitExp *e) final override
2968 /* The front-end only generates these for the initializer of globals.
2969 Represent `void' as zeroes, regardless of the type's default value. */
2970 gcc_assert (this->constp_);
2971 this->result_ = build_zero_cst (build_ctype (e->type));
2974 /* These expressions are mainly just a placeholders in the frontend.
2975 We shouldn't see them here. */
2977 void visit (ScopeExp *e) final override
2979 error_at (make_location_t (e->loc), "%qs is not an expression",
2980 e->toChars ());
2981 this->result_ = error_mark_node;
2984 void visit (TypeExp *e) final override
2986 error_at (make_location_t (e->loc), "type %qs is not an expression",
2987 e->toChars ());
2988 this->result_ = error_mark_node;
2993 /* Main entry point for ExprVisitor interface to generate code for
2994 the Expression AST class E. If CONST_P is true, then E is a
2995 constant expression. If LITERAL_P is true, then E is a value used
2996 in the initialization of another literal. */
2998 tree
2999 build_expr (Expression *e, bool const_p, bool literal_p)
3001 ExprVisitor v = ExprVisitor (const_p, literal_p);
3002 location_t saved_location = input_location;
3004 input_location = make_location_t (e->loc);
3005 e->accept (&v);
3006 tree expr = v.result ();
3007 input_location = saved_location;
3009 /* Check if initializer expression is valid constant. */
3010 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3012 error_at (make_location_t (e->loc), "non-constant expression %qs",
3013 e->toChars ());
3014 return error_mark_node;
3017 return expr;
3020 /* Same as build_expr, but also calls destructors on any temporaries. */
3022 tree
3023 build_expr_dtor (Expression *e)
3025 /* Codegen can be improved by determining if no exceptions can be thrown
3026 between the ctor and dtor, and eliminating the ctor and dtor. */
3027 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3028 tree result = build_expr (e);
3030 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3032 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3033 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3036 return result;
3039 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3041 tree
3042 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3044 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3045 tree result = build_expr (e);
3047 /* Convert for initializing the DECL_RESULT. */
3048 if (tf->isref ())
3050 /* If we are returning a reference, take the address. */
3051 result = convert_expr (result, e->type, type);
3052 result = build_address (result);
3054 else
3055 result = convert_for_rvalue (result, e->type, type);
3057 /* The decl to store the return expression. */
3058 tree decl = DECL_RESULT (cfun->decl);
3060 /* Split comma expressions, so that the result is returned directly. */
3061 tree expr = stabilize_expr (&result);
3062 result = build_assign (INIT_EXPR, decl, result);
3063 result = compound_expr (expr, return_expr (result));
3065 /* May nest the return expression inside the try/finally expression. */
3066 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3068 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3069 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3072 return result;