d: Merge dmd. druntime e770945277, phobos 6d6e0b9b9
[official-gcc.git] / gcc / d / expr.cc
blob0a85a55b397bf42af09d18453034a68b62032204
1 /* expr.cc -- Lower D frontend expressions to GCC trees.
2 Copyright (C) 2015-2024 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 /* Compile the function literal body. */
209 static void
210 build_lambda_tree (FuncLiteralDeclaration *fld, Type *type = NULL)
212 /* This check is for lambda's, remove `vthis' as function isn't nested. */
213 if (fld->tok == TOK::reserved && (type == NULL || type->ty == TY::Tpointer))
215 fld->tok = TOK::function_;
216 fld->vthis = NULL;
219 /* Compile the function literal body. */
220 build_decl_tree (fld);
223 /* Implements the visitor interface to build the GCC trees of all Expression
224 AST classes emitted from the D Front-end.
225 All visit methods accept one parameter E, which holds the frontend AST
226 of the expression to compile. They also don't return any value, instead
227 generated code is cached in RESULT_ and returned from the caller. */
229 class ExprVisitor : public Visitor
231 using Visitor::visit;
233 tree result_;
234 bool constp_;
235 bool literalp_;
237 public:
238 ExprVisitor (bool constp, bool literalp)
240 this->result_ = NULL_TREE;
241 this->constp_ = constp;
242 this->literalp_ = literalp;
245 tree result (void)
247 return this->result_;
250 /* Visitor interfaces, each Expression class should have
251 overridden the default. */
253 void visit (Expression *) final override
255 gcc_unreachable ();
258 /* Build a conditional expression. If either the second or third
259 expression is void, then the resulting type is void. Otherwise
260 they are implicitly converted to a common type. */
262 void visit (CondExp *e) final override
264 tree cond = convert_for_condition (build_expr (e->econd),
265 e->econd->type);
266 tree t1 = build_expr (e->e1);
267 tree t2 = build_expr (e->e2);
269 if (e->type->ty != TY::Tvoid)
271 t1 = convert_expr (t1, e->e1->type, e->type);
272 t2 = convert_expr (t2, e->e2->type, e->type);
275 this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
278 /* Build an identity comparison expression. Operands go through the
279 usual conversions to bring them to a common type before comparison.
280 The result type is bool. */
282 void visit (IdentityExp *e) final override
284 tree_code code = (e->op == EXP::identity) ? EQ_EXPR : NE_EXPR;
285 Type *tb1 = e->e1->type->toBasetype ();
286 Type *tb2 = e->e2->type->toBasetype ();
288 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
289 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
291 /* For static and dynamic arrays, identity is defined as referring to
292 the same array elements and the same number of elements. */
293 tree t1 = d_array_convert (e->e1);
294 tree t2 = d_array_convert (e->e2);
295 this->result_ = d_convert (build_ctype (e->type),
296 build_boolop (code, t1, t2));
298 else if (tb1->isfloating () && tb1->ty != TY::Tvector)
300 /* For floating-point values, identity is defined as the bits in the
301 operands being identical. */
302 tree t1 = d_save_expr (build_expr (e->e1));
303 tree t2 = d_save_expr (build_expr (e->e2));
305 if (!tb1->iscomplex ())
306 this->result_ = build_float_identity (code, t1, t2);
307 else
309 /* Compare the real and imaginary parts separately. */
310 tree req = build_float_identity (code, real_part (t1),
311 real_part (t2));
312 tree ieq = build_float_identity (code, imaginary_part (t1),
313 imaginary_part (t2));
315 if (code == EQ_EXPR)
316 this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
317 else
318 this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
321 else if (TypeStruct *ts = tb1->isTypeStruct ())
323 /* For struct objects, identity is defined as bits in operands being
324 identical also. Alignment holes in structs are ignored. */
325 tree t1 = build_expr (e->e1);
326 tree t2 = build_expr (e->e2);
328 gcc_assert (same_type_p (tb1, tb2));
330 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
332 else if (tb1->ty == TY::Tvector && tb2->ty == TY::Tvector)
334 /* For vectors, identity is defined as all values being equal. */
335 tree t1 = build_expr (e->e1);
336 tree t2 = build_expr (e->e2);
337 tree mask = build_boolop (code, t1, t2);
339 /* To reinterpret the vector comparison as a boolean expression, bitcast
340 the bitmask result and generate an additional integer comparison. */
341 opt_scalar_int_mode mode =
342 int_mode_for_mode (TYPE_MODE (TREE_TYPE (mask)));
343 gcc_assert (mode.exists ());
345 tree type = lang_hooks.types.type_for_mode (mode.require (), 1);
346 if (type == NULL_TREE)
347 type = make_unsigned_type (GET_MODE_BITSIZE (mode.require ()));
349 /* In `t1 is t2', all mask bits must be set for vectors to be equal.
350 Otherwise any bit set is enough for vectors to be not-equal. */
351 tree mask_eq = (code == EQ_EXPR)
352 ? build_all_ones_cst (type) : build_zero_cst (type);
354 this->result_ = build_boolop (code, mask_eq,
355 build_vconvert (type, mask));
357 else
359 /* For operands of other types, identity is defined as being the
360 same as equality expressions. */
361 tree t1 = build_expr (e->e1);
362 tree t2 = build_expr (e->e2);
363 this->result_ = d_convert (build_ctype (e->type),
364 build_boolop (code, t1, t2));
368 /* Build an equality expression, which compare the two operands for either
369 equality or inequality. Operands go through the usual conversions to bring
370 them to a common type before comparison. The result type is bool. */
372 void visit (EqualExp *e) final override
374 Type *tb1 = e->e1->type->toBasetype ();
375 Type *tb2 = e->e2->type->toBasetype ();
376 tree_code code = (e->op == EXP::equal) ? EQ_EXPR : NE_EXPR;
378 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
379 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
381 /* For static and dynamic arrays, equality is defined as the lengths of
382 the arrays matching, and all the elements are equal. */
383 Type *t1elem = tb1->nextOf ()->toBasetype ();
384 Type *t2elem = tb1->nextOf ()->toBasetype ();
386 /* Check if comparisons of arrays can be optimized using memcmp.
387 This will inline EQ expressions as:
388 e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
389 Or when generating a NE expression:
390 e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */
391 if ((t1elem->isintegral () || t1elem->ty == TY::Tvoid
392 || (t1elem->ty == TY::Tstruct
393 && !t1elem->isTypeStruct ()->sym->xeq))
394 && t1elem->ty == t2elem->ty)
396 tree t1 = d_array_convert (e->e1);
397 tree t2 = d_array_convert (e->e2);
398 tree result;
400 /* Make temporaries to prevent multiple evaluations. */
401 tree t1saved = d_save_expr (t1);
402 tree t2saved = d_save_expr (t2);
404 /* Length of arrays, for comparisons done before calling memcmp. */
405 tree t1len = d_array_length (t1saved);
406 tree t2len = d_array_length (t2saved);
408 /* Reference to array data. */
409 tree t1ptr = d_array_ptr (t1saved);
410 tree t2ptr = d_array_ptr (t2saved);
412 /* Compare arrays using memcmp if possible, otherwise for structs,
413 each field is compared inline. */
414 if (t1elem->ty != TY::Tstruct
415 || identity_compare_p (t1elem->isTypeStruct ()->sym))
417 tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
419 result = build_memcmp_call (t1ptr, t2ptr, size);
420 result = build_boolop (code, result, integer_zero_node);
422 else
424 StructDeclaration *sd = t1elem->isTypeStruct ()->sym;
426 result = build_array_struct_comparison (code, sd, t1len,
427 t1ptr, t2ptr);
430 /* Check array length first before passing to memcmp.
431 For equality expressions, this becomes:
432 (e1.length == 0 || memcmp);
433 Otherwise for inequality:
434 (e1.length != 0 && memcmp); */
435 tree tsizecmp = build_boolop (code, t1len, size_zero_node);
436 if (e->op == EXP::equal)
437 result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
438 else
439 result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
441 /* Finally, check if lengths of both arrays match if dynamic.
442 The frontend should have already guaranteed that static arrays
443 have same size. */
444 if (tb1->ty == TY::Tsarray && tb2->ty == TY::Tsarray)
445 gcc_assert (tb1->size () == tb2->size ());
446 else
448 tree tlencmp = build_boolop (code, t1len, t2len);
449 if (e->op == EXP::equal)
450 result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
451 else
452 result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
455 /* Ensure left-to-right order of evaluation. */
456 if (TREE_SIDE_EFFECTS (t2))
457 result = compound_expr (t2saved, result);
459 if (TREE_SIDE_EFFECTS (t1))
460 result = compound_expr (t1saved, result);
462 this->result_ = result;
464 else
466 /* Use _adEq2() to compare each element. */
467 Type *t1array = t1elem->arrayOf ();
468 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
469 d_array_convert (e->e1),
470 d_array_convert (e->e2),
471 build_typeinfo (e, t1array));
473 if (e->op == EXP::notEqual)
474 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
476 this->result_ = result;
479 else if (TypeStruct *ts = tb1->isTypeStruct ())
481 /* Equality for struct objects means the logical product of all
482 equality results of the corresponding object fields. */
483 tree t1 = build_expr (e->e1);
484 tree t2 = build_expr (e->e2);
486 gcc_assert (same_type_p (tb1, tb2));
488 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
490 else if (tb1->ty == TY::Taarray && tb2->ty == TY::Taarray)
492 /* Use _aaEqual() for associative arrays. */
493 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
494 build_typeinfo (e, tb1),
495 build_expr (e->e1),
496 build_expr (e->e2));
498 if (e->op == EXP::notEqual)
499 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
501 this->result_ = result;
503 else
505 /* For operands of other types, equality is defined as the bit pattern
506 of the type matches exactly. */
507 tree t1 = build_expr (e->e1);
508 tree t2 = build_expr (e->e2);
510 this->result_ = d_convert (build_ctype (e->type),
511 build_boolop (code, t1, t2));
515 /* Build an `in' expression. This is a condition to see if an element
516 exists in an associative array. The result is a pointer to the
517 element, or null if false. */
519 void visit (InExp *e) final override
521 Type *tb2 = e->e2->type->toBasetype ();
522 Type *tkey = tb2->isTypeAArray ()->index->toBasetype ();
523 tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
525 /* Build a call to _aaInX(). */
526 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
527 build_expr (e->e2),
528 build_typeinfo (e, tkey),
529 build_address (key));
532 /* Build a relational expression. The result type is bool. */
534 void visit (CmpExp *e) final override
536 Type *tb1 = e->e1->type->toBasetype ();
537 Type *tb2 = e->e2->type->toBasetype ();
539 tree result;
540 tree_code code;
542 switch (e->op)
544 case EXP::lessOrEqual:
545 code = LE_EXPR;
546 break;
548 case EXP::lessThan:
549 code = LT_EXPR;
550 break;
552 case EXP::greaterOrEqual:
553 code = GE_EXPR;
554 break;
556 case EXP::greaterThan:
557 code = GT_EXPR;
558 break;
560 default:
561 gcc_unreachable ();
564 /* For static and dynamic arrays, the relational op is turned into a
565 library call. It is not lowered during codegen. */
566 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
567 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
569 error ("cannot handle comparison of type %<%s == %s%>",
570 tb1->toChars (), tb2->toChars ());
571 gcc_unreachable ();
574 /* Simple comparison. */
575 result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
576 this->result_ = d_convert (build_ctype (e->type), result);
579 /* Build a logical `and if' or `or if' expression. If the right operand
580 expression is void, then the resulting type is void. Otherwise the
581 result is bool. */
583 void visit (LogicalExp *e) final override
585 tree_code code = (e->op == EXP::andAnd) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
587 if (e->e2->type->toBasetype ()->ty != TY::Tvoid)
589 tree t1 = build_expr (e->e1);
590 tree t2 = build_expr (e->e2);
592 t1 = convert_for_condition (t1, e->e1->type);
593 t2 = convert_for_condition (t2, e->e2->type);
595 this->result_ = d_convert (build_ctype (e->type),
596 build_boolop (code, t1, t2));
598 else
600 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
601 tree t2 = build_expr_dtor (e->e2);
603 /* Invert condition for logical or if expression. */
604 if (e->op == EXP::orOr)
605 t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);
607 this->result_ = build_condition (build_ctype (e->type),
608 t1, t2, void_node);
612 /* Build a binary operand expression. Operands go through usual arithmetic
613 conversions to bring them to a common type before evaluating. */
615 void visit (BinExp *e) final override
617 tree_code code;
619 switch (e->op)
621 case EXP::add:
622 case EXP::min:
623 if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
624 || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
626 /* If the result is complex, then we can shortcut binary_op.
627 Frontend should have already validated types and sizes. */
628 tree t1 = build_expr (e->e1);
629 tree t2 = build_expr (e->e2);
631 if (e->op == EXP::min)
632 t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
634 if (e->e1->type->isreal ())
635 this->result_ = complex_expr (build_ctype (e->type), t1, t2);
636 else
637 this->result_ = complex_expr (build_ctype (e->type), t2, t1);
639 return;
641 else
642 code = (e->op == EXP::add)
643 ? PLUS_EXPR : MINUS_EXPR;
644 break;
646 case EXP::mul:
647 code = MULT_EXPR;
648 break;
650 case EXP::div:
651 /* Determine if the div expression is a lowered pointer diff operation.
652 The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */
653 if (MinExp *me = e->e1->isMinExp ())
655 if (me->e1->type->ty == TY::Tpointer
656 && me->e2->type->ty == TY::Tpointer
657 && e->e2->op == EXP::int64)
659 code = EXACT_DIV_EXPR;
660 break;
664 code = e->e1->type->isintegral ()
665 ? TRUNC_DIV_EXPR : RDIV_EXPR;
666 break;
668 case EXP::mod:
669 code = e->e1->type->isfloating ()
670 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
671 break;
673 case EXP::and_:
674 code = BIT_AND_EXPR;
675 break;
677 case EXP::or_:
678 code = BIT_IOR_EXPR;
679 break;
681 case EXP::xor_:
682 code = BIT_XOR_EXPR;
683 break;
685 case EXP::leftShift:
686 code = LSHIFT_EXPR;
687 break;
689 case EXP::rightShift:
690 code = RSHIFT_EXPR;
691 break;
693 case EXP::unsignedRightShift:
694 code = UNSIGNED_RSHIFT_EXPR;
695 break;
697 default:
698 gcc_unreachable ();
701 this->result_ = binary_op (code, build_ctype (e->type),
702 build_expr (e->e1), build_expr (e->e2));
706 /* Build a concat expression, which concatenates two or more arrays of the
707 same type, producing a dynamic array with the result. If one operand
708 is an element type, that element is converted to an array of length 1. */
710 void visit (CatExp *e) final override
712 /* This error is only emitted during the code generation pass because
713 concatentation is allowed in CTFE. */
714 if (!global.params.useGC)
716 error_at (make_location_t (e->loc),
717 "array concatenation of expression %qs requires the GC and "
718 "cannot be used with %<-fno-druntime%>", e->toChars ());
719 this->result_ = error_mark_node;
720 return;
723 /* All concat expressions should have been rewritten to `_d_arraycatnTX` in
724 the semantic phase. */
725 gcc_assert (e->lowering);
727 this->result_ = build_expr (e->lowering);
730 /* Build an assignment operator expression. The right operand is implicitly
731 converted to the type of the left operand, and assigned to it. */
733 void visit (BinAssignExp *e) final override
735 tree_code code;
736 Expression *e1b = e->e1;
738 switch (e->op)
740 case EXP::addAssign:
741 code = PLUS_EXPR;
742 break;
744 case EXP::minAssign:
745 code = MINUS_EXPR;
746 break;
748 case EXP::mulAssign:
749 code = MULT_EXPR;
750 break;
752 case EXP::divAssign:
753 code = e->e1->type->isintegral ()
754 ? TRUNC_DIV_EXPR : RDIV_EXPR;
755 break;
757 case EXP::modAssign:
758 code = e->e1->type->isfloating ()
759 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
760 break;
762 case EXP::andAssign:
763 code = BIT_AND_EXPR;
764 break;
766 case EXP::orAssign:
767 code = BIT_IOR_EXPR;
768 break;
770 case EXP::xorAssign:
771 code = BIT_XOR_EXPR;
772 break;
774 case EXP::powAssign:
775 gcc_unreachable ();
777 case EXP::leftShiftAssign:
778 code = LSHIFT_EXPR;
779 break;
781 case EXP::rightShiftAssign:
782 case EXP::unsignedRightShiftAssign:
783 /* Use the original lhs type before it was promoted. The left operand
784 of `>>>=' does not undergo integral promotions before shifting.
785 Strip off casts just incase anyway. */
786 while (e1b->op == EXP::cast_)
788 CastExp *ce = e1b->isCastExp ();
789 gcc_assert (same_type_p (ce->type, ce->to));
790 e1b = ce->e1;
792 code = (e->op == EXP::rightShiftAssign) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
793 break;
795 default:
796 gcc_unreachable ();
799 tree exp = binop_assignment (code, e1b, e->e2);
800 this->result_ = convert_expr (exp, e1b->type, e->type);
803 /* Build a concat assignment expression. The right operand is appended
804 to the left operand. */
806 void visit (CatAssignExp *e) final override
808 if (!global.params.useGC)
810 error_at (make_location_t (e->loc),
811 "appending to array in %qs requires the GC and cannot be "
812 "used with %<-fno-druntime%>", e->toChars ());
813 this->result_ = error_mark_node;
814 return;
817 Type *tb1 = e->e1->type->toBasetype ();
818 Type *tb2 = e->e2->type->toBasetype ();
820 if (e->op == EXP::concatenateDcharAssign)
822 /* Append a dchar to a char[] or wchar[]:
823 The assignment is handled by the D run-time library, so only
824 need to call `_d_arrayappend[cw]d(&e1, e2)' */
825 Type *etype = tb1->nextOf ()->toBasetype ();
827 /* Save the address of `e1', so it can be evaluated first.
828 As all D run-time library functions for concat assignments update
829 `e1' in-place and then return its value, the saved address can also
830 be used as the result of this expression as well. */
831 tree lhs = build_expr (e->e1);
832 tree lexpr = stabilize_expr (&lhs);
833 tree ptr = d_save_expr (build_address (lhs));
834 tree result = NULL_TREE;
836 gcc_assert (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar
837 && (etype->ty == TY::Tchar || etype->ty == TY::Twchar));
839 libcall_fn libcall = (etype->ty == TY::Tchar)
840 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
842 result = build_libcall (libcall, e->type, 2,
843 ptr, build_expr (e->e2));
845 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
846 result = compound_expr (compound_expr (lexpr, ptr), result);
847 this->result_ = compound_expr (result, build_deref (ptr));
849 else
851 gcc_assert (e->op == EXP::concatenateAssign
852 || e->op == EXP::concatenateElemAssign);
853 gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray);
854 /* Appending an element or array to another array has already been
855 handled by the front-end. */
856 gcc_assert (e->lowering);
858 this->result_ = build_expr (e->lowering);
862 /* Build an assignment expression. The right operand is implicitly
863 converted to the type of the left operand, and assigned to it. */
865 void visit (AssignExp *e) final override
867 /* First, handle special assignment semantics. */
869 /* Look for array.length = n; */
870 if (e->e1->op == EXP::arrayLength)
872 /* This case should have been rewritten to `_d_arraysetlengthT` in the
873 semantic phase. */
874 gcc_unreachable ();
877 /* Look for exp = noreturn; */
878 if (e->e2->type->isTypeNoreturn ())
880 /* If the RHS is a `noreturn' expression, there is no point generating
881 any code for the assignment, just evaluate side effects. */
882 tree t1 = build_expr (e->e1);
883 tree t2 = build_expr (e->e2);
884 this->result_ = compound_expr (t1, t2);
885 return;
888 /* Look for array[] = n; */
889 if (e->e1->op == EXP::slice)
891 SliceExp *se = e->e1->isSliceExp ();
892 Type *stype = se->e1->type->toBasetype ();
893 Type *etype = stype->nextOf ()->toBasetype ();
895 /* Determine if we need to run postblit or dtor. */
896 bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
897 bool destructor = needs_dtor (etype);
899 if (e->memset == MemorySet::blockAssign)
901 /* Set a range of elements to one value. */
902 tree t1 = build_expr (e->e1);
903 tree t2 = build_expr (e->e2);
904 tree result;
906 /* Extract any array bounds checks from the slice expression. */
907 tree init = stabilize_expr (&t1);
908 t1 = d_save_expr (t1);
910 if ((postblit || destructor) && e->op != EXP::blit)
912 /* This case should have been rewritten to `_d_arraysetassign`
913 in the semantic phase. */
914 gcc_unreachable ();
917 if (integer_zerop (t2))
919 tree size = size_mult_expr (d_array_length (t1),
920 size_int (etype->size ()));
921 result = build_memset_call (d_array_ptr (t1), size);
923 else
924 result = build_array_set (d_array_ptr (t1),
925 d_array_length (t1), t2);
927 result = compound_expr (init, result);
928 this->result_ = compound_expr (result, t1);
930 else
932 /* Perform a memcpy operation. */
933 gcc_assert (e->e2->type->ty != TY::Tpointer);
935 if (!postblit && !destructor)
937 tree t1 = d_save_expr (d_array_convert (e->e1));
938 tree t2 = d_save_expr (d_array_convert (e->e2));
940 /* References to array data. */
941 tree t1ptr = d_array_ptr (t1);
942 tree t1len = d_array_length (t1);
943 tree t2ptr = d_array_ptr (t2);
945 /* Generate: memcpy(to, from, size) */
946 tree size = size_mult_expr (t1len, size_int (etype->size ()));
947 tree result = build_memcpy_call (t1ptr, t2ptr, size);
949 /* Insert check that array lengths match and do not overlap. */
950 if (array_bounds_check ())
952 /* tlencmp = (t1len == t2len) */
953 tree t2len = d_array_length (t2);
954 tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len);
956 /* toverlap = (t1ptr + size <= t2ptr
957 || t2ptr + size <= t1ptr) */
958 tree t1ptrcmp = build_boolop (LE_EXPR,
959 build_offset (t1ptr, size),
960 t2ptr);
961 tree t2ptrcmp = build_boolop (LE_EXPR,
962 build_offset (t2ptr, size),
963 t1ptr);
964 tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp,
965 t2ptrcmp);
967 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */
968 tree tassert = build_array_bounds_call (e->loc);
969 tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR,
970 tlencmp, toverlap);
972 result = build_condition (void_type_node, tboundscheck,
973 result, tassert);
976 this->result_ = compound_expr (result, t1);
978 else if ((postblit || destructor)
979 && e->op != EXP::blit && e->op != EXP::construct)
981 /* Assigning to a non-trivially copyable array has already been
982 handled by the front-end. */
983 gcc_unreachable ();
985 else
987 /* Generate: _d_arraycopy() */
988 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
989 size_int (etype->size ()),
990 d_array_convert (e->e2),
991 d_array_convert (e->e1));
995 return;
998 /* Look for reference initializations. */
999 if (e->memset == MemorySet::referenceInit)
1001 gcc_assert (e->op == EXP::construct || e->op == EXP::blit);
1002 gcc_assert (e->e1->op == EXP::variable);
1004 Declaration *decl = e->e1->isVarExp ()->var;
1005 if (decl->storage_class & (STCout | STCref))
1007 tree t2 = convert_for_assignment (e->e2, e->e1->type);
1008 tree t1 = build_expr (e->e1);
1009 /* Want reference to lhs, not indirect ref. */
1010 t1 = TREE_OPERAND (t1, 0);
1011 t2 = build_address (t2);
1013 this->result_ = indirect_ref (build_ctype (e->type),
1014 build_assign (INIT_EXPR, t1, t2));
1015 return;
1019 /* Other types of assignments that may require post construction. */
1020 Type *tb1 = e->e1->type->toBasetype ();
1021 tree_code modifycode = (e->op == EXP::construct) ? INIT_EXPR : MODIFY_EXPR;
1023 /* Look for struct assignment. */
1024 if (tb1->ty == TY::Tstruct)
1026 tree t1 = build_expr (e->e1);
1027 tree t2 = convert_for_assignment (e->e2, e->e1->type, true);
1028 StructDeclaration *sd = tb1->isTypeStruct ()->sym;
1030 /* Look for struct = 0. */
1031 if (e->e2->op == EXP::int64)
1033 /* Use memset to fill struct. */
1034 gcc_assert (e->op == EXP::blit);
1035 tree result = build_memset_call (t1);
1037 /* Maybe set-up hidden pointer to outer scope context. */
1038 if (sd->isNested ())
1040 tree field = get_symbol_decl (sd->vthis);
1041 tree value = build_vthis (sd);
1043 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1044 result = compound_expr (result, vthis_exp);
1047 this->result_ = compound_expr (result, t1);
1049 else
1051 /* Simple struct literal assignment. */
1052 tree init = NULL_TREE;
1054 /* Fill any alignment holes in the struct using memset. */
1055 if ((e->op == EXP::construct
1056 || (e->e2->op == EXP::structLiteral && e->op == EXP::blit))
1057 && (sd->isUnionDeclaration () || !identity_compare_p (sd)))
1059 t1 = stabilize_reference (t1);
1060 init = build_memset_call (t1);
1063 /* Elide generating assignment if init is all zeroes. */
1064 if (init != NULL_TREE && initializer_zerop (t2))
1065 this->result_ = compound_expr (init, t1);
1066 else
1068 tree result = build_assign (modifycode, t1, t2);
1069 this->result_ = compound_expr (init, result);
1073 return;
1076 /* Look for static array assignment. */
1077 if (tb1->ty == TY::Tsarray)
1079 /* Look for array = 0. */
1080 if (e->e2->op == EXP::int64)
1082 /* Use memset to fill the array. */
1083 gcc_assert (e->op == EXP::blit);
1084 this->result_ = build_memset_call (build_expr (e->e1));
1085 return;
1088 Type *etype = tb1->nextOf ();
1089 gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray);
1091 /* Determine if we need to run postblit. */
1092 const bool postblit = needs_postblit (etype);
1093 const bool destructor = needs_dtor (etype);
1094 const bool lvalue = lvalue_p (e->e2);
1096 /* Optimize static array assignment with array literal. Even if the
1097 elements in rhs are all rvalues and don't have to call postblits,
1098 this assignment should call dtors on old assigned elements. */
1099 if ((!postblit && !destructor)
1100 || (e->op == EXP::construct && e->e2->op == EXP::arrayLiteral)
1101 || (e->op == EXP::construct && e->e2->op == EXP::call)
1102 || (e->op == EXP::construct && !lvalue && postblit)
1103 || (e->op == EXP::blit || e->e1->type->size () == 0))
1105 tree t1 = build_expr (e->e1);
1106 tree t2 = convert_for_assignment (e->e2, e->e1->type);
1108 this->result_ = build_assign (modifycode, t1, t2);
1109 return;
1112 /* All other kinds of lvalue or rvalue static array assignment.
1113 Array construction has already been handled by the front-end. */
1114 gcc_assert (e->op != EXP::construct);
1115 gcc_unreachable ();
1118 /* Simple assignment. */
1119 tree t1 = build_expr (e->e1);
1120 tree t2 = convert_for_assignment (e->e2, e->e1->type);
1122 this->result_ = build_assign (modifycode, t1, t2);
1125 /* Build an assignment expression that has been lowered in the front-end. */
1127 void visit (LoweredAssignExp *e) final override
1129 this->result_ = build_expr (e->lowering);
1132 /* Build a throw expression. */
1134 void visit (ThrowExp *e) final override
1136 tree arg = build_expr_dtor (e->e1);
1137 this->result_ = build_libcall (LIBCALL_THROW, Type::tvoid, 1, arg);
1140 /* Build a postfix expression. */
1142 void visit (PostExp *e) final override
1144 tree result;
1146 if (e->op == EXP::plusPlus)
1148 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1149 build_expr (e->e1), build_expr (e->e2));
1151 else if (e->op == EXP::minusMinus)
1153 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1154 build_expr (e->e1), build_expr (e->e2));
1156 else
1157 gcc_unreachable ();
1159 TREE_SIDE_EFFECTS (result) = 1;
1160 this->result_ = result;
1163 /* Build an index expression. */
1165 void visit (IndexExp *e) final override
1167 Type *tb1 = e->e1->type->toBasetype ();
1169 if (tb1->ty == TY::Taarray)
1171 /* Get the key for the associative array. */
1172 Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
1173 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1174 libcall_fn libcall;
1175 tree tinfo, ptr;
1177 if (e->modifiable)
1179 libcall = LIBCALL_AAGETY;
1180 ptr = build_address (build_expr (e->e1));
1181 tinfo = build_typeinfo (e, tb1->unSharedOf ()->mutableOf ());
1183 else
1185 libcall = LIBCALL_AAGETRVALUEX;
1186 ptr = build_expr (e->e1);
1187 tinfo = build_typeinfo (e, tkey);
1190 /* Index the associative array. */
1191 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1192 ptr, tinfo,
1193 size_int (tb1->nextOf ()->size ()),
1194 build_address (key));
1196 if (!e->indexIsInBounds && array_bounds_check ())
1198 tree tassert = build_array_bounds_call (e->loc);
1200 result = d_save_expr (result);
1201 result = build_condition (TREE_TYPE (result),
1202 d_truthvalue_conversion (result),
1203 result, tassert);
1206 this->result_ = indirect_ref (build_ctype (e->type), result);
1208 else
1210 /* Get the array and length for static and dynamic arrays. */
1211 tree array = d_save_expr (build_expr (e->e1));
1213 tree length = NULL_TREE;
1214 if (tb1->ty != TY::Tpointer)
1215 length = get_array_length (array, tb1);
1216 else
1217 gcc_assert (e->lengthVar == NULL);
1219 /* The __dollar variable just becomes a placeholder for the
1220 actual length. */
1221 if (e->lengthVar)
1222 e->lengthVar->csym = length;
1224 /* Generate the index. */
1225 tree index = build_expr (e->e2);
1227 /* If it's a static array and the index is constant, the front end has
1228 already checked the bounds. */
1229 if (tb1->ty != TY::Tpointer)
1230 index = build_bounds_index_condition (e, index, length);
1232 /* Convert vectors to their underlying array type. */
1233 if (VECTOR_TYPE_P (TREE_TYPE (array)))
1235 tree array_type =
1236 build_array_type_nelts (TREE_TYPE (TREE_TYPE (array)),
1237 TYPE_VECTOR_SUBPARTS (TREE_TYPE (array)));
1238 d_mark_addressable (array, false);
1239 array = build1 (VIEW_CONVERT_EXPR, array_type, array);
1242 if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
1244 /* Generate `array[index]'. When the index is non-constant, we must
1245 mark the array as addressable because we'll need to do pointer
1246 arithmetic on its address. */
1247 if (TREE_CODE (index) != INTEGER_CST)
1248 d_mark_addressable (array);
1250 this->result_ = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
1251 array, index, NULL_TREE, NULL_TREE);
1253 else
1255 /* Generate `array.ptr[index]'. */
1256 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1257 ptr = void_okay_p (ptr);
1258 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1259 build_pointer_index (ptr, index));
1264 /* Build a comma expression. The type is the type of the right operand. */
1266 void visit (CommaExp *e) final override
1268 tree t1 = build_expr (e->e1);
1269 tree t2 = build_expr (e->e2);
1270 tree type = e->type ? build_ctype (e->type) : void_type_node;
1272 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1275 /* Build an array length expression. Returns the number of elements
1276 in the array. The result is of type size_t. */
1278 void visit (ArrayLengthExp *e) final override
1280 if (e->e1->type->toBasetype ()->ty == TY::Tarray)
1281 this->result_ = d_array_length (build_expr (e->e1));
1282 else
1284 /* Static arrays have already been handled by the front-end. */
1285 error ("unexpected type for array length: %qs", e->type->toChars ());
1286 this->result_ = error_mark_node;
1290 /* Build a delegate pointer expression. This will return the frame
1291 pointer value as a type void*. */
1293 void visit (DelegatePtrExp *e) final override
1295 tree t1 = build_expr (e->e1);
1296 this->result_ = delegate_object (t1);
1299 /* Build a delegate function pointer expression. This will return the
1300 function pointer value as a function type. */
1302 void visit (DelegateFuncptrExp *e) final override
1304 tree t1 = build_expr (e->e1);
1305 this->result_ = delegate_method (t1);
1308 /* Build a slice expression. */
1310 void visit (SliceExp *e) final override
1312 Type *tb = e->type->toBasetype ();
1313 Type *tb1 = e->e1->type->toBasetype ();
1314 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray);
1316 /* Use convert-to-dynamic-array code if possible. */
1317 if (!e->lwr)
1319 tree result = build_expr (e->e1);
1320 if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
1321 result = convert_expr (result, e->e1->type, e->type);
1323 this->result_ = result;
1324 return;
1326 else
1327 gcc_assert (e->upr != NULL);
1329 /* Get the data pointer and length for static and dynamic arrays. */
1330 tree array = d_save_expr (build_expr (e->e1));
1331 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1332 tree length = NULL_TREE;
1334 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1335 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1336 if (tb1->ty != TY::Tpointer)
1337 length = get_array_length (array, tb1);
1338 else
1339 gcc_assert (e->lengthVar == NULL);
1341 /* The __dollar variable just becomes a placeholder for the
1342 actual length. */
1343 if (e->lengthVar)
1344 e->lengthVar->csym = length;
1346 /* Generate upper and lower bounds. */
1347 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1348 tree upr_tree = d_save_expr (build_expr (e->upr));
1350 /* If the upper bound has any side effects, then the lower bound should be
1351 copied to a temporary always. */
1352 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1353 lwr_tree = save_expr (lwr_tree);
1355 /* Adjust the .ptr offset. */
1356 if (!integer_zerop (lwr_tree))
1358 tree ptrtype = TREE_TYPE (ptr);
1359 ptr = build_pointer_index (void_okay_p (ptr), lwr_tree);
1360 ptr = build_nop (ptrtype, ptr);
1363 /* Nothing more to do for static arrays, their bounds checking has been
1364 done at compile-time. */
1365 if (tb->ty == TY::Tsarray)
1367 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1368 return;
1370 else
1371 gcc_assert (tb->ty == TY::Tarray);
1373 /* Generate bounds checking code. */
1374 tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree,
1375 length);
1376 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1377 this->result_ = compound_expr (array, result);
1380 /* Build a cast expression, which converts the given unary expression to the
1381 type of result. */
1383 void visit (CastExp *e) final override
1385 Type *ebtype = e->e1->type->toBasetype ();
1386 Type *tbtype = e->to->toBasetype ();
1387 tree result = build_expr (e->e1, this->constp_, this->literalp_);
1389 /* Just evaluate e1 if it has any side effects. */
1390 if (tbtype->ty == TY::Tvoid)
1391 this->result_ = build_nop (build_ctype (tbtype), result);
1392 else
1393 this->result_ = convert_for_rvalue (result, ebtype, tbtype);
1396 /* Build a delete expression. */
1398 void visit (DeleteExp *e) final override
1400 tree t1 = build_expr (e->e1);
1401 Type *tb1 = e->e1->type->toBasetype ();
1403 if (tb1->ty == TY::Tclass)
1405 /* For class object references, if there is a destructor for that class,
1406 the destructor is called for the object instance. */
1407 gcc_assert (e->e1->op == EXP::variable);
1409 VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
1410 gcc_assert (v && v->onstack ());
1412 libcall_fn libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1413 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1415 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1416 return;
1418 else
1420 error ("don%'t know how to delete %qs", e->e1->toChars ());
1421 this->result_ = error_mark_node;
1425 /* Build a remove expression, which removes a particular key from an
1426 associative array. */
1428 void visit (RemoveExp *e) final override
1430 /* Check that the array is actually an associative array. */
1431 if (e->e1->type->toBasetype ()->ty == TY::Taarray)
1433 Type *tb = e->e1->type->toBasetype ();
1434 Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
1435 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1437 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1438 build_expr (e->e1),
1439 build_typeinfo (e, tkey),
1440 build_address (index));
1442 else
1444 error ("%qs is not an associative array", e->e1->toChars ());
1445 this->result_ = error_mark_node;
1449 /* Build an unary not expression. */
1451 void visit (NotExp *e) final override
1453 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1454 /* Need to convert to boolean type or this will fail. */
1455 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1457 this->result_ = d_convert (build_ctype (e->type), result);
1460 /* Build a compliment expression, where all the bits in the value are
1461 complemented. Note: unlike in C, the usual integral promotions
1462 are not performed prior to the complement operation. */
1464 void visit (ComExp *e) final override
1466 TY ty1 = e->e1->type->toBasetype ()->ty;
1467 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1469 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1470 build_expr (e->e1));
1473 /* Build an unary negation expression. */
1475 void visit (NegExp *e) final override
1477 TY ty1 = e->e1->type->toBasetype ()->ty;
1478 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1480 tree type = build_ctype (e->type);
1481 tree expr = build_expr (e->e1);
1483 /* If the operation needs excess precision. */
1484 tree eptype = excess_precision_type (type);
1485 if (eptype != NULL_TREE)
1486 expr = d_convert (eptype, expr);
1487 else
1488 eptype = type;
1490 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1491 this->result_ = d_convert (type, ret);
1494 /* Build a pointer index expression. */
1496 void visit (PtrExp *e) final override
1498 Type *tnext = NULL;
1499 size_t offset;
1500 tree result;
1502 if (e->e1->op == EXP::add)
1504 AddExp *ae = e->e1->isAddExp ();
1505 if (ae->e1->op == EXP::address
1506 && ae->e2->isConst () && ae->e2->type->isintegral ())
1508 Expression *ex = ae->e1->isAddrExp ()->e1;
1509 tnext = ex->type->toBasetype ();
1510 result = build_expr (ex);
1511 offset = ae->e2->toUInteger ();
1514 else if (e->e1->op == EXP::symbolOffset)
1516 SymOffExp *se = e->e1->isSymOffExp ();
1517 if (!declaration_reference_p (se->var))
1519 tnext = se->var->type->toBasetype ();
1520 result = get_decl_tree (se->var);
1521 offset = se->offset;
1525 /* Produce better code by converting *(#record + n) to
1526 COMPONENT_REFERENCE. Otherwise, the variable will always be
1527 allocated in memory because its address is taken. */
1528 if (tnext && tnext->ty == TY::Tstruct)
1530 StructDeclaration *sd = tnext->isTypeStruct ()->sym;
1532 for (size_t i = 0; i < sd->fields.length; i++)
1534 VarDeclaration *field = sd->fields[i];
1536 if (field->offset == offset
1537 && same_type_p (field->type, e->type))
1539 /* Catch errors, backend will ICE otherwise. */
1540 if (error_operand_p (result))
1541 this->result_ = result;
1542 else
1544 result = component_ref (result, get_symbol_decl (field));
1545 this->result_ = result;
1547 return;
1549 else if (field->offset > offset)
1550 break;
1554 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1557 /* Build an unary address expression. */
1559 void visit (AddrExp *e) final override
1561 tree type = build_ctype (e->type);
1562 tree exp;
1564 /* The frontend optimizer can convert const symbol into a struct literal.
1565 Taking the address of a struct literal is otherwise illegal. */
1566 if (e->e1->op == EXP::structLiteral)
1568 StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
1569 gcc_assert (sle != NULL);
1571 /* Build the reference symbol, the decl is built first as the
1572 initializer may have recursive references. */
1573 if (!sle->sym)
1575 sle->sym = build_artificial_decl (build_ctype (sle->type),
1576 NULL_TREE, "S");
1577 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1578 d_pushdecl (sle->sym);
1579 rest_of_decl_compilation (sle->sym, 1, 0);
1582 exp = sle->sym;
1584 else
1585 exp = build_expr (e->e1, this->constp_, this->literalp_);
1587 TREE_CONSTANT (exp) = 0;
1588 this->result_ = d_convert (type, build_address (exp));
1591 /* Build a function call expression. */
1593 void visit (CallExp *e) final override
1595 Type *tb = e->e1->type->toBasetype ();
1596 Expression *e1b = e->e1;
1598 tree callee = NULL_TREE;
1599 tree object = NULL_TREE;
1600 tree cleanup = NULL_TREE;
1601 tree returnvalue = NULL_TREE;
1602 TypeFunction *tf = NULL;
1604 /* Calls to delegates can sometimes look like this. */
1605 if (e1b->op == EXP::comma)
1607 e1b = e1b->isCommaExp ()->e2;
1608 gcc_assert (e1b->op == EXP::variable);
1610 Declaration *var = e1b->isVarExp ()->var;
1611 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1614 if (e1b->op == EXP::dotVariable && tb->ty != TY::Tdelegate)
1616 DotVarExp *dve = e1b->isDotVarExp ();
1618 /* Don't modify the static initializer for struct literals. */
1619 if (dve->e1->op == EXP::structLiteral)
1621 StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
1622 sle->useStaticInit = false;
1625 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1626 if (fd != NULL)
1628 /* Get the correct callee from the DotVarExp object. */
1629 tree fndecl = get_symbol_decl (fd);
1630 AggregateDeclaration *ad = fd->isThis ();
1632 /* Static method; ignore the object instance. */
1633 if (!ad)
1634 callee = build_address (fndecl);
1635 else
1637 tree thisexp = build_expr (dve->e1);
1639 /* When constructing temporaries, if the constructor throws,
1640 then the object is destructed even though it is not a fully
1641 constructed object yet. And so this call will need to be
1642 moved inside the TARGET_EXPR_INITIAL slot. */
1643 if (fd->isCtorDeclaration ()
1644 && TREE_CODE (thisexp) == COMPOUND_EXPR
1645 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1646 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1648 cleanup = TREE_OPERAND (thisexp, 0);
1649 thisexp = TREE_OPERAND (thisexp, 1);
1652 if (TREE_CODE (thisexp) == CONSTRUCTOR)
1653 thisexp = force_target_expr (thisexp);
1655 /* Want reference to `this' object. */
1656 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1657 thisexp = build_address (thisexp);
1659 /* Make the callee a virtual call. */
1660 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1662 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1663 tree thistype = build_ctype (ad->handleType ());
1664 thisexp = build_nop (thistype, d_save_expr (thisexp));
1665 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1667 else
1668 fndecl = build_address (fndecl);
1670 /* C++ constructors return void, even though front-end semantic
1671 treats them as implicitly returning `this'. Set returnvalue
1672 to override the result of this expression. */
1673 if (fd->isCtorDeclaration ())
1675 thisexp = d_save_expr (thisexp);
1676 returnvalue = thisexp;
1679 callee = build_method_call (fndecl, thisexp, fd->type);
1684 if (callee == NULL_TREE)
1685 callee = build_expr (e1b);
1687 if (METHOD_CALL_EXPR (callee))
1689 /* This could be a delegate expression (TY == Tdelegate), but not
1690 actually a delegate variable. */
1691 if (e1b->op == EXP::dotVariable)
1693 /* This gets the true function type, getting the function type
1694 from e1->type can sometimes be incorrect, such as when calling
1695 a `ref' return function. */
1696 tf = get_function_type (e1b->isDotVarExp ()->var->type);
1698 else
1699 tf = get_function_type (tb);
1701 extract_from_method_call (callee, callee, object);
1703 else if (tb->ty == TY::Tdelegate)
1705 /* Delegate call, extract .object and .funcptr from var. */
1706 callee = d_save_expr (callee);
1707 tf = get_function_type (tb);
1708 object = delegate_object (callee);
1709 callee = delegate_method (callee);
1711 else if (e1b->op == EXP::variable)
1713 FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
1714 gcc_assert (fd != NULL);
1715 tf = get_function_type (fd->type);
1717 if (fd->isNested ())
1719 /* Maybe re-evaluate symbol storage treating `fd' as public. */
1720 if (call_by_alias_p (d_function_chain->function, fd))
1721 TREE_PUBLIC (callee) = 1;
1723 object = get_frame_for_symbol (fd);
1725 else if (fd->needThis ())
1727 error_at (make_location_t (e1b->loc),
1728 "need %<this%> to access member %qs", fd->toChars ());
1729 /* Continue compiling... */
1730 object = null_pointer_node;
1733 else
1735 /* Normal direct function call. */
1736 tf = get_function_type (tb);
1739 gcc_assert (tf != NULL);
1741 /* Now we have the type, callee and maybe object reference,
1742 build the call expression. */
1743 tree exp = d_build_call (tf, callee, object, e->arguments);
1745 /* Record whether the call expression has no side effects, so we can check
1746 for an unused return value later. */
1747 if (TREE_CODE (exp) == CALL_EXPR && CALL_EXPR_FN (exp) != NULL_TREE
1748 && call_side_effect_free_p (e->f, e->e1->type))
1749 CALL_EXPR_WARN_IF_UNUSED (exp) = 1;
1751 if (returnvalue != NULL_TREE)
1752 exp = compound_expr (exp, returnvalue);
1754 if (tf->isref ())
1755 exp = build_deref (exp);
1757 /* Some library calls are defined to return a generic type.
1758 this->type is the real type we want to return. */
1759 if (e->type->isTypeBasic ())
1760 exp = d_convert (build_ctype (e->type), exp);
1762 /* If this call was found to be a constructor for a temporary with a
1763 cleanup, then move the call inside the TARGET_EXPR. */
1764 if (cleanup != NULL_TREE)
1766 tree init = TARGET_EXPR_INITIAL (cleanup);
1767 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1769 /* Keep the return value outside the TARGET_EXPR. */
1770 if (returnvalue != NULL_TREE)
1771 cleanup = compound_expr (cleanup, TREE_OPERAND (exp, 1));
1773 exp = cleanup;
1776 this->result_ = exp;
1779 /* Build a delegate expression. */
1781 void visit (DelegateExp *e) final override
1783 if (e->func->semanticRun == PASS::semantic3done)
1785 /* Add the function as nested function if it belongs to this module.
1786 ie: it is a member of this module, or it is a template instance. */
1787 Dsymbol *owner = e->func->toParent ();
1788 while (!owner->isTemplateInstance () && owner->toParent ())
1789 owner = owner->toParent ();
1790 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1791 build_decl_tree (e->func);
1794 tree fndecl;
1795 tree object;
1797 if (e->func->isNested () && !e->func->isThis ())
1799 if (e->e1->op == EXP::null_)
1800 object = build_expr (e->e1);
1801 else
1802 object = get_frame_for_symbol (e->func);
1804 fndecl = build_address (get_symbol_decl (e->func));
1806 else
1808 if (!e->func->isThis ())
1810 error ("delegates are only for non-static functions");
1811 this->result_ = error_mark_node;
1812 return;
1815 object = build_expr (e->e1);
1817 /* Want reference to `this' object. */
1818 if (e->e1->type->ty != TY::Tclass && e->e1->type->ty != TY::Tpointer)
1819 object = build_address (object);
1821 /* Object reference could be the outer `this' field of a class or
1822 closure of type `void*'. Cast it to the right type. */
1823 if (e->e1->type->ty == TY::Tclass)
1824 object = d_convert (build_ctype (e->e1->type), object);
1826 fndecl = get_symbol_decl (e->func);
1828 /* Get pointer to function out of the virtual table. */
1829 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1830 && e->e1->op != EXP::super_ && e->e1->op != EXP::dotType)
1832 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1833 object = d_save_expr (object);
1834 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1836 else
1837 fndecl = build_address (fndecl);
1840 this->result_ = build_method_call (fndecl, object, e->type);
1843 /* Build a type component expression. */
1845 void visit (DotTypeExp *e) final override
1847 /* Just a pass through to underlying expression. */
1848 this->result_ = build_expr (e->e1);
1851 /* Build a component reference expression. */
1853 void visit (DotVarExp *e) final override
1855 VarDeclaration *vd = e->var->isVarDeclaration ();
1857 /* This could also be a function, but relying on that being taken
1858 care of by the visitor interface for CallExp. */
1859 if (vd != NULL)
1861 if (!vd->isField ())
1862 this->result_ = get_decl_tree (vd);
1863 else
1865 tree object = build_expr (e->e1);
1866 Type *tb = e->e1->type->toBasetype ();
1868 if (tb->ty != TY::Tstruct)
1869 object = build_deref (object);
1871 /* __complex is represented as a struct in the front-end, but
1872 underlying is really a complex type. */
1873 if (e->e1->type->ty == TY::Tenum
1874 && e->e1->type->isTypeEnum ()->sym->isSpecial ())
1875 object = underlying_complex_expr (build_ctype (tb), object);
1877 this->result_ = component_ref (object, get_symbol_decl (vd));
1880 else
1882 error ("%qs is not a field, but a %qs",
1883 e->var->toChars (), e->var->kind ());
1884 this->result_ = error_mark_node;
1888 /* Build an assert expression, used to declare conditions that must hold at
1889 that a given point in the program. */
1891 void visit (AssertExp *e) final override
1893 Type *tb1 = e->e1->type->toBasetype ();
1894 tree arg = build_expr (e->e1);
1895 tree tmsg = NULL_TREE;
1896 tree assert_pass = void_node;
1897 tree assert_fail;
1899 if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ())
1901 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1902 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1903 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1904 libcall_fn libcall;
1906 if (e->msg)
1908 tmsg = build_expr_dtor (e->msg);
1909 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1911 else
1912 libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP;
1914 /* Build a call to _d_assert(). */
1915 assert_fail = build_assert_call (e->loc, libcall, tmsg);
1917 if (global.params.useInvariants == CHECKENABLEon)
1919 /* If the condition is a D class or struct object with an invariant,
1920 call it if the condition result is true. */
1921 if (tb1->ty == TY::Tclass)
1923 ClassDeclaration *cd = tb1->isClassHandle ();
1924 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
1926 arg = d_save_expr (arg);
1927 assert_pass = build_libcall (LIBCALL_INVARIANT,
1928 Type::tvoid, 1, arg);
1931 else if (tb1->ty == TY::Tpointer
1932 && tb1->nextOf ()->ty == TY::Tstruct)
1934 StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
1935 if (sd->inv != NULL)
1937 Expressions args;
1938 arg = d_save_expr (arg);
1939 assert_pass = d_build_call_expr (sd->inv, arg, &args);
1944 else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
1946 /* Generate: __builtin_trap() */
1947 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
1948 assert_fail = build_call_expr (fn, 0);
1950 else
1952 /* Assert contracts are turned off. */
1953 this->result_ = void_node;
1954 return;
1957 /* Build condition that we are asserting in this contract. */
1958 tree condition = convert_for_condition (arg, e->e1->type);
1960 /* We expect the condition to always be true, as what happens if an assert
1961 contract is false is undefined behavior. */
1962 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
1963 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
1964 tree pred_type = TREE_VALUE (arg_types);
1965 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
1967 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
1968 build_int_cst (expected_type, 1));
1969 condition = d_truthvalue_conversion (condition);
1971 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
1974 /* Build a declaration expression. */
1976 void visit (DeclarationExp *e) final override
1978 /* Compile the declaration. */
1979 push_stmt_list ();
1980 build_decl_tree (e->declaration);
1981 tree result = pop_stmt_list ();
1983 /* Construction of an array for typesafe-variadic function arguments
1984 can cause an empty STMT_LIST here. This can causes problems
1985 during gimplification. */
1986 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
1987 result = build_empty_stmt (input_location);
1989 this->result_ = result;
1992 /* Build a typeid expression. Returns an instance of class TypeInfo
1993 corresponding to. */
1995 void visit (TypeidExp *e) final override
1997 if (Type *tid = isType (e->obj))
1999 tree ti = build_typeinfo (e, tid);
2001 /* If the typeinfo is at an offset. */
2002 if (tid->vtinfo->offset)
2003 ti = build_offset (ti, size_int (tid->vtinfo->offset));
2005 this->result_ = build_nop (build_ctype (e->type), ti);
2007 else if (Expression *tid = isExpression (e->obj))
2009 Type *type = tid->type->toBasetype ();
2010 assert (type->ty == TY::Tclass);
2012 /* Generate **classptr to get the classinfo. */
2013 tree ci = build_expr (tid);
2014 ci = indirect_ref (ptr_type_node, ci);
2015 ci = indirect_ref (ptr_type_node, ci);
2017 /* Add extra indirection for interfaces. */
2018 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
2019 ci = indirect_ref (ptr_type_node, ci);
2021 this->result_ = build_nop (build_ctype (e->type), ci);
2023 else
2024 gcc_unreachable ();
2027 /* Build a function/lambda expression. */
2029 void visit (FuncExp *e) final override
2031 /* Compile the declaration. */
2032 build_lambda_tree (e->fd, e->type->toBasetype ());
2034 /* If nested, this will be a trampoline. */
2035 if (e->fd->isNested ())
2037 tree func = build_address (get_symbol_decl (e->fd));
2038 tree object;
2040 if (this->constp_)
2042 /* Static delegate variables have no context pointer. */
2043 object = null_pointer_node;
2044 this->result_ = build_method_call (func, object, e->fd->type);
2045 TREE_CONSTANT (this->result_) = 1;
2047 else
2049 object = get_frame_for_symbol (e->fd);
2050 this->result_ = build_method_call (func, object, e->fd->type);
2053 else
2055 this->result_ = build_nop (build_ctype (e->type),
2056 build_address (get_symbol_decl (e->fd)));
2060 /* Build a halt expression. */
2062 void visit (HaltExp *) final override
2064 /* Should we use trap() or abort()? */
2065 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2066 this->result_ = build_call_expr (ttrap, 0);
2069 /* Build a symbol pointer offset expression. */
2071 void visit (SymOffExp *e) final override
2073 /* Build the address and offset of the symbol. */
2074 size_t soffset = e->isSymOffExp ()->offset;
2075 tree result = get_decl_tree (e->var);
2076 TREE_USED (result) = 1;
2078 if (e->var->isFuncDeclaration ())
2079 result = maybe_reject_intrinsic (result);
2081 /* Emit lambdas, same as is done in FuncExp. */
2082 if (FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ())
2083 build_lambda_tree (fld);
2085 if (declaration_reference_p (e->var))
2086 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2087 else
2088 result = build_address (result);
2090 if (!soffset)
2091 result = d_convert (build_ctype (e->type), result);
2092 else
2094 tree offset = size_int (soffset);
2095 result = build_nop (build_ctype (e->type),
2096 build_offset (result, offset));
2099 this->result_ = result;
2102 /* Build a variable expression. */
2104 void visit (VarExp *e) final override
2106 if (e->var->needThis ())
2108 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2109 this->result_ = error_mark_node;
2110 return;
2112 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2114 /* __ctfe is always false at run-time. */
2115 this->result_ = integer_zero_node;
2116 return;
2119 /* Emit lambdas, same as is done in FuncExp. */
2120 if (FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ())
2121 build_lambda_tree (fld);
2123 if (this->constp_)
2125 /* Want the initializer, not the expression. */
2126 VarDeclaration *var = e->var->isVarDeclaration ();
2127 SymbolDeclaration *sdecl = e->var->isSymbolDeclaration ();
2128 tree init = NULL_TREE;
2130 if (var && (var->isConst () || var->isImmutable ())
2131 && e->type->toBasetype ()->ty != TY::Tsarray && var->_init)
2133 if (var->inuse)
2134 error_at (make_location_t (e->loc), "recursive reference %qs",
2135 e->toChars ());
2136 else
2138 var->inuse++;
2139 init = build_expr (initializerToExpression (var->_init), true);
2140 var->inuse--;
2143 else if (sdecl && sdecl->dsym)
2145 if (StructDeclaration *sd = sdecl->dsym->isStructDeclaration ())
2146 init = layout_struct_initializer (sd);
2147 else if (ClassDeclaration *cd = sdecl->dsym->isClassDeclaration ())
2148 init = layout_class_initializer (cd);
2149 else
2150 gcc_unreachable ();
2152 else
2153 error_at (make_location_t (e->loc), "non-constant expression %qs",
2154 e->toChars ());
2156 if (init != NULL_TREE)
2157 this->result_ = init;
2158 else
2159 this->result_ = error_mark_node;
2161 else
2163 tree result = get_decl_tree (e->var);
2164 TREE_USED (result) = 1;
2166 /* The variable expression generated for `__traits(initSymbol)'. */
2167 if (SymbolDeclaration *sd = e->var->isSymbolDeclaration ())
2169 if (e->type->isTypeDArray ())
2171 /* Generate a slice for non-zero initialized aggregates,
2172 otherwise create an empty array. */
2173 gcc_assert (e->type == Type::tvoid->arrayOf ()->constOf ());
2175 tree type = build_ctype (e->type);
2176 tree length = size_int (sd->dsym->structsize);
2177 tree ptr = (sd->dsym->isStructDeclaration ()
2178 && sd->dsym->type->isZeroInit (e->loc))
2179 ? null_pointer_node : build_address (result);
2181 this->result_ = d_array_value (type, length, ptr);
2182 return;
2186 /* For variables that are references - currently only out/inout
2187 arguments; objects don't count - evaluating the variable means
2188 we want what it refers to. */
2189 if (declaration_reference_p (e->var))
2190 result = indirect_ref (build_ctype (e->var->type), result);
2192 this->result_ = result;
2196 /* Build a this variable expression. */
2198 void visit (ThisExp *e) final override
2200 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2201 tree result = NULL_TREE;
2203 if (e->var)
2204 result = get_decl_tree (e->var);
2205 else
2207 gcc_assert (fd && fd->vthis);
2208 result = get_decl_tree (fd->vthis);
2211 if (e->type->ty == TY::Tstruct)
2212 result = build_deref (result);
2214 this->result_ = result;
2217 /* Build a new expression, which allocates memory either on the garbage
2218 collected heap or by using a class or struct specific allocator. */
2220 void visit (NewExp *e) final override
2222 Type *tb = e->type->toBasetype ();
2223 tree result;
2225 if (tb->ty == TY::Tclass)
2227 /* Allocating a new class. */
2228 tb = e->newtype->toBasetype ();
2230 ClassDeclaration *cd = tb->isTypeClass ()->sym;
2231 tree type = build_ctype (tb);
2232 tree setup_exp = NULL_TREE;
2233 tree new_call;
2235 if (e->onstack)
2237 /* If being used as an initializer for a local variable with scope
2238 storage class, then the instance is allocated on the stack
2239 rather than the heap or using the class specific allocator. */
2240 tree var = build_local_temp (TREE_TYPE (type));
2241 new_call = build_nop (type, build_address (var));
2242 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2244 else if (global.params.ehnogc && e->thrownew)
2246 /* Allocating a `@nogc' Exception with `_d_newThrowable' has already
2247 been handled by the front-end. */
2248 gcc_unreachable ();
2250 else
2252 /* Generate: _d_newclass() */
2253 new_call = build_expr (e->lowering);
2256 /* Set the context pointer for nested classes. */
2257 if (cd->isNested ())
2259 tree field = get_symbol_decl (cd->vthis);
2260 tree value = NULL_TREE;
2262 if (e->thisexp)
2264 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2265 /* The class or function we're nested in. */
2266 Dsymbol *outer = cd->toParentLocal ();
2268 value = build_expr (e->thisexp);
2270 if (outer != tcd)
2272 ClassDeclaration *ocd = outer->isClassDeclaration ();
2273 int offset = 0;
2274 gcc_assert (ocd->isBaseOf (tcd, &offset));
2275 /* Could just add offset... */
2276 value = convert_expr (value, e->thisexp->type, ocd->type);
2279 else
2280 value = build_vthis (cd);
2282 if (value != NULL_TREE)
2284 /* Generate: (new())->vthis = this; */
2285 new_call = d_save_expr (new_call);
2286 field = component_ref (build_deref (new_call), field);
2287 setup_exp = compound_expr (setup_exp,
2288 modify_expr (field, value));
2291 new_call = compound_expr (setup_exp, new_call);
2293 /* Call the class constructor. */
2294 if (e->member)
2295 result = d_build_call_expr (e->member, new_call, e->arguments);
2296 else
2297 result = new_call;
2299 if (e->argprefix)
2300 result = compound_expr (build_expr (e->argprefix), result);
2302 else if (tb->ty == TY::Tpointer
2303 && tb->nextOf ()->toBasetype ()->ty == TY::Tstruct)
2305 /* Allocating memory for a new struct. */
2306 Type *htype = e->newtype->toBasetype ();
2307 gcc_assert (!e->onstack);
2309 TypeStruct *stype = htype->isTypeStruct ();
2310 StructDeclaration *sd = stype->sym;
2311 tree new_call;
2313 /* Cannot new an opaque struct. */
2314 if (sd->size (e->loc) == 0)
2316 this->result_ = d_convert (build_ctype (e->type),
2317 integer_zero_node);
2318 return;
2321 /* This case should have been rewritten to `_d_newitemT' during the
2322 semantic phase. */
2323 gcc_assert (e->lowering);
2325 /* Generate: _d_newitemT() */
2326 new_call = build_expr (e->lowering);
2328 if (e->member || !e->arguments)
2330 /* Set the context pointer for nested structs. */
2331 if (sd->isNested ())
2333 tree value = build_vthis (sd);
2334 tree field = get_symbol_decl (sd->vthis);
2335 tree type = build_ctype (stype);
2337 new_call = d_save_expr (new_call);
2338 field = component_ref (indirect_ref (type, new_call), field);
2339 new_call = compound_expr (modify_expr (field, value), new_call);
2342 /* Call the struct constructor. */
2343 if (e->member)
2344 result = d_build_call_expr (e->member, new_call, e->arguments);
2345 else
2346 result = new_call;
2348 else
2350 /* If we have a user supplied initializer, then set-up with a
2351 struct literal. */
2352 if (e->arguments != NULL && sd->fields.length != 0)
2354 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2355 e->arguments,
2356 htype);
2357 new_call = d_save_expr (new_call);
2358 se->type = sd->type;
2359 se->sym = new_call;
2361 /* Setting `se->sym' would mean that the result of the
2362 constructed struct literal expression is `*(new_call)'.
2363 Strip off the indirect reference, as we don't mean to
2364 compute the value yet. */
2365 result = build_address (build_expr (se));
2367 else
2368 result = new_call;
2371 if (e->argprefix)
2372 result = compound_expr (build_expr (e->argprefix), result);
2374 else if (tb->ty == TY::Tarray)
2376 /* Allocating memory for a new D array. */
2377 gcc_assert (e->arguments && e->arguments->length >= 1);
2379 /* Array allocations have already been handled by the front-end. */
2380 gcc_assert (e->lowering != NULL);
2381 result = build_expr (e->lowering);
2383 if (e->argprefix)
2384 result = compound_expr (build_expr (e->argprefix), result);
2386 else if (tb->ty == TY::Tpointer)
2388 /* Allocating memory for a new pointer. */
2389 TypePointer *tpointer = tb->isTypePointer ();
2391 if (tpointer->next->size () == 0)
2393 /* Pointer element size is unknown. */
2394 this->result_ = d_convert (build_ctype (e->type),
2395 integer_zero_node);
2396 return;
2399 /* This case should have been rewritten to `_d_newitemT' during the
2400 semantic phase. */
2401 gcc_assert (e->lowering);
2403 /* Generate: _d_newitemT() */
2404 result = build_expr (e->lowering);
2406 if (e->arguments && e->arguments->length == 1)
2408 result = d_save_expr (result);
2409 tree init = modify_expr (build_deref (result),
2410 build_expr ((*e->arguments)[0]));
2411 result = compound_expr (init, result);
2414 if (e->argprefix)
2415 result = compound_expr (build_expr (e->argprefix), result);
2417 else if (tb->ty == TY::Taarray)
2419 /* Allocating memory for a new associative array. */
2420 tree arg = build_typeinfo (e, e->newtype);
2421 tree mem = build_libcall (LIBCALL_AANEW, Type::tvoidptr, 1, arg);
2423 /* Return an associative array pointed to by MEM. */
2424 tree aatype = build_ctype (tb);
2425 vec <constructor_elt, va_gc> *ce = NULL;
2426 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2428 result = build_nop (build_ctype (e->type),
2429 build_constructor (aatype, ce));
2431 else
2432 gcc_unreachable ();
2434 this->result_ = convert_expr (result, tb, e->type);
2437 /* Build an integer literal. */
2439 void visit (IntegerExp *e) final override
2441 tree ctype = build_ctype (e->type->toBasetype ());
2442 this->result_ = build_integer_cst (e->value, ctype);
2445 /* Build a floating-point literal. */
2447 void visit (RealExp *e) final override
2449 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2452 /* Build a complex literal. */
2454 void visit (ComplexExp *e) final override
2456 Type *tnext;
2458 switch (e->type->toBasetype ()->ty)
2460 case TY::Tcomplex32:
2461 tnext = (TypeBasic *) Type::tfloat32;
2462 break;
2464 case TY::Tcomplex64:
2465 tnext = (TypeBasic *) Type::tfloat64;
2466 break;
2468 case TY::Tcomplex80:
2469 tnext = (TypeBasic *) Type::tfloat80;
2470 break;
2472 default:
2473 gcc_unreachable ();
2476 this->result_ = build_complex (build_ctype (e->type),
2477 build_float_cst (creall (e->value), tnext),
2478 build_float_cst (cimagl (e->value), tnext));
2481 /* Build a string literal, all strings are null terminated except for
2482 static arrays. */
2484 void visit (StringExp *e) final override
2486 Type *tb = e->type->toBasetype ();
2487 tree type = build_ctype (e->type);
2489 if (tb->ty == TY::Tsarray)
2491 /* Turn the string into a constructor for the static array. */
2492 vec <constructor_elt, va_gc> *elms = NULL;
2493 vec_safe_reserve (elms, e->len);
2494 tree etype = TREE_TYPE (type);
2496 for (size_t i = 0; i < e->len; i++)
2498 tree value = build_integer_cst (e->getIndex (i), etype);
2499 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2502 tree ctor = build_constructor (type, elms);
2503 TREE_CONSTANT (ctor) = 1;
2504 this->result_ = ctor;
2505 return;
2507 else
2509 /* Copy the string contents to a null terminated STRING_CST. */
2510 dinteger_t length = (e->len * e->sz);
2511 char *string = XALLOCAVEC (char, length + e->sz);
2512 memset (string, 0, length + e->sz);
2513 if (length > 0)
2514 memcpy (string, e->string, length);
2516 /* String value and type includes the null terminator. */
2517 tree value = build_string (length + e->sz, string);
2518 if (e->sz <= 4)
2519 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2520 else
2522 /* Hexadecimal literal strings with an 8-byte character type are
2523 just an alternative way to store an array of `ulong'.
2524 Treat it as if it were a `uint[]' array instead. */
2525 dinteger_t resize = e->sz / 4;
2526 TREE_TYPE (value) = make_array_type (Type::tuns32,
2527 (length * resize) + resize);
2530 value = build_address (value);
2532 if (tb->ty == TY::Tarray)
2533 value = d_array_value (type, size_int (e->len), value);
2535 TREE_CONSTANT (value) = 1;
2536 this->result_ = d_convert (type, value);
2540 /* Build a tuple literal. Just an argument list that may have
2541 side effects that need evaluation. */
2543 void visit (TupleExp *e) final override
2545 tree result = NULL_TREE;
2547 if (e->e0)
2548 result = build_expr (e->e0, this->constp_, true);
2550 for (size_t i = 0; i < e->exps->length; ++i)
2552 Expression *exp = (*e->exps)[i];
2553 result = compound_expr (result, build_expr (exp, this->constp_, true));
2556 if (result == NULL_TREE)
2557 result = void_node;
2559 this->result_ = result;
2562 /* Build an array literal. The common type of the all elements is taken to
2563 be the type of the array element, and all elements are implicitly
2564 converted to that type. */
2566 void visit (ArrayLiteralExp *e) final override
2568 Type *tb = e->type->toBasetype ();
2570 /* Implicitly convert void[n] to ubyte[n]. */
2571 if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid)
2572 tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());
2574 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray
2575 || tb->ty == TY::Tpointer);
2577 /* Handle empty array literals. */
2578 if (e->elements->length == 0)
2580 if (tb->ty == TY::Tarray)
2581 this->result_ = d_array_value (build_ctype (e->type),
2582 size_int (0), null_pointer_node);
2583 else
2584 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2585 NULL);
2587 return;
2590 /* Build an expression that assigns the expressions in ELEMENTS to
2591 a constructor. */
2592 vec <constructor_elt, va_gc> *elms = NULL;
2593 vec_safe_reserve (elms, e->elements->length);
2594 bool constant_p = true;
2595 tree saved_elems = NULL_TREE;
2597 Type *etype = tb->nextOf ();
2598 tree satype = make_array_type (etype, e->elements->length);
2600 for (size_t i = 0; i < e->elements->length; i++)
2602 Expression *expr = e->getElement (i);
2603 tree value = build_expr (expr, this->constp_, true);
2605 /* Only append nonzero values, the backend will zero out the rest
2606 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2607 if (!initializer_zerop (value))
2609 if (!TREE_CONSTANT (value))
2610 constant_p = false;
2612 /* Split construction of values out of the constructor if there
2613 may be side effects. */
2614 tree init = stabilize_expr (&value);
2615 if (init != NULL_TREE)
2616 saved_elems = compound_expr (saved_elems, init);
2618 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2619 convert_expr (value, expr->type, etype));
2623 /* Now return the constructor as the correct type. For static arrays there
2624 is nothing else to do. For dynamic arrays, return a two field struct.
2625 For pointers, return the address. */
2626 tree ctor = build_constructor (satype, elms);
2627 tree type = build_ctype (e->type);
2629 /* Nothing else to do for static arrays. */
2630 if (tb->ty == TY::Tsarray || this->constp_)
2632 /* Can't take the address of the constructor, so create an anonymous
2633 static symbol, and then refer to it. */
2634 if (tb->ty != TY::Tsarray)
2636 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2637 ctor = build_address (decl);
2638 if (tb->ty == TY::Tarray)
2639 ctor = d_array_value (type, size_int (e->elements->length), ctor);
2641 /* Immutable literals can be placed in rodata. */
2642 if (tb->isImmutable ())
2643 TREE_READONLY (decl) = 1;
2645 d_pushdecl (decl);
2646 rest_of_decl_compilation (decl, 1, 0);
2649 /* If the array literal is readonly or static. */
2650 if (constant_p)
2651 TREE_CONSTANT (ctor) = 1;
2652 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2653 TREE_STATIC (ctor) = 1;
2655 /* Use memset to fill any alignment holes in the array. */
2656 if (!this->constp_ && !this->literalp_)
2658 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
2660 if (ts != NULL && (!identity_compare_p (ts->sym)
2661 || ts->sym->isUnionDeclaration ()))
2663 tree var = build_local_temp (TREE_TYPE (ctor));
2664 tree init = build_memset_call (var);
2665 /* Evaluate memset() first, then any saved elements. */
2666 saved_elems = compound_expr (init, saved_elems);
2667 ctor = compound_expr (modify_expr (var, ctor), var);
2671 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2673 else if (e->onstack)
2675 /* Array literal for a `scope' dynamic array. */
2676 gcc_assert (tb->ty == TY::Tarray);
2677 ctor = force_target_expr (ctor);
2678 this->result_ = d_array_value (type, size_int (e->elements->length),
2679 build_address (ctor));
2681 else
2683 /* Allocate space on the memory managed heap. */
2684 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2685 etype->pointerTo (), 2,
2686 build_typeinfo (e, etype->arrayOf ()),
2687 size_int (e->elements->length));
2688 mem = d_save_expr (mem);
2690 /* Now copy the constructor into memory. */
2691 tree size = size_mult_expr (size_int (e->elements->length),
2692 size_int (tb->nextOf ()->size ()));
2694 tree result = build_memcpy_call (mem, build_address (ctor), size);
2696 /* Return the array pointed to by MEM. */
2697 result = compound_expr (result, mem);
2699 if (tb->ty == TY::Tarray)
2700 result = d_array_value (type, size_int (e->elements->length), result);
2702 this->result_ = compound_expr (saved_elems, result);
2706 /* Build an associative array literal. The common type of the all keys is
2707 taken to be the key type, and common type of all values the value type.
2708 All keys and values are then implicitly converted as needed. */
2710 void visit (AssocArrayLiteralExp *e) final override
2712 if (e->lowering != NULL)
2714 /* When an associative array literal gets lowered, it's converted into a
2715 struct literal suitable for static initialization. */
2716 gcc_assert (this->constp_);
2717 this->result_ = build_expr (e->lowering, this->constp_, true);
2718 return ;
2721 /* Want the mutable type for typeinfo reference. */
2722 Type *tb = e->type->toBasetype ()->mutableOf ();
2724 /* Handle empty assoc array literals. */
2725 TypeAArray *ta = tb->isTypeAArray ();
2726 if (e->keys->length == 0)
2728 this->result_ = build_constructor (build_ctype (ta), NULL);
2729 return;
2732 /* Build an expression that assigns all expressions in KEYS
2733 to a constructor. */
2734 tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
2735 e->keys, this->constp_);
2736 tree init = stabilize_expr (&akeys);
2738 /* Do the same with all expressions in VALUES. */
2739 tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
2740 e->values, this->constp_);
2741 init = compound_expr (init, stabilize_expr (&avals));
2743 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2744 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2745 size_int (e->keys->length),
2746 build_address (akeys));
2747 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2748 size_int (e->values->length),
2749 build_address (avals));
2751 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2752 build_typeinfo (e, ta), keys, vals);
2754 /* Return an associative array pointed to by MEM. */
2755 tree aatype = build_ctype (ta);
2756 vec <constructor_elt, va_gc> *ce = NULL;
2757 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2759 tree result = build_nop (build_ctype (e->type),
2760 build_constructor (aatype, ce));
2761 this->result_ = compound_expr (init, result);
2764 /* Build a struct literal. */
2766 void visit (StructLiteralExp *e) final override
2768 /* Handle empty struct literals. */
2769 if (e->elements == NULL || e->sd->fields.length == 0)
2771 this->result_ = build_constructor (build_ctype (e->type), NULL);
2772 return;
2775 /* Building sinit trees are delayed until after frontend semantic
2776 processing has complete. Build the static initializer now. */
2777 if (e->useStaticInit && !this->constp_ && !e->sd->isCsymbol ())
2779 tree init = aggregate_initializer_decl (e->sd);
2781 /* If initializing a symbol, don't forget to set it. */
2782 if (e->sym != NULL)
2784 tree var = build_deref (e->sym);
2785 init = compound_expr (modify_expr (var, init), var);
2788 this->result_ = init;
2789 return;
2792 /* Build a constructor that assigns the expressions in ELEMENTS
2793 at each field index that has been filled in. */
2794 vec <constructor_elt, va_gc> *ve = NULL;
2795 tree saved_elems = NULL_TREE;
2797 /* CTFE may fill the hidden pointer by NullExp. */
2798 gcc_assert (e->elements->length <= e->sd->fields.length);
2800 Type *tb = e->type->toBasetype ();
2801 gcc_assert (tb->ty == TY::Tstruct);
2803 for (size_t i = 0; i < e->elements->length; i++)
2805 Expression *exp = (*e->elements)[i];
2806 if (!exp)
2807 continue;
2809 VarDeclaration *field = e->sd->fields[i];
2810 Type *type = exp->type->toBasetype ();
2811 Type *ftype = field->type->toBasetype ();
2812 tree value = NULL_TREE;
2814 if (ftype->ty == TY::Tsarray && !same_type_p (type, ftype))
2816 /* Initialize a static array with a single element. */
2817 tree elem = build_expr (exp, this->constp_, true);
2818 saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
2819 elem = d_save_expr (elem);
2821 if (initializer_zerop (elem))
2822 value = build_constructor (build_ctype (ftype), NULL);
2823 else
2824 value = build_array_from_val (ftype, elem);
2826 else
2828 value = convert_expr (build_expr (exp, this->constp_, true),
2829 exp->type, field->type);
2832 /* Split construction of values out of the constructor. */
2833 saved_elems = compound_expr (saved_elems, stabilize_expr (&value));
2835 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2838 /* Maybe setup hidden pointer to outer scope context. */
2839 if (e->sd->isNested () && e->elements->length != e->sd->fields.length
2840 && this->constp_ == false)
2842 tree field = get_symbol_decl (e->sd->vthis);
2843 tree value = build_vthis (e->sd);
2844 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2845 gcc_assert (e->useStaticInit == false);
2848 /* Build a constructor in the correct shape of the aggregate type. */
2849 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2851 /* Nothing more to do for constant literals. */
2852 if (this->constp_)
2854 /* If the struct literal is a valid for static data. */
2855 if (TREE_CONSTANT (ctor)
2856 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2857 TREE_STATIC (ctor) = 1;
2859 this->result_ = compound_expr (saved_elems, ctor);
2860 return;
2863 /* Construct the struct literal for run-time. */
2864 if (e->sym != NULL)
2866 /* Store the result in a symbol to initialize the literal. */
2867 tree var = build_deref (e->sym);
2868 ctor = compound_expr (modify_expr (var, ctor), var);
2870 else if (!this->literalp_)
2872 /* Use memset to fill any alignment holes in the object. */
2873 if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
2875 tree var = build_local_temp (TREE_TYPE (ctor));
2876 tree init = build_memset_call (var);
2877 /* Evaluate memset() first, then any saved element constructors. */
2878 saved_elems = compound_expr (init, saved_elems);
2879 ctor = compound_expr (modify_expr (var, ctor), var);
2883 this->result_ = compound_expr (saved_elems, ctor);
2886 /* Build a null literal. */
2888 void visit (NullExp *e) final override
2890 this->result_ = build_typeof_null_value (e->type);
2893 /* Build a vector literal. */
2895 void visit (VectorExp *e) final override
2897 /* First handle array literal expressions. */
2898 if (e->e1->op == EXP::arrayLiteral)
2900 ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
2901 vec <constructor_elt, va_gc> *elms = NULL;
2902 bool constant_p = true;
2903 tree type = build_ctype (e->type);
2905 vec_safe_reserve (elms, ale->elements->length);
2906 for (size_t i = 0; i < ale->elements->length; i++)
2908 Expression *expr = ale->getElement (i);
2909 tree value = d_convert (TREE_TYPE (type),
2910 build_expr (expr, this->constp_, true));
2911 if (!CONSTANT_CLASS_P (value))
2912 constant_p = false;
2914 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2917 /* Build a VECTOR_CST from a constant vector constructor. */
2918 if (constant_p)
2919 this->result_ = build_vector_from_ctor (type, elms);
2920 else
2921 this->result_ = build_constructor (type, elms);
2923 else if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
2925 /* Build a vector representation from a static array. */
2926 this->result_ = convert_expr (build_expr (e->e1, this->constp_),
2927 e->e1->type, e->type);
2929 else
2931 /* Build constructor from single value. */
2932 tree type = build_ctype (e->type);
2933 tree value = d_convert (TREE_TYPE (type),
2934 build_expr (e->e1, this->constp_, true));
2935 this->result_ = build_vector_from_val (type, value);
2939 /* Build a static array representation of a vector expression. */
2941 void visit (VectorArrayExp *e) final override
2943 this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
2944 e->e1->type, e->type);
2947 /* Build a static class literal, return its reference. */
2949 void visit (ClassReferenceExp *e) final override
2951 /* The result of build_new_class_expr is a RECORD_TYPE, we want
2952 the reference. */
2953 tree var = build_address (build_new_class_expr (e));
2955 /* If the type of this literal is an interface, the we must add the
2956 interface offset to symbol. */
2957 if (this->constp_)
2959 TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
2960 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
2962 if (to != NULL)
2964 ClassDeclaration *from = e->originalClass ();
2965 int offset = 0;
2967 gcc_assert (to->isBaseOf (from, &offset) != 0);
2969 if (offset != 0)
2970 var = build_offset (var, size_int (offset));
2974 this->result_ = var;
2977 /* Build an uninitialized value, generated from void initializers. */
2979 void visit (VoidInitExp *e) final override
2981 /* The front-end only generates these for the initializer of globals.
2982 Represent `void' as zeroes, regardless of the type's default value. */
2983 gcc_assert (this->constp_);
2984 this->result_ = build_zero_cst (build_ctype (e->type));
2987 /* These expressions are mainly just a placeholders in the frontend.
2988 We shouldn't see them here. */
2990 void visit (ScopeExp *e) final override
2992 error_at (make_location_t (e->loc), "%qs is not an expression",
2993 e->toChars ());
2994 this->result_ = error_mark_node;
2997 void visit (TypeExp *e) final override
2999 error_at (make_location_t (e->loc), "type %qs is not an expression",
3000 e->toChars ());
3001 this->result_ = error_mark_node;
3006 /* Main entry point for ExprVisitor interface to generate code for
3007 the Expression AST class E. If CONST_P is true, then E is a
3008 constant expression. If LITERAL_P is true, then E is a value used
3009 in the initialization of another literal. */
3011 tree
3012 build_expr (Expression *e, bool const_p, bool literal_p)
3014 ExprVisitor v = ExprVisitor (const_p, literal_p);
3015 location_t saved_location = input_location;
3017 input_location = make_location_t (e->loc);
3018 e->accept (&v);
3019 tree expr = v.result ();
3020 input_location = saved_location;
3022 /* Check if initializer expression is valid constant. */
3023 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3025 error_at (make_location_t (e->loc), "non-constant expression %qs",
3026 e->toChars ());
3027 return error_mark_node;
3030 return expr;
3033 /* Same as build_expr, but also calls destructors on any temporaries. */
3035 tree
3036 build_expr_dtor (Expression *e)
3038 /* Codegen can be improved by determining if no exceptions can be thrown
3039 between the ctor and dtor, and eliminating the ctor and dtor. */
3040 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3041 tree result = build_expr (e);
3043 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3045 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3046 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3049 return result;
3052 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3054 tree
3055 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3057 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3058 tree result = build_expr (e);
3060 /* Convert for initializing the DECL_RESULT. */
3061 if (tf->isref ())
3063 /* If we are returning a reference, take the address. */
3064 result = convert_expr (result, e->type, type);
3065 result = build_address (result);
3067 else
3068 result = convert_for_rvalue (result, e->type, type);
3070 /* The decl to store the return expression. */
3071 tree decl = DECL_RESULT (cfun->decl);
3073 /* Split comma expressions, so that the result is returned directly. */
3074 tree expr = stabilize_expr (&result);
3075 result = build_assign (INIT_EXPR, decl, result);
3076 result = compound_expr (expr, return_expr (result));
3078 /* May nest the return expression inside the try/finally expression. */
3079 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3081 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3082 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3085 return result;