Fix ICE in set_cell_span, at text-art/table.cc:148 with D front-end and -fanalyzer
[official-gcc.git] / gcc / d / expr.cc
blob551d004c241616cffe41b32bf73e0b171f81edb1
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 (build_expr (e->e2),
976 e->e2->type, e->e1->type);
977 tree t1 = build_expr (e->e1);
978 /* Want reference to lhs, not indirect ref. */
979 t1 = TREE_OPERAND (t1, 0);
980 t2 = build_address (t2);
982 this->result_ = indirect_ref (build_ctype (e->type),
983 build_assign (INIT_EXPR, t1, t2));
984 return;
988 /* Other types of assignments that may require post construction. */
989 Type *tb1 = e->e1->type->toBasetype ();
990 tree_code modifycode = (e->op == EXP::construct) ? INIT_EXPR : MODIFY_EXPR;
992 /* Look for struct assignment. */
993 if (tb1->ty == TY::Tstruct)
995 tree t1 = build_expr (e->e1);
996 tree t2 = convert_for_assignment (build_expr (e->e2, false, true),
997 e->e2->type, e->e1->type);
998 StructDeclaration *sd = tb1->isTypeStruct ()->sym;
1000 /* Look for struct = 0. */
1001 if (e->e2->op == EXP::int64)
1003 /* Use memset to fill struct. */
1004 gcc_assert (e->op == EXP::blit);
1005 tree result = build_memset_call (t1);
1007 /* Maybe set-up hidden pointer to outer scope context. */
1008 if (sd->isNested ())
1010 tree field = get_symbol_decl (sd->vthis);
1011 tree value = build_vthis (sd);
1013 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1014 result = compound_expr (result, vthis_exp);
1017 this->result_ = compound_expr (result, t1);
1019 else
1021 /* Simple struct literal assignment. */
1022 tree init = NULL_TREE;
1024 /* Fill any alignment holes in the struct using memset. */
1025 if ((e->op == EXP::construct
1026 || (e->e2->op == EXP::structLiteral && e->op == EXP::blit))
1027 && (sd->isUnionDeclaration () || !identity_compare_p (sd)))
1029 t1 = stabilize_reference (t1);
1030 init = build_memset_call (t1);
1033 /* Elide generating assignment if init is all zeroes. */
1034 if (init != NULL_TREE && initializer_zerop (t2))
1035 this->result_ = compound_expr (init, t1);
1036 else
1038 tree result = build_assign (modifycode, t1, t2);
1039 this->result_ = compound_expr (init, result);
1043 return;
1046 /* Look for static array assignment. */
1047 if (tb1->ty == TY::Tsarray)
1049 /* Look for array = 0. */
1050 if (e->e2->op == EXP::int64)
1052 /* Use memset to fill the array. */
1053 gcc_assert (e->op == EXP::blit);
1054 this->result_ = build_memset_call (build_expr (e->e1));
1055 return;
1058 Type *etype = tb1->nextOf ();
1059 gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray);
1061 /* Determine if we need to run postblit. */
1062 const bool postblit = needs_postblit (etype);
1063 const bool destructor = needs_dtor (etype);
1064 const bool lvalue = lvalue_p (e->e2);
1066 /* Optimize static array assignment with array literal. Even if the
1067 elements in rhs are all rvalues and don't have to call postblits,
1068 this assignment should call dtors on old assigned elements. */
1069 if ((!postblit && !destructor)
1070 || (e->op == EXP::construct && e->e2->op == EXP::arrayLiteral)
1071 || (e->op == EXP::construct && e->e2->op == EXP::call)
1072 || (e->op == EXP::construct && !lvalue && postblit)
1073 || (e->op == EXP::blit || e->e1->type->size () == 0))
1075 tree t1 = build_expr (e->e1);
1076 tree t2 = convert_for_assignment (build_expr (e->e2),
1077 e->e2->type, e->e1->type);
1079 this->result_ = build_assign (modifycode, t1, t2);
1080 return;
1083 /* All other kinds of lvalue or rvalue static array assignment.
1084 Array construction has already been handled by the front-end. */
1085 gcc_assert (e->op != EXP::construct);
1086 gcc_unreachable ();
1089 /* Simple assignment. */
1090 tree t1 = build_expr (e->e1);
1091 tree t2 = convert_for_assignment (build_expr (e->e2),
1092 e->e2->type, e->e1->type);
1094 this->result_ = build_assign (modifycode, t1, t2);
1097 /* Build an assignment expression that has been lowered in the front-end. */
1099 void visit (LoweredAssignExp *e) final override
1101 this->result_ = build_expr (e->lowering);
1104 /* Build a throw expression. */
1106 void visit (ThrowExp *e) final override
1108 tree arg = build_expr_dtor (e->e1);
1109 this->result_ = build_libcall (LIBCALL_THROW, Type::tvoid, 1, arg);
1112 /* Build a postfix expression. */
1114 void visit (PostExp *e) final override
1116 tree result;
1118 if (e->op == EXP::plusPlus)
1120 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1121 build_expr (e->e1), build_expr (e->e2));
1123 else if (e->op == EXP::minusMinus)
1125 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1126 build_expr (e->e1), build_expr (e->e2));
1128 else
1129 gcc_unreachable ();
1131 TREE_SIDE_EFFECTS (result) = 1;
1132 this->result_ = result;
1135 /* Build an index expression. */
1137 void visit (IndexExp *e) final override
1139 Type *tb1 = e->e1->type->toBasetype ();
1141 if (tb1->ty == TY::Taarray)
1143 /* Get the key for the associative array. */
1144 Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
1145 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1146 libcall_fn libcall;
1147 tree tinfo, ptr;
1149 if (e->modifiable)
1151 libcall = LIBCALL_AAGETY;
1152 ptr = build_address (build_expr (e->e1));
1153 tinfo = build_typeinfo (e, tb1->unSharedOf ()->mutableOf ());
1155 else
1157 libcall = LIBCALL_AAGETRVALUEX;
1158 ptr = build_expr (e->e1);
1159 tinfo = build_typeinfo (e, tkey);
1162 /* Index the associative array. */
1163 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1164 ptr, tinfo,
1165 size_int (tb1->nextOf ()->size ()),
1166 build_address (key));
1168 if (!e->indexIsInBounds && array_bounds_check ())
1170 tree tassert = build_array_bounds_call (e->loc);
1172 result = d_save_expr (result);
1173 result = build_condition (TREE_TYPE (result),
1174 d_truthvalue_conversion (result),
1175 result, tassert);
1178 this->result_ = indirect_ref (build_ctype (e->type), result);
1180 else
1182 /* Get the array and length for static and dynamic arrays. */
1183 tree array = d_save_expr (build_expr (e->e1));
1185 tree length = NULL_TREE;
1186 if (tb1->ty != TY::Tpointer)
1187 length = get_array_length (array, tb1);
1188 else
1189 gcc_assert (e->lengthVar == NULL);
1191 /* The __dollar variable just becomes a placeholder for the
1192 actual length. */
1193 if (e->lengthVar)
1194 e->lengthVar->csym = length;
1196 /* Generate the index. */
1197 tree index = build_expr (e->e2);
1199 /* If it's a static array and the index is constant, the front end has
1200 already checked the bounds. */
1201 if (tb1->ty != TY::Tpointer)
1202 index = build_bounds_index_condition (e, index, length);
1204 /* Convert vectors to their underlying array type. */
1205 if (VECTOR_TYPE_P (TREE_TYPE (array)))
1207 tree array_type =
1208 build_array_type_nelts (TREE_TYPE (TREE_TYPE (array)),
1209 TYPE_VECTOR_SUBPARTS (TREE_TYPE (array)));
1210 d_mark_addressable (array, false);
1211 array = build1 (VIEW_CONVERT_EXPR, array_type, array);
1214 if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
1216 /* Generate `array[index]'. When the index is non-constant, we must
1217 mark the array as addressable because we'll need to do pointer
1218 arithmetic on its address. */
1219 if (TREE_CODE (index) != INTEGER_CST)
1220 d_mark_addressable (array);
1222 this->result_ = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
1223 array, index, NULL_TREE, NULL_TREE);
1225 else
1227 /* Generate `array.ptr[index]'. */
1228 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1229 ptr = void_okay_p (ptr);
1230 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1231 build_pointer_index (ptr, index));
1236 /* Build a comma expression. The type is the type of the right operand. */
1238 void visit (CommaExp *e) final override
1240 tree t1 = build_expr (e->e1);
1241 tree t2 = build_expr (e->e2);
1242 tree type = e->type ? build_ctype (e->type) : void_type_node;
1244 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1247 /* Build an array length expression. Returns the number of elements
1248 in the array. The result is of type size_t. */
1250 void visit (ArrayLengthExp *e) final override
1252 if (e->e1->type->toBasetype ()->ty == TY::Tarray)
1253 this->result_ = d_array_length (build_expr (e->e1));
1254 else
1256 /* Static arrays have already been handled by the front-end. */
1257 error ("unexpected type for array length: %qs", e->type->toChars ());
1258 this->result_ = error_mark_node;
1262 /* Build a delegate pointer expression. This will return the frame
1263 pointer value as a type void*. */
1265 void visit (DelegatePtrExp *e) final override
1267 tree t1 = build_expr (e->e1);
1268 this->result_ = delegate_object (t1);
1271 /* Build a delegate function pointer expression. This will return the
1272 function pointer value as a function type. */
1274 void visit (DelegateFuncptrExp *e) final override
1276 tree t1 = build_expr (e->e1);
1277 this->result_ = delegate_method (t1);
1280 /* Build a slice expression. */
1282 void visit (SliceExp *e) final override
1284 Type *tb = e->type->toBasetype ();
1285 Type *tb1 = e->e1->type->toBasetype ();
1286 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray);
1288 /* Use convert-to-dynamic-array code if possible. */
1289 if (!e->lwr)
1291 tree result = build_expr (e->e1);
1292 if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
1293 result = convert_expr (result, e->e1->type, e->type);
1295 this->result_ = result;
1296 return;
1298 else
1299 gcc_assert (e->upr != NULL);
1301 /* Get the data pointer and length for static and dynamic arrays. */
1302 tree array = d_save_expr (build_expr (e->e1));
1303 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1304 tree length = NULL_TREE;
1306 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1307 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1308 if (tb1->ty != TY::Tpointer)
1309 length = get_array_length (array, tb1);
1310 else
1311 gcc_assert (e->lengthVar == NULL);
1313 /* The __dollar variable just becomes a placeholder for the
1314 actual length. */
1315 if (e->lengthVar)
1316 e->lengthVar->csym = length;
1318 /* Generate upper and lower bounds. */
1319 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1320 tree upr_tree = d_save_expr (build_expr (e->upr));
1322 /* If the upper bound has any side effects, then the lower bound should be
1323 copied to a temporary always. */
1324 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1325 lwr_tree = save_expr (lwr_tree);
1327 /* Adjust the .ptr offset. */
1328 if (!integer_zerop (lwr_tree))
1330 tree ptrtype = TREE_TYPE (ptr);
1331 ptr = build_pointer_index (void_okay_p (ptr), lwr_tree);
1332 ptr = build_nop (ptrtype, ptr);
1335 /* Nothing more to do for static arrays, their bounds checking has been
1336 done at compile-time. */
1337 if (tb->ty == TY::Tsarray)
1339 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1340 return;
1342 else
1343 gcc_assert (tb->ty == TY::Tarray);
1345 /* Generate bounds checking code. */
1346 tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree,
1347 length);
1348 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1349 this->result_ = compound_expr (array, result);
1352 /* Build a cast expression, which converts the given unary expression to the
1353 type of result. */
1355 void visit (CastExp *e) final override
1357 Type *ebtype = e->e1->type->toBasetype ();
1358 Type *tbtype = e->to->toBasetype ();
1359 tree result = build_expr (e->e1, this->constp_, this->literalp_);
1361 /* Just evaluate e1 if it has any side effects. */
1362 if (tbtype->ty == TY::Tvoid)
1363 this->result_ = build_nop (build_ctype (tbtype), result);
1364 else
1365 this->result_ = convert_for_rvalue (result, ebtype, tbtype);
1368 /* Build a delete expression. */
1370 void visit (DeleteExp *e) final override
1372 tree t1 = build_expr (e->e1);
1373 Type *tb1 = e->e1->type->toBasetype ();
1375 if (tb1->ty == TY::Tclass)
1377 /* For class object references, if there is a destructor for that class,
1378 the destructor is called for the object instance. */
1379 gcc_assert (e->e1->op == EXP::variable);
1381 VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
1382 gcc_assert (v && v->onstack ());
1384 libcall_fn libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1385 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1387 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1388 return;
1390 else
1392 error ("don%'t know how to delete %qs", e->e1->toChars ());
1393 this->result_ = error_mark_node;
1397 /* Build a remove expression, which removes a particular key from an
1398 associative array. */
1400 void visit (RemoveExp *e) final override
1402 /* Check that the array is actually an associative array. */
1403 if (e->e1->type->toBasetype ()->ty == TY::Taarray)
1405 Type *tb = e->e1->type->toBasetype ();
1406 Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
1407 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1409 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1410 build_expr (e->e1),
1411 build_typeinfo (e, tkey),
1412 build_address (index));
1414 else
1416 error ("%qs is not an associative array", e->e1->toChars ());
1417 this->result_ = error_mark_node;
1421 /* Build an unary not expression. */
1423 void visit (NotExp *e) final override
1425 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1426 /* Need to convert to boolean type or this will fail. */
1427 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1429 this->result_ = d_convert (build_ctype (e->type), result);
1432 /* Build a compliment expression, where all the bits in the value are
1433 complemented. Note: unlike in C, the usual integral promotions
1434 are not performed prior to the complement operation. */
1436 void visit (ComExp *e) final override
1438 TY ty1 = e->e1->type->toBasetype ()->ty;
1439 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1441 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1442 build_expr (e->e1));
1445 /* Build an unary negation expression. */
1447 void visit (NegExp *e) final override
1449 TY ty1 = e->e1->type->toBasetype ()->ty;
1450 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1452 tree type = build_ctype (e->type);
1453 tree expr = build_expr (e->e1);
1455 /* If the operation needs excess precision. */
1456 tree eptype = excess_precision_type (type);
1457 if (eptype != NULL_TREE)
1458 expr = d_convert (eptype, expr);
1459 else
1460 eptype = type;
1462 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1463 this->result_ = d_convert (type, ret);
1466 /* Build a pointer index expression. */
1468 void visit (PtrExp *e) final override
1470 Type *tnext = NULL;
1471 size_t offset;
1472 tree result;
1474 if (e->e1->op == EXP::add)
1476 AddExp *ae = e->e1->isAddExp ();
1477 if (ae->e1->op == EXP::address
1478 && ae->e2->isConst () && ae->e2->type->isintegral ())
1480 Expression *ex = ae->e1->isAddrExp ()->e1;
1481 tnext = ex->type->toBasetype ();
1482 result = build_expr (ex);
1483 offset = ae->e2->toUInteger ();
1486 else if (e->e1->op == EXP::symbolOffset)
1488 SymOffExp *se = e->e1->isSymOffExp ();
1489 if (!declaration_reference_p (se->var))
1491 tnext = se->var->type->toBasetype ();
1492 result = get_decl_tree (se->var);
1493 offset = se->offset;
1497 /* Produce better code by converting *(#record + n) to
1498 COMPONENT_REFERENCE. Otherwise, the variable will always be
1499 allocated in memory because its address is taken. */
1500 if (tnext && tnext->ty == TY::Tstruct)
1502 StructDeclaration *sd = tnext->isTypeStruct ()->sym;
1504 for (size_t i = 0; i < sd->fields.length; i++)
1506 VarDeclaration *field = sd->fields[i];
1508 if (field->offset == offset
1509 && same_type_p (field->type, e->type))
1511 /* Catch errors, backend will ICE otherwise. */
1512 if (error_operand_p (result))
1513 this->result_ = result;
1514 else
1516 result = component_ref (result, get_symbol_decl (field));
1517 this->result_ = result;
1519 return;
1521 else if (field->offset > offset)
1522 break;
1526 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1529 /* Build an unary address expression. */
1531 void visit (AddrExp *e) final override
1533 tree type = build_ctype (e->type);
1534 tree exp;
1536 /* The frontend optimizer can convert const symbol into a struct literal.
1537 Taking the address of a struct literal is otherwise illegal. */
1538 if (e->e1->op == EXP::structLiteral)
1540 StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
1541 gcc_assert (sle != NULL);
1543 /* Build the reference symbol, the decl is built first as the
1544 initializer may have recursive references. */
1545 if (!sle->sym)
1547 sle->sym = build_artificial_decl (build_ctype (sle->type),
1548 NULL_TREE, "S");
1549 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1550 d_pushdecl (sle->sym);
1551 rest_of_decl_compilation (sle->sym, 1, 0);
1554 exp = sle->sym;
1556 else
1557 exp = build_expr (e->e1, this->constp_, this->literalp_);
1559 TREE_CONSTANT (exp) = 0;
1560 this->result_ = d_convert (type, build_address (exp));
1563 /* Build a function call expression. */
1565 void visit (CallExp *e) final override
1567 Type *tb = e->e1->type->toBasetype ();
1568 Expression *e1b = e->e1;
1570 tree callee = NULL_TREE;
1571 tree object = NULL_TREE;
1572 tree cleanup = NULL_TREE;
1573 tree returnvalue = NULL_TREE;
1574 TypeFunction *tf = NULL;
1576 /* Calls to delegates can sometimes look like this. */
1577 if (e1b->op == EXP::comma)
1579 e1b = e1b->isCommaExp ()->e2;
1580 gcc_assert (e1b->op == EXP::variable);
1582 Declaration *var = e1b->isVarExp ()->var;
1583 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1586 if (e1b->op == EXP::dotVariable && tb->ty != TY::Tdelegate)
1588 DotVarExp *dve = e1b->isDotVarExp ();
1590 /* Don't modify the static initializer for struct literals. */
1591 if (dve->e1->op == EXP::structLiteral)
1593 StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
1594 sle->useStaticInit = false;
1597 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1598 if (fd != NULL)
1600 /* Get the correct callee from the DotVarExp object. */
1601 tree fndecl = get_symbol_decl (fd);
1602 AggregateDeclaration *ad = fd->isThis ();
1604 /* Static method; ignore the object instance. */
1605 if (!ad)
1606 callee = build_address (fndecl);
1607 else
1609 tree thisexp = build_expr (dve->e1);
1611 /* When constructing temporaries, if the constructor throws,
1612 then the object is destructed even though it is not a fully
1613 constructed object yet. And so this call will need to be
1614 moved inside the TARGET_EXPR_INITIAL slot. */
1615 if (fd->isCtorDeclaration ()
1616 && TREE_CODE (thisexp) == COMPOUND_EXPR
1617 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1618 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1620 cleanup = TREE_OPERAND (thisexp, 0);
1621 thisexp = TREE_OPERAND (thisexp, 1);
1624 if (TREE_CODE (thisexp) == CONSTRUCTOR)
1625 thisexp = force_target_expr (thisexp);
1627 /* Want reference to `this' object. */
1628 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1629 thisexp = build_address (thisexp);
1631 /* Make the callee a virtual call. */
1632 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1634 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1635 tree thistype = build_ctype (ad->handleType ());
1636 thisexp = build_nop (thistype, d_save_expr (thisexp));
1637 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1639 else
1640 fndecl = build_address (fndecl);
1642 /* C++ constructors return void, even though front-end semantic
1643 treats them as implicitly returning `this'. Set returnvalue
1644 to override the result of this expression. */
1645 if (fd->isCtorDeclaration ())
1647 thisexp = d_save_expr (thisexp);
1648 returnvalue = thisexp;
1651 callee = build_method_call (fndecl, thisexp, fd->type);
1656 if (callee == NULL_TREE)
1657 callee = build_expr (e1b);
1659 if (METHOD_CALL_EXPR (callee))
1661 /* This could be a delegate expression (TY == Tdelegate), but not
1662 actually a delegate variable. */
1663 if (e1b->op == EXP::dotVariable)
1665 /* This gets the true function type, getting the function type
1666 from e1->type can sometimes be incorrect, such as when calling
1667 a `ref' return function. */
1668 tf = get_function_type (e1b->isDotVarExp ()->var->type);
1670 else
1671 tf = get_function_type (tb);
1673 extract_from_method_call (callee, callee, object);
1675 else if (tb->ty == TY::Tdelegate)
1677 /* Delegate call, extract .object and .funcptr from var. */
1678 callee = d_save_expr (callee);
1679 tf = get_function_type (tb);
1680 object = delegate_object (callee);
1681 callee = delegate_method (callee);
1683 else if (e1b->op == EXP::variable)
1685 FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
1686 gcc_assert (fd != NULL);
1687 tf = get_function_type (fd->type);
1689 if (fd->isNested ())
1691 /* Maybe re-evaluate symbol storage treating `fd' as public. */
1692 if (call_by_alias_p (d_function_chain->function, fd))
1693 TREE_PUBLIC (callee) = 1;
1695 object = get_frame_for_symbol (fd);
1697 else if (fd->needThis ())
1699 error_at (make_location_t (e1b->loc),
1700 "need %<this%> to access member %qs", fd->toChars ());
1701 /* Continue compiling... */
1702 object = null_pointer_node;
1705 else
1707 /* Normal direct function call. */
1708 tf = get_function_type (tb);
1711 gcc_assert (tf != NULL);
1713 /* Now we have the type, callee and maybe object reference,
1714 build the call expression. */
1715 tree exp = d_build_call (tf, callee, object, e->arguments);
1717 if (returnvalue != NULL_TREE)
1718 exp = compound_expr (exp, returnvalue);
1720 if (tf->isref ())
1721 exp = build_deref (exp);
1723 /* Some library calls are defined to return a generic type.
1724 this->type is the real type we want to return. */
1725 if (e->type->isTypeBasic ())
1726 exp = d_convert (build_ctype (e->type), exp);
1728 /* If this call was found to be a constructor for a temporary with a
1729 cleanup, then move the call inside the TARGET_EXPR. */
1730 if (cleanup != NULL_TREE)
1732 tree init = TARGET_EXPR_INITIAL (cleanup);
1733 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1735 /* Keep the return value outside the TARGET_EXPR. */
1736 if (returnvalue != NULL_TREE)
1737 cleanup = compound_expr (cleanup, TREE_OPERAND (exp, 1));
1739 exp = cleanup;
1742 this->result_ = exp;
1745 /* Build a delegate expression. */
1747 void visit (DelegateExp *e) final override
1749 if (e->func->semanticRun == PASS::semantic3done)
1751 /* Add the function as nested function if it belongs to this module.
1752 ie: it is a member of this module, or it is a template instance. */
1753 Dsymbol *owner = e->func->toParent ();
1754 while (!owner->isTemplateInstance () && owner->toParent ())
1755 owner = owner->toParent ();
1756 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1757 build_decl_tree (e->func);
1760 tree fndecl;
1761 tree object;
1763 if (e->func->isNested () && !e->func->isThis ())
1765 if (e->e1->op == EXP::null_)
1766 object = build_expr (e->e1);
1767 else
1768 object = get_frame_for_symbol (e->func);
1770 fndecl = build_address (get_symbol_decl (e->func));
1772 else
1774 if (!e->func->isThis ())
1776 error ("delegates are only for non-static functions");
1777 this->result_ = error_mark_node;
1778 return;
1781 object = build_expr (e->e1);
1783 /* Want reference to `this' object. */
1784 if (e->e1->type->ty != TY::Tclass && e->e1->type->ty != TY::Tpointer)
1785 object = build_address (object);
1787 /* Object reference could be the outer `this' field of a class or
1788 closure of type `void*'. Cast it to the right type. */
1789 if (e->e1->type->ty == TY::Tclass)
1790 object = d_convert (build_ctype (e->e1->type), object);
1792 fndecl = get_symbol_decl (e->func);
1794 /* Get pointer to function out of the virtual table. */
1795 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1796 && e->e1->op != EXP::super_ && e->e1->op != EXP::dotType)
1798 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1799 object = d_save_expr (object);
1800 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1802 else
1803 fndecl = build_address (fndecl);
1806 this->result_ = build_method_call (fndecl, object, e->type);
1809 /* Build a type component expression. */
1811 void visit (DotTypeExp *e) final override
1813 /* Just a pass through to underlying expression. */
1814 this->result_ = build_expr (e->e1);
1817 /* Build a component reference expression. */
1819 void visit (DotVarExp *e) final override
1821 VarDeclaration *vd = e->var->isVarDeclaration ();
1823 /* This could also be a function, but relying on that being taken
1824 care of by the visitor interface for CallExp. */
1825 if (vd != NULL)
1827 if (!vd->isField ())
1828 this->result_ = get_decl_tree (vd);
1829 else
1831 tree object = build_expr (e->e1);
1832 Type *tb = e->e1->type->toBasetype ();
1834 if (tb->ty != TY::Tstruct)
1835 object = build_deref (object);
1837 /* __complex is represented as a struct in the front-end, but
1838 underlying is really a complex type. */
1839 if (e->e1->type->ty == TY::Tenum
1840 && e->e1->type->isTypeEnum ()->sym->isSpecial ())
1841 object = underlying_complex_expr (build_ctype (tb), object);
1843 this->result_ = component_ref (object, get_symbol_decl (vd));
1846 else
1848 error ("%qs is not a field, but a %qs",
1849 e->var->toChars (), e->var->kind ());
1850 this->result_ = error_mark_node;
1854 /* Build an assert expression, used to declare conditions that must hold at
1855 that a given point in the program. */
1857 void visit (AssertExp *e) final override
1859 Type *tb1 = e->e1->type->toBasetype ();
1860 tree arg = build_expr (e->e1);
1861 tree tmsg = NULL_TREE;
1862 tree assert_pass = void_node;
1863 tree assert_fail;
1865 if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ())
1867 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1868 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1869 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1870 libcall_fn libcall;
1872 if (e->msg)
1874 tmsg = build_expr_dtor (e->msg);
1875 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1877 else
1878 libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP;
1880 /* Build a call to _d_assert(). */
1881 assert_fail = build_assert_call (e->loc, libcall, tmsg);
1883 if (global.params.useInvariants == CHECKENABLEon)
1885 /* If the condition is a D class or struct object with an invariant,
1886 call it if the condition result is true. */
1887 if (tb1->ty == TY::Tclass)
1889 ClassDeclaration *cd = tb1->isClassHandle ();
1890 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
1892 arg = d_save_expr (arg);
1893 assert_pass = build_libcall (LIBCALL_INVARIANT,
1894 Type::tvoid, 1, arg);
1897 else if (tb1->ty == TY::Tpointer
1898 && tb1->nextOf ()->ty == TY::Tstruct)
1900 StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
1901 if (sd->inv != NULL)
1903 Expressions args;
1904 arg = d_save_expr (arg);
1905 assert_pass = d_build_call_expr (sd->inv, arg, &args);
1910 else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
1912 /* Generate: __builtin_trap() */
1913 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
1914 assert_fail = build_call_expr (fn, 0);
1916 else
1918 /* Assert contracts are turned off. */
1919 this->result_ = void_node;
1920 return;
1923 /* Build condition that we are asserting in this contract. */
1924 tree condition = convert_for_condition (arg, e->e1->type);
1926 /* We expect the condition to always be true, as what happens if an assert
1927 contract is false is undefined behavior. */
1928 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
1929 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
1930 tree pred_type = TREE_VALUE (arg_types);
1931 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
1933 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
1934 build_int_cst (expected_type, 1));
1935 condition = d_truthvalue_conversion (condition);
1937 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
1940 /* Build a declaration expression. */
1942 void visit (DeclarationExp *e) final override
1944 /* Compile the declaration. */
1945 push_stmt_list ();
1946 build_decl_tree (e->declaration);
1947 tree result = pop_stmt_list ();
1949 /* Construction of an array for typesafe-variadic function arguments
1950 can cause an empty STMT_LIST here. This can causes problems
1951 during gimplification. */
1952 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
1953 result = build_empty_stmt (input_location);
1955 this->result_ = result;
1958 /* Build a typeid expression. Returns an instance of class TypeInfo
1959 corresponding to. */
1961 void visit (TypeidExp *e) final override
1963 if (Type *tid = isType (e->obj))
1965 tree ti = build_typeinfo (e, tid);
1967 /* If the typeinfo is at an offset. */
1968 if (tid->vtinfo->offset)
1969 ti = build_offset (ti, size_int (tid->vtinfo->offset));
1971 this->result_ = build_nop (build_ctype (e->type), ti);
1973 else if (Expression *tid = isExpression (e->obj))
1975 Type *type = tid->type->toBasetype ();
1976 assert (type->ty == TY::Tclass);
1978 /* Generate **classptr to get the classinfo. */
1979 tree ci = build_expr (tid);
1980 ci = indirect_ref (ptr_type_node, ci);
1981 ci = indirect_ref (ptr_type_node, ci);
1983 /* Add extra indirection for interfaces. */
1984 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
1985 ci = indirect_ref (ptr_type_node, ci);
1987 this->result_ = build_nop (build_ctype (e->type), ci);
1989 else
1990 gcc_unreachable ();
1993 /* Build a function/lambda expression. */
1995 void visit (FuncExp *e) final override
1997 Type *ftype = e->type->toBasetype ();
1999 /* This check is for lambda's, remove `vthis' as function isn't nested. */
2000 if (e->fd->tok == TOK::reserved && ftype->ty == TY::Tpointer)
2002 e->fd->tok = TOK::function_;
2003 e->fd->vthis = NULL;
2006 /* Compile the function literal body. */
2007 build_decl_tree (e->fd);
2009 /* If nested, this will be a trampoline. */
2010 if (e->fd->isNested ())
2012 tree func = build_address (get_symbol_decl (e->fd));
2013 tree object;
2015 if (this->constp_)
2017 /* Static delegate variables have no context pointer. */
2018 object = null_pointer_node;
2019 this->result_ = build_method_call (func, object, e->fd->type);
2020 TREE_CONSTANT (this->result_) = 1;
2022 else
2024 object = get_frame_for_symbol (e->fd);
2025 this->result_ = build_method_call (func, object, e->fd->type);
2028 else
2030 this->result_ = build_nop (build_ctype (e->type),
2031 build_address (get_symbol_decl (e->fd)));
2035 /* Build a halt expression. */
2037 void visit (HaltExp *) final override
2039 /* Should we use trap() or abort()? */
2040 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2041 this->result_ = build_call_expr (ttrap, 0);
2044 /* Build a symbol pointer offset expression. */
2046 void visit (SymOffExp *e) final override
2048 /* Build the address and offset of the symbol. */
2049 size_t soffset = e->isSymOffExp ()->offset;
2050 tree result = get_decl_tree (e->var);
2051 TREE_USED (result) = 1;
2053 if (declaration_reference_p (e->var))
2054 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2055 else
2056 result = build_address (result);
2058 if (!soffset)
2059 result = d_convert (build_ctype (e->type), result);
2060 else
2062 tree offset = size_int (soffset);
2063 result = build_nop (build_ctype (e->type),
2064 build_offset (result, offset));
2067 this->result_ = result;
2070 /* Build a variable expression. */
2072 void visit (VarExp *e) final override
2074 if (e->var->needThis ())
2076 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2077 this->result_ = error_mark_node;
2078 return;
2080 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2082 /* __ctfe is always false at run-time. */
2083 this->result_ = integer_zero_node;
2084 return;
2087 /* This check is same as is done in FuncExp for lambdas. */
2088 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2089 if (fld != NULL)
2091 if (fld->tok == TOK::reserved)
2093 fld->tok = TOK::function_;
2094 fld->vthis = NULL;
2097 /* Compiler the function literal body. */
2098 build_decl_tree (fld);
2101 if (this->constp_)
2103 /* Want the initializer, not the expression. */
2104 VarDeclaration *var = e->var->isVarDeclaration ();
2105 SymbolDeclaration *sdecl = e->var->isSymbolDeclaration ();
2106 tree init = NULL_TREE;
2108 if (var && (var->isConst () || var->isImmutable ())
2109 && e->type->toBasetype ()->ty != TY::Tsarray && var->_init)
2111 if (var->inuse)
2112 error_at (make_location_t (e->loc), "recursive reference %qs",
2113 e->toChars ());
2114 else
2116 var->inuse++;
2117 init = build_expr (initializerToExpression (var->_init), true);
2118 var->inuse--;
2121 else if (sdecl && sdecl->dsym)
2123 if (StructDeclaration *sd = sdecl->dsym->isStructDeclaration ())
2124 init = layout_struct_initializer (sd);
2125 else if (ClassDeclaration *cd = sdecl->dsym->isClassDeclaration ())
2126 init = layout_class_initializer (cd);
2127 else
2128 gcc_unreachable ();
2130 else
2131 error_at (make_location_t (e->loc), "non-constant expression %qs",
2132 e->toChars ());
2134 if (init != NULL_TREE)
2135 this->result_ = init;
2136 else
2137 this->result_ = error_mark_node;
2139 else
2141 tree result = get_decl_tree (e->var);
2142 TREE_USED (result) = 1;
2144 /* The variable expression generated for `__traits(initSymbol)'. */
2145 if (SymbolDeclaration *sd = e->var->isSymbolDeclaration ())
2147 if (e->type->isTypeDArray ())
2149 /* Generate a slice for non-zero initialized aggregates,
2150 otherwise create an empty array. */
2151 gcc_assert (e->type == Type::tvoid->arrayOf ()->constOf ());
2153 tree type = build_ctype (e->type);
2154 tree length = size_int (sd->dsym->structsize);
2155 tree ptr = (sd->dsym->isStructDeclaration ()
2156 && sd->dsym->type->isZeroInit (e->loc))
2157 ? null_pointer_node : build_address (result);
2159 this->result_ = d_array_value (type, length, ptr);
2160 return;
2164 /* For variables that are references - currently only out/inout
2165 arguments; objects don't count - evaluating the variable means
2166 we want what it refers to. */
2167 if (declaration_reference_p (e->var))
2168 result = indirect_ref (build_ctype (e->var->type), result);
2170 this->result_ = result;
2174 /* Build a this variable expression. */
2176 void visit (ThisExp *e) final override
2178 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2179 tree result = NULL_TREE;
2181 if (e->var)
2182 result = get_decl_tree (e->var);
2183 else
2185 gcc_assert (fd && fd->vthis);
2186 result = get_decl_tree (fd->vthis);
2189 if (e->type->ty == TY::Tstruct)
2190 result = build_deref (result);
2192 this->result_ = result;
2195 /* Build a new expression, which allocates memory either on the garbage
2196 collected heap or by using a class or struct specific allocator. */
2198 void visit (NewExp *e) final override
2200 Type *tb = e->type->toBasetype ();
2201 tree result;
2203 if (tb->ty == TY::Tclass)
2205 /* Allocating a new class. */
2206 tb = e->newtype->toBasetype ();
2208 ClassDeclaration *cd = tb->isTypeClass ()->sym;
2209 tree type = build_ctype (tb);
2210 tree setup_exp = NULL_TREE;
2211 tree new_call;
2213 if (e->onstack)
2215 /* If being used as an initializer for a local variable with scope
2216 storage class, then the instance is allocated on the stack
2217 rather than the heap or using the class specific allocator. */
2218 tree var = build_local_temp (TREE_TYPE (type));
2219 new_call = build_nop (type, build_address (var));
2220 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2222 else if (global.params.ehnogc && e->thrownew)
2224 /* Allocating a `@nogc' Exception with `_d_newThrowable' has already
2225 been handled by the front-end. */
2226 gcc_unreachable ();
2228 else
2230 /* Generate: _d_newclass() */
2231 new_call = build_expr (e->lowering);
2234 /* Set the context pointer for nested classes. */
2235 if (cd->isNested ())
2237 tree field = get_symbol_decl (cd->vthis);
2238 tree value = NULL_TREE;
2240 if (e->thisexp)
2242 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2243 /* The class or function we're nested in. */
2244 Dsymbol *outer = cd->toParentLocal ();
2246 value = build_expr (e->thisexp);
2248 if (outer != tcd)
2250 ClassDeclaration *ocd = outer->isClassDeclaration ();
2251 int offset = 0;
2252 gcc_assert (ocd->isBaseOf (tcd, &offset));
2253 /* Could just add offset... */
2254 value = convert_expr (value, e->thisexp->type, ocd->type);
2257 else
2258 value = build_vthis (cd);
2260 if (value != NULL_TREE)
2262 /* Generate: (new())->vthis = this; */
2263 new_call = d_save_expr (new_call);
2264 field = component_ref (build_deref (new_call), field);
2265 setup_exp = compound_expr (setup_exp,
2266 modify_expr (field, value));
2269 new_call = compound_expr (setup_exp, new_call);
2271 /* Call the class constructor. */
2272 if (e->member)
2273 result = d_build_call_expr (e->member, new_call, e->arguments);
2274 else
2275 result = new_call;
2277 if (e->argprefix)
2278 result = compound_expr (build_expr (e->argprefix), result);
2280 else if (tb->ty == TY::Tpointer
2281 && tb->nextOf ()->toBasetype ()->ty == TY::Tstruct)
2283 /* Allocating memory for a new struct. */
2284 Type *htype = e->newtype->toBasetype ();
2285 gcc_assert (!e->onstack);
2287 TypeStruct *stype = htype->isTypeStruct ();
2288 StructDeclaration *sd = stype->sym;
2289 tree new_call;
2291 /* Cannot new an opaque struct. */
2292 if (sd->size (e->loc) == 0)
2294 this->result_ = d_convert (build_ctype (e->type),
2295 integer_zero_node);
2296 return;
2299 /* This case should have been rewritten to `_d_newitemT' during the
2300 semantic phase. */
2301 gcc_assert (e->lowering);
2303 /* Generate: _d_newitemT() */
2304 new_call = build_expr (e->lowering);
2306 if (e->member || !e->arguments)
2308 /* Set the context pointer for nested structs. */
2309 if (sd->isNested ())
2311 tree value = build_vthis (sd);
2312 tree field = get_symbol_decl (sd->vthis);
2313 tree type = build_ctype (stype);
2315 new_call = d_save_expr (new_call);
2316 field = component_ref (indirect_ref (type, new_call), field);
2317 new_call = compound_expr (modify_expr (field, value), new_call);
2320 /* Call the struct constructor. */
2321 if (e->member)
2322 result = d_build_call_expr (e->member, new_call, e->arguments);
2323 else
2324 result = new_call;
2326 else
2328 /* If we have a user supplied initializer, then set-up with a
2329 struct literal. */
2330 if (e->arguments != NULL && sd->fields.length != 0)
2332 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2333 e->arguments,
2334 htype);
2335 new_call = d_save_expr (new_call);
2336 se->type = sd->type;
2337 se->sym = new_call;
2338 result = compound_expr (build_expr (se), new_call);
2340 else
2341 result = new_call;
2344 if (e->argprefix)
2345 result = compound_expr (build_expr (e->argprefix), result);
2347 else if (tb->ty == TY::Tarray)
2349 /* Allocating memory for a new D array. */
2350 tb = e->newtype->toBasetype ();
2351 TypeDArray *tarray = tb->isTypeDArray ();
2353 gcc_assert (e->arguments && e->arguments->length >= 1);
2355 if (e->arguments->length == 1)
2357 /* Single dimension array allocations. */
2358 Expression *arg = (*e->arguments)[0];
2360 if (tarray->next->size () == 0)
2362 /* Array element size is unknown. */
2363 this->result_ = d_array_value (build_ctype (e->type),
2364 size_int (0), null_pointer_node);
2365 return;
2368 libcall_fn libcall = tarray->next->isZeroInit ()
2369 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
2370 result = build_libcall (libcall, tb, 2,
2371 build_typeinfo (e, e->type),
2372 build_expr (arg));
2374 else
2376 /* Multidimensional array allocations. */
2377 tree tarray = make_array_type (Type::tsize_t, e->arguments->length);
2378 tree var = build_local_temp (tarray);
2379 vec <constructor_elt, va_gc> *elms = NULL;
2381 /* Get the base element type for the array, generating the
2382 initializer for the dims parameter along the way. */
2383 Type *telem = e->newtype->toBasetype ();
2384 for (size_t i = 0; i < e->arguments->length; i++)
2386 Expression *arg = (*e->arguments)[i];
2387 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2389 gcc_assert (telem->ty == TY::Tarray);
2390 telem = telem->toBasetype ()->nextOf ();
2391 gcc_assert (telem);
2394 /* Initialize the temporary. */
2395 tree init = modify_expr (var, build_constructor (tarray, elms));
2396 var = compound_expr (init, var);
2398 /* Generate: _d_newarraymTX(ti, dims)
2399 or: _d_newarraymiTX(ti, dims) */
2400 libcall_fn libcall = telem->isZeroInit ()
2401 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2403 tree tinfo = build_typeinfo (e, e->type);
2404 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2405 size_int (e->arguments->length),
2406 build_address (var));
2408 result = build_libcall (libcall, tb, 2, tinfo, dims);
2411 if (e->argprefix)
2412 result = compound_expr (build_expr (e->argprefix), result);
2414 else if (tb->ty == TY::Tpointer)
2416 /* Allocating memory for a new pointer. */
2417 TypePointer *tpointer = tb->isTypePointer ();
2419 if (tpointer->next->size () == 0)
2421 /* Pointer element size is unknown. */
2422 this->result_ = d_convert (build_ctype (e->type),
2423 integer_zero_node);
2424 return;
2427 /* This case should have been rewritten to `_d_newitemT' during the
2428 semantic phase. */
2429 gcc_assert (e->lowering);
2431 /* Generate: _d_newitemT() */
2432 result = build_expr (e->lowering);
2434 if (e->arguments && e->arguments->length == 1)
2436 result = d_save_expr (result);
2437 tree init = modify_expr (build_deref (result),
2438 build_expr ((*e->arguments)[0]));
2439 result = compound_expr (init, result);
2442 if (e->argprefix)
2443 result = compound_expr (build_expr (e->argprefix), result);
2445 else if (tb->ty == TY::Taarray)
2447 /* Allocating memory for a new associative array. */
2448 tree arg = build_typeinfo (e, e->newtype);
2449 tree mem = build_libcall (LIBCALL_AANEW, Type::tvoidptr, 1, arg);
2451 /* Return an associative array pointed to by MEM. */
2452 tree aatype = build_ctype (tb);
2453 vec <constructor_elt, va_gc> *ce = NULL;
2454 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2456 result = build_nop (build_ctype (e->type),
2457 build_constructor (aatype, ce));
2459 else
2460 gcc_unreachable ();
2462 this->result_ = convert_expr (result, tb, e->type);
2465 /* Build an integer literal. */
2467 void visit (IntegerExp *e) final override
2469 tree ctype = build_ctype (e->type->toBasetype ());
2470 this->result_ = build_integer_cst (e->value, ctype);
2473 /* Build a floating-point literal. */
2475 void visit (RealExp *e) final override
2477 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2480 /* Build a complex literal. */
2482 void visit (ComplexExp *e) final override
2484 Type *tnext;
2486 switch (e->type->toBasetype ()->ty)
2488 case TY::Tcomplex32:
2489 tnext = (TypeBasic *) Type::tfloat32;
2490 break;
2492 case TY::Tcomplex64:
2493 tnext = (TypeBasic *) Type::tfloat64;
2494 break;
2496 case TY::Tcomplex80:
2497 tnext = (TypeBasic *) Type::tfloat80;
2498 break;
2500 default:
2501 gcc_unreachable ();
2504 this->result_ = build_complex (build_ctype (e->type),
2505 build_float_cst (creall (e->value), tnext),
2506 build_float_cst (cimagl (e->value), tnext));
2509 /* Build a string literal, all strings are null terminated except for
2510 static arrays. */
2512 void visit (StringExp *e) final override
2514 Type *tb = e->type->toBasetype ();
2515 tree type = build_ctype (e->type);
2517 if (tb->ty == TY::Tsarray)
2519 /* Turn the string into a constructor for the static array. */
2520 vec <constructor_elt, va_gc> *elms = NULL;
2521 vec_safe_reserve (elms, e->len);
2522 tree etype = TREE_TYPE (type);
2524 for (size_t i = 0; i < e->len; i++)
2526 tree value = build_integer_cst (e->getCodeUnit (i), etype);
2527 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2530 tree ctor = build_constructor (type, elms);
2531 TREE_CONSTANT (ctor) = 1;
2532 this->result_ = ctor;
2534 else
2536 /* Copy the string contents to a null terminated string. */
2537 dinteger_t length = (e->len * e->sz);
2538 char *string = XALLOCAVEC (char, length + e->sz);
2539 memset (string, 0, length + e->sz);
2540 if (length > 0)
2541 memcpy (string, e->string, length);
2543 /* String value and type includes the null terminator. */
2544 tree value = build_string (length + e->sz, string);
2545 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2546 value = build_address (value);
2548 if (tb->ty == TY::Tarray)
2549 value = d_array_value (type, size_int (e->len), value);
2551 TREE_CONSTANT (value) = 1;
2552 this->result_ = d_convert (type, value);
2556 /* Build a tuple literal. Just an argument list that may have
2557 side effects that need evaluation. */
2559 void visit (TupleExp *e) final override
2561 tree result = NULL_TREE;
2563 if (e->e0)
2564 result = build_expr (e->e0, this->constp_, true);
2566 for (size_t i = 0; i < e->exps->length; ++i)
2568 Expression *exp = (*e->exps)[i];
2569 result = compound_expr (result, build_expr (exp, this->constp_, true));
2572 if (result == NULL_TREE)
2573 result = void_node;
2575 this->result_ = result;
2578 /* Build an array literal. The common type of the all elements is taken to
2579 be the type of the array element, and all elements are implicitly
2580 converted to that type. */
2582 void visit (ArrayLiteralExp *e) final override
2584 Type *tb = e->type->toBasetype ();
2586 /* Implicitly convert void[n] to ubyte[n]. */
2587 if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid)
2588 tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());
2590 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray
2591 || tb->ty == TY::Tpointer);
2593 /* Handle empty array literals. */
2594 if (e->elements->length == 0)
2596 if (tb->ty == TY::Tarray)
2597 this->result_ = d_array_value (build_ctype (e->type),
2598 size_int (0), null_pointer_node);
2599 else
2600 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2601 NULL);
2603 return;
2606 /* Build an expression that assigns the expressions in ELEMENTS to
2607 a constructor. */
2608 vec <constructor_elt, va_gc> *elms = NULL;
2609 vec_safe_reserve (elms, e->elements->length);
2610 bool constant_p = true;
2611 tree saved_elems = NULL_TREE;
2613 Type *etype = tb->nextOf ();
2614 tree satype = make_array_type (etype, e->elements->length);
2616 for (size_t i = 0; i < e->elements->length; i++)
2618 Expression *expr = e->getElement (i);
2619 tree value = build_expr (expr, this->constp_, true);
2621 /* Only append nonzero values, the backend will zero out the rest
2622 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2623 if (!initializer_zerop (value))
2625 if (!TREE_CONSTANT (value))
2626 constant_p = false;
2628 /* Split construction of values out of the constructor if there
2629 may be side effects. */
2630 tree init = stabilize_expr (&value);
2631 if (init != NULL_TREE)
2632 saved_elems = compound_expr (saved_elems, init);
2634 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2635 convert_expr (value, expr->type, etype));
2639 /* Now return the constructor as the correct type. For static arrays there
2640 is nothing else to do. For dynamic arrays, return a two field struct.
2641 For pointers, return the address. */
2642 tree ctor = build_constructor (satype, elms);
2643 tree type = build_ctype (e->type);
2645 /* Nothing else to do for static arrays. */
2646 if (tb->ty == TY::Tsarray || this->constp_)
2648 /* Can't take the address of the constructor, so create an anonymous
2649 static symbol, and then refer to it. */
2650 if (tb->ty != TY::Tsarray)
2652 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2653 ctor = build_address (decl);
2654 if (tb->ty == TY::Tarray)
2655 ctor = d_array_value (type, size_int (e->elements->length), ctor);
2657 /* Immutable literals can be placed in rodata. */
2658 if (tb->isImmutable ())
2659 TREE_READONLY (decl) = 1;
2661 d_pushdecl (decl);
2662 rest_of_decl_compilation (decl, 1, 0);
2665 /* If the array literal is readonly or static. */
2666 if (constant_p)
2667 TREE_CONSTANT (ctor) = 1;
2668 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2669 TREE_STATIC (ctor) = 1;
2671 /* Use memset to fill any alignment holes in the array. */
2672 if (!this->constp_ && !this->literalp_)
2674 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
2676 if (ts != NULL && (!identity_compare_p (ts->sym)
2677 || ts->sym->isUnionDeclaration ()))
2679 tree var = build_local_temp (TREE_TYPE (ctor));
2680 tree init = build_memset_call (var);
2681 /* Evaluate memset() first, then any saved elements. */
2682 saved_elems = compound_expr (init, saved_elems);
2683 ctor = compound_expr (modify_expr (var, ctor), var);
2687 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2689 else if (e->onstack)
2691 /* Array literal for a `scope' dynamic array. */
2692 gcc_assert (tb->ty == TY::Tarray);
2693 ctor = force_target_expr (ctor);
2694 this->result_ = d_array_value (type, size_int (e->elements->length),
2695 build_address (ctor));
2697 else
2699 /* Allocate space on the memory managed heap. */
2700 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2701 etype->pointerTo (), 2,
2702 build_typeinfo (e, etype->arrayOf ()),
2703 size_int (e->elements->length));
2704 mem = d_save_expr (mem);
2706 /* Now copy the constructor into memory. */
2707 tree size = size_mult_expr (size_int (e->elements->length),
2708 size_int (tb->nextOf ()->size ()));
2710 tree result = build_memcpy_call (mem, build_address (ctor), size);
2712 /* Return the array pointed to by MEM. */
2713 result = compound_expr (result, mem);
2715 if (tb->ty == TY::Tarray)
2716 result = d_array_value (type, size_int (e->elements->length), result);
2718 this->result_ = compound_expr (saved_elems, result);
2722 /* Build an associative array literal. The common type of the all keys is
2723 taken to be the key type, and common type of all values the value type.
2724 All keys and values are then implicitly converted as needed. */
2726 void visit (AssocArrayLiteralExp *e) final override
2728 /* Want the mutable type for typeinfo reference. */
2729 Type *tb = e->type->toBasetype ()->mutableOf ();
2731 /* Handle empty assoc array literals. */
2732 TypeAArray *ta = tb->isTypeAArray ();
2733 if (e->keys->length == 0)
2735 this->result_ = build_constructor (build_ctype (ta), NULL);
2736 return;
2739 /* Build an expression that assigns all expressions in KEYS
2740 to a constructor. */
2741 tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
2742 e->keys, this->constp_);
2743 tree init = stabilize_expr (&akeys);
2745 /* Do the same with all expressions in VALUES. */
2746 tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
2747 e->values, this->constp_);
2748 init = compound_expr (init, stabilize_expr (&avals));
2750 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2751 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2752 size_int (e->keys->length),
2753 build_address (akeys));
2754 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2755 size_int (e->values->length),
2756 build_address (avals));
2758 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2759 build_typeinfo (e, ta), keys, vals);
2761 /* Return an associative array pointed to by MEM. */
2762 tree aatype = build_ctype (ta);
2763 vec <constructor_elt, va_gc> *ce = NULL;
2764 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2766 tree result = build_nop (build_ctype (e->type),
2767 build_constructor (aatype, ce));
2768 this->result_ = compound_expr (init, result);
2771 /* Build a struct literal. */
2773 void visit (StructLiteralExp *e) final override
2775 /* Handle empty struct literals. */
2776 if (e->elements == NULL || e->sd->fields.length == 0)
2778 this->result_ = build_constructor (build_ctype (e->type), NULL);
2779 return;
2782 /* Building sinit trees are delayed until after frontend semantic
2783 processing has complete. Build the static initializer now. */
2784 if (e->useStaticInit && !this->constp_ && !e->sd->isCsymbol ())
2786 tree init = aggregate_initializer_decl (e->sd);
2788 /* If initializing a symbol, don't forget to set it. */
2789 if (e->sym != NULL)
2791 tree var = build_deref (e->sym);
2792 init = compound_expr (modify_expr (var, init), var);
2795 this->result_ = init;
2796 return;
2799 /* Build a constructor that assigns the expressions in ELEMENTS
2800 at each field index that has been filled in. */
2801 vec <constructor_elt, va_gc> *ve = NULL;
2802 tree saved_elems = NULL_TREE;
2804 /* CTFE may fill the hidden pointer by NullExp. */
2805 gcc_assert (e->elements->length <= e->sd->fields.length);
2807 Type *tb = e->type->toBasetype ();
2808 gcc_assert (tb->ty == TY::Tstruct);
2810 for (size_t i = 0; i < e->elements->length; i++)
2812 Expression *exp = (*e->elements)[i];
2813 if (!exp)
2814 continue;
2816 VarDeclaration *field = e->sd->fields[i];
2817 Type *type = exp->type->toBasetype ();
2818 Type *ftype = field->type->toBasetype ();
2819 tree value = NULL_TREE;
2821 if (ftype->ty == TY::Tsarray && !same_type_p (type, ftype))
2823 /* Initialize a static array with a single element. */
2824 tree elem = build_expr (exp, this->constp_, true);
2825 saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
2826 elem = d_save_expr (elem);
2828 if (initializer_zerop (elem))
2829 value = build_constructor (build_ctype (ftype), NULL);
2830 else
2831 value = build_array_from_val (ftype, elem);
2833 else
2835 value = convert_expr (build_expr (exp, this->constp_, true),
2836 exp->type, field->type);
2839 /* Split construction of values out of the constructor. */
2840 saved_elems = compound_expr (saved_elems, stabilize_expr (&value));
2842 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2845 /* Maybe setup hidden pointer to outer scope context. */
2846 if (e->sd->isNested () && e->elements->length != e->sd->fields.length
2847 && this->constp_ == false)
2849 tree field = get_symbol_decl (e->sd->vthis);
2850 tree value = build_vthis (e->sd);
2851 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2852 gcc_assert (e->useStaticInit == false);
2855 /* Build a constructor in the correct shape of the aggregate type. */
2856 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2858 /* Nothing more to do for constant literals. */
2859 if (this->constp_)
2861 /* If the struct literal is a valid for static data. */
2862 if (TREE_CONSTANT (ctor)
2863 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2864 TREE_STATIC (ctor) = 1;
2866 this->result_ = compound_expr (saved_elems, ctor);
2867 return;
2870 /* Construct the struct literal for run-time. */
2871 if (e->sym != NULL)
2873 /* Store the result in a symbol to initialize the literal. */
2874 tree var = build_deref (e->sym);
2875 ctor = compound_expr (modify_expr (var, ctor), var);
2877 else if (!this->literalp_)
2879 /* Use memset to fill any alignment holes in the object. */
2880 if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
2882 tree var = build_local_temp (TREE_TYPE (ctor));
2883 tree init = build_memset_call (var);
2884 /* Evaluate memset() first, then any saved element constructors. */
2885 saved_elems = compound_expr (init, saved_elems);
2886 ctor = compound_expr (modify_expr (var, ctor), var);
2890 this->result_ = compound_expr (saved_elems, ctor);
2893 /* Build a null literal. */
2895 void visit (NullExp *e) final override
2897 this->result_ = build_typeof_null_value (e->type);
2900 /* Build a vector literal. */
2902 void visit (VectorExp *e) final override
2904 /* First handle array literal expressions. */
2905 if (e->e1->op == EXP::arrayLiteral)
2907 ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
2908 vec <constructor_elt, va_gc> *elms = NULL;
2909 bool constant_p = true;
2910 tree type = build_ctype (e->type);
2912 vec_safe_reserve (elms, ale->elements->length);
2913 for (size_t i = 0; i < ale->elements->length; i++)
2915 Expression *expr = ale->getElement (i);
2916 tree value = d_convert (TREE_TYPE (type),
2917 build_expr (expr, this->constp_, true));
2918 if (!CONSTANT_CLASS_P (value))
2919 constant_p = false;
2921 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2924 /* Build a VECTOR_CST from a constant vector constructor. */
2925 if (constant_p)
2926 this->result_ = build_vector_from_ctor (type, elms);
2927 else
2928 this->result_ = build_constructor (type, elms);
2930 else if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
2932 /* Build a vector representation from a static array. */
2933 this->result_ = convert_expr (build_expr (e->e1, this->constp_),
2934 e->e1->type, e->type);
2936 else
2938 /* Build constructor from single value. */
2939 tree type = build_ctype (e->type);
2940 tree value = d_convert (TREE_TYPE (type),
2941 build_expr (e->e1, this->constp_, true));
2942 this->result_ = build_vector_from_val (type, value);
2946 /* Build a static array representation of a vector expression. */
2948 void visit (VectorArrayExp *e) final override
2950 this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
2951 e->e1->type, e->type);
2954 /* Build a static class literal, return its reference. */
2956 void visit (ClassReferenceExp *e) final override
2958 /* The result of build_new_class_expr is a RECORD_TYPE, we want
2959 the reference. */
2960 tree var = build_address (build_new_class_expr (e));
2962 /* If the type of this literal is an interface, the we must add the
2963 interface offset to symbol. */
2964 if (this->constp_)
2966 TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
2967 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
2969 if (to != NULL)
2971 ClassDeclaration *from = e->originalClass ();
2972 int offset = 0;
2974 gcc_assert (to->isBaseOf (from, &offset) != 0);
2976 if (offset != 0)
2977 var = build_offset (var, size_int (offset));
2981 this->result_ = var;
2984 /* Build an uninitialized value, generated from void initializers. */
2986 void visit (VoidInitExp *e) final override
2988 /* The front-end only generates these for the initializer of globals.
2989 Represent `void' as zeroes, regardless of the type's default value. */
2990 gcc_assert (this->constp_);
2991 this->result_ = build_zero_cst (build_ctype (e->type));
2994 /* These expressions are mainly just a placeholders in the frontend.
2995 We shouldn't see them here. */
2997 void visit (ScopeExp *e) final override
2999 error_at (make_location_t (e->loc), "%qs is not an expression",
3000 e->toChars ());
3001 this->result_ = error_mark_node;
3004 void visit (TypeExp *e) final override
3006 error_at (make_location_t (e->loc), "type %qs is not an expression",
3007 e->toChars ());
3008 this->result_ = error_mark_node;
3013 /* Main entry point for ExprVisitor interface to generate code for
3014 the Expression AST class E. If CONST_P is true, then E is a
3015 constant expression. If LITERAL_P is true, then E is a value used
3016 in the initialization of another literal. */
3018 tree
3019 build_expr (Expression *e, bool const_p, bool literal_p)
3021 ExprVisitor v = ExprVisitor (const_p, literal_p);
3022 location_t saved_location = input_location;
3024 input_location = make_location_t (e->loc);
3025 e->accept (&v);
3026 tree expr = v.result ();
3027 input_location = saved_location;
3029 /* Check if initializer expression is valid constant. */
3030 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3032 error_at (make_location_t (e->loc), "non-constant expression %qs",
3033 e->toChars ());
3034 return error_mark_node;
3037 return expr;
3040 /* Same as build_expr, but also calls destructors on any temporaries. */
3042 tree
3043 build_expr_dtor (Expression *e)
3045 /* Codegen can be improved by determining if no exceptions can be thrown
3046 between the ctor and dtor, and eliminating the ctor and dtor. */
3047 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3048 tree result = build_expr (e);
3050 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3052 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3053 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3056 return result;
3059 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3061 tree
3062 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3064 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3065 tree result = build_expr (e);
3067 /* Convert for initializing the DECL_RESULT. */
3068 if (tf->isref ())
3070 /* If we are returning a reference, take the address. */
3071 result = convert_expr (result, e->type, type);
3072 result = build_address (result);
3074 else
3075 result = convert_for_rvalue (result, e->type, type);
3077 /* The decl to store the return expression. */
3078 tree decl = DECL_RESULT (cfun->decl);
3080 /* Split comma expressions, so that the result is returned directly. */
3081 tree expr = stabilize_expr (&result);
3082 result = build_assign (INIT_EXPR, decl, result);
3083 result = compound_expr (expr, return_expr (result));
3085 /* May nest the return expression inside the try/finally expression. */
3086 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3088 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3089 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3092 return result;