d: Clarify comment for generating static array assignment with literal.
[official-gcc.git] / gcc / d / expr.cc
blob76c1e613e77fcb785a1f1b65f8ffc13c2483b279
1 /* expr.cc -- Lower D frontend expressions to GCC trees.
2 Copyright (C) 2015-2021 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/expression.h"
26 #include "dmd/identifier.h"
27 #include "dmd/init.h"
28 #include "dmd/module.h"
29 #include "dmd/mtype.h"
30 #include "dmd/template.h"
32 #include "tree.h"
33 #include "fold-const.h"
34 #include "diagnostic.h"
35 #include "langhooks.h"
36 #include "tm.h"
37 #include "function.h"
38 #include "toplev.h"
39 #include "varasm.h"
40 #include "predict.h"
41 #include "stor-layout.h"
43 #include "d-tree.h"
46 /* Determine if type T is a struct that has a postblit. */
48 static bool
49 needs_postblit (Type *t)
51 t = t->baseElemOf ();
53 if (TypeStruct *ts = t->isTypeStruct ())
55 if (ts->sym->postblit)
56 return true;
59 return false;
62 /* Determine if type T is a struct that has a destructor. */
64 static bool
65 needs_dtor (Type *t)
67 t = t->baseElemOf ();
69 if (TypeStruct *ts = t->isTypeStruct ())
71 if (ts->sym->dtor)
72 return true;
75 return false;
78 /* Determine if expression E is a suitable lvalue. */
80 static bool
81 lvalue_p (Expression *e)
83 SliceExp *se = e->isSliceExp ();
84 if (se != NULL && se->e1->isLvalue ())
85 return true;
87 CastExp *ce = e->isCastExp ();
88 if (ce != NULL && ce->e1->isLvalue ())
89 return true;
91 return (e->op != TOKslice && e->isLvalue ());
94 /* Build an expression of code CODE, data type TYPE, and operands ARG0 and
95 ARG1. Perform relevant conversions needed for correct code operations. */
97 static tree
98 binary_op (tree_code code, tree type, tree arg0, tree arg1)
100 tree t0 = TREE_TYPE (arg0);
101 tree t1 = TREE_TYPE (arg1);
102 tree ret = NULL_TREE;
104 bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1);
106 /* Deal with float mod expressions immediately. */
107 if (code == FLOAT_MOD_EXPR)
108 return build_float_modulus (type, arg0, arg1);
110 if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
111 return build_nop (type, build_offset_op (code, arg0, arg1));
113 if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
114 return build_nop (type, build_offset_op (code, arg1, arg0));
116 if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
118 gcc_assert (code == MINUS_EXPR);
119 tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
121 /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
122 pointers. If some platform cannot provide that, or has a larger
123 ptrdiff_type to support differences larger than half the address
124 space, cast the pointers to some larger integer type and do the
125 computations in that type. */
126 if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
127 ret = fold_build2 (MINUS_EXPR, ptrtype,
128 d_convert (ptrtype, arg0),
129 d_convert (ptrtype, arg1));
130 else
131 ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
133 else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp))
135 tree inttype = (unsignedp)
136 ? d_unsigned_type (type) : d_signed_type (type);
137 ret = fold_build2 (code, inttype, arg0, arg1);
139 else
141 /* If the operation needs excess precision. */
142 tree eptype = excess_precision_type (type);
143 if (eptype != NULL_TREE)
145 arg0 = d_convert (eptype, arg0);
146 arg1 = d_convert (eptype, arg1);
148 else
150 /* Front-end does not do this conversion and GCC does not
151 always do it right. */
152 if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
153 arg1 = d_convert (t0, arg1);
154 else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
155 arg0 = d_convert (t1, arg0);
157 eptype = type;
160 ret = build2 (code, eptype, arg0, arg1);
163 return d_convert (type, ret);
166 /* Build a binary expression of code CODE, assigning the result into E1. */
168 static tree
169 binop_assignment (tree_code code, Expression *e1, Expression *e2)
171 /* Skip casts for lhs assignment. */
172 Expression *e1b = e1;
173 while (e1b->op == TOKcast)
175 CastExp *ce = e1b->isCastExp ();
176 gcc_assert (same_type_p (ce->type, ce->to));
177 e1b = ce->e1;
180 /* Stabilize LHS for assignment. */
181 tree lhs = build_expr (e1b);
182 tree lexpr = stabilize_expr (&lhs);
184 /* The LHS expression could be an assignment, to which its operation gets
185 lost during gimplification. */
186 if (TREE_CODE (lhs) == MODIFY_EXPR)
188 /* If LHS has side effects, call stabilize_reference on it, so it can
189 be evaluated multiple times. */
190 if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
191 lhs = build_assign (MODIFY_EXPR,
192 stabilize_reference (TREE_OPERAND (lhs, 0)),
193 TREE_OPERAND (lhs, 1));
195 lexpr = compound_expr (lexpr, lhs);
196 lhs = TREE_OPERAND (lhs, 0);
199 lhs = stabilize_reference (lhs);
201 /* Save RHS, to ensure that the expression is evaluated before LHS. */
202 tree rhs = build_expr (e2);
203 tree rexpr = d_save_expr (rhs);
205 rhs = binary_op (code, build_ctype (e1->type),
206 convert_expr (lhs, e1b->type, e1->type), rexpr);
207 if (TREE_SIDE_EFFECTS (rhs))
208 rhs = compound_expr (rexpr, rhs);
210 tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
211 return compound_expr (lexpr, expr);
214 /* Implements the visitor interface to build the GCC trees of all Expression
215 AST classes emitted from the D Front-end.
216 All visit methods accept one parameter E, which holds the frontend AST
217 of the expression to compile. They also don't return any value, instead
218 generated code is cached in RESULT_ and returned from the caller. */
220 class ExprVisitor : public Visitor
222 using Visitor::visit;
224 tree result_;
225 bool constp_;
226 bool literalp_;
228 public:
229 ExprVisitor (bool constp, bool literalp)
231 this->result_ = NULL_TREE;
232 this->constp_ = constp;
233 this->literalp_ = literalp;
236 tree result (void)
238 return this->result_;
241 /* Visitor interfaces, each Expression class should have
242 overridden the default. */
244 void visit (Expression *)
246 gcc_unreachable ();
249 /* Build a conditional expression. If either the second or third
250 expression is void, then the resulting type is void. Otherwise
251 they are implicitly converted to a common type. */
253 void visit (CondExp *e)
255 tree cond = convert_for_condition (build_expr (e->econd),
256 e->econd->type);
257 tree t1 = build_expr (e->e1);
258 tree t2 = build_expr (e->e2);
260 if (e->type->ty != Tvoid)
262 t1 = convert_expr (t1, e->e1->type, e->type);
263 t2 = convert_expr (t2, e->e2->type, e->type);
266 this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
269 /* Build an identity comparison expression. Operands go through the
270 usual conversions to bring them to a common type before comparison.
271 The result type is bool. */
273 void visit (IdentityExp *e)
275 tree_code code = (e->op == TOKidentity) ? EQ_EXPR : NE_EXPR;
276 Type *tb1 = e->e1->type->toBasetype ();
277 Type *tb2 = e->e2->type->toBasetype ();
279 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
280 && (tb2->ty == Tsarray || tb2->ty == Tarray))
282 /* For static and dynamic arrays, identity is defined as referring to
283 the same array elements and the same number of elements. */
284 tree t1 = d_array_convert (e->e1);
285 tree t2 = d_array_convert (e->e2);
286 this->result_ = d_convert (build_ctype (e->type),
287 build_boolop (code, t1, t2));
289 else if (tb1->isfloating () && tb1->ty != Tvector)
291 /* For floating-point values, identity is defined as the bits in the
292 operands being identical. */
293 tree t1 = d_save_expr (build_expr (e->e1));
294 tree t2 = d_save_expr (build_expr (e->e2));
296 if (!tb1->iscomplex ())
297 this->result_ = build_float_identity (code, t1, t2);
298 else
300 /* Compare the real and imaginary parts separately. */
301 tree req = build_float_identity (code, real_part (t1),
302 real_part (t2));
303 tree ieq = build_float_identity (code, imaginary_part (t1),
304 imaginary_part (t2));
306 if (code == EQ_EXPR)
307 this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
308 else
309 this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
312 else if (TypeStruct *ts = tb1->isTypeStruct ())
314 /* For struct objects, identity is defined as bits in operands being
315 identical also. Alignment holes in structs are ignored. */
316 tree t1 = build_expr (e->e1);
317 tree t2 = build_expr (e->e2);
319 gcc_assert (same_type_p (tb1, tb2));
321 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
323 else
325 /* For operands of other types, identity is defined as being the
326 same as equality expressions. */
327 tree t1 = build_expr (e->e1);
328 tree t2 = build_expr (e->e2);
329 this->result_ = d_convert (build_ctype (e->type),
330 build_boolop (code, t1, t2));
334 /* Build an equality expression, which compare the two operands for either
335 equality or inequality. Operands go through the usual conversions to bring
336 them to a common type before comparison. The result type is bool. */
338 void visit (EqualExp *e)
340 Type *tb1 = e->e1->type->toBasetype ();
341 Type *tb2 = e->e2->type->toBasetype ();
342 tree_code code = (e->op == TOKequal) ? EQ_EXPR : NE_EXPR;
344 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
345 && (tb2->ty == Tsarray || tb2->ty == Tarray))
347 /* For static and dynamic arrays, equality is defined as the lengths of
348 the arrays matching, and all the elements are equal. */
349 Type *t1elem = tb1->nextOf ()->toBasetype ();
350 Type *t2elem = tb1->nextOf ()->toBasetype ();
352 /* Check if comparisons of arrays can be optimized using memcmp.
353 This will inline EQ expressions as:
354 e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
355 Or when generating a NE expression:
356 e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */
357 if ((t1elem->isintegral () || t1elem->ty == Tvoid
358 || (t1elem->ty == Tstruct && !t1elem->isTypeStruct ()->sym->xeq))
359 && t1elem->ty == t2elem->ty)
361 tree t1 = d_array_convert (e->e1);
362 tree t2 = d_array_convert (e->e2);
363 tree result;
365 /* Make temporaries to prevent multiple evaluations. */
366 tree t1saved = d_save_expr (t1);
367 tree t2saved = d_save_expr (t2);
369 /* Length of arrays, for comparisons done before calling memcmp. */
370 tree t1len = d_array_length (t1saved);
371 tree t2len = d_array_length (t2saved);
373 /* Reference to array data. */
374 tree t1ptr = d_array_ptr (t1saved);
375 tree t2ptr = d_array_ptr (t2saved);
377 /* Compare arrays using memcmp if possible, otherwise for structs,
378 each field is compared inline. */
379 if (t1elem->ty != Tstruct
380 || identity_compare_p (t1elem->isTypeStruct ()->sym))
382 tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
384 result = build_memcmp_call (t1ptr, t2ptr, size);
385 result = build_boolop (code, result, integer_zero_node);
387 else
389 StructDeclaration *sd = t1elem->isTypeStruct ()->sym;
391 result = build_array_struct_comparison (code, sd, t1len,
392 t1ptr, t2ptr);
395 /* Check array length first before passing to memcmp.
396 For equality expressions, this becomes:
397 (e1.length == 0 || memcmp);
398 Otherwise for inequality:
399 (e1.length != 0 && memcmp); */
400 tree tsizecmp = build_boolop (code, t1len, size_zero_node);
401 if (e->op == TOKequal)
402 result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
403 else
404 result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
406 /* Finally, check if lengths of both arrays match if dynamic.
407 The frontend should have already guaranteed that static arrays
408 have same size. */
409 if (tb1->ty == Tsarray && tb2->ty == Tsarray)
410 gcc_assert (tb1->size () == tb2->size ());
411 else
413 tree tlencmp = build_boolop (code, t1len, t2len);
414 if (e->op == TOKequal)
415 result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
416 else
417 result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
420 /* Ensure left-to-right order of evaluation. */
421 if (TREE_SIDE_EFFECTS (t2))
422 result = compound_expr (t2saved, result);
424 if (TREE_SIDE_EFFECTS (t1))
425 result = compound_expr (t1saved, result);
427 this->result_ = result;
429 else
431 /* Use _adEq2() to compare each element. */
432 Type *t1array = t1elem->arrayOf ();
433 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
434 d_array_convert (e->e1),
435 d_array_convert (e->e2),
436 build_typeinfo (e->loc, t1array));
438 if (e->op == TOKnotequal)
439 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
441 this->result_ = result;
444 else if (TypeStruct *ts = tb1->isTypeStruct ())
446 /* Equality for struct objects means the logical product of all
447 equality results of the corresponding object fields. */
448 tree t1 = build_expr (e->e1);
449 tree t2 = build_expr (e->e2);
451 gcc_assert (same_type_p (tb1, tb2));
453 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
455 else if (tb1->ty == Taarray && tb2->ty == Taarray)
457 /* Use _aaEqual() for associative arrays. */
458 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
459 build_typeinfo (e->loc, tb1),
460 build_expr (e->e1),
461 build_expr (e->e2));
463 if (e->op == TOKnotequal)
464 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
466 this->result_ = result;
468 else
470 /* For operands of other types, equality is defined as the bit pattern
471 of the type matches exactly. */
472 tree t1 = build_expr (e->e1);
473 tree t2 = build_expr (e->e2);
475 this->result_ = d_convert (build_ctype (e->type),
476 build_boolop (code, t1, t2));
480 /* Build an `in' expression. This is a condition to see if an element
481 exists in an associative array. The result is a pointer to the
482 element, or null if false. */
484 void visit (InExp *e)
486 Type *tb2 = e->e2->type->toBasetype ();
487 Type *tkey = tb2->isTypeAArray ()->index->toBasetype ();
488 tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
490 /* Build a call to _aaInX(). */
491 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
492 build_expr (e->e2),
493 build_typeinfo (e->loc, tkey),
494 build_address (key));
497 /* Build a relational expression. The result type is bool. */
499 void visit (CmpExp *e)
501 Type *tb1 = e->e1->type->toBasetype ();
502 Type *tb2 = e->e2->type->toBasetype ();
504 tree result;
505 tree_code code;
507 switch (e->op)
509 case TOKle:
510 code = LE_EXPR;
511 break;
513 case TOKlt:
514 code = LT_EXPR;
515 break;
517 case TOKge:
518 code = GE_EXPR;
519 break;
521 case TOKgt:
522 code = GT_EXPR;
523 break;
525 default:
526 gcc_unreachable ();
529 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
530 && (tb2->ty == Tsarray || tb2->ty == Tarray))
532 /* For static and dynamic arrays, the result of the relational op is
533 the result of the operator applied to the first non-equal element
534 of the array. If two arrays compare equal, but are of different
535 lengths, the shorter array compares as less than the longer. */
536 Type *telem = tb1->nextOf ()->toBasetype ();
538 tree call = build_libcall (LIBCALL_ADCMP2, Type::tint32, 3,
539 d_array_convert (e->e1),
540 d_array_convert (e->e2),
541 build_typeinfo (e->loc, telem->arrayOf ()));
542 result = build_boolop (code, call, integer_zero_node);
544 this->result_ = d_convert (build_ctype (e->type), result);
545 return;
548 /* Simple comparison. */
549 result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
550 this->result_ = d_convert (build_ctype (e->type), result);
553 /* Build a logical `and if' or `or if' expression. If the right operand
554 expression is void, then the resulting type is void. Otherwise the
555 result is bool. */
557 void visit (LogicalExp *e)
559 tree_code code = (e->op == TOKandand) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
561 if (e->e2->type->toBasetype ()->ty != Tvoid)
563 tree t1 = build_expr (e->e1);
564 tree t2 = build_expr (e->e2);
566 t1 = convert_for_condition (t1, e->e1->type);
567 t2 = convert_for_condition (t2, e->e2->type);
569 this->result_ = d_convert (build_ctype (e->type),
570 build_boolop (code, t1, t2));
572 else
574 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
575 tree t2 = build_expr_dtor (e->e2);
577 /* Invert condition for logical or if expression. */
578 if (e->op == TOKoror)
579 t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);
581 this->result_ = build_condition (build_ctype (e->type),
582 t1, t2, void_node);
586 /* Build a binary operand expression. Operands go through usual arithmetic
587 conversions to bring them to a common type before evaluating. */
589 void visit (BinExp *e)
591 tree_code code;
593 switch (e->op)
595 case TOKadd:
596 case TOKmin:
597 if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
598 || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
600 /* If the result is complex, then we can shortcut binary_op.
601 Frontend should have already validated types and sizes. */
602 tree t1 = build_expr (e->e1);
603 tree t2 = build_expr (e->e2);
605 if (e->op == TOKmin)
606 t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
608 if (e->e1->type->isreal ())
609 this->result_ = complex_expr (build_ctype (e->type), t1, t2);
610 else
611 this->result_ = complex_expr (build_ctype (e->type), t2, t1);
613 return;
615 else
616 code = (e->op == TOKadd)
617 ? PLUS_EXPR : MINUS_EXPR;
618 break;
620 case TOKmul:
621 code = MULT_EXPR;
622 break;
624 case TOKdiv:
625 /* Determine if the div expression is a lowered pointer diff operation.
626 The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */
627 if (MinExp *me = e->e1->isMinExp ())
629 if (me->e1->type->ty == Tpointer && me->e2->type->ty == Tpointer
630 && e->e2->op == TOKint64)
632 code = EXACT_DIV_EXPR;
633 break;
637 code = e->e1->type->isintegral ()
638 ? TRUNC_DIV_EXPR : RDIV_EXPR;
639 break;
641 case TOKmod:
642 code = e->e1->type->isfloating ()
643 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
644 break;
646 case TOKand:
647 code = BIT_AND_EXPR;
648 break;
650 case TOKor:
651 code = BIT_IOR_EXPR;
652 break;
654 case TOKxor:
655 code = BIT_XOR_EXPR;
656 break;
658 case TOKshl:
659 code = LSHIFT_EXPR;
660 break;
662 case TOKshr:
663 code = RSHIFT_EXPR;
664 break;
666 case TOKushr:
667 code = UNSIGNED_RSHIFT_EXPR;
668 break;
670 default:
671 gcc_unreachable ();
674 this->result_ = binary_op (code, build_ctype (e->type),
675 build_expr (e->e1), build_expr (e->e2));
679 /* Build a concat expression, which concatenates two or more arrays of the
680 same type, producing a dynamic array with the result. If one operand
681 is an element type, that element is converted to an array of length 1. */
683 void visit (CatExp *e)
685 Type *tb1 = e->e1->type->toBasetype ();
686 Type *tb2 = e->e2->type->toBasetype ();
687 Type *etype;
689 if (tb1->ty == Tarray || tb1->ty == Tsarray)
690 etype = tb1->nextOf ();
691 else
692 etype = tb2->nextOf ();
694 tree result;
696 if (e->e1->op == TOKcat)
698 /* Flatten multiple concatenations to an array.
699 So the expression ((a ~ b) ~ c) becomes [a, b, c] */
700 int ndims = 2;
702 for (Expression *ex = e->e1; ex->op == TOKcat;)
704 if (ex->op == TOKcat)
706 ex = ex->isCatExp ()->e1;
707 ndims++;
711 /* Store all concatenation args to a temporary byte[][ndims] array. */
712 Type *targselem = Type::tint8->arrayOf ();
713 tree var = build_local_temp (make_array_type (targselem, ndims));
715 /* Loop through each concatenation from right to left. */
716 vec <constructor_elt, va_gc> *elms = NULL;
717 CatExp *ce = e;
718 int dim = ndims - 1;
720 for (Expression *oe = ce->e2; oe != NULL;
721 (ce->e1->op != TOKcat
722 ? (oe = ce->e1)
723 : (ce = ce->e1->isCatExp (), oe = ce->e2)))
725 tree arg = d_array_convert (etype, oe);
726 tree index = size_int (dim);
727 CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));
729 /* Finished pushing all arrays. */
730 if (oe == ce->e1)
731 break;
733 dim -= 1;
736 /* Check there is no logic bug in constructing byte[][] of arrays. */
737 gcc_assert (dim == 0);
738 tree init = build_constructor (TREE_TYPE (var), elms);
739 var = compound_expr (modify_expr (var, init), var);
741 tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
742 size_int (ndims), build_address (var));
744 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
745 build_typeinfo (e->loc, e->type), arrs);
747 else
749 /* Handle single concatenation (a ~ b). */
750 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
751 build_typeinfo (e->loc, e->type),
752 d_array_convert (etype, e->e1),
753 d_array_convert (etype, e->e2));
756 this->result_ = result;
759 /* Build an assignment operator expression. The right operand is implicitly
760 converted to the type of the left operand, and assigned to it. */
762 void visit (BinAssignExp *e)
764 tree_code code;
765 Expression *e1b = e->e1;
767 switch (e->op)
769 case TOKaddass:
770 code = PLUS_EXPR;
771 break;
773 case TOKminass:
774 code = MINUS_EXPR;
775 break;
777 case TOKmulass:
778 code = MULT_EXPR;
779 break;
781 case TOKdivass:
782 code = e->e1->type->isintegral ()
783 ? TRUNC_DIV_EXPR : RDIV_EXPR;
784 break;
786 case TOKmodass:
787 code = e->e1->type->isfloating ()
788 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
789 break;
791 case TOKandass:
792 code = BIT_AND_EXPR;
793 break;
795 case TOKorass:
796 code = BIT_IOR_EXPR;
797 break;
799 case TOKxorass:
800 code = BIT_XOR_EXPR;
801 break;
803 case TOKpowass:
804 gcc_unreachable ();
806 case TOKshlass:
807 code = LSHIFT_EXPR;
808 break;
810 case TOKshrass:
811 case TOKushrass:
812 /* Use the original lhs type before it was promoted. The left operand
813 of `>>>=' does not undergo integral promotions before shifting.
814 Strip off casts just incase anyway. */
815 while (e1b->op == TOKcast)
817 CastExp *ce = e1b->isCastExp ();
818 gcc_assert (same_type_p (ce->type, ce->to));
819 e1b = ce->e1;
821 code = (e->op == TOKshrass) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
822 break;
824 default:
825 gcc_unreachable ();
828 tree exp = binop_assignment (code, e1b, e->e2);
829 this->result_ = convert_expr (exp, e1b->type, e->type);
832 /* Build a concat assignment expression. The right operand is appended
833 to the left operand. */
835 void visit (CatAssignExp *e)
837 Type *tb1 = e->e1->type->toBasetype ();
838 Type *tb2 = e->e2->type->toBasetype ();
839 Type *etype = tb1->nextOf ()->toBasetype ();
841 /* Save the address of `e1', so it can be evaluated first.
842 As all D run-time library functions for concat assignments update `e1'
843 in-place and then return its value, the saved address can also be used as
844 the result of this expression as well. */
845 tree lhs = build_expr (e->e1);
846 tree lexpr = stabilize_expr (&lhs);
847 tree ptr = d_save_expr (build_address (lhs));
848 tree result = NULL_TREE;
850 if (tb1->ty == Tarray && tb2->ty == Tdchar
851 && (etype->ty == Tchar || etype->ty == Twchar))
853 /* Append a dchar to a char[] or wchar[]:
854 The assignment is handled by the D run-time library, so only
855 need to call `_d_arrayappend[cw]d(&e1, e2)' */
856 libcall_fn libcall = (etype->ty == Tchar)
857 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
859 result = build_libcall (libcall, e->type, 2,
860 ptr, build_expr (e->e2));
862 else
864 gcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray);
866 if ((tb2->ty == Tarray || tb2->ty == Tsarray)
867 && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
869 /* Append an array to another array:
870 The assignment is handled by the D run-time library, so only
871 need to call `_d_arrayappendT(ti, &e1, e2)' */
872 result = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
873 build_typeinfo (e->loc, e->type),
874 ptr, d_array_convert (e->e2));
876 else if (same_type_p (etype, tb2))
878 /* Append an element to an array:
879 The assignment is generated inline, so need to handle temporaries
880 here, and ensure that they are evaluated in the correct order.
882 The generated code should end up being equivalent to:
883 _d_arrayappendcTX(ti, &e1, 1)[e1.length - 1] = e2
885 tree callexp = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
886 build_typeinfo (e->loc, e->type),
887 ptr, size_one_node);
888 callexp = d_save_expr (callexp);
890 /* Assign e2 to last element. */
891 tree offexp = d_array_length (callexp);
892 offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
893 offexp, size_one_node);
895 tree ptrexp = d_array_ptr (callexp);
896 ptrexp = void_okay_p (ptrexp);
897 ptrexp = build_array_index (ptrexp, offexp);
899 /* Evaluate expression before appending. */
900 tree rhs = build_expr (e->e2);
901 tree rexpr = stabilize_expr (&rhs);
903 if (TREE_CODE (rhs) == CALL_EXPR)
904 rhs = force_target_expr (rhs);
906 result = modify_expr (build_deref (ptrexp), rhs);
907 result = compound_expr (rexpr, result);
909 else
910 gcc_unreachable ();
913 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
914 result = compound_expr (compound_expr (lexpr, ptr), result);
915 this->result_ = compound_expr (result, build_deref (ptr));
918 /* Build an assignment expression. The right operand is implicitly
919 converted to the type of the left operand, and assigned to it. */
921 void visit (AssignExp *e)
923 /* First, handle special assignment semantics. */
925 /* Look for array.length = n; */
926 if (e->e1->op == TOKarraylength)
928 /* Assignment to an array's length property; resize the array. */
929 ArrayLengthExp *ale = e->e1->isArrayLengthExp ();
930 tree newlength = convert_expr (build_expr (e->e2), e->e2->type,
931 Type::tsize_t);
932 tree ptr = build_address (build_expr (ale->e1));
934 /* Don't want the basetype for the element type. */
935 Type *etype = ale->e1->type->toBasetype ()->nextOf ();
936 libcall_fn libcall = etype->isZeroInit ()
937 ? LIBCALL_ARRAYSETLENGTHT : LIBCALL_ARRAYSETLENGTHIT;
939 tree result = build_libcall (libcall, ale->e1->type, 3,
940 build_typeinfo (ale->loc, ale->e1->type),
941 newlength, ptr);
943 this->result_ = d_array_length (result);
944 return;
947 /* Look for array[] = n; */
948 if (e->e1->op == TOKslice)
950 SliceExp *se = e->e1->isSliceExp ();
951 Type *stype = se->e1->type->toBasetype ();
952 Type *etype = stype->nextOf ()->toBasetype ();
954 /* Determine if we need to run postblit or dtor. */
955 bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
956 bool destructor = needs_dtor (etype);
958 if (e->memset & blockAssign)
960 /* Set a range of elements to one value. */
961 tree t1 = d_save_expr (build_expr (e->e1));
962 tree t2 = build_expr (e->e2);
963 tree result;
965 if ((postblit || destructor) && e->op != TOKblit)
967 libcall_fn libcall = (e->op == TOKconstruct)
968 ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN;
969 /* So we can call postblits on const/immutable objects. */
970 Type *tm = etype->unSharedOf ()->mutableOf ();
971 tree ti = build_typeinfo (e->loc, tm);
973 tree result = build_libcall (libcall, Type::tvoid, 4,
974 d_array_ptr (t1),
975 build_address (t2),
976 d_array_length (t1), ti);
977 this->result_ = compound_expr (result, t1);
978 return;
981 if (integer_zerop (t2))
983 tree size = size_mult_expr (d_array_length (t1),
984 size_int (etype->size ()));
985 result = build_memset_call (d_array_ptr (t1), size);
987 else
988 result = build_array_set (d_array_ptr (t1),
989 d_array_length (t1), t2);
991 this->result_ = compound_expr (result, t1);
993 else
995 /* Perform a memcpy operation. */
996 gcc_assert (e->e2->type->ty != Tpointer);
998 if (!postblit && !destructor)
1000 tree t1 = d_save_expr (d_array_convert (e->e1));
1001 tree t2 = d_save_expr (d_array_convert (e->e2));
1003 /* References to array data. */
1004 tree t1ptr = d_array_ptr (t1);
1005 tree t1len = d_array_length (t1);
1006 tree t2ptr = d_array_ptr (t2);
1008 /* Generate: memcpy(to, from, size) */
1009 tree size = size_mult_expr (t1len, size_int (etype->size ()));
1010 tree result = build_memcpy_call (t1ptr, t2ptr, size);
1012 /* Insert check that array lengths match and do not overlap. */
1013 if (array_bounds_check ())
1015 /* tlencmp = (t1len == t2len) */
1016 tree t2len = d_array_length (t2);
1017 tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len);
1019 /* toverlap = (t1ptr + size <= t2ptr
1020 || t2ptr + size <= t1ptr) */
1021 tree t1ptrcmp = build_boolop (LE_EXPR,
1022 build_offset (t1ptr, size),
1023 t2ptr);
1024 tree t2ptrcmp = build_boolop (LE_EXPR,
1025 build_offset (t2ptr, size),
1026 t1ptr);
1027 tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp,
1028 t2ptrcmp);
1030 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */
1031 tree tassert = build_array_bounds_call (e->loc);
1032 tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR,
1033 tlencmp, toverlap);
1035 result = build_condition (void_type_node, tboundscheck,
1036 result, tassert);
1039 this->result_ = compound_expr (result, t1);
1041 else if ((postblit || destructor) && e->op != TOKblit)
1043 /* Generate: _d_arrayassign(ti, from, to)
1044 or: _d_arrayctor(ti, from, to) */
1045 libcall_fn libcall = (e->op == TOKconstruct)
1046 ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN;
1048 this->result_ = build_libcall (libcall, e->type, 3,
1049 build_typeinfo (e->loc, etype),
1050 d_array_convert (e->e2),
1051 d_array_convert (e->e1));
1053 else
1055 /* Generate: _d_arraycopy() */
1056 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
1057 size_int (etype->size ()),
1058 d_array_convert (e->e2),
1059 d_array_convert (e->e1));
1063 return;
1066 /* Look for reference initializations. */
1067 if (e->memset & referenceInit)
1069 gcc_assert (e->op == TOKconstruct || e->op == TOKblit);
1070 gcc_assert (e->e1->op == TOKvar);
1072 Declaration *decl = e->e1->isVarExp ()->var;
1073 if (decl->storage_class & (STCout | STCref))
1075 tree t2 = convert_for_assignment (build_expr (e->e2),
1076 e->e2->type, e->e1->type);
1077 tree t1 = build_expr (e->e1);
1078 /* Want reference to lhs, not indirect ref. */
1079 t1 = TREE_OPERAND (t1, 0);
1080 t2 = build_address (t2);
1082 this->result_ = indirect_ref (build_ctype (e->type),
1083 build_assign (INIT_EXPR, t1, t2));
1084 return;
1088 /* Other types of assignments that may require post construction. */
1089 Type *tb1 = e->e1->type->toBasetype ();
1090 tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR;
1092 /* Look for struct assignment. */
1093 if (tb1->ty == Tstruct)
1095 tree t1 = build_expr (e->e1);
1096 tree t2 = convert_for_assignment (build_expr (e->e2, false, true),
1097 e->e2->type, e->e1->type);
1098 StructDeclaration *sd = tb1->isTypeStruct ()->sym;
1100 /* Look for struct = 0. */
1101 if (e->e2->op == TOKint64)
1103 /* Use memset to fill struct. */
1104 gcc_assert (e->op == TOKblit);
1105 tree result = build_memset_call (t1);
1107 /* Maybe set-up hidden pointer to outer scope context. */
1108 if (sd->isNested ())
1110 tree field = get_symbol_decl (sd->vthis);
1111 tree value = build_vthis (sd);
1113 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1114 result = compound_expr (result, vthis_exp);
1117 this->result_ = compound_expr (result, t1);
1119 else
1121 /* Simple struct literal assignment. */
1122 tree init = NULL_TREE;
1124 /* Fill any alignment holes in the struct using memset. */
1125 if ((e->op == TOKconstruct
1126 || (e->e2->op == TOKstructliteral && e->op == TOKblit))
1127 && (sd->isUnionDeclaration () || !identity_compare_p (sd)))
1129 t1 = stabilize_reference (t1);
1130 init = build_memset_call (t1);
1133 /* Elide generating assignment if init is all zeroes. */
1134 if (init != NULL_TREE && initializer_zerop (t2))
1135 this->result_ = compound_expr (init, t1);
1136 else
1138 tree result = build_assign (modifycode, t1, t2);
1139 this->result_ = compound_expr (init, result);
1143 return;
1146 /* Look for static array assignment. */
1147 if (tb1->ty == Tsarray)
1149 /* Look for array = 0. */
1150 if (e->e2->op == TOKint64)
1152 /* Use memset to fill the array. */
1153 gcc_assert (e->op == TOKblit);
1154 this->result_ = build_memset_call (build_expr (e->e1));
1155 return;
1158 Type *etype = tb1->nextOf ();
1159 gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);
1161 /* Determine if we need to run postblit. */
1162 bool postblit = needs_postblit (etype);
1163 bool destructor = needs_dtor (etype);
1164 bool lvalue = lvalue_p (e->e2);
1166 /* Optimize static array assignment with array literal. Even if the
1167 elements in rhs are all rvalues and don't have to call postblits,
1168 this assignment should call dtors on old assigned elements. */
1169 if ((!postblit && !destructor)
1170 || (e->op == TOKconstruct && e->e2->op == TOKarrayliteral)
1171 || (e->op == TOKconstruct && !lvalue && postblit)
1172 || (e->op == TOKblit || e->e1->type->size () == 0))
1174 tree t1 = build_expr (e->e1);
1175 tree t2 = convert_for_assignment (build_expr (e->e2),
1176 e->e2->type, e->e1->type);
1178 this->result_ = build_assign (modifycode, t1, t2);
1179 return;
1182 Type *arrtype = (e->type->ty == Tsarray) ? etype->arrayOf () : e->type;
1183 tree result;
1185 if (e->op == TOKconstruct)
1187 /* Generate: _d_arrayctor(ti, from, to) */
1188 result = build_libcall (LIBCALL_ARRAYCTOR, arrtype, 3,
1189 build_typeinfo (e->loc, etype),
1190 d_array_convert (e->e2),
1191 d_array_convert (e->e1));
1193 else
1195 /* Generate: _d_arrayassign_l()
1196 or: _d_arrayassign_r() */
1197 libcall_fn libcall = (lvalue)
1198 ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
1199 tree elembuf = build_local_temp (build_ctype (etype));
1201 result = build_libcall (libcall, arrtype, 4,
1202 build_typeinfo (e->loc, etype),
1203 d_array_convert (e->e2),
1204 d_array_convert (e->e1),
1205 build_address (elembuf));
1208 /* Cast the libcall result back to a static array. */
1209 if (e->type->ty == Tsarray)
1210 result = indirect_ref (build_ctype (e->type),
1211 d_array_ptr (result));
1213 this->result_ = result;
1214 return;
1217 /* Simple assignment. */
1218 tree t1 = build_expr (e->e1);
1219 tree t2 = convert_for_assignment (build_expr (e->e2),
1220 e->e2->type, e->e1->type);
1222 this->result_ = build_assign (modifycode, t1, t2);
1225 /* Build a postfix expression. */
1227 void visit (PostExp *e)
1229 tree result;
1231 if (e->op == TOKplusplus)
1233 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1234 build_expr (e->e1), build_expr (e->e2));
1236 else if (e->op == TOKminusminus)
1238 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1239 build_expr (e->e1), build_expr (e->e2));
1241 else
1242 gcc_unreachable ();
1244 TREE_SIDE_EFFECTS (result) = 1;
1245 this->result_ = result;
1248 /* Build an index expression. */
1250 void visit (IndexExp *e)
1252 Type *tb1 = e->e1->type->toBasetype ();
1254 if (tb1->ty == Taarray)
1256 /* Get the key for the associative array. */
1257 Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
1258 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1259 libcall_fn libcall;
1260 tree tinfo, ptr;
1262 if (e->modifiable)
1264 libcall = LIBCALL_AAGETY;
1265 ptr = build_address (build_expr (e->e1));
1266 tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());
1268 else
1270 libcall = LIBCALL_AAGETRVALUEX;
1271 ptr = build_expr (e->e1);
1272 tinfo = build_typeinfo (e->loc, tkey);
1275 /* Index the associative array. */
1276 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1277 ptr, tinfo,
1278 size_int (tb1->nextOf ()->size ()),
1279 build_address (key));
1281 if (!e->indexIsInBounds && array_bounds_check ())
1283 tree tassert = build_array_bounds_call (e->loc);
1285 result = d_save_expr (result);
1286 result = build_condition (TREE_TYPE (result),
1287 d_truthvalue_conversion (result),
1288 result, tassert);
1291 this->result_ = indirect_ref (build_ctype (e->type), result);
1293 else
1295 /* Get the data pointer and length for static and dynamic arrays. */
1296 tree array = d_save_expr (build_expr (e->e1));
1297 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1299 tree length = NULL_TREE;
1300 if (tb1->ty != Tpointer)
1301 length = get_array_length (array, tb1);
1302 else
1303 gcc_assert (e->lengthVar == NULL);
1305 /* The __dollar variable just becomes a placeholder for the
1306 actual length. */
1307 if (e->lengthVar)
1308 e->lengthVar->csym = length;
1310 /* Generate the index. */
1311 tree index = build_expr (e->e2);
1313 /* If it's a static array and the index is constant, the front end has
1314 already checked the bounds. */
1315 if (tb1->ty != Tpointer && !e->indexIsInBounds)
1316 index = build_bounds_condition (e->e2->loc, index, length, false);
1318 /* Index the .ptr. */
1319 ptr = void_okay_p (ptr);
1320 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1321 build_array_index (ptr, index));
1325 /* Build a comma expression. The type is the type of the right operand. */
1327 void visit (CommaExp *e)
1329 tree t1 = build_expr (e->e1);
1330 tree t2 = build_expr (e->e2);
1331 tree type = e->type ? build_ctype (e->type) : void_type_node;
1333 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1336 /* Build an array length expression. Returns the number of elements
1337 in the array. The result is of type size_t. */
1339 void visit (ArrayLengthExp *e)
1341 if (e->e1->type->toBasetype ()->ty == Tarray)
1342 this->result_ = d_array_length (build_expr (e->e1));
1343 else
1345 /* Static arrays have already been handled by the front-end. */
1346 error ("unexpected type for array length: %qs", e->type->toChars ());
1347 this->result_ = error_mark_node;
1351 /* Build a delegate pointer expression. This will return the frame
1352 pointer value as a type void*. */
1354 void visit (DelegatePtrExp *e)
1356 tree t1 = build_expr (e->e1);
1357 this->result_ = delegate_object (t1);
1360 /* Build a delegate function pointer expression. This will return the
1361 function pointer value as a function type. */
1363 void visit (DelegateFuncptrExp *e)
1365 tree t1 = build_expr (e->e1);
1366 this->result_ = delegate_method (t1);
1369 /* Build a slice expression. */
1371 void visit (SliceExp *e)
1373 Type *tb = e->type->toBasetype ();
1374 Type *tb1 = e->e1->type->toBasetype ();
1375 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray);
1377 /* Use convert-to-dynamic-array code if possible. */
1378 if (!e->lwr)
1380 tree result = build_expr (e->e1);
1381 if (e->e1->type->toBasetype ()->ty == Tsarray)
1382 result = convert_expr (result, e->e1->type, e->type);
1384 this->result_ = result;
1385 return;
1387 else
1388 gcc_assert (e->upr != NULL);
1390 /* Get the data pointer and length for static and dynamic arrays. */
1391 tree array = d_save_expr (build_expr (e->e1));
1392 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1393 tree length = NULL_TREE;
1395 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1396 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1397 if (tb1->ty != Tpointer)
1398 length = get_array_length (array, tb1);
1399 else
1400 gcc_assert (e->lengthVar == NULL);
1402 /* The __dollar variable just becomes a placeholder for the
1403 actual length. */
1404 if (e->lengthVar)
1405 e->lengthVar->csym = length;
1407 /* Generate upper and lower bounds. */
1408 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1409 tree upr_tree = d_save_expr (build_expr (e->upr));
1411 /* If the upper bound has any side effects, then the lower bound should be
1412 copied to a temporary always. */
1413 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1414 lwr_tree = save_expr (lwr_tree);
1416 /* Adjust the .ptr offset. */
1417 if (!integer_zerop (lwr_tree))
1419 tree ptrtype = TREE_TYPE (ptr);
1420 ptr = build_array_index (void_okay_p (ptr), lwr_tree);
1421 ptr = build_nop (ptrtype, ptr);
1423 else
1424 lwr_tree = NULL_TREE;
1426 /* Nothing more to do for static arrays, their bounds checking has been
1427 done at compile-time. */
1428 if (tb->ty == Tsarray)
1430 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1431 return;
1433 else
1434 gcc_assert (tb->ty == Tarray);
1436 /* Generate bounds checking code. */
1437 tree newlength;
1439 if (!e->upperIsInBounds)
1441 if (length)
1443 newlength = build_bounds_condition (e->upr->loc, upr_tree,
1444 length, true);
1446 else
1448 /* Still need to check bounds lwr <= upr for pointers. */
1449 gcc_assert (tb1->ty == Tpointer);
1450 newlength = upr_tree;
1453 else
1454 newlength = upr_tree;
1456 if (lwr_tree)
1458 /* Enforces lwr <= upr. No need to check lwr <= length as
1459 we've already ensured that upr <= length. */
1460 if (!e->lowerIsLessThanUpper)
1462 tree cond = build_bounds_condition (e->lwr->loc, lwr_tree,
1463 upr_tree, true);
1465 /* When bounds checking is off, the index value is
1466 returned directly. */
1467 if (cond != lwr_tree)
1468 newlength = compound_expr (cond, newlength);
1471 /* Need to ensure lwr always gets evaluated first, as it may be a
1472 function call. Generates (lwr, upr) - lwr. */
1473 newlength = fold_build2 (MINUS_EXPR, TREE_TYPE (newlength),
1474 compound_expr (lwr_tree, newlength), lwr_tree);
1477 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1478 this->result_ = compound_expr (array, result);
1481 /* Build a cast expression, which converts the given unary expression to the
1482 type of result. */
1484 void visit (CastExp *e)
1486 Type *ebtype = e->e1->type->toBasetype ();
1487 Type *tbtype = e->to->toBasetype ();
1488 tree result = build_expr (e->e1, this->constp_, this->literalp_);
1490 /* Just evaluate e1 if it has any side effects. */
1491 if (tbtype->ty == Tvoid)
1492 this->result_ = build_nop (build_ctype (tbtype), result);
1493 else
1494 this->result_ = convert_for_rvalue (result, ebtype, tbtype);
1497 /* Build a delete expression. */
1499 void visit (DeleteExp *e)
1501 tree t1 = build_expr (e->e1);
1502 Type *tb1 = e->e1->type->toBasetype ();
1504 if (tb1->ty == Tclass)
1506 /* For class object references, if there is a destructor for that class,
1507 the destructor is called for the object instance. */
1508 libcall_fn libcall;
1510 if (e->e1->op == TOKvar)
1512 VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
1513 if (v && v->onstack)
1515 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1516 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1518 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1519 return;
1523 /* Otherwise, the garbage collector is called to immediately free the
1524 memory allocated for the class instance. */
1525 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1526 ? LIBCALL_DELINTERFACE : LIBCALL_DELCLASS;
1528 t1 = build_address (t1);
1529 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1531 else if (tb1->ty == Tarray)
1533 /* For dynamic arrays, the garbage collector is called to immediately
1534 release the memory. */
1535 Type *telem = tb1->nextOf ()->baseElemOf ();
1536 tree ti = null_pointer_node;
1538 if (TypeStruct *ts = telem->isTypeStruct ())
1540 /* Might need to run destructor on array contents. */
1541 if (ts->sym->dtor)
1542 ti = build_typeinfo (e->loc, tb1->nextOf ());
1545 /* Generate: _delarray_t (&t1, ti); */
1546 this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,
1547 build_address (t1), ti);
1549 else if (tb1->ty == Tpointer)
1551 /* For pointers to a struct instance, if the struct has overloaded
1552 operator delete, then that operator is called. */
1553 t1 = build_address (t1);
1554 Type *tnext = tb1->isTypePointer ()->next->toBasetype ();
1556 if (TypeStruct *ts = tnext->isTypeStruct ())
1558 if (ts->sym->dtor)
1560 tree ti = build_typeinfo (e->loc, tnext);
1561 this->result_ = build_libcall (LIBCALL_DELSTRUCT, Type::tvoid,
1562 2, t1, ti);
1563 return;
1567 /* Otherwise, the garbage collector is called to immediately free the
1568 memory allocated for the pointer. */
1569 this->result_ = build_libcall (LIBCALL_DELMEMORY, Type::tvoid, 1, t1);
1571 else
1573 error ("don%'t know how to delete %qs", e->e1->toChars ());
1574 this->result_ = error_mark_node;
1578 /* Build a remove expression, which removes a particular key from an
1579 associative array. */
1581 void visit (RemoveExp *e)
1583 /* Check that the array is actually an associative array. */
1584 if (e->e1->type->toBasetype ()->ty == Taarray)
1586 Type *tb = e->e1->type->toBasetype ();
1587 Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
1588 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1590 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1591 build_expr (e->e1),
1592 build_typeinfo (e->loc, tkey),
1593 build_address (index));
1595 else
1597 error ("%qs is not an associative array", e->e1->toChars ());
1598 this->result_ = error_mark_node;
1602 /* Build an unary not expression. */
1604 void visit (NotExp *e)
1606 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1607 /* Need to convert to boolean type or this will fail. */
1608 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1610 this->result_ = d_convert (build_ctype (e->type), result);
1613 /* Build a compliment expression, where all the bits in the value are
1614 complemented. Note: unlike in C, the usual integral promotions
1615 are not performed prior to the complement operation. */
1617 void visit (ComExp *e)
1619 TY ty1 = e->e1->type->toBasetype ()->ty;
1620 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1622 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1623 build_expr (e->e1));
1626 /* Build an unary negation expression. */
1628 void visit (NegExp *e)
1630 TY ty1 = e->e1->type->toBasetype ()->ty;
1631 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1633 tree type = build_ctype (e->type);
1634 tree expr = build_expr (e->e1);
1636 /* If the operation needs excess precision. */
1637 tree eptype = excess_precision_type (type);
1638 if (eptype != NULL_TREE)
1639 expr = d_convert (eptype, expr);
1640 else
1641 eptype = type;
1643 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1644 this->result_ = d_convert (type, ret);
1647 /* Build a pointer index expression. */
1649 void visit (PtrExp *e)
1651 Type *tnext = NULL;
1652 size_t offset;
1653 tree result;
1655 if (e->e1->op == TOKadd)
1657 AddExp *ae = e->e1->isAddExp ();
1658 if (ae->e1->op == TOKaddress
1659 && ae->e2->isConst () && ae->e2->type->isintegral ())
1661 Expression *ex = ae->e1->isAddrExp ()->e1;
1662 tnext = ex->type->toBasetype ();
1663 result = build_expr (ex);
1664 offset = ae->e2->toUInteger ();
1667 else if (e->e1->op == TOKsymoff)
1669 SymOffExp *se = e->e1->isSymOffExp ();
1670 if (!declaration_reference_p (se->var))
1672 tnext = se->var->type->toBasetype ();
1673 result = get_decl_tree (se->var);
1674 offset = se->offset;
1678 /* Produce better code by converting *(#record + n) to
1679 COMPONENT_REFERENCE. Otherwise, the variable will always be
1680 allocated in memory because its address is taken. */
1681 if (tnext && tnext->ty == Tstruct)
1683 StructDeclaration *sd = tnext->isTypeStruct ()->sym;
1685 for (size_t i = 0; i < sd->fields.length; i++)
1687 VarDeclaration *field = sd->fields[i];
1689 if (field->offset == offset
1690 && same_type_p (field->type, e->type))
1692 /* Catch errors, backend will ICE otherwise. */
1693 if (error_operand_p (result))
1694 this->result_ = result;
1695 else
1697 result = component_ref (result, get_symbol_decl (field));
1698 this->result_ = result;
1700 return;
1702 else if (field->offset > offset)
1703 break;
1707 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1710 /* Build an unary address expression. */
1712 void visit (AddrExp *e)
1714 tree type = build_ctype (e->type);
1715 tree exp;
1717 /* The frontend optimizer can convert const symbol into a struct literal.
1718 Taking the address of a struct literal is otherwise illegal. */
1719 if (e->e1->op == TOKstructliteral)
1721 StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
1722 gcc_assert (sle != NULL);
1724 /* Build the reference symbol, the decl is built first as the
1725 initializer may have recursive references. */
1726 if (!sle->sym)
1728 sle->sym = build_artificial_decl (build_ctype (sle->type),
1729 NULL_TREE, "S");
1730 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1731 d_pushdecl (sle->sym);
1732 rest_of_decl_compilation (sle->sym, 1, 0);
1735 exp = sle->sym;
1737 else
1738 exp = build_expr (e->e1, this->constp_, this->literalp_);
1740 TREE_CONSTANT (exp) = 0;
1741 this->result_ = d_convert (type, build_address (exp));
1744 /* Build a function call expression. */
1746 void visit (CallExp *e)
1748 Type *tb = e->e1->type->toBasetype ();
1749 Expression *e1b = e->e1;
1751 tree callee = NULL_TREE;
1752 tree object = NULL_TREE;
1753 tree cleanup = NULL_TREE;
1754 tree returnvalue = NULL_TREE;
1755 TypeFunction *tf = NULL;
1757 /* Calls to delegates can sometimes look like this. */
1758 if (e1b->op == TOKcomma)
1760 e1b = e1b->isCommaExp ()->e2;
1761 gcc_assert (e1b->op == TOKvar);
1763 Declaration *var = e1b->isVarExp ()->var;
1764 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1767 if (e1b->op == TOKdotvar && tb->ty != Tdelegate)
1769 DotVarExp *dve = e1b->isDotVarExp ();
1771 /* Don't modify the static initializer for struct literals. */
1772 if (dve->e1->op == TOKstructliteral)
1774 StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
1775 sle->useStaticInit = false;
1778 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1779 if (fd != NULL)
1781 /* Get the correct callee from the DotVarExp object. */
1782 tree fndecl = get_symbol_decl (fd);
1783 AggregateDeclaration *ad = fd->isThis ();
1785 /* Static method; ignore the object instance. */
1786 if (!ad)
1787 callee = build_address (fndecl);
1788 else
1790 tree thisexp = build_expr (dve->e1);
1792 /* When constructing temporaries, if the constructor throws,
1793 then the object is destructed even though it is not a fully
1794 constructed object yet. And so this call will need to be
1795 moved inside the TARGET_EXPR_INITIAL slot. */
1796 if (fd->isCtorDeclaration ()
1797 && TREE_CODE (thisexp) == COMPOUND_EXPR
1798 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1799 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1801 cleanup = TREE_OPERAND (thisexp, 0);
1802 thisexp = TREE_OPERAND (thisexp, 1);
1805 if (TREE_CODE (thisexp) == CONSTRUCTOR)
1806 thisexp = force_target_expr (thisexp);
1808 /* Want reference to `this' object. */
1809 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1810 thisexp = build_address (thisexp);
1812 /* Make the callee a virtual call. */
1813 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1815 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1816 tree thistype = build_ctype (ad->handleType ());
1817 thisexp = build_nop (thistype, d_save_expr (thisexp));
1818 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1820 else
1821 fndecl = build_address (fndecl);
1823 /* C++ constructors return void, even though front-end semantic
1824 treats them as implicitly returning `this'. Set returnvalue
1825 to override the result of this expression. */
1826 if (fd->isCtorDeclaration () && fd->linkage == LINKcpp)
1828 thisexp = d_save_expr (thisexp);
1829 returnvalue = thisexp;
1832 callee = build_method_call (fndecl, thisexp, fd->type);
1837 if (callee == NULL_TREE)
1838 callee = build_expr (e1b);
1840 if (METHOD_CALL_EXPR (callee))
1842 /* This could be a delegate expression (TY == Tdelegate), but not
1843 actually a delegate variable. */
1844 if (e1b->op == TOKdotvar)
1846 /* This gets the true function type, getting the function type
1847 from e1->type can sometimes be incorrect, such as when calling
1848 a `ref' return function. */
1849 tf = get_function_type (e1b->isDotVarExp ()->var->type);
1851 else
1852 tf = get_function_type (tb);
1854 extract_from_method_call (callee, callee, object);
1856 else if (tb->ty == Tdelegate)
1858 /* Delegate call, extract .object and .funcptr from var. */
1859 callee = d_save_expr (callee);
1860 tf = get_function_type (tb);
1861 object = delegate_object (callee);
1862 callee = delegate_method (callee);
1864 else if (e1b->op == TOKvar)
1866 FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
1867 gcc_assert (fd != NULL);
1868 tf = get_function_type (fd->type);
1870 if (fd->isNested ())
1872 /* Maybe re-evaluate symbol storage treating `fd' as public. */
1873 if (call_by_alias_p (d_function_chain->function, fd))
1874 TREE_PUBLIC (callee) = 1;
1876 object = get_frame_for_symbol (fd);
1878 else if (fd->needThis ())
1880 error_at (make_location_t (e1b->loc),
1881 "need %<this%> to access member %qs", fd->toChars ());
1882 /* Continue compiling... */
1883 object = null_pointer_node;
1886 else
1888 /* Normal direct function call. */
1889 tf = get_function_type (tb);
1892 gcc_assert (tf != NULL);
1894 /* Now we have the type, callee and maybe object reference,
1895 build the call expression. */
1896 tree exp = d_build_call (tf, callee, object, e->arguments);
1898 if (returnvalue != NULL_TREE)
1899 exp = compound_expr (exp, returnvalue);
1901 if (tf->isref)
1902 exp = build_deref (exp);
1904 /* Some library calls are defined to return a generic type.
1905 this->type is the real type we want to return. */
1906 if (e->type->isTypeBasic ())
1907 exp = d_convert (build_ctype (e->type), exp);
1909 /* If this call was found to be a constructor for a temporary with a
1910 cleanup, then move the call inside the TARGET_EXPR. */
1911 if (cleanup != NULL_TREE)
1913 tree init = TARGET_EXPR_INITIAL (cleanup);
1914 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1915 exp = cleanup;
1918 this->result_ = exp;
1921 /* Build a delegate expression. */
1923 void visit (DelegateExp *e)
1925 if (e->func->semanticRun == PASSsemantic3done)
1927 /* Add the function as nested function if it belongs to this module.
1928 ie: it is a member of this module, or it is a template instance. */
1929 Dsymbol *owner = e->func->toParent ();
1930 while (!owner->isTemplateInstance () && owner->toParent ())
1931 owner = owner->toParent ();
1932 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1933 build_decl_tree (e->func);
1936 tree fndecl;
1937 tree object;
1939 if (e->func->isNested ())
1941 if (e->e1->op == TOKnull)
1942 object = build_expr (e->e1);
1943 else
1944 object = get_frame_for_symbol (e->func);
1946 fndecl = build_address (get_symbol_decl (e->func));
1948 else
1950 if (!e->func->isThis ())
1952 error ("delegates are only for non-static functions");
1953 this->result_ = error_mark_node;
1954 return;
1957 object = build_expr (e->e1);
1959 /* Want reference to `this' object. */
1960 if (e->e1->type->ty != Tclass && e->e1->type->ty != Tpointer)
1961 object = build_address (object);
1963 /* Object reference could be the outer `this' field of a class or
1964 closure of type `void*'. Cast it to the right type. */
1965 if (e->e1->type->ty == Tclass)
1966 object = d_convert (build_ctype (e->e1->type), object);
1968 fndecl = get_symbol_decl (e->func);
1970 /* Get pointer to function out of the virtual table. */
1971 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1972 && e->e1->op != TOKsuper && e->e1->op != TOKdottype)
1974 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1975 object = d_save_expr (object);
1976 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1978 else
1979 fndecl = build_address (fndecl);
1982 this->result_ = build_method_call (fndecl, object, e->type);
1985 /* Build a type component expression. */
1987 void visit (DotTypeExp *e)
1989 /* Just a pass through to underlying expression. */
1990 this->result_ = build_expr (e->e1);
1993 /* Build a component reference expression. */
1995 void visit (DotVarExp *e)
1997 VarDeclaration *vd = e->var->isVarDeclaration ();
1999 /* This could also be a function, but relying on that being taken
2000 care of by the visitor interface for CallExp. */
2001 if (vd != NULL)
2003 if (!vd->isField ())
2004 this->result_ = get_decl_tree (vd);
2005 else
2007 tree object = build_expr (e->e1);
2009 if (e->e1->type->toBasetype ()->ty != Tstruct)
2010 object = build_deref (object);
2012 this->result_ = component_ref (object, get_symbol_decl (vd));
2015 else
2017 error ("%qs is not a field, but a %qs",
2018 e->var->toChars (), e->var->kind ());
2019 this->result_ = error_mark_node;
2023 /* Build an assert expression, used to declare conditions that must hold at
2024 that a given point in the program. */
2026 void visit (AssertExp *e)
2028 Type *tb1 = e->e1->type->toBasetype ();
2029 tree arg = build_expr (e->e1);
2030 tree tmsg = NULL_TREE;
2031 tree assert_pass = void_node;
2032 tree assert_fail;
2034 if (global.params.useAssert == CHECKENABLEon
2035 && global.params.checkAction == CHECKACTION_D)
2037 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
2038 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
2039 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
2040 libcall_fn libcall;
2042 if (e->msg)
2044 tmsg = build_expr_dtor (e->msg);
2045 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
2047 else
2048 libcall = unittest_p ? LIBCALL_UNITTEST : LIBCALL_ASSERT;
2050 /* Build a call to _d_assert(). */
2051 assert_fail = d_assert_call (e->loc, libcall, tmsg);
2053 if (global.params.useInvariants == CHECKENABLEon)
2055 /* If the condition is a D class or struct object with an invariant,
2056 call it if the condition result is true. */
2057 if (tb1->ty == Tclass)
2059 ClassDeclaration *cd = tb1->isClassHandle ();
2060 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
2062 arg = d_save_expr (arg);
2063 assert_pass = build_libcall (LIBCALL_INVARIANT,
2064 Type::tvoid, 1, arg);
2067 else if (tb1->ty == Tpointer && tb1->nextOf ()->ty == Tstruct)
2069 StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
2070 if (sd->inv != NULL)
2072 Expressions args;
2073 arg = d_save_expr (arg);
2074 assert_pass = d_build_call_expr (sd->inv, arg, &args);
2079 else if (global.params.useAssert == CHECKENABLEon
2080 && global.params.checkAction == CHECKACTION_C)
2082 /* Generate: __builtin_trap() */
2083 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
2084 assert_fail = build_call_expr (fn, 0);
2086 else
2088 /* Assert contracts are turned off, if the contract condition has no
2089 side effects can still use it as a predicate for the optimizer. */
2090 if (TREE_SIDE_EFFECTS (arg))
2092 this->result_ = void_node;
2093 return;
2096 assert_fail = build_predict_expr (PRED_NORETURN, NOT_TAKEN);
2099 /* Build condition that we are asserting in this contract. */
2100 tree condition = convert_for_condition (arg, e->e1->type);
2102 /* We expect the condition to always be true, as what happens if an assert
2103 contract is false is undefined behavior. */
2104 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
2105 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
2106 tree pred_type = TREE_VALUE (arg_types);
2107 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
2109 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
2110 build_int_cst (expected_type, 1));
2111 condition = d_truthvalue_conversion (condition);
2113 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
2116 /* Build a declaration expression. */
2118 void visit (DeclarationExp *e)
2120 /* Compile the declaration. */
2121 push_stmt_list ();
2122 build_decl_tree (e->declaration);
2123 tree result = pop_stmt_list ();
2125 /* Construction of an array for typesafe-variadic function arguments
2126 can cause an empty STMT_LIST here. This can causes problems
2127 during gimplification. */
2128 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
2129 result = build_empty_stmt (input_location);
2131 this->result_ = result;
2134 /* Build a typeid expression. Returns an instance of class TypeInfo
2135 corresponding to. */
2137 void visit (TypeidExp *e)
2139 if (Type *tid = isType (e->obj))
2141 tree ti = build_typeinfo (e->loc, tid);
2143 /* If the typeinfo is at an offset. */
2144 if (tid->vtinfo->offset)
2145 ti = build_offset (ti, size_int (tid->vtinfo->offset));
2147 this->result_ = build_nop (build_ctype (e->type), ti);
2149 else if (Expression *tid = isExpression (e->obj))
2151 Type *type = tid->type->toBasetype ();
2152 assert (type->ty == Tclass);
2154 /* Generate **classptr to get the classinfo. */
2155 tree ci = build_expr (tid);
2156 ci = indirect_ref (ptr_type_node, ci);
2157 ci = indirect_ref (ptr_type_node, ci);
2159 /* Add extra indirection for interfaces. */
2160 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
2161 ci = indirect_ref (ptr_type_node, ci);
2163 this->result_ = build_nop (build_ctype (e->type), ci);
2165 else
2166 gcc_unreachable ();
2169 /* Build a function/lambda expression. */
2171 void visit (FuncExp *e)
2173 Type *ftype = e->type->toBasetype ();
2175 /* This check is for lambda's, remove `vthis' as function isn't nested. */
2176 if (e->fd->tok == TOKreserved && ftype->ty == Tpointer)
2178 e->fd->tok = TOKfunction;
2179 e->fd->vthis = NULL;
2182 /* Compile the function literal body. */
2183 build_decl_tree (e->fd);
2185 /* If nested, this will be a trampoline. */
2186 if (e->fd->isNested ())
2188 tree func = build_address (get_symbol_decl (e->fd));
2189 tree object;
2191 if (this->constp_)
2193 /* Static delegate variables have no context pointer. */
2194 object = null_pointer_node;
2195 this->result_ = build_method_call (func, object, e->fd->type);
2196 TREE_CONSTANT (this->result_) = 1;
2198 else
2200 object = get_frame_for_symbol (e->fd);
2201 this->result_ = build_method_call (func, object, e->fd->type);
2204 else
2206 this->result_ = build_nop (build_ctype (e->type),
2207 build_address (get_symbol_decl (e->fd)));
2211 /* Build a halt expression. */
2213 void visit (HaltExp *)
2215 /* Should we use trap() or abort()? */
2216 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2217 this->result_ = build_call_expr (ttrap, 0);
2220 /* Build a symbol pointer offset expression. */
2222 void visit (SymOffExp *e)
2224 /* Build the address and offset of the symbol. */
2225 size_t soffset = e->isSymOffExp ()->offset;
2226 tree result = get_decl_tree (e->var);
2227 TREE_USED (result) = 1;
2229 if (declaration_reference_p (e->var))
2230 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2231 else
2232 result = build_address (result);
2234 if (!soffset)
2235 result = d_convert (build_ctype (e->type), result);
2236 else
2238 tree offset = size_int (soffset);
2239 result = build_nop (build_ctype (e->type),
2240 build_offset (result, offset));
2243 this->result_ = result;
2246 /* Build a variable expression. */
2248 void visit (VarExp *e)
2250 if (e->var->needThis ())
2252 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2253 this->result_ = error_mark_node;
2254 return;
2256 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2258 /* __ctfe is always false at run-time. */
2259 this->result_ = integer_zero_node;
2260 return;
2263 /* This check is same as is done in FuncExp for lambdas. */
2264 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2265 if (fld != NULL)
2267 if (fld->tok == TOKreserved)
2269 fld->tok = TOKfunction;
2270 fld->vthis = NULL;
2273 /* Compiler the function literal body. */
2274 build_decl_tree (fld);
2277 if (this->constp_)
2279 /* Want the initializer, not the expression. */
2280 VarDeclaration *var = e->var->isVarDeclaration ();
2281 SymbolDeclaration *sd = e->var->isSymbolDeclaration ();
2282 tree init = NULL_TREE;
2284 if (var && (var->isConst () || var->isImmutable ())
2285 && e->type->toBasetype ()->ty != Tsarray && var->_init)
2287 if (var->inuse)
2288 error_at (make_location_t (e->loc), "recursive reference %qs",
2289 e->toChars ());
2290 else
2292 var->inuse++;
2293 init = build_expr (initializerToExpression (var->_init), true);
2294 var->inuse--;
2297 else if (sd && sd->dsym)
2298 init = layout_struct_initializer (sd->dsym);
2299 else
2300 error_at (make_location_t (e->loc), "non-constant expression %qs",
2301 e->toChars ());
2303 if (init != NULL_TREE)
2304 this->result_ = init;
2305 else
2306 this->result_ = error_mark_node;
2308 else
2310 tree result = get_decl_tree (e->var);
2311 TREE_USED (result) = 1;
2313 /* For variables that are references - currently only out/inout
2314 arguments; objects don't count - evaluating the variable means
2315 we want what it refers to. */
2316 if (declaration_reference_p (e->var))
2317 result = indirect_ref (build_ctype (e->var->type), result);
2319 this->result_ = result;
2323 /* Build a this variable expression. */
2325 void visit (ThisExp *e)
2327 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2328 tree result = NULL_TREE;
2330 if (e->var)
2331 result = get_decl_tree (e->var);
2332 else
2334 gcc_assert (fd && fd->vthis);
2335 result = get_decl_tree (fd->vthis);
2338 if (e->type->ty == Tstruct)
2339 result = build_deref (result);
2341 this->result_ = result;
2344 /* Build a new expression, which allocates memory either on the garbage
2345 collected heap or by using a class or struct specific allocator. */
2347 void visit (NewExp *e)
2349 Type *tb = e->type->toBasetype ();
2350 tree result;
2352 if (e->allocator)
2353 gcc_assert (e->newargs);
2355 if (tb->ty == Tclass)
2357 /* Allocating a new class. */
2358 tb = e->newtype->toBasetype ();
2360 ClassDeclaration *cd = tb->isTypeClass ()->sym;
2361 tree type = build_ctype (tb);
2362 tree setup_exp = NULL_TREE;
2363 tree new_call;
2365 if (e->onstack)
2367 /* If being used as an initializer for a local variable with scope
2368 storage class, then the instance is allocated on the stack
2369 rather than the heap or using the class specific allocator. */
2370 tree var = build_local_temp (TREE_TYPE (type));
2371 new_call = build_nop (type, build_address (var));
2372 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2374 else if (e->allocator)
2376 /* Call class allocator, and copy the initializer into memory. */
2377 new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
2378 new_call = d_save_expr (new_call);
2379 new_call = build_nop (type, new_call);
2380 setup_exp = modify_expr (build_deref (new_call),
2381 aggregate_initializer_decl (cd));
2383 else
2385 /* Generate: _d_newclass() */
2386 tree arg = build_address (get_classinfo_decl (cd));
2387 new_call = build_libcall (LIBCALL_NEWCLASS, tb, 1, arg);
2390 /* Set the context pointer for nested classes. */
2391 if (cd->isNested ())
2393 tree field = get_symbol_decl (cd->vthis);
2394 tree value = NULL_TREE;
2396 if (e->thisexp)
2398 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2399 Dsymbol *outer = cd->toParent2 ();
2400 int offset = 0;
2402 value = build_expr (e->thisexp);
2403 if (outer != tcd)
2405 ClassDeclaration *ocd = outer->isClassDeclaration ();
2406 gcc_assert (ocd->isBaseOf (tcd, &offset));
2407 /* Could just add offset... */
2408 value = convert_expr (value, e->thisexp->type, ocd->type);
2411 else
2412 value = build_vthis (cd);
2414 if (value != NULL_TREE)
2416 /* Generate: (new())->vthis = this; */
2417 new_call = d_save_expr (new_call);
2418 field = component_ref (build_deref (new_call), field);
2419 setup_exp = compound_expr (setup_exp,
2420 modify_expr (field, value));
2423 new_call = compound_expr (setup_exp, new_call);
2425 /* Call the class constructor. */
2426 if (e->member)
2427 result = d_build_call_expr (e->member, new_call, e->arguments);
2428 else
2429 result = new_call;
2431 if (e->argprefix)
2432 result = compound_expr (build_expr (e->argprefix), result);
2434 else if (tb->ty == Tpointer && tb->nextOf ()->toBasetype ()->ty == Tstruct)
2436 /* Allocating memory for a new struct. */
2437 Type *htype = e->newtype->toBasetype ();
2438 gcc_assert (!e->onstack);
2440 TypeStruct *stype = htype->isTypeStruct ();
2441 StructDeclaration *sd = stype->sym;
2442 tree new_call;
2444 /* Cannot new an opaque struct. */
2445 if (sd->size (e->loc) == 0)
2447 this->result_ = d_convert (build_ctype (e->type),
2448 integer_zero_node);
2449 return;
2452 if (e->allocator)
2454 /* Call struct allocator. */
2455 new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
2456 new_call = build_nop (build_ctype (tb), new_call);
2458 else
2460 /* Generate: _d_newitemT() */
2461 libcall_fn libcall = htype->isZeroInit ()
2462 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2463 tree arg = build_typeinfo (e->loc, e->newtype);
2464 new_call = build_libcall (libcall, tb, 1, arg);
2467 if (e->member || !e->arguments)
2469 /* Set the context pointer for nested structs. */
2470 if (sd->isNested ())
2472 tree value = build_vthis (sd);
2473 tree field = get_symbol_decl (sd->vthis);
2474 tree type = build_ctype (stype);
2476 new_call = d_save_expr (new_call);
2477 field = component_ref (indirect_ref (type, new_call), field);
2478 new_call = compound_expr (modify_expr (field, value), new_call);
2481 /* Call the struct constructor. */
2482 if (e->member)
2483 result = d_build_call_expr (e->member, new_call, e->arguments);
2484 else
2485 result = new_call;
2487 else
2489 /* If we have a user supplied initializer, then set-up with a
2490 struct literal. */
2491 if (e->arguments != NULL && sd->fields.length != 0)
2493 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2494 e->arguments,
2495 htype);
2496 new_call = d_save_expr (new_call);
2497 se->type = sd->type;
2498 se->sym = new_call;
2499 result = compound_expr (build_expr (se), new_call);
2501 else
2502 result = new_call;
2505 if (e->argprefix)
2506 result = compound_expr (build_expr (e->argprefix), result);
2508 else if (tb->ty == Tarray)
2510 /* Allocating memory for a new D array. */
2511 tb = e->newtype->toBasetype ();
2512 TypeDArray *tarray = tb->isTypeDArray ();
2514 gcc_assert (!e->allocator);
2515 gcc_assert (e->arguments && e->arguments->length >= 1);
2517 if (e->arguments->length == 1)
2519 /* Single dimension array allocations. */
2520 Expression *arg = (*e->arguments)[0];
2522 if (tarray->next->size () == 0)
2524 /* Array element size is unknown. */
2525 this->result_ = d_array_value (build_ctype (e->type),
2526 size_int (0), null_pointer_node);
2527 return;
2530 libcall_fn libcall = tarray->next->isZeroInit ()
2531 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
2532 result = build_libcall (libcall, tb, 2,
2533 build_typeinfo (e->loc, e->type),
2534 build_expr (arg));
2536 else
2538 /* Multidimensional array allocations. */
2539 tree tarray = make_array_type (Type::tsize_t, e->arguments->length);
2540 tree var = build_local_temp (tarray);
2541 vec <constructor_elt, va_gc> *elms = NULL;
2543 /* Get the base element type for the array, generating the
2544 initializer for the dims parameter along the way. */
2545 Type *telem = e->newtype->toBasetype ();
2546 for (size_t i = 0; i < e->arguments->length; i++)
2548 Expression *arg = (*e->arguments)[i];
2549 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2551 gcc_assert (telem->ty == Tarray);
2552 telem = telem->toBasetype ()->nextOf ();
2553 gcc_assert (telem);
2556 /* Initialize the temporary. */
2557 tree init = modify_expr (var, build_constructor (tarray, elms));
2558 var = compound_expr (init, var);
2560 /* Generate: _d_newarraymTX(ti, dims)
2561 or: _d_newarraymiTX(ti, dims) */
2562 libcall_fn libcall = telem->isZeroInit ()
2563 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2565 tree tinfo = build_typeinfo (e->loc, e->type);
2566 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2567 size_int (e->arguments->length),
2568 build_address (var));
2570 result = build_libcall (libcall, tb, 2, tinfo, dims);
2573 if (e->argprefix)
2574 result = compound_expr (build_expr (e->argprefix), result);
2576 else if (tb->ty == Tpointer)
2578 /* Allocating memory for a new pointer. */
2579 TypePointer *tpointer = tb->isTypePointer ();
2581 if (tpointer->next->size () == 0)
2583 /* Pointer element size is unknown. */
2584 this->result_ = d_convert (build_ctype (e->type),
2585 integer_zero_node);
2586 return;
2589 libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
2590 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2592 tree arg = build_typeinfo (e->loc, e->newtype);
2593 result = build_libcall (libcall, tb, 1, arg);
2595 if (e->arguments && e->arguments->length == 1)
2597 result = d_save_expr (result);
2598 tree init = modify_expr (build_deref (result),
2599 build_expr ((*e->arguments)[0]));
2600 result = compound_expr (init, result);
2603 if (e->argprefix)
2604 result = compound_expr (build_expr (e->argprefix), result);
2606 else
2607 gcc_unreachable ();
2609 this->result_ = convert_expr (result, tb, e->type);
2612 /* Build an integer literal. */
2614 void visit (IntegerExp *e)
2616 tree ctype = build_ctype (e->type->toBasetype ());
2617 this->result_ = build_integer_cst (e->value, ctype);
2620 /* Build a floating-point literal. */
2622 void visit (RealExp *e)
2624 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2627 /* Build a complex literal. */
2629 void visit (ComplexExp *e)
2631 Type *tnext;
2633 switch (e->type->toBasetype ()->ty)
2635 case Tcomplex32:
2636 tnext = (TypeBasic *) Type::tfloat32;
2637 break;
2639 case Tcomplex64:
2640 tnext = (TypeBasic *) Type::tfloat64;
2641 break;
2643 case Tcomplex80:
2644 tnext = (TypeBasic *) Type::tfloat80;
2645 break;
2647 default:
2648 gcc_unreachable ();
2651 this->result_ = build_complex (build_ctype (e->type),
2652 build_float_cst (creall (e->value), tnext),
2653 build_float_cst (cimagl (e->value), tnext));
2656 /* Build a string literal, all strings are null terminated except for
2657 static arrays. */
2659 void visit (StringExp *e)
2661 Type *tb = e->type->toBasetype ();
2662 tree type = build_ctype (e->type);
2664 if (tb->ty == Tsarray)
2666 /* Turn the string into a constructor for the static array. */
2667 vec <constructor_elt, va_gc> *elms = NULL;
2668 vec_safe_reserve (elms, e->len);
2669 tree etype = TREE_TYPE (type);
2671 for (size_t i = 0; i < e->len; i++)
2673 tree value = build_integer_cst (e->charAt (i), etype);
2674 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2677 tree ctor = build_constructor (type, elms);
2678 TREE_CONSTANT (ctor) = 1;
2679 this->result_ = ctor;
2681 else
2683 /* Copy the string contents to a null terminated string. */
2684 dinteger_t length = (e->len * e->sz);
2685 char *string = XALLOCAVEC (char, length + 1);
2686 memcpy (string, e->string, length);
2687 string[length] = '\0';
2689 /* String value and type includes the null terminator. */
2690 tree value = build_string (length, string);
2691 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2692 value = build_address (value);
2694 if (tb->ty == Tarray)
2695 value = d_array_value (type, size_int (e->len), value);
2697 TREE_CONSTANT (value) = 1;
2698 this->result_ = d_convert (type, value);
2702 /* Build a tuple literal. Just an argument list that may have
2703 side effects that need evaluation. */
2705 void visit (TupleExp *e)
2707 tree result = NULL_TREE;
2709 if (e->e0)
2710 result = build_expr (e->e0, this->constp_, true);
2712 for (size_t i = 0; i < e->exps->length; ++i)
2714 Expression *exp = (*e->exps)[i];
2715 result = compound_expr (result, build_expr (exp, this->constp_, true));
2718 if (result == NULL_TREE)
2719 result = void_node;
2721 this->result_ = result;
2724 /* Build an array literal. The common type of the all elements is taken to
2725 be the type of the array element, and all elements are implicitly
2726 converted to that type. */
2728 void visit (ArrayLiteralExp *e)
2730 Type *tb = e->type->toBasetype ();
2732 /* Implicitly convert void[n] to ubyte[n]. */
2733 if (tb->ty == Tsarray && tb->nextOf ()->toBasetype ()->ty == Tvoid)
2734 tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());
2736 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tpointer);
2738 /* Handle empty array literals. */
2739 if (e->elements->length == 0)
2741 if (tb->ty == Tarray)
2742 this->result_ = d_array_value (build_ctype (e->type),
2743 size_int (0), null_pointer_node);
2744 else
2745 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2746 NULL);
2748 return;
2751 /* Build an expression that assigns the expressions in ELEMENTS to
2752 a constructor. */
2753 vec <constructor_elt, va_gc> *elms = NULL;
2754 vec_safe_reserve (elms, e->elements->length);
2755 bool constant_p = true;
2756 tree saved_elems = NULL_TREE;
2758 Type *etype = tb->nextOf ();
2759 tree satype = make_array_type (etype, e->elements->length);
2761 for (size_t i = 0; i < e->elements->length; i++)
2763 Expression *expr = e->getElement (i);
2764 tree value = build_expr (expr, this->constp_, true);
2766 /* Only append nonzero values, the backend will zero out the rest
2767 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2768 if (!initializer_zerop (value))
2770 if (!TREE_CONSTANT (value))
2771 constant_p = false;
2773 /* Split construction of values out of the constructor if there
2774 may be side effects. */
2775 tree init = stabilize_expr (&value);
2776 if (init != NULL_TREE)
2777 saved_elems = compound_expr (saved_elems, init);
2779 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2780 convert_expr (value, expr->type, etype));
2784 /* Now return the constructor as the correct type. For static arrays there
2785 is nothing else to do. For dynamic arrays, return a two field struct.
2786 For pointers, return the address. */
2787 tree ctor = build_constructor (satype, elms);
2788 tree type = build_ctype (e->type);
2790 /* Nothing else to do for static arrays. */
2791 if (tb->ty == Tsarray || this->constp_)
2793 /* Can't take the address of the constructor, so create an anonymous
2794 static symbol, and then refer to it. */
2795 if (tb->ty != Tsarray)
2797 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2798 ctor = build_address (decl);
2799 if (tb->ty == Tarray)
2800 ctor = d_array_value (type, size_int (e->elements->length), ctor);
2802 d_pushdecl (decl);
2803 rest_of_decl_compilation (decl, 1, 0);
2806 /* If the array literal is readonly or static. */
2807 if (constant_p)
2808 TREE_CONSTANT (ctor) = 1;
2809 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2810 TREE_STATIC (ctor) = 1;
2812 /* Use memset to fill any alignment holes in the array. */
2813 if (!this->constp_ && !this->literalp_)
2815 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
2817 if (ts != NULL && (!identity_compare_p (ts->sym)
2818 || ts->sym->isUnionDeclaration ()))
2820 tree var = build_local_temp (TREE_TYPE (ctor));
2821 tree init = build_memset_call (var);
2822 /* Evaluate memset() first, then any saved elements. */
2823 saved_elems = compound_expr (init, saved_elems);
2824 ctor = compound_expr (modify_expr (var, ctor), var);
2828 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2830 else
2832 /* Allocate space on the memory managed heap. */
2833 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2834 etype->pointerTo (), 2,
2835 build_typeinfo (e->loc, etype->arrayOf ()),
2836 size_int (e->elements->length));
2837 mem = d_save_expr (mem);
2839 /* Now copy the constructor into memory. */
2840 tree size = size_mult_expr (size_int (e->elements->length),
2841 size_int (tb->nextOf ()->size ()));
2843 tree result = build_memcpy_call (mem, build_address (ctor), size);
2845 /* Return the array pointed to by MEM. */
2846 result = compound_expr (result, mem);
2848 if (tb->ty == Tarray)
2849 result = d_array_value (type, size_int (e->elements->length), result);
2851 this->result_ = compound_expr (saved_elems, result);
2855 /* Build an associative array literal. The common type of the all keys is
2856 taken to be the key type, and common type of all values the value type.
2857 All keys and values are then implicitly converted as needed. */
2859 void visit (AssocArrayLiteralExp *e)
2861 /* Want the mutable type for typeinfo reference. */
2862 Type *tb = e->type->toBasetype ()->mutableOf ();
2864 /* Handle empty assoc array literals. */
2865 TypeAArray *ta = tb->isTypeAArray ();
2866 if (e->keys->length == 0)
2868 this->result_ = build_constructor (build_ctype (ta), NULL);
2869 return;
2872 /* Build an expression that assigns all expressions in KEYS
2873 to a constructor. */
2874 tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
2875 e->keys, this->constp_);
2876 tree init = stabilize_expr (&akeys);
2878 /* Do the same with all expressions in VALUES. */
2879 tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
2880 e->values, this->constp_);
2881 init = compound_expr (init, stabilize_expr (&avals));
2883 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2884 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2885 size_int (e->keys->length),
2886 build_address (akeys));
2887 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2888 size_int (e->values->length),
2889 build_address (avals));
2891 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2892 build_typeinfo (e->loc, ta), keys, vals);
2894 /* Return an associative array pointed to by MEM. */
2895 tree aatype = build_ctype (ta);
2896 vec <constructor_elt, va_gc> *ce = NULL;
2897 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2899 tree result = build_nop (build_ctype (e->type),
2900 build_constructor (aatype, ce));
2901 this->result_ = compound_expr (init, result);
2904 /* Build a struct literal. */
2906 void visit (StructLiteralExp *e)
2908 /* Handle empty struct literals. */
2909 if (e->elements == NULL || e->sd->fields.length == 0)
2911 this->result_ = build_constructor (build_ctype (e->type), NULL);
2912 return;
2915 /* Building sinit trees are delayed until after frontend semantic
2916 processing has complete. Build the static initializer now. */
2917 if (e->useStaticInit && !this->constp_)
2919 tree init = aggregate_initializer_decl (e->sd);
2921 /* If initializing a symbol, don't forget to set it. */
2922 if (e->sym != NULL)
2924 tree var = build_deref (e->sym);
2925 init = compound_expr (modify_expr (var, init), var);
2928 this->result_ = init;
2929 return;
2932 /* Build a constructor that assigns the expressions in ELEMENTS
2933 at each field index that has been filled in. */
2934 vec <constructor_elt, va_gc> *ve = NULL;
2935 tree saved_elems = NULL_TREE;
2937 /* CTFE may fill the hidden pointer by NullExp. */
2938 gcc_assert (e->elements->length <= e->sd->fields.length);
2940 Type *tb = e->type->toBasetype ();
2941 gcc_assert (tb->ty == Tstruct);
2943 for (size_t i = 0; i < e->elements->length; i++)
2945 Expression *exp = (*e->elements)[i];
2946 if (!exp)
2947 continue;
2949 VarDeclaration *field = e->sd->fields[i];
2950 Type *type = exp->type->toBasetype ();
2951 Type *ftype = field->type->toBasetype ();
2952 tree value = NULL_TREE;
2954 if (ftype->ty == Tsarray && !same_type_p (type, ftype))
2956 /* Initialize a static array with a single element. */
2957 tree elem = build_expr (exp, this->constp_, true);
2958 saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
2959 elem = d_save_expr (elem);
2961 if (initializer_zerop (elem))
2962 value = build_constructor (build_ctype (ftype), NULL);
2963 else
2964 value = build_array_from_val (ftype, elem);
2966 else
2968 value = convert_expr (build_expr (exp, this->constp_, true),
2969 exp->type, field->type);
2972 /* Split construction of values out of the constructor. */
2973 saved_elems = compound_expr (saved_elems, stabilize_expr (&value));
2975 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2978 /* Maybe setup hidden pointer to outer scope context. */
2979 if (e->sd->isNested () && e->elements->length != e->sd->fields.length
2980 && this->constp_ == false)
2982 tree field = get_symbol_decl (e->sd->vthis);
2983 tree value = build_vthis (e->sd);
2984 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2985 gcc_assert (e->useStaticInit == false);
2988 /* Build a constructor in the correct shape of the aggregate type. */
2989 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2991 /* Nothing more to do for constant literals. */
2992 if (this->constp_)
2994 /* If the struct literal is a valid for static data. */
2995 if (TREE_CONSTANT (ctor)
2996 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2997 TREE_STATIC (ctor) = 1;
2999 this->result_ = compound_expr (saved_elems, ctor);
3000 return;
3003 /* Construct the struct literal for run-time. */
3004 if (e->sym != NULL)
3006 /* Store the result in a symbol to initialize the literal. */
3007 tree var = build_deref (e->sym);
3008 ctor = compound_expr (modify_expr (var, ctor), var);
3010 else if (!this->literalp_)
3012 /* Use memset to fill any alignment holes in the object. */
3013 if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
3015 tree var = build_local_temp (TREE_TYPE (ctor));
3016 tree init = build_memset_call (var);
3017 /* Evaluate memset() first, then any saved element constructors. */
3018 saved_elems = compound_expr (init, saved_elems);
3019 ctor = compound_expr (modify_expr (var, ctor), var);
3023 this->result_ = compound_expr (saved_elems, ctor);
3026 /* Build a null literal. */
3028 void visit (NullExp *e)
3030 this->result_ = build_typeof_null_value (e->type);
3033 /* Build a vector literal. */
3035 void visit (VectorExp *e)
3037 tree type = build_ctype (e->type);
3039 /* First handle array literal expressions. */
3040 if (e->e1->op == TOKarrayliteral)
3042 ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
3043 vec <constructor_elt, va_gc> *elms = NULL;
3044 bool constant_p = true;
3046 vec_safe_reserve (elms, ale->elements->length);
3047 for (size_t i = 0; i < ale->elements->length; i++)
3049 Expression *expr = ale->getElement (i);
3050 tree value = d_convert (TREE_TYPE (type),
3051 build_expr (expr, this->constp_, true));
3052 if (!CONSTANT_CLASS_P (value))
3053 constant_p = false;
3055 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
3058 /* Build a VECTOR_CST from a constant vector constructor. */
3059 if (constant_p)
3060 this->result_ = build_vector_from_ctor (type, elms);
3061 else
3062 this->result_ = build_constructor (type, elms);
3064 else
3066 /* Build constructor from single value. */
3067 tree value = d_convert (TREE_TYPE (type),
3068 build_expr (e->e1, this->constp_, true));
3069 this->result_ = build_vector_from_val (type, value);
3073 /* Build a static array representation of a vector expression. */
3075 void visit (VectorArrayExp *e)
3077 this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
3078 e->e1->type, e->type);
3081 /* Build a static class literal, return its reference. */
3083 void visit (ClassReferenceExp *e)
3085 /* The result of build_new_class_expr is a RECORD_TYPE, we want
3086 the reference. */
3087 tree var = build_address (build_new_class_expr (e));
3089 /* If the type of this literal is an interface, the we must add the
3090 interface offset to symbol. */
3091 if (this->constp_)
3093 TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
3094 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
3096 if (to != NULL)
3098 ClassDeclaration *from = e->originalClass ();
3099 int offset = 0;
3101 gcc_assert (to->isBaseOf (from, &offset) != 0);
3103 if (offset != 0)
3104 var = build_offset (var, size_int (offset));
3108 this->result_ = var;
3111 /* These expressions are mainly just a placeholders in the frontend.
3112 We shouldn't see them here. */
3114 void visit (ScopeExp *e)
3116 error_at (make_location_t (e->loc), "%qs is not an expression",
3117 e->toChars ());
3118 this->result_ = error_mark_node;
3121 void visit (TypeExp *e)
3123 error_at (make_location_t (e->loc), "type %qs is not an expression",
3124 e->toChars ());
3125 this->result_ = error_mark_node;
3130 /* Main entry point for ExprVisitor interface to generate code for
3131 the Expression AST class E. If CONST_P is true, then E is a
3132 constant expression. If LITERAL_P is true, then E is a value used
3133 in the initialization of another literal. */
3135 tree
3136 build_expr (Expression *e, bool const_p, bool literal_p)
3138 ExprVisitor v = ExprVisitor (const_p, literal_p);
3139 location_t saved_location = input_location;
3141 input_location = make_location_t (e->loc);
3142 e->accept (&v);
3143 tree expr = v.result ();
3144 input_location = saved_location;
3146 /* Check if initializer expression is valid constant. */
3147 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3149 error_at (make_location_t (e->loc), "non-constant expression %qs",
3150 e->toChars ());
3151 return error_mark_node;
3154 return expr;
3157 /* Same as build_expr, but also calls destructors on any temporaries. */
3159 tree
3160 build_expr_dtor (Expression *e)
3162 /* Codegen can be improved by determining if no exceptions can be thrown
3163 between the ctor and dtor, and eliminating the ctor and dtor. */
3164 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3165 tree result = build_expr (e);
3167 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3169 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3170 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3173 return result;
3176 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3178 tree
3179 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3181 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3182 tree result = build_expr (e);
3184 /* Convert for initializing the DECL_RESULT. */
3185 if (tf->isref)
3187 /* If we are returning a reference, take the address. */
3188 result = convert_expr (result, e->type, type);
3189 result = build_address (result);
3191 else
3192 result = convert_for_rvalue (result, e->type, type);
3194 /* The decl to store the return expression. */
3195 tree decl = DECL_RESULT (cfun->decl);
3197 /* Split comma expressions, so that the result is returned directly. */
3198 tree expr = stabilize_expr (&result);
3199 result = build_assign (INIT_EXPR, decl, result);
3200 result = compound_expr (expr, return_expr (result));
3202 /* May nest the return expression inside the try/finally expression. */
3203 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3205 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3206 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3209 return result;