PR rtl-optimization/88470
[official-gcc.git] / gcc / d / expr.cc
blob9a1aad42ddcc31e22c35b61cedf4d2be53818b27
1 /* expr.cc -- Lower D frontend expressions to GCC trees.
2 Copyright (C) 2015-2018 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 /* Implements the visitor interface to build the GCC trees of all Expression
47 AST classes emitted from the D Front-end.
48 All visit methods accept one parameter E, which holds the frontend AST
49 of the expression to compile. They also don't return any value, instead
50 generated code is cached in RESULT_ and returned from the caller. */
52 class ExprVisitor : public Visitor
54 using Visitor::visit;
56 tree result_;
57 bool constp_;
59 /* Determine if type is a struct that has a postblit. */
61 bool needs_postblit (Type *t)
63 t = t->baseElemOf ();
65 if (t->ty == Tstruct)
67 StructDeclaration *sd = ((TypeStruct *) t)->sym;
68 if (sd->postblit)
69 return true;
72 return false;
75 /* Determine if type is a struct that has a destructor. */
77 bool needs_dtor (Type *t)
79 t = t->baseElemOf ();
81 if (t->ty == Tstruct)
83 StructDeclaration *sd = ((TypeStruct *) t)->sym;
84 if (sd->dtor)
85 return true;
88 return false;
91 /* Determine if expression is suitable lvalue. */
93 bool lvalue_p (Expression *e)
95 return ((e->op != TOKslice && e->isLvalue ())
96 || (e->op == TOKslice && ((UnaExp *) e)->e1->isLvalue ())
97 || (e->op == TOKcast && ((UnaExp *) e)->e1->isLvalue ()));
100 /* Build an expression of code CODE, data type TYPE, and operands ARG0 and
101 ARG1. Perform relevant conversions needed for correct code operations. */
103 tree binary_op (tree_code code, tree type, tree arg0, tree arg1)
105 tree t0 = TREE_TYPE (arg0);
106 tree t1 = TREE_TYPE (arg1);
107 tree ret = NULL_TREE;
109 bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1);
111 /* Deal with float mod expressions immediately. */
112 if (code == FLOAT_MOD_EXPR)
113 return build_float_modulus (type, arg0, arg1);
115 if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
116 return build_nop (type, build_offset_op (code, arg0, arg1));
118 if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
119 return build_nop (type, build_offset_op (code, arg1, arg0));
121 if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
123 gcc_assert (code == MINUS_EXPR);
124 tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
126 /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
127 pointers. If some platform cannot provide that, or has a larger
128 ptrdiff_type to support differences larger than half the address
129 space, cast the pointers to some larger integer type and do the
130 computations in that type. */
131 if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
132 ret = fold_build2 (MINUS_EXPR, ptrtype,
133 d_convert (ptrtype, arg0),
134 d_convert (ptrtype, arg1));
135 else
136 ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
138 else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp))
140 tree inttype = (unsignedp)
141 ? d_unsigned_type (type) : d_signed_type (type);
142 ret = fold_build2 (code, inttype, arg0, arg1);
144 else
146 /* If the operation needs excess precision. */
147 tree eptype = excess_precision_type (type);
148 if (eptype != NULL_TREE)
150 arg0 = d_convert (eptype, arg0);
151 arg1 = d_convert (eptype, arg1);
153 else
155 /* Front-end does not do this conversion and GCC does not
156 always do it right. */
157 if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
158 arg1 = d_convert (t0, arg1);
159 else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
160 arg0 = d_convert (t1, arg0);
162 eptype = type;
165 ret = fold_build2 (code, eptype, arg0, arg1);
168 return d_convert (type, ret);
171 /* Build a binary expression of code CODE, assigning the result into E1. */
173 tree binop_assignment (tree_code code, Expression *e1, Expression *e2)
175 /* Skip casts for lhs assignment. */
176 Expression *e1b = e1;
177 while (e1b->op == TOKcast)
179 CastExp *ce = (CastExp *) e1b;
180 gcc_assert (same_type_p (ce->type, ce->to));
181 e1b = ce->e1;
184 /* Stabilize LHS for assignment. */
185 tree lhs = build_expr (e1b);
186 tree lexpr = stabilize_expr (&lhs);
188 /* The LHS expression could be an assignment, to which its operation gets
189 lost during gimplification. */
190 if (TREE_CODE (lhs) == MODIFY_EXPR)
192 /* If LHS has side effects, call stabilize_reference on it, so it can
193 be evaluated multiple times. */
194 if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
195 lhs = build_assign (MODIFY_EXPR,
196 stabilize_reference (TREE_OPERAND (lhs, 0)),
197 TREE_OPERAND (lhs, 1));
199 lexpr = compound_expr (lexpr, lhs);
200 lhs = TREE_OPERAND (lhs, 0);
203 lhs = stabilize_reference (lhs);
205 /* Save RHS, to ensure that the expression is evaluated before LHS. */
206 tree rhs = build_expr (e2);
207 tree rexpr = d_save_expr (rhs);
209 rhs = this->binary_op (code, build_ctype (e1->type),
210 convert_expr (lhs, e1b->type, e1->type), rexpr);
211 if (TREE_SIDE_EFFECTS (rhs))
212 rhs = compound_expr (rexpr, rhs);
214 tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
215 return compound_expr (lexpr, expr);
218 public:
219 ExprVisitor (bool constp)
221 this->result_ = NULL_TREE;
222 this->constp_ = constp;
225 tree result (void)
227 return this->result_;
230 /* Visitor interfaces, each Expression class should have
231 overridden the default. */
233 void visit (Expression *)
235 gcc_unreachable ();
238 /* Build a conditional expression. If either the second or third
239 expression is void, then the resulting type is void. Otherwise
240 they are implicitly converted to a common type. */
242 void visit (CondExp *e)
244 tree cond = convert_for_condition (build_expr (e->econd),
245 e->econd->type);
246 tree t1 = build_expr (e->e1);
247 tree t2 = build_expr (e->e2);
249 if (e->type->ty != Tvoid)
251 t1 = convert_expr (t1, e->e1->type, e->type);
252 t2 = convert_expr (t2, e->e2->type, e->type);
255 this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
258 /* Build an identity comparison expression. Operands go through the
259 usual conversions to bring them to a common type before comparison.
260 The result type is bool. */
262 void visit (IdentityExp *e)
264 tree_code code = (e->op == TOKidentity) ? EQ_EXPR : NE_EXPR;
265 Type *tb1 = e->e1->type->toBasetype ();
266 Type *tb2 = e->e2->type->toBasetype ();
268 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
269 && (tb2->ty == Tsarray || tb2->ty == Tarray))
271 /* For static and dynamic arrays, identity is defined as referring to
272 the same array elements and the same number of elements. */
273 tree t1 = d_array_convert (e->e1);
274 tree t2 = d_array_convert (e->e2);
275 this->result_ = d_convert (build_ctype (e->type),
276 build_boolop (code, t1, t2));
278 else if (tb1->isfloating () && tb1->ty != Tvector)
280 /* For floating-point values, identity is defined as the bits in the
281 operands being identical. */
282 tree t1 = d_save_expr (build_expr (e->e1));
283 tree t2 = d_save_expr (build_expr (e->e2));
285 tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
286 tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
288 tree result = build_call_expr (tmemcmp, 3, build_address (t1),
289 build_address (t2), size);
290 this->result_ = build_boolop (code, result, integer_zero_node);
292 else if (tb1->ty == Tstruct)
294 /* For struct objects, identity is defined as bits in operands being
295 identical also. Alignment holes in structs are ignored. */
296 StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
297 tree t1 = build_expr (e->e1);
298 tree t2 = build_expr (e->e2);
300 gcc_assert (same_type_p (tb1, tb2));
302 this->result_ = build_struct_comparison (code, sd, t1, t2);
304 else
306 /* For operands of other types, identity is defined as being the
307 same as equality expressions. */
308 tree t1 = build_expr (e->e1);
309 tree t2 = build_expr (e->e2);
310 this->result_ = d_convert (build_ctype (e->type),
311 build_boolop (code, t1, t2));
315 /* Build an equality expression, which compare the two operands for either
316 equality or inequality. Operands go through the usual conversions to bring
317 them to a common type before comparison. The result type is bool. */
319 void visit (EqualExp *e)
321 Type *tb1 = e->e1->type->toBasetype ();
322 Type *tb2 = e->e2->type->toBasetype ();
323 tree_code code = (e->op == TOKequal) ? EQ_EXPR : NE_EXPR;
325 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
326 && (tb2->ty == Tsarray || tb2->ty == Tarray))
328 /* For static and dynamic arrays, equality is defined as the lengths of
329 the arrays matching, and all the elements are equal. */
330 Type *t1elem = tb1->nextOf ()->toBasetype ();
331 Type *t2elem = tb1->nextOf ()->toBasetype ();
333 /* Check if comparisons of arrays can be optimized using memcmp.
334 This will inline EQ expressions as:
335 e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
336 Or when generating a NE expression:
337 e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */
338 if ((t1elem->isintegral () || t1elem->ty == Tvoid
339 || (t1elem->ty == Tstruct && !((TypeStruct *)t1elem)->sym->xeq))
340 && t1elem->ty == t2elem->ty)
342 tree t1 = d_array_convert (e->e1);
343 tree t2 = d_array_convert (e->e2);
344 tree result;
346 /* Make temporaries to prevent multiple evaluations. */
347 tree t1saved = d_save_expr (t1);
348 tree t2saved = d_save_expr (t2);
350 /* Length of arrays, for comparisons done before calling memcmp. */
351 tree t1len = d_array_length (t1saved);
352 tree t2len = d_array_length (t2saved);
354 /* Reference to array data. */
355 tree t1ptr = d_array_ptr (t1saved);
356 tree t2ptr = d_array_ptr (t2saved);
358 /* Compare arrays using memcmp if possible, otherwise for structs,
359 each field is compared inline. */
360 if (t1elem->ty != Tstruct
361 || identity_compare_p (((TypeStruct *) t1elem)->sym))
363 tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
364 tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
366 result = build_call_expr (tmemcmp, 3, t1ptr, t2ptr, size);
367 result = build_boolop (code, result, integer_zero_node);
369 else
371 StructDeclaration *sd = ((TypeStruct *) t1elem)->sym;
373 result = build_array_struct_comparison (code, sd, t1len,
374 t1ptr, t2ptr);
377 /* Check array length first before passing to memcmp.
378 For equality expressions, this becomes:
379 (e1.length == 0 || memcmp);
380 Otherwise for inequality:
381 (e1.length != 0 && memcmp); */
382 tree tsizecmp = build_boolop (code, t1len, size_zero_node);
383 if (e->op == TOKequal)
384 result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
385 else
386 result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
388 /* Finally, check if lengths of both arrays match if dynamic.
389 The frontend should have already guaranteed that static arrays
390 have same size. */
391 if (tb1->ty == Tsarray && tb2->ty == Tsarray)
392 gcc_assert (tb1->size () == tb2->size ());
393 else
395 tree tlencmp = build_boolop (code, t1len, t2len);
396 if (e->op == TOKequal)
397 result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
398 else
399 result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
402 /* Ensure left-to-right order of evaluation. */
403 if (TREE_SIDE_EFFECTS (t2))
404 result = compound_expr (t2saved, result);
406 if (TREE_SIDE_EFFECTS (t1))
407 result = compound_expr (t1saved, result);
409 this->result_ = result;
411 else
413 /* Use _adEq2() to compare each element. */
414 Type *t1array = t1elem->arrayOf ();
415 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
416 d_array_convert (e->e1),
417 d_array_convert (e->e2),
418 build_typeinfo (t1array));
420 if (e->op == TOKnotequal)
421 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
423 this->result_ = result;
426 else if (tb1->ty == Tstruct)
428 /* Equality for struct objects means the logical product of all
429 equality results of the corresponding object fields. */
430 StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
431 tree t1 = build_expr (e->e1);
432 tree t2 = build_expr (e->e2);
434 gcc_assert (same_type_p (tb1, tb2));
436 this->result_ = build_struct_comparison (code, sd, t1, t2);
438 else if (tb1->ty == Taarray && tb2->ty == Taarray)
440 /* Use _aaEqual() for associative arrays. */
441 TypeAArray *taa1 = (TypeAArray *) tb1;
442 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
443 build_typeinfo (taa1),
444 build_expr (e->e1),
445 build_expr (e->e2));
447 if (e->op == TOKnotequal)
448 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
450 this->result_ = result;
452 else
454 /* For operands of other types, equality is defined as the bit pattern
455 of the type matches exactly. */
456 tree t1 = build_expr (e->e1);
457 tree t2 = build_expr (e->e2);
459 this->result_ = d_convert (build_ctype (e->type),
460 build_boolop (code, t1, t2));
464 /* Build an `in' expression. This is a condition to see if an element
465 exists in an associative array. The result is a pointer to the
466 element, or null if false. */
468 void visit (InExp *e)
470 Type *tb2 = e->e2->type->toBasetype ();
471 gcc_assert (tb2->ty == Taarray);
473 Type *tkey = ((TypeAArray *) tb2)->index->toBasetype ();
474 tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
476 /* Build a call to _aaInX(). */
477 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
478 build_expr (e->e2),
479 build_typeinfo (tkey),
480 build_address (key));
483 /* Build a relational expression. The result type is bool. */
485 void visit (CmpExp *e)
487 Type *tb1 = e->e1->type->toBasetype ();
488 Type *tb2 = e->e2->type->toBasetype ();
490 tree result;
491 tree_code code;
493 switch (e->op)
495 case TOKle:
496 code = LE_EXPR;
497 break;
499 case TOKlt:
500 code = LT_EXPR;
501 break;
503 case TOKge:
504 code = GE_EXPR;
505 break;
507 case TOKgt:
508 code = GT_EXPR;
509 break;
511 default:
512 gcc_unreachable ();
515 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
516 && (tb2->ty == Tsarray || tb2->ty == Tarray))
518 /* For static and dynamic arrays, the result of the relational op is
519 the result of the operator applied to the first non-equal element
520 of the array. If two arrays compare equal, but are of different
521 lengths, the shorter array compares as less than the longer. */
522 Type *telem = tb1->nextOf ()->toBasetype ();
524 tree call = build_libcall (LIBCALL_ADCMP2, Type::tint32, 3,
525 d_array_convert (e->e1),
526 d_array_convert (e->e2),
527 build_typeinfo (telem->arrayOf ()));
528 result = build_boolop (code, call, integer_zero_node);
530 this->result_ = d_convert (build_ctype (e->type), result);
531 return;
534 /* Simple comparison. */
535 result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
536 this->result_ = d_convert (build_ctype (e->type), result);
539 /* Build an `and if' expression. If the right operand expression is void,
540 then the resulting type is void. Otherwise the result is bool. */
542 void visit (AndAndExp *e)
544 if (e->e2->type->toBasetype ()->ty != Tvoid)
546 tree t1 = build_expr (e->e1);
547 tree t2 = build_expr (e->e2);
549 t1 = convert_for_condition (t1, e->e1->type);
550 t2 = convert_for_condition (t2, e->e2->type);
552 this->result_ = d_convert (build_ctype (e->type),
553 build_boolop (TRUTH_ANDIF_EXPR, t1, t2));
555 else
557 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
558 tree t2 = build_expr_dtor (e->e2);
560 this->result_ = build_condition (build_ctype (e->type),
561 t1, t2, void_node);
565 /* Build an `or if' expression. If the right operand expression is void,
566 then the resulting type is void. Otherwise the result is bool. */
568 void visit (OrOrExp *e)
570 if (e->e2->type->toBasetype ()->ty != Tvoid)
572 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
573 tree t2 = convert_for_condition (build_expr (e->e2), e->e2->type);
575 this->result_ = d_convert (build_ctype (e->type),
576 build_boolop (TRUTH_ORIF_EXPR, t1, t2));
578 else
580 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
581 tree t2 = build_expr_dtor (e->e2);
582 tree cond = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);
584 this->result_ = build_condition (build_ctype (e->type),
585 cond, t2, void_node);
589 /* Build a binary operand expression. Operands go through usual arithmetic
590 conversions to bring them to a common type before evaluating. */
592 void visit (BinExp *e)
594 tree_code code;
596 switch (e->op)
598 case TOKadd:
599 case TOKmin:
600 if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
601 || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
603 /* If the result is complex, then we can shortcut binary_op.
604 Frontend should have already validated types and sizes. */
605 tree t1 = build_expr (e->e1);
606 tree t2 = build_expr (e->e2);
608 if (e->op == TOKmin)
609 t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
611 if (e->e1->type->isreal ())
612 this->result_ = complex_expr (build_ctype (e->type), t1, t2);
613 else
614 this->result_ = complex_expr (build_ctype (e->type), t2, t1);
616 return;
618 else
619 code = (e->op == TOKadd)
620 ? PLUS_EXPR : MINUS_EXPR;
621 break;
623 case TOKmul:
624 code = MULT_EXPR;
625 break;
627 case TOKdiv:
628 code = e->e1->type->isintegral ()
629 ? TRUNC_DIV_EXPR : RDIV_EXPR;
630 break;
632 case TOKmod:
633 code = e->e1->type->isfloating ()
634 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
635 break;
637 case TOKand:
638 code = BIT_AND_EXPR;
639 break;
641 case TOKor:
642 code = BIT_IOR_EXPR;
643 break;
645 case TOKxor:
646 code = BIT_XOR_EXPR;
647 break;
649 case TOKshl:
650 code = LSHIFT_EXPR;
651 break;
653 case TOKshr:
654 code = RSHIFT_EXPR;
655 break;
657 case TOKushr:
658 code = UNSIGNED_RSHIFT_EXPR;
659 break;
661 default:
662 gcc_unreachable ();
665 this->result_ = this->binary_op (code, build_ctype (e->type),
666 build_expr (e->e1), build_expr (e->e2));
670 /* Build a concat expression, which concatenates two or more arrays of the
671 same type, producing a dynamic array with the result. If one operand
672 is an element type, that element is converted to an array of length 1. */
674 void visit (CatExp *e)
676 Type *tb1 = e->e1->type->toBasetype ();
677 Type *tb2 = e->e2->type->toBasetype ();
678 Type *etype;
680 if (tb1->ty == Tarray || tb1->ty == Tsarray)
681 etype = tb1->nextOf ();
682 else
683 etype = tb2->nextOf ();
685 vec<tree, va_gc> *elemvars = NULL;
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 = ((CatExp *) ex)->e1;
699 ndims++;
703 /* Store all concatenation args to a temporary byte[][ndims] array. */
704 Type *targselem = Type::tint8->arrayOf ();
705 tree var = create_temporary_var (make_array_type (targselem, ndims));
706 tree init = build_constructor (TREE_TYPE (var), NULL);
707 vec_safe_push (elemvars, var);
709 /* Loop through each concatenation from right to left. */
710 vec<constructor_elt, va_gc> *elms = NULL;
711 CatExp *ce = e;
712 int dim = ndims - 1;
714 for (Expression *oe = ce->e2; oe != NULL;
715 (ce->e1->op != TOKcat
716 ? (oe = ce->e1)
717 : (ce = (CatExp *)ce->e1, oe = ce->e2)))
719 tree arg = d_array_convert (etype, oe, &elemvars);
720 tree index = size_int (dim);
721 CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));
723 /* Finished pushing all arrays. */
724 if (oe == ce->e1)
725 break;
727 dim -= 1;
730 /* Check there is no logic bug in constructing byte[][] of arrays. */
731 gcc_assert (dim == 0);
732 CONSTRUCTOR_ELTS (init) = elms;
733 DECL_INITIAL (var) = init;
735 tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
736 size_int (ndims), build_address (var));
738 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
739 build_typeinfo (e->type), arrs);
741 else
743 /* Handle single concatenation (a ~ b). */
744 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
745 build_typeinfo (e->type),
746 d_array_convert (etype, e->e1, &elemvars),
747 d_array_convert (etype, e->e2, &elemvars));
750 for (size_t i = 0; i < vec_safe_length (elemvars); ++i)
751 result = bind_expr ((*elemvars)[i], result);
753 this->result_ = result;
756 /* Build an assignment operator expression. The right operand is implicitly
757 converted to the type of the left operand, and assigned to it. */
759 void visit (BinAssignExp *e)
761 tree_code code;
762 Expression *e1b = e->e1;
764 switch (e->op)
766 case TOKaddass:
767 code = PLUS_EXPR;
768 break;
770 case TOKminass:
771 code = MINUS_EXPR;
772 break;
774 case TOKmulass:
775 code = MULT_EXPR;
776 break;
778 case TOKdivass:
779 code = e->e1->type->isintegral ()
780 ? TRUNC_DIV_EXPR : RDIV_EXPR;
781 break;
783 case TOKmodass:
784 code = e->e1->type->isfloating ()
785 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
786 break;
788 case TOKandass:
789 code = BIT_AND_EXPR;
790 break;
792 case TOKorass:
793 code = BIT_IOR_EXPR;
794 break;
796 case TOKxorass:
797 code = BIT_XOR_EXPR;
798 break;
800 case TOKpowass:
801 gcc_unreachable ();
803 case TOKshlass:
804 code = LSHIFT_EXPR;
805 break;
807 case TOKshrass:
808 case TOKushrass:
809 /* Use the original lhs type before it was promoted. The left operand
810 of `>>>=' does not undergo integral promotions before shifting.
811 Strip off casts just incase anyway. */
812 while (e1b->op == TOKcast)
814 CastExp *ce = (CastExp *) e1b;
815 gcc_assert (same_type_p (ce->type, ce->to));
816 e1b = ce->e1;
818 code = (e->op == TOKshrass) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
819 break;
821 default:
822 gcc_unreachable ();
825 tree exp = this->binop_assignment (code, e1b, e->e2);
826 this->result_ = convert_expr (exp, e1b->type, e->type);
829 /* Build a concat assignment expression. The right operand is appended
830 to the the left operand. */
832 void visit (CatAssignExp *e)
834 Type *tb1 = e->e1->type->toBasetype ();
835 Type *tb2 = e->e2->type->toBasetype ();
836 Type *etype = tb1->nextOf ()->toBasetype ();
838 if (tb1->ty == Tarray && tb2->ty == Tdchar
839 && (etype->ty == Tchar || etype->ty == Twchar))
841 /* Append a dchar to a char[] or wchar[] */
842 libcall_fn libcall = (etype->ty == Tchar)
843 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
845 this->result_ = build_libcall (libcall, e->type, 2,
846 build_address (build_expr (e->e1)),
847 build_expr (e->e2));
849 else
851 gcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray);
853 tree tinfo = build_typeinfo (e->type);
854 tree ptr = build_address (build_expr (e->e1));
856 if ((tb2->ty == Tarray || tb2->ty == Tsarray)
857 && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
859 /* Append an array. */
860 this->result_ = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
861 tinfo, ptr, d_array_convert (e->e2));
864 else if (same_type_p (etype, tb2))
866 /* Append an element. */
867 tree result = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
868 tinfo, ptr, size_one_node);
869 result = d_save_expr (result);
871 /* Assign e2 to last element. */
872 tree offexp = d_array_length (result);
873 offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
874 offexp, size_one_node);
875 offexp = d_save_expr (offexp);
877 tree ptrexp = d_array_ptr (result);
878 ptrexp = void_okay_p (ptrexp);
879 ptrexp = build_array_index (ptrexp, offexp);
881 /* Evaluate expression before appending. */
882 tree t2 = build_expr (e->e2);
883 tree expr = stabilize_expr (&t2);
885 t2 = d_save_expr (t2);
886 result = modify_expr (build_deref (ptrexp), t2);
887 result = compound_expr (t2, result);
889 this->result_ = compound_expr (expr, result);
891 else
892 gcc_unreachable ();
896 /* Build an assignment expression. The right operand is implicitly
897 converted to the type of the left operand, and assigned to it. */
899 void visit (AssignExp *e)
901 /* First, handle special assignment semantics. */
903 /* Look for array.length = n; */
904 if (e->e1->op == TOKarraylength)
906 /* Assignment to an array's length property; resize the array. */
907 ArrayLengthExp *ale = (ArrayLengthExp *) e->e1;
908 tree newlength = convert_expr (build_expr (e->e2), e->e2->type,
909 Type::tsize_t);
910 tree ptr = build_address (build_expr (ale->e1));
912 /* Don't want the basetype for the element type. */
913 Type *etype = ale->e1->type->toBasetype ()->nextOf ();
914 libcall_fn libcall = etype->isZeroInit ()
915 ? LIBCALL_ARRAYSETLENGTHT : LIBCALL_ARRAYSETLENGTHIT;
917 tree result = build_libcall (libcall, ale->e1->type, 3,
918 build_typeinfo (ale->e1->type),
919 newlength, ptr);
921 this->result_ = d_array_length (result);
922 return;
925 /* Look for array[] = n; */
926 if (e->e1->op == TOKslice)
928 SliceExp *se = (SliceExp *) e->e1;
929 Type *stype = se->e1->type->toBasetype ();
930 Type *etype = stype->nextOf ()->toBasetype ();
932 /* Determine if we need to run postblit or dtor. */
933 bool postblit = this->needs_postblit (etype) && this->lvalue_p (e->e2);
934 bool destructor = this->needs_dtor (etype);
936 if (e->memset & blockAssign)
938 /* Set a range of elements to one value. */
939 tree t1 = d_save_expr (build_expr (e->e1));
940 tree t2 = build_expr (e->e2);
941 tree result;
943 if ((postblit || destructor) && e->op != TOKblit)
945 libcall_fn libcall = (e->op == TOKconstruct)
946 ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN;
947 /* So we can call postblits on const/immutable objects. */
948 tree ti = build_typeinfo (etype->unSharedOf ()->mutableOf ());
950 tree result = build_libcall (libcall, Type::tvoid, 4,
951 d_array_ptr (t1),
952 build_address (t2),
953 d_array_length (t1), ti);
954 this->result_ = compound_expr (result, t1);
955 return;
958 if (integer_zerop (t2))
960 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
961 tree size = size_mult_expr (d_array_length (t1),
962 size_int (etype->size ()));
964 result = build_call_expr (tmemset, 3, d_array_ptr (t1),
965 integer_zero_node, size);
967 else
968 result = build_array_set (d_array_ptr (t1),
969 d_array_length (t1), t2);
971 this->result_ = compound_expr (result, t1);
973 else
975 /* Perform a memcpy operation. */
976 gcc_assert (e->e2->type->ty != Tpointer);
978 if (!postblit && !destructor && !array_bounds_check ())
980 tree t1 = d_save_expr (d_array_convert (e->e1));
981 tree t2 = d_array_convert (e->e2);
982 tree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);
983 tree size = size_mult_expr (d_array_length (t1),
984 size_int (etype->size ()));
986 tree result = build_call_expr (tmemcpy, 3, d_array_ptr (t1),
987 d_array_ptr (t2), size);
988 this->result_ = compound_expr (result, t1);
990 else if ((postblit || destructor) && e->op != TOKblit)
992 /* Generate: _d_arrayassign(ti, from, to)
993 or: _d_arrayctor(ti, from, to) */
994 libcall_fn libcall = (e->op == TOKconstruct)
995 ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN;
997 this->result_ = build_libcall (libcall, e->type, 3,
998 build_typeinfo (etype),
999 d_array_convert (e->e2),
1000 d_array_convert (e->e1));
1002 else
1004 /* Generate: _d_arraycopy() */
1005 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
1006 size_int (etype->size ()),
1007 d_array_convert (e->e2),
1008 d_array_convert (e->e1));
1012 return;
1015 /* Look for reference initializations. */
1016 if (e->memset & referenceInit)
1018 gcc_assert (e->op == TOKconstruct || e->op == TOKblit);
1019 gcc_assert (e->e1->op == TOKvar);
1021 Declaration *decl = ((VarExp *) e->e1)->var;
1022 if (decl->storage_class & (STCout | STCref))
1024 tree t2 = convert_for_assignment (build_expr (e->e2),
1025 e->e2->type, e->e1->type);
1026 tree t1 = build_expr (e->e1);
1027 /* Want reference to lhs, not indirect ref. */
1028 t1 = TREE_OPERAND (t1, 0);
1029 t2 = build_address (t2);
1031 this->result_ = indirect_ref (build_ctype (e->type),
1032 build_assign (INIT_EXPR, t1, t2));
1033 return;
1037 /* Other types of assignments that may require post construction. */
1038 Type *tb1 = e->e1->type->toBasetype ();
1039 tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR;
1041 /* Look for struct assignment. */
1042 if (tb1->ty == Tstruct)
1044 tree t1 = build_expr (e->e1);
1045 tree t2 = convert_for_assignment (build_expr (e->e2),
1046 e->e2->type, e->e1->type);
1048 /* Look for struct = 0. */
1049 if (e->e2->op == TOKint64)
1051 /* Use memset to fill struct. */
1052 gcc_assert (e->op == TOKblit);
1053 StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
1055 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1056 tree result = build_call_expr (tmemset, 3, build_address (t1),
1057 t2, size_int (sd->structsize));
1059 /* Maybe set-up hidden pointer to outer scope context. */
1060 if (sd->isNested ())
1062 tree field = get_symbol_decl (sd->vthis);
1063 tree value = build_vthis (sd);
1065 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1066 result = compound_expr (result, vthis_exp);
1069 this->result_ = compound_expr (result, t1);
1071 else
1072 this->result_ = build_assign (modifycode, t1, t2);
1074 return;
1077 /* Look for static array assignment. */
1078 if (tb1->ty == Tsarray)
1080 /* Look for array = 0. */
1081 if (e->e2->op == TOKint64)
1083 /* Use memset to fill the array. */
1084 gcc_assert (e->op == TOKblit);
1086 tree t1 = build_expr (e->e1);
1087 tree t2 = convert_for_assignment (build_expr (e->e2),
1088 e->e2->type, e->e1->type);
1089 tree size = size_int (e->e1->type->size ());
1091 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1092 this->result_ = build_call_expr (tmemset, 3, build_address (t1),
1093 t2, size);
1094 return;
1097 Type *etype = tb1->nextOf ();
1098 gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);
1100 /* Determine if we need to run postblit. */
1101 bool postblit = this->needs_postblit (etype);
1102 bool destructor = this->needs_dtor (etype);
1103 bool lvalue_p = this->lvalue_p (e->e2);
1105 /* Even if the elements in rhs are all rvalues and don't have
1106 to call postblits, this assignment should call dtors on old
1107 assigned elements. */
1108 if ((!postblit && !destructor)
1109 || (e->op == TOKconstruct && !lvalue_p && postblit)
1110 || (e->op == TOKblit || e->e1->type->size () == 0))
1112 tree t1 = build_expr (e->e1);
1113 tree t2 = convert_for_assignment (build_expr (e->e2),
1114 e->e2->type, e->e1->type);
1116 this->result_ = build_assign (modifycode, t1, t2);
1117 return;
1120 Type *arrtype = (e->type->ty == Tsarray) ? etype->arrayOf () : e->type;
1121 tree result;
1123 if (e->op == TOKconstruct)
1125 /* Generate: _d_arrayctor(ti, from, to) */
1126 result = build_libcall (LIBCALL_ARRAYCTOR, arrtype, 3,
1127 build_typeinfo (etype),
1128 d_array_convert (e->e2),
1129 d_array_convert (e->e1));
1131 else
1133 /* Generate: _d_arrayassign_l()
1134 or: _d_arrayassign_r() */
1135 libcall_fn libcall = (lvalue_p)
1136 ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
1137 tree elembuf = build_local_temp (build_ctype (etype));
1139 result = build_libcall (libcall, arrtype, 4,
1140 build_typeinfo (etype),
1141 d_array_convert (e->e2),
1142 d_array_convert (e->e1),
1143 build_address (elembuf));
1146 /* Cast the libcall result back to a static array. */
1147 if (e->type->ty == Tsarray)
1148 result = indirect_ref (build_ctype (e->type),
1149 d_array_ptr (result));
1151 this->result_ = result;
1152 return;
1155 /* Simple assignment. */
1156 tree t1 = build_expr (e->e1);
1157 tree t2 = convert_for_assignment (build_expr (e->e2),
1158 e->e2->type, e->e1->type);
1160 this->result_ = build_assign (modifycode, t1, t2);
1163 /* Build a postfix expression. */
1165 void visit (PostExp *e)
1167 tree result;
1169 if (e->op == TOKplusplus)
1171 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1172 build_expr (e->e1), build_expr (e->e2));
1174 else if (e->op == TOKminusminus)
1176 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1177 build_expr (e->e1), build_expr (e->e2));
1179 else
1180 gcc_unreachable ();
1182 TREE_SIDE_EFFECTS (result) = 1;
1183 this->result_ = result;
1186 /* Build an index expression. */
1188 void visit (IndexExp *e)
1190 Type *tb1 = e->e1->type->toBasetype ();
1192 if (tb1->ty == Taarray)
1194 /* Get the key for the associative array. */
1195 Type *tkey = ((TypeAArray *) tb1)->index->toBasetype ();
1196 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1197 libcall_fn libcall;
1198 tree tinfo, ptr;
1200 if (e->modifiable)
1202 libcall = LIBCALL_AAGETY;
1203 ptr = build_address (build_expr (e->e1));
1204 tinfo = build_typeinfo (tb1->unSharedOf ()->mutableOf ());
1206 else
1208 libcall = LIBCALL_AAGETRVALUEX;
1209 ptr = build_expr (e->e1);
1210 tinfo = build_typeinfo (tkey);
1213 /* Index the associative array. */
1214 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1215 ptr, tinfo,
1216 size_int (tb1->nextOf ()->size ()),
1217 build_address (key));
1219 if (!e->indexIsInBounds && array_bounds_check ())
1221 tree tassert = d_assert_call (e->loc, LIBCALL_ARRAY_BOUNDS);
1222 result = d_save_expr (result);
1223 result = build_condition (TREE_TYPE (result),
1224 d_truthvalue_conversion (result),
1225 result, tassert);
1228 this->result_ = indirect_ref (build_ctype (e->type), result);
1230 else
1232 /* Get the data pointer and length for static and dynamic arrays. */
1233 tree array = d_save_expr (build_expr (e->e1));
1234 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1236 tree length = NULL_TREE;
1237 if (tb1->ty != Tpointer)
1238 length = get_array_length (array, tb1);
1239 else
1240 gcc_assert (e->lengthVar == NULL);
1242 /* The __dollar variable just becomes a placeholder for the
1243 actual length. */
1244 if (e->lengthVar)
1245 e->lengthVar->csym = length;
1247 /* Generate the index. */
1248 tree index = build_expr (e->e2);
1250 /* If it's a static array and the index is constant, the front end has
1251 already checked the bounds. */
1252 if (tb1->ty != Tpointer && !e->indexIsInBounds)
1253 index = build_bounds_condition (e->e2->loc, index, length, false);
1255 /* Index the .ptr. */
1256 ptr = void_okay_p (ptr);
1257 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1258 build_array_index (ptr, index));
1262 /* Build a comma expression. The type is the type of the right operand. */
1264 void visit (CommaExp *e)
1266 tree t1 = build_expr (e->e1);
1267 tree t2 = build_expr (e->e2);
1268 tree type = e->type ? build_ctype (e->type) : void_type_node;
1270 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1273 /* Build an array length expression. Returns the number of elements
1274 in the array. The result is of type size_t. */
1276 void visit (ArrayLengthExp *e)
1278 if (e->e1->type->toBasetype ()->ty == Tarray)
1279 this->result_ = d_array_length (build_expr (e->e1));
1280 else
1282 /* Static arrays have already been handled by the front-end. */
1283 error ("unexpected type for array length: %qs", e->type->toChars ());
1284 this->result_ = error_mark_node;
1288 /* Build a delegate pointer expression. This will return the frame
1289 pointer value as a type void*. */
1291 void visit (DelegatePtrExp *e)
1293 tree t1 = build_expr (e->e1);
1294 this->result_ = delegate_object (t1);
1297 /* Build a delegate function pointer expression. This will return the
1298 function pointer value as a function type. */
1300 void visit (DelegateFuncptrExp *e)
1302 tree t1 = build_expr (e->e1);
1303 this->result_ = delegate_method (t1);
1306 /* Build a slice expression. */
1308 void visit (SliceExp *e)
1310 Type *tb = e->type->toBasetype ();
1311 Type *tb1 = e->e1->type->toBasetype ();
1312 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray);
1314 /* Use convert-to-dynamic-array code if possible. */
1315 if (!e->lwr)
1317 tree result = build_expr (e->e1);
1318 if (e->e1->type->toBasetype ()->ty == Tsarray)
1319 result = convert_expr (result, e->e1->type, e->type);
1321 this->result_ = result;
1322 return;
1324 else
1325 gcc_assert (e->upr != NULL);
1327 /* Get the data pointer and length for static and dynamic arrays. */
1328 tree array = d_save_expr (build_expr (e->e1));
1329 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1330 tree length = NULL_TREE;
1332 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1333 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1334 if (tb1->ty != Tpointer)
1335 length = get_array_length (array, tb1);
1336 else
1337 gcc_assert (e->lengthVar == NULL);
1339 /* The __dollar variable just becomes a placeholder for the
1340 actual length. */
1341 if (e->lengthVar)
1342 e->lengthVar->csym = length;
1344 /* Generate upper and lower bounds. */
1345 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1346 tree upr_tree = d_save_expr (build_expr (e->upr));
1348 /* If the upper bound has any side effects, then the lower bound should be
1349 copied to a temporary always. */
1350 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1351 lwr_tree = save_expr (lwr_tree);
1353 /* Adjust the .ptr offset. */
1354 if (!integer_zerop (lwr_tree))
1356 tree ptrtype = TREE_TYPE (ptr);
1357 ptr = build_array_index (void_okay_p (ptr), lwr_tree);
1358 ptr = build_nop (ptrtype, ptr);
1360 else
1361 lwr_tree = NULL_TREE;
1363 /* Nothing more to do for static arrays, their bounds checking has been
1364 done at compile-time. */
1365 if (tb->ty == Tsarray)
1367 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1368 return;
1370 else
1371 gcc_assert (tb->ty == Tarray);
1373 /* Generate bounds checking code. */
1374 tree newlength;
1376 if (!e->upperIsInBounds)
1378 if (length)
1380 newlength = build_bounds_condition (e->upr->loc, upr_tree,
1381 length, true);
1383 else
1385 /* Still need to check bounds lwr <= upr for pointers. */
1386 gcc_assert (tb1->ty == Tpointer);
1387 newlength = upr_tree;
1390 else
1391 newlength = upr_tree;
1393 if (lwr_tree)
1395 /* Enforces lwr <= upr. No need to check lwr <= length as
1396 we've already ensured that upr <= length. */
1397 if (!e->lowerIsLessThanUpper)
1399 tree cond = build_bounds_condition (e->lwr->loc, lwr_tree,
1400 upr_tree, true);
1402 /* When bounds checking is off, the index value is
1403 returned directly. */
1404 if (cond != lwr_tree)
1405 newlength = compound_expr (cond, newlength);
1408 /* Need to ensure lwr always gets evaluated first, as it may be a
1409 function call. Generates (lwr, upr) - lwr. */
1410 newlength = fold_build2 (MINUS_EXPR, TREE_TYPE (newlength),
1411 compound_expr (lwr_tree, newlength), lwr_tree);
1414 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1415 this->result_ = compound_expr (array, result);
1418 /* Build a cast expression, which converts the given unary expression to the
1419 type of result. */
1421 void visit (CastExp *e)
1423 Type *ebtype = e->e1->type->toBasetype ();
1424 Type *tbtype = e->to->toBasetype ();
1425 tree result = build_expr (e->e1, this->constp_);
1427 /* Just evaluate e1 if it has any side effects. */
1428 if (tbtype->ty == Tvoid)
1429 this->result_ = build_nop (build_ctype (tbtype), result);
1430 else
1431 this->result_ = convert_expr (result, ebtype, tbtype);
1434 /* Build a delete expression. */
1436 void visit (DeleteExp *e)
1438 tree t1 = build_expr (e->e1);
1439 Type *tb1 = e->e1->type->toBasetype ();
1441 if (tb1->ty == Tclass)
1443 /* For class object references, if there is a destructor for that class,
1444 the destructor is called for the object instance. */
1445 libcall_fn libcall;
1447 if (e->e1->op == TOKvar)
1449 VarDeclaration *v = ((VarExp *) e->e1)->var->isVarDeclaration ();
1450 if (v && v->onstack)
1452 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1453 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1455 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1456 return;
1460 /* Otherwise, the garbage collector is called to immediately free the
1461 memory allocated for the class instance. */
1462 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1463 ? LIBCALL_DELINTERFACE : LIBCALL_DELCLASS;
1465 t1 = build_address (t1);
1466 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1468 else if (tb1->ty == Tarray)
1470 /* For dynamic arrays, the garbage collector is called to immediately
1471 release the memory. */
1472 Type *telem = tb1->nextOf ()->baseElemOf ();
1473 tree ti = null_pointer_node;
1475 if (telem->ty == Tstruct)
1477 /* Might need to run destructor on array contents. */
1478 TypeStruct *ts = (TypeStruct *) telem;
1479 if (ts->sym->dtor)
1480 ti = build_typeinfo (tb1->nextOf ());
1483 /* Generate: _delarray_t (&t1, ti); */
1484 this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,
1485 build_address (t1), ti);
1487 else if (tb1->ty == Tpointer)
1489 /* For pointers to a struct instance, if the struct has overloaded
1490 operator delete, then that operator is called. */
1491 t1 = build_address (t1);
1492 Type *tnext = ((TypePointer *)tb1)->next->toBasetype ();
1494 if (tnext->ty == Tstruct)
1496 TypeStruct *ts = (TypeStruct *)tnext;
1497 if (ts->sym->dtor)
1499 this->result_ = build_libcall (LIBCALL_DELSTRUCT, Type::tvoid,
1500 2, t1, build_typeinfo (tnext));
1501 return;
1505 /* Otherwise, the garbage collector is called to immediately free the
1506 memory allocated for the pointer. */
1507 this->result_ = build_libcall (LIBCALL_DELMEMORY, Type::tvoid, 1, t1);
1509 else
1511 error ("don't know how to delete %qs", e->e1->toChars ());
1512 this->result_ = error_mark_node;
1516 /* Build a remove expression, which removes a particular key from an
1517 associative array. */
1519 void visit (RemoveExp *e)
1521 /* Check that the array is actually an associative array. */
1522 if (e->e1->type->toBasetype ()->ty == Taarray)
1524 Type *tb = e->e1->type->toBasetype ();
1525 Type *tkey = ((TypeAArray *) tb)->index->toBasetype ();
1526 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1528 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1529 build_expr (e->e1),
1530 build_typeinfo (tkey),
1531 build_address (index));
1533 else
1535 error ("%qs is not an associative array", e->e1->toChars ());
1536 this->result_ = error_mark_node;
1540 /* Build an unary not expression. */
1542 void visit (NotExp *e)
1544 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1545 /* Need to convert to boolean type or this will fail. */
1546 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1548 this->result_ = d_convert (build_ctype (e->type), result);
1551 /* Build a compliment expression, where all the bits in the value are
1552 complemented. Note: unlike in C, the usual integral promotions
1553 are not performed prior to the complement operation. */
1555 void visit (ComExp *e)
1557 TY ty1 = e->e1->type->toBasetype ()->ty;
1558 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1560 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1561 build_expr (e->e1));
1564 /* Build an unary negation expression. */
1566 void visit (NegExp *e)
1568 TY ty1 = e->e1->type->toBasetype ()->ty;
1569 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1571 tree type = build_ctype (e->type);
1572 tree expr = build_expr (e->e1);
1574 /* If the operation needs excess precision. */
1575 tree eptype = excess_precision_type (type);
1576 if (eptype != NULL_TREE)
1577 expr = d_convert (eptype, expr);
1578 else
1579 eptype = type;
1581 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1582 this->result_ = d_convert (type, ret);
1585 /* Build a pointer index expression. */
1587 void visit (PtrExp *e)
1589 Type *tnext = NULL;
1590 size_t offset;
1591 tree result;
1593 if (e->e1->op == TOKadd)
1595 BinExp *be = (BinExp *) e->e1;
1596 if (be->e1->op == TOKaddress
1597 && be->e2->isConst () && be->e2->type->isintegral ())
1599 Expression *ae = ((AddrExp *) be->e1)->e1;
1600 tnext = ae->type->toBasetype ();
1601 result = build_expr (ae);
1602 offset = be->e2->toUInteger ();
1605 else if (e->e1->op == TOKsymoff)
1607 SymOffExp *se = (SymOffExp *) e->e1;
1608 if (!declaration_reference_p (se->var))
1610 tnext = se->var->type->toBasetype ();
1611 result = get_decl_tree (se->var);
1612 offset = se->offset;
1616 /* Produce better code by converting *(#record + n) to
1617 COMPONENT_REFERENCE. Otherwise, the variable will always be
1618 allocated in memory because its address is taken. */
1619 if (tnext && tnext->ty == Tstruct)
1621 StructDeclaration *sd = ((TypeStruct *) tnext)->sym;
1623 for (size_t i = 0; i < sd->fields.dim; i++)
1625 VarDeclaration *field = sd->fields[i];
1627 if (field->offset == offset
1628 && same_type_p (field->type, e->type))
1630 /* Catch errors, backend will ICE otherwise. */
1631 if (error_operand_p (result))
1632 this->result_ = result;
1633 else
1635 result = component_ref (result, get_symbol_decl (field));
1636 this->result_ = result;
1638 return;
1640 else if (field->offset > offset)
1641 break;
1645 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1648 /* Build an unary address expression. */
1650 void visit (AddrExp *e)
1652 tree type = build_ctype (e->type);
1653 tree exp;
1655 /* The frontend optimizer can convert const symbol into a struct literal.
1656 Taking the address of a struct literal is otherwise illegal. */
1657 if (e->e1->op == TOKstructliteral)
1659 StructLiteralExp *sle = ((StructLiteralExp *) e->e1)->origin;
1660 gcc_assert (sle != NULL);
1662 /* Build the reference symbol, the decl is built first as the
1663 initializer may have recursive references. */
1664 if (!sle->sym)
1666 sle->sym = build_artificial_decl (build_ctype (sle->type),
1667 NULL_TREE, "S");
1668 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1669 d_pushdecl (sle->sym);
1670 rest_of_decl_compilation (sle->sym, 1, 0);
1673 exp = sle->sym;
1675 else
1676 exp = build_expr (e->e1, this->constp_);
1678 TREE_CONSTANT (exp) = 0;
1679 this->result_ = d_convert (type, build_address (exp));
1682 /* Build a function call expression. */
1684 void visit (CallExp *e)
1686 Type *tb = e->e1->type->toBasetype ();
1687 Expression *e1b = e->e1;
1689 tree callee = NULL_TREE;
1690 tree object = NULL_TREE;
1691 tree cleanup = NULL_TREE;
1692 TypeFunction *tf = NULL;
1694 /* Calls to delegates can sometimes look like this. */
1695 if (e1b->op == TOKcomma)
1697 e1b = ((CommaExp *) e1b)->e2;
1698 gcc_assert (e1b->op == TOKvar);
1700 Declaration *var = ((VarExp *) e1b)->var;
1701 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1704 if (e1b->op == TOKdotvar && tb->ty != Tdelegate)
1706 DotVarExp *dve = (DotVarExp *) e1b;
1708 /* Don't modify the static initializer for struct literals. */
1709 if (dve->e1->op == TOKstructliteral)
1711 StructLiteralExp *sle = (StructLiteralExp *) dve->e1;
1712 sle->useStaticInit = false;
1715 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1716 if (fd != NULL)
1718 /* Get the correct callee from the DotVarExp object. */
1719 tree fndecl = get_symbol_decl (fd);
1720 AggregateDeclaration *ad = fd->isThis ();
1722 /* Static method; ignore the object instance. */
1723 if (!ad)
1724 callee = build_address (fndecl);
1725 else
1727 tree thisexp = build_expr (dve->e1);
1729 /* When constructing temporaries, if the constructor throws,
1730 then the object is destructed even though it is not a fully
1731 constructed object yet. And so this call will need to be
1732 moved inside the TARGET_EXPR_INITIAL slot. */
1733 if (fd->isCtorDeclaration ()
1734 && TREE_CODE (thisexp) == COMPOUND_EXPR
1735 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1736 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1738 cleanup = TREE_OPERAND (thisexp, 0);
1739 thisexp = TREE_OPERAND (thisexp, 1);
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 callee = build_method_call (fndecl, thisexp, fd->type);
1762 if (callee == NULL_TREE)
1763 callee = build_expr (e1b);
1765 if (METHOD_CALL_EXPR (callee))
1767 /* This could be a delegate expression (TY == Tdelegate), but not
1768 actually a delegate variable. */
1769 if (e1b->op == TOKdotvar)
1771 /* This gets the true function type, getting the function type
1772 from e1->type can sometimes be incorrect, such as when calling
1773 a 'ref' return function. */
1774 tf = get_function_type (((DotVarExp *) e1b)->var->type);
1776 else
1777 tf = get_function_type (tb);
1779 extract_from_method_call (callee, callee, object);
1781 else if (tb->ty == Tdelegate)
1783 /* Delegate call, extract .object and .funcptr from var. */
1784 callee = d_save_expr (callee);
1785 tf = get_function_type (tb);
1786 object = delegate_object (callee);
1787 callee = delegate_method (callee);
1789 else if (e1b->op == TOKvar)
1791 FuncDeclaration *fd = ((VarExp *) e1b)->var->isFuncDeclaration ();
1792 gcc_assert (fd != NULL);
1793 tf = get_function_type (fd->type);
1795 if (fd->isNested ())
1797 /* Maybe re-evaluate symbol storage treating 'fd' as public. */
1798 if (call_by_alias_p (d_function_chain->function, fd))
1799 TREE_PUBLIC (callee) = 1;
1801 object = get_frame_for_symbol (fd);
1803 else if (fd->needThis ())
1805 error_at (make_location_t (e1b->loc),
1806 "need %<this%> to access member %qs", fd->toChars ());
1807 /* Continue compiling... */
1808 object = null_pointer_node;
1811 else
1813 /* Normal direct function call. */
1814 tf = get_function_type (tb);
1817 gcc_assert (tf != NULL);
1819 /* Now we have the type, callee and maybe object reference,
1820 build the call expression. */
1821 tree exp = d_build_call (tf, callee, object, e->arguments);
1823 if (tf->isref)
1824 exp = build_deref (exp);
1826 /* Some library calls are defined to return a generic type.
1827 this->type is the real type we want to return. */
1828 if (e->type->isTypeBasic ())
1829 exp = d_convert (build_ctype (e->type), exp);
1831 /* If this call was found to be a constructor for a temporary with a
1832 cleanup, then move the call inside the TARGET_EXPR. The original
1833 initializer is turned into an assignment, to keep its side effect. */
1834 if (cleanup != NULL_TREE)
1836 tree init = TARGET_EXPR_INITIAL (cleanup);
1837 tree slot = TARGET_EXPR_SLOT (cleanup);
1838 d_mark_addressable (slot);
1839 init = build_assign (INIT_EXPR, slot, init);
1841 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1842 exp = cleanup;
1845 this->result_ = exp;
1848 /* Build a delegate expression. */
1850 void visit (DelegateExp *e)
1852 if (e->func->semanticRun == PASSsemantic3done)
1854 /* Add the function as nested function if it belongs to this module.
1855 ie: it is a member of this module, or it is a template instance. */
1856 Dsymbol *owner = e->func->toParent ();
1857 while (!owner->isTemplateInstance () && owner->toParent ())
1858 owner = owner->toParent ();
1859 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1860 build_decl_tree (e->func);
1863 tree fndecl;
1864 tree object;
1866 if (e->func->isNested ())
1868 if (e->e1->op == TOKnull)
1869 object = build_expr (e->e1);
1870 else
1871 object = get_frame_for_symbol (e->func);
1873 fndecl = build_address (get_symbol_decl (e->func));
1875 else
1877 if (!e->func->isThis ())
1879 error ("delegates are only for non-static functions");
1880 this->result_ = error_mark_node;
1881 return;
1884 object = build_expr (e->e1);
1886 /* Want reference to `this' object. */
1887 if (e->e1->type->ty != Tclass && e->e1->type->ty != Tpointer)
1888 object = build_address (object);
1890 /* Object reference could be the outer `this' field of a class or
1891 closure of type `void*'. Cast it to the right type. */
1892 if (e->e1->type->ty == Tclass)
1893 object = d_convert (build_ctype (e->e1->type), object);
1895 fndecl = get_symbol_decl (e->func);
1897 /* Get pointer to function out of the virtual table. */
1898 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1899 && e->e1->op != TOKsuper && e->e1->op != TOKdottype)
1901 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1902 object = d_save_expr (object);
1903 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1905 else
1906 fndecl = build_address (fndecl);
1909 this->result_ = build_method_call (fndecl, object, e->type);
1912 /* Build a type component expression. */
1914 void visit (DotTypeExp *e)
1916 /* Just a pass through to underlying expression. */
1917 this->result_ = build_expr (e->e1);
1920 /* Build a component reference expression. */
1922 void visit (DotVarExp *e)
1924 VarDeclaration *vd = e->var->isVarDeclaration ();
1926 /* This could also be a function, but relying on that being taken
1927 care of by the visitor interface for CallExp. */
1928 if (vd != NULL)
1930 if (!vd->isField ())
1931 this->result_ = get_decl_tree (vd);
1932 else
1934 tree object = build_expr (e->e1);
1936 if (e->e1->type->toBasetype ()->ty != Tstruct)
1937 object = build_deref (object);
1939 this->result_ = component_ref (object, get_symbol_decl (vd));
1942 else
1944 error ("%qs is not a field, but a %qs",
1945 e->var->toChars (), e->var->kind ());
1946 this->result_ = error_mark_node;
1950 /* Build an assert expression, used to declare conditions that must hold at
1951 that a given point in the program. */
1953 void visit (AssertExp *e)
1955 Type *tb1 = e->e1->type->toBasetype ();
1956 tree arg = build_expr (e->e1);
1957 tree tmsg = NULL_TREE;
1958 tree assert_pass = void_node;
1959 tree assert_fail;
1961 if (global.params.useAssert)
1963 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1964 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1965 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1966 libcall_fn libcall;
1968 if (e->msg)
1970 tmsg = build_expr_dtor (e->msg);
1971 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1973 else
1974 libcall = unittest_p ? LIBCALL_UNITTEST : LIBCALL_ASSERT;
1976 /* Build a call to _d_assert(). */
1977 assert_fail = d_assert_call (e->loc, libcall, tmsg);
1979 if (global.params.useInvariants)
1981 /* If the condition is a D class or struct object with an invariant,
1982 call it if the condition result is true. */
1983 if (tb1->ty == Tclass)
1985 ClassDeclaration *cd = tb1->isClassHandle ();
1986 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
1988 arg = d_save_expr (arg);
1989 assert_pass = build_libcall (LIBCALL_INVARIANT,
1990 Type::tvoid, 1, arg);
1993 else if (tb1->ty == Tpointer && tb1->nextOf ()->ty == Tstruct)
1995 StructDeclaration *sd = ((TypeStruct *) tb1->nextOf ())->sym;
1996 if (sd->inv != NULL)
1998 Expressions args;
1999 arg = d_save_expr (arg);
2000 assert_pass = d_build_call_expr (sd->inv, arg, &args);
2005 else
2007 /* Assert contracts are turned off, if the contract condition has no
2008 side effects can still use it as a predicate for the optimizer. */
2009 if (TREE_SIDE_EFFECTS (arg))
2011 this->result_ = void_node;
2012 return;
2015 assert_fail = build_predict_expr (PRED_NORETURN, NOT_TAKEN);
2018 /* Build condition that we are asserting in this contract. */
2019 tree condition = convert_for_condition (arg, e->e1->type);
2021 /* We expect the condition to always be true, as what happens if an assert
2022 contract is false is undefined behavior. */
2023 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
2024 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
2025 tree pred_type = TREE_VALUE (arg_types);
2026 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
2028 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
2029 build_int_cst (expected_type, 1));
2030 condition = d_truthvalue_conversion (condition);
2032 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
2035 /* Build a declaration expression. */
2037 void visit (DeclarationExp *e)
2039 /* Compile the declaration. */
2040 push_stmt_list ();
2041 build_decl_tree (e->declaration);
2042 tree result = pop_stmt_list ();
2044 /* Construction of an array for typesafe-variadic function arguments
2045 can cause an empty STMT_LIST here. This can causes problems
2046 during gimplification. */
2047 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
2048 result = build_empty_stmt (input_location);
2050 this->result_ = result;
2053 /* Build a typeid expression. Returns an instance of class TypeInfo
2054 corresponding to. */
2056 void visit (TypeidExp *e)
2058 if (Type *tid = isType (e->obj))
2060 tree ti = build_typeinfo (tid);
2062 /* If the typeinfo is at an offset. */
2063 if (tid->vtinfo->offset)
2064 ti = build_offset (ti, size_int (tid->vtinfo->offset));
2066 this->result_ = build_nop (build_ctype (e->type), ti);
2068 else if (Expression *tid = isExpression (e->obj))
2070 Type *type = tid->type->toBasetype ();
2071 assert (type->ty == Tclass);
2073 /* Generate **classptr to get the classinfo. */
2074 tree ci = build_expr (tid);
2075 ci = indirect_ref (ptr_type_node, ci);
2076 ci = indirect_ref (ptr_type_node, ci);
2078 /* Add extra indirection for interfaces. */
2079 if (((TypeClass *) type)->sym->isInterfaceDeclaration ())
2080 ci = indirect_ref (ptr_type_node, ci);
2082 this->result_ = build_nop (build_ctype (e->type), ci);
2084 else
2085 gcc_unreachable ();
2088 /* Build a function/lambda expression. */
2090 void visit (FuncExp *e)
2092 Type *ftype = e->type->toBasetype ();
2094 /* This check is for lambda's, remove 'vthis' as function isn't nested. */
2095 if (e->fd->tok == TOKreserved && ftype->ty == Tpointer)
2097 e->fd->tok = TOKfunction;
2098 e->fd->vthis = NULL;
2101 /* Compile the function literal body. */
2102 build_decl_tree (e->fd);
2104 /* If nested, this will be a trampoline. */
2105 if (e->fd->isNested ())
2107 tree func = build_address (get_symbol_decl (e->fd));
2108 tree object;
2110 if (this->constp_)
2112 /* Static delegate variables have no context pointer. */
2113 object = null_pointer_node;
2114 this->result_ = build_method_call (func, object, e->fd->type);
2115 TREE_CONSTANT (this->result_) = 1;
2117 else
2119 object = get_frame_for_symbol (e->fd);
2120 this->result_ = build_method_call (func, object, e->fd->type);
2123 else
2125 this->result_ = build_nop (build_ctype (e->type),
2126 build_address (get_symbol_decl (e->fd)));
2130 /* Build a halt expression. */
2132 void visit (HaltExp *)
2134 /* Should we use trap() or abort()? */
2135 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2136 this->result_ = build_call_expr (ttrap, 0);
2139 /* Build a symbol pointer offset expression. */
2141 void visit (SymOffExp *e)
2143 /* Build the address and offset of the symbol. */
2144 size_t soffset = ((SymOffExp *) e)->offset;
2145 tree result = get_decl_tree (e->var);
2146 TREE_USED (result) = 1;
2148 if (declaration_reference_p (e->var))
2149 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2150 else
2151 result = build_address (result);
2153 if (!soffset)
2154 result = d_convert (build_ctype (e->type), result);
2155 else
2157 tree offset = size_int (soffset);
2158 result = build_nop (build_ctype (e->type),
2159 build_offset (result, offset));
2162 this->result_ = result;
2165 /* Build a variable expression. */
2167 void visit (VarExp *e)
2169 if (e->var->needThis ())
2171 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2172 this->result_ = error_mark_node;
2173 return;
2175 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2177 /* __ctfe is always false at run-time. */
2178 this->result_ = integer_zero_node;
2179 return;
2182 /* This check is same as is done in FuncExp for lambdas. */
2183 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2184 if (fld != NULL)
2186 if (fld->tok == TOKreserved)
2188 fld->tok = TOKfunction;
2189 fld->vthis = NULL;
2192 /* Compiler the function literal body. */
2193 build_decl_tree (fld);
2196 if (this->constp_)
2198 /* Want the initializer, not the expression. */
2199 VarDeclaration *var = e->var->isVarDeclaration ();
2200 SymbolDeclaration *sd = e->var->isSymbolDeclaration ();
2201 tree init = NULL_TREE;
2203 if (var && (var->isConst () || var->isImmutable ())
2204 && e->type->toBasetype ()->ty != Tsarray && var->_init)
2206 if (var->inuse)
2207 error_at (make_location_t (e->loc), "recursive reference %qs",
2208 e->toChars ());
2209 else
2211 var->inuse++;
2212 init = build_expr (initializerToExpression (var->_init), true);
2213 var->inuse--;
2216 else if (sd && sd->dsym)
2217 init = layout_struct_initializer (sd->dsym);
2218 else
2219 error_at (make_location_t (e->loc), "non-constant expression %qs",
2220 e->toChars ());
2222 if (init != NULL_TREE)
2223 this->result_ = init;
2224 else
2225 this->result_ = error_mark_node;
2227 else
2229 tree result = get_decl_tree (e->var);
2230 TREE_USED (result) = 1;
2232 /* For variables that are references - currently only out/inout
2233 arguments; objects don't count - evaluating the variable means
2234 we want what it refers to. */
2235 if (declaration_reference_p (e->var))
2236 result = indirect_ref (build_ctype (e->var->type), result);
2238 this->result_ = result;
2242 /* Build a this variable expression. */
2244 void visit (ThisExp *e)
2246 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2247 tree result = NULL_TREE;
2249 if (e->var)
2250 result = get_decl_tree (e->var);
2251 else
2253 gcc_assert (fd && fd->vthis);
2254 result = get_decl_tree (fd->vthis);
2257 if (e->type->ty == Tstruct)
2258 result = build_deref (result);
2260 this->result_ = result;
2263 /* Build a new expression, which allocates memory either on the garbage
2264 collected heap or by using a class or struct specific allocator. */
2266 void visit (NewExp *e)
2268 Type *tb = e->type->toBasetype ();
2269 tree result;
2271 if (e->allocator)
2272 gcc_assert (e->newargs);
2274 if (tb->ty == Tclass)
2276 /* Allocating a new class. */
2277 tb = e->newtype->toBasetype ();
2278 gcc_assert (tb->ty == Tclass);
2280 ClassDeclaration *cd = ((TypeClass *) tb)->sym;
2281 tree type = build_ctype (tb);
2282 tree setup_exp = NULL_TREE;
2283 tree new_call;
2285 if (e->onstack)
2287 /* If being used as an initializer for a local variable with scope
2288 storage class, then the instance is allocated on the stack
2289 rather than the heap or using the class specific allocator. */
2290 tree var = build_local_temp (TREE_TYPE (type));
2291 new_call = build_nop (type, build_address (var));
2292 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2294 else if (e->allocator)
2296 /* Call class allocator, and copy the initializer into memory. */
2297 new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
2298 new_call = d_save_expr (new_call);
2299 new_call = build_nop (type, new_call);
2300 setup_exp = modify_expr (build_deref (new_call),
2301 aggregate_initializer_decl (cd));
2303 else
2305 /* Generate: _d_newclass() */
2306 tree arg = build_address (get_classinfo_decl (cd));
2307 new_call = build_libcall (LIBCALL_NEWCLASS, tb, 1, arg);
2310 /* Set the context pointer for nested classes. */
2311 if (cd->isNested ())
2313 tree field = get_symbol_decl (cd->vthis);
2314 tree value = NULL_TREE;
2316 if (e->thisexp)
2318 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2319 Dsymbol *outer = cd->toParent2 ();
2320 int offset = 0;
2322 value = build_expr (e->thisexp);
2323 if (outer != tcd)
2325 ClassDeclaration *ocd = outer->isClassDeclaration ();
2326 gcc_assert (ocd->isBaseOf (tcd, &offset));
2327 /* Could just add offset... */
2328 value = convert_expr (value, e->thisexp->type, ocd->type);
2331 else
2332 value = build_vthis (cd);
2334 if (value != NULL_TREE)
2336 /* Generate: (new())->vthis = this; */
2337 new_call = d_save_expr (new_call);
2338 field = component_ref (build_deref (new_call), field);
2339 setup_exp = compound_expr (setup_exp,
2340 modify_expr (field, value));
2343 new_call = compound_expr (setup_exp, new_call);
2345 /* Call the class constructor. */
2346 if (e->member)
2347 result = d_build_call_expr (e->member, new_call, e->arguments);
2348 else
2349 result = new_call;
2351 if (e->argprefix)
2352 result = compound_expr (build_expr (e->argprefix), result);
2354 else if (tb->ty == Tpointer && tb->nextOf ()->toBasetype ()->ty == Tstruct)
2356 /* Allocating memory for a new struct. */
2357 Type *htype = e->newtype->toBasetype ();
2358 gcc_assert (htype->ty == Tstruct);
2359 gcc_assert (!e->onstack);
2361 TypeStruct *stype = (TypeStruct *) htype;
2362 StructDeclaration *sd = stype->sym;
2363 tree new_call;
2365 /* Cannot new an opaque struct. */
2366 if (sd->size (e->loc) == 0)
2368 this->result_ = d_convert (build_ctype (e->type),
2369 integer_zero_node);
2370 return;
2373 if (e->allocator)
2375 /* Call struct allocator. */
2376 new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
2377 new_call = build_nop (build_ctype (tb), new_call);
2379 else
2381 /* Generate: _d_newitemT() */
2382 libcall_fn libcall = htype->isZeroInit ()
2383 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2384 tree arg = build_typeinfo (e->newtype);
2385 new_call = build_libcall (libcall, tb, 1, arg);
2388 if (e->member || !e->arguments)
2390 /* Set the context pointer for nested structs. */
2391 if (sd->isNested ())
2393 tree value = build_vthis (sd);
2394 tree field = get_symbol_decl (sd->vthis);
2395 tree type = build_ctype (stype);
2397 new_call = d_save_expr (new_call);
2398 field = component_ref (indirect_ref (type, new_call), field);
2399 new_call = compound_expr (modify_expr (field, value), new_call);
2402 /* Call the struct constructor. */
2403 if (e->member)
2404 result = d_build_call_expr (e->member, new_call, e->arguments);
2405 else
2406 result = new_call;
2408 else
2410 /* If we have a user supplied initializer, then set-up with a
2411 struct literal. */
2412 if (e->arguments != NULL && sd->fields.dim != 0)
2414 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2415 e->arguments,
2416 htype);
2417 new_call = d_save_expr (new_call);
2418 se->type = sd->type;
2419 se->sym = new_call;
2420 result = compound_expr (build_expr (se), new_call);
2422 else
2423 result = new_call;
2426 if (e->argprefix)
2427 result = compound_expr (build_expr (e->argprefix), result);
2429 else if (tb->ty == Tarray)
2431 /* Allocating memory for a new D array. */
2432 tb = e->newtype->toBasetype ();
2433 gcc_assert (tb->ty == Tarray);
2434 TypeDArray *tarray = (TypeDArray *) tb;
2436 gcc_assert (!e->allocator);
2437 gcc_assert (e->arguments && e->arguments->dim >= 1);
2439 if (e->arguments->dim == 1)
2441 /* Single dimension array allocations. */
2442 Expression *arg = (*e->arguments)[0];
2444 if (tarray->next->size () == 0)
2446 /* Array element size is unknown. */
2447 this->result_ = d_array_value (build_ctype (e->type),
2448 size_int (0), null_pointer_node);
2449 return;
2452 libcall_fn libcall = tarray->next->isZeroInit ()
2453 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
2454 result = build_libcall (libcall, tb, 2,
2455 build_typeinfo (e->type),
2456 build_expr (arg));
2458 else
2460 /* Multidimensional array allocations. */
2461 vec<constructor_elt, va_gc> *elms = NULL;
2462 Type *telem = e->newtype->toBasetype ();
2463 tree tarray = make_array_type (Type::tsize_t, e->arguments->dim);
2464 tree var = create_temporary_var (tarray);
2465 tree init = build_constructor (TREE_TYPE (var), NULL);
2467 for (size_t i = 0; i < e->arguments->dim; i++)
2469 Expression *arg = (*e->arguments)[i];
2470 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2472 gcc_assert (telem->ty == Tarray);
2473 telem = telem->toBasetype ()->nextOf ();
2474 gcc_assert (telem);
2477 CONSTRUCTOR_ELTS (init) = elms;
2478 DECL_INITIAL (var) = init;
2480 /* Generate: _d_newarraymTX(ti, dims)
2481 or: _d_newarraymiTX(ti, dims) */
2482 libcall_fn libcall = telem->isZeroInit ()
2483 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2485 tree tinfo = build_typeinfo (e->type);
2486 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2487 size_int (e->arguments->dim),
2488 build_address (var));
2490 result = build_libcall (libcall, tb, 2, tinfo, dims);
2491 result = bind_expr (var, result);
2494 if (e->argprefix)
2495 result = compound_expr (build_expr (e->argprefix), result);
2497 else if (tb->ty == Tpointer)
2499 /* Allocating memory for a new pointer. */
2500 TypePointer *tpointer = (TypePointer *) tb;
2502 if (tpointer->next->size () == 0)
2504 /* Pointer element size is unknown. */
2505 this->result_ = d_convert (build_ctype (e->type),
2506 integer_zero_node);
2507 return;
2510 libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
2511 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2513 tree arg = build_typeinfo (e->newtype);
2514 result = build_libcall (libcall, tb, 1, arg);
2516 if (e->arguments && e->arguments->dim == 1)
2518 result = d_save_expr (result);
2519 tree init = modify_expr (build_deref (result),
2520 build_expr ((*e->arguments)[0]));
2521 result = compound_expr (init, result);
2524 if (e->argprefix)
2525 result = compound_expr (build_expr (e->argprefix), result);
2527 else
2528 gcc_unreachable ();
2530 this->result_ = convert_expr (result, tb, e->type);
2533 /* Build an integer literal. */
2535 void visit (IntegerExp *e)
2537 tree ctype = build_ctype (e->type->toBasetype ());
2538 this->result_ = build_integer_cst (e->value, ctype);
2541 /* Build a floating-point literal. */
2543 void visit (RealExp *e)
2545 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2548 /* Build a complex literal. */
2550 void visit (ComplexExp *e)
2552 Type *tnext;
2554 switch (e->type->toBasetype ()->ty)
2556 case Tcomplex32:
2557 tnext = (TypeBasic *) Type::tfloat32;
2558 break;
2560 case Tcomplex64:
2561 tnext = (TypeBasic *) Type::tfloat64;
2562 break;
2564 case Tcomplex80:
2565 tnext = (TypeBasic *) Type::tfloat80;
2566 break;
2568 default:
2569 gcc_unreachable ();
2572 this->result_ = build_complex (build_ctype (e->type),
2573 build_float_cst (creall (e->value), tnext),
2574 build_float_cst (cimagl (e->value), tnext));
2577 /* Build a string literal, all strings are null terminated except for
2578 static arrays. */
2580 void visit (StringExp *e)
2582 Type *tb = e->type->toBasetype ();
2583 tree type = build_ctype (e->type);
2585 if (tb->ty == Tsarray)
2587 /* Turn the string into a constructor for the static array. */
2588 vec<constructor_elt, va_gc> *elms = NULL;
2589 vec_safe_reserve (elms, e->len);
2590 tree etype = TREE_TYPE (type);
2592 for (size_t i = 0; i < e->len; i++)
2594 tree value = build_integer_cst (e->charAt (i), etype);
2595 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2598 tree ctor = build_constructor (type, elms);
2599 TREE_CONSTANT (ctor) = 1;
2600 this->result_ = ctor;
2602 else
2604 /* Copy the string contents to a null terminated string. */
2605 dinteger_t length = (e->len * e->sz);
2606 char *string = XALLOCAVEC (char, length + 1);
2607 memcpy (string, e->string, length);
2608 string[length] = '\0';
2610 /* String value and type includes the null terminator. */
2611 tree value = build_string (length, string);
2612 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2613 value = build_address (value);
2615 if (tb->ty == Tarray)
2616 value = d_array_value (type, size_int (e->len), value);
2618 TREE_CONSTANT (value) = 1;
2619 this->result_ = d_convert (type, value);
2623 /* Build a tuple literal. Just an argument list that may have
2624 side effects that need evaluation. */
2626 void visit (TupleExp *e)
2628 tree result = NULL_TREE;
2630 if (e->e0)
2631 result = build_expr (e->e0);
2633 for (size_t i = 0; i < e->exps->dim; ++i)
2635 Expression *exp = (*e->exps)[i];
2636 result = compound_expr (result, build_expr (exp));
2639 if (result == NULL_TREE)
2640 result = void_node;
2642 this->result_ = result;
2645 /* Build an array literal. The common type of the all elements is taken to
2646 be the type of the array element, and all elements are implicitly
2647 converted to that type. */
2649 void visit (ArrayLiteralExp *e)
2651 Type *tb = e->type->toBasetype ();
2653 /* Implicitly convert void[n] to ubyte[n]. */
2654 if (tb->ty == Tsarray && tb->nextOf ()->toBasetype ()->ty == Tvoid)
2655 tb = Type::tuns8->sarrayOf (((TypeSArray *) tb)->dim->toUInteger ());
2657 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tpointer);
2659 /* Handle empty array literals. */
2660 if (e->elements->dim == 0)
2662 if (tb->ty == Tarray)
2663 this->result_ = d_array_value (build_ctype (e->type),
2664 size_int (0), null_pointer_node);
2665 else
2666 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2667 NULL);
2669 return;
2672 /* Build an expression that assigns the expressions in ELEMENTS to
2673 a constructor. */
2674 vec<constructor_elt, va_gc> *elms = NULL;
2675 vec_safe_reserve (elms, e->elements->dim);
2676 bool constant_p = true;
2677 tree saved_elems = NULL_TREE;
2679 Type *etype = tb->nextOf ();
2680 tree satype = make_array_type (etype, e->elements->dim);
2682 for (size_t i = 0; i < e->elements->dim; i++)
2684 Expression *expr = e->getElement (i);
2685 tree value = build_expr (expr, this->constp_);
2687 /* Only append nonzero values, the backend will zero out the rest
2688 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2689 if (!initializer_zerop (value))
2691 if (!TREE_CONSTANT (value))
2692 constant_p = false;
2694 /* Split construction of values out of the constructor if there
2695 may be side effects. */
2696 tree init = stabilize_expr (&value);
2697 if (init != NULL_TREE)
2698 saved_elems = compound_expr (saved_elems, init);
2700 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2701 convert_expr (value, expr->type, etype));
2705 /* Now return the constructor as the correct type. For static arrays there
2706 is nothing else to do. For dynamic arrays, return a two field struct.
2707 For pointers, return the address. */
2708 tree ctor = build_constructor (satype, elms);
2709 tree type = build_ctype (e->type);
2711 /* Nothing else to do for static arrays. */
2712 if (tb->ty == Tsarray || this->constp_)
2714 /* Can't take the address of the constructor, so create an anonymous
2715 static symbol, and then refer to it. */
2716 if (tb->ty != Tsarray)
2718 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2719 ctor = build_address (decl);
2720 if (tb->ty == Tarray)
2721 ctor = d_array_value (type, size_int (e->elements->dim), ctor);
2723 d_pushdecl (decl);
2724 rest_of_decl_compilation (decl, 1, 0);
2727 /* If the array literal is readonly or static. */
2728 if (constant_p)
2729 TREE_CONSTANT (ctor) = 1;
2730 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2731 TREE_STATIC (ctor) = 1;
2733 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2735 else
2737 /* Allocate space on the memory managed heap. */
2738 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2739 etype->pointerTo (), 2,
2740 build_typeinfo (etype->arrayOf ()),
2741 size_int (e->elements->dim));
2742 mem = d_save_expr (mem);
2744 /* Now copy the constructor into memory. */
2745 tree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);
2746 tree size = size_mult_expr (size_int (e->elements->dim),
2747 size_int (tb->nextOf ()->size ()));
2749 tree result = build_call_expr (tmemcpy, 3, mem,
2750 build_address (ctor), size);
2752 /* Return the array pointed to by MEM. */
2753 result = compound_expr (result, mem);
2755 if (tb->ty == Tarray)
2756 result = d_array_value (type, size_int (e->elements->dim), result);
2758 this->result_ = compound_expr (saved_elems, result);
2762 /* Build an associative array literal. The common type of the all keys is
2763 taken to be the key type, and common type of all values the value type.
2764 All keys and values are then implicitly converted as needed. */
2766 void visit (AssocArrayLiteralExp *e)
2768 /* Want the mutable type for typeinfo reference. */
2769 Type *tb = e->type->toBasetype ()->mutableOf ();
2770 gcc_assert (tb->ty == Taarray);
2772 /* Handle empty assoc array literals. */
2773 TypeAArray *ta = (TypeAArray *) tb;
2774 if (e->keys->dim == 0)
2776 this->result_ = build_constructor (build_ctype (ta), NULL);
2777 return;
2780 /* Build an expression that assigns all expressions in KEYS
2781 to a constructor. */
2782 vec<constructor_elt, va_gc> *kelts = NULL;
2783 vec_safe_reserve (kelts, e->keys->dim);
2784 for (size_t i = 0; i < e->keys->dim; i++)
2786 Expression *key = (*e->keys)[i];
2787 tree t = build_expr (key);
2788 CONSTRUCTOR_APPEND_ELT (kelts, size_int (i),
2789 convert_expr (t, key->type, ta->index));
2791 tree tkeys = make_array_type (ta->index, e->keys->dim);
2792 tree akeys = build_constructor (tkeys, kelts);
2794 /* Do the same with all expressions in VALUES. */
2795 vec<constructor_elt, va_gc> *velts = NULL;
2796 vec_safe_reserve (velts, e->values->dim);
2797 for (size_t i = 0; i < e->values->dim; i++)
2799 Expression *value = (*e->values)[i];
2800 tree t = build_expr (value);
2801 CONSTRUCTOR_APPEND_ELT (velts, size_int (i),
2802 convert_expr (t, value->type, ta->next));
2804 tree tvals = make_array_type (ta->next, e->values->dim);
2805 tree avals = build_constructor (tvals, velts);
2807 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2808 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2809 size_int (e->keys->dim), build_address (akeys));
2810 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2811 size_int (e->values->dim),
2812 build_address (avals));
2814 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2815 build_typeinfo (ta), keys, vals);
2817 /* Return an associative array pointed to by MEM. */
2818 tree aatype = build_ctype (ta);
2819 vec<constructor_elt, va_gc> *ce = NULL;
2820 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2822 this->result_ = build_nop (build_ctype (e->type),
2823 build_constructor (aatype, ce));
2826 /* Build a struct literal. */
2828 void visit (StructLiteralExp *e)
2830 /* Handle empty struct literals. */
2831 if (e->elements == NULL || e->sd->fields.dim == 0)
2833 this->result_ = build_constructor (build_ctype (e->type), NULL);
2834 return;
2837 /* Building sinit trees are delayed until after frontend semantic
2838 processing has complete. Build the static initializer now. */
2839 if (e->useStaticInit && !this->constp_)
2841 this->result_ = aggregate_initializer_decl (e->sd);
2842 return;
2845 /* Build a constructor that assigns the expressions in ELEMENTS
2846 at each field index that has been filled in. */
2847 vec<constructor_elt, va_gc> *ve = NULL;
2848 tree saved_elems = NULL_TREE;
2850 /* CTFE may fill the hidden pointer by NullExp. */
2851 gcc_assert (e->elements->dim <= e->sd->fields.dim);
2853 Type *tb = e->type->toBasetype ();
2854 gcc_assert (tb->ty == Tstruct);
2856 for (size_t i = 0; i < e->elements->dim; i++)
2858 Expression *exp = (*e->elements)[i];
2859 if (!exp)
2860 continue;
2862 VarDeclaration *field = e->sd->fields[i];
2863 Type *type = exp->type->toBasetype ();
2864 Type *ftype = field->type->toBasetype ();
2865 tree value = NULL_TREE;
2867 if (ftype->ty == Tsarray && !same_type_p (type, ftype))
2869 /* Initialize a static array with a single element. */
2870 tree elem = build_expr (exp, this->constp_);
2871 elem = d_save_expr (elem);
2873 if (initializer_zerop (elem))
2874 value = build_constructor (build_ctype (ftype), NULL);
2875 else
2876 value = build_array_from_val (ftype, elem);
2878 else
2880 value = convert_expr (build_expr (exp, this->constp_),
2881 exp->type, field->type);
2884 /* Split construction of values out of the constructor. */
2885 tree init = stabilize_expr (&value);
2886 if (init != NULL_TREE)
2887 saved_elems = compound_expr (saved_elems, init);
2889 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2892 /* Maybe setup hidden pointer to outer scope context. */
2893 if (e->sd->isNested () && e->elements->dim != e->sd->fields.dim
2894 && this->constp_ == false)
2896 tree field = get_symbol_decl (e->sd->vthis);
2897 tree value = build_vthis (e->sd);
2898 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2899 gcc_assert (e->useStaticInit == false);
2902 /* Build a constructor in the correct shape of the aggregate type. */
2903 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2905 /* Nothing more to do for constant literals. */
2906 if (this->constp_)
2908 /* If the struct literal is a valid for static data. */
2909 if (TREE_CONSTANT (ctor)
2910 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2911 TREE_STATIC (ctor) = 1;
2913 this->result_ = compound_expr (saved_elems, ctor);
2914 return;
2917 if (e->sym != NULL)
2919 tree var = build_deref (e->sym);
2920 ctor = compound_expr (modify_expr (var, ctor), var);
2921 this->result_ = compound_expr (saved_elems, ctor);
2923 else if (e->sd->isUnionDeclaration ())
2925 /* For unions, use memset to fill holes in the object. */
2926 tree var = build_local_temp (TREE_TYPE (ctor));
2927 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
2928 tree init = build_call_expr (tmemset, 3, build_address (var),
2929 size_zero_node,
2930 size_int (e->sd->structsize));
2932 init = compound_expr (init, saved_elems);
2933 init = compound_expr (init, modify_expr (var, ctor));
2934 this->result_ = compound_expr (init, var);
2936 else
2937 this->result_ = compound_expr (saved_elems, ctor);
2940 /* Build a null literal. */
2942 void visit (NullExp *e)
2944 Type *tb = e->type->toBasetype ();
2945 tree value;
2947 /* Handle certain special case conversions, where the underlying type is an
2948 aggregate with a nullable interior pointer. */
2949 if (tb->ty == Tarray)
2951 /* For dynamic arrays, set length and pointer fields to zero. */
2952 value = d_array_value (build_ctype (e->type), size_int (0),
2953 null_pointer_node);
2955 else if (tb->ty == Taarray)
2957 /* For associative arrays, set the pointer field to null. */
2958 value = build_constructor (build_ctype (e->type), NULL);
2960 else if (tb->ty == Tdelegate)
2962 /* For delegates, set the frame and function pointer to null. */
2963 value = build_delegate_cst (null_pointer_node,
2964 null_pointer_node, e->type);
2966 else
2967 value = d_convert (build_ctype (e->type), integer_zero_node);
2969 TREE_CONSTANT (value) = 1;
2970 this->result_ = value;
2973 /* Build a vector literal. */
2975 void visit (VectorExp *e)
2977 tree type = build_ctype (e->type);
2978 tree etype = TREE_TYPE (type);
2980 /* First handle array literal expressions. */
2981 if (e->e1->op == TOKarrayliteral)
2983 ArrayLiteralExp *ale = ((ArrayLiteralExp *) e->e1);
2984 vec<constructor_elt, va_gc> *elms = NULL;
2985 bool constant_p = true;
2987 vec_safe_reserve (elms, ale->elements->dim);
2988 for (size_t i = 0; i < ale->elements->dim; i++)
2990 Expression *expr = ale->getElement (i);
2991 tree value = d_convert (etype, build_expr (expr, this->constp_));
2992 if (!CONSTANT_CLASS_P (value))
2993 constant_p = false;
2995 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2998 /* Build a VECTOR_CST from a constant vector constructor. */
2999 if (constant_p)
3000 this->result_ = build_vector_from_ctor (type, elms);
3001 else
3002 this->result_ = build_constructor (type, elms);
3004 else
3006 /* Build constructor from single value. */
3007 tree val = d_convert (etype, build_expr (e->e1, this->constp_));
3008 this->result_ = build_vector_from_val (type, val);
3012 /* Build a static class literal, return its reference. */
3014 void visit (ClassReferenceExp *e)
3016 /* The result of build_new_class_expr is a RECORD_TYPE, we want
3017 the reference. */
3018 tree var = build_address (build_new_class_expr (e));
3020 /* If the type of this literal is an interface, the we must add the
3021 interface offset to symbol. */
3022 if (this->constp_)
3024 TypeClass *tc = (TypeClass *) e->type;
3025 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
3027 if (to != NULL)
3029 ClassDeclaration *from = e->originalClass ();
3030 int offset = 0;
3032 gcc_assert (to->isBaseOf (from, &offset) != 0);
3034 if (offset != 0)
3035 var = build_offset (var, size_int (offset));
3039 this->result_ = var;
3042 /* These expressions are mainly just a placeholders in the frontend.
3043 We shouldn't see them here. */
3045 void visit (ScopeExp *e)
3047 error_at (make_location_t (e->loc), "%qs is not an expression",
3048 e->toChars ());
3049 this->result_ = error_mark_node;
3052 void visit (TypeExp *e)
3054 error_at (make_location_t (e->loc), "type %qs is not an expression",
3055 e->toChars ());
3056 this->result_ = error_mark_node;
3061 /* Main entry point for ExprVisitor interface to generate code for
3062 the Expression AST class E. If CONST_P is true, then E is a
3063 constant expression. */
3065 tree
3066 build_expr (Expression *e, bool const_p)
3068 ExprVisitor v = ExprVisitor (const_p);
3069 location_t saved_location = input_location;
3071 input_location = make_location_t (e->loc);
3072 e->accept (&v);
3073 tree expr = v.result ();
3074 input_location = saved_location;
3076 /* Check if initializer expression is valid constant. */
3077 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3079 error_at (make_location_t (e->loc), "non-constant expression %qs",
3080 e->toChars ());
3081 return error_mark_node;
3084 return expr;
3087 /* Same as build_expr, but also calls destructors on any temporaries. */
3089 tree
3090 build_expr_dtor (Expression *e)
3092 /* Codegen can be improved by determining if no exceptions can be thrown
3093 between the ctor and dtor, and eliminating the ctor and dtor. */
3094 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3095 tree result = build_expr (e);
3097 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3099 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3100 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3103 return result;
3106 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3108 tree
3109 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3111 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3112 tree result = build_expr (e);
3114 /* Convert for initializing the DECL_RESULT. */
3115 result = convert_expr (result, e->type, type);
3117 /* If we are returning a reference, take the address. */
3118 if (tf->isref)
3119 result = build_address (result);
3121 /* The decl to store the return expression. */
3122 tree decl = DECL_RESULT (cfun->decl);
3124 /* Split comma expressions, so that the result is returned directly. */
3125 tree expr = stabilize_expr (&result);
3126 result = build_assign (INIT_EXPR, decl, result);
3127 result = compound_expr (expr, return_expr (result));
3129 /* May nest the return expression inside the try/finally expression. */
3130 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3132 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3133 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3136 return result;