tree-optimization/112450 - avoid AVX512 style masking for BImode masks
[official-gcc.git] / gcc / d / expr.cc
blob17801a3bd1ef8e23c307b65b470cab979727daf1
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 Type *tb1 = e->e1->type->toBasetype ();
793 Type *tb2 = e->e2->type->toBasetype ();
794 Type *etype = tb1->nextOf ()->toBasetype ();
796 /* Save the address of `e1', so it can be evaluated first.
797 As all D run-time library functions for concat assignments update `e1'
798 in-place and then return its value, the saved address can also be used as
799 the result of this expression as well. */
800 tree lhs = build_expr (e->e1);
801 tree lexpr = stabilize_expr (&lhs);
802 tree ptr = d_save_expr (build_address (lhs));
803 tree result = NULL_TREE;
805 if (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar
806 && (etype->ty == TY::Tchar || etype->ty == TY::Twchar))
808 /* Append a dchar to a char[] or wchar[]:
809 The assignment is handled by the D run-time library, so only
810 need to call `_d_arrayappend[cw]d(&e1, e2)' */
811 libcall_fn libcall = (etype->ty == TY::Tchar)
812 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
814 result = build_libcall (libcall, e->type, 2,
815 ptr, build_expr (e->e2));
817 else
819 /* Appending an element or array to another array has already been
820 handled by the front-end. */
821 gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray);
822 gcc_unreachable ();
825 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
826 result = compound_expr (compound_expr (lexpr, ptr), result);
827 this->result_ = compound_expr (result, build_deref (ptr));
830 /* Build an assignment expression. The right operand is implicitly
831 converted to the type of the left operand, and assigned to it. */
833 void visit (AssignExp *e) final override
835 /* First, handle special assignment semantics. */
837 /* Look for array.length = n; */
838 if (e->e1->op == EXP::arrayLength)
840 /* This case should have been rewritten to `_d_arraysetlengthT` in the
841 semantic phase. */
842 gcc_unreachable ();
845 /* Look for exp = noreturn; */
846 if (e->e2->type->isTypeNoreturn ())
848 /* If the RHS is a `noreturn' expression, there is no point generating
849 any code for the assignment, just evaluate side effects. */
850 tree t1 = build_expr (e->e1);
851 tree t2 = build_expr (e->e2);
852 this->result_ = compound_expr (t1, t2);
853 return;
856 /* Look for array[] = n; */
857 if (e->e1->op == EXP::slice)
859 SliceExp *se = e->e1->isSliceExp ();
860 Type *stype = se->e1->type->toBasetype ();
861 Type *etype = stype->nextOf ()->toBasetype ();
863 /* Determine if we need to run postblit or dtor. */
864 bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
865 bool destructor = needs_dtor (etype);
867 if (e->memset == MemorySet::blockAssign)
869 /* Set a range of elements to one value. */
870 tree t1 = build_expr (e->e1);
871 tree t2 = build_expr (e->e2);
872 tree result;
874 /* Extract any array bounds checks from the slice expression. */
875 tree init = stabilize_expr (&t1);
876 t1 = d_save_expr (t1);
878 if ((postblit || destructor) && e->op != EXP::blit)
880 /* This case should have been rewritten to `_d_arraysetassign`
881 in the semantic phase. */
882 gcc_unreachable ();
885 if (integer_zerop (t2))
887 tree size = size_mult_expr (d_array_length (t1),
888 size_int (etype->size ()));
889 result = build_memset_call (d_array_ptr (t1), size);
891 else
892 result = build_array_set (d_array_ptr (t1),
893 d_array_length (t1), t2);
895 result = compound_expr (init, result);
896 this->result_ = compound_expr (result, t1);
898 else
900 /* Perform a memcpy operation. */
901 gcc_assert (e->e2->type->ty != TY::Tpointer);
903 if (!postblit && !destructor)
905 tree t1 = d_save_expr (d_array_convert (e->e1));
906 tree t2 = d_save_expr (d_array_convert (e->e2));
908 /* References to array data. */
909 tree t1ptr = d_array_ptr (t1);
910 tree t1len = d_array_length (t1);
911 tree t2ptr = d_array_ptr (t2);
913 /* Generate: memcpy(to, from, size) */
914 tree size = size_mult_expr (t1len, size_int (etype->size ()));
915 tree result = build_memcpy_call (t1ptr, t2ptr, size);
917 /* Insert check that array lengths match and do not overlap. */
918 if (array_bounds_check ())
920 /* tlencmp = (t1len == t2len) */
921 tree t2len = d_array_length (t2);
922 tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len);
924 /* toverlap = (t1ptr + size <= t2ptr
925 || t2ptr + size <= t1ptr) */
926 tree t1ptrcmp = build_boolop (LE_EXPR,
927 build_offset (t1ptr, size),
928 t2ptr);
929 tree t2ptrcmp = build_boolop (LE_EXPR,
930 build_offset (t2ptr, size),
931 t1ptr);
932 tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp,
933 t2ptrcmp);
935 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */
936 tree tassert = build_array_bounds_call (e->loc);
937 tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR,
938 tlencmp, toverlap);
940 result = build_condition (void_type_node, tboundscheck,
941 result, tassert);
944 this->result_ = compound_expr (result, t1);
946 else if ((postblit || destructor)
947 && e->op != EXP::blit && e->op != EXP::construct)
949 /* Assigning to a non-trivially copyable array has already been
950 handled by the front-end. */
951 gcc_unreachable ();
953 else
955 /* Generate: _d_arraycopy() */
956 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
957 size_int (etype->size ()),
958 d_array_convert (e->e2),
959 d_array_convert (e->e1));
963 return;
966 /* Look for reference initializations. */
967 if (e->memset == MemorySet::referenceInit)
969 gcc_assert (e->op == EXP::construct || e->op == EXP::blit);
970 gcc_assert (e->e1->op == EXP::variable);
972 Declaration *decl = e->e1->isVarExp ()->var;
973 if (decl->storage_class & (STCout | STCref))
975 tree t2 = convert_for_assignment (e->e2, e->e1->type);
976 tree t1 = build_expr (e->e1);
977 /* Want reference to lhs, not indirect ref. */
978 t1 = TREE_OPERAND (t1, 0);
979 t2 = build_address (t2);
981 this->result_ = indirect_ref (build_ctype (e->type),
982 build_assign (INIT_EXPR, t1, t2));
983 return;
987 /* Other types of assignments that may require post construction. */
988 Type *tb1 = e->e1->type->toBasetype ();
989 tree_code modifycode = (e->op == EXP::construct) ? INIT_EXPR : MODIFY_EXPR;
991 /* Look for struct assignment. */
992 if (tb1->ty == TY::Tstruct)
994 tree t1 = build_expr (e->e1);
995 tree t2 = convert_for_assignment (e->e2, e->e1->type, true);
996 StructDeclaration *sd = tb1->isTypeStruct ()->sym;
998 /* Look for struct = 0. */
999 if (e->e2->op == EXP::int64)
1001 /* Use memset to fill struct. */
1002 gcc_assert (e->op == EXP::blit);
1003 tree result = build_memset_call (t1);
1005 /* Maybe set-up hidden pointer to outer scope context. */
1006 if (sd->isNested ())
1008 tree field = get_symbol_decl (sd->vthis);
1009 tree value = build_vthis (sd);
1011 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1012 result = compound_expr (result, vthis_exp);
1015 this->result_ = compound_expr (result, t1);
1017 else
1019 /* Simple struct literal assignment. */
1020 tree init = NULL_TREE;
1022 /* Fill any alignment holes in the struct using memset. */
1023 if ((e->op == EXP::construct
1024 || (e->e2->op == EXP::structLiteral && e->op == EXP::blit))
1025 && (sd->isUnionDeclaration () || !identity_compare_p (sd)))
1027 t1 = stabilize_reference (t1);
1028 init = build_memset_call (t1);
1031 /* Elide generating assignment if init is all zeroes. */
1032 if (init != NULL_TREE && initializer_zerop (t2))
1033 this->result_ = compound_expr (init, t1);
1034 else
1036 tree result = build_assign (modifycode, t1, t2);
1037 this->result_ = compound_expr (init, result);
1041 return;
1044 /* Look for static array assignment. */
1045 if (tb1->ty == TY::Tsarray)
1047 /* Look for array = 0. */
1048 if (e->e2->op == EXP::int64)
1050 /* Use memset to fill the array. */
1051 gcc_assert (e->op == EXP::blit);
1052 this->result_ = build_memset_call (build_expr (e->e1));
1053 return;
1056 Type *etype = tb1->nextOf ();
1057 gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray);
1059 /* Determine if we need to run postblit. */
1060 const bool postblit = needs_postblit (etype);
1061 const bool destructor = needs_dtor (etype);
1062 const bool lvalue = lvalue_p (e->e2);
1064 /* Optimize static array assignment with array literal. Even if the
1065 elements in rhs are all rvalues and don't have to call postblits,
1066 this assignment should call dtors on old assigned elements. */
1067 if ((!postblit && !destructor)
1068 || (e->op == EXP::construct && e->e2->op == EXP::arrayLiteral)
1069 || (e->op == EXP::construct && e->e2->op == EXP::call)
1070 || (e->op == EXP::construct && !lvalue && postblit)
1071 || (e->op == EXP::blit || e->e1->type->size () == 0))
1073 tree t1 = build_expr (e->e1);
1074 tree t2 = convert_for_assignment (e->e2, e->e1->type);
1076 this->result_ = build_assign (modifycode, t1, t2);
1077 return;
1080 /* All other kinds of lvalue or rvalue static array assignment.
1081 Array construction has already been handled by the front-end. */
1082 gcc_assert (e->op != EXP::construct);
1083 gcc_unreachable ();
1086 /* Simple assignment. */
1087 tree t1 = build_expr (e->e1);
1088 tree t2 = convert_for_assignment (e->e2, e->e1->type);
1090 this->result_ = build_assign (modifycode, t1, t2);
1093 /* Build an assignment expression that has been lowered in the front-end. */
1095 void visit (LoweredAssignExp *e) final override
1097 this->result_ = build_expr (e->lowering);
1100 /* Build a throw expression. */
1102 void visit (ThrowExp *e) final override
1104 tree arg = build_expr_dtor (e->e1);
1105 this->result_ = build_libcall (LIBCALL_THROW, Type::tvoid, 1, arg);
1108 /* Build a postfix expression. */
1110 void visit (PostExp *e) final override
1112 tree result;
1114 if (e->op == EXP::plusPlus)
1116 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1117 build_expr (e->e1), build_expr (e->e2));
1119 else if (e->op == EXP::minusMinus)
1121 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1122 build_expr (e->e1), build_expr (e->e2));
1124 else
1125 gcc_unreachable ();
1127 TREE_SIDE_EFFECTS (result) = 1;
1128 this->result_ = result;
1131 /* Build an index expression. */
1133 void visit (IndexExp *e) final override
1135 Type *tb1 = e->e1->type->toBasetype ();
1137 if (tb1->ty == TY::Taarray)
1139 /* Get the key for the associative array. */
1140 Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
1141 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1142 libcall_fn libcall;
1143 tree tinfo, ptr;
1145 if (e->modifiable)
1147 libcall = LIBCALL_AAGETY;
1148 ptr = build_address (build_expr (e->e1));
1149 tinfo = build_typeinfo (e, tb1->unSharedOf ()->mutableOf ());
1151 else
1153 libcall = LIBCALL_AAGETRVALUEX;
1154 ptr = build_expr (e->e1);
1155 tinfo = build_typeinfo (e, tkey);
1158 /* Index the associative array. */
1159 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1160 ptr, tinfo,
1161 size_int (tb1->nextOf ()->size ()),
1162 build_address (key));
1164 if (!e->indexIsInBounds && array_bounds_check ())
1166 tree tassert = build_array_bounds_call (e->loc);
1168 result = d_save_expr (result);
1169 result = build_condition (TREE_TYPE (result),
1170 d_truthvalue_conversion (result),
1171 result, tassert);
1174 this->result_ = indirect_ref (build_ctype (e->type), result);
1176 else
1178 /* Get the array and length for static and dynamic arrays. */
1179 tree array = d_save_expr (build_expr (e->e1));
1181 tree length = NULL_TREE;
1182 if (tb1->ty != TY::Tpointer)
1183 length = get_array_length (array, tb1);
1184 else
1185 gcc_assert (e->lengthVar == NULL);
1187 /* The __dollar variable just becomes a placeholder for the
1188 actual length. */
1189 if (e->lengthVar)
1190 e->lengthVar->csym = length;
1192 /* Generate the index. */
1193 tree index = build_expr (e->e2);
1195 /* If it's a static array and the index is constant, the front end has
1196 already checked the bounds. */
1197 if (tb1->ty != TY::Tpointer)
1198 index = build_bounds_index_condition (e, index, length);
1200 /* Convert vectors to their underlying array type. */
1201 if (VECTOR_TYPE_P (TREE_TYPE (array)))
1203 tree array_type =
1204 build_array_type_nelts (TREE_TYPE (TREE_TYPE (array)),
1205 TYPE_VECTOR_SUBPARTS (TREE_TYPE (array)));
1206 d_mark_addressable (array, false);
1207 array = build1 (VIEW_CONVERT_EXPR, array_type, array);
1210 if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
1212 /* Generate `array[index]'. When the index is non-constant, we must
1213 mark the array as addressable because we'll need to do pointer
1214 arithmetic on its address. */
1215 if (TREE_CODE (index) != INTEGER_CST)
1216 d_mark_addressable (array);
1218 this->result_ = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
1219 array, index, NULL_TREE, NULL_TREE);
1221 else
1223 /* Generate `array.ptr[index]'. */
1224 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1225 ptr = void_okay_p (ptr);
1226 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1227 build_pointer_index (ptr, index));
1232 /* Build a comma expression. The type is the type of the right operand. */
1234 void visit (CommaExp *e) final override
1236 tree t1 = build_expr (e->e1);
1237 tree t2 = build_expr (e->e2);
1238 tree type = e->type ? build_ctype (e->type) : void_type_node;
1240 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1243 /* Build an array length expression. Returns the number of elements
1244 in the array. The result is of type size_t. */
1246 void visit (ArrayLengthExp *e) final override
1248 if (e->e1->type->toBasetype ()->ty == TY::Tarray)
1249 this->result_ = d_array_length (build_expr (e->e1));
1250 else
1252 /* Static arrays have already been handled by the front-end. */
1253 error ("unexpected type for array length: %qs", e->type->toChars ());
1254 this->result_ = error_mark_node;
1258 /* Build a delegate pointer expression. This will return the frame
1259 pointer value as a type void*. */
1261 void visit (DelegatePtrExp *e) final override
1263 tree t1 = build_expr (e->e1);
1264 this->result_ = delegate_object (t1);
1267 /* Build a delegate function pointer expression. This will return the
1268 function pointer value as a function type. */
1270 void visit (DelegateFuncptrExp *e) final override
1272 tree t1 = build_expr (e->e1);
1273 this->result_ = delegate_method (t1);
1276 /* Build a slice expression. */
1278 void visit (SliceExp *e) final override
1280 Type *tb = e->type->toBasetype ();
1281 Type *tb1 = e->e1->type->toBasetype ();
1282 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray);
1284 /* Use convert-to-dynamic-array code if possible. */
1285 if (!e->lwr)
1287 tree result = build_expr (e->e1);
1288 if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
1289 result = convert_expr (result, e->e1->type, e->type);
1291 this->result_ = result;
1292 return;
1294 else
1295 gcc_assert (e->upr != NULL);
1297 /* Get the data pointer and length for static and dynamic arrays. */
1298 tree array = d_save_expr (build_expr (e->e1));
1299 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1300 tree length = NULL_TREE;
1302 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1303 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1304 if (tb1->ty != TY::Tpointer)
1305 length = get_array_length (array, tb1);
1306 else
1307 gcc_assert (e->lengthVar == NULL);
1309 /* The __dollar variable just becomes a placeholder for the
1310 actual length. */
1311 if (e->lengthVar)
1312 e->lengthVar->csym = length;
1314 /* Generate upper and lower bounds. */
1315 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1316 tree upr_tree = d_save_expr (build_expr (e->upr));
1318 /* If the upper bound has any side effects, then the lower bound should be
1319 copied to a temporary always. */
1320 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1321 lwr_tree = save_expr (lwr_tree);
1323 /* Adjust the .ptr offset. */
1324 if (!integer_zerop (lwr_tree))
1326 tree ptrtype = TREE_TYPE (ptr);
1327 ptr = build_pointer_index (void_okay_p (ptr), lwr_tree);
1328 ptr = build_nop (ptrtype, ptr);
1331 /* Nothing more to do for static arrays, their bounds checking has been
1332 done at compile-time. */
1333 if (tb->ty == TY::Tsarray)
1335 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1336 return;
1338 else
1339 gcc_assert (tb->ty == TY::Tarray);
1341 /* Generate bounds checking code. */
1342 tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree,
1343 length);
1344 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1345 this->result_ = compound_expr (array, result);
1348 /* Build a cast expression, which converts the given unary expression to the
1349 type of result. */
1351 void visit (CastExp *e) final override
1353 Type *ebtype = e->e1->type->toBasetype ();
1354 Type *tbtype = e->to->toBasetype ();
1355 tree result = build_expr (e->e1, this->constp_, this->literalp_);
1357 /* Just evaluate e1 if it has any side effects. */
1358 if (tbtype->ty == TY::Tvoid)
1359 this->result_ = build_nop (build_ctype (tbtype), result);
1360 else
1361 this->result_ = convert_for_rvalue (result, ebtype, tbtype);
1364 /* Build a delete expression. */
1366 void visit (DeleteExp *e) final override
1368 tree t1 = build_expr (e->e1);
1369 Type *tb1 = e->e1->type->toBasetype ();
1371 if (tb1->ty == TY::Tclass)
1373 /* For class object references, if there is a destructor for that class,
1374 the destructor is called for the object instance. */
1375 gcc_assert (e->e1->op == EXP::variable);
1377 VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
1378 gcc_assert (v && v->onstack ());
1380 libcall_fn libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1381 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1383 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1384 return;
1386 else
1388 error ("don%'t know how to delete %qs", e->e1->toChars ());
1389 this->result_ = error_mark_node;
1393 /* Build a remove expression, which removes a particular key from an
1394 associative array. */
1396 void visit (RemoveExp *e) final override
1398 /* Check that the array is actually an associative array. */
1399 if (e->e1->type->toBasetype ()->ty == TY::Taarray)
1401 Type *tb = e->e1->type->toBasetype ();
1402 Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
1403 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1405 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1406 build_expr (e->e1),
1407 build_typeinfo (e, tkey),
1408 build_address (index));
1410 else
1412 error ("%qs is not an associative array", e->e1->toChars ());
1413 this->result_ = error_mark_node;
1417 /* Build an unary not expression. */
1419 void visit (NotExp *e) final override
1421 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1422 /* Need to convert to boolean type or this will fail. */
1423 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1425 this->result_ = d_convert (build_ctype (e->type), result);
1428 /* Build a compliment expression, where all the bits in the value are
1429 complemented. Note: unlike in C, the usual integral promotions
1430 are not performed prior to the complement operation. */
1432 void visit (ComExp *e) final override
1434 TY ty1 = e->e1->type->toBasetype ()->ty;
1435 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1437 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1438 build_expr (e->e1));
1441 /* Build an unary negation expression. */
1443 void visit (NegExp *e) final override
1445 TY ty1 = e->e1->type->toBasetype ()->ty;
1446 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1448 tree type = build_ctype (e->type);
1449 tree expr = build_expr (e->e1);
1451 /* If the operation needs excess precision. */
1452 tree eptype = excess_precision_type (type);
1453 if (eptype != NULL_TREE)
1454 expr = d_convert (eptype, expr);
1455 else
1456 eptype = type;
1458 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1459 this->result_ = d_convert (type, ret);
1462 /* Build a pointer index expression. */
1464 void visit (PtrExp *e) final override
1466 Type *tnext = NULL;
1467 size_t offset;
1468 tree result;
1470 if (e->e1->op == EXP::add)
1472 AddExp *ae = e->e1->isAddExp ();
1473 if (ae->e1->op == EXP::address
1474 && ae->e2->isConst () && ae->e2->type->isintegral ())
1476 Expression *ex = ae->e1->isAddrExp ()->e1;
1477 tnext = ex->type->toBasetype ();
1478 result = build_expr (ex);
1479 offset = ae->e2->toUInteger ();
1482 else if (e->e1->op == EXP::symbolOffset)
1484 SymOffExp *se = e->e1->isSymOffExp ();
1485 if (!declaration_reference_p (se->var))
1487 tnext = se->var->type->toBasetype ();
1488 result = get_decl_tree (se->var);
1489 offset = se->offset;
1493 /* Produce better code by converting *(#record + n) to
1494 COMPONENT_REFERENCE. Otherwise, the variable will always be
1495 allocated in memory because its address is taken. */
1496 if (tnext && tnext->ty == TY::Tstruct)
1498 StructDeclaration *sd = tnext->isTypeStruct ()->sym;
1500 for (size_t i = 0; i < sd->fields.length; i++)
1502 VarDeclaration *field = sd->fields[i];
1504 if (field->offset == offset
1505 && same_type_p (field->type, e->type))
1507 /* Catch errors, backend will ICE otherwise. */
1508 if (error_operand_p (result))
1509 this->result_ = result;
1510 else
1512 result = component_ref (result, get_symbol_decl (field));
1513 this->result_ = result;
1515 return;
1517 else if (field->offset > offset)
1518 break;
1522 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1525 /* Build an unary address expression. */
1527 void visit (AddrExp *e) final override
1529 tree type = build_ctype (e->type);
1530 tree exp;
1532 /* The frontend optimizer can convert const symbol into a struct literal.
1533 Taking the address of a struct literal is otherwise illegal. */
1534 if (e->e1->op == EXP::structLiteral)
1536 StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
1537 gcc_assert (sle != NULL);
1539 /* Build the reference symbol, the decl is built first as the
1540 initializer may have recursive references. */
1541 if (!sle->sym)
1543 sle->sym = build_artificial_decl (build_ctype (sle->type),
1544 NULL_TREE, "S");
1545 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1546 d_pushdecl (sle->sym);
1547 rest_of_decl_compilation (sle->sym, 1, 0);
1550 exp = sle->sym;
1552 else
1553 exp = build_expr (e->e1, this->constp_, this->literalp_);
1555 TREE_CONSTANT (exp) = 0;
1556 this->result_ = d_convert (type, build_address (exp));
1559 /* Build a function call expression. */
1561 void visit (CallExp *e) final override
1563 Type *tb = e->e1->type->toBasetype ();
1564 Expression *e1b = e->e1;
1566 tree callee = NULL_TREE;
1567 tree object = NULL_TREE;
1568 tree cleanup = NULL_TREE;
1569 tree returnvalue = NULL_TREE;
1570 TypeFunction *tf = NULL;
1572 /* Calls to delegates can sometimes look like this. */
1573 if (e1b->op == EXP::comma)
1575 e1b = e1b->isCommaExp ()->e2;
1576 gcc_assert (e1b->op == EXP::variable);
1578 Declaration *var = e1b->isVarExp ()->var;
1579 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1582 if (e1b->op == EXP::dotVariable && tb->ty != TY::Tdelegate)
1584 DotVarExp *dve = e1b->isDotVarExp ();
1586 /* Don't modify the static initializer for struct literals. */
1587 if (dve->e1->op == EXP::structLiteral)
1589 StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
1590 sle->useStaticInit = false;
1593 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1594 if (fd != NULL)
1596 /* Get the correct callee from the DotVarExp object. */
1597 tree fndecl = get_symbol_decl (fd);
1598 AggregateDeclaration *ad = fd->isThis ();
1600 /* Static method; ignore the object instance. */
1601 if (!ad)
1602 callee = build_address (fndecl);
1603 else
1605 tree thisexp = build_expr (dve->e1);
1607 /* When constructing temporaries, if the constructor throws,
1608 then the object is destructed even though it is not a fully
1609 constructed object yet. And so this call will need to be
1610 moved inside the TARGET_EXPR_INITIAL slot. */
1611 if (fd->isCtorDeclaration ()
1612 && TREE_CODE (thisexp) == COMPOUND_EXPR
1613 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1614 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1616 cleanup = TREE_OPERAND (thisexp, 0);
1617 thisexp = TREE_OPERAND (thisexp, 1);
1620 if (TREE_CODE (thisexp) == CONSTRUCTOR)
1621 thisexp = force_target_expr (thisexp);
1623 /* Want reference to `this' object. */
1624 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1625 thisexp = build_address (thisexp);
1627 /* Make the callee a virtual call. */
1628 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1630 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1631 tree thistype = build_ctype (ad->handleType ());
1632 thisexp = build_nop (thistype, d_save_expr (thisexp));
1633 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1635 else
1636 fndecl = build_address (fndecl);
1638 /* C++ constructors return void, even though front-end semantic
1639 treats them as implicitly returning `this'. Set returnvalue
1640 to override the result of this expression. */
1641 if (fd->isCtorDeclaration ())
1643 thisexp = d_save_expr (thisexp);
1644 returnvalue = thisexp;
1647 callee = build_method_call (fndecl, thisexp, fd->type);
1652 if (callee == NULL_TREE)
1653 callee = build_expr (e1b);
1655 if (METHOD_CALL_EXPR (callee))
1657 /* This could be a delegate expression (TY == Tdelegate), but not
1658 actually a delegate variable. */
1659 if (e1b->op == EXP::dotVariable)
1661 /* This gets the true function type, getting the function type
1662 from e1->type can sometimes be incorrect, such as when calling
1663 a `ref' return function. */
1664 tf = get_function_type (e1b->isDotVarExp ()->var->type);
1666 else
1667 tf = get_function_type (tb);
1669 extract_from_method_call (callee, callee, object);
1671 else if (tb->ty == TY::Tdelegate)
1673 /* Delegate call, extract .object and .funcptr from var. */
1674 callee = d_save_expr (callee);
1675 tf = get_function_type (tb);
1676 object = delegate_object (callee);
1677 callee = delegate_method (callee);
1679 else if (e1b->op == EXP::variable)
1681 FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
1682 gcc_assert (fd != NULL);
1683 tf = get_function_type (fd->type);
1685 if (fd->isNested ())
1687 /* Maybe re-evaluate symbol storage treating `fd' as public. */
1688 if (call_by_alias_p (d_function_chain->function, fd))
1689 TREE_PUBLIC (callee) = 1;
1691 object = get_frame_for_symbol (fd);
1693 else if (fd->needThis ())
1695 error_at (make_location_t (e1b->loc),
1696 "need %<this%> to access member %qs", fd->toChars ());
1697 /* Continue compiling... */
1698 object = null_pointer_node;
1701 else
1703 /* Normal direct function call. */
1704 tf = get_function_type (tb);
1707 gcc_assert (tf != NULL);
1709 /* Now we have the type, callee and maybe object reference,
1710 build the call expression. */
1711 tree exp = d_build_call (tf, callee, object, e->arguments);
1713 /* Record whether the call expression has no side effects, so we can check
1714 for an unused return value later. */
1715 if (TREE_CODE (exp) == CALL_EXPR && CALL_EXPR_FN (exp) != NULL_TREE
1716 && call_side_effect_free_p (e->f, e->e1->type))
1717 CALL_EXPR_WARN_IF_UNUSED (exp) = 1;
1719 if (returnvalue != NULL_TREE)
1720 exp = compound_expr (exp, returnvalue);
1722 if (tf->isref ())
1723 exp = build_deref (exp);
1725 /* Some library calls are defined to return a generic type.
1726 this->type is the real type we want to return. */
1727 if (e->type->isTypeBasic ())
1728 exp = d_convert (build_ctype (e->type), exp);
1730 /* If this call was found to be a constructor for a temporary with a
1731 cleanup, then move the call inside the TARGET_EXPR. */
1732 if (cleanup != NULL_TREE)
1734 tree init = TARGET_EXPR_INITIAL (cleanup);
1735 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1737 /* Keep the return value outside the TARGET_EXPR. */
1738 if (returnvalue != NULL_TREE)
1739 cleanup = compound_expr (cleanup, TREE_OPERAND (exp, 1));
1741 exp = cleanup;
1744 this->result_ = exp;
1747 /* Build a delegate expression. */
1749 void visit (DelegateExp *e) final override
1751 if (e->func->semanticRun == PASS::semantic3done)
1753 /* Add the function as nested function if it belongs to this module.
1754 ie: it is a member of this module, or it is a template instance. */
1755 Dsymbol *owner = e->func->toParent ();
1756 while (!owner->isTemplateInstance () && owner->toParent ())
1757 owner = owner->toParent ();
1758 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1759 build_decl_tree (e->func);
1762 tree fndecl;
1763 tree object;
1765 if (e->func->isNested () && !e->func->isThis ())
1767 if (e->e1->op == EXP::null_)
1768 object = build_expr (e->e1);
1769 else
1770 object = get_frame_for_symbol (e->func);
1772 fndecl = build_address (get_symbol_decl (e->func));
1774 else
1776 if (!e->func->isThis ())
1778 error ("delegates are only for non-static functions");
1779 this->result_ = error_mark_node;
1780 return;
1783 object = build_expr (e->e1);
1785 /* Want reference to `this' object. */
1786 if (e->e1->type->ty != TY::Tclass && e->e1->type->ty != TY::Tpointer)
1787 object = build_address (object);
1789 /* Object reference could be the outer `this' field of a class or
1790 closure of type `void*'. Cast it to the right type. */
1791 if (e->e1->type->ty == TY::Tclass)
1792 object = d_convert (build_ctype (e->e1->type), object);
1794 fndecl = get_symbol_decl (e->func);
1796 /* Get pointer to function out of the virtual table. */
1797 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1798 && e->e1->op != EXP::super_ && e->e1->op != EXP::dotType)
1800 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1801 object = d_save_expr (object);
1802 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1804 else
1805 fndecl = build_address (fndecl);
1808 this->result_ = build_method_call (fndecl, object, e->type);
1811 /* Build a type component expression. */
1813 void visit (DotTypeExp *e) final override
1815 /* Just a pass through to underlying expression. */
1816 this->result_ = build_expr (e->e1);
1819 /* Build a component reference expression. */
1821 void visit (DotVarExp *e) final override
1823 VarDeclaration *vd = e->var->isVarDeclaration ();
1825 /* This could also be a function, but relying on that being taken
1826 care of by the visitor interface for CallExp. */
1827 if (vd != NULL)
1829 if (!vd->isField ())
1830 this->result_ = get_decl_tree (vd);
1831 else
1833 tree object = build_expr (e->e1);
1834 Type *tb = e->e1->type->toBasetype ();
1836 if (tb->ty != TY::Tstruct)
1837 object = build_deref (object);
1839 /* __complex is represented as a struct in the front-end, but
1840 underlying is really a complex type. */
1841 if (e->e1->type->ty == TY::Tenum
1842 && e->e1->type->isTypeEnum ()->sym->isSpecial ())
1843 object = underlying_complex_expr (build_ctype (tb), object);
1845 this->result_ = component_ref (object, get_symbol_decl (vd));
1848 else
1850 error ("%qs is not a field, but a %qs",
1851 e->var->toChars (), e->var->kind ());
1852 this->result_ = error_mark_node;
1856 /* Build an assert expression, used to declare conditions that must hold at
1857 that a given point in the program. */
1859 void visit (AssertExp *e) final override
1861 Type *tb1 = e->e1->type->toBasetype ();
1862 tree arg = build_expr (e->e1);
1863 tree tmsg = NULL_TREE;
1864 tree assert_pass = void_node;
1865 tree assert_fail;
1867 if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ())
1869 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1870 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1871 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1872 libcall_fn libcall;
1874 if (e->msg)
1876 tmsg = build_expr_dtor (e->msg);
1877 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1879 else
1880 libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP;
1882 /* Build a call to _d_assert(). */
1883 assert_fail = build_assert_call (e->loc, libcall, tmsg);
1885 if (global.params.useInvariants == CHECKENABLEon)
1887 /* If the condition is a D class or struct object with an invariant,
1888 call it if the condition result is true. */
1889 if (tb1->ty == TY::Tclass)
1891 ClassDeclaration *cd = tb1->isClassHandle ();
1892 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
1894 arg = d_save_expr (arg);
1895 assert_pass = build_libcall (LIBCALL_INVARIANT,
1896 Type::tvoid, 1, arg);
1899 else if (tb1->ty == TY::Tpointer
1900 && tb1->nextOf ()->ty == TY::Tstruct)
1902 StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
1903 if (sd->inv != NULL)
1905 Expressions args;
1906 arg = d_save_expr (arg);
1907 assert_pass = d_build_call_expr (sd->inv, arg, &args);
1912 else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
1914 /* Generate: __builtin_trap() */
1915 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
1916 assert_fail = build_call_expr (fn, 0);
1918 else
1920 /* Assert contracts are turned off. */
1921 this->result_ = void_node;
1922 return;
1925 /* Build condition that we are asserting in this contract. */
1926 tree condition = convert_for_condition (arg, e->e1->type);
1928 /* We expect the condition to always be true, as what happens if an assert
1929 contract is false is undefined behavior. */
1930 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
1931 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
1932 tree pred_type = TREE_VALUE (arg_types);
1933 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
1935 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
1936 build_int_cst (expected_type, 1));
1937 condition = d_truthvalue_conversion (condition);
1939 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
1942 /* Build a declaration expression. */
1944 void visit (DeclarationExp *e) final override
1946 /* Compile the declaration. */
1947 push_stmt_list ();
1948 build_decl_tree (e->declaration);
1949 tree result = pop_stmt_list ();
1951 /* Construction of an array for typesafe-variadic function arguments
1952 can cause an empty STMT_LIST here. This can causes problems
1953 during gimplification. */
1954 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
1955 result = build_empty_stmt (input_location);
1957 this->result_ = result;
1960 /* Build a typeid expression. Returns an instance of class TypeInfo
1961 corresponding to. */
1963 void visit (TypeidExp *e) final override
1965 if (Type *tid = isType (e->obj))
1967 tree ti = build_typeinfo (e, tid);
1969 /* If the typeinfo is at an offset. */
1970 if (tid->vtinfo->offset)
1971 ti = build_offset (ti, size_int (tid->vtinfo->offset));
1973 this->result_ = build_nop (build_ctype (e->type), ti);
1975 else if (Expression *tid = isExpression (e->obj))
1977 Type *type = tid->type->toBasetype ();
1978 assert (type->ty == TY::Tclass);
1980 /* Generate **classptr to get the classinfo. */
1981 tree ci = build_expr (tid);
1982 ci = indirect_ref (ptr_type_node, ci);
1983 ci = indirect_ref (ptr_type_node, ci);
1985 /* Add extra indirection for interfaces. */
1986 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
1987 ci = indirect_ref (ptr_type_node, ci);
1989 this->result_ = build_nop (build_ctype (e->type), ci);
1991 else
1992 gcc_unreachable ();
1995 /* Build a function/lambda expression. */
1997 void visit (FuncExp *e) final override
1999 Type *ftype = e->type->toBasetype ();
2001 /* This check is for lambda's, remove `vthis' as function isn't nested. */
2002 if (e->fd->tok == TOK::reserved && ftype->ty == TY::Tpointer)
2004 e->fd->tok = TOK::function_;
2005 e->fd->vthis = NULL;
2008 /* Compile the function literal body. */
2009 build_decl_tree (e->fd);
2011 /* If nested, this will be a trampoline. */
2012 if (e->fd->isNested ())
2014 tree func = build_address (get_symbol_decl (e->fd));
2015 tree object;
2017 if (this->constp_)
2019 /* Static delegate variables have no context pointer. */
2020 object = null_pointer_node;
2021 this->result_ = build_method_call (func, object, e->fd->type);
2022 TREE_CONSTANT (this->result_) = 1;
2024 else
2026 object = get_frame_for_symbol (e->fd);
2027 this->result_ = build_method_call (func, object, e->fd->type);
2030 else
2032 this->result_ = build_nop (build_ctype (e->type),
2033 build_address (get_symbol_decl (e->fd)));
2037 /* Build a halt expression. */
2039 void visit (HaltExp *) final override
2041 /* Should we use trap() or abort()? */
2042 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2043 this->result_ = build_call_expr (ttrap, 0);
2046 /* Build a symbol pointer offset expression. */
2048 void visit (SymOffExp *e) final override
2050 /* Build the address and offset of the symbol. */
2051 size_t soffset = e->isSymOffExp ()->offset;
2052 tree result = get_decl_tree (e->var);
2053 TREE_USED (result) = 1;
2055 if (e->var->isFuncDeclaration ())
2056 result = maybe_reject_intrinsic (result);
2058 if (declaration_reference_p (e->var))
2059 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2060 else
2061 result = build_address (result);
2063 if (!soffset)
2064 result = d_convert (build_ctype (e->type), result);
2065 else
2067 tree offset = size_int (soffset);
2068 result = build_nop (build_ctype (e->type),
2069 build_offset (result, offset));
2072 this->result_ = result;
2075 /* Build a variable expression. */
2077 void visit (VarExp *e) final override
2079 if (e->var->needThis ())
2081 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2082 this->result_ = error_mark_node;
2083 return;
2085 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2087 /* __ctfe is always false at run-time. */
2088 this->result_ = integer_zero_node;
2089 return;
2092 /* This check is same as is done in FuncExp for lambdas. */
2093 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2094 if (fld != NULL)
2096 if (fld->tok == TOK::reserved)
2098 fld->tok = TOK::function_;
2099 fld->vthis = NULL;
2102 /* Compiler the function literal body. */
2103 build_decl_tree (fld);
2106 if (this->constp_)
2108 /* Want the initializer, not the expression. */
2109 VarDeclaration *var = e->var->isVarDeclaration ();
2110 SymbolDeclaration *sdecl = e->var->isSymbolDeclaration ();
2111 tree init = NULL_TREE;
2113 if (var && (var->isConst () || var->isImmutable ())
2114 && e->type->toBasetype ()->ty != TY::Tsarray && var->_init)
2116 if (var->inuse)
2117 error_at (make_location_t (e->loc), "recursive reference %qs",
2118 e->toChars ());
2119 else
2121 var->inuse++;
2122 init = build_expr (initializerToExpression (var->_init), true);
2123 var->inuse--;
2126 else if (sdecl && sdecl->dsym)
2128 if (StructDeclaration *sd = sdecl->dsym->isStructDeclaration ())
2129 init = layout_struct_initializer (sd);
2130 else if (ClassDeclaration *cd = sdecl->dsym->isClassDeclaration ())
2131 init = layout_class_initializer (cd);
2132 else
2133 gcc_unreachable ();
2135 else
2136 error_at (make_location_t (e->loc), "non-constant expression %qs",
2137 e->toChars ());
2139 if (init != NULL_TREE)
2140 this->result_ = init;
2141 else
2142 this->result_ = error_mark_node;
2144 else
2146 tree result = get_decl_tree (e->var);
2147 TREE_USED (result) = 1;
2149 /* The variable expression generated for `__traits(initSymbol)'. */
2150 if (SymbolDeclaration *sd = e->var->isSymbolDeclaration ())
2152 if (e->type->isTypeDArray ())
2154 /* Generate a slice for non-zero initialized aggregates,
2155 otherwise create an empty array. */
2156 gcc_assert (e->type == Type::tvoid->arrayOf ()->constOf ());
2158 tree type = build_ctype (e->type);
2159 tree length = size_int (sd->dsym->structsize);
2160 tree ptr = (sd->dsym->isStructDeclaration ()
2161 && sd->dsym->type->isZeroInit (e->loc))
2162 ? null_pointer_node : build_address (result);
2164 this->result_ = d_array_value (type, length, ptr);
2165 return;
2169 /* For variables that are references - currently only out/inout
2170 arguments; objects don't count - evaluating the variable means
2171 we want what it refers to. */
2172 if (declaration_reference_p (e->var))
2173 result = indirect_ref (build_ctype (e->var->type), result);
2175 this->result_ = result;
2179 /* Build a this variable expression. */
2181 void visit (ThisExp *e) final override
2183 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2184 tree result = NULL_TREE;
2186 if (e->var)
2187 result = get_decl_tree (e->var);
2188 else
2190 gcc_assert (fd && fd->vthis);
2191 result = get_decl_tree (fd->vthis);
2194 if (e->type->ty == TY::Tstruct)
2195 result = build_deref (result);
2197 this->result_ = result;
2200 /* Build a new expression, which allocates memory either on the garbage
2201 collected heap or by using a class or struct specific allocator. */
2203 void visit (NewExp *e) final override
2205 Type *tb = e->type->toBasetype ();
2206 tree result;
2208 if (tb->ty == TY::Tclass)
2210 /* Allocating a new class. */
2211 tb = e->newtype->toBasetype ();
2213 ClassDeclaration *cd = tb->isTypeClass ()->sym;
2214 tree type = build_ctype (tb);
2215 tree setup_exp = NULL_TREE;
2216 tree new_call;
2218 if (e->onstack)
2220 /* If being used as an initializer for a local variable with scope
2221 storage class, then the instance is allocated on the stack
2222 rather than the heap or using the class specific allocator. */
2223 tree var = build_local_temp (TREE_TYPE (type));
2224 new_call = build_nop (type, build_address (var));
2225 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2227 else if (global.params.ehnogc && e->thrownew)
2229 /* Allocating a `@nogc' Exception with `_d_newThrowable' has already
2230 been handled by the front-end. */
2231 gcc_unreachable ();
2233 else
2235 /* Generate: _d_newclass() */
2236 new_call = build_expr (e->lowering);
2239 /* Set the context pointer for nested classes. */
2240 if (cd->isNested ())
2242 tree field = get_symbol_decl (cd->vthis);
2243 tree value = NULL_TREE;
2245 if (e->thisexp)
2247 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2248 /* The class or function we're nested in. */
2249 Dsymbol *outer = cd->toParentLocal ();
2251 value = build_expr (e->thisexp);
2253 if (outer != tcd)
2255 ClassDeclaration *ocd = outer->isClassDeclaration ();
2256 int offset = 0;
2257 gcc_assert (ocd->isBaseOf (tcd, &offset));
2258 /* Could just add offset... */
2259 value = convert_expr (value, e->thisexp->type, ocd->type);
2262 else
2263 value = build_vthis (cd);
2265 if (value != NULL_TREE)
2267 /* Generate: (new())->vthis = this; */
2268 new_call = d_save_expr (new_call);
2269 field = component_ref (build_deref (new_call), field);
2270 setup_exp = compound_expr (setup_exp,
2271 modify_expr (field, value));
2274 new_call = compound_expr (setup_exp, new_call);
2276 /* Call the class constructor. */
2277 if (e->member)
2278 result = d_build_call_expr (e->member, new_call, e->arguments);
2279 else
2280 result = new_call;
2282 if (e->argprefix)
2283 result = compound_expr (build_expr (e->argprefix), result);
2285 else if (tb->ty == TY::Tpointer
2286 && tb->nextOf ()->toBasetype ()->ty == TY::Tstruct)
2288 /* Allocating memory for a new struct. */
2289 Type *htype = e->newtype->toBasetype ();
2290 gcc_assert (!e->onstack);
2292 TypeStruct *stype = htype->isTypeStruct ();
2293 StructDeclaration *sd = stype->sym;
2294 tree new_call;
2296 /* Cannot new an opaque struct. */
2297 if (sd->size (e->loc) == 0)
2299 this->result_ = d_convert (build_ctype (e->type),
2300 integer_zero_node);
2301 return;
2304 /* This case should have been rewritten to `_d_newitemT' during the
2305 semantic phase. */
2306 gcc_assert (e->lowering);
2308 /* Generate: _d_newitemT() */
2309 new_call = build_expr (e->lowering);
2311 if (e->member || !e->arguments)
2313 /* Set the context pointer for nested structs. */
2314 if (sd->isNested ())
2316 tree value = build_vthis (sd);
2317 tree field = get_symbol_decl (sd->vthis);
2318 tree type = build_ctype (stype);
2320 new_call = d_save_expr (new_call);
2321 field = component_ref (indirect_ref (type, new_call), field);
2322 new_call = compound_expr (modify_expr (field, value), new_call);
2325 /* Call the struct constructor. */
2326 if (e->member)
2327 result = d_build_call_expr (e->member, new_call, e->arguments);
2328 else
2329 result = new_call;
2331 else
2333 /* If we have a user supplied initializer, then set-up with a
2334 struct literal. */
2335 if (e->arguments != NULL && sd->fields.length != 0)
2337 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2338 e->arguments,
2339 htype);
2340 new_call = d_save_expr (new_call);
2341 se->type = sd->type;
2342 se->sym = new_call;
2344 /* Setting `se->sym' would mean that the result of the
2345 constructed struct literal expression is `*(new_call)'.
2346 Strip off the indirect reference, as we don't mean to
2347 compute the value yet. */
2348 result = build_address (build_expr (se));
2350 else
2351 result = new_call;
2354 if (e->argprefix)
2355 result = compound_expr (build_expr (e->argprefix), result);
2357 else if (tb->ty == TY::Tarray)
2359 /* Allocating memory for a new D array. */
2360 gcc_assert (e->arguments && e->arguments->length >= 1);
2362 if (e->arguments->length == 1)
2364 /* Single dimension array allocations has already been handled by
2365 the front-end. */
2366 gcc_assert (e->lowering);
2367 result = build_expr (e->lowering);
2369 else
2371 /* Multidimensional array allocations. */
2372 tree tarray = make_array_type (Type::tsize_t, e->arguments->length);
2373 tree var = build_local_temp (tarray);
2374 vec <constructor_elt, va_gc> *elms = NULL;
2376 /* Get the base element type for the array, generating the
2377 initializer for the dims parameter along the way. */
2378 Type *telem = e->newtype->toBasetype ();
2379 for (size_t i = 0; i < e->arguments->length; i++)
2381 Expression *arg = (*e->arguments)[i];
2382 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2384 gcc_assert (telem->ty == TY::Tarray);
2385 telem = telem->toBasetype ()->nextOf ();
2386 gcc_assert (telem);
2389 /* Initialize the temporary. */
2390 tree init = modify_expr (var, build_constructor (tarray, elms));
2391 var = compound_expr (init, var);
2393 /* Generate: _d_newarraymTX(ti, dims)
2394 or: _d_newarraymiTX(ti, dims) */
2395 libcall_fn libcall = telem->isZeroInit ()
2396 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2398 tree tinfo = build_typeinfo (e, e->type);
2399 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2400 size_int (e->arguments->length),
2401 build_address (var));
2403 result = build_libcall (libcall, e->newtype->toBasetype (), 2,
2404 tinfo, dims);
2407 if (e->argprefix)
2408 result = compound_expr (build_expr (e->argprefix), result);
2410 else if (tb->ty == TY::Tpointer)
2412 /* Allocating memory for a new pointer. */
2413 TypePointer *tpointer = tb->isTypePointer ();
2415 if (tpointer->next->size () == 0)
2417 /* Pointer element size is unknown. */
2418 this->result_ = d_convert (build_ctype (e->type),
2419 integer_zero_node);
2420 return;
2423 /* This case should have been rewritten to `_d_newitemT' during the
2424 semantic phase. */
2425 gcc_assert (e->lowering);
2427 /* Generate: _d_newitemT() */
2428 result = build_expr (e->lowering);
2430 if (e->arguments && e->arguments->length == 1)
2432 result = d_save_expr (result);
2433 tree init = modify_expr (build_deref (result),
2434 build_expr ((*e->arguments)[0]));
2435 result = compound_expr (init, result);
2438 if (e->argprefix)
2439 result = compound_expr (build_expr (e->argprefix), result);
2441 else if (tb->ty == TY::Taarray)
2443 /* Allocating memory for a new associative array. */
2444 tree arg = build_typeinfo (e, e->newtype);
2445 tree mem = build_libcall (LIBCALL_AANEW, Type::tvoidptr, 1, arg);
2447 /* Return an associative array pointed to by MEM. */
2448 tree aatype = build_ctype (tb);
2449 vec <constructor_elt, va_gc> *ce = NULL;
2450 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2452 result = build_nop (build_ctype (e->type),
2453 build_constructor (aatype, ce));
2455 else
2456 gcc_unreachable ();
2458 this->result_ = convert_expr (result, tb, e->type);
2461 /* Build an integer literal. */
2463 void visit (IntegerExp *e) final override
2465 tree ctype = build_ctype (e->type->toBasetype ());
2466 this->result_ = build_integer_cst (e->value, ctype);
2469 /* Build a floating-point literal. */
2471 void visit (RealExp *e) final override
2473 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2476 /* Build a complex literal. */
2478 void visit (ComplexExp *e) final override
2480 Type *tnext;
2482 switch (e->type->toBasetype ()->ty)
2484 case TY::Tcomplex32:
2485 tnext = (TypeBasic *) Type::tfloat32;
2486 break;
2488 case TY::Tcomplex64:
2489 tnext = (TypeBasic *) Type::tfloat64;
2490 break;
2492 case TY::Tcomplex80:
2493 tnext = (TypeBasic *) Type::tfloat80;
2494 break;
2496 default:
2497 gcc_unreachable ();
2500 this->result_ = build_complex (build_ctype (e->type),
2501 build_float_cst (creall (e->value), tnext),
2502 build_float_cst (cimagl (e->value), tnext));
2505 /* Build a string literal, all strings are null terminated except for
2506 static arrays. */
2508 void visit (StringExp *e) final override
2510 Type *tb = e->type->toBasetype ();
2511 tree type = build_ctype (e->type);
2513 if (tb->ty == TY::Tsarray)
2515 /* Turn the string into a constructor for the static array. */
2516 vec <constructor_elt, va_gc> *elms = NULL;
2517 vec_safe_reserve (elms, e->len);
2518 tree etype = TREE_TYPE (type);
2520 for (size_t i = 0; i < e->len; i++)
2522 tree value = build_integer_cst (e->getCodeUnit (i), etype);
2523 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2526 tree ctor = build_constructor (type, elms);
2527 TREE_CONSTANT (ctor) = 1;
2528 this->result_ = ctor;
2530 else
2532 /* Copy the string contents to a null terminated string. */
2533 dinteger_t length = (e->len * e->sz);
2534 char *string = XALLOCAVEC (char, length + e->sz);
2535 memset (string, 0, length + e->sz);
2536 if (length > 0)
2537 memcpy (string, e->string, length);
2539 /* String value and type includes the null terminator. */
2540 tree value = build_string (length + e->sz, string);
2541 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2542 value = build_address (value);
2544 if (tb->ty == TY::Tarray)
2545 value = d_array_value (type, size_int (e->len), value);
2547 TREE_CONSTANT (value) = 1;
2548 this->result_ = d_convert (type, value);
2552 /* Build a tuple literal. Just an argument list that may have
2553 side effects that need evaluation. */
2555 void visit (TupleExp *e) final override
2557 tree result = NULL_TREE;
2559 if (e->e0)
2560 result = build_expr (e->e0, this->constp_, true);
2562 for (size_t i = 0; i < e->exps->length; ++i)
2564 Expression *exp = (*e->exps)[i];
2565 result = compound_expr (result, build_expr (exp, this->constp_, true));
2568 if (result == NULL_TREE)
2569 result = void_node;
2571 this->result_ = result;
2574 /* Build an array literal. The common type of the all elements is taken to
2575 be the type of the array element, and all elements are implicitly
2576 converted to that type. */
2578 void visit (ArrayLiteralExp *e) final override
2580 Type *tb = e->type->toBasetype ();
2582 /* Implicitly convert void[n] to ubyte[n]. */
2583 if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid)
2584 tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());
2586 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray
2587 || tb->ty == TY::Tpointer);
2589 /* Handle empty array literals. */
2590 if (e->elements->length == 0)
2592 if (tb->ty == TY::Tarray)
2593 this->result_ = d_array_value (build_ctype (e->type),
2594 size_int (0), null_pointer_node);
2595 else
2596 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2597 NULL);
2599 return;
2602 /* Build an expression that assigns the expressions in ELEMENTS to
2603 a constructor. */
2604 vec <constructor_elt, va_gc> *elms = NULL;
2605 vec_safe_reserve (elms, e->elements->length);
2606 bool constant_p = true;
2607 tree saved_elems = NULL_TREE;
2609 Type *etype = tb->nextOf ();
2610 tree satype = make_array_type (etype, e->elements->length);
2612 for (size_t i = 0; i < e->elements->length; i++)
2614 Expression *expr = e->getElement (i);
2615 tree value = build_expr (expr, this->constp_, true);
2617 /* Only append nonzero values, the backend will zero out the rest
2618 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2619 if (!initializer_zerop (value))
2621 if (!TREE_CONSTANT (value))
2622 constant_p = false;
2624 /* Split construction of values out of the constructor if there
2625 may be side effects. */
2626 tree init = stabilize_expr (&value);
2627 if (init != NULL_TREE)
2628 saved_elems = compound_expr (saved_elems, init);
2630 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2631 convert_expr (value, expr->type, etype));
2635 /* Now return the constructor as the correct type. For static arrays there
2636 is nothing else to do. For dynamic arrays, return a two field struct.
2637 For pointers, return the address. */
2638 tree ctor = build_constructor (satype, elms);
2639 tree type = build_ctype (e->type);
2641 /* Nothing else to do for static arrays. */
2642 if (tb->ty == TY::Tsarray || this->constp_)
2644 /* Can't take the address of the constructor, so create an anonymous
2645 static symbol, and then refer to it. */
2646 if (tb->ty != TY::Tsarray)
2648 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2649 ctor = build_address (decl);
2650 if (tb->ty == TY::Tarray)
2651 ctor = d_array_value (type, size_int (e->elements->length), ctor);
2653 /* Immutable literals can be placed in rodata. */
2654 if (tb->isImmutable ())
2655 TREE_READONLY (decl) = 1;
2657 d_pushdecl (decl);
2658 rest_of_decl_compilation (decl, 1, 0);
2661 /* If the array literal is readonly or static. */
2662 if (constant_p)
2663 TREE_CONSTANT (ctor) = 1;
2664 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2665 TREE_STATIC (ctor) = 1;
2667 /* Use memset to fill any alignment holes in the array. */
2668 if (!this->constp_ && !this->literalp_)
2670 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
2672 if (ts != NULL && (!identity_compare_p (ts->sym)
2673 || ts->sym->isUnionDeclaration ()))
2675 tree var = build_local_temp (TREE_TYPE (ctor));
2676 tree init = build_memset_call (var);
2677 /* Evaluate memset() first, then any saved elements. */
2678 saved_elems = compound_expr (init, saved_elems);
2679 ctor = compound_expr (modify_expr (var, ctor), var);
2683 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2685 else if (e->onstack)
2687 /* Array literal for a `scope' dynamic array. */
2688 gcc_assert (tb->ty == TY::Tarray);
2689 ctor = force_target_expr (ctor);
2690 this->result_ = d_array_value (type, size_int (e->elements->length),
2691 build_address (ctor));
2693 else
2695 /* Allocate space on the memory managed heap. */
2696 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2697 etype->pointerTo (), 2,
2698 build_typeinfo (e, etype->arrayOf ()),
2699 size_int (e->elements->length));
2700 mem = d_save_expr (mem);
2702 /* Now copy the constructor into memory. */
2703 tree size = size_mult_expr (size_int (e->elements->length),
2704 size_int (tb->nextOf ()->size ()));
2706 tree result = build_memcpy_call (mem, build_address (ctor), size);
2708 /* Return the array pointed to by MEM. */
2709 result = compound_expr (result, mem);
2711 if (tb->ty == TY::Tarray)
2712 result = d_array_value (type, size_int (e->elements->length), result);
2714 this->result_ = compound_expr (saved_elems, result);
2718 /* Build an associative array literal. The common type of the all keys is
2719 taken to be the key type, and common type of all values the value type.
2720 All keys and values are then implicitly converted as needed. */
2722 void visit (AssocArrayLiteralExp *e) final override
2724 if (e->lowering != NULL)
2726 /* When an associative array literal gets lowered, it's converted into a
2727 struct literal suitable for static initialization. */
2728 gcc_assert (this->constp_);
2729 this->result_ = build_expr (e->lowering, this->constp_, true);
2730 return ;
2733 /* Want the mutable type for typeinfo reference. */
2734 Type *tb = e->type->toBasetype ()->mutableOf ();
2736 /* Handle empty assoc array literals. */
2737 TypeAArray *ta = tb->isTypeAArray ();
2738 if (e->keys->length == 0)
2740 this->result_ = build_constructor (build_ctype (ta), NULL);
2741 return;
2744 /* Build an expression that assigns all expressions in KEYS
2745 to a constructor. */
2746 tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
2747 e->keys, this->constp_);
2748 tree init = stabilize_expr (&akeys);
2750 /* Do the same with all expressions in VALUES. */
2751 tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
2752 e->values, this->constp_);
2753 init = compound_expr (init, stabilize_expr (&avals));
2755 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2756 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2757 size_int (e->keys->length),
2758 build_address (akeys));
2759 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2760 size_int (e->values->length),
2761 build_address (avals));
2763 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2764 build_typeinfo (e, ta), keys, vals);
2766 /* Return an associative array pointed to by MEM. */
2767 tree aatype = build_ctype (ta);
2768 vec <constructor_elt, va_gc> *ce = NULL;
2769 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2771 tree result = build_nop (build_ctype (e->type),
2772 build_constructor (aatype, ce));
2773 this->result_ = compound_expr (init, result);
2776 /* Build a struct literal. */
2778 void visit (StructLiteralExp *e) final override
2780 /* Handle empty struct literals. */
2781 if (e->elements == NULL || e->sd->fields.length == 0)
2783 this->result_ = build_constructor (build_ctype (e->type), NULL);
2784 return;
2787 /* Building sinit trees are delayed until after frontend semantic
2788 processing has complete. Build the static initializer now. */
2789 if (e->useStaticInit && !this->constp_ && !e->sd->isCsymbol ())
2791 tree init = aggregate_initializer_decl (e->sd);
2793 /* If initializing a symbol, don't forget to set it. */
2794 if (e->sym != NULL)
2796 tree var = build_deref (e->sym);
2797 init = compound_expr (modify_expr (var, init), var);
2800 this->result_ = init;
2801 return;
2804 /* Build a constructor that assigns the expressions in ELEMENTS
2805 at each field index that has been filled in. */
2806 vec <constructor_elt, va_gc> *ve = NULL;
2807 tree saved_elems = NULL_TREE;
2809 /* CTFE may fill the hidden pointer by NullExp. */
2810 gcc_assert (e->elements->length <= e->sd->fields.length);
2812 Type *tb = e->type->toBasetype ();
2813 gcc_assert (tb->ty == TY::Tstruct);
2815 for (size_t i = 0; i < e->elements->length; i++)
2817 Expression *exp = (*e->elements)[i];
2818 if (!exp)
2819 continue;
2821 VarDeclaration *field = e->sd->fields[i];
2822 Type *type = exp->type->toBasetype ();
2823 Type *ftype = field->type->toBasetype ();
2824 tree value = NULL_TREE;
2826 if (ftype->ty == TY::Tsarray && !same_type_p (type, ftype))
2828 /* Initialize a static array with a single element. */
2829 tree elem = build_expr (exp, this->constp_, true);
2830 saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
2831 elem = d_save_expr (elem);
2833 if (initializer_zerop (elem))
2834 value = build_constructor (build_ctype (ftype), NULL);
2835 else
2836 value = build_array_from_val (ftype, elem);
2838 else
2840 value = convert_expr (build_expr (exp, this->constp_, true),
2841 exp->type, field->type);
2844 /* Split construction of values out of the constructor. */
2845 saved_elems = compound_expr (saved_elems, stabilize_expr (&value));
2847 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2850 /* Maybe setup hidden pointer to outer scope context. */
2851 if (e->sd->isNested () && e->elements->length != e->sd->fields.length
2852 && this->constp_ == false)
2854 tree field = get_symbol_decl (e->sd->vthis);
2855 tree value = build_vthis (e->sd);
2856 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2857 gcc_assert (e->useStaticInit == false);
2860 /* Build a constructor in the correct shape of the aggregate type. */
2861 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2863 /* Nothing more to do for constant literals. */
2864 if (this->constp_)
2866 /* If the struct literal is a valid for static data. */
2867 if (TREE_CONSTANT (ctor)
2868 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2869 TREE_STATIC (ctor) = 1;
2871 this->result_ = compound_expr (saved_elems, ctor);
2872 return;
2875 /* Construct the struct literal for run-time. */
2876 if (e->sym != NULL)
2878 /* Store the result in a symbol to initialize the literal. */
2879 tree var = build_deref (e->sym);
2880 ctor = compound_expr (modify_expr (var, ctor), var);
2882 else if (!this->literalp_)
2884 /* Use memset to fill any alignment holes in the object. */
2885 if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
2887 tree var = build_local_temp (TREE_TYPE (ctor));
2888 tree init = build_memset_call (var);
2889 /* Evaluate memset() first, then any saved element constructors. */
2890 saved_elems = compound_expr (init, saved_elems);
2891 ctor = compound_expr (modify_expr (var, ctor), var);
2895 this->result_ = compound_expr (saved_elems, ctor);
2898 /* Build a null literal. */
2900 void visit (NullExp *e) final override
2902 this->result_ = build_typeof_null_value (e->type);
2905 /* Build a vector literal. */
2907 void visit (VectorExp *e) final override
2909 /* First handle array literal expressions. */
2910 if (e->e1->op == EXP::arrayLiteral)
2912 ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
2913 vec <constructor_elt, va_gc> *elms = NULL;
2914 bool constant_p = true;
2915 tree type = build_ctype (e->type);
2917 vec_safe_reserve (elms, ale->elements->length);
2918 for (size_t i = 0; i < ale->elements->length; i++)
2920 Expression *expr = ale->getElement (i);
2921 tree value = d_convert (TREE_TYPE (type),
2922 build_expr (expr, this->constp_, true));
2923 if (!CONSTANT_CLASS_P (value))
2924 constant_p = false;
2926 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2929 /* Build a VECTOR_CST from a constant vector constructor. */
2930 if (constant_p)
2931 this->result_ = build_vector_from_ctor (type, elms);
2932 else
2933 this->result_ = build_constructor (type, elms);
2935 else if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
2937 /* Build a vector representation from a static array. */
2938 this->result_ = convert_expr (build_expr (e->e1, this->constp_),
2939 e->e1->type, e->type);
2941 else
2943 /* Build constructor from single value. */
2944 tree type = build_ctype (e->type);
2945 tree value = d_convert (TREE_TYPE (type),
2946 build_expr (e->e1, this->constp_, true));
2947 this->result_ = build_vector_from_val (type, value);
2951 /* Build a static array representation of a vector expression. */
2953 void visit (VectorArrayExp *e) final override
2955 this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
2956 e->e1->type, e->type);
2959 /* Build a static class literal, return its reference. */
2961 void visit (ClassReferenceExp *e) final override
2963 /* The result of build_new_class_expr is a RECORD_TYPE, we want
2964 the reference. */
2965 tree var = build_address (build_new_class_expr (e));
2967 /* If the type of this literal is an interface, the we must add the
2968 interface offset to symbol. */
2969 if (this->constp_)
2971 TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
2972 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
2974 if (to != NULL)
2976 ClassDeclaration *from = e->originalClass ();
2977 int offset = 0;
2979 gcc_assert (to->isBaseOf (from, &offset) != 0);
2981 if (offset != 0)
2982 var = build_offset (var, size_int (offset));
2986 this->result_ = var;
2989 /* Build an uninitialized value, generated from void initializers. */
2991 void visit (VoidInitExp *e) final override
2993 /* The front-end only generates these for the initializer of globals.
2994 Represent `void' as zeroes, regardless of the type's default value. */
2995 gcc_assert (this->constp_);
2996 this->result_ = build_zero_cst (build_ctype (e->type));
2999 /* These expressions are mainly just a placeholders in the frontend.
3000 We shouldn't see them here. */
3002 void visit (ScopeExp *e) final override
3004 error_at (make_location_t (e->loc), "%qs is not an expression",
3005 e->toChars ());
3006 this->result_ = error_mark_node;
3009 void visit (TypeExp *e) final override
3011 error_at (make_location_t (e->loc), "type %qs is not an expression",
3012 e->toChars ());
3013 this->result_ = error_mark_node;
3018 /* Main entry point for ExprVisitor interface to generate code for
3019 the Expression AST class E. If CONST_P is true, then E is a
3020 constant expression. If LITERAL_P is true, then E is a value used
3021 in the initialization of another literal. */
3023 tree
3024 build_expr (Expression *e, bool const_p, bool literal_p)
3026 ExprVisitor v = ExprVisitor (const_p, literal_p);
3027 location_t saved_location = input_location;
3029 input_location = make_location_t (e->loc);
3030 e->accept (&v);
3031 tree expr = v.result ();
3032 input_location = saved_location;
3034 /* Check if initializer expression is valid constant. */
3035 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3037 error_at (make_location_t (e->loc), "non-constant expression %qs",
3038 e->toChars ());
3039 return error_mark_node;
3042 return expr;
3045 /* Same as build_expr, but also calls destructors on any temporaries. */
3047 tree
3048 build_expr_dtor (Expression *e)
3050 /* Codegen can be improved by determining if no exceptions can be thrown
3051 between the ctor and dtor, and eliminating the ctor and dtor. */
3052 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3053 tree result = build_expr (e);
3055 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3057 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3058 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3061 return result;
3064 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3066 tree
3067 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3069 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3070 tree result = build_expr (e);
3072 /* Convert for initializing the DECL_RESULT. */
3073 if (tf->isref ())
3075 /* If we are returning a reference, take the address. */
3076 result = convert_expr (result, e->type, type);
3077 result = build_address (result);
3079 else
3080 result = convert_for_rvalue (result, e->type, type);
3082 /* The decl to store the return expression. */
3083 tree decl = DECL_RESULT (cfun->decl);
3085 /* Split comma expressions, so that the result is returned directly. */
3086 tree expr = stabilize_expr (&result);
3087 result = build_assign (INIT_EXPR, decl, result);
3088 result = compound_expr (expr, return_expr (result));
3090 /* May nest the return expression inside the try/finally expression. */
3091 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3093 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3094 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3097 return result;