d: Merge upstream dmd 568496d5b, druntime 178c44ff, phobos 574bf883b.
[official-gcc.git] / gcc / d / expr.cc
blob2831eefc4ba6469a368cc89ab3ad238603b1cc3d
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 != 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 == TY::Tsarray || tb1->ty == TY::Tarray)
272 && (tb2->ty == TY::Tsarray || tb2->ty == 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 != 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 == TY::Tsarray || tb1->ty == TY::Tarray)
337 && (tb2->ty == TY::Tsarray || tb2->ty == 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 == TY::Tvoid
350 || (t1elem->ty == TY::Tstruct
351 && !t1elem->isTypeStruct ()->sym->xeq))
352 && t1elem->ty == t2elem->ty)
354 tree t1 = d_array_convert (e->e1);
355 tree t2 = d_array_convert (e->e2);
356 tree result;
358 /* Make temporaries to prevent multiple evaluations. */
359 tree t1saved = d_save_expr (t1);
360 tree t2saved = d_save_expr (t2);
362 /* Length of arrays, for comparisons done before calling memcmp. */
363 tree t1len = d_array_length (t1saved);
364 tree t2len = d_array_length (t2saved);
366 /* Reference to array data. */
367 tree t1ptr = d_array_ptr (t1saved);
368 tree t2ptr = d_array_ptr (t2saved);
370 /* Compare arrays using memcmp if possible, otherwise for structs,
371 each field is compared inline. */
372 if (t1elem->ty != TY::Tstruct
373 || identity_compare_p (t1elem->isTypeStruct ()->sym))
375 tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
377 result = build_memcmp_call (t1ptr, t2ptr, size);
378 result = build_boolop (code, result, integer_zero_node);
380 else
382 StructDeclaration *sd = t1elem->isTypeStruct ()->sym;
384 result = build_array_struct_comparison (code, sd, t1len,
385 t1ptr, t2ptr);
388 /* Check array length first before passing to memcmp.
389 For equality expressions, this becomes:
390 (e1.length == 0 || memcmp);
391 Otherwise for inequality:
392 (e1.length != 0 && memcmp); */
393 tree tsizecmp = build_boolop (code, t1len, size_zero_node);
394 if (e->op == TOKequal)
395 result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
396 else
397 result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
399 /* Finally, check if lengths of both arrays match if dynamic.
400 The frontend should have already guaranteed that static arrays
401 have same size. */
402 if (tb1->ty == TY::Tsarray && tb2->ty == TY::Tsarray)
403 gcc_assert (tb1->size () == tb2->size ());
404 else
406 tree tlencmp = build_boolop (code, t1len, t2len);
407 if (e->op == TOKequal)
408 result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
409 else
410 result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
413 /* Ensure left-to-right order of evaluation. */
414 if (TREE_SIDE_EFFECTS (t2))
415 result = compound_expr (t2saved, result);
417 if (TREE_SIDE_EFFECTS (t1))
418 result = compound_expr (t1saved, result);
420 this->result_ = result;
422 else
424 /* Use _adEq2() to compare each element. */
425 Type *t1array = t1elem->arrayOf ();
426 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
427 d_array_convert (e->e1),
428 d_array_convert (e->e2),
429 build_typeinfo (e->loc, t1array));
431 if (e->op == TOKnotequal)
432 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
434 this->result_ = result;
437 else if (TypeStruct *ts = tb1->isTypeStruct ())
439 /* Equality for struct objects means the logical product of all
440 equality results of the corresponding object fields. */
441 tree t1 = build_expr (e->e1);
442 tree t2 = build_expr (e->e2);
444 gcc_assert (same_type_p (tb1, tb2));
446 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
448 else if (tb1->ty == TY::Taarray && tb2->ty == TY::Taarray)
450 /* Use _aaEqual() for associative arrays. */
451 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
452 build_typeinfo (e->loc, tb1),
453 build_expr (e->e1),
454 build_expr (e->e2));
456 if (e->op == TOKnotequal)
457 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
459 this->result_ = result;
461 else
463 /* For operands of other types, equality is defined as the bit pattern
464 of the type matches exactly. */
465 tree t1 = build_expr (e->e1);
466 tree t2 = build_expr (e->e2);
468 this->result_ = d_convert (build_ctype (e->type),
469 build_boolop (code, t1, t2));
473 /* Build an `in' expression. This is a condition to see if an element
474 exists in an associative array. The result is a pointer to the
475 element, or null if false. */
477 void visit (InExp *e)
479 Type *tb2 = e->e2->type->toBasetype ();
480 Type *tkey = tb2->isTypeAArray ()->index->toBasetype ();
481 tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
483 /* Build a call to _aaInX(). */
484 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
485 build_expr (e->e2),
486 build_typeinfo (e->loc, tkey),
487 build_address (key));
490 /* Build a relational expression. The result type is bool. */
492 void visit (CmpExp *e)
494 Type *tb1 = e->e1->type->toBasetype ();
495 Type *tb2 = e->e2->type->toBasetype ();
497 tree result;
498 tree_code code;
500 switch (e->op)
502 case TOKle:
503 code = LE_EXPR;
504 break;
506 case TOKlt:
507 code = LT_EXPR;
508 break;
510 case TOKge:
511 code = GE_EXPR;
512 break;
514 case TOKgt:
515 code = GT_EXPR;
516 break;
518 default:
519 gcc_unreachable ();
522 /* For static and dynamic arrays, the relational op is turned into a
523 library call. It is not lowered during codegen. */
524 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
525 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
527 error ("cannot handle comparison of type %<%s == %s%>",
528 tb1->toChars (), tb2->toChars ());
529 gcc_unreachable ();
532 /* Simple comparison. */
533 result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
534 this->result_ = d_convert (build_ctype (e->type), result);
537 /* Build a logical `and if' or `or if' expression. If the right operand
538 expression is void, then the resulting type is void. Otherwise the
539 result is bool. */
541 void visit (LogicalExp *e)
543 tree_code code = (e->op == TOKandand) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
545 if (e->e2->type->toBasetype ()->ty != TY::Tvoid)
547 tree t1 = build_expr (e->e1);
548 tree t2 = build_expr (e->e2);
550 t1 = convert_for_condition (t1, e->e1->type);
551 t2 = convert_for_condition (t2, e->e2->type);
553 this->result_ = d_convert (build_ctype (e->type),
554 build_boolop (code, t1, t2));
556 else
558 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
559 tree t2 = build_expr_dtor (e->e2);
561 /* Invert condition for logical or if expression. */
562 if (e->op == TOKoror)
563 t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);
565 this->result_ = build_condition (build_ctype (e->type),
566 t1, t2, void_node);
570 /* Build a binary operand expression. Operands go through usual arithmetic
571 conversions to bring them to a common type before evaluating. */
573 void visit (BinExp *e)
575 tree_code code;
577 switch (e->op)
579 case TOKadd:
580 case TOKmin:
581 if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
582 || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
584 /* If the result is complex, then we can shortcut binary_op.
585 Frontend should have already validated types and sizes. */
586 tree t1 = build_expr (e->e1);
587 tree t2 = build_expr (e->e2);
589 if (e->op == TOKmin)
590 t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
592 if (e->e1->type->isreal ())
593 this->result_ = complex_expr (build_ctype (e->type), t1, t2);
594 else
595 this->result_ = complex_expr (build_ctype (e->type), t2, t1);
597 return;
599 else
600 code = (e->op == TOKadd)
601 ? PLUS_EXPR : MINUS_EXPR;
602 break;
604 case TOKmul:
605 code = MULT_EXPR;
606 break;
608 case TOKdiv:
609 /* Determine if the div expression is a lowered pointer diff operation.
610 The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */
611 if (MinExp *me = e->e1->isMinExp ())
613 if (me->e1->type->ty == TY::Tpointer
614 && me->e2->type->ty == TY::Tpointer
615 && e->e2->op == TOKint64)
617 code = EXACT_DIV_EXPR;
618 break;
622 code = e->e1->type->isintegral ()
623 ? TRUNC_DIV_EXPR : RDIV_EXPR;
624 break;
626 case TOKmod:
627 code = e->e1->type->isfloating ()
628 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
629 break;
631 case TOKand:
632 code = BIT_AND_EXPR;
633 break;
635 case TOKor:
636 code = BIT_IOR_EXPR;
637 break;
639 case TOKxor:
640 code = BIT_XOR_EXPR;
641 break;
643 case TOKshl:
644 code = LSHIFT_EXPR;
645 break;
647 case TOKshr:
648 code = RSHIFT_EXPR;
649 break;
651 case TOKushr:
652 code = UNSIGNED_RSHIFT_EXPR;
653 break;
655 default:
656 gcc_unreachable ();
659 this->result_ = binary_op (code, build_ctype (e->type),
660 build_expr (e->e1), build_expr (e->e2));
664 /* Build a concat expression, which concatenates two or more arrays of the
665 same type, producing a dynamic array with the result. If one operand
666 is an element type, that element is converted to an array of length 1. */
668 void visit (CatExp *e)
670 Type *tb1 = e->e1->type->toBasetype ();
671 Type *tb2 = e->e2->type->toBasetype ();
672 Type *etype;
674 if (tb1->ty == TY::Tarray || tb1->ty == TY::Tsarray)
675 etype = tb1->nextOf ();
676 else
677 etype = tb2->nextOf ();
679 tree result;
681 if (e->e1->op == TOKcat)
683 /* Flatten multiple concatenations to an array.
684 So the expression ((a ~ b) ~ c) becomes [a, b, c] */
685 int ndims = 2;
687 for (Expression *ex = e->e1; ex->op == TOKcat;)
689 if (ex->op == TOKcat)
691 ex = ex->isCatExp ()->e1;
692 ndims++;
696 /* Store all concatenation args to a temporary byte[][ndims] array. */
697 Type *targselem = Type::tint8->arrayOf ();
698 tree var = build_local_temp (make_array_type (targselem, ndims));
700 /* Loop through each concatenation from right to left. */
701 vec <constructor_elt, va_gc> *elms = NULL;
702 CatExp *ce = e;
703 int dim = ndims - 1;
705 for (Expression *oe = ce->e2; oe != NULL;
706 (ce->e1->op != TOKcat
707 ? (oe = ce->e1)
708 : (ce = ce->e1->isCatExp (), oe = ce->e2)))
710 tree arg = d_array_convert (etype, oe);
711 tree index = size_int (dim);
712 CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));
714 /* Finished pushing all arrays. */
715 if (oe == ce->e1)
716 break;
718 dim -= 1;
721 /* Check there is no logic bug in constructing byte[][] of arrays. */
722 gcc_assert (dim == 0);
723 tree init = build_constructor (TREE_TYPE (var), elms);
724 var = compound_expr (modify_expr (var, init), var);
726 tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
727 size_int (ndims), build_address (var));
729 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
730 build_typeinfo (e->loc, e->type), arrs);
732 else
734 /* Handle single concatenation (a ~ b). */
735 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
736 build_typeinfo (e->loc, e->type),
737 d_array_convert (etype, e->e1),
738 d_array_convert (etype, e->e2));
741 this->result_ = result;
744 /* Build an assignment operator expression. The right operand is implicitly
745 converted to the type of the left operand, and assigned to it. */
747 void visit (BinAssignExp *e)
749 tree_code code;
750 Expression *e1b = e->e1;
752 switch (e->op)
754 case TOKaddass:
755 code = PLUS_EXPR;
756 break;
758 case TOKminass:
759 code = MINUS_EXPR;
760 break;
762 case TOKmulass:
763 code = MULT_EXPR;
764 break;
766 case TOKdivass:
767 code = e->e1->type->isintegral ()
768 ? TRUNC_DIV_EXPR : RDIV_EXPR;
769 break;
771 case TOKmodass:
772 code = e->e1->type->isfloating ()
773 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
774 break;
776 case TOKandass:
777 code = BIT_AND_EXPR;
778 break;
780 case TOKorass:
781 code = BIT_IOR_EXPR;
782 break;
784 case TOKxorass:
785 code = BIT_XOR_EXPR;
786 break;
788 case TOKpowass:
789 gcc_unreachable ();
791 case TOKshlass:
792 code = LSHIFT_EXPR;
793 break;
795 case TOKshrass:
796 case TOKushrass:
797 /* Use the original lhs type before it was promoted. The left operand
798 of `>>>=' does not undergo integral promotions before shifting.
799 Strip off casts just incase anyway. */
800 while (e1b->op == TOKcast)
802 CastExp *ce = e1b->isCastExp ();
803 gcc_assert (same_type_p (ce->type, ce->to));
804 e1b = ce->e1;
806 code = (e->op == TOKshrass) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
807 break;
809 default:
810 gcc_unreachable ();
813 tree exp = binop_assignment (code, e1b, e->e2);
814 this->result_ = convert_expr (exp, e1b->type, e->type);
817 /* Build a concat assignment expression. The right operand is appended
818 to the left operand. */
820 void visit (CatAssignExp *e)
822 Type *tb1 = e->e1->type->toBasetype ();
823 Type *tb2 = e->e2->type->toBasetype ();
824 Type *etype = tb1->nextOf ()->toBasetype ();
826 /* Save the address of `e1', so it can be evaluated first.
827 As all D run-time library functions for concat assignments update `e1'
828 in-place and then return its value, the saved address can also be used as
829 the result of this expression as well. */
830 tree lhs = build_expr (e->e1);
831 tree lexpr = stabilize_expr (&lhs);
832 tree ptr = d_save_expr (build_address (lhs));
833 tree result = NULL_TREE;
835 if (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar
836 && (etype->ty == TY::Tchar || etype->ty == TY::Twchar))
838 /* Append a dchar to a char[] or wchar[]:
839 The assignment is handled by the D run-time library, so only
840 need to call `_d_arrayappend[cw]d(&e1, e2)' */
841 libcall_fn libcall = (etype->ty == TY::Tchar)
842 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
844 result = build_libcall (libcall, e->type, 2,
845 ptr, build_expr (e->e2));
847 else
849 gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray);
851 if ((tb2->ty == TY::Tarray || tb2->ty == TY::Tsarray)
852 && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
854 /* Append an array to another array:
855 The assignment is handled by the D run-time library, so only
856 need to call `_d_arrayappendT(ti, &e1, e2)' */
857 result = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
858 build_typeinfo (e->loc, e->type),
859 ptr, d_array_convert (e->e2));
861 else if (same_type_p (etype, tb2))
863 /* Append an element to an array:
864 The assignment is generated inline, so need to handle temporaries
865 here, and ensure that they are evaluated in the correct order.
867 The generated code should end up being equivalent to:
868 _d_arrayappendcTX(ti, &e1, 1)[e1.length - 1] = e2
870 tree callexp = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
871 build_typeinfo (e->loc, e->type),
872 ptr, size_one_node);
873 callexp = d_save_expr (callexp);
875 /* Assign e2 to last element. */
876 tree offexp = d_array_length (callexp);
877 offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
878 offexp, size_one_node);
880 tree ptrexp = d_array_ptr (callexp);
881 ptrexp = void_okay_p (ptrexp);
882 ptrexp = build_array_index (ptrexp, offexp);
884 /* Evaluate expression before appending. */
885 tree rhs = build_expr (e->e2);
886 tree rexpr = stabilize_expr (&rhs);
888 if (TREE_CODE (rhs) == CALL_EXPR)
889 rhs = force_target_expr (rhs);
891 result = modify_expr (build_deref (ptrexp), rhs);
892 result = compound_expr (rexpr, result);
894 else
895 gcc_unreachable ();
898 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
899 result = compound_expr (compound_expr (lexpr, ptr), result);
900 this->result_ = compound_expr (result, build_deref (ptr));
903 /* Build an assignment expression. The right operand is implicitly
904 converted to the type of the left operand, and assigned to it. */
906 void visit (AssignExp *e)
908 /* First, handle special assignment semantics. */
910 /* Look for array.length = n; */
911 if (e->e1->op == TOKarraylength)
913 /* This case should have been rewritten to `_d_arraysetlengthT` in the
914 semantic phase. */
915 gcc_unreachable ();
918 /* Look for array[] = n; */
919 if (e->e1->op == TOKslice)
921 SliceExp *se = e->e1->isSliceExp ();
922 Type *stype = se->e1->type->toBasetype ();
923 Type *etype = stype->nextOf ()->toBasetype ();
925 /* Determine if we need to run postblit or dtor. */
926 bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
927 bool destructor = needs_dtor (etype);
929 if (e->memset == MemorySet::blockAssign)
931 /* Set a range of elements to one value. */
932 tree t1 = build_expr (e->e1);
933 tree t2 = build_expr (e->e2);
934 tree result;
936 /* Extract any array bounds checks from the slice expression. */
937 tree init = stabilize_expr (&t1);
938 t1 = d_save_expr (t1);
940 if ((postblit || destructor) && e->op != TOKblit)
942 libcall_fn libcall = (e->op == TOKconstruct)
943 ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN;
944 /* So we can call postblits on const/immutable objects. */
945 Type *tm = etype->unSharedOf ()->mutableOf ();
946 tree ti = build_typeinfo (e->loc, tm);
948 result = build_libcall (libcall, Type::tvoid, 4,
949 d_array_ptr (t1),
950 build_address (t2),
951 d_array_length (t1), ti);
953 else if (integer_zerop (t2))
955 tree size = size_mult_expr (d_array_length (t1),
956 size_int (etype->size ()));
957 result = build_memset_call (d_array_ptr (t1), size);
959 else
960 result = build_array_set (d_array_ptr (t1),
961 d_array_length (t1), t2);
963 result = compound_expr (init, result);
964 this->result_ = compound_expr (result, t1);
966 else
968 /* Perform a memcpy operation. */
969 gcc_assert (e->e2->type->ty != TY::Tpointer);
971 if (!postblit && !destructor)
973 tree t1 = d_save_expr (d_array_convert (e->e1));
974 tree t2 = d_save_expr (d_array_convert (e->e2));
976 /* References to array data. */
977 tree t1ptr = d_array_ptr (t1);
978 tree t1len = d_array_length (t1);
979 tree t2ptr = d_array_ptr (t2);
981 /* Generate: memcpy(to, from, size) */
982 tree size = size_mult_expr (t1len, size_int (etype->size ()));
983 tree result = build_memcpy_call (t1ptr, t2ptr, size);
985 /* Insert check that array lengths match and do not overlap. */
986 if (array_bounds_check ())
988 /* tlencmp = (t1len == t2len) */
989 tree t2len = d_array_length (t2);
990 tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len);
992 /* toverlap = (t1ptr + size <= t2ptr
993 || t2ptr + size <= t1ptr) */
994 tree t1ptrcmp = build_boolop (LE_EXPR,
995 build_offset (t1ptr, size),
996 t2ptr);
997 tree t2ptrcmp = build_boolop (LE_EXPR,
998 build_offset (t2ptr, size),
999 t1ptr);
1000 tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp,
1001 t2ptrcmp);
1003 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */
1004 tree tassert = build_array_bounds_call (e->loc);
1005 tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR,
1006 tlencmp, toverlap);
1008 result = build_condition (void_type_node, tboundscheck,
1009 result, tassert);
1012 this->result_ = compound_expr (result, t1);
1014 else if ((postblit || destructor) && e->op != TOKblit)
1016 /* Generate: _d_arrayassign(ti, from, to)
1017 or: _d_arrayctor(ti, from, to) */
1018 libcall_fn libcall = (e->op == TOKconstruct)
1019 ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN;
1021 this->result_ = build_libcall (libcall, e->type, 3,
1022 build_typeinfo (e->loc, etype),
1023 d_array_convert (e->e2),
1024 d_array_convert (e->e1));
1026 else
1028 /* Generate: _d_arraycopy() */
1029 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
1030 size_int (etype->size ()),
1031 d_array_convert (e->e2),
1032 d_array_convert (e->e1));
1036 return;
1039 /* Look for reference initializations. */
1040 if (e->memset == MemorySet::referenceInit)
1042 gcc_assert (e->op == TOKconstruct || e->op == TOKblit);
1043 gcc_assert (e->e1->op == TOKvar);
1045 Declaration *decl = e->e1->isVarExp ()->var;
1046 if (decl->storage_class & (STCout | STCref))
1048 tree t2 = convert_for_assignment (build_expr (e->e2),
1049 e->e2->type, e->e1->type);
1050 tree t1 = build_expr (e->e1);
1051 /* Want reference to lhs, not indirect ref. */
1052 t1 = TREE_OPERAND (t1, 0);
1053 t2 = build_address (t2);
1055 this->result_ = indirect_ref (build_ctype (e->type),
1056 build_assign (INIT_EXPR, t1, t2));
1057 return;
1061 /* Other types of assignments that may require post construction. */
1062 Type *tb1 = e->e1->type->toBasetype ();
1063 tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR;
1065 /* Look for struct assignment. */
1066 if (tb1->ty == TY::Tstruct)
1068 tree t1 = build_expr (e->e1);
1069 tree t2 = convert_for_assignment (build_expr (e->e2, false, true),
1070 e->e2->type, e->e1->type);
1071 StructDeclaration *sd = tb1->isTypeStruct ()->sym;
1073 /* Look for struct = 0. */
1074 if (e->e2->op == TOKint64)
1076 /* Use memset to fill struct. */
1077 gcc_assert (e->op == TOKblit);
1078 tree result = build_memset_call (t1);
1080 /* Maybe set-up hidden pointer to outer scope context. */
1081 if (sd->isNested ())
1083 tree field = get_symbol_decl (sd->vthis);
1084 tree value = build_vthis (sd);
1086 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1087 result = compound_expr (result, vthis_exp);
1090 this->result_ = compound_expr (result, t1);
1092 else
1094 /* Simple struct literal assignment. */
1095 tree init = NULL_TREE;
1097 /* Fill any alignment holes in the struct using memset. */
1098 if ((e->op == TOKconstruct
1099 || (e->e2->op == TOKstructliteral && e->op == TOKblit))
1100 && (sd->isUnionDeclaration () || !identity_compare_p (sd)))
1102 t1 = stabilize_reference (t1);
1103 init = build_memset_call (t1);
1106 /* Elide generating assignment if init is all zeroes. */
1107 if (init != NULL_TREE && initializer_zerop (t2))
1108 this->result_ = compound_expr (init, t1);
1109 else
1111 tree result = build_assign (modifycode, t1, t2);
1112 this->result_ = compound_expr (init, result);
1116 return;
1119 /* Look for static array assignment. */
1120 if (tb1->ty == TY::Tsarray)
1122 /* Look for array = 0. */
1123 if (e->e2->op == TOKint64)
1125 /* Use memset to fill the array. */
1126 gcc_assert (e->op == TOKblit);
1127 this->result_ = build_memset_call (build_expr (e->e1));
1128 return;
1131 Type *etype = tb1->nextOf ();
1132 gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray);
1134 /* Determine if we need to run postblit. */
1135 bool postblit = needs_postblit (etype);
1136 bool destructor = needs_dtor (etype);
1137 bool lvalue = lvalue_p (e->e2);
1139 /* Optimize static array assignment with array literal. Even if the
1140 elements in rhs are all rvalues and don't have to call postblits,
1141 this assignment should call dtors on old assigned elements. */
1142 if ((!postblit && !destructor)
1143 || (e->op == TOKconstruct && e->e2->op == TOKarrayliteral)
1144 || (e->op == TOKconstruct && !lvalue && postblit)
1145 || (e->op == TOKblit || e->e1->type->size () == 0))
1147 tree t1 = build_expr (e->e1);
1148 tree t2 = convert_for_assignment (build_expr (e->e2),
1149 e->e2->type, e->e1->type);
1151 this->result_ = build_assign (modifycode, t1, t2);
1152 return;
1155 Type *arrtype = (e->type->ty == TY::Tsarray)
1156 ? etype->arrayOf () : e->type;
1157 tree result;
1159 if (e->op == TOKconstruct)
1161 /* Generate: _d_arrayctor(ti, from, to) */
1162 result = build_libcall (LIBCALL_ARRAYCTOR, arrtype, 3,
1163 build_typeinfo (e->loc, etype),
1164 d_array_convert (e->e2),
1165 d_array_convert (e->e1));
1167 else
1169 /* Generate: _d_arrayassign_l()
1170 or: _d_arrayassign_r() */
1171 libcall_fn libcall = (lvalue)
1172 ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
1173 tree elembuf = build_local_temp (build_ctype (etype));
1175 result = build_libcall (libcall, arrtype, 4,
1176 build_typeinfo (e->loc, etype),
1177 d_array_convert (e->e2),
1178 d_array_convert (e->e1),
1179 build_address (elembuf));
1182 /* Cast the libcall result back to a static array. */
1183 if (e->type->ty == TY::Tsarray)
1184 result = indirect_ref (build_ctype (e->type),
1185 d_array_ptr (result));
1187 this->result_ = result;
1188 return;
1191 /* Simple assignment. */
1192 tree t1 = build_expr (e->e1);
1193 tree t2 = convert_for_assignment (build_expr (e->e2),
1194 e->e2->type, e->e1->type);
1196 this->result_ = build_assign (modifycode, t1, t2);
1199 /* Build a postfix expression. */
1201 void visit (PostExp *e)
1203 tree result;
1205 if (e->op == TOKplusplus)
1207 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1208 build_expr (e->e1), build_expr (e->e2));
1210 else if (e->op == TOKminusminus)
1212 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1213 build_expr (e->e1), build_expr (e->e2));
1215 else
1216 gcc_unreachable ();
1218 TREE_SIDE_EFFECTS (result) = 1;
1219 this->result_ = result;
1222 /* Build an index expression. */
1224 void visit (IndexExp *e)
1226 Type *tb1 = e->e1->type->toBasetype ();
1228 if (tb1->ty == TY::Taarray)
1230 /* Get the key for the associative array. */
1231 Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
1232 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1233 libcall_fn libcall;
1234 tree tinfo, ptr;
1236 if (e->modifiable)
1238 libcall = LIBCALL_AAGETY;
1239 ptr = build_address (build_expr (e->e1));
1240 tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());
1242 else
1244 libcall = LIBCALL_AAGETRVALUEX;
1245 ptr = build_expr (e->e1);
1246 tinfo = build_typeinfo (e->loc, tkey);
1249 /* Index the associative array. */
1250 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1251 ptr, tinfo,
1252 size_int (tb1->nextOf ()->size ()),
1253 build_address (key));
1255 if (!e->indexIsInBounds && array_bounds_check ())
1257 tree tassert = build_array_bounds_call (e->loc);
1259 result = d_save_expr (result);
1260 result = build_condition (TREE_TYPE (result),
1261 d_truthvalue_conversion (result),
1262 result, tassert);
1265 this->result_ = indirect_ref (build_ctype (e->type), result);
1267 else
1269 /* Get the data pointer and length for static and dynamic arrays. */
1270 tree array = d_save_expr (build_expr (e->e1));
1271 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1273 tree length = NULL_TREE;
1274 if (tb1->ty != TY::Tpointer)
1275 length = get_array_length (array, tb1);
1276 else
1277 gcc_assert (e->lengthVar == NULL);
1279 /* The __dollar variable just becomes a placeholder for the
1280 actual length. */
1281 if (e->lengthVar)
1282 e->lengthVar->csym = length;
1284 /* Generate the index. */
1285 tree index = build_expr (e->e2);
1287 /* If it's a static array and the index is constant, the front end has
1288 already checked the bounds. */
1289 if (tb1->ty != TY::Tpointer)
1290 index = build_bounds_index_condition (e, index, length);
1292 /* Index the .ptr. */
1293 ptr = void_okay_p (ptr);
1294 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1295 build_array_index (ptr, index));
1299 /* Build a comma expression. The type is the type of the right operand. */
1301 void visit (CommaExp *e)
1303 tree t1 = build_expr (e->e1);
1304 tree t2 = build_expr (e->e2);
1305 tree type = e->type ? build_ctype (e->type) : void_type_node;
1307 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1310 /* Build an array length expression. Returns the number of elements
1311 in the array. The result is of type size_t. */
1313 void visit (ArrayLengthExp *e)
1315 if (e->e1->type->toBasetype ()->ty == TY::Tarray)
1316 this->result_ = d_array_length (build_expr (e->e1));
1317 else
1319 /* Static arrays have already been handled by the front-end. */
1320 error ("unexpected type for array length: %qs", e->type->toChars ());
1321 this->result_ = error_mark_node;
1325 /* Build a delegate pointer expression. This will return the frame
1326 pointer value as a type void*. */
1328 void visit (DelegatePtrExp *e)
1330 tree t1 = build_expr (e->e1);
1331 this->result_ = delegate_object (t1);
1334 /* Build a delegate function pointer expression. This will return the
1335 function pointer value as a function type. */
1337 void visit (DelegateFuncptrExp *e)
1339 tree t1 = build_expr (e->e1);
1340 this->result_ = delegate_method (t1);
1343 /* Build a slice expression. */
1345 void visit (SliceExp *e)
1347 Type *tb = e->type->toBasetype ();
1348 Type *tb1 = e->e1->type->toBasetype ();
1349 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray);
1351 /* Use convert-to-dynamic-array code if possible. */
1352 if (!e->lwr)
1354 tree result = build_expr (e->e1);
1355 if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
1356 result = convert_expr (result, e->e1->type, e->type);
1358 this->result_ = result;
1359 return;
1361 else
1362 gcc_assert (e->upr != NULL);
1364 /* Get the data pointer and length for static and dynamic arrays. */
1365 tree array = d_save_expr (build_expr (e->e1));
1366 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1367 tree length = NULL_TREE;
1369 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1370 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1371 if (tb1->ty != TY::Tpointer)
1372 length = get_array_length (array, tb1);
1373 else
1374 gcc_assert (e->lengthVar == NULL);
1376 /* The __dollar variable just becomes a placeholder for the
1377 actual length. */
1378 if (e->lengthVar)
1379 e->lengthVar->csym = length;
1381 /* Generate upper and lower bounds. */
1382 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1383 tree upr_tree = d_save_expr (build_expr (e->upr));
1385 /* If the upper bound has any side effects, then the lower bound should be
1386 copied to a temporary always. */
1387 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1388 lwr_tree = save_expr (lwr_tree);
1390 /* Adjust the .ptr offset. */
1391 if (!integer_zerop (lwr_tree))
1393 tree ptrtype = TREE_TYPE (ptr);
1394 ptr = build_array_index (void_okay_p (ptr), lwr_tree);
1395 ptr = build_nop (ptrtype, ptr);
1398 /* Nothing more to do for static arrays, their bounds checking has been
1399 done at compile-time. */
1400 if (tb->ty == TY::Tsarray)
1402 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1403 return;
1405 else
1406 gcc_assert (tb->ty == TY::Tarray);
1408 /* Generate bounds checking code. */
1409 tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree,
1410 length);
1411 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1412 this->result_ = compound_expr (array, result);
1415 /* Build a cast expression, which converts the given unary expression to the
1416 type of result. */
1418 void visit (CastExp *e)
1420 Type *ebtype = e->e1->type->toBasetype ();
1421 Type *tbtype = e->to->toBasetype ();
1422 tree result = build_expr (e->e1, this->constp_, this->literalp_);
1424 /* Just evaluate e1 if it has any side effects. */
1425 if (tbtype->ty == TY::Tvoid)
1426 this->result_ = build_nop (build_ctype (tbtype), result);
1427 else
1428 this->result_ = convert_for_rvalue (result, ebtype, tbtype);
1431 /* Build a delete expression. */
1433 void visit (DeleteExp *e)
1435 tree t1 = build_expr (e->e1);
1436 Type *tb1 = e->e1->type->toBasetype ();
1438 if (tb1->ty == TY::Tclass)
1440 /* For class object references, if there is a destructor for that class,
1441 the destructor is called for the object instance. */
1442 libcall_fn libcall;
1444 if (e->e1->op == TOKvar)
1446 VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
1447 if (v && v->onstack)
1449 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1450 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1452 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1453 return;
1457 /* Otherwise, the garbage collector is called to immediately free the
1458 memory allocated for the class instance. */
1459 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1460 ? LIBCALL_DELINTERFACE : LIBCALL_DELCLASS;
1462 t1 = build_address (t1);
1463 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1465 else if (tb1->ty == TY::Tarray)
1467 /* For dynamic arrays, the garbage collector is called to immediately
1468 release the memory. */
1469 Type *telem = tb1->nextOf ()->baseElemOf ();
1470 tree ti = null_pointer_node;
1472 if (TypeStruct *ts = telem->isTypeStruct ())
1474 /* Might need to run destructor on array contents. */
1475 if (ts->sym->dtor)
1476 ti = build_typeinfo (e->loc, tb1->nextOf ());
1479 /* Generate: _delarray_t (&t1, ti); */
1480 this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,
1481 build_address (t1), ti);
1483 else if (tb1->ty == TY::Tpointer)
1485 /* For pointers to a struct instance, if the struct has overloaded
1486 operator delete, then that operator is called. */
1487 t1 = build_address (t1);
1488 Type *tnext = tb1->isTypePointer ()->next->toBasetype ();
1490 if (TypeStruct *ts = tnext->isTypeStruct ())
1492 if (ts->sym->dtor)
1494 tree ti = build_typeinfo (e->loc, tnext);
1495 this->result_ = build_libcall (LIBCALL_DELSTRUCT, Type::tvoid,
1496 2, t1, ti);
1497 return;
1501 /* Otherwise, the garbage collector is called to immediately free the
1502 memory allocated for the pointer. */
1503 this->result_ = build_libcall (LIBCALL_DELMEMORY, Type::tvoid, 1, t1);
1505 else
1507 error ("don%'t know how to delete %qs", e->e1->toChars ());
1508 this->result_ = error_mark_node;
1512 /* Build a remove expression, which removes a particular key from an
1513 associative array. */
1515 void visit (RemoveExp *e)
1517 /* Check that the array is actually an associative array. */
1518 if (e->e1->type->toBasetype ()->ty == TY::Taarray)
1520 Type *tb = e->e1->type->toBasetype ();
1521 Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
1522 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1524 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1525 build_expr (e->e1),
1526 build_typeinfo (e->loc, tkey),
1527 build_address (index));
1529 else
1531 error ("%qs is not an associative array", e->e1->toChars ());
1532 this->result_ = error_mark_node;
1536 /* Build an unary not expression. */
1538 void visit (NotExp *e)
1540 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1541 /* Need to convert to boolean type or this will fail. */
1542 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1544 this->result_ = d_convert (build_ctype (e->type), result);
1547 /* Build a compliment expression, where all the bits in the value are
1548 complemented. Note: unlike in C, the usual integral promotions
1549 are not performed prior to the complement operation. */
1551 void visit (ComExp *e)
1553 TY ty1 = e->e1->type->toBasetype ()->ty;
1554 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1556 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1557 build_expr (e->e1));
1560 /* Build an unary negation expression. */
1562 void visit (NegExp *e)
1564 TY ty1 = e->e1->type->toBasetype ()->ty;
1565 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1567 tree type = build_ctype (e->type);
1568 tree expr = build_expr (e->e1);
1570 /* If the operation needs excess precision. */
1571 tree eptype = excess_precision_type (type);
1572 if (eptype != NULL_TREE)
1573 expr = d_convert (eptype, expr);
1574 else
1575 eptype = type;
1577 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1578 this->result_ = d_convert (type, ret);
1581 /* Build a pointer index expression. */
1583 void visit (PtrExp *e)
1585 Type *tnext = NULL;
1586 size_t offset;
1587 tree result;
1589 if (e->e1->op == TOKadd)
1591 AddExp *ae = e->e1->isAddExp ();
1592 if (ae->e1->op == TOKaddress
1593 && ae->e2->isConst () && ae->e2->type->isintegral ())
1595 Expression *ex = ae->e1->isAddrExp ()->e1;
1596 tnext = ex->type->toBasetype ();
1597 result = build_expr (ex);
1598 offset = ae->e2->toUInteger ();
1601 else if (e->e1->op == TOKsymoff)
1603 SymOffExp *se = e->e1->isSymOffExp ();
1604 if (!declaration_reference_p (se->var))
1606 tnext = se->var->type->toBasetype ();
1607 result = get_decl_tree (se->var);
1608 offset = se->offset;
1612 /* Produce better code by converting *(#record + n) to
1613 COMPONENT_REFERENCE. Otherwise, the variable will always be
1614 allocated in memory because its address is taken. */
1615 if (tnext && tnext->ty == TY::Tstruct)
1617 StructDeclaration *sd = tnext->isTypeStruct ()->sym;
1619 for (size_t i = 0; i < sd->fields.length; i++)
1621 VarDeclaration *field = sd->fields[i];
1623 if (field->offset == offset
1624 && same_type_p (field->type, e->type))
1626 /* Catch errors, backend will ICE otherwise. */
1627 if (error_operand_p (result))
1628 this->result_ = result;
1629 else
1631 result = component_ref (result, get_symbol_decl (field));
1632 this->result_ = result;
1634 return;
1636 else if (field->offset > offset)
1637 break;
1641 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1644 /* Build an unary address expression. */
1646 void visit (AddrExp *e)
1648 tree type = build_ctype (e->type);
1649 tree exp;
1651 /* The frontend optimizer can convert const symbol into a struct literal.
1652 Taking the address of a struct literal is otherwise illegal. */
1653 if (e->e1->op == TOKstructliteral)
1655 StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
1656 gcc_assert (sle != NULL);
1658 /* Build the reference symbol, the decl is built first as the
1659 initializer may have recursive references. */
1660 if (!sle->sym)
1662 sle->sym = build_artificial_decl (build_ctype (sle->type),
1663 NULL_TREE, "S");
1664 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1665 d_pushdecl (sle->sym);
1666 rest_of_decl_compilation (sle->sym, 1, 0);
1669 exp = sle->sym;
1671 else
1672 exp = build_expr (e->e1, this->constp_, this->literalp_);
1674 TREE_CONSTANT (exp) = 0;
1675 this->result_ = d_convert (type, build_address (exp));
1678 /* Build a function call expression. */
1680 void visit (CallExp *e)
1682 Type *tb = e->e1->type->toBasetype ();
1683 Expression *e1b = e->e1;
1685 tree callee = NULL_TREE;
1686 tree object = NULL_TREE;
1687 tree cleanup = NULL_TREE;
1688 tree returnvalue = NULL_TREE;
1689 TypeFunction *tf = NULL;
1691 /* Calls to delegates can sometimes look like this. */
1692 if (e1b->op == TOKcomma)
1694 e1b = e1b->isCommaExp ()->e2;
1695 gcc_assert (e1b->op == TOKvar);
1697 Declaration *var = e1b->isVarExp ()->var;
1698 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1701 if (e1b->op == TOKdotvar && tb->ty != TY::Tdelegate)
1703 DotVarExp *dve = e1b->isDotVarExp ();
1705 /* Don't modify the static initializer for struct literals. */
1706 if (dve->e1->op == TOKstructliteral)
1708 StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
1709 sle->useStaticInit = false;
1712 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1713 if (fd != NULL)
1715 /* Get the correct callee from the DotVarExp object. */
1716 tree fndecl = get_symbol_decl (fd);
1717 AggregateDeclaration *ad = fd->isThis ();
1719 /* Static method; ignore the object instance. */
1720 if (!ad)
1721 callee = build_address (fndecl);
1722 else
1724 tree thisexp = build_expr (dve->e1);
1726 /* When constructing temporaries, if the constructor throws,
1727 then the object is destructed even though it is not a fully
1728 constructed object yet. And so this call will need to be
1729 moved inside the TARGET_EXPR_INITIAL slot. */
1730 if (fd->isCtorDeclaration ()
1731 && TREE_CODE (thisexp) == COMPOUND_EXPR
1732 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1733 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1735 cleanup = TREE_OPERAND (thisexp, 0);
1736 thisexp = TREE_OPERAND (thisexp, 1);
1739 if (TREE_CODE (thisexp) == CONSTRUCTOR)
1740 thisexp = force_target_expr (thisexp);
1742 /* Want reference to `this' object. */
1743 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1744 thisexp = build_address (thisexp);
1746 /* Make the callee a virtual call. */
1747 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1749 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1750 tree thistype = build_ctype (ad->handleType ());
1751 thisexp = build_nop (thistype, d_save_expr (thisexp));
1752 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1754 else
1755 fndecl = build_address (fndecl);
1757 /* C++ constructors return void, even though front-end semantic
1758 treats them as implicitly returning `this'. Set returnvalue
1759 to override the result of this expression. */
1760 if (fd->isCtorDeclaration ())
1762 thisexp = d_save_expr (thisexp);
1763 returnvalue = thisexp;
1766 callee = build_method_call (fndecl, thisexp, fd->type);
1771 if (callee == NULL_TREE)
1772 callee = build_expr (e1b);
1774 if (METHOD_CALL_EXPR (callee))
1776 /* This could be a delegate expression (TY == Tdelegate), but not
1777 actually a delegate variable. */
1778 if (e1b->op == TOKdotvar)
1780 /* This gets the true function type, getting the function type
1781 from e1->type can sometimes be incorrect, such as when calling
1782 a `ref' return function. */
1783 tf = get_function_type (e1b->isDotVarExp ()->var->type);
1785 else
1786 tf = get_function_type (tb);
1788 extract_from_method_call (callee, callee, object);
1790 else if (tb->ty == TY::Tdelegate)
1792 /* Delegate call, extract .object and .funcptr from var. */
1793 callee = d_save_expr (callee);
1794 tf = get_function_type (tb);
1795 object = delegate_object (callee);
1796 callee = delegate_method (callee);
1798 else if (e1b->op == TOKvar)
1800 FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
1801 gcc_assert (fd != NULL);
1802 tf = get_function_type (fd->type);
1804 if (fd->isNested ())
1806 /* Maybe re-evaluate symbol storage treating `fd' as public. */
1807 if (call_by_alias_p (d_function_chain->function, fd))
1808 TREE_PUBLIC (callee) = 1;
1810 object = get_frame_for_symbol (fd);
1812 else if (fd->needThis ())
1814 error_at (make_location_t (e1b->loc),
1815 "need %<this%> to access member %qs", fd->toChars ());
1816 /* Continue compiling... */
1817 object = null_pointer_node;
1820 else
1822 /* Normal direct function call. */
1823 tf = get_function_type (tb);
1826 gcc_assert (tf != NULL);
1828 /* Now we have the type, callee and maybe object reference,
1829 build the call expression. */
1830 tree exp = d_build_call (tf, callee, object, e->arguments);
1832 if (returnvalue != NULL_TREE)
1833 exp = compound_expr (exp, returnvalue);
1835 if (tf->isref ())
1836 exp = build_deref (exp);
1838 /* Some library calls are defined to return a generic type.
1839 this->type is the real type we want to return. */
1840 if (e->type->isTypeBasic ())
1841 exp = d_convert (build_ctype (e->type), exp);
1843 /* If this call was found to be a constructor for a temporary with a
1844 cleanup, then move the call inside the TARGET_EXPR. */
1845 if (cleanup != NULL_TREE)
1847 tree init = TARGET_EXPR_INITIAL (cleanup);
1848 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1850 /* Keep the return value outside the TARGET_EXPR. */
1851 if (returnvalue != NULL_TREE)
1852 cleanup = compound_expr (cleanup, TREE_OPERAND (exp, 1));
1854 exp = cleanup;
1857 this->result_ = exp;
1860 /* Build a delegate expression. */
1862 void visit (DelegateExp *e)
1864 if (e->func->semanticRun == PASS::semantic3done)
1866 /* Add the function as nested function if it belongs to this module.
1867 ie: it is a member of this module, or it is a template instance. */
1868 Dsymbol *owner = e->func->toParent ();
1869 while (!owner->isTemplateInstance () && owner->toParent ())
1870 owner = owner->toParent ();
1871 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1872 build_decl_tree (e->func);
1875 tree fndecl;
1876 tree object;
1878 if (e->func->isNested () && !e->func->isThis ())
1880 if (e->e1->op == TOKnull)
1881 object = build_expr (e->e1);
1882 else
1883 object = get_frame_for_symbol (e->func);
1885 fndecl = build_address (get_symbol_decl (e->func));
1887 else
1889 if (!e->func->isThis ())
1891 error ("delegates are only for non-static functions");
1892 this->result_ = error_mark_node;
1893 return;
1896 object = build_expr (e->e1);
1898 /* Want reference to `this' object. */
1899 if (e->e1->type->ty != TY::Tclass && e->e1->type->ty != TY::Tpointer)
1900 object = build_address (object);
1902 /* Object reference could be the outer `this' field of a class or
1903 closure of type `void*'. Cast it to the right type. */
1904 if (e->e1->type->ty == TY::Tclass)
1905 object = d_convert (build_ctype (e->e1->type), object);
1907 fndecl = get_symbol_decl (e->func);
1909 /* Get pointer to function out of the virtual table. */
1910 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1911 && e->e1->op != TOKsuper && e->e1->op != TOKdottype)
1913 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1914 object = d_save_expr (object);
1915 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1917 else
1918 fndecl = build_address (fndecl);
1921 this->result_ = build_method_call (fndecl, object, e->type);
1924 /* Build a type component expression. */
1926 void visit (DotTypeExp *e)
1928 /* Just a pass through to underlying expression. */
1929 this->result_ = build_expr (e->e1);
1932 /* Build a component reference expression. */
1934 void visit (DotVarExp *e)
1936 VarDeclaration *vd = e->var->isVarDeclaration ();
1938 /* This could also be a function, but relying on that being taken
1939 care of by the visitor interface for CallExp. */
1940 if (vd != NULL)
1942 if (!vd->isField ())
1943 this->result_ = get_decl_tree (vd);
1944 else
1946 tree object = build_expr (e->e1);
1948 if (e->e1->type->toBasetype ()->ty != TY::Tstruct)
1949 object = build_deref (object);
1951 this->result_ = component_ref (object, get_symbol_decl (vd));
1954 else
1956 error ("%qs is not a field, but a %qs",
1957 e->var->toChars (), e->var->kind ());
1958 this->result_ = error_mark_node;
1962 /* Build an assert expression, used to declare conditions that must hold at
1963 that a given point in the program. */
1965 void visit (AssertExp *e)
1967 Type *tb1 = e->e1->type->toBasetype ();
1968 tree arg = build_expr (e->e1);
1969 tree tmsg = NULL_TREE;
1970 tree assert_pass = void_node;
1971 tree assert_fail;
1973 if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ())
1975 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1976 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1977 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1978 libcall_fn libcall;
1980 if (e->msg)
1982 tmsg = build_expr_dtor (e->msg);
1983 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1985 else
1986 libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP;
1988 /* Build a call to _d_assert(). */
1989 assert_fail = build_assert_call (e->loc, libcall, tmsg);
1991 if (global.params.useInvariants == CHECKENABLEon)
1993 /* If the condition is a D class or struct object with an invariant,
1994 call it if the condition result is true. */
1995 if (tb1->ty == TY::Tclass)
1997 ClassDeclaration *cd = tb1->isClassHandle ();
1998 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
2000 arg = d_save_expr (arg);
2001 assert_pass = build_libcall (LIBCALL_INVARIANT,
2002 Type::tvoid, 1, arg);
2005 else if (tb1->ty == TY::Tpointer
2006 && tb1->nextOf ()->ty == TY::Tstruct)
2008 StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
2009 if (sd->inv != NULL)
2011 Expressions args;
2012 arg = d_save_expr (arg);
2013 assert_pass = d_build_call_expr (sd->inv, arg, &args);
2018 else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
2020 /* Generate: __builtin_trap() */
2021 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
2022 assert_fail = build_call_expr (fn, 0);
2024 else
2026 /* Assert contracts are turned off. */
2027 this->result_ = void_node;
2028 return;
2031 /* Build condition that we are asserting in this contract. */
2032 tree condition = convert_for_condition (arg, e->e1->type);
2034 /* We expect the condition to always be true, as what happens if an assert
2035 contract is false is undefined behavior. */
2036 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
2037 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
2038 tree pred_type = TREE_VALUE (arg_types);
2039 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
2041 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
2042 build_int_cst (expected_type, 1));
2043 condition = d_truthvalue_conversion (condition);
2045 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
2048 /* Build a declaration expression. */
2050 void visit (DeclarationExp *e)
2052 /* Compile the declaration. */
2053 push_stmt_list ();
2054 build_decl_tree (e->declaration);
2055 tree result = pop_stmt_list ();
2057 /* Construction of an array for typesafe-variadic function arguments
2058 can cause an empty STMT_LIST here. This can causes problems
2059 during gimplification. */
2060 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
2061 result = build_empty_stmt (input_location);
2063 this->result_ = result;
2066 /* Build a typeid expression. Returns an instance of class TypeInfo
2067 corresponding to. */
2069 void visit (TypeidExp *e)
2071 if (Type *tid = isType (e->obj))
2073 tree ti = build_typeinfo (e->loc, tid);
2075 /* If the typeinfo is at an offset. */
2076 if (tid->vtinfo->offset)
2077 ti = build_offset (ti, size_int (tid->vtinfo->offset));
2079 this->result_ = build_nop (build_ctype (e->type), ti);
2081 else if (Expression *tid = isExpression (e->obj))
2083 Type *type = tid->type->toBasetype ();
2084 assert (type->ty == TY::Tclass);
2086 /* Generate **classptr to get the classinfo. */
2087 tree ci = build_expr (tid);
2088 ci = indirect_ref (ptr_type_node, ci);
2089 ci = indirect_ref (ptr_type_node, ci);
2091 /* Add extra indirection for interfaces. */
2092 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
2093 ci = indirect_ref (ptr_type_node, ci);
2095 this->result_ = build_nop (build_ctype (e->type), ci);
2097 else
2098 gcc_unreachable ();
2101 /* Build a function/lambda expression. */
2103 void visit (FuncExp *e)
2105 Type *ftype = e->type->toBasetype ();
2107 /* This check is for lambda's, remove `vthis' as function isn't nested. */
2108 if (e->fd->tok == TOKreserved && ftype->ty == TY::Tpointer)
2110 e->fd->tok = TOKfunction;
2111 e->fd->vthis = NULL;
2114 /* Compile the function literal body. */
2115 build_decl_tree (e->fd);
2117 /* If nested, this will be a trampoline. */
2118 if (e->fd->isNested ())
2120 tree func = build_address (get_symbol_decl (e->fd));
2121 tree object;
2123 if (this->constp_)
2125 /* Static delegate variables have no context pointer. */
2126 object = null_pointer_node;
2127 this->result_ = build_method_call (func, object, e->fd->type);
2128 TREE_CONSTANT (this->result_) = 1;
2130 else
2132 object = get_frame_for_symbol (e->fd);
2133 this->result_ = build_method_call (func, object, e->fd->type);
2136 else
2138 this->result_ = build_nop (build_ctype (e->type),
2139 build_address (get_symbol_decl (e->fd)));
2143 /* Build a halt expression. */
2145 void visit (HaltExp *)
2147 /* Should we use trap() or abort()? */
2148 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2149 this->result_ = build_call_expr (ttrap, 0);
2152 /* Build a symbol pointer offset expression. */
2154 void visit (SymOffExp *e)
2156 /* Build the address and offset of the symbol. */
2157 size_t soffset = e->isSymOffExp ()->offset;
2158 tree result = get_decl_tree (e->var);
2159 TREE_USED (result) = 1;
2161 if (declaration_reference_p (e->var))
2162 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2163 else
2164 result = build_address (result);
2166 if (!soffset)
2167 result = d_convert (build_ctype (e->type), result);
2168 else
2170 tree offset = size_int (soffset);
2171 result = build_nop (build_ctype (e->type),
2172 build_offset (result, offset));
2175 this->result_ = result;
2178 /* Build a variable expression. */
2180 void visit (VarExp *e)
2182 if (e->var->needThis ())
2184 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2185 this->result_ = error_mark_node;
2186 return;
2188 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2190 /* __ctfe is always false at run-time. */
2191 this->result_ = integer_zero_node;
2192 return;
2195 /* This check is same as is done in FuncExp for lambdas. */
2196 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2197 if (fld != NULL)
2199 if (fld->tok == TOKreserved)
2201 fld->tok = TOKfunction;
2202 fld->vthis = NULL;
2205 /* Compiler the function literal body. */
2206 build_decl_tree (fld);
2209 if (this->constp_)
2211 /* Want the initializer, not the expression. */
2212 VarDeclaration *var = e->var->isVarDeclaration ();
2213 SymbolDeclaration *sd = e->var->isSymbolDeclaration ();
2214 tree init = NULL_TREE;
2216 if (var && (var->isConst () || var->isImmutable ())
2217 && e->type->toBasetype ()->ty != TY::Tsarray && var->_init)
2219 if (var->inuse)
2220 error_at (make_location_t (e->loc), "recursive reference %qs",
2221 e->toChars ());
2222 else
2224 var->inuse++;
2225 init = build_expr (initializerToExpression (var->_init), true);
2226 var->inuse--;
2229 else if (sd && sd->dsym)
2230 init = layout_struct_initializer (sd->dsym);
2231 else
2232 error_at (make_location_t (e->loc), "non-constant expression %qs",
2233 e->toChars ());
2235 if (init != NULL_TREE)
2236 this->result_ = init;
2237 else
2238 this->result_ = error_mark_node;
2240 else
2242 tree result = get_decl_tree (e->var);
2243 TREE_USED (result) = 1;
2245 /* For variables that are references - currently only out/inout
2246 arguments; objects don't count - evaluating the variable means
2247 we want what it refers to. */
2248 if (declaration_reference_p (e->var))
2249 result = indirect_ref (build_ctype (e->var->type), result);
2251 this->result_ = result;
2255 /* Build a this variable expression. */
2257 void visit (ThisExp *e)
2259 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2260 tree result = NULL_TREE;
2262 if (e->var)
2263 result = get_decl_tree (e->var);
2264 else
2266 gcc_assert (fd && fd->vthis);
2267 result = get_decl_tree (fd->vthis);
2270 if (e->type->ty == TY::Tstruct)
2271 result = build_deref (result);
2273 this->result_ = result;
2276 /* Build a new expression, which allocates memory either on the garbage
2277 collected heap or by using a class or struct specific allocator. */
2279 void visit (NewExp *e)
2281 Type *tb = e->type->toBasetype ();
2282 tree result;
2284 if (tb->ty == TY::Tclass)
2286 /* Allocating a new class. */
2287 tb = e->newtype->toBasetype ();
2289 ClassDeclaration *cd = tb->isTypeClass ()->sym;
2290 tree type = build_ctype (tb);
2291 tree setup_exp = NULL_TREE;
2292 tree new_call;
2294 if (e->onstack)
2296 /* If being used as an initializer for a local variable with scope
2297 storage class, then the instance is allocated on the stack
2298 rather than the heap or using the class specific allocator. */
2299 tree var = build_local_temp (TREE_TYPE (type));
2300 new_call = build_nop (type, build_address (var));
2301 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2303 else
2305 /* Generate: _d_newclass() */
2306 tree arg = build_address (get_classinfo_decl (cd));
2307 libcall_fn libcall = (global.params.ehnogc && e->thrownew)
2308 ? LIBCALL_NEWTHROW : LIBCALL_NEWCLASS;
2309 new_call = build_libcall (libcall, tb, 1, arg);
2312 /* Set the context pointer for nested classes. */
2313 if (cd->isNested ())
2315 tree field = get_symbol_decl (cd->vthis);
2316 tree value = NULL_TREE;
2318 if (e->thisexp)
2320 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2321 /* The class or function we're nested in. */
2322 Dsymbol *outer = cd->toParentLocal ();
2324 value = build_expr (e->thisexp);
2326 if (outer != tcd)
2328 ClassDeclaration *ocd = outer->isClassDeclaration ();
2329 int offset = 0;
2330 gcc_assert (ocd->isBaseOf (tcd, &offset));
2331 /* Could just add offset... */
2332 value = convert_expr (value, e->thisexp->type, ocd->type);
2335 else
2336 value = build_vthis (cd);
2338 if (value != NULL_TREE)
2340 /* Generate: (new())->vthis = this; */
2341 new_call = d_save_expr (new_call);
2342 field = component_ref (build_deref (new_call), field);
2343 setup_exp = compound_expr (setup_exp,
2344 modify_expr (field, value));
2347 new_call = compound_expr (setup_exp, new_call);
2349 /* Call the class constructor. */
2350 if (e->member)
2351 result = d_build_call_expr (e->member, new_call, e->arguments);
2352 else
2353 result = new_call;
2355 if (e->argprefix)
2356 result = compound_expr (build_expr (e->argprefix), result);
2358 else if (tb->ty == TY::Tpointer
2359 && tb->nextOf ()->toBasetype ()->ty == TY::Tstruct)
2361 /* Allocating memory for a new struct. */
2362 Type *htype = e->newtype->toBasetype ();
2363 gcc_assert (!e->onstack);
2365 TypeStruct *stype = htype->isTypeStruct ();
2366 StructDeclaration *sd = stype->sym;
2367 tree new_call;
2369 /* Cannot new an opaque struct. */
2370 if (sd->size (e->loc) == 0)
2372 this->result_ = d_convert (build_ctype (e->type),
2373 integer_zero_node);
2374 return;
2377 /* Generate: _d_newitemT() */
2378 libcall_fn libcall = htype->isZeroInit ()
2379 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2380 tree arg = build_typeinfo (e->loc, e->newtype);
2381 new_call = build_libcall (libcall, tb, 1, arg);
2383 if (e->member || !e->arguments)
2385 /* Set the context pointer for nested structs. */
2386 if (sd->isNested ())
2388 tree value = build_vthis (sd);
2389 tree field = get_symbol_decl (sd->vthis);
2390 tree type = build_ctype (stype);
2392 new_call = d_save_expr (new_call);
2393 field = component_ref (indirect_ref (type, new_call), field);
2394 new_call = compound_expr (modify_expr (field, value), new_call);
2397 /* Call the struct constructor. */
2398 if (e->member)
2399 result = d_build_call_expr (e->member, new_call, e->arguments);
2400 else
2401 result = new_call;
2403 else
2405 /* If we have a user supplied initializer, then set-up with a
2406 struct literal. */
2407 if (e->arguments != NULL && sd->fields.length != 0)
2409 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2410 e->arguments,
2411 htype);
2412 new_call = d_save_expr (new_call);
2413 se->type = sd->type;
2414 se->sym = new_call;
2415 result = compound_expr (build_expr (se), new_call);
2417 else
2418 result = new_call;
2421 if (e->argprefix)
2422 result = compound_expr (build_expr (e->argprefix), result);
2424 else if (tb->ty == TY::Tarray)
2426 /* Allocating memory for a new D array. */
2427 tb = e->newtype->toBasetype ();
2428 TypeDArray *tarray = tb->isTypeDArray ();
2430 gcc_assert (e->arguments && e->arguments->length >= 1);
2432 if (e->arguments->length == 1)
2434 /* Single dimension array allocations. */
2435 Expression *arg = (*e->arguments)[0];
2437 if (tarray->next->size () == 0)
2439 /* Array element size is unknown. */
2440 this->result_ = d_array_value (build_ctype (e->type),
2441 size_int (0), null_pointer_node);
2442 return;
2445 libcall_fn libcall = tarray->next->isZeroInit ()
2446 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
2447 result = build_libcall (libcall, tb, 2,
2448 build_typeinfo (e->loc, e->type),
2449 build_expr (arg));
2451 else
2453 /* Multidimensional array allocations. */
2454 tree tarray = make_array_type (Type::tsize_t, e->arguments->length);
2455 tree var = build_local_temp (tarray);
2456 vec <constructor_elt, va_gc> *elms = NULL;
2458 /* Get the base element type for the array, generating the
2459 initializer for the dims parameter along the way. */
2460 Type *telem = e->newtype->toBasetype ();
2461 for (size_t i = 0; i < e->arguments->length; i++)
2463 Expression *arg = (*e->arguments)[i];
2464 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2466 gcc_assert (telem->ty == TY::Tarray);
2467 telem = telem->toBasetype ()->nextOf ();
2468 gcc_assert (telem);
2471 /* Initialize the temporary. */
2472 tree init = modify_expr (var, build_constructor (tarray, elms));
2473 var = compound_expr (init, var);
2475 /* Generate: _d_newarraymTX(ti, dims)
2476 or: _d_newarraymiTX(ti, dims) */
2477 libcall_fn libcall = telem->isZeroInit ()
2478 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2480 tree tinfo = build_typeinfo (e->loc, e->type);
2481 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2482 size_int (e->arguments->length),
2483 build_address (var));
2485 result = build_libcall (libcall, tb, 2, tinfo, dims);
2488 if (e->argprefix)
2489 result = compound_expr (build_expr (e->argprefix), result);
2491 else if (tb->ty == TY::Tpointer)
2493 /* Allocating memory for a new pointer. */
2494 TypePointer *tpointer = tb->isTypePointer ();
2496 if (tpointer->next->size () == 0)
2498 /* Pointer element size is unknown. */
2499 this->result_ = d_convert (build_ctype (e->type),
2500 integer_zero_node);
2501 return;
2504 libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
2505 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2507 tree arg = build_typeinfo (e->loc, e->newtype);
2508 result = build_libcall (libcall, tb, 1, arg);
2510 if (e->arguments && e->arguments->length == 1)
2512 result = d_save_expr (result);
2513 tree init = modify_expr (build_deref (result),
2514 build_expr ((*e->arguments)[0]));
2515 result = compound_expr (init, result);
2518 if (e->argprefix)
2519 result = compound_expr (build_expr (e->argprefix), result);
2521 else
2522 gcc_unreachable ();
2524 this->result_ = convert_expr (result, tb, e->type);
2527 /* Build an integer literal. */
2529 void visit (IntegerExp *e)
2531 tree ctype = build_ctype (e->type->toBasetype ());
2532 this->result_ = build_integer_cst (e->value, ctype);
2535 /* Build a floating-point literal. */
2537 void visit (RealExp *e)
2539 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2542 /* Build a complex literal. */
2544 void visit (ComplexExp *e)
2546 Type *tnext;
2548 switch (e->type->toBasetype ()->ty)
2550 case TY::Tcomplex32:
2551 tnext = (TypeBasic *) Type::tfloat32;
2552 break;
2554 case TY::Tcomplex64:
2555 tnext = (TypeBasic *) Type::tfloat64;
2556 break;
2558 case TY::Tcomplex80:
2559 tnext = (TypeBasic *) Type::tfloat80;
2560 break;
2562 default:
2563 gcc_unreachable ();
2566 this->result_ = build_complex (build_ctype (e->type),
2567 build_float_cst (creall (e->value), tnext),
2568 build_float_cst (cimagl (e->value), tnext));
2571 /* Build a string literal, all strings are null terminated except for
2572 static arrays. */
2574 void visit (StringExp *e)
2576 Type *tb = e->type->toBasetype ();
2577 tree type = build_ctype (e->type);
2579 if (tb->ty == TY::Tsarray)
2581 /* Turn the string into a constructor for the static array. */
2582 vec <constructor_elt, va_gc> *elms = NULL;
2583 vec_safe_reserve (elms, e->len);
2584 tree etype = TREE_TYPE (type);
2586 for (size_t i = 0; i < e->len; i++)
2588 tree value = build_integer_cst (e->charAt (i), etype);
2589 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2592 tree ctor = build_constructor (type, elms);
2593 TREE_CONSTANT (ctor) = 1;
2594 this->result_ = ctor;
2596 else
2598 /* Copy the string contents to a null terminated string. */
2599 dinteger_t length = (e->len * e->sz);
2600 char *string = XALLOCAVEC (char, length + 1);
2601 memcpy (string, e->string, length);
2602 string[length] = '\0';
2604 /* String value and type includes the null terminator. */
2605 tree value = build_string (length, string);
2606 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2607 value = build_address (value);
2609 if (tb->ty == TY::Tarray)
2610 value = d_array_value (type, size_int (e->len), value);
2612 TREE_CONSTANT (value) = 1;
2613 this->result_ = d_convert (type, value);
2617 /* Build a tuple literal. Just an argument list that may have
2618 side effects that need evaluation. */
2620 void visit (TupleExp *e)
2622 tree result = NULL_TREE;
2624 if (e->e0)
2625 result = build_expr (e->e0, this->constp_, true);
2627 for (size_t i = 0; i < e->exps->length; ++i)
2629 Expression *exp = (*e->exps)[i];
2630 result = compound_expr (result, build_expr (exp, this->constp_, true));
2633 if (result == NULL_TREE)
2634 result = void_node;
2636 this->result_ = result;
2639 /* Build an array literal. The common type of the all elements is taken to
2640 be the type of the array element, and all elements are implicitly
2641 converted to that type. */
2643 void visit (ArrayLiteralExp *e)
2645 Type *tb = e->type->toBasetype ();
2647 /* Implicitly convert void[n] to ubyte[n]. */
2648 if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid)
2649 tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());
2651 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray
2652 || tb->ty == TY::Tpointer);
2654 /* Handle empty array literals. */
2655 if (e->elements->length == 0)
2657 if (tb->ty == TY::Tarray)
2658 this->result_ = d_array_value (build_ctype (e->type),
2659 size_int (0), null_pointer_node);
2660 else
2661 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2662 NULL);
2664 return;
2667 /* Build an expression that assigns the expressions in ELEMENTS to
2668 a constructor. */
2669 vec <constructor_elt, va_gc> *elms = NULL;
2670 vec_safe_reserve (elms, e->elements->length);
2671 bool constant_p = true;
2672 tree saved_elems = NULL_TREE;
2674 Type *etype = tb->nextOf ();
2675 tree satype = make_array_type (etype, e->elements->length);
2677 for (size_t i = 0; i < e->elements->length; i++)
2679 Expression *expr = e->getElement (i);
2680 tree value = build_expr (expr, this->constp_, true);
2682 /* Only append nonzero values, the backend will zero out the rest
2683 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2684 if (!initializer_zerop (value))
2686 if (!TREE_CONSTANT (value))
2687 constant_p = false;
2689 /* Split construction of values out of the constructor if there
2690 may be side effects. */
2691 tree init = stabilize_expr (&value);
2692 if (init != NULL_TREE)
2693 saved_elems = compound_expr (saved_elems, init);
2695 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2696 convert_expr (value, expr->type, etype));
2700 /* Now return the constructor as the correct type. For static arrays there
2701 is nothing else to do. For dynamic arrays, return a two field struct.
2702 For pointers, return the address. */
2703 tree ctor = build_constructor (satype, elms);
2704 tree type = build_ctype (e->type);
2706 /* Nothing else to do for static arrays. */
2707 if (tb->ty == TY::Tsarray || this->constp_)
2709 /* Can't take the address of the constructor, so create an anonymous
2710 static symbol, and then refer to it. */
2711 if (tb->ty != TY::Tsarray)
2713 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2714 ctor = build_address (decl);
2715 if (tb->ty == TY::Tarray)
2716 ctor = d_array_value (type, size_int (e->elements->length), ctor);
2718 d_pushdecl (decl);
2719 rest_of_decl_compilation (decl, 1, 0);
2722 /* If the array literal is readonly or static. */
2723 if (constant_p)
2724 TREE_CONSTANT (ctor) = 1;
2725 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2726 TREE_STATIC (ctor) = 1;
2728 /* Use memset to fill any alignment holes in the array. */
2729 if (!this->constp_ && !this->literalp_)
2731 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
2733 if (ts != NULL && (!identity_compare_p (ts->sym)
2734 || ts->sym->isUnionDeclaration ()))
2736 tree var = build_local_temp (TREE_TYPE (ctor));
2737 tree init = build_memset_call (var);
2738 /* Evaluate memset() first, then any saved elements. */
2739 saved_elems = compound_expr (init, saved_elems);
2740 ctor = compound_expr (modify_expr (var, ctor), var);
2744 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2746 else
2748 /* Allocate space on the memory managed heap. */
2749 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2750 etype->pointerTo (), 2,
2751 build_typeinfo (e->loc, etype->arrayOf ()),
2752 size_int (e->elements->length));
2753 mem = d_save_expr (mem);
2755 /* Now copy the constructor into memory. */
2756 tree size = size_mult_expr (size_int (e->elements->length),
2757 size_int (tb->nextOf ()->size ()));
2759 tree result = build_memcpy_call (mem, build_address (ctor), size);
2761 /* Return the array pointed to by MEM. */
2762 result = compound_expr (result, mem);
2764 if (tb->ty == TY::Tarray)
2765 result = d_array_value (type, size_int (e->elements->length), result);
2767 this->result_ = compound_expr (saved_elems, result);
2771 /* Build an associative array literal. The common type of the all keys is
2772 taken to be the key type, and common type of all values the value type.
2773 All keys and values are then implicitly converted as needed. */
2775 void visit (AssocArrayLiteralExp *e)
2777 /* Want the mutable type for typeinfo reference. */
2778 Type *tb = e->type->toBasetype ()->mutableOf ();
2780 /* Handle empty assoc array literals. */
2781 TypeAArray *ta = tb->isTypeAArray ();
2782 if (e->keys->length == 0)
2784 this->result_ = build_constructor (build_ctype (ta), NULL);
2785 return;
2788 /* Build an expression that assigns all expressions in KEYS
2789 to a constructor. */
2790 tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
2791 e->keys, this->constp_);
2792 tree init = stabilize_expr (&akeys);
2794 /* Do the same with all expressions in VALUES. */
2795 tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
2796 e->values, this->constp_);
2797 init = compound_expr (init, stabilize_expr (&avals));
2799 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2800 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2801 size_int (e->keys->length),
2802 build_address (akeys));
2803 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2804 size_int (e->values->length),
2805 build_address (avals));
2807 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2808 build_typeinfo (e->loc, ta), keys, vals);
2810 /* Return an associative array pointed to by MEM. */
2811 tree aatype = build_ctype (ta);
2812 vec <constructor_elt, va_gc> *ce = NULL;
2813 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2815 tree result = build_nop (build_ctype (e->type),
2816 build_constructor (aatype, ce));
2817 this->result_ = compound_expr (init, result);
2820 /* Build a struct literal. */
2822 void visit (StructLiteralExp *e)
2824 /* Handle empty struct literals. */
2825 if (e->elements == NULL || e->sd->fields.length == 0)
2827 this->result_ = build_constructor (build_ctype (e->type), NULL);
2828 return;
2831 /* Building sinit trees are delayed until after frontend semantic
2832 processing has complete. Build the static initializer now. */
2833 if (e->useStaticInit && !this->constp_)
2835 tree init = aggregate_initializer_decl (e->sd);
2837 /* If initializing a symbol, don't forget to set it. */
2838 if (e->sym != NULL)
2840 tree var = build_deref (e->sym);
2841 init = compound_expr (modify_expr (var, init), var);
2844 this->result_ = init;
2845 return;
2848 /* Build a constructor that assigns the expressions in ELEMENTS
2849 at each field index that has been filled in. */
2850 vec <constructor_elt, va_gc> *ve = NULL;
2851 tree saved_elems = NULL_TREE;
2853 /* CTFE may fill the hidden pointer by NullExp. */
2854 gcc_assert (e->elements->length <= e->sd->fields.length);
2856 Type *tb = e->type->toBasetype ();
2857 gcc_assert (tb->ty == TY::Tstruct);
2859 for (size_t i = 0; i < e->elements->length; i++)
2861 Expression *exp = (*e->elements)[i];
2862 if (!exp)
2863 continue;
2865 VarDeclaration *field = e->sd->fields[i];
2866 Type *type = exp->type->toBasetype ();
2867 Type *ftype = field->type->toBasetype ();
2868 tree value = NULL_TREE;
2870 if (ftype->ty == TY::Tsarray && !same_type_p (type, ftype))
2872 /* Initialize a static array with a single element. */
2873 tree elem = build_expr (exp, this->constp_, true);
2874 saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
2875 elem = d_save_expr (elem);
2877 if (initializer_zerop (elem))
2878 value = build_constructor (build_ctype (ftype), NULL);
2879 else
2880 value = build_array_from_val (ftype, elem);
2882 else
2884 value = convert_expr (build_expr (exp, this->constp_, true),
2885 exp->type, field->type);
2888 /* Split construction of values out of the constructor. */
2889 saved_elems = compound_expr (saved_elems, stabilize_expr (&value));
2891 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2894 /* Maybe setup hidden pointer to outer scope context. */
2895 if (e->sd->isNested () && e->elements->length != e->sd->fields.length
2896 && this->constp_ == false)
2898 tree field = get_symbol_decl (e->sd->vthis);
2899 tree value = build_vthis (e->sd);
2900 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2901 gcc_assert (e->useStaticInit == false);
2904 /* Build a constructor in the correct shape of the aggregate type. */
2905 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2907 /* Nothing more to do for constant literals. */
2908 if (this->constp_)
2910 /* If the struct literal is a valid for static data. */
2911 if (TREE_CONSTANT (ctor)
2912 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2913 TREE_STATIC (ctor) = 1;
2915 this->result_ = compound_expr (saved_elems, ctor);
2916 return;
2919 /* Construct the struct literal for run-time. */
2920 if (e->sym != NULL)
2922 /* Store the result in a symbol to initialize the literal. */
2923 tree var = build_deref (e->sym);
2924 ctor = compound_expr (modify_expr (var, ctor), var);
2926 else if (!this->literalp_)
2928 /* Use memset to fill any alignment holes in the object. */
2929 if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
2931 tree var = build_local_temp (TREE_TYPE (ctor));
2932 tree init = build_memset_call (var);
2933 /* Evaluate memset() first, then any saved element constructors. */
2934 saved_elems = compound_expr (init, saved_elems);
2935 ctor = compound_expr (modify_expr (var, ctor), var);
2939 this->result_ = compound_expr (saved_elems, ctor);
2942 /* Build a null literal. */
2944 void visit (NullExp *e)
2946 this->result_ = build_typeof_null_value (e->type);
2949 /* Build a vector literal. */
2951 void visit (VectorExp *e)
2953 tree type = build_ctype (e->type);
2955 /* First handle array literal expressions. */
2956 if (e->e1->op == TOKarrayliteral)
2958 ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
2959 vec <constructor_elt, va_gc> *elms = NULL;
2960 bool constant_p = true;
2962 vec_safe_reserve (elms, ale->elements->length);
2963 for (size_t i = 0; i < ale->elements->length; i++)
2965 Expression *expr = ale->getElement (i);
2966 tree value = d_convert (TREE_TYPE (type),
2967 build_expr (expr, this->constp_, true));
2968 if (!CONSTANT_CLASS_P (value))
2969 constant_p = false;
2971 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2974 /* Build a VECTOR_CST from a constant vector constructor. */
2975 if (constant_p)
2976 this->result_ = build_vector_from_ctor (type, elms);
2977 else
2978 this->result_ = build_constructor (type, elms);
2980 else
2982 /* Build constructor from single value. */
2983 tree value = d_convert (TREE_TYPE (type),
2984 build_expr (e->e1, this->constp_, true));
2985 this->result_ = build_vector_from_val (type, value);
2989 /* Build a static array representation of a vector expression. */
2991 void visit (VectorArrayExp *e)
2993 this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
2994 e->e1->type, e->type);
2997 /* Build a static class literal, return its reference. */
2999 void visit (ClassReferenceExp *e)
3001 /* The result of build_new_class_expr is a RECORD_TYPE, we want
3002 the reference. */
3003 tree var = build_address (build_new_class_expr (e));
3005 /* If the type of this literal is an interface, the we must add the
3006 interface offset to symbol. */
3007 if (this->constp_)
3009 TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
3010 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
3012 if (to != NULL)
3014 ClassDeclaration *from = e->originalClass ();
3015 int offset = 0;
3017 gcc_assert (to->isBaseOf (from, &offset) != 0);
3019 if (offset != 0)
3020 var = build_offset (var, size_int (offset));
3024 this->result_ = var;
3027 /* These expressions are mainly just a placeholders in the frontend.
3028 We shouldn't see them here. */
3030 void visit (ScopeExp *e)
3032 error_at (make_location_t (e->loc), "%qs is not an expression",
3033 e->toChars ());
3034 this->result_ = error_mark_node;
3037 void visit (TypeExp *e)
3039 error_at (make_location_t (e->loc), "type %qs is not an expression",
3040 e->toChars ());
3041 this->result_ = error_mark_node;
3046 /* Main entry point for ExprVisitor interface to generate code for
3047 the Expression AST class E. If CONST_P is true, then E is a
3048 constant expression. If LITERAL_P is true, then E is a value used
3049 in the initialization of another literal. */
3051 tree
3052 build_expr (Expression *e, bool const_p, bool literal_p)
3054 ExprVisitor v = ExprVisitor (const_p, literal_p);
3055 location_t saved_location = input_location;
3057 input_location = make_location_t (e->loc);
3058 e->accept (&v);
3059 tree expr = v.result ();
3060 input_location = saved_location;
3062 /* Check if initializer expression is valid constant. */
3063 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3065 error_at (make_location_t (e->loc), "non-constant expression %qs",
3066 e->toChars ());
3067 return error_mark_node;
3070 return expr;
3073 /* Same as build_expr, but also calls destructors on any temporaries. */
3075 tree
3076 build_expr_dtor (Expression *e)
3078 /* Codegen can be improved by determining if no exceptions can be thrown
3079 between the ctor and dtor, and eliminating the ctor and dtor. */
3080 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3081 tree result = build_expr (e);
3083 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3085 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3086 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3089 return result;
3092 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3094 tree
3095 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3097 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3098 tree result = build_expr (e);
3100 /* Convert for initializing the DECL_RESULT. */
3101 if (tf->isref ())
3103 /* If we are returning a reference, take the address. */
3104 result = convert_expr (result, e->type, type);
3105 result = build_address (result);
3107 else
3108 result = convert_for_rvalue (result, e->type, type);
3110 /* The decl to store the return expression. */
3111 tree decl = DECL_RESULT (cfun->decl);
3113 /* Split comma expressions, so that the result is returned directly. */
3114 tree expr = stabilize_expr (&result);
3115 result = build_assign (INIT_EXPR, decl, result);
3116 result = compound_expr (expr, return_expr (result));
3118 /* May nest the return expression inside the try/finally expression. */
3119 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3121 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3122 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3125 return result;