Move PREFERRED_DEBUGGING_TYPE define in pa64-hpux.h to pa.h
[official-gcc.git] / gcc / d / expr.cc
blobea21bd5a8a15d171af5a2828459853a613789e23
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 /* Deal with float mod expressions immediately. */
105 if (code == FLOAT_MOD_EXPR)
106 return build_float_modulus (type, arg0, arg1);
108 if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
109 return build_nop (type, build_offset_op (code, arg0, arg1));
111 if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
112 return build_nop (type, build_offset_op (code, arg1, arg0));
114 if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
116 gcc_assert (code == MINUS_EXPR);
117 tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
119 /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
120 pointers. If some platform cannot provide that, or has a larger
121 ptrdiff_type to support differences larger than half the address
122 space, cast the pointers to some larger integer type and do the
123 computations in that type. */
124 if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
125 ret = fold_build2 (MINUS_EXPR, ptrtype,
126 d_convert (ptrtype, arg0),
127 d_convert (ptrtype, arg1));
128 else
129 ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
131 else
133 /* If the operation needs excess precision. */
134 tree eptype = excess_precision_type (type);
135 if (eptype != NULL_TREE)
137 arg0 = d_convert (eptype, arg0);
138 arg1 = d_convert (eptype, arg1);
140 else
142 /* Front-end does not do this conversion and GCC does not
143 always do it right. */
144 if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
145 arg1 = d_convert (t0, arg1);
146 else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
147 arg0 = d_convert (t1, arg0);
149 eptype = type;
152 ret = build2 (code, eptype, arg0, arg1);
155 return d_convert (type, ret);
158 /* Build a binary expression of code CODE, assigning the result into E1. */
160 static tree
161 binop_assignment (tree_code code, Expression *e1, Expression *e2)
163 /* Skip casts for lhs assignment. */
164 Expression *e1b = e1;
165 while (e1b->op == TOKcast)
167 CastExp *ce = e1b->isCastExp ();
168 gcc_assert (same_type_p (ce->type, ce->to));
169 e1b = ce->e1;
172 /* Stabilize LHS for assignment. */
173 tree lhs = build_expr (e1b);
174 tree lexpr = stabilize_expr (&lhs);
176 /* The LHS expression could be an assignment, to which its operation gets
177 lost during gimplification. */
178 if (TREE_CODE (lhs) == MODIFY_EXPR)
180 /* If LHS has side effects, call stabilize_reference on it, so it can
181 be evaluated multiple times. */
182 if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
183 lhs = build_assign (MODIFY_EXPR,
184 stabilize_reference (TREE_OPERAND (lhs, 0)),
185 TREE_OPERAND (lhs, 1));
187 lexpr = compound_expr (lexpr, lhs);
188 lhs = TREE_OPERAND (lhs, 0);
191 lhs = stabilize_reference (lhs);
193 /* Save RHS, to ensure that the expression is evaluated before LHS. */
194 tree rhs = build_expr (e2);
195 tree rexpr = d_save_expr (rhs);
197 rhs = binary_op (code, build_ctype (e1->type),
198 convert_expr (lhs, e1b->type, e1->type), rexpr);
199 if (TREE_SIDE_EFFECTS (rhs))
200 rhs = compound_expr (rexpr, rhs);
202 tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
203 return compound_expr (lexpr, expr);
206 /* Implements the visitor interface to build the GCC trees of all Expression
207 AST classes emitted from the D Front-end.
208 All visit methods accept one parameter E, which holds the frontend AST
209 of the expression to compile. They also don't return any value, instead
210 generated code is cached in RESULT_ and returned from the caller. */
212 class ExprVisitor : public Visitor
214 using Visitor::visit;
216 tree result_;
217 bool constp_;
218 bool literalp_;
220 public:
221 ExprVisitor (bool constp, bool literalp)
223 this->result_ = NULL_TREE;
224 this->constp_ = constp;
225 this->literalp_ = literalp;
228 tree result (void)
230 return this->result_;
233 /* Visitor interfaces, each Expression class should have
234 overridden the default. */
236 void visit (Expression *)
238 gcc_unreachable ();
241 /* Build a conditional expression. If either the second or third
242 expression is void, then the resulting type is void. Otherwise
243 they are implicitly converted to a common type. */
245 void visit (CondExp *e)
247 tree cond = convert_for_condition (build_expr (e->econd),
248 e->econd->type);
249 tree t1 = build_expr (e->e1);
250 tree t2 = build_expr (e->e2);
252 if (e->type->ty != Tvoid)
254 t1 = convert_expr (t1, e->e1->type, e->type);
255 t2 = convert_expr (t2, e->e2->type, e->type);
258 this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
261 /* Build an identity comparison expression. Operands go through the
262 usual conversions to bring them to a common type before comparison.
263 The result type is bool. */
265 void visit (IdentityExp *e)
267 tree_code code = (e->op == TOKidentity) ? EQ_EXPR : NE_EXPR;
268 Type *tb1 = e->e1->type->toBasetype ();
269 Type *tb2 = e->e2->type->toBasetype ();
271 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
272 && (tb2->ty == Tsarray || tb2->ty == Tarray))
274 /* For static and dynamic arrays, identity is defined as referring to
275 the same array elements and the same number of elements. */
276 tree t1 = d_array_convert (e->e1);
277 tree t2 = d_array_convert (e->e2);
278 this->result_ = d_convert (build_ctype (e->type),
279 build_boolop (code, t1, t2));
281 else if (tb1->isfloating () && tb1->ty != Tvector)
283 /* For floating-point values, identity is defined as the bits in the
284 operands being identical. */
285 tree t1 = d_save_expr (build_expr (e->e1));
286 tree t2 = d_save_expr (build_expr (e->e2));
288 if (!tb1->iscomplex ())
289 this->result_ = build_float_identity (code, t1, t2);
290 else
292 /* Compare the real and imaginary parts separately. */
293 tree req = build_float_identity (code, real_part (t1),
294 real_part (t2));
295 tree ieq = build_float_identity (code, imaginary_part (t1),
296 imaginary_part (t2));
298 if (code == EQ_EXPR)
299 this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
300 else
301 this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
304 else if (TypeStruct *ts = tb1->isTypeStruct ())
306 /* For struct objects, identity is defined as bits in operands being
307 identical also. Alignment holes in structs are ignored. */
308 tree t1 = build_expr (e->e1);
309 tree t2 = build_expr (e->e2);
311 gcc_assert (same_type_p (tb1, tb2));
313 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
315 else
317 /* For operands of other types, identity is defined as being the
318 same as equality expressions. */
319 tree t1 = build_expr (e->e1);
320 tree t2 = build_expr (e->e2);
321 this->result_ = d_convert (build_ctype (e->type),
322 build_boolop (code, t1, t2));
326 /* Build an equality expression, which compare the two operands for either
327 equality or inequality. Operands go through the usual conversions to bring
328 them to a common type before comparison. The result type is bool. */
330 void visit (EqualExp *e)
332 Type *tb1 = e->e1->type->toBasetype ();
333 Type *tb2 = e->e2->type->toBasetype ();
334 tree_code code = (e->op == TOKequal) ? EQ_EXPR : NE_EXPR;
336 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
337 && (tb2->ty == Tsarray || tb2->ty == Tarray))
339 /* For static and dynamic arrays, equality is defined as the lengths of
340 the arrays matching, and all the elements are equal. */
341 Type *t1elem = tb1->nextOf ()->toBasetype ();
342 Type *t2elem = tb1->nextOf ()->toBasetype ();
344 /* Check if comparisons of arrays can be optimized using memcmp.
345 This will inline EQ expressions as:
346 e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
347 Or when generating a NE expression:
348 e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */
349 if ((t1elem->isintegral () || t1elem->ty == Tvoid
350 || (t1elem->ty == Tstruct && !t1elem->isTypeStruct ()->sym->xeq))
351 && t1elem->ty == t2elem->ty)
353 tree t1 = d_array_convert (e->e1);
354 tree t2 = d_array_convert (e->e2);
355 tree result;
357 /* Make temporaries to prevent multiple evaluations. */
358 tree t1saved = d_save_expr (t1);
359 tree t2saved = d_save_expr (t2);
361 /* Length of arrays, for comparisons done before calling memcmp. */
362 tree t1len = d_array_length (t1saved);
363 tree t2len = d_array_length (t2saved);
365 /* Reference to array data. */
366 tree t1ptr = d_array_ptr (t1saved);
367 tree t2ptr = d_array_ptr (t2saved);
369 /* Compare arrays using memcmp if possible, otherwise for structs,
370 each field is compared inline. */
371 if (t1elem->ty != Tstruct
372 || identity_compare_p (t1elem->isTypeStruct ()->sym))
374 tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
376 result = build_memcmp_call (t1ptr, t2ptr, size);
377 result = build_boolop (code, result, integer_zero_node);
379 else
381 StructDeclaration *sd = t1elem->isTypeStruct ()->sym;
383 result = build_array_struct_comparison (code, sd, t1len,
384 t1ptr, t2ptr);
387 /* Check array length first before passing to memcmp.
388 For equality expressions, this becomes:
389 (e1.length == 0 || memcmp);
390 Otherwise for inequality:
391 (e1.length != 0 && memcmp); */
392 tree tsizecmp = build_boolop (code, t1len, size_zero_node);
393 if (e->op == TOKequal)
394 result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
395 else
396 result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
398 /* Finally, check if lengths of both arrays match if dynamic.
399 The frontend should have already guaranteed that static arrays
400 have same size. */
401 if (tb1->ty == Tsarray && tb2->ty == Tsarray)
402 gcc_assert (tb1->size () == tb2->size ());
403 else
405 tree tlencmp = build_boolop (code, t1len, t2len);
406 if (e->op == TOKequal)
407 result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
408 else
409 result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
412 /* Ensure left-to-right order of evaluation. */
413 if (TREE_SIDE_EFFECTS (t2))
414 result = compound_expr (t2saved, result);
416 if (TREE_SIDE_EFFECTS (t1))
417 result = compound_expr (t1saved, result);
419 this->result_ = result;
421 else
423 /* Use _adEq2() to compare each element. */
424 Type *t1array = t1elem->arrayOf ();
425 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
426 d_array_convert (e->e1),
427 d_array_convert (e->e2),
428 build_typeinfo (e->loc, t1array));
430 if (e->op == TOKnotequal)
431 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
433 this->result_ = result;
436 else if (TypeStruct *ts = tb1->isTypeStruct ())
438 /* Equality for struct objects means the logical product of all
439 equality results of the corresponding object fields. */
440 tree t1 = build_expr (e->e1);
441 tree t2 = build_expr (e->e2);
443 gcc_assert (same_type_p (tb1, tb2));
445 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
447 else if (tb1->ty == Taarray && tb2->ty == Taarray)
449 /* Use _aaEqual() for associative arrays. */
450 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
451 build_typeinfo (e->loc, tb1),
452 build_expr (e->e1),
453 build_expr (e->e2));
455 if (e->op == TOKnotequal)
456 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
458 this->result_ = result;
460 else
462 /* For operands of other types, equality is defined as the bit pattern
463 of the type matches exactly. */
464 tree t1 = build_expr (e->e1);
465 tree t2 = build_expr (e->e2);
467 this->result_ = d_convert (build_ctype (e->type),
468 build_boolop (code, t1, t2));
472 /* Build an `in' expression. This is a condition to see if an element
473 exists in an associative array. The result is a pointer to the
474 element, or null if false. */
476 void visit (InExp *e)
478 Type *tb2 = e->e2->type->toBasetype ();
479 Type *tkey = tb2->isTypeAArray ()->index->toBasetype ();
480 tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
482 /* Build a call to _aaInX(). */
483 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
484 build_expr (e->e2),
485 build_typeinfo (e->loc, tkey),
486 build_address (key));
489 /* Build a relational expression. The result type is bool. */
491 void visit (CmpExp *e)
493 Type *tb1 = e->e1->type->toBasetype ();
494 Type *tb2 = e->e2->type->toBasetype ();
496 tree result;
497 tree_code code;
499 switch (e->op)
501 case TOKle:
502 code = LE_EXPR;
503 break;
505 case TOKlt:
506 code = LT_EXPR;
507 break;
509 case TOKge:
510 code = GE_EXPR;
511 break;
513 case TOKgt:
514 code = GT_EXPR;
515 break;
517 default:
518 gcc_unreachable ();
521 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
522 && (tb2->ty == Tsarray || tb2->ty == Tarray))
524 /* For static and dynamic arrays, the result of the relational op is
525 the result of the operator applied to the first non-equal element
526 of the array. If two arrays compare equal, but are of different
527 lengths, the shorter array compares as less than the longer. */
528 Type *telem = tb1->nextOf ()->toBasetype ();
530 tree call = build_libcall (LIBCALL_ADCMP2, Type::tint32, 3,
531 d_array_convert (e->e1),
532 d_array_convert (e->e2),
533 build_typeinfo (e->loc, telem->arrayOf ()));
534 result = build_boolop (code, call, integer_zero_node);
536 this->result_ = d_convert (build_ctype (e->type), result);
537 return;
540 /* Simple comparison. */
541 result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
542 this->result_ = d_convert (build_ctype (e->type), result);
545 /* Build a logical `and if' or `or if' expression. If the right operand
546 expression is void, then the resulting type is void. Otherwise the
547 result is bool. */
549 void visit (LogicalExp *e)
551 tree_code code = (e->op == TOKandand) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
553 if (e->e2->type->toBasetype ()->ty != Tvoid)
555 tree t1 = build_expr (e->e1);
556 tree t2 = build_expr (e->e2);
558 t1 = convert_for_condition (t1, e->e1->type);
559 t2 = convert_for_condition (t2, e->e2->type);
561 this->result_ = d_convert (build_ctype (e->type),
562 build_boolop (code, t1, t2));
564 else
566 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
567 tree t2 = build_expr_dtor (e->e2);
569 /* Invert condition for logical or if expression. */
570 if (e->op == TOKoror)
571 t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);
573 this->result_ = build_condition (build_ctype (e->type),
574 t1, t2, void_node);
578 /* Build a binary operand expression. Operands go through usual arithmetic
579 conversions to bring them to a common type before evaluating. */
581 void visit (BinExp *e)
583 tree_code code;
585 switch (e->op)
587 case TOKadd:
588 case TOKmin:
589 if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
590 || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
592 /* If the result is complex, then we can shortcut binary_op.
593 Frontend should have already validated types and sizes. */
594 tree t1 = build_expr (e->e1);
595 tree t2 = build_expr (e->e2);
597 if (e->op == TOKmin)
598 t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
600 if (e->e1->type->isreal ())
601 this->result_ = complex_expr (build_ctype (e->type), t1, t2);
602 else
603 this->result_ = complex_expr (build_ctype (e->type), t2, t1);
605 return;
607 else
608 code = (e->op == TOKadd)
609 ? PLUS_EXPR : MINUS_EXPR;
610 break;
612 case TOKmul:
613 code = MULT_EXPR;
614 break;
616 case TOKdiv:
617 /* Determine if the div expression is a lowered pointer diff operation.
618 The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */
619 if (MinExp *me = e->e1->isMinExp ())
621 if (me->e1->type->ty == Tpointer && me->e2->type->ty == Tpointer
622 && e->e2->op == TOKint64)
624 code = EXACT_DIV_EXPR;
625 break;
629 code = e->e1->type->isintegral ()
630 ? TRUNC_DIV_EXPR : RDIV_EXPR;
631 break;
633 case TOKmod:
634 code = e->e1->type->isfloating ()
635 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
636 break;
638 case TOKand:
639 code = BIT_AND_EXPR;
640 break;
642 case TOKor:
643 code = BIT_IOR_EXPR;
644 break;
646 case TOKxor:
647 code = BIT_XOR_EXPR;
648 break;
650 case TOKshl:
651 code = LSHIFT_EXPR;
652 break;
654 case TOKshr:
655 code = RSHIFT_EXPR;
656 break;
658 case TOKushr:
659 code = UNSIGNED_RSHIFT_EXPR;
660 break;
662 default:
663 gcc_unreachable ();
666 this->result_ = binary_op (code, build_ctype (e->type),
667 build_expr (e->e1), build_expr (e->e2));
671 /* Build a concat expression, which concatenates two or more arrays of the
672 same type, producing a dynamic array with the result. If one operand
673 is an element type, that element is converted to an array of length 1. */
675 void visit (CatExp *e)
677 Type *tb1 = e->e1->type->toBasetype ();
678 Type *tb2 = e->e2->type->toBasetype ();
679 Type *etype;
681 if (tb1->ty == Tarray || tb1->ty == Tsarray)
682 etype = tb1->nextOf ();
683 else
684 etype = tb2->nextOf ();
686 tree result;
688 if (e->e1->op == TOKcat)
690 /* Flatten multiple concatenations to an array.
691 So the expression ((a ~ b) ~ c) becomes [a, b, c] */
692 int ndims = 2;
694 for (Expression *ex = e->e1; ex->op == TOKcat;)
696 if (ex->op == TOKcat)
698 ex = ex->isCatExp ()->e1;
699 ndims++;
703 /* Store all concatenation args to a temporary byte[][ndims] array. */
704 Type *targselem = Type::tint8->arrayOf ();
705 tree var = build_local_temp (make_array_type (targselem, ndims));
707 /* Loop through each concatenation from right to left. */
708 vec <constructor_elt, va_gc> *elms = NULL;
709 CatExp *ce = e;
710 int dim = ndims - 1;
712 for (Expression *oe = ce->e2; oe != NULL;
713 (ce->e1->op != TOKcat
714 ? (oe = ce->e1)
715 : (ce = ce->e1->isCatExp (), oe = ce->e2)))
717 tree arg = d_array_convert (etype, oe);
718 tree index = size_int (dim);
719 CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));
721 /* Finished pushing all arrays. */
722 if (oe == ce->e1)
723 break;
725 dim -= 1;
728 /* Check there is no logic bug in constructing byte[][] of arrays. */
729 gcc_assert (dim == 0);
730 tree init = build_constructor (TREE_TYPE (var), elms);
731 var = compound_expr (modify_expr (var, init), var);
733 tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
734 size_int (ndims), build_address (var));
736 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
737 build_typeinfo (e->loc, e->type), arrs);
739 else
741 /* Handle single concatenation (a ~ b). */
742 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
743 build_typeinfo (e->loc, e->type),
744 d_array_convert (etype, e->e1),
745 d_array_convert (etype, e->e2));
748 this->result_ = result;
751 /* Build an assignment operator expression. The right operand is implicitly
752 converted to the type of the left operand, and assigned to it. */
754 void visit (BinAssignExp *e)
756 tree_code code;
757 Expression *e1b = e->e1;
759 switch (e->op)
761 case TOKaddass:
762 code = PLUS_EXPR;
763 break;
765 case TOKminass:
766 code = MINUS_EXPR;
767 break;
769 case TOKmulass:
770 code = MULT_EXPR;
771 break;
773 case TOKdivass:
774 code = e->e1->type->isintegral ()
775 ? TRUNC_DIV_EXPR : RDIV_EXPR;
776 break;
778 case TOKmodass:
779 code = e->e1->type->isfloating ()
780 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
781 break;
783 case TOKandass:
784 code = BIT_AND_EXPR;
785 break;
787 case TOKorass:
788 code = BIT_IOR_EXPR;
789 break;
791 case TOKxorass:
792 code = BIT_XOR_EXPR;
793 break;
795 case TOKpowass:
796 gcc_unreachable ();
798 case TOKshlass:
799 code = LSHIFT_EXPR;
800 break;
802 case TOKshrass:
803 case TOKushrass:
804 /* Use the original lhs type before it was promoted. The left operand
805 of `>>>=' does not undergo integral promotions before shifting.
806 Strip off casts just incase anyway. */
807 while (e1b->op == TOKcast)
809 CastExp *ce = e1b->isCastExp ();
810 gcc_assert (same_type_p (ce->type, ce->to));
811 e1b = ce->e1;
813 code = (e->op == TOKshrass) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
814 break;
816 default:
817 gcc_unreachable ();
820 tree exp = binop_assignment (code, e1b, e->e2);
821 this->result_ = convert_expr (exp, e1b->type, e->type);
824 /* Build a concat assignment expression. The right operand is appended
825 to the left operand. */
827 void visit (CatAssignExp *e)
829 Type *tb1 = e->e1->type->toBasetype ();
830 Type *tb2 = e->e2->type->toBasetype ();
831 Type *etype = tb1->nextOf ()->toBasetype ();
833 /* Save the address of `e1', so it can be evaluated first.
834 As all D run-time library functions for concat assignments update `e1'
835 in-place and then return its value, the saved address can also be used as
836 the result of this expression as well. */
837 tree lhs = build_expr (e->e1);
838 tree lexpr = stabilize_expr (&lhs);
839 tree ptr = d_save_expr (build_address (lhs));
840 tree result = NULL_TREE;
842 if (tb1->ty == Tarray && tb2->ty == Tdchar
843 && (etype->ty == Tchar || etype->ty == Twchar))
845 /* Append a dchar to a char[] or wchar[]:
846 The assignment is handled by the D run-time library, so only
847 need to call `_d_arrayappend[cw]d(&e1, e2)' */
848 libcall_fn libcall = (etype->ty == Tchar)
849 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
851 result = build_libcall (libcall, e->type, 2,
852 ptr, build_expr (e->e2));
854 else
856 gcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray);
858 if ((tb2->ty == Tarray || tb2->ty == Tsarray)
859 && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
861 /* Append an array to another array:
862 The assignment is handled by the D run-time library, so only
863 need to call `_d_arrayappendT(ti, &e1, e2)' */
864 result = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
865 build_typeinfo (e->loc, e->type),
866 ptr, d_array_convert (e->e2));
868 else if (same_type_p (etype, tb2))
870 /* Append an element to an array:
871 The assignment is generated inline, so need to handle temporaries
872 here, and ensure that they are evaluated in the correct order.
874 The generated code should end up being equivalent to:
875 _d_arrayappendcTX(ti, &e1, 1)[e1.length - 1] = e2
877 tree callexp = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
878 build_typeinfo (e->loc, e->type),
879 ptr, size_one_node);
880 callexp = d_save_expr (callexp);
882 /* Assign e2 to last element. */
883 tree offexp = d_array_length (callexp);
884 offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
885 offexp, size_one_node);
887 tree ptrexp = d_array_ptr (callexp);
888 ptrexp = void_okay_p (ptrexp);
889 ptrexp = build_array_index (ptrexp, offexp);
891 /* Evaluate expression before appending. */
892 tree rhs = build_expr (e->e2);
893 tree rexpr = stabilize_expr (&rhs);
895 if (TREE_CODE (rhs) == CALL_EXPR)
896 rhs = force_target_expr (rhs);
898 result = modify_expr (build_deref (ptrexp), rhs);
899 result = compound_expr (rexpr, result);
901 else
902 gcc_unreachable ();
905 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
906 result = compound_expr (compound_expr (lexpr, ptr), result);
907 this->result_ = compound_expr (result, build_deref (ptr));
910 /* Build an assignment expression. The right operand is implicitly
911 converted to the type of the left operand, and assigned to it. */
913 void visit (AssignExp *e)
915 /* First, handle special assignment semantics. */
917 /* Look for array.length = n; */
918 if (e->e1->op == TOKarraylength)
920 /* Assignment to an array's length property; resize the array. */
921 ArrayLengthExp *ale = e->e1->isArrayLengthExp ();
922 tree newlength = convert_expr (build_expr (e->e2), e->e2->type,
923 Type::tsize_t);
924 tree ptr = build_address (build_expr (ale->e1));
926 /* Don't want the basetype for the element type. */
927 Type *etype = ale->e1->type->toBasetype ()->nextOf ();
928 libcall_fn libcall = etype->isZeroInit ()
929 ? LIBCALL_ARRAYSETLENGTHT : LIBCALL_ARRAYSETLENGTHIT;
931 tree result = build_libcall (libcall, ale->e1->type, 3,
932 build_typeinfo (ale->loc, ale->e1->type),
933 newlength, ptr);
935 this->result_ = d_array_length (result);
936 return;
939 /* Look for array[] = n; */
940 if (e->e1->op == TOKslice)
942 SliceExp *se = e->e1->isSliceExp ();
943 Type *stype = se->e1->type->toBasetype ();
944 Type *etype = stype->nextOf ()->toBasetype ();
946 /* Determine if we need to run postblit or dtor. */
947 bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
948 bool destructor = needs_dtor (etype);
950 if (e->memset & blockAssign)
952 /* Set a range of elements to one value. */
953 tree t1 = d_save_expr (build_expr (e->e1));
954 tree t2 = build_expr (e->e2);
955 tree result;
957 if ((postblit || destructor) && e->op != TOKblit)
959 libcall_fn libcall = (e->op == TOKconstruct)
960 ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN;
961 /* So we can call postblits on const/immutable objects. */
962 Type *tm = etype->unSharedOf ()->mutableOf ();
963 tree ti = build_typeinfo (e->loc, tm);
965 tree result = build_libcall (libcall, Type::tvoid, 4,
966 d_array_ptr (t1),
967 build_address (t2),
968 d_array_length (t1), ti);
969 this->result_ = compound_expr (result, t1);
970 return;
973 if (integer_zerop (t2))
975 tree size = size_mult_expr (d_array_length (t1),
976 size_int (etype->size ()));
977 result = build_memset_call (d_array_ptr (t1), size);
979 else
980 result = build_array_set (d_array_ptr (t1),
981 d_array_length (t1), t2);
983 this->result_ = compound_expr (result, t1);
985 else
987 /* Perform a memcpy operation. */
988 gcc_assert (e->e2->type->ty != Tpointer);
990 if (!postblit && !destructor)
992 tree t1 = d_save_expr (d_array_convert (e->e1));
993 tree t2 = d_save_expr (d_array_convert (e->e2));
995 /* References to array data. */
996 tree t1ptr = d_array_ptr (t1);
997 tree t1len = d_array_length (t1);
998 tree t2ptr = d_array_ptr (t2);
1000 /* Generate: memcpy(to, from, size) */
1001 tree size = size_mult_expr (t1len, size_int (etype->size ()));
1002 tree result = build_memcpy_call (t1ptr, t2ptr, size);
1004 /* Insert check that array lengths match and do not overlap. */
1005 if (array_bounds_check ())
1007 /* tlencmp = (t1len == t2len) */
1008 tree t2len = d_array_length (t2);
1009 tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len);
1011 /* toverlap = (t1ptr + size <= t2ptr
1012 || t2ptr + size <= t1ptr) */
1013 tree t1ptrcmp = build_boolop (LE_EXPR,
1014 build_offset (t1ptr, size),
1015 t2ptr);
1016 tree t2ptrcmp = build_boolop (LE_EXPR,
1017 build_offset (t2ptr, size),
1018 t1ptr);
1019 tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp,
1020 t2ptrcmp);
1022 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */
1023 tree tassert = build_array_bounds_call (e->loc);
1024 tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR,
1025 tlencmp, toverlap);
1027 result = build_condition (void_type_node, tboundscheck,
1028 result, tassert);
1031 this->result_ = compound_expr (result, t1);
1033 else if ((postblit || destructor) && e->op != TOKblit)
1035 /* Generate: _d_arrayassign(ti, from, to)
1036 or: _d_arrayctor(ti, from, to) */
1037 libcall_fn libcall = (e->op == TOKconstruct)
1038 ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN;
1040 this->result_ = build_libcall (libcall, e->type, 3,
1041 build_typeinfo (e->loc, etype),
1042 d_array_convert (e->e2),
1043 d_array_convert (e->e1));
1045 else
1047 /* Generate: _d_arraycopy() */
1048 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
1049 size_int (etype->size ()),
1050 d_array_convert (e->e2),
1051 d_array_convert (e->e1));
1055 return;
1058 /* Look for reference initializations. */
1059 if (e->memset & referenceInit)
1061 gcc_assert (e->op == TOKconstruct || e->op == TOKblit);
1062 gcc_assert (e->e1->op == TOKvar);
1064 Declaration *decl = e->e1->isVarExp ()->var;
1065 if (decl->storage_class & (STCout | STCref))
1067 tree t2 = convert_for_assignment (build_expr (e->e2),
1068 e->e2->type, e->e1->type);
1069 tree t1 = build_expr (e->e1);
1070 /* Want reference to lhs, not indirect ref. */
1071 t1 = TREE_OPERAND (t1, 0);
1072 t2 = build_address (t2);
1074 this->result_ = indirect_ref (build_ctype (e->type),
1075 build_assign (INIT_EXPR, t1, t2));
1076 return;
1080 /* Other types of assignments that may require post construction. */
1081 Type *tb1 = e->e1->type->toBasetype ();
1082 tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR;
1084 /* Look for struct assignment. */
1085 if (tb1->ty == Tstruct)
1087 tree t1 = build_expr (e->e1);
1088 tree t2 = convert_for_assignment (build_expr (e->e2, false, true),
1089 e->e2->type, e->e1->type);
1090 StructDeclaration *sd = tb1->isTypeStruct ()->sym;
1092 /* Look for struct = 0. */
1093 if (e->e2->op == TOKint64)
1095 /* Use memset to fill struct. */
1096 gcc_assert (e->op == TOKblit);
1097 tree result = build_memset_call (t1);
1099 /* Maybe set-up hidden pointer to outer scope context. */
1100 if (sd->isNested ())
1102 tree field = get_symbol_decl (sd->vthis);
1103 tree value = build_vthis (sd);
1105 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1106 result = compound_expr (result, vthis_exp);
1109 this->result_ = compound_expr (result, t1);
1111 else
1113 /* Simple struct literal assignment. */
1114 tree init = NULL_TREE;
1116 /* Fill any alignment holes in the struct using memset. */
1117 if ((e->op == TOKconstruct
1118 || (e->e2->op == TOKstructliteral && e->op == TOKblit))
1119 && (sd->isUnionDeclaration () || !identity_compare_p (sd)))
1121 t1 = stabilize_reference (t1);
1122 init = build_memset_call (t1);
1125 /* Elide generating assignment if init is all zeroes. */
1126 if (init != NULL_TREE && initializer_zerop (t2))
1127 this->result_ = compound_expr (init, t1);
1128 else
1130 tree result = build_assign (modifycode, t1, t2);
1131 this->result_ = compound_expr (init, result);
1135 return;
1138 /* Look for static array assignment. */
1139 if (tb1->ty == Tsarray)
1141 /* Look for array = 0. */
1142 if (e->e2->op == TOKint64)
1144 /* Use memset to fill the array. */
1145 gcc_assert (e->op == TOKblit);
1146 this->result_ = build_memset_call (build_expr (e->e1));
1147 return;
1150 Type *etype = tb1->nextOf ();
1151 gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);
1153 /* Determine if we need to run postblit. */
1154 bool postblit = needs_postblit (etype);
1155 bool destructor = needs_dtor (etype);
1156 bool lvalue = lvalue_p (e->e2);
1158 /* Optimize static array assignment with array literal. Even if the
1159 elements in rhs are all rvalues and don't have to call postblits,
1160 this assignment should call dtors on old assigned elements. */
1161 if ((!postblit && !destructor)
1162 || (e->op == TOKconstruct && e->e2->op == TOKarrayliteral)
1163 || (e->op == TOKconstruct && !lvalue && postblit)
1164 || (e->op == TOKblit || e->e1->type->size () == 0))
1166 tree t1 = build_expr (e->e1);
1167 tree t2 = convert_for_assignment (build_expr (e->e2),
1168 e->e2->type, e->e1->type);
1170 this->result_ = build_assign (modifycode, t1, t2);
1171 return;
1174 Type *arrtype = (e->type->ty == Tsarray) ? etype->arrayOf () : e->type;
1175 tree result;
1177 if (e->op == TOKconstruct)
1179 /* Generate: _d_arrayctor(ti, from, to) */
1180 result = build_libcall (LIBCALL_ARRAYCTOR, arrtype, 3,
1181 build_typeinfo (e->loc, etype),
1182 d_array_convert (e->e2),
1183 d_array_convert (e->e1));
1185 else
1187 /* Generate: _d_arrayassign_l()
1188 or: _d_arrayassign_r() */
1189 libcall_fn libcall = (lvalue)
1190 ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
1191 tree elembuf = build_local_temp (build_ctype (etype));
1193 result = build_libcall (libcall, arrtype, 4,
1194 build_typeinfo (e->loc, etype),
1195 d_array_convert (e->e2),
1196 d_array_convert (e->e1),
1197 build_address (elembuf));
1200 /* Cast the libcall result back to a static array. */
1201 if (e->type->ty == Tsarray)
1202 result = indirect_ref (build_ctype (e->type),
1203 d_array_ptr (result));
1205 this->result_ = result;
1206 return;
1209 /* Simple assignment. */
1210 tree t1 = build_expr (e->e1);
1211 tree t2 = convert_for_assignment (build_expr (e->e2),
1212 e->e2->type, e->e1->type);
1214 this->result_ = build_assign (modifycode, t1, t2);
1217 /* Build a postfix expression. */
1219 void visit (PostExp *e)
1221 tree result;
1223 if (e->op == TOKplusplus)
1225 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1226 build_expr (e->e1), build_expr (e->e2));
1228 else if (e->op == TOKminusminus)
1230 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1231 build_expr (e->e1), build_expr (e->e2));
1233 else
1234 gcc_unreachable ();
1236 TREE_SIDE_EFFECTS (result) = 1;
1237 this->result_ = result;
1240 /* Build an index expression. */
1242 void visit (IndexExp *e)
1244 Type *tb1 = e->e1->type->toBasetype ();
1246 if (tb1->ty == Taarray)
1248 /* Get the key for the associative array. */
1249 Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
1250 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1251 libcall_fn libcall;
1252 tree tinfo, ptr;
1254 if (e->modifiable)
1256 libcall = LIBCALL_AAGETY;
1257 ptr = build_address (build_expr (e->e1));
1258 tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());
1260 else
1262 libcall = LIBCALL_AAGETRVALUEX;
1263 ptr = build_expr (e->e1);
1264 tinfo = build_typeinfo (e->loc, tkey);
1267 /* Index the associative array. */
1268 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1269 ptr, tinfo,
1270 size_int (tb1->nextOf ()->size ()),
1271 build_address (key));
1273 if (!e->indexIsInBounds && array_bounds_check ())
1275 tree tassert = build_array_bounds_call (e->loc);
1277 result = d_save_expr (result);
1278 result = build_condition (TREE_TYPE (result),
1279 d_truthvalue_conversion (result),
1280 result, tassert);
1283 this->result_ = indirect_ref (build_ctype (e->type), result);
1285 else
1287 /* Get the data pointer and length for static and dynamic arrays. */
1288 tree array = d_save_expr (build_expr (e->e1));
1289 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1291 tree length = NULL_TREE;
1292 if (tb1->ty != Tpointer)
1293 length = get_array_length (array, tb1);
1294 else
1295 gcc_assert (e->lengthVar == NULL);
1297 /* The __dollar variable just becomes a placeholder for the
1298 actual length. */
1299 if (e->lengthVar)
1300 e->lengthVar->csym = length;
1302 /* Generate the index. */
1303 tree index = build_expr (e->e2);
1305 /* If it's a static array and the index is constant, the front end has
1306 already checked the bounds. */
1307 if (tb1->ty != Tpointer)
1308 index = build_bounds_index_condition (e, index, length);
1310 /* Index the .ptr. */
1311 ptr = void_okay_p (ptr);
1312 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1313 build_array_index (ptr, index));
1317 /* Build a comma expression. The type is the type of the right operand. */
1319 void visit (CommaExp *e)
1321 tree t1 = build_expr (e->e1);
1322 tree t2 = build_expr (e->e2);
1323 tree type = e->type ? build_ctype (e->type) : void_type_node;
1325 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1328 /* Build an array length expression. Returns the number of elements
1329 in the array. The result is of type size_t. */
1331 void visit (ArrayLengthExp *e)
1333 if (e->e1->type->toBasetype ()->ty == Tarray)
1334 this->result_ = d_array_length (build_expr (e->e1));
1335 else
1337 /* Static arrays have already been handled by the front-end. */
1338 error ("unexpected type for array length: %qs", e->type->toChars ());
1339 this->result_ = error_mark_node;
1343 /* Build a delegate pointer expression. This will return the frame
1344 pointer value as a type void*. */
1346 void visit (DelegatePtrExp *e)
1348 tree t1 = build_expr (e->e1);
1349 this->result_ = delegate_object (t1);
1352 /* Build a delegate function pointer expression. This will return the
1353 function pointer value as a function type. */
1355 void visit (DelegateFuncptrExp *e)
1357 tree t1 = build_expr (e->e1);
1358 this->result_ = delegate_method (t1);
1361 /* Build a slice expression. */
1363 void visit (SliceExp *e)
1365 Type *tb = e->type->toBasetype ();
1366 Type *tb1 = e->e1->type->toBasetype ();
1367 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray);
1369 /* Use convert-to-dynamic-array code if possible. */
1370 if (!e->lwr)
1372 tree result = build_expr (e->e1);
1373 if (e->e1->type->toBasetype ()->ty == Tsarray)
1374 result = convert_expr (result, e->e1->type, e->type);
1376 this->result_ = result;
1377 return;
1379 else
1380 gcc_assert (e->upr != NULL);
1382 /* Get the data pointer and length for static and dynamic arrays. */
1383 tree array = d_save_expr (build_expr (e->e1));
1384 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1385 tree length = NULL_TREE;
1387 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1388 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1389 if (tb1->ty != Tpointer)
1390 length = get_array_length (array, tb1);
1391 else
1392 gcc_assert (e->lengthVar == NULL);
1394 /* The __dollar variable just becomes a placeholder for the
1395 actual length. */
1396 if (e->lengthVar)
1397 e->lengthVar->csym = length;
1399 /* Generate upper and lower bounds. */
1400 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1401 tree upr_tree = d_save_expr (build_expr (e->upr));
1403 /* If the upper bound has any side effects, then the lower bound should be
1404 copied to a temporary always. */
1405 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1406 lwr_tree = save_expr (lwr_tree);
1408 /* Adjust the .ptr offset. */
1409 if (!integer_zerop (lwr_tree))
1411 tree ptrtype = TREE_TYPE (ptr);
1412 ptr = build_array_index (void_okay_p (ptr), lwr_tree);
1413 ptr = build_nop (ptrtype, ptr);
1416 /* Nothing more to do for static arrays, their bounds checking has been
1417 done at compile-time. */
1418 if (tb->ty == Tsarray)
1420 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1421 return;
1423 else
1424 gcc_assert (tb->ty == Tarray);
1426 /* Generate bounds checking code. */
1427 tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree,
1428 length);
1429 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1430 this->result_ = compound_expr (array, result);
1433 /* Build a cast expression, which converts the given unary expression to the
1434 type of result. */
1436 void visit (CastExp *e)
1438 Type *ebtype = e->e1->type->toBasetype ();
1439 Type *tbtype = e->to->toBasetype ();
1440 tree result = build_expr (e->e1, this->constp_, this->literalp_);
1442 /* Just evaluate e1 if it has any side effects. */
1443 if (tbtype->ty == Tvoid)
1444 this->result_ = build_nop (build_ctype (tbtype), result);
1445 else
1446 this->result_ = convert_for_rvalue (result, ebtype, tbtype);
1449 /* Build a delete expression. */
1451 void visit (DeleteExp *e)
1453 tree t1 = build_expr (e->e1);
1454 Type *tb1 = e->e1->type->toBasetype ();
1456 if (tb1->ty == Tclass)
1458 /* For class object references, if there is a destructor for that class,
1459 the destructor is called for the object instance. */
1460 libcall_fn libcall;
1462 if (e->e1->op == TOKvar)
1464 VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
1465 if (v && v->onstack)
1467 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1468 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1470 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1471 return;
1475 /* Otherwise, the garbage collector is called to immediately free the
1476 memory allocated for the class instance. */
1477 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1478 ? LIBCALL_DELINTERFACE : LIBCALL_DELCLASS;
1480 t1 = build_address (t1);
1481 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1483 else if (tb1->ty == Tarray)
1485 /* For dynamic arrays, the garbage collector is called to immediately
1486 release the memory. */
1487 Type *telem = tb1->nextOf ()->baseElemOf ();
1488 tree ti = null_pointer_node;
1490 if (TypeStruct *ts = telem->isTypeStruct ())
1492 /* Might need to run destructor on array contents. */
1493 if (ts->sym->dtor)
1494 ti = build_typeinfo (e->loc, tb1->nextOf ());
1497 /* Generate: _delarray_t (&t1, ti); */
1498 this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,
1499 build_address (t1), ti);
1501 else if (tb1->ty == Tpointer)
1503 /* For pointers to a struct instance, if the struct has overloaded
1504 operator delete, then that operator is called. */
1505 t1 = build_address (t1);
1506 Type *tnext = tb1->isTypePointer ()->next->toBasetype ();
1508 if (TypeStruct *ts = tnext->isTypeStruct ())
1510 if (ts->sym->dtor)
1512 tree ti = build_typeinfo (e->loc, tnext);
1513 this->result_ = build_libcall (LIBCALL_DELSTRUCT, Type::tvoid,
1514 2, t1, ti);
1515 return;
1519 /* Otherwise, the garbage collector is called to immediately free the
1520 memory allocated for the pointer. */
1521 this->result_ = build_libcall (LIBCALL_DELMEMORY, Type::tvoid, 1, t1);
1523 else
1525 error ("don%'t know how to delete %qs", e->e1->toChars ());
1526 this->result_ = error_mark_node;
1530 /* Build a remove expression, which removes a particular key from an
1531 associative array. */
1533 void visit (RemoveExp *e)
1535 /* Check that the array is actually an associative array. */
1536 if (e->e1->type->toBasetype ()->ty == Taarray)
1538 Type *tb = e->e1->type->toBasetype ();
1539 Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
1540 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1542 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1543 build_expr (e->e1),
1544 build_typeinfo (e->loc, tkey),
1545 build_address (index));
1547 else
1549 error ("%qs is not an associative array", e->e1->toChars ());
1550 this->result_ = error_mark_node;
1554 /* Build an unary not expression. */
1556 void visit (NotExp *e)
1558 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1559 /* Need to convert to boolean type or this will fail. */
1560 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1562 this->result_ = d_convert (build_ctype (e->type), result);
1565 /* Build a compliment expression, where all the bits in the value are
1566 complemented. Note: unlike in C, the usual integral promotions
1567 are not performed prior to the complement operation. */
1569 void visit (ComExp *e)
1571 TY ty1 = e->e1->type->toBasetype ()->ty;
1572 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1574 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1575 build_expr (e->e1));
1578 /* Build an unary negation expression. */
1580 void visit (NegExp *e)
1582 TY ty1 = e->e1->type->toBasetype ()->ty;
1583 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1585 tree type = build_ctype (e->type);
1586 tree expr = build_expr (e->e1);
1588 /* If the operation needs excess precision. */
1589 tree eptype = excess_precision_type (type);
1590 if (eptype != NULL_TREE)
1591 expr = d_convert (eptype, expr);
1592 else
1593 eptype = type;
1595 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1596 this->result_ = d_convert (type, ret);
1599 /* Build a pointer index expression. */
1601 void visit (PtrExp *e)
1603 Type *tnext = NULL;
1604 size_t offset;
1605 tree result;
1607 if (e->e1->op == TOKadd)
1609 AddExp *ae = e->e1->isAddExp ();
1610 if (ae->e1->op == TOKaddress
1611 && ae->e2->isConst () && ae->e2->type->isintegral ())
1613 Expression *ex = ae->e1->isAddrExp ()->e1;
1614 tnext = ex->type->toBasetype ();
1615 result = build_expr (ex);
1616 offset = ae->e2->toUInteger ();
1619 else if (e->e1->op == TOKsymoff)
1621 SymOffExp *se = e->e1->isSymOffExp ();
1622 if (!declaration_reference_p (se->var))
1624 tnext = se->var->type->toBasetype ();
1625 result = get_decl_tree (se->var);
1626 offset = se->offset;
1630 /* Produce better code by converting *(#record + n) to
1631 COMPONENT_REFERENCE. Otherwise, the variable will always be
1632 allocated in memory because its address is taken. */
1633 if (tnext && tnext->ty == Tstruct)
1635 StructDeclaration *sd = tnext->isTypeStruct ()->sym;
1637 for (size_t i = 0; i < sd->fields.length; i++)
1639 VarDeclaration *field = sd->fields[i];
1641 if (field->offset == offset
1642 && same_type_p (field->type, e->type))
1644 /* Catch errors, backend will ICE otherwise. */
1645 if (error_operand_p (result))
1646 this->result_ = result;
1647 else
1649 result = component_ref (result, get_symbol_decl (field));
1650 this->result_ = result;
1652 return;
1654 else if (field->offset > offset)
1655 break;
1659 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1662 /* Build an unary address expression. */
1664 void visit (AddrExp *e)
1666 tree type = build_ctype (e->type);
1667 tree exp;
1669 /* The frontend optimizer can convert const symbol into a struct literal.
1670 Taking the address of a struct literal is otherwise illegal. */
1671 if (e->e1->op == TOKstructliteral)
1673 StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
1674 gcc_assert (sle != NULL);
1676 /* Build the reference symbol, the decl is built first as the
1677 initializer may have recursive references. */
1678 if (!sle->sym)
1680 sle->sym = build_artificial_decl (build_ctype (sle->type),
1681 NULL_TREE, "S");
1682 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1683 d_pushdecl (sle->sym);
1684 rest_of_decl_compilation (sle->sym, 1, 0);
1687 exp = sle->sym;
1689 else
1690 exp = build_expr (e->e1, this->constp_, this->literalp_);
1692 TREE_CONSTANT (exp) = 0;
1693 this->result_ = d_convert (type, build_address (exp));
1696 /* Build a function call expression. */
1698 void visit (CallExp *e)
1700 Type *tb = e->e1->type->toBasetype ();
1701 Expression *e1b = e->e1;
1703 tree callee = NULL_TREE;
1704 tree object = NULL_TREE;
1705 tree cleanup = NULL_TREE;
1706 tree returnvalue = NULL_TREE;
1707 TypeFunction *tf = NULL;
1709 /* Calls to delegates can sometimes look like this. */
1710 if (e1b->op == TOKcomma)
1712 e1b = e1b->isCommaExp ()->e2;
1713 gcc_assert (e1b->op == TOKvar);
1715 Declaration *var = e1b->isVarExp ()->var;
1716 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1719 if (e1b->op == TOKdotvar && tb->ty != Tdelegate)
1721 DotVarExp *dve = e1b->isDotVarExp ();
1723 /* Don't modify the static initializer for struct literals. */
1724 if (dve->e1->op == TOKstructliteral)
1726 StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
1727 sle->useStaticInit = false;
1730 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1731 if (fd != NULL)
1733 /* Get the correct callee from the DotVarExp object. */
1734 tree fndecl = get_symbol_decl (fd);
1735 AggregateDeclaration *ad = fd->isThis ();
1737 /* Static method; ignore the object instance. */
1738 if (!ad)
1739 callee = build_address (fndecl);
1740 else
1742 tree thisexp = build_expr (dve->e1);
1744 /* When constructing temporaries, if the constructor throws,
1745 then the object is destructed even though it is not a fully
1746 constructed object yet. And so this call will need to be
1747 moved inside the TARGET_EXPR_INITIAL slot. */
1748 if (fd->isCtorDeclaration ()
1749 && TREE_CODE (thisexp) == COMPOUND_EXPR
1750 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1751 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1753 cleanup = TREE_OPERAND (thisexp, 0);
1754 thisexp = TREE_OPERAND (thisexp, 1);
1757 if (TREE_CODE (thisexp) == CONSTRUCTOR)
1758 thisexp = force_target_expr (thisexp);
1760 /* Want reference to `this' object. */
1761 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1762 thisexp = build_address (thisexp);
1764 /* Make the callee a virtual call. */
1765 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1767 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1768 tree thistype = build_ctype (ad->handleType ());
1769 thisexp = build_nop (thistype, d_save_expr (thisexp));
1770 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1772 else
1773 fndecl = build_address (fndecl);
1775 /* C++ constructors return void, even though front-end semantic
1776 treats them as implicitly returning `this'. Set returnvalue
1777 to override the result of this expression. */
1778 if (fd->isCtorDeclaration () && fd->linkage == LINKcpp)
1780 thisexp = d_save_expr (thisexp);
1781 returnvalue = thisexp;
1784 callee = build_method_call (fndecl, thisexp, fd->type);
1789 if (callee == NULL_TREE)
1790 callee = build_expr (e1b);
1792 if (METHOD_CALL_EXPR (callee))
1794 /* This could be a delegate expression (TY == Tdelegate), but not
1795 actually a delegate variable. */
1796 if (e1b->op == TOKdotvar)
1798 /* This gets the true function type, getting the function type
1799 from e1->type can sometimes be incorrect, such as when calling
1800 a `ref' return function. */
1801 tf = get_function_type (e1b->isDotVarExp ()->var->type);
1803 else
1804 tf = get_function_type (tb);
1806 extract_from_method_call (callee, callee, object);
1808 else if (tb->ty == Tdelegate)
1810 /* Delegate call, extract .object and .funcptr from var. */
1811 callee = d_save_expr (callee);
1812 tf = get_function_type (tb);
1813 object = delegate_object (callee);
1814 callee = delegate_method (callee);
1816 else if (e1b->op == TOKvar)
1818 FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
1819 gcc_assert (fd != NULL);
1820 tf = get_function_type (fd->type);
1822 if (fd->isNested ())
1824 /* Maybe re-evaluate symbol storage treating `fd' as public. */
1825 if (call_by_alias_p (d_function_chain->function, fd))
1826 TREE_PUBLIC (callee) = 1;
1828 object = get_frame_for_symbol (fd);
1830 else if (fd->needThis ())
1832 error_at (make_location_t (e1b->loc),
1833 "need %<this%> to access member %qs", fd->toChars ());
1834 /* Continue compiling... */
1835 object = null_pointer_node;
1838 else
1840 /* Normal direct function call. */
1841 tf = get_function_type (tb);
1844 gcc_assert (tf != NULL);
1846 /* Now we have the type, callee and maybe object reference,
1847 build the call expression. */
1848 tree exp = d_build_call (tf, callee, object, e->arguments);
1850 if (returnvalue != NULL_TREE)
1851 exp = compound_expr (exp, returnvalue);
1853 if (tf->isref)
1854 exp = build_deref (exp);
1856 /* Some library calls are defined to return a generic type.
1857 this->type is the real type we want to return. */
1858 if (e->type->isTypeBasic ())
1859 exp = d_convert (build_ctype (e->type), exp);
1861 /* If this call was found to be a constructor for a temporary with a
1862 cleanup, then move the call inside the TARGET_EXPR. */
1863 if (cleanup != NULL_TREE)
1865 tree init = TARGET_EXPR_INITIAL (cleanup);
1866 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1867 exp = cleanup;
1870 this->result_ = exp;
1873 /* Build a delegate expression. */
1875 void visit (DelegateExp *e)
1877 if (e->func->semanticRun == PASSsemantic3done)
1879 /* Add the function as nested function if it belongs to this module.
1880 ie: it is a member of this module, or it is a template instance. */
1881 Dsymbol *owner = e->func->toParent ();
1882 while (!owner->isTemplateInstance () && owner->toParent ())
1883 owner = owner->toParent ();
1884 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1885 build_decl_tree (e->func);
1888 tree fndecl;
1889 tree object;
1891 if (e->func->isNested ())
1893 if (e->e1->op == TOKnull)
1894 object = build_expr (e->e1);
1895 else
1896 object = get_frame_for_symbol (e->func);
1898 fndecl = build_address (get_symbol_decl (e->func));
1900 else
1902 if (!e->func->isThis ())
1904 error ("delegates are only for non-static functions");
1905 this->result_ = error_mark_node;
1906 return;
1909 object = build_expr (e->e1);
1911 /* Want reference to `this' object. */
1912 if (e->e1->type->ty != Tclass && e->e1->type->ty != Tpointer)
1913 object = build_address (object);
1915 /* Object reference could be the outer `this' field of a class or
1916 closure of type `void*'. Cast it to the right type. */
1917 if (e->e1->type->ty == Tclass)
1918 object = d_convert (build_ctype (e->e1->type), object);
1920 fndecl = get_symbol_decl (e->func);
1922 /* Get pointer to function out of the virtual table. */
1923 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1924 && e->e1->op != TOKsuper && e->e1->op != TOKdottype)
1926 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1927 object = d_save_expr (object);
1928 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1930 else
1931 fndecl = build_address (fndecl);
1934 this->result_ = build_method_call (fndecl, object, e->type);
1937 /* Build a type component expression. */
1939 void visit (DotTypeExp *e)
1941 /* Just a pass through to underlying expression. */
1942 this->result_ = build_expr (e->e1);
1945 /* Build a component reference expression. */
1947 void visit (DotVarExp *e)
1949 VarDeclaration *vd = e->var->isVarDeclaration ();
1951 /* This could also be a function, but relying on that being taken
1952 care of by the visitor interface for CallExp. */
1953 if (vd != NULL)
1955 if (!vd->isField ())
1956 this->result_ = get_decl_tree (vd);
1957 else
1959 tree object = build_expr (e->e1);
1961 if (e->e1->type->toBasetype ()->ty != Tstruct)
1962 object = build_deref (object);
1964 this->result_ = component_ref (object, get_symbol_decl (vd));
1967 else
1969 error ("%qs is not a field, but a %qs",
1970 e->var->toChars (), e->var->kind ());
1971 this->result_ = error_mark_node;
1975 /* Build an assert expression, used to declare conditions that must hold at
1976 that a given point in the program. */
1978 void visit (AssertExp *e)
1980 Type *tb1 = e->e1->type->toBasetype ();
1981 tree arg = build_expr (e->e1);
1982 tree tmsg = NULL_TREE;
1983 tree assert_pass = void_node;
1984 tree assert_fail;
1986 if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ())
1988 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1989 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1990 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1991 libcall_fn libcall;
1993 if (e->msg)
1995 tmsg = build_expr_dtor (e->msg);
1996 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1998 else
1999 libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP;
2001 /* Build a call to _d_assert(). */
2002 assert_fail = build_assert_call (e->loc, libcall, tmsg);
2004 if (global.params.useInvariants == CHECKENABLEon)
2006 /* If the condition is a D class or struct object with an invariant,
2007 call it if the condition result is true. */
2008 if (tb1->ty == Tclass)
2010 ClassDeclaration *cd = tb1->isClassHandle ();
2011 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
2013 arg = d_save_expr (arg);
2014 assert_pass = build_libcall (LIBCALL_INVARIANT,
2015 Type::tvoid, 1, arg);
2018 else if (tb1->ty == Tpointer && tb1->nextOf ()->ty == Tstruct)
2020 StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
2021 if (sd->inv != NULL)
2023 Expressions args;
2024 arg = d_save_expr (arg);
2025 assert_pass = d_build_call_expr (sd->inv, arg, &args);
2030 else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
2032 /* Generate: __builtin_trap() */
2033 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
2034 assert_fail = build_call_expr (fn, 0);
2036 else
2038 /* Assert contracts are turned off. */
2039 this->result_ = void_node;
2040 return;
2043 /* Build condition that we are asserting in this contract. */
2044 tree condition = convert_for_condition (arg, e->e1->type);
2046 /* We expect the condition to always be true, as what happens if an assert
2047 contract is false is undefined behavior. */
2048 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
2049 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
2050 tree pred_type = TREE_VALUE (arg_types);
2051 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
2053 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
2054 build_int_cst (expected_type, 1));
2055 condition = d_truthvalue_conversion (condition);
2057 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
2060 /* Build a declaration expression. */
2062 void visit (DeclarationExp *e)
2064 /* Compile the declaration. */
2065 push_stmt_list ();
2066 build_decl_tree (e->declaration);
2067 tree result = pop_stmt_list ();
2069 /* Construction of an array for typesafe-variadic function arguments
2070 can cause an empty STMT_LIST here. This can causes problems
2071 during gimplification. */
2072 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
2073 result = build_empty_stmt (input_location);
2075 this->result_ = result;
2078 /* Build a typeid expression. Returns an instance of class TypeInfo
2079 corresponding to. */
2081 void visit (TypeidExp *e)
2083 if (Type *tid = isType (e->obj))
2085 tree ti = build_typeinfo (e->loc, tid);
2087 /* If the typeinfo is at an offset. */
2088 if (tid->vtinfo->offset)
2089 ti = build_offset (ti, size_int (tid->vtinfo->offset));
2091 this->result_ = build_nop (build_ctype (e->type), ti);
2093 else if (Expression *tid = isExpression (e->obj))
2095 Type *type = tid->type->toBasetype ();
2096 assert (type->ty == Tclass);
2098 /* Generate **classptr to get the classinfo. */
2099 tree ci = build_expr (tid);
2100 ci = indirect_ref (ptr_type_node, ci);
2101 ci = indirect_ref (ptr_type_node, ci);
2103 /* Add extra indirection for interfaces. */
2104 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
2105 ci = indirect_ref (ptr_type_node, ci);
2107 this->result_ = build_nop (build_ctype (e->type), ci);
2109 else
2110 gcc_unreachable ();
2113 /* Build a function/lambda expression. */
2115 void visit (FuncExp *e)
2117 Type *ftype = e->type->toBasetype ();
2119 /* This check is for lambda's, remove `vthis' as function isn't nested. */
2120 if (e->fd->tok == TOKreserved && ftype->ty == Tpointer)
2122 e->fd->tok = TOKfunction;
2123 e->fd->vthis = NULL;
2126 /* Compile the function literal body. */
2127 build_decl_tree (e->fd);
2129 /* If nested, this will be a trampoline. */
2130 if (e->fd->isNested ())
2132 tree func = build_address (get_symbol_decl (e->fd));
2133 tree object;
2135 if (this->constp_)
2137 /* Static delegate variables have no context pointer. */
2138 object = null_pointer_node;
2139 this->result_ = build_method_call (func, object, e->fd->type);
2140 TREE_CONSTANT (this->result_) = 1;
2142 else
2144 object = get_frame_for_symbol (e->fd);
2145 this->result_ = build_method_call (func, object, e->fd->type);
2148 else
2150 this->result_ = build_nop (build_ctype (e->type),
2151 build_address (get_symbol_decl (e->fd)));
2155 /* Build a halt expression. */
2157 void visit (HaltExp *)
2159 /* Should we use trap() or abort()? */
2160 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2161 this->result_ = build_call_expr (ttrap, 0);
2164 /* Build a symbol pointer offset expression. */
2166 void visit (SymOffExp *e)
2168 /* Build the address and offset of the symbol. */
2169 size_t soffset = e->isSymOffExp ()->offset;
2170 tree result = get_decl_tree (e->var);
2171 TREE_USED (result) = 1;
2173 if (declaration_reference_p (e->var))
2174 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2175 else
2176 result = build_address (result);
2178 if (!soffset)
2179 result = d_convert (build_ctype (e->type), result);
2180 else
2182 tree offset = size_int (soffset);
2183 result = build_nop (build_ctype (e->type),
2184 build_offset (result, offset));
2187 this->result_ = result;
2190 /* Build a variable expression. */
2192 void visit (VarExp *e)
2194 if (e->var->needThis ())
2196 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2197 this->result_ = error_mark_node;
2198 return;
2200 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2202 /* __ctfe is always false at run-time. */
2203 this->result_ = integer_zero_node;
2204 return;
2207 /* This check is same as is done in FuncExp for lambdas. */
2208 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2209 if (fld != NULL)
2211 if (fld->tok == TOKreserved)
2213 fld->tok = TOKfunction;
2214 fld->vthis = NULL;
2217 /* Compiler the function literal body. */
2218 build_decl_tree (fld);
2221 if (this->constp_)
2223 /* Want the initializer, not the expression. */
2224 VarDeclaration *var = e->var->isVarDeclaration ();
2225 SymbolDeclaration *sd = e->var->isSymbolDeclaration ();
2226 tree init = NULL_TREE;
2228 if (var && (var->isConst () || var->isImmutable ())
2229 && e->type->toBasetype ()->ty != Tsarray && var->_init)
2231 if (var->inuse)
2232 error_at (make_location_t (e->loc), "recursive reference %qs",
2233 e->toChars ());
2234 else
2236 var->inuse++;
2237 init = build_expr (initializerToExpression (var->_init), true);
2238 var->inuse--;
2241 else if (sd && sd->dsym)
2242 init = layout_struct_initializer (sd->dsym);
2243 else
2244 error_at (make_location_t (e->loc), "non-constant expression %qs",
2245 e->toChars ());
2247 if (init != NULL_TREE)
2248 this->result_ = init;
2249 else
2250 this->result_ = error_mark_node;
2252 else
2254 tree result = get_decl_tree (e->var);
2255 TREE_USED (result) = 1;
2257 /* For variables that are references - currently only out/inout
2258 arguments; objects don't count - evaluating the variable means
2259 we want what it refers to. */
2260 if (declaration_reference_p (e->var))
2261 result = indirect_ref (build_ctype (e->var->type), result);
2263 this->result_ = result;
2267 /* Build a this variable expression. */
2269 void visit (ThisExp *e)
2271 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2272 tree result = NULL_TREE;
2274 if (e->var)
2275 result = get_decl_tree (e->var);
2276 else
2278 gcc_assert (fd && fd->vthis);
2279 result = get_decl_tree (fd->vthis);
2282 if (e->type->ty == Tstruct)
2283 result = build_deref (result);
2285 this->result_ = result;
2288 /* Build a new expression, which allocates memory either on the garbage
2289 collected heap or by using a class or struct specific allocator. */
2291 void visit (NewExp *e)
2293 Type *tb = e->type->toBasetype ();
2294 tree result;
2296 if (e->allocator)
2297 gcc_assert (e->newargs);
2299 if (tb->ty == Tclass)
2301 /* Allocating a new class. */
2302 tb = e->newtype->toBasetype ();
2304 ClassDeclaration *cd = tb->isTypeClass ()->sym;
2305 tree type = build_ctype (tb);
2306 tree setup_exp = NULL_TREE;
2307 tree new_call;
2309 if (e->onstack)
2311 /* If being used as an initializer for a local variable with scope
2312 storage class, then the instance is allocated on the stack
2313 rather than the heap or using the class specific allocator. */
2314 tree var = build_local_temp (TREE_TYPE (type));
2315 new_call = build_nop (type, build_address (var));
2316 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2318 else if (e->allocator)
2320 /* Call class allocator, and copy the initializer into memory. */
2321 new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
2322 new_call = d_save_expr (new_call);
2323 new_call = build_nop (type, new_call);
2324 setup_exp = modify_expr (build_deref (new_call),
2325 aggregate_initializer_decl (cd));
2327 else
2329 /* Generate: _d_newclass() */
2330 tree arg = build_address (get_classinfo_decl (cd));
2331 new_call = build_libcall (LIBCALL_NEWCLASS, tb, 1, arg);
2334 /* Set the context pointer for nested classes. */
2335 if (cd->isNested ())
2337 tree field = get_symbol_decl (cd->vthis);
2338 tree value = NULL_TREE;
2340 if (e->thisexp)
2342 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2343 Dsymbol *outer = cd->toParent2 ();
2344 int offset = 0;
2346 value = build_expr (e->thisexp);
2347 if (outer != tcd)
2349 ClassDeclaration *ocd = outer->isClassDeclaration ();
2350 gcc_assert (ocd->isBaseOf (tcd, &offset));
2351 /* Could just add offset... */
2352 value = convert_expr (value, e->thisexp->type, ocd->type);
2355 else
2356 value = build_vthis (cd);
2358 if (value != NULL_TREE)
2360 /* Generate: (new())->vthis = this; */
2361 new_call = d_save_expr (new_call);
2362 field = component_ref (build_deref (new_call), field);
2363 setup_exp = compound_expr (setup_exp,
2364 modify_expr (field, value));
2367 new_call = compound_expr (setup_exp, new_call);
2369 /* Call the class constructor. */
2370 if (e->member)
2371 result = d_build_call_expr (e->member, new_call, e->arguments);
2372 else
2373 result = new_call;
2375 if (e->argprefix)
2376 result = compound_expr (build_expr (e->argprefix), result);
2378 else if (tb->ty == Tpointer && tb->nextOf ()->toBasetype ()->ty == Tstruct)
2380 /* Allocating memory for a new struct. */
2381 Type *htype = e->newtype->toBasetype ();
2382 gcc_assert (!e->onstack);
2384 TypeStruct *stype = htype->isTypeStruct ();
2385 StructDeclaration *sd = stype->sym;
2386 tree new_call;
2388 /* Cannot new an opaque struct. */
2389 if (sd->size (e->loc) == 0)
2391 this->result_ = d_convert (build_ctype (e->type),
2392 integer_zero_node);
2393 return;
2396 if (e->allocator)
2398 /* Call struct allocator. */
2399 new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
2400 new_call = build_nop (build_ctype (tb), new_call);
2402 else
2404 /* Generate: _d_newitemT() */
2405 libcall_fn libcall = htype->isZeroInit ()
2406 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2407 tree arg = build_typeinfo (e->loc, e->newtype);
2408 new_call = build_libcall (libcall, tb, 1, arg);
2411 if (e->member || !e->arguments)
2413 /* Set the context pointer for nested structs. */
2414 if (sd->isNested ())
2416 tree value = build_vthis (sd);
2417 tree field = get_symbol_decl (sd->vthis);
2418 tree type = build_ctype (stype);
2420 new_call = d_save_expr (new_call);
2421 field = component_ref (indirect_ref (type, new_call), field);
2422 new_call = compound_expr (modify_expr (field, value), new_call);
2425 /* Call the struct constructor. */
2426 if (e->member)
2427 result = d_build_call_expr (e->member, new_call, e->arguments);
2428 else
2429 result = new_call;
2431 else
2433 /* If we have a user supplied initializer, then set-up with a
2434 struct literal. */
2435 if (e->arguments != NULL && sd->fields.length != 0)
2437 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2438 e->arguments,
2439 htype);
2440 new_call = d_save_expr (new_call);
2441 se->type = sd->type;
2442 se->sym = new_call;
2443 result = compound_expr (build_expr (se), new_call);
2445 else
2446 result = new_call;
2449 if (e->argprefix)
2450 result = compound_expr (build_expr (e->argprefix), result);
2452 else if (tb->ty == Tarray)
2454 /* Allocating memory for a new D array. */
2455 tb = e->newtype->toBasetype ();
2456 TypeDArray *tarray = tb->isTypeDArray ();
2458 gcc_assert (!e->allocator);
2459 gcc_assert (e->arguments && e->arguments->length >= 1);
2461 if (e->arguments->length == 1)
2463 /* Single dimension array allocations. */
2464 Expression *arg = (*e->arguments)[0];
2466 if (tarray->next->size () == 0)
2468 /* Array element size is unknown. */
2469 this->result_ = d_array_value (build_ctype (e->type),
2470 size_int (0), null_pointer_node);
2471 return;
2474 libcall_fn libcall = tarray->next->isZeroInit ()
2475 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
2476 result = build_libcall (libcall, tb, 2,
2477 build_typeinfo (e->loc, e->type),
2478 build_expr (arg));
2480 else
2482 /* Multidimensional array allocations. */
2483 tree tarray = make_array_type (Type::tsize_t, e->arguments->length);
2484 tree var = build_local_temp (tarray);
2485 vec <constructor_elt, va_gc> *elms = NULL;
2487 /* Get the base element type for the array, generating the
2488 initializer for the dims parameter along the way. */
2489 Type *telem = e->newtype->toBasetype ();
2490 for (size_t i = 0; i < e->arguments->length; i++)
2492 Expression *arg = (*e->arguments)[i];
2493 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2495 gcc_assert (telem->ty == Tarray);
2496 telem = telem->toBasetype ()->nextOf ();
2497 gcc_assert (telem);
2500 /* Initialize the temporary. */
2501 tree init = modify_expr (var, build_constructor (tarray, elms));
2502 var = compound_expr (init, var);
2504 /* Generate: _d_newarraymTX(ti, dims)
2505 or: _d_newarraymiTX(ti, dims) */
2506 libcall_fn libcall = telem->isZeroInit ()
2507 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2509 tree tinfo = build_typeinfo (e->loc, e->type);
2510 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2511 size_int (e->arguments->length),
2512 build_address (var));
2514 result = build_libcall (libcall, tb, 2, tinfo, dims);
2517 if (e->argprefix)
2518 result = compound_expr (build_expr (e->argprefix), result);
2520 else if (tb->ty == Tpointer)
2522 /* Allocating memory for a new pointer. */
2523 TypePointer *tpointer = tb->isTypePointer ();
2525 if (tpointer->next->size () == 0)
2527 /* Pointer element size is unknown. */
2528 this->result_ = d_convert (build_ctype (e->type),
2529 integer_zero_node);
2530 return;
2533 libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
2534 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2536 tree arg = build_typeinfo (e->loc, e->newtype);
2537 result = build_libcall (libcall, tb, 1, arg);
2539 if (e->arguments && e->arguments->length == 1)
2541 result = d_save_expr (result);
2542 tree init = modify_expr (build_deref (result),
2543 build_expr ((*e->arguments)[0]));
2544 result = compound_expr (init, result);
2547 if (e->argprefix)
2548 result = compound_expr (build_expr (e->argprefix), result);
2550 else
2551 gcc_unreachable ();
2553 this->result_ = convert_expr (result, tb, e->type);
2556 /* Build an integer literal. */
2558 void visit (IntegerExp *e)
2560 tree ctype = build_ctype (e->type->toBasetype ());
2561 this->result_ = build_integer_cst (e->value, ctype);
2564 /* Build a floating-point literal. */
2566 void visit (RealExp *e)
2568 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2571 /* Build a complex literal. */
2573 void visit (ComplexExp *e)
2575 Type *tnext;
2577 switch (e->type->toBasetype ()->ty)
2579 case Tcomplex32:
2580 tnext = (TypeBasic *) Type::tfloat32;
2581 break;
2583 case Tcomplex64:
2584 tnext = (TypeBasic *) Type::tfloat64;
2585 break;
2587 case Tcomplex80:
2588 tnext = (TypeBasic *) Type::tfloat80;
2589 break;
2591 default:
2592 gcc_unreachable ();
2595 this->result_ = build_complex (build_ctype (e->type),
2596 build_float_cst (creall (e->value), tnext),
2597 build_float_cst (cimagl (e->value), tnext));
2600 /* Build a string literal, all strings are null terminated except for
2601 static arrays. */
2603 void visit (StringExp *e)
2605 Type *tb = e->type->toBasetype ();
2606 tree type = build_ctype (e->type);
2608 if (tb->ty == Tsarray)
2610 /* Turn the string into a constructor for the static array. */
2611 vec <constructor_elt, va_gc> *elms = NULL;
2612 vec_safe_reserve (elms, e->len);
2613 tree etype = TREE_TYPE (type);
2615 for (size_t i = 0; i < e->len; i++)
2617 tree value = build_integer_cst (e->charAt (i), etype);
2618 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2621 tree ctor = build_constructor (type, elms);
2622 TREE_CONSTANT (ctor) = 1;
2623 this->result_ = ctor;
2625 else
2627 /* Copy the string contents to a null terminated string. */
2628 dinteger_t length = (e->len * e->sz);
2629 char *string = XALLOCAVEC (char, length + 1);
2630 memcpy (string, e->string, length);
2631 string[length] = '\0';
2633 /* String value and type includes the null terminator. */
2634 tree value = build_string (length, string);
2635 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2636 value = build_address (value);
2638 if (tb->ty == Tarray)
2639 value = d_array_value (type, size_int (e->len), value);
2641 TREE_CONSTANT (value) = 1;
2642 this->result_ = d_convert (type, value);
2646 /* Build a tuple literal. Just an argument list that may have
2647 side effects that need evaluation. */
2649 void visit (TupleExp *e)
2651 tree result = NULL_TREE;
2653 if (e->e0)
2654 result = build_expr (e->e0, this->constp_, true);
2656 for (size_t i = 0; i < e->exps->length; ++i)
2658 Expression *exp = (*e->exps)[i];
2659 result = compound_expr (result, build_expr (exp, this->constp_, true));
2662 if (result == NULL_TREE)
2663 result = void_node;
2665 this->result_ = result;
2668 /* Build an array literal. The common type of the all elements is taken to
2669 be the type of the array element, and all elements are implicitly
2670 converted to that type. */
2672 void visit (ArrayLiteralExp *e)
2674 Type *tb = e->type->toBasetype ();
2676 /* Implicitly convert void[n] to ubyte[n]. */
2677 if (tb->ty == Tsarray && tb->nextOf ()->toBasetype ()->ty == Tvoid)
2678 tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());
2680 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tpointer);
2682 /* Handle empty array literals. */
2683 if (e->elements->length == 0)
2685 if (tb->ty == Tarray)
2686 this->result_ = d_array_value (build_ctype (e->type),
2687 size_int (0), null_pointer_node);
2688 else
2689 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2690 NULL);
2692 return;
2695 /* Build an expression that assigns the expressions in ELEMENTS to
2696 a constructor. */
2697 vec <constructor_elt, va_gc> *elms = NULL;
2698 vec_safe_reserve (elms, e->elements->length);
2699 bool constant_p = true;
2700 tree saved_elems = NULL_TREE;
2702 Type *etype = tb->nextOf ();
2703 tree satype = make_array_type (etype, e->elements->length);
2705 for (size_t i = 0; i < e->elements->length; i++)
2707 Expression *expr = e->getElement (i);
2708 tree value = build_expr (expr, this->constp_, true);
2710 /* Only append nonzero values, the backend will zero out the rest
2711 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2712 if (!initializer_zerop (value))
2714 if (!TREE_CONSTANT (value))
2715 constant_p = false;
2717 /* Split construction of values out of the constructor if there
2718 may be side effects. */
2719 tree init = stabilize_expr (&value);
2720 if (init != NULL_TREE)
2721 saved_elems = compound_expr (saved_elems, init);
2723 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2724 convert_expr (value, expr->type, etype));
2728 /* Now return the constructor as the correct type. For static arrays there
2729 is nothing else to do. For dynamic arrays, return a two field struct.
2730 For pointers, return the address. */
2731 tree ctor = build_constructor (satype, elms);
2732 tree type = build_ctype (e->type);
2734 /* Nothing else to do for static arrays. */
2735 if (tb->ty == Tsarray || this->constp_)
2737 /* Can't take the address of the constructor, so create an anonymous
2738 static symbol, and then refer to it. */
2739 if (tb->ty != Tsarray)
2741 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2742 ctor = build_address (decl);
2743 if (tb->ty == Tarray)
2744 ctor = d_array_value (type, size_int (e->elements->length), ctor);
2746 d_pushdecl (decl);
2747 rest_of_decl_compilation (decl, 1, 0);
2750 /* If the array literal is readonly or static. */
2751 if (constant_p)
2752 TREE_CONSTANT (ctor) = 1;
2753 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2754 TREE_STATIC (ctor) = 1;
2756 /* Use memset to fill any alignment holes in the array. */
2757 if (!this->constp_ && !this->literalp_)
2759 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
2761 if (ts != NULL && (!identity_compare_p (ts->sym)
2762 || ts->sym->isUnionDeclaration ()))
2764 tree var = build_local_temp (TREE_TYPE (ctor));
2765 tree init = build_memset_call (var);
2766 /* Evaluate memset() first, then any saved elements. */
2767 saved_elems = compound_expr (init, saved_elems);
2768 ctor = compound_expr (modify_expr (var, ctor), var);
2772 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2774 else
2776 /* Allocate space on the memory managed heap. */
2777 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2778 etype->pointerTo (), 2,
2779 build_typeinfo (e->loc, etype->arrayOf ()),
2780 size_int (e->elements->length));
2781 mem = d_save_expr (mem);
2783 /* Now copy the constructor into memory. */
2784 tree size = size_mult_expr (size_int (e->elements->length),
2785 size_int (tb->nextOf ()->size ()));
2787 tree result = build_memcpy_call (mem, build_address (ctor), size);
2789 /* Return the array pointed to by MEM. */
2790 result = compound_expr (result, mem);
2792 if (tb->ty == Tarray)
2793 result = d_array_value (type, size_int (e->elements->length), result);
2795 this->result_ = compound_expr (saved_elems, result);
2799 /* Build an associative array literal. The common type of the all keys is
2800 taken to be the key type, and common type of all values the value type.
2801 All keys and values are then implicitly converted as needed. */
2803 void visit (AssocArrayLiteralExp *e)
2805 /* Want the mutable type for typeinfo reference. */
2806 Type *tb = e->type->toBasetype ()->mutableOf ();
2808 /* Handle empty assoc array literals. */
2809 TypeAArray *ta = tb->isTypeAArray ();
2810 if (e->keys->length == 0)
2812 this->result_ = build_constructor (build_ctype (ta), NULL);
2813 return;
2816 /* Build an expression that assigns all expressions in KEYS
2817 to a constructor. */
2818 tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
2819 e->keys, this->constp_);
2820 tree init = stabilize_expr (&akeys);
2822 /* Do the same with all expressions in VALUES. */
2823 tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
2824 e->values, this->constp_);
2825 init = compound_expr (init, stabilize_expr (&avals));
2827 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2828 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2829 size_int (e->keys->length),
2830 build_address (akeys));
2831 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2832 size_int (e->values->length),
2833 build_address (avals));
2835 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2836 build_typeinfo (e->loc, ta), keys, vals);
2838 /* Return an associative array pointed to by MEM. */
2839 tree aatype = build_ctype (ta);
2840 vec <constructor_elt, va_gc> *ce = NULL;
2841 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2843 tree result = build_nop (build_ctype (e->type),
2844 build_constructor (aatype, ce));
2845 this->result_ = compound_expr (init, result);
2848 /* Build a struct literal. */
2850 void visit (StructLiteralExp *e)
2852 /* Handle empty struct literals. */
2853 if (e->elements == NULL || e->sd->fields.length == 0)
2855 this->result_ = build_constructor (build_ctype (e->type), NULL);
2856 return;
2859 /* Building sinit trees are delayed until after frontend semantic
2860 processing has complete. Build the static initializer now. */
2861 if (e->useStaticInit && !this->constp_)
2863 tree init = aggregate_initializer_decl (e->sd);
2865 /* If initializing a symbol, don't forget to set it. */
2866 if (e->sym != NULL)
2868 tree var = build_deref (e->sym);
2869 init = compound_expr (modify_expr (var, init), var);
2872 this->result_ = init;
2873 return;
2876 /* Build a constructor that assigns the expressions in ELEMENTS
2877 at each field index that has been filled in. */
2878 vec <constructor_elt, va_gc> *ve = NULL;
2879 tree saved_elems = NULL_TREE;
2881 /* CTFE may fill the hidden pointer by NullExp. */
2882 gcc_assert (e->elements->length <= e->sd->fields.length);
2884 Type *tb = e->type->toBasetype ();
2885 gcc_assert (tb->ty == Tstruct);
2887 for (size_t i = 0; i < e->elements->length; i++)
2889 Expression *exp = (*e->elements)[i];
2890 if (!exp)
2891 continue;
2893 VarDeclaration *field = e->sd->fields[i];
2894 Type *type = exp->type->toBasetype ();
2895 Type *ftype = field->type->toBasetype ();
2896 tree value = NULL_TREE;
2898 if (ftype->ty == Tsarray && !same_type_p (type, ftype))
2900 /* Initialize a static array with a single element. */
2901 tree elem = build_expr (exp, this->constp_, true);
2902 saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
2903 elem = d_save_expr (elem);
2905 if (initializer_zerop (elem))
2906 value = build_constructor (build_ctype (ftype), NULL);
2907 else
2908 value = build_array_from_val (ftype, elem);
2910 else
2912 value = convert_expr (build_expr (exp, this->constp_, true),
2913 exp->type, field->type);
2916 /* Split construction of values out of the constructor. */
2917 saved_elems = compound_expr (saved_elems, stabilize_expr (&value));
2919 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2922 /* Maybe setup hidden pointer to outer scope context. */
2923 if (e->sd->isNested () && e->elements->length != e->sd->fields.length
2924 && this->constp_ == false)
2926 tree field = get_symbol_decl (e->sd->vthis);
2927 tree value = build_vthis (e->sd);
2928 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2929 gcc_assert (e->useStaticInit == false);
2932 /* Build a constructor in the correct shape of the aggregate type. */
2933 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2935 /* Nothing more to do for constant literals. */
2936 if (this->constp_)
2938 /* If the struct literal is a valid for static data. */
2939 if (TREE_CONSTANT (ctor)
2940 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2941 TREE_STATIC (ctor) = 1;
2943 this->result_ = compound_expr (saved_elems, ctor);
2944 return;
2947 /* Construct the struct literal for run-time. */
2948 if (e->sym != NULL)
2950 /* Store the result in a symbol to initialize the literal. */
2951 tree var = build_deref (e->sym);
2952 ctor = compound_expr (modify_expr (var, ctor), var);
2954 else if (!this->literalp_)
2956 /* Use memset to fill any alignment holes in the object. */
2957 if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
2959 tree var = build_local_temp (TREE_TYPE (ctor));
2960 tree init = build_memset_call (var);
2961 /* Evaluate memset() first, then any saved element constructors. */
2962 saved_elems = compound_expr (init, saved_elems);
2963 ctor = compound_expr (modify_expr (var, ctor), var);
2967 this->result_ = compound_expr (saved_elems, ctor);
2970 /* Build a null literal. */
2972 void visit (NullExp *e)
2974 this->result_ = build_typeof_null_value (e->type);
2977 /* Build a vector literal. */
2979 void visit (VectorExp *e)
2981 tree type = build_ctype (e->type);
2983 /* First handle array literal expressions. */
2984 if (e->e1->op == TOKarrayliteral)
2986 ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
2987 vec <constructor_elt, va_gc> *elms = NULL;
2988 bool constant_p = true;
2990 vec_safe_reserve (elms, ale->elements->length);
2991 for (size_t i = 0; i < ale->elements->length; i++)
2993 Expression *expr = ale->getElement (i);
2994 tree value = d_convert (TREE_TYPE (type),
2995 build_expr (expr, this->constp_, true));
2996 if (!CONSTANT_CLASS_P (value))
2997 constant_p = false;
2999 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
3002 /* Build a VECTOR_CST from a constant vector constructor. */
3003 if (constant_p)
3004 this->result_ = build_vector_from_ctor (type, elms);
3005 else
3006 this->result_ = build_constructor (type, elms);
3008 else
3010 /* Build constructor from single value. */
3011 tree value = d_convert (TREE_TYPE (type),
3012 build_expr (e->e1, this->constp_, true));
3013 this->result_ = build_vector_from_val (type, value);
3017 /* Build a static array representation of a vector expression. */
3019 void visit (VectorArrayExp *e)
3021 this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
3022 e->e1->type, e->type);
3025 /* Build a static class literal, return its reference. */
3027 void visit (ClassReferenceExp *e)
3029 /* The result of build_new_class_expr is a RECORD_TYPE, we want
3030 the reference. */
3031 tree var = build_address (build_new_class_expr (e));
3033 /* If the type of this literal is an interface, the we must add the
3034 interface offset to symbol. */
3035 if (this->constp_)
3037 TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
3038 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
3040 if (to != NULL)
3042 ClassDeclaration *from = e->originalClass ();
3043 int offset = 0;
3045 gcc_assert (to->isBaseOf (from, &offset) != 0);
3047 if (offset != 0)
3048 var = build_offset (var, size_int (offset));
3052 this->result_ = var;
3055 /* These expressions are mainly just a placeholders in the frontend.
3056 We shouldn't see them here. */
3058 void visit (ScopeExp *e)
3060 error_at (make_location_t (e->loc), "%qs is not an expression",
3061 e->toChars ());
3062 this->result_ = error_mark_node;
3065 void visit (TypeExp *e)
3067 error_at (make_location_t (e->loc), "type %qs is not an expression",
3068 e->toChars ());
3069 this->result_ = error_mark_node;
3074 /* Main entry point for ExprVisitor interface to generate code for
3075 the Expression AST class E. If CONST_P is true, then E is a
3076 constant expression. If LITERAL_P is true, then E is a value used
3077 in the initialization of another literal. */
3079 tree
3080 build_expr (Expression *e, bool const_p, bool literal_p)
3082 ExprVisitor v = ExprVisitor (const_p, literal_p);
3083 location_t saved_location = input_location;
3085 input_location = make_location_t (e->loc);
3086 e->accept (&v);
3087 tree expr = v.result ();
3088 input_location = saved_location;
3090 /* Check if initializer expression is valid constant. */
3091 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3093 error_at (make_location_t (e->loc), "non-constant expression %qs",
3094 e->toChars ());
3095 return error_mark_node;
3098 return expr;
3101 /* Same as build_expr, but also calls destructors on any temporaries. */
3103 tree
3104 build_expr_dtor (Expression *e)
3106 /* Codegen can be improved by determining if no exceptions can be thrown
3107 between the ctor and dtor, and eliminating the ctor and dtor. */
3108 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3109 tree result = build_expr (e);
3111 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3113 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3114 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3117 return result;
3120 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3122 tree
3123 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3125 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3126 tree result = build_expr (e);
3128 /* Convert for initializing the DECL_RESULT. */
3129 if (tf->isref)
3131 /* If we are returning a reference, take the address. */
3132 result = convert_expr (result, e->type, type);
3133 result = build_address (result);
3135 else
3136 result = convert_for_rvalue (result, e->type, type);
3138 /* The decl to store the return expression. */
3139 tree decl = DECL_RESULT (cfun->decl);
3141 /* Split comma expressions, so that the result is returned directly. */
3142 tree expr = stabilize_expr (&result);
3143 result = build_assign (INIT_EXPR, decl, result);
3144 result = compound_expr (expr, return_expr (result));
3146 /* May nest the return expression inside the try/finally expression. */
3147 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3149 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3150 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3153 return result;