d: Merge upstream dmd, druntime 4ca4140e58, phobos 454dff14d.
[official-gcc.git] / gcc / d / expr.cc
blobc6245ff5fc19f4b89eeb8ce4bae4862c3526f6ef
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 Type *tb1 = e->e1->type->toBasetype ();
697 Type *tb2 = e->e2->type->toBasetype ();
698 Type *etype;
700 if (tb1->ty == TY::Tarray || tb1->ty == TY::Tsarray)
701 etype = tb1->nextOf ();
702 else
703 etype = tb2->nextOf ();
705 tree result;
707 if (e->e1->op == EXP::concatenate)
709 /* Flatten multiple concatenations to an array.
710 So the expression ((a ~ b) ~ c) becomes [a, b, c] */
711 int ndims = 2;
713 for (Expression *ex = e->e1; ex->op == EXP::concatenate;)
715 if (ex->op == EXP::concatenate)
717 ex = ex->isCatExp ()->e1;
718 ndims++;
722 /* Store all concatenation args to a temporary byte[][ndims] array. */
723 Type *targselem = Type::tint8->arrayOf ();
724 tree var = build_local_temp (make_array_type (targselem, ndims));
726 /* Loop through each concatenation from right to left. */
727 vec <constructor_elt, va_gc> *elms = NULL;
728 CatExp *ce = e;
729 int dim = ndims - 1;
731 for (Expression *oe = ce->e2; oe != NULL;
732 (ce->e1->op != EXP::concatenate
733 ? (oe = ce->e1)
734 : (ce = ce->e1->isCatExp (), oe = ce->e2)))
736 tree arg = d_array_convert (etype, oe);
737 tree index = size_int (dim);
738 CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));
740 /* Finished pushing all arrays. */
741 if (oe == ce->e1)
742 break;
744 dim -= 1;
747 /* Check there is no logic bug in constructing byte[][] of arrays. */
748 gcc_assert (dim == 0);
749 tree init = build_constructor (TREE_TYPE (var), elms);
750 var = compound_expr (modify_expr (var, init), var);
752 tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
753 size_int (ndims), build_address (var));
755 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
756 build_typeinfo (e, e->type), arrs);
758 else
760 /* Handle single concatenation (a ~ b). */
761 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
762 build_typeinfo (e, e->type),
763 d_array_convert (etype, e->e1),
764 d_array_convert (etype, e->e2));
767 this->result_ = result;
770 /* Build an assignment operator expression. The right operand is implicitly
771 converted to the type of the left operand, and assigned to it. */
773 void visit (BinAssignExp *e) final override
775 tree_code code;
776 Expression *e1b = e->e1;
778 switch (e->op)
780 case EXP::addAssign:
781 code = PLUS_EXPR;
782 break;
784 case EXP::minAssign:
785 code = MINUS_EXPR;
786 break;
788 case EXP::mulAssign:
789 code = MULT_EXPR;
790 break;
792 case EXP::divAssign:
793 code = e->e1->type->isintegral ()
794 ? TRUNC_DIV_EXPR : RDIV_EXPR;
795 break;
797 case EXP::modAssign:
798 code = e->e1->type->isfloating ()
799 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
800 break;
802 case EXP::andAssign:
803 code = BIT_AND_EXPR;
804 break;
806 case EXP::orAssign:
807 code = BIT_IOR_EXPR;
808 break;
810 case EXP::xorAssign:
811 code = BIT_XOR_EXPR;
812 break;
814 case EXP::powAssign:
815 gcc_unreachable ();
817 case EXP::leftShiftAssign:
818 code = LSHIFT_EXPR;
819 break;
821 case EXP::rightShiftAssign:
822 case EXP::unsignedRightShiftAssign:
823 /* Use the original lhs type before it was promoted. The left operand
824 of `>>>=' does not undergo integral promotions before shifting.
825 Strip off casts just incase anyway. */
826 while (e1b->op == EXP::cast_)
828 CastExp *ce = e1b->isCastExp ();
829 gcc_assert (same_type_p (ce->type, ce->to));
830 e1b = ce->e1;
832 code = (e->op == EXP::rightShiftAssign) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
833 break;
835 default:
836 gcc_unreachable ();
839 tree exp = binop_assignment (code, e1b, e->e2);
840 this->result_ = convert_expr (exp, e1b->type, e->type);
843 /* Build a concat assignment expression. The right operand is appended
844 to the left operand. */
846 void visit (CatAssignExp *e) final override
848 Type *tb1 = e->e1->type->toBasetype ();
849 Type *tb2 = e->e2->type->toBasetype ();
850 Type *etype = tb1->nextOf ()->toBasetype ();
852 /* Save the address of `e1', so it can be evaluated first.
853 As all D run-time library functions for concat assignments update `e1'
854 in-place and then return its value, the saved address can also be used as
855 the result of this expression as well. */
856 tree lhs = build_expr (e->e1);
857 tree lexpr = stabilize_expr (&lhs);
858 tree ptr = d_save_expr (build_address (lhs));
859 tree result = NULL_TREE;
861 if (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar
862 && (etype->ty == TY::Tchar || etype->ty == TY::Twchar))
864 /* Append a dchar to a char[] or wchar[]:
865 The assignment is handled by the D run-time library, so only
866 need to call `_d_arrayappend[cw]d(&e1, e2)' */
867 libcall_fn libcall = (etype->ty == TY::Tchar)
868 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
870 result = build_libcall (libcall, e->type, 2,
871 ptr, build_expr (e->e2));
873 else
875 /* Appending an element or array to another array has already been
876 handled by the front-end. */
877 gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray);
878 gcc_unreachable ();
881 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
882 result = compound_expr (compound_expr (lexpr, ptr), result);
883 this->result_ = compound_expr (result, build_deref (ptr));
886 /* Build an assignment expression. The right operand is implicitly
887 converted to the type of the left operand, and assigned to it. */
889 void visit (AssignExp *e) final override
891 /* First, handle special assignment semantics. */
893 /* Look for array.length = n; */
894 if (e->e1->op == EXP::arrayLength)
896 /* This case should have been rewritten to `_d_arraysetlengthT` in the
897 semantic phase. */
898 gcc_unreachable ();
901 /* Look for exp = noreturn; */
902 if (e->e2->type->isTypeNoreturn ())
904 /* If the RHS is a `noreturn' expression, there is no point generating
905 any code for the assignment, just evaluate side effects. */
906 tree t1 = build_expr (e->e1);
907 tree t2 = build_expr (e->e2);
908 this->result_ = compound_expr (t1, t2);
909 return;
912 /* Look for array[] = n; */
913 if (e->e1->op == EXP::slice)
915 SliceExp *se = e->e1->isSliceExp ();
916 Type *stype = se->e1->type->toBasetype ();
917 Type *etype = stype->nextOf ()->toBasetype ();
919 /* Determine if we need to run postblit or dtor. */
920 bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
921 bool destructor = needs_dtor (etype);
923 if (e->memset == MemorySet::blockAssign)
925 /* Set a range of elements to one value. */
926 tree t1 = build_expr (e->e1);
927 tree t2 = build_expr (e->e2);
928 tree result;
930 /* Extract any array bounds checks from the slice expression. */
931 tree init = stabilize_expr (&t1);
932 t1 = d_save_expr (t1);
934 if ((postblit || destructor) && e->op != EXP::blit)
936 /* This case should have been rewritten to `_d_arraysetassign`
937 in the semantic phase. */
938 gcc_unreachable ();
941 if (integer_zerop (t2))
943 tree size = size_mult_expr (d_array_length (t1),
944 size_int (etype->size ()));
945 result = build_memset_call (d_array_ptr (t1), size);
947 else
948 result = build_array_set (d_array_ptr (t1),
949 d_array_length (t1), t2);
951 result = compound_expr (init, result);
952 this->result_ = compound_expr (result, t1);
954 else
956 /* Perform a memcpy operation. */
957 gcc_assert (e->e2->type->ty != TY::Tpointer);
959 if (!postblit && !destructor)
961 tree t1 = d_save_expr (d_array_convert (e->e1));
962 tree t2 = d_save_expr (d_array_convert (e->e2));
964 /* References to array data. */
965 tree t1ptr = d_array_ptr (t1);
966 tree t1len = d_array_length (t1);
967 tree t2ptr = d_array_ptr (t2);
969 /* Generate: memcpy(to, from, size) */
970 tree size = size_mult_expr (t1len, size_int (etype->size ()));
971 tree result = build_memcpy_call (t1ptr, t2ptr, size);
973 /* Insert check that array lengths match and do not overlap. */
974 if (array_bounds_check ())
976 /* tlencmp = (t1len == t2len) */
977 tree t2len = d_array_length (t2);
978 tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len);
980 /* toverlap = (t1ptr + size <= t2ptr
981 || t2ptr + size <= t1ptr) */
982 tree t1ptrcmp = build_boolop (LE_EXPR,
983 build_offset (t1ptr, size),
984 t2ptr);
985 tree t2ptrcmp = build_boolop (LE_EXPR,
986 build_offset (t2ptr, size),
987 t1ptr);
988 tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp,
989 t2ptrcmp);
991 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */
992 tree tassert = build_array_bounds_call (e->loc);
993 tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR,
994 tlencmp, toverlap);
996 result = build_condition (void_type_node, tboundscheck,
997 result, tassert);
1000 this->result_ = compound_expr (result, t1);
1002 else if ((postblit || destructor)
1003 && e->op != EXP::blit && e->op != EXP::construct)
1005 /* Assigning to a non-trivially copyable array has already been
1006 handled by the front-end. */
1007 gcc_unreachable ();
1009 else
1011 /* Generate: _d_arraycopy() */
1012 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
1013 size_int (etype->size ()),
1014 d_array_convert (e->e2),
1015 d_array_convert (e->e1));
1019 return;
1022 /* Look for reference initializations. */
1023 if (e->memset == MemorySet::referenceInit)
1025 gcc_assert (e->op == EXP::construct || e->op == EXP::blit);
1026 gcc_assert (e->e1->op == EXP::variable);
1028 Declaration *decl = e->e1->isVarExp ()->var;
1029 if (decl->storage_class & (STCout | STCref))
1031 tree t2 = convert_for_assignment (build_expr (e->e2),
1032 e->e2->type, e->e1->type);
1033 tree t1 = build_expr (e->e1);
1034 /* Want reference to lhs, not indirect ref. */
1035 t1 = TREE_OPERAND (t1, 0);
1036 t2 = build_address (t2);
1038 this->result_ = indirect_ref (build_ctype (e->type),
1039 build_assign (INIT_EXPR, t1, t2));
1040 return;
1044 /* Other types of assignments that may require post construction. */
1045 Type *tb1 = e->e1->type->toBasetype ();
1046 tree_code modifycode = (e->op == EXP::construct) ? INIT_EXPR : MODIFY_EXPR;
1048 /* Look for struct assignment. */
1049 if (tb1->ty == TY::Tstruct)
1051 tree t1 = build_expr (e->e1);
1052 tree t2 = convert_for_assignment (build_expr (e->e2, false, true),
1053 e->e2->type, e->e1->type);
1054 StructDeclaration *sd = tb1->isTypeStruct ()->sym;
1056 /* Look for struct = 0. */
1057 if (e->e2->op == EXP::int64)
1059 /* Use memset to fill struct. */
1060 gcc_assert (e->op == EXP::blit);
1061 tree result = build_memset_call (t1);
1063 /* Maybe set-up hidden pointer to outer scope context. */
1064 if (sd->isNested ())
1066 tree field = get_symbol_decl (sd->vthis);
1067 tree value = build_vthis (sd);
1069 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1070 result = compound_expr (result, vthis_exp);
1073 this->result_ = compound_expr (result, t1);
1075 else
1077 /* Simple struct literal assignment. */
1078 tree init = NULL_TREE;
1080 /* Fill any alignment holes in the struct using memset. */
1081 if ((e->op == EXP::construct
1082 || (e->e2->op == EXP::structLiteral && e->op == EXP::blit))
1083 && (sd->isUnionDeclaration () || !identity_compare_p (sd)))
1085 t1 = stabilize_reference (t1);
1086 init = build_memset_call (t1);
1089 /* Elide generating assignment if init is all zeroes. */
1090 if (init != NULL_TREE && initializer_zerop (t2))
1091 this->result_ = compound_expr (init, t1);
1092 else
1094 tree result = build_assign (modifycode, t1, t2);
1095 this->result_ = compound_expr (init, result);
1099 return;
1102 /* Look for static array assignment. */
1103 if (tb1->ty == TY::Tsarray)
1105 /* Look for array = 0. */
1106 if (e->e2->op == EXP::int64)
1108 /* Use memset to fill the array. */
1109 gcc_assert (e->op == EXP::blit);
1110 this->result_ = build_memset_call (build_expr (e->e1));
1111 return;
1114 Type *etype = tb1->nextOf ();
1115 gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray);
1117 /* Determine if we need to run postblit. */
1118 const bool postblit = needs_postblit (etype);
1119 const bool destructor = needs_dtor (etype);
1120 const bool lvalue = lvalue_p (e->e2);
1122 /* Optimize static array assignment with array literal. Even if the
1123 elements in rhs are all rvalues and don't have to call postblits,
1124 this assignment should call dtors on old assigned elements. */
1125 if ((!postblit && !destructor)
1126 || (e->op == EXP::construct && e->e2->op == EXP::arrayLiteral)
1127 || (e->op == EXP::construct && e->e2->op == EXP::call)
1128 || (e->op == EXP::construct && !lvalue && postblit)
1129 || (e->op == EXP::blit || e->e1->type->size () == 0))
1131 tree t1 = build_expr (e->e1);
1132 tree t2 = convert_for_assignment (build_expr (e->e2),
1133 e->e2->type, e->e1->type);
1135 this->result_ = build_assign (modifycode, t1, t2);
1136 return;
1139 /* All other kinds of lvalue or rvalue static array assignment.
1140 Array construction has already been handled by the front-end. */
1141 gcc_assert (e->op != EXP::construct);
1142 gcc_unreachable ();
1145 /* Simple assignment. */
1146 tree t1 = build_expr (e->e1);
1147 tree t2 = convert_for_assignment (build_expr (e->e2),
1148 e->e2->type, e->e1->type);
1150 this->result_ = build_assign (modifycode, t1, t2);
1153 /* Build a throw expression. */
1155 void visit (ThrowExp *e) final override
1157 tree arg = build_expr_dtor (e->e1);
1158 this->result_ = build_libcall (LIBCALL_THROW, Type::tvoid, 1, arg);
1161 /* Build a postfix expression. */
1163 void visit (PostExp *e) final override
1165 tree result;
1167 if (e->op == EXP::plusPlus)
1169 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1170 build_expr (e->e1), build_expr (e->e2));
1172 else if (e->op == EXP::minusMinus)
1174 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1175 build_expr (e->e1), build_expr (e->e2));
1177 else
1178 gcc_unreachable ();
1180 TREE_SIDE_EFFECTS (result) = 1;
1181 this->result_ = result;
1184 /* Build an index expression. */
1186 void visit (IndexExp *e) final override
1188 Type *tb1 = e->e1->type->toBasetype ();
1190 if (tb1->ty == TY::Taarray)
1192 /* Get the key for the associative array. */
1193 Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
1194 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1195 libcall_fn libcall;
1196 tree tinfo, ptr;
1198 if (e->modifiable)
1200 libcall = LIBCALL_AAGETY;
1201 ptr = build_address (build_expr (e->e1));
1202 tinfo = build_typeinfo (e, tb1->unSharedOf ()->mutableOf ());
1204 else
1206 libcall = LIBCALL_AAGETRVALUEX;
1207 ptr = build_expr (e->e1);
1208 tinfo = build_typeinfo (e, tkey);
1211 /* Index the associative array. */
1212 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1213 ptr, tinfo,
1214 size_int (tb1->nextOf ()->size ()),
1215 build_address (key));
1217 if (!e->indexIsInBounds && array_bounds_check ())
1219 tree tassert = build_array_bounds_call (e->loc);
1221 result = d_save_expr (result);
1222 result = build_condition (TREE_TYPE (result),
1223 d_truthvalue_conversion (result),
1224 result, tassert);
1227 this->result_ = indirect_ref (build_ctype (e->type), result);
1229 else
1231 /* Get the array and length for static and dynamic arrays. */
1232 tree array = d_save_expr (build_expr (e->e1));
1234 tree length = NULL_TREE;
1235 if (tb1->ty != TY::Tpointer)
1236 length = get_array_length (array, tb1);
1237 else
1238 gcc_assert (e->lengthVar == NULL);
1240 /* The __dollar variable just becomes a placeholder for the
1241 actual length. */
1242 if (e->lengthVar)
1243 e->lengthVar->csym = length;
1245 /* Generate the index. */
1246 tree index = build_expr (e->e2);
1248 /* If it's a static array and the index is constant, the front end has
1249 already checked the bounds. */
1250 if (tb1->ty != TY::Tpointer)
1251 index = build_bounds_index_condition (e, index, length);
1253 /* Convert vectors to their underlying array type. */
1254 if (VECTOR_TYPE_P (TREE_TYPE (array)))
1256 tree array_type =
1257 build_array_type_nelts (TREE_TYPE (TREE_TYPE (array)),
1258 TYPE_VECTOR_SUBPARTS (TREE_TYPE (array)));
1259 d_mark_addressable (array, false);
1260 array = build1 (VIEW_CONVERT_EXPR, array_type, array);
1263 if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
1265 /* Generate `array[index]'. When the index is non-constant, we must
1266 mark the array as addressable because we'll need to do pointer
1267 arithmetic on its address. */
1268 if (TREE_CODE (index) != INTEGER_CST)
1269 d_mark_addressable (array);
1271 this->result_ = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
1272 array, index, NULL_TREE, NULL_TREE);
1274 else
1276 /* Generate `array.ptr[index]'. */
1277 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1278 ptr = void_okay_p (ptr);
1279 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1280 build_pointer_index (ptr, index));
1285 /* Build a comma expression. The type is the type of the right operand. */
1287 void visit (CommaExp *e) final override
1289 tree t1 = build_expr (e->e1);
1290 tree t2 = build_expr (e->e2);
1291 tree type = e->type ? build_ctype (e->type) : void_type_node;
1293 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1296 /* Build an array length expression. Returns the number of elements
1297 in the array. The result is of type size_t. */
1299 void visit (ArrayLengthExp *e) final override
1301 if (e->e1->type->toBasetype ()->ty == TY::Tarray)
1302 this->result_ = d_array_length (build_expr (e->e1));
1303 else
1305 /* Static arrays have already been handled by the front-end. */
1306 error ("unexpected type for array length: %qs", e->type->toChars ());
1307 this->result_ = error_mark_node;
1311 /* Build a delegate pointer expression. This will return the frame
1312 pointer value as a type void*. */
1314 void visit (DelegatePtrExp *e) final override
1316 tree t1 = build_expr (e->e1);
1317 this->result_ = delegate_object (t1);
1320 /* Build a delegate function pointer expression. This will return the
1321 function pointer value as a function type. */
1323 void visit (DelegateFuncptrExp *e) final override
1325 tree t1 = build_expr (e->e1);
1326 this->result_ = delegate_method (t1);
1329 /* Build a slice expression. */
1331 void visit (SliceExp *e) final override
1333 Type *tb = e->type->toBasetype ();
1334 Type *tb1 = e->e1->type->toBasetype ();
1335 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray);
1337 /* Use convert-to-dynamic-array code if possible. */
1338 if (!e->lwr)
1340 tree result = build_expr (e->e1);
1341 if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
1342 result = convert_expr (result, e->e1->type, e->type);
1344 this->result_ = result;
1345 return;
1347 else
1348 gcc_assert (e->upr != NULL);
1350 /* Get the data pointer and length for static and dynamic arrays. */
1351 tree array = d_save_expr (build_expr (e->e1));
1352 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1353 tree length = NULL_TREE;
1355 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1356 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1357 if (tb1->ty != TY::Tpointer)
1358 length = get_array_length (array, tb1);
1359 else
1360 gcc_assert (e->lengthVar == NULL);
1362 /* The __dollar variable just becomes a placeholder for the
1363 actual length. */
1364 if (e->lengthVar)
1365 e->lengthVar->csym = length;
1367 /* Generate upper and lower bounds. */
1368 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1369 tree upr_tree = d_save_expr (build_expr (e->upr));
1371 /* If the upper bound has any side effects, then the lower bound should be
1372 copied to a temporary always. */
1373 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1374 lwr_tree = save_expr (lwr_tree);
1376 /* Adjust the .ptr offset. */
1377 if (!integer_zerop (lwr_tree))
1379 tree ptrtype = TREE_TYPE (ptr);
1380 ptr = build_pointer_index (void_okay_p (ptr), lwr_tree);
1381 ptr = build_nop (ptrtype, ptr);
1384 /* Nothing more to do for static arrays, their bounds checking has been
1385 done at compile-time. */
1386 if (tb->ty == TY::Tsarray)
1388 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1389 return;
1391 else
1392 gcc_assert (tb->ty == TY::Tarray);
1394 /* Generate bounds checking code. */
1395 tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree,
1396 length);
1397 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1398 this->result_ = compound_expr (array, result);
1401 /* Build a cast expression, which converts the given unary expression to the
1402 type of result. */
1404 void visit (CastExp *e) final override
1406 Type *ebtype = e->e1->type->toBasetype ();
1407 Type *tbtype = e->to->toBasetype ();
1408 tree result = build_expr (e->e1, this->constp_, this->literalp_);
1410 /* Just evaluate e1 if it has any side effects. */
1411 if (tbtype->ty == TY::Tvoid)
1412 this->result_ = build_nop (build_ctype (tbtype), result);
1413 else
1414 this->result_ = convert_for_rvalue (result, ebtype, tbtype);
1417 /* Build a delete expression. */
1419 void visit (DeleteExp *e) final override
1421 tree t1 = build_expr (e->e1);
1422 Type *tb1 = e->e1->type->toBasetype ();
1424 if (tb1->ty == TY::Tclass)
1426 /* For class object references, if there is a destructor for that class,
1427 the destructor is called for the object instance. */
1428 gcc_assert (e->e1->op == EXP::variable);
1430 VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
1431 gcc_assert (v && v->onstack ());
1433 libcall_fn libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1434 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1436 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1437 return;
1439 else
1441 error ("don%'t know how to delete %qs", e->e1->toChars ());
1442 this->result_ = error_mark_node;
1446 /* Build a remove expression, which removes a particular key from an
1447 associative array. */
1449 void visit (RemoveExp *e) final override
1451 /* Check that the array is actually an associative array. */
1452 if (e->e1->type->toBasetype ()->ty == TY::Taarray)
1454 Type *tb = e->e1->type->toBasetype ();
1455 Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
1456 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1458 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1459 build_expr (e->e1),
1460 build_typeinfo (e, tkey),
1461 build_address (index));
1463 else
1465 error ("%qs is not an associative array", e->e1->toChars ());
1466 this->result_ = error_mark_node;
1470 /* Build an unary not expression. */
1472 void visit (NotExp *e) final override
1474 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1475 /* Need to convert to boolean type or this will fail. */
1476 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1478 this->result_ = d_convert (build_ctype (e->type), result);
1481 /* Build a compliment expression, where all the bits in the value are
1482 complemented. Note: unlike in C, the usual integral promotions
1483 are not performed prior to the complement operation. */
1485 void visit (ComExp *e) final override
1487 TY ty1 = e->e1->type->toBasetype ()->ty;
1488 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1490 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1491 build_expr (e->e1));
1494 /* Build an unary negation expression. */
1496 void visit (NegExp *e) final override
1498 TY ty1 = e->e1->type->toBasetype ()->ty;
1499 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1501 tree type = build_ctype (e->type);
1502 tree expr = build_expr (e->e1);
1504 /* If the operation needs excess precision. */
1505 tree eptype = excess_precision_type (type);
1506 if (eptype != NULL_TREE)
1507 expr = d_convert (eptype, expr);
1508 else
1509 eptype = type;
1511 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1512 this->result_ = d_convert (type, ret);
1515 /* Build a pointer index expression. */
1517 void visit (PtrExp *e) final override
1519 Type *tnext = NULL;
1520 size_t offset;
1521 tree result;
1523 if (e->e1->op == EXP::add)
1525 AddExp *ae = e->e1->isAddExp ();
1526 if (ae->e1->op == EXP::address
1527 && ae->e2->isConst () && ae->e2->type->isintegral ())
1529 Expression *ex = ae->e1->isAddrExp ()->e1;
1530 tnext = ex->type->toBasetype ();
1531 result = build_expr (ex);
1532 offset = ae->e2->toUInteger ();
1535 else if (e->e1->op == EXP::symbolOffset)
1537 SymOffExp *se = e->e1->isSymOffExp ();
1538 if (!declaration_reference_p (se->var))
1540 tnext = se->var->type->toBasetype ();
1541 result = get_decl_tree (se->var);
1542 offset = se->offset;
1546 /* Produce better code by converting *(#record + n) to
1547 COMPONENT_REFERENCE. Otherwise, the variable will always be
1548 allocated in memory because its address is taken. */
1549 if (tnext && tnext->ty == TY::Tstruct)
1551 StructDeclaration *sd = tnext->isTypeStruct ()->sym;
1553 for (size_t i = 0; i < sd->fields.length; i++)
1555 VarDeclaration *field = sd->fields[i];
1557 if (field->offset == offset
1558 && same_type_p (field->type, e->type))
1560 /* Catch errors, backend will ICE otherwise. */
1561 if (error_operand_p (result))
1562 this->result_ = result;
1563 else
1565 result = component_ref (result, get_symbol_decl (field));
1566 this->result_ = result;
1568 return;
1570 else if (field->offset > offset)
1571 break;
1575 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1578 /* Build an unary address expression. */
1580 void visit (AddrExp *e) final override
1582 tree type = build_ctype (e->type);
1583 tree exp;
1585 /* The frontend optimizer can convert const symbol into a struct literal.
1586 Taking the address of a struct literal is otherwise illegal. */
1587 if (e->e1->op == EXP::structLiteral)
1589 StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
1590 gcc_assert (sle != NULL);
1592 /* Build the reference symbol, the decl is built first as the
1593 initializer may have recursive references. */
1594 if (!sle->sym)
1596 sle->sym = build_artificial_decl (build_ctype (sle->type),
1597 NULL_TREE, "S");
1598 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1599 d_pushdecl (sle->sym);
1600 rest_of_decl_compilation (sle->sym, 1, 0);
1603 exp = sle->sym;
1605 else
1606 exp = build_expr (e->e1, this->constp_, this->literalp_);
1608 TREE_CONSTANT (exp) = 0;
1609 this->result_ = d_convert (type, build_address (exp));
1612 /* Build a function call expression. */
1614 void visit (CallExp *e) final override
1616 Type *tb = e->e1->type->toBasetype ();
1617 Expression *e1b = e->e1;
1619 tree callee = NULL_TREE;
1620 tree object = NULL_TREE;
1621 tree cleanup = NULL_TREE;
1622 tree returnvalue = NULL_TREE;
1623 TypeFunction *tf = NULL;
1625 /* Calls to delegates can sometimes look like this. */
1626 if (e1b->op == EXP::comma)
1628 e1b = e1b->isCommaExp ()->e2;
1629 gcc_assert (e1b->op == EXP::variable);
1631 Declaration *var = e1b->isVarExp ()->var;
1632 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1635 if (e1b->op == EXP::dotVariable && tb->ty != TY::Tdelegate)
1637 DotVarExp *dve = e1b->isDotVarExp ();
1639 /* Don't modify the static initializer for struct literals. */
1640 if (dve->e1->op == EXP::structLiteral)
1642 StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
1643 sle->useStaticInit = false;
1646 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1647 if (fd != NULL)
1649 /* Get the correct callee from the DotVarExp object. */
1650 tree fndecl = get_symbol_decl (fd);
1651 AggregateDeclaration *ad = fd->isThis ();
1653 /* Static method; ignore the object instance. */
1654 if (!ad)
1655 callee = build_address (fndecl);
1656 else
1658 tree thisexp = build_expr (dve->e1);
1660 /* When constructing temporaries, if the constructor throws,
1661 then the object is destructed even though it is not a fully
1662 constructed object yet. And so this call will need to be
1663 moved inside the TARGET_EXPR_INITIAL slot. */
1664 if (fd->isCtorDeclaration ()
1665 && TREE_CODE (thisexp) == COMPOUND_EXPR
1666 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1667 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1669 cleanup = TREE_OPERAND (thisexp, 0);
1670 thisexp = TREE_OPERAND (thisexp, 1);
1673 if (TREE_CODE (thisexp) == CONSTRUCTOR)
1674 thisexp = force_target_expr (thisexp);
1676 /* Want reference to `this' object. */
1677 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1678 thisexp = build_address (thisexp);
1680 /* Make the callee a virtual call. */
1681 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1683 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1684 tree thistype = build_ctype (ad->handleType ());
1685 thisexp = build_nop (thistype, d_save_expr (thisexp));
1686 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1688 else
1689 fndecl = build_address (fndecl);
1691 /* C++ constructors return void, even though front-end semantic
1692 treats them as implicitly returning `this'. Set returnvalue
1693 to override the result of this expression. */
1694 if (fd->isCtorDeclaration ())
1696 thisexp = d_save_expr (thisexp);
1697 returnvalue = thisexp;
1700 callee = build_method_call (fndecl, thisexp, fd->type);
1705 if (callee == NULL_TREE)
1706 callee = build_expr (e1b);
1708 if (METHOD_CALL_EXPR (callee))
1710 /* This could be a delegate expression (TY == Tdelegate), but not
1711 actually a delegate variable. */
1712 if (e1b->op == EXP::dotVariable)
1714 /* This gets the true function type, getting the function type
1715 from e1->type can sometimes be incorrect, such as when calling
1716 a `ref' return function. */
1717 tf = get_function_type (e1b->isDotVarExp ()->var->type);
1719 else
1720 tf = get_function_type (tb);
1722 extract_from_method_call (callee, callee, object);
1724 else if (tb->ty == TY::Tdelegate)
1726 /* Delegate call, extract .object and .funcptr from var. */
1727 callee = d_save_expr (callee);
1728 tf = get_function_type (tb);
1729 object = delegate_object (callee);
1730 callee = delegate_method (callee);
1732 else if (e1b->op == EXP::variable)
1734 FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
1735 gcc_assert (fd != NULL);
1736 tf = get_function_type (fd->type);
1738 if (fd->isNested ())
1740 /* Maybe re-evaluate symbol storage treating `fd' as public. */
1741 if (call_by_alias_p (d_function_chain->function, fd))
1742 TREE_PUBLIC (callee) = 1;
1744 object = get_frame_for_symbol (fd);
1746 else if (fd->needThis ())
1748 error_at (make_location_t (e1b->loc),
1749 "need %<this%> to access member %qs", fd->toChars ());
1750 /* Continue compiling... */
1751 object = null_pointer_node;
1754 else
1756 /* Normal direct function call. */
1757 tf = get_function_type (tb);
1760 gcc_assert (tf != NULL);
1762 /* Now we have the type, callee and maybe object reference,
1763 build the call expression. */
1764 tree exp = d_build_call (tf, callee, object, e->arguments);
1766 if (returnvalue != NULL_TREE)
1767 exp = compound_expr (exp, returnvalue);
1769 if (tf->isref ())
1770 exp = build_deref (exp);
1772 /* Some library calls are defined to return a generic type.
1773 this->type is the real type we want to return. */
1774 if (e->type->isTypeBasic ())
1775 exp = d_convert (build_ctype (e->type), exp);
1777 /* If this call was found to be a constructor for a temporary with a
1778 cleanup, then move the call inside the TARGET_EXPR. */
1779 if (cleanup != NULL_TREE)
1781 tree init = TARGET_EXPR_INITIAL (cleanup);
1782 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1784 /* Keep the return value outside the TARGET_EXPR. */
1785 if (returnvalue != NULL_TREE)
1786 cleanup = compound_expr (cleanup, TREE_OPERAND (exp, 1));
1788 exp = cleanup;
1791 this->result_ = exp;
1794 /* Build a delegate expression. */
1796 void visit (DelegateExp *e) final override
1798 if (e->func->semanticRun == PASS::semantic3done)
1800 /* Add the function as nested function if it belongs to this module.
1801 ie: it is a member of this module, or it is a template instance. */
1802 Dsymbol *owner = e->func->toParent ();
1803 while (!owner->isTemplateInstance () && owner->toParent ())
1804 owner = owner->toParent ();
1805 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1806 build_decl_tree (e->func);
1809 tree fndecl;
1810 tree object;
1812 if (e->func->isNested () && !e->func->isThis ())
1814 if (e->e1->op == EXP::null_)
1815 object = build_expr (e->e1);
1816 else
1817 object = get_frame_for_symbol (e->func);
1819 fndecl = build_address (get_symbol_decl (e->func));
1821 else
1823 if (!e->func->isThis ())
1825 error ("delegates are only for non-static functions");
1826 this->result_ = error_mark_node;
1827 return;
1830 object = build_expr (e->e1);
1832 /* Want reference to `this' object. */
1833 if (e->e1->type->ty != TY::Tclass && e->e1->type->ty != TY::Tpointer)
1834 object = build_address (object);
1836 /* Object reference could be the outer `this' field of a class or
1837 closure of type `void*'. Cast it to the right type. */
1838 if (e->e1->type->ty == TY::Tclass)
1839 object = d_convert (build_ctype (e->e1->type), object);
1841 fndecl = get_symbol_decl (e->func);
1843 /* Get pointer to function out of the virtual table. */
1844 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1845 && e->e1->op != EXP::super_ && e->e1->op != EXP::dotType)
1847 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1848 object = d_save_expr (object);
1849 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1851 else
1852 fndecl = build_address (fndecl);
1855 this->result_ = build_method_call (fndecl, object, e->type);
1858 /* Build a type component expression. */
1860 void visit (DotTypeExp *e) final override
1862 /* Just a pass through to underlying expression. */
1863 this->result_ = build_expr (e->e1);
1866 /* Build a component reference expression. */
1868 void visit (DotVarExp *e) final override
1870 VarDeclaration *vd = e->var->isVarDeclaration ();
1872 /* This could also be a function, but relying on that being taken
1873 care of by the visitor interface for CallExp. */
1874 if (vd != NULL)
1876 if (!vd->isField ())
1877 this->result_ = get_decl_tree (vd);
1878 else
1880 tree object = build_expr (e->e1);
1881 Type *tb = e->e1->type->toBasetype ();
1883 if (tb->ty != TY::Tstruct)
1884 object = build_deref (object);
1886 /* __complex is represented as a struct in the front-end, but
1887 underlying is really a complex type. */
1888 if (e->e1->type->ty == TY::Tenum
1889 && e->e1->type->isTypeEnum ()->sym->isSpecial ())
1890 object = underlying_complex_expr (build_ctype (tb), object);
1892 this->result_ = component_ref (object, get_symbol_decl (vd));
1895 else
1897 error ("%qs is not a field, but a %qs",
1898 e->var->toChars (), e->var->kind ());
1899 this->result_ = error_mark_node;
1903 /* Build an assert expression, used to declare conditions that must hold at
1904 that a given point in the program. */
1906 void visit (AssertExp *e) final override
1908 Type *tb1 = e->e1->type->toBasetype ();
1909 tree arg = build_expr (e->e1);
1910 tree tmsg = NULL_TREE;
1911 tree assert_pass = void_node;
1912 tree assert_fail;
1914 if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ())
1916 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1917 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1918 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1919 libcall_fn libcall;
1921 if (e->msg)
1923 tmsg = build_expr_dtor (e->msg);
1924 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1926 else
1927 libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP;
1929 /* Build a call to _d_assert(). */
1930 assert_fail = build_assert_call (e->loc, libcall, tmsg);
1932 if (global.params.useInvariants == CHECKENABLEon)
1934 /* If the condition is a D class or struct object with an invariant,
1935 call it if the condition result is true. */
1936 if (tb1->ty == TY::Tclass)
1938 ClassDeclaration *cd = tb1->isClassHandle ();
1939 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
1941 arg = d_save_expr (arg);
1942 assert_pass = build_libcall (LIBCALL_INVARIANT,
1943 Type::tvoid, 1, arg);
1946 else if (tb1->ty == TY::Tpointer
1947 && tb1->nextOf ()->ty == TY::Tstruct)
1949 StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
1950 if (sd->inv != NULL)
1952 Expressions args;
1953 arg = d_save_expr (arg);
1954 assert_pass = d_build_call_expr (sd->inv, arg, &args);
1959 else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
1961 /* Generate: __builtin_trap() */
1962 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
1963 assert_fail = build_call_expr (fn, 0);
1965 else
1967 /* Assert contracts are turned off. */
1968 this->result_ = void_node;
1969 return;
1972 /* Build condition that we are asserting in this contract. */
1973 tree condition = convert_for_condition (arg, e->e1->type);
1975 /* We expect the condition to always be true, as what happens if an assert
1976 contract is false is undefined behavior. */
1977 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
1978 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
1979 tree pred_type = TREE_VALUE (arg_types);
1980 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
1982 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
1983 build_int_cst (expected_type, 1));
1984 condition = d_truthvalue_conversion (condition);
1986 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
1989 /* Build a declaration expression. */
1991 void visit (DeclarationExp *e) final override
1993 /* Compile the declaration. */
1994 push_stmt_list ();
1995 build_decl_tree (e->declaration);
1996 tree result = pop_stmt_list ();
1998 /* Construction of an array for typesafe-variadic function arguments
1999 can cause an empty STMT_LIST here. This can causes problems
2000 during gimplification. */
2001 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
2002 result = build_empty_stmt (input_location);
2004 this->result_ = result;
2007 /* Build a typeid expression. Returns an instance of class TypeInfo
2008 corresponding to. */
2010 void visit (TypeidExp *e) final override
2012 if (Type *tid = isType (e->obj))
2014 tree ti = build_typeinfo (e, tid);
2016 /* If the typeinfo is at an offset. */
2017 if (tid->vtinfo->offset)
2018 ti = build_offset (ti, size_int (tid->vtinfo->offset));
2020 this->result_ = build_nop (build_ctype (e->type), ti);
2022 else if (Expression *tid = isExpression (e->obj))
2024 Type *type = tid->type->toBasetype ();
2025 assert (type->ty == TY::Tclass);
2027 /* Generate **classptr to get the classinfo. */
2028 tree ci = build_expr (tid);
2029 ci = indirect_ref (ptr_type_node, ci);
2030 ci = indirect_ref (ptr_type_node, ci);
2032 /* Add extra indirection for interfaces. */
2033 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
2034 ci = indirect_ref (ptr_type_node, ci);
2036 this->result_ = build_nop (build_ctype (e->type), ci);
2038 else
2039 gcc_unreachable ();
2042 /* Build a function/lambda expression. */
2044 void visit (FuncExp *e) final override
2046 Type *ftype = e->type->toBasetype ();
2048 /* This check is for lambda's, remove `vthis' as function isn't nested. */
2049 if (e->fd->tok == TOK::reserved && ftype->ty == TY::Tpointer)
2051 e->fd->tok = TOK::function_;
2052 e->fd->vthis = NULL;
2055 /* Compile the function literal body. */
2056 build_decl_tree (e->fd);
2058 /* If nested, this will be a trampoline. */
2059 if (e->fd->isNested ())
2061 tree func = build_address (get_symbol_decl (e->fd));
2062 tree object;
2064 if (this->constp_)
2066 /* Static delegate variables have no context pointer. */
2067 object = null_pointer_node;
2068 this->result_ = build_method_call (func, object, e->fd->type);
2069 TREE_CONSTANT (this->result_) = 1;
2071 else
2073 object = get_frame_for_symbol (e->fd);
2074 this->result_ = build_method_call (func, object, e->fd->type);
2077 else
2079 this->result_ = build_nop (build_ctype (e->type),
2080 build_address (get_symbol_decl (e->fd)));
2084 /* Build a halt expression. */
2086 void visit (HaltExp *) final override
2088 /* Should we use trap() or abort()? */
2089 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2090 this->result_ = build_call_expr (ttrap, 0);
2093 /* Build a symbol pointer offset expression. */
2095 void visit (SymOffExp *e) final override
2097 /* Build the address and offset of the symbol. */
2098 size_t soffset = e->isSymOffExp ()->offset;
2099 tree result = get_decl_tree (e->var);
2100 TREE_USED (result) = 1;
2102 if (declaration_reference_p (e->var))
2103 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2104 else
2105 result = build_address (result);
2107 if (!soffset)
2108 result = d_convert (build_ctype (e->type), result);
2109 else
2111 tree offset = size_int (soffset);
2112 result = build_nop (build_ctype (e->type),
2113 build_offset (result, offset));
2116 this->result_ = result;
2119 /* Build a variable expression. */
2121 void visit (VarExp *e) final override
2123 if (e->var->needThis ())
2125 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2126 this->result_ = error_mark_node;
2127 return;
2129 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2131 /* __ctfe is always false at run-time. */
2132 this->result_ = integer_zero_node;
2133 return;
2136 /* This check is same as is done in FuncExp for lambdas. */
2137 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2138 if (fld != NULL)
2140 if (fld->tok == TOK::reserved)
2142 fld->tok = TOK::function_;
2143 fld->vthis = NULL;
2146 /* Compiler the function literal body. */
2147 build_decl_tree (fld);
2150 if (this->constp_)
2152 /* Want the initializer, not the expression. */
2153 VarDeclaration *var = e->var->isVarDeclaration ();
2154 SymbolDeclaration *sdecl = e->var->isSymbolDeclaration ();
2155 tree init = NULL_TREE;
2157 if (var && (var->isConst () || var->isImmutable ())
2158 && e->type->toBasetype ()->ty != TY::Tsarray && var->_init)
2160 if (var->inuse)
2161 error_at (make_location_t (e->loc), "recursive reference %qs",
2162 e->toChars ());
2163 else
2165 var->inuse++;
2166 init = build_expr (initializerToExpression (var->_init), true);
2167 var->inuse--;
2170 else if (sdecl && sdecl->dsym)
2172 if (StructDeclaration *sd = sdecl->dsym->isStructDeclaration ())
2173 init = layout_struct_initializer (sd);
2174 else if (ClassDeclaration *cd = sdecl->dsym->isClassDeclaration ())
2175 init = layout_class_initializer (cd);
2176 else
2177 gcc_unreachable ();
2179 else
2180 error_at (make_location_t (e->loc), "non-constant expression %qs",
2181 e->toChars ());
2183 if (init != NULL_TREE)
2184 this->result_ = init;
2185 else
2186 this->result_ = error_mark_node;
2188 else
2190 tree result = get_decl_tree (e->var);
2191 TREE_USED (result) = 1;
2193 /* The variable expression generated for `__traits(initSymbol)'. */
2194 if (SymbolDeclaration *sd = e->var->isSymbolDeclaration ())
2196 if (e->type->isTypeDArray ())
2198 /* Generate a slice for non-zero initialized aggregates,
2199 otherwise create an empty array. */
2200 gcc_assert (e->type == Type::tvoid->arrayOf ()->constOf ());
2202 tree type = build_ctype (e->type);
2203 tree length = size_int (sd->dsym->structsize);
2204 tree ptr = (sd->dsym->isStructDeclaration ()
2205 && sd->dsym->type->isZeroInit (e->loc))
2206 ? null_pointer_node : build_address (result);
2208 this->result_ = d_array_value (type, length, ptr);
2209 return;
2213 /* For variables that are references - currently only out/inout
2214 arguments; objects don't count - evaluating the variable means
2215 we want what it refers to. */
2216 if (declaration_reference_p (e->var))
2217 result = indirect_ref (build_ctype (e->var->type), result);
2219 this->result_ = result;
2223 /* Build a this variable expression. */
2225 void visit (ThisExp *e) final override
2227 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2228 tree result = NULL_TREE;
2230 if (e->var)
2231 result = get_decl_tree (e->var);
2232 else
2234 gcc_assert (fd && fd->vthis);
2235 result = get_decl_tree (fd->vthis);
2238 if (e->type->ty == TY::Tstruct)
2239 result = build_deref (result);
2241 this->result_ = result;
2244 /* Build a new expression, which allocates memory either on the garbage
2245 collected heap or by using a class or struct specific allocator. */
2247 void visit (NewExp *e) final override
2249 Type *tb = e->type->toBasetype ();
2250 tree result;
2252 if (tb->ty == TY::Tclass)
2254 /* Allocating a new class. */
2255 tb = e->newtype->toBasetype ();
2257 ClassDeclaration *cd = tb->isTypeClass ()->sym;
2258 tree type = build_ctype (tb);
2259 tree setup_exp = NULL_TREE;
2260 tree new_call;
2262 if (e->onstack)
2264 /* If being used as an initializer for a local variable with scope
2265 storage class, then the instance is allocated on the stack
2266 rather than the heap or using the class specific allocator. */
2267 tree var = build_local_temp (TREE_TYPE (type));
2268 new_call = build_nop (type, build_address (var));
2269 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2271 else if (global.params.ehnogc && e->thrownew)
2273 /* Allocating a `@nogc' Exception with `_d_newThrowable' has already
2274 been handled by the front-end. */
2275 gcc_unreachable ();
2277 else
2279 /* Generate: _d_newclass() */
2280 new_call = build_expr (e->lowering);
2283 /* Set the context pointer for nested classes. */
2284 if (cd->isNested ())
2286 tree field = get_symbol_decl (cd->vthis);
2287 tree value = NULL_TREE;
2289 if (e->thisexp)
2291 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2292 /* The class or function we're nested in. */
2293 Dsymbol *outer = cd->toParentLocal ();
2295 value = build_expr (e->thisexp);
2297 if (outer != tcd)
2299 ClassDeclaration *ocd = outer->isClassDeclaration ();
2300 int offset = 0;
2301 gcc_assert (ocd->isBaseOf (tcd, &offset));
2302 /* Could just add offset... */
2303 value = convert_expr (value, e->thisexp->type, ocd->type);
2306 else
2307 value = build_vthis (cd);
2309 if (value != NULL_TREE)
2311 /* Generate: (new())->vthis = this; */
2312 new_call = d_save_expr (new_call);
2313 field = component_ref (build_deref (new_call), field);
2314 setup_exp = compound_expr (setup_exp,
2315 modify_expr (field, value));
2318 new_call = compound_expr (setup_exp, new_call);
2320 /* Call the class constructor. */
2321 if (e->member)
2322 result = d_build_call_expr (e->member, new_call, e->arguments);
2323 else
2324 result = new_call;
2326 if (e->argprefix)
2327 result = compound_expr (build_expr (e->argprefix), result);
2329 else if (tb->ty == TY::Tpointer
2330 && tb->nextOf ()->toBasetype ()->ty == TY::Tstruct)
2332 /* Allocating memory for a new struct. */
2333 Type *htype = e->newtype->toBasetype ();
2334 gcc_assert (!e->onstack);
2336 TypeStruct *stype = htype->isTypeStruct ();
2337 StructDeclaration *sd = stype->sym;
2338 tree new_call;
2340 /* Cannot new an opaque struct. */
2341 if (sd->size (e->loc) == 0)
2343 this->result_ = d_convert (build_ctype (e->type),
2344 integer_zero_node);
2345 return;
2348 /* Generate: _d_newitemT() */
2349 libcall_fn libcall = htype->isZeroInit ()
2350 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2351 tree arg = build_typeinfo (e, e->newtype);
2352 new_call = build_libcall (libcall, tb, 1, arg);
2354 if (e->member || !e->arguments)
2356 /* Set the context pointer for nested structs. */
2357 if (sd->isNested ())
2359 tree value = build_vthis (sd);
2360 tree field = get_symbol_decl (sd->vthis);
2361 tree type = build_ctype (stype);
2363 new_call = d_save_expr (new_call);
2364 field = component_ref (indirect_ref (type, new_call), field);
2365 new_call = compound_expr (modify_expr (field, value), new_call);
2368 /* Call the struct constructor. */
2369 if (e->member)
2370 result = d_build_call_expr (e->member, new_call, e->arguments);
2371 else
2372 result = new_call;
2374 else
2376 /* If we have a user supplied initializer, then set-up with a
2377 struct literal. */
2378 if (e->arguments != NULL && sd->fields.length != 0)
2380 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2381 e->arguments,
2382 htype);
2383 new_call = d_save_expr (new_call);
2384 se->type = sd->type;
2385 se->sym = new_call;
2386 result = compound_expr (build_expr (se), new_call);
2388 else
2389 result = new_call;
2392 if (e->argprefix)
2393 result = compound_expr (build_expr (e->argprefix), result);
2395 else if (tb->ty == TY::Tarray)
2397 /* Allocating memory for a new D array. */
2398 tb = e->newtype->toBasetype ();
2399 TypeDArray *tarray = tb->isTypeDArray ();
2401 gcc_assert (e->arguments && e->arguments->length >= 1);
2403 if (e->arguments->length == 1)
2405 /* Single dimension array allocations. */
2406 Expression *arg = (*e->arguments)[0];
2408 if (tarray->next->size () == 0)
2410 /* Array element size is unknown. */
2411 this->result_ = d_array_value (build_ctype (e->type),
2412 size_int (0), null_pointer_node);
2413 return;
2416 libcall_fn libcall = tarray->next->isZeroInit ()
2417 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
2418 result = build_libcall (libcall, tb, 2,
2419 build_typeinfo (e, e->type),
2420 build_expr (arg));
2422 else
2424 /* Multidimensional array allocations. */
2425 tree tarray = make_array_type (Type::tsize_t, e->arguments->length);
2426 tree var = build_local_temp (tarray);
2427 vec <constructor_elt, va_gc> *elms = NULL;
2429 /* Get the base element type for the array, generating the
2430 initializer for the dims parameter along the way. */
2431 Type *telem = e->newtype->toBasetype ();
2432 for (size_t i = 0; i < e->arguments->length; i++)
2434 Expression *arg = (*e->arguments)[i];
2435 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2437 gcc_assert (telem->ty == TY::Tarray);
2438 telem = telem->toBasetype ()->nextOf ();
2439 gcc_assert (telem);
2442 /* Initialize the temporary. */
2443 tree init = modify_expr (var, build_constructor (tarray, elms));
2444 var = compound_expr (init, var);
2446 /* Generate: _d_newarraymTX(ti, dims)
2447 or: _d_newarraymiTX(ti, dims) */
2448 libcall_fn libcall = telem->isZeroInit ()
2449 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2451 tree tinfo = build_typeinfo (e, e->type);
2452 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2453 size_int (e->arguments->length),
2454 build_address (var));
2456 result = build_libcall (libcall, tb, 2, tinfo, dims);
2459 if (e->argprefix)
2460 result = compound_expr (build_expr (e->argprefix), result);
2462 else if (tb->ty == TY::Tpointer)
2464 /* Allocating memory for a new pointer. */
2465 TypePointer *tpointer = tb->isTypePointer ();
2467 if (tpointer->next->size () == 0)
2469 /* Pointer element size is unknown. */
2470 this->result_ = d_convert (build_ctype (e->type),
2471 integer_zero_node);
2472 return;
2475 libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
2476 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2478 tree arg = build_typeinfo (e, e->newtype);
2479 result = build_libcall (libcall, tb, 1, arg);
2481 if (e->arguments && e->arguments->length == 1)
2483 result = d_save_expr (result);
2484 tree init = modify_expr (build_deref (result),
2485 build_expr ((*e->arguments)[0]));
2486 result = compound_expr (init, result);
2489 if (e->argprefix)
2490 result = compound_expr (build_expr (e->argprefix), result);
2492 else if (tb->ty == TY::Taarray)
2494 /* Allocating memory for a new associative array. */
2495 tree arg = build_typeinfo (e, e->newtype);
2496 tree mem = build_libcall (LIBCALL_AANEW, Type::tvoidptr, 1, arg);
2498 /* Return an associative array pointed to by MEM. */
2499 tree aatype = build_ctype (tb);
2500 vec <constructor_elt, va_gc> *ce = NULL;
2501 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2503 result = build_nop (build_ctype (e->type),
2504 build_constructor (aatype, ce));
2506 else
2507 gcc_unreachable ();
2509 this->result_ = convert_expr (result, tb, e->type);
2512 /* Build an integer literal. */
2514 void visit (IntegerExp *e) final override
2516 tree ctype = build_ctype (e->type->toBasetype ());
2517 this->result_ = build_integer_cst (e->value, ctype);
2520 /* Build a floating-point literal. */
2522 void visit (RealExp *e) final override
2524 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2527 /* Build a complex literal. */
2529 void visit (ComplexExp *e) final override
2531 Type *tnext;
2533 switch (e->type->toBasetype ()->ty)
2535 case TY::Tcomplex32:
2536 tnext = (TypeBasic *) Type::tfloat32;
2537 break;
2539 case TY::Tcomplex64:
2540 tnext = (TypeBasic *) Type::tfloat64;
2541 break;
2543 case TY::Tcomplex80:
2544 tnext = (TypeBasic *) Type::tfloat80;
2545 break;
2547 default:
2548 gcc_unreachable ();
2551 this->result_ = build_complex (build_ctype (e->type),
2552 build_float_cst (creall (e->value), tnext),
2553 build_float_cst (cimagl (e->value), tnext));
2556 /* Build a string literal, all strings are null terminated except for
2557 static arrays. */
2559 void visit (StringExp *e) final override
2561 Type *tb = e->type->toBasetype ();
2562 tree type = build_ctype (e->type);
2564 if (tb->ty == TY::Tsarray)
2566 /* Turn the string into a constructor for the static array. */
2567 vec <constructor_elt, va_gc> *elms = NULL;
2568 vec_safe_reserve (elms, e->len);
2569 tree etype = TREE_TYPE (type);
2571 for (size_t i = 0; i < e->len; i++)
2573 tree value = build_integer_cst (e->getCodeUnit (i), etype);
2574 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2577 tree ctor = build_constructor (type, elms);
2578 TREE_CONSTANT (ctor) = 1;
2579 this->result_ = ctor;
2581 else
2583 /* Copy the string contents to a null terminated string. */
2584 dinteger_t length = (e->len * e->sz);
2585 char *string = XALLOCAVEC (char, length + 1);
2586 if (length > 0)
2587 memcpy (string, e->string, length);
2588 string[length] = '\0';
2590 /* String value and type includes the null terminator. */
2591 tree value = build_string (length, string);
2592 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2593 value = build_address (value);
2595 if (tb->ty == TY::Tarray)
2596 value = d_array_value (type, size_int (e->len), value);
2598 TREE_CONSTANT (value) = 1;
2599 this->result_ = d_convert (type, value);
2603 /* Build a tuple literal. Just an argument list that may have
2604 side effects that need evaluation. */
2606 void visit (TupleExp *e) final override
2608 tree result = NULL_TREE;
2610 if (e->e0)
2611 result = build_expr (e->e0, this->constp_, true);
2613 for (size_t i = 0; i < e->exps->length; ++i)
2615 Expression *exp = (*e->exps)[i];
2616 result = compound_expr (result, build_expr (exp, this->constp_, true));
2619 if (result == NULL_TREE)
2620 result = void_node;
2622 this->result_ = result;
2625 /* Build an array literal. The common type of the all elements is taken to
2626 be the type of the array element, and all elements are implicitly
2627 converted to that type. */
2629 void visit (ArrayLiteralExp *e) final override
2631 Type *tb = e->type->toBasetype ();
2633 /* Implicitly convert void[n] to ubyte[n]. */
2634 if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid)
2635 tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());
2637 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray
2638 || tb->ty == TY::Tpointer);
2640 /* Handle empty array literals. */
2641 if (e->elements->length == 0)
2643 if (tb->ty == TY::Tarray)
2644 this->result_ = d_array_value (build_ctype (e->type),
2645 size_int (0), null_pointer_node);
2646 else
2647 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2648 NULL);
2650 return;
2653 /* Build an expression that assigns the expressions in ELEMENTS to
2654 a constructor. */
2655 vec <constructor_elt, va_gc> *elms = NULL;
2656 vec_safe_reserve (elms, e->elements->length);
2657 bool constant_p = true;
2658 tree saved_elems = NULL_TREE;
2660 Type *etype = tb->nextOf ();
2661 tree satype = make_array_type (etype, e->elements->length);
2663 for (size_t i = 0; i < e->elements->length; i++)
2665 Expression *expr = e->getElement (i);
2666 tree value = build_expr (expr, this->constp_, true);
2668 /* Only append nonzero values, the backend will zero out the rest
2669 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2670 if (!initializer_zerop (value))
2672 if (!TREE_CONSTANT (value))
2673 constant_p = false;
2675 /* Split construction of values out of the constructor if there
2676 may be side effects. */
2677 tree init = stabilize_expr (&value);
2678 if (init != NULL_TREE)
2679 saved_elems = compound_expr (saved_elems, init);
2681 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2682 convert_expr (value, expr->type, etype));
2686 /* Now return the constructor as the correct type. For static arrays there
2687 is nothing else to do. For dynamic arrays, return a two field struct.
2688 For pointers, return the address. */
2689 tree ctor = build_constructor (satype, elms);
2690 tree type = build_ctype (e->type);
2692 /* Nothing else to do for static arrays. */
2693 if (tb->ty == TY::Tsarray || this->constp_)
2695 /* Can't take the address of the constructor, so create an anonymous
2696 static symbol, and then refer to it. */
2697 if (tb->ty != TY::Tsarray)
2699 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2700 ctor = build_address (decl);
2701 if (tb->ty == TY::Tarray)
2702 ctor = d_array_value (type, size_int (e->elements->length), ctor);
2704 d_pushdecl (decl);
2705 rest_of_decl_compilation (decl, 1, 0);
2708 /* If the array literal is readonly or static. */
2709 if (constant_p)
2710 TREE_CONSTANT (ctor) = 1;
2711 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2712 TREE_STATIC (ctor) = 1;
2714 /* Use memset to fill any alignment holes in the array. */
2715 if (!this->constp_ && !this->literalp_)
2717 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
2719 if (ts != NULL && (!identity_compare_p (ts->sym)
2720 || ts->sym->isUnionDeclaration ()))
2722 tree var = build_local_temp (TREE_TYPE (ctor));
2723 tree init = build_memset_call (var);
2724 /* Evaluate memset() first, then any saved elements. */
2725 saved_elems = compound_expr (init, saved_elems);
2726 ctor = compound_expr (modify_expr (var, ctor), var);
2730 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2732 else if (e->onstack)
2734 /* Array literal for a `scope' dynamic array. */
2735 gcc_assert (tb->ty == TY::Tarray);
2736 ctor = force_target_expr (ctor);
2737 this->result_ = d_array_value (type, size_int (e->elements->length),
2738 build_address (ctor));
2740 else
2742 /* Allocate space on the memory managed heap. */
2743 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2744 etype->pointerTo (), 2,
2745 build_typeinfo (e, etype->arrayOf ()),
2746 size_int (e->elements->length));
2747 mem = d_save_expr (mem);
2749 /* Now copy the constructor into memory. */
2750 tree size = size_mult_expr (size_int (e->elements->length),
2751 size_int (tb->nextOf ()->size ()));
2753 tree result = build_memcpy_call (mem, build_address (ctor), size);
2755 /* Return the array pointed to by MEM. */
2756 result = compound_expr (result, mem);
2758 if (tb->ty == TY::Tarray)
2759 result = d_array_value (type, size_int (e->elements->length), result);
2761 this->result_ = compound_expr (saved_elems, result);
2765 /* Build an associative array literal. The common type of the all keys is
2766 taken to be the key type, and common type of all values the value type.
2767 All keys and values are then implicitly converted as needed. */
2769 void visit (AssocArrayLiteralExp *e) final override
2771 /* Want the mutable type for typeinfo reference. */
2772 Type *tb = e->type->toBasetype ()->mutableOf ();
2774 /* Handle empty assoc array literals. */
2775 TypeAArray *ta = tb->isTypeAArray ();
2776 if (e->keys->length == 0)
2778 this->result_ = build_constructor (build_ctype (ta), NULL);
2779 return;
2782 /* Build an expression that assigns all expressions in KEYS
2783 to a constructor. */
2784 tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
2785 e->keys, this->constp_);
2786 tree init = stabilize_expr (&akeys);
2788 /* Do the same with all expressions in VALUES. */
2789 tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
2790 e->values, this->constp_);
2791 init = compound_expr (init, stabilize_expr (&avals));
2793 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2794 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2795 size_int (e->keys->length),
2796 build_address (akeys));
2797 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2798 size_int (e->values->length),
2799 build_address (avals));
2801 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2802 build_typeinfo (e, ta), keys, vals);
2804 /* Return an associative array pointed to by MEM. */
2805 tree aatype = build_ctype (ta);
2806 vec <constructor_elt, va_gc> *ce = NULL;
2807 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2809 tree result = build_nop (build_ctype (e->type),
2810 build_constructor (aatype, ce));
2811 this->result_ = compound_expr (init, result);
2814 /* Build a struct literal. */
2816 void visit (StructLiteralExp *e) final override
2818 /* Handle empty struct literals. */
2819 if (e->elements == NULL || e->sd->fields.length == 0)
2821 this->result_ = build_constructor (build_ctype (e->type), NULL);
2822 return;
2825 /* Building sinit trees are delayed until after frontend semantic
2826 processing has complete. Build the static initializer now. */
2827 if (e->useStaticInit && !this->constp_)
2829 tree init = aggregate_initializer_decl (e->sd);
2831 /* If initializing a symbol, don't forget to set it. */
2832 if (e->sym != NULL)
2834 tree var = build_deref (e->sym);
2835 init = compound_expr (modify_expr (var, init), var);
2838 this->result_ = init;
2839 return;
2842 /* Build a constructor that assigns the expressions in ELEMENTS
2843 at each field index that has been filled in. */
2844 vec <constructor_elt, va_gc> *ve = NULL;
2845 tree saved_elems = NULL_TREE;
2847 /* CTFE may fill the hidden pointer by NullExp. */
2848 gcc_assert (e->elements->length <= e->sd->fields.length);
2850 Type *tb = e->type->toBasetype ();
2851 gcc_assert (tb->ty == TY::Tstruct);
2853 for (size_t i = 0; i < e->elements->length; i++)
2855 Expression *exp = (*e->elements)[i];
2856 if (!exp)
2857 continue;
2859 VarDeclaration *field = e->sd->fields[i];
2860 Type *type = exp->type->toBasetype ();
2861 Type *ftype = field->type->toBasetype ();
2862 tree value = NULL_TREE;
2864 if (ftype->ty == TY::Tsarray && !same_type_p (type, ftype))
2866 /* Initialize a static array with a single element. */
2867 tree elem = build_expr (exp, this->constp_, true);
2868 saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
2869 elem = d_save_expr (elem);
2871 if (initializer_zerop (elem))
2872 value = build_constructor (build_ctype (ftype), NULL);
2873 else
2874 value = build_array_from_val (ftype, elem);
2876 else
2878 value = convert_expr (build_expr (exp, this->constp_, true),
2879 exp->type, field->type);
2882 /* Split construction of values out of the constructor. */
2883 saved_elems = compound_expr (saved_elems, stabilize_expr (&value));
2885 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2888 /* Maybe setup hidden pointer to outer scope context. */
2889 if (e->sd->isNested () && e->elements->length != e->sd->fields.length
2890 && this->constp_ == false)
2892 tree field = get_symbol_decl (e->sd->vthis);
2893 tree value = build_vthis (e->sd);
2894 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2895 gcc_assert (e->useStaticInit == false);
2898 /* Build a constructor in the correct shape of the aggregate type. */
2899 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2901 /* Nothing more to do for constant literals. */
2902 if (this->constp_)
2904 /* If the struct literal is a valid for static data. */
2905 if (TREE_CONSTANT (ctor)
2906 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2907 TREE_STATIC (ctor) = 1;
2909 this->result_ = compound_expr (saved_elems, ctor);
2910 return;
2913 /* Construct the struct literal for run-time. */
2914 if (e->sym != NULL)
2916 /* Store the result in a symbol to initialize the literal. */
2917 tree var = build_deref (e->sym);
2918 ctor = compound_expr (modify_expr (var, ctor), var);
2920 else if (!this->literalp_)
2922 /* Use memset to fill any alignment holes in the object. */
2923 if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
2925 tree var = build_local_temp (TREE_TYPE (ctor));
2926 tree init = build_memset_call (var);
2927 /* Evaluate memset() first, then any saved element constructors. */
2928 saved_elems = compound_expr (init, saved_elems);
2929 ctor = compound_expr (modify_expr (var, ctor), var);
2933 this->result_ = compound_expr (saved_elems, ctor);
2936 /* Build a null literal. */
2938 void visit (NullExp *e) final override
2940 this->result_ = build_typeof_null_value (e->type);
2943 /* Build a vector literal. */
2945 void visit (VectorExp *e) final override
2947 /* First handle array literal expressions. */
2948 if (e->e1->op == EXP::arrayLiteral)
2950 ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
2951 vec <constructor_elt, va_gc> *elms = NULL;
2952 bool constant_p = true;
2953 tree type = build_ctype (e->type);
2955 vec_safe_reserve (elms, ale->elements->length);
2956 for (size_t i = 0; i < ale->elements->length; i++)
2958 Expression *expr = ale->getElement (i);
2959 tree value = d_convert (TREE_TYPE (type),
2960 build_expr (expr, this->constp_, true));
2961 if (!CONSTANT_CLASS_P (value))
2962 constant_p = false;
2964 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2967 /* Build a VECTOR_CST from a constant vector constructor. */
2968 if (constant_p)
2969 this->result_ = build_vector_from_ctor (type, elms);
2970 else
2971 this->result_ = build_constructor (type, elms);
2973 else if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
2975 /* Build a vector representation from a static array. */
2976 this->result_ = convert_expr (build_expr (e->e1, this->constp_),
2977 e->e1->type, e->type);
2979 else
2981 /* Build constructor from single value. */
2982 tree type = build_ctype (e->type);
2983 tree value = d_convert (TREE_TYPE (type),
2984 build_expr (e->e1, this->constp_, true));
2985 this->result_ = build_vector_from_val (type, value);
2989 /* Build a static array representation of a vector expression. */
2991 void visit (VectorArrayExp *e) final override
2993 this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
2994 e->e1->type, e->type);
2997 /* Build a static class literal, return its reference. */
2999 void visit (ClassReferenceExp *e) final override
3001 /* The result of build_new_class_expr is a RECORD_TYPE, we want
3002 the reference. */
3003 tree var = build_address (build_new_class_expr (e));
3005 /* If the type of this literal is an interface, the we must add the
3006 interface offset to symbol. */
3007 if (this->constp_)
3009 TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
3010 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
3012 if (to != NULL)
3014 ClassDeclaration *from = e->originalClass ();
3015 int offset = 0;
3017 gcc_assert (to->isBaseOf (from, &offset) != 0);
3019 if (offset != 0)
3020 var = build_offset (var, size_int (offset));
3024 this->result_ = var;
3027 /* Build an uninitialized value, generated from void initializers. */
3029 void visit (VoidInitExp *e) final override
3031 /* The front-end only generates these for the initializer of globals.
3032 Represent `void' as zeroes, regardless of the type's default value. */
3033 gcc_assert (this->constp_);
3034 this->result_ = build_zero_cst (build_ctype (e->type));
3037 /* These expressions are mainly just a placeholders in the frontend.
3038 We shouldn't see them here. */
3040 void visit (ScopeExp *e) final override
3042 error_at (make_location_t (e->loc), "%qs is not an expression",
3043 e->toChars ());
3044 this->result_ = error_mark_node;
3047 void visit (TypeExp *e) final override
3049 error_at (make_location_t (e->loc), "type %qs is not an expression",
3050 e->toChars ());
3051 this->result_ = error_mark_node;
3056 /* Main entry point for ExprVisitor interface to generate code for
3057 the Expression AST class E. If CONST_P is true, then E is a
3058 constant expression. If LITERAL_P is true, then E is a value used
3059 in the initialization of another literal. */
3061 tree
3062 build_expr (Expression *e, bool const_p, bool literal_p)
3064 ExprVisitor v = ExprVisitor (const_p, literal_p);
3065 location_t saved_location = input_location;
3067 input_location = make_location_t (e->loc);
3068 e->accept (&v);
3069 tree expr = v.result ();
3070 input_location = saved_location;
3072 /* Check if initializer expression is valid constant. */
3073 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3075 error_at (make_location_t (e->loc), "non-constant expression %qs",
3076 e->toChars ());
3077 return error_mark_node;
3080 return expr;
3083 /* Same as build_expr, but also calls destructors on any temporaries. */
3085 tree
3086 build_expr_dtor (Expression *e)
3088 /* Codegen can be improved by determining if no exceptions can be thrown
3089 between the ctor and dtor, and eliminating the ctor and dtor. */
3090 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3091 tree result = build_expr (e);
3093 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3095 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3096 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3099 return result;
3102 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3104 tree
3105 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3107 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3108 tree result = build_expr (e);
3110 /* Convert for initializing the DECL_RESULT. */
3111 if (tf->isref ())
3113 /* If we are returning a reference, take the address. */
3114 result = convert_expr (result, e->type, type);
3115 result = build_address (result);
3117 else
3118 result = convert_for_rvalue (result, e->type, type);
3120 /* The decl to store the return expression. */
3121 tree decl = DECL_RESULT (cfun->decl);
3123 /* Split comma expressions, so that the result is returned directly. */
3124 tree expr = stabilize_expr (&result);
3125 result = build_assign (INIT_EXPR, decl, result);
3126 result = compound_expr (expr, return_expr (result));
3128 /* May nest the return expression inside the try/finally expression. */
3129 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3131 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3132 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3135 return result;