d: Fix internal compiler error: Segmentation fault at gimple-expr.cc:88
[official-gcc.git] / gcc / d / expr.cc
blob6654244292efd3d357e47bfc38d4cb36a707c0d9
1 /* expr.cc -- Lower D frontend expressions to GCC trees.
2 Copyright (C) 2015-2022 Free Software Foundation, Inc.
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
22 #include "dmd/aggregate.h"
23 #include "dmd/ctfe.h"
24 #include "dmd/declaration.h"
25 #include "dmd/enum.h"
26 #include "dmd/expression.h"
27 #include "dmd/identifier.h"
28 #include "dmd/init.h"
29 #include "dmd/module.h"
30 #include "dmd/mtype.h"
31 #include "dmd/template.h"
33 #include "tree.h"
34 #include "fold-const.h"
35 #include "diagnostic.h"
36 #include "langhooks.h"
37 #include "tm.h"
38 #include "function.h"
39 #include "toplev.h"
40 #include "varasm.h"
41 #include "predict.h"
42 #include "stor-layout.h"
44 #include "d-tree.h"
47 /* Determine if type T is a struct that has a postblit. */
49 static bool
50 needs_postblit (Type *t)
52 t = t->baseElemOf ();
54 if (TypeStruct *ts = t->isTypeStruct ())
56 if (ts->sym->postblit)
57 return true;
60 return false;
63 /* Determine if type T is a struct that has a destructor. */
65 static bool
66 needs_dtor (Type *t)
68 t = t->baseElemOf ();
70 if (TypeStruct *ts = t->isTypeStruct ())
72 if (ts->sym->dtor)
73 return true;
76 return false;
79 /* Determine if expression E is a suitable lvalue. */
81 static bool
82 lvalue_p (Expression *e)
84 SliceExp *se = e->isSliceExp ();
85 if (se != NULL && se->e1->isLvalue ())
86 return true;
88 CastExp *ce = e->isCastExp ();
89 if (ce != NULL && ce->e1->isLvalue ())
90 return true;
92 return (e->op != EXP::slice && e->isLvalue ());
95 /* Build an expression of code CODE, data type TYPE, and operands ARG0 and
96 ARG1. Perform relevant conversions needed for correct code operations. */
98 static tree
99 binary_op (tree_code code, tree type, tree arg0, tree arg1)
101 tree t0 = TREE_TYPE (arg0);
102 tree t1 = TREE_TYPE (arg1);
103 tree ret = NULL_TREE;
105 /* Deal with float mod expressions immediately. */
106 if (code == FLOAT_MOD_EXPR)
107 return build_float_modulus (type, arg0, arg1);
109 if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
110 return build_nop (type, build_offset_op (code, arg0, arg1));
112 if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
113 return build_nop (type, build_offset_op (code, arg1, arg0));
115 if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
117 gcc_assert (code == MINUS_EXPR);
118 tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
120 /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
121 pointers. If some platform cannot provide that, or has a larger
122 ptrdiff_type to support differences larger than half the address
123 space, cast the pointers to some larger integer type and do the
124 computations in that type. */
125 if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
126 ret = fold_build2 (MINUS_EXPR, ptrtype,
127 d_convert (ptrtype, arg0),
128 d_convert (ptrtype, arg1));
129 else
130 ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
132 else
134 /* If the operation needs excess precision. */
135 tree eptype = excess_precision_type (type);
136 if (eptype != NULL_TREE)
138 arg0 = d_convert (eptype, arg0);
139 arg1 = d_convert (eptype, arg1);
141 else
143 /* Front-end does not do this conversion and GCC does not
144 always do it right. */
145 if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
146 arg1 = d_convert (t0, arg1);
147 else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
148 arg0 = d_convert (t1, arg0);
150 eptype = type;
153 ret = build2 (code, eptype, arg0, arg1);
156 return d_convert (type, ret);
159 /* Build a binary expression of code CODE, assigning the result into E1. */
161 static tree
162 binop_assignment (tree_code code, Expression *e1, Expression *e2)
164 /* Skip casts for lhs assignment. */
165 Expression *e1b = e1;
166 while (e1b->op == EXP::cast_)
168 CastExp *ce = e1b->isCastExp ();
169 gcc_assert (same_type_p (ce->type, ce->to));
170 e1b = ce->e1;
173 /* Stabilize LHS for assignment. */
174 tree lhs = build_expr (e1b);
175 tree lexpr = stabilize_expr (&lhs);
177 /* The LHS expression could be an assignment, to which its operation gets
178 lost during gimplification. */
179 if (TREE_CODE (lhs) == MODIFY_EXPR)
181 /* If LHS has side effects, call stabilize_reference on it, so it can
182 be evaluated multiple times. */
183 if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
184 lhs = build_assign (MODIFY_EXPR,
185 stabilize_reference (TREE_OPERAND (lhs, 0)),
186 TREE_OPERAND (lhs, 1));
188 lexpr = compound_expr (lexpr, lhs);
189 lhs = TREE_OPERAND (lhs, 0);
192 lhs = stabilize_reference (lhs);
194 /* Save RHS, to ensure that the expression is evaluated before LHS. */
195 tree rhs = build_expr (e2);
196 tree rexpr = d_save_expr (rhs);
198 rhs = binary_op (code, build_ctype (e1->type),
199 convert_expr (lhs, e1b->type, e1->type), rexpr);
200 if (TREE_SIDE_EFFECTS (rhs))
201 rhs = compound_expr (rexpr, rhs);
203 tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
204 return compound_expr (lexpr, expr);
207 /* Implements the visitor interface to build the GCC trees of all Expression
208 AST classes emitted from the D Front-end.
209 All visit methods accept one parameter E, which holds the frontend AST
210 of the expression to compile. They also don't return any value, instead
211 generated code is cached in RESULT_ and returned from the caller. */
213 class ExprVisitor : public Visitor
215 using Visitor::visit;
217 tree result_;
218 bool constp_;
219 bool literalp_;
221 public:
222 ExprVisitor (bool constp, bool literalp)
224 this->result_ = NULL_TREE;
225 this->constp_ = constp;
226 this->literalp_ = literalp;
229 tree result (void)
231 return this->result_;
234 /* Visitor interfaces, each Expression class should have
235 overridden the default. */
237 void visit (Expression *)
239 gcc_unreachable ();
242 /* Build a conditional expression. If either the second or third
243 expression is void, then the resulting type is void. Otherwise
244 they are implicitly converted to a common type. */
246 void visit (CondExp *e)
248 tree cond = convert_for_condition (build_expr (e->econd),
249 e->econd->type);
250 tree t1 = build_expr (e->e1);
251 tree t2 = build_expr (e->e2);
253 if (e->type->ty != TY::Tvoid)
255 t1 = convert_expr (t1, e->e1->type, e->type);
256 t2 = convert_expr (t2, e->e2->type, e->type);
259 this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
262 /* Build an identity comparison expression. Operands go through the
263 usual conversions to bring them to a common type before comparison.
264 The result type is bool. */
266 void visit (IdentityExp *e)
268 tree_code code = (e->op == EXP::identity) ? EQ_EXPR : NE_EXPR;
269 Type *tb1 = e->e1->type->toBasetype ();
270 Type *tb2 = e->e2->type->toBasetype ();
272 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
273 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
275 /* For static and dynamic arrays, identity is defined as referring to
276 the same array elements and the same number of elements. */
277 tree t1 = d_array_convert (e->e1);
278 tree t2 = d_array_convert (e->e2);
279 this->result_ = d_convert (build_ctype (e->type),
280 build_boolop (code, t1, t2));
282 else if (tb1->isfloating () && tb1->ty != TY::Tvector)
284 /* For floating-point values, identity is defined as the bits in the
285 operands being identical. */
286 tree t1 = d_save_expr (build_expr (e->e1));
287 tree t2 = d_save_expr (build_expr (e->e2));
289 if (!tb1->iscomplex ())
290 this->result_ = build_float_identity (code, t1, t2);
291 else
293 /* Compare the real and imaginary parts separately. */
294 tree req = build_float_identity (code, real_part (t1),
295 real_part (t2));
296 tree ieq = build_float_identity (code, imaginary_part (t1),
297 imaginary_part (t2));
299 if (code == EQ_EXPR)
300 this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
301 else
302 this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
305 else if (TypeStruct *ts = tb1->isTypeStruct ())
307 /* For struct objects, identity is defined as bits in operands being
308 identical also. Alignment holes in structs are ignored. */
309 tree t1 = build_expr (e->e1);
310 tree t2 = build_expr (e->e2);
312 gcc_assert (same_type_p (tb1, tb2));
314 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
316 else
318 /* For operands of other types, identity is defined as being the
319 same as equality expressions. */
320 tree t1 = build_expr (e->e1);
321 tree t2 = build_expr (e->e2);
322 this->result_ = d_convert (build_ctype (e->type),
323 build_boolop (code, t1, t2));
327 /* Build an equality expression, which compare the two operands for either
328 equality or inequality. Operands go through the usual conversions to bring
329 them to a common type before comparison. The result type is bool. */
331 void visit (EqualExp *e)
333 Type *tb1 = e->e1->type->toBasetype ();
334 Type *tb2 = e->e2->type->toBasetype ();
335 tree_code code = (e->op == EXP::equal) ? EQ_EXPR : NE_EXPR;
337 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
338 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
340 /* For static and dynamic arrays, equality is defined as the lengths of
341 the arrays matching, and all the elements are equal. */
342 Type *t1elem = tb1->nextOf ()->toBasetype ();
343 Type *t2elem = tb1->nextOf ()->toBasetype ();
345 /* Check if comparisons of arrays can be optimized using memcmp.
346 This will inline EQ expressions as:
347 e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
348 Or when generating a NE expression:
349 e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */
350 if ((t1elem->isintegral () || t1elem->ty == TY::Tvoid
351 || (t1elem->ty == TY::Tstruct
352 && !t1elem->isTypeStruct ()->sym->xeq))
353 && t1elem->ty == t2elem->ty)
355 tree t1 = d_array_convert (e->e1);
356 tree t2 = d_array_convert (e->e2);
357 tree result;
359 /* Make temporaries to prevent multiple evaluations. */
360 tree t1saved = d_save_expr (t1);
361 tree t2saved = d_save_expr (t2);
363 /* Length of arrays, for comparisons done before calling memcmp. */
364 tree t1len = d_array_length (t1saved);
365 tree t2len = d_array_length (t2saved);
367 /* Reference to array data. */
368 tree t1ptr = d_array_ptr (t1saved);
369 tree t2ptr = d_array_ptr (t2saved);
371 /* Compare arrays using memcmp if possible, otherwise for structs,
372 each field is compared inline. */
373 if (t1elem->ty != TY::Tstruct
374 || identity_compare_p (t1elem->isTypeStruct ()->sym))
376 tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
378 result = build_memcmp_call (t1ptr, t2ptr, size);
379 result = build_boolop (code, result, integer_zero_node);
381 else
383 StructDeclaration *sd = t1elem->isTypeStruct ()->sym;
385 result = build_array_struct_comparison (code, sd, t1len,
386 t1ptr, t2ptr);
389 /* Check array length first before passing to memcmp.
390 For equality expressions, this becomes:
391 (e1.length == 0 || memcmp);
392 Otherwise for inequality:
393 (e1.length != 0 && memcmp); */
394 tree tsizecmp = build_boolop (code, t1len, size_zero_node);
395 if (e->op == EXP::equal)
396 result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
397 else
398 result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
400 /* Finally, check if lengths of both arrays match if dynamic.
401 The frontend should have already guaranteed that static arrays
402 have same size. */
403 if (tb1->ty == TY::Tsarray && tb2->ty == TY::Tsarray)
404 gcc_assert (tb1->size () == tb2->size ());
405 else
407 tree tlencmp = build_boolop (code, t1len, t2len);
408 if (e->op == EXP::equal)
409 result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
410 else
411 result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
414 /* Ensure left-to-right order of evaluation. */
415 if (TREE_SIDE_EFFECTS (t2))
416 result = compound_expr (t2saved, result);
418 if (TREE_SIDE_EFFECTS (t1))
419 result = compound_expr (t1saved, result);
421 this->result_ = result;
423 else
425 /* Use _adEq2() to compare each element. */
426 Type *t1array = t1elem->arrayOf ();
427 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
428 d_array_convert (e->e1),
429 d_array_convert (e->e2),
430 build_typeinfo (e, t1array));
432 if (e->op == EXP::notEqual)
433 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
435 this->result_ = result;
438 else if (TypeStruct *ts = tb1->isTypeStruct ())
440 /* Equality for struct objects means the logical product of all
441 equality results of the corresponding object fields. */
442 tree t1 = build_expr (e->e1);
443 tree t2 = build_expr (e->e2);
445 gcc_assert (same_type_p (tb1, tb2));
447 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
449 else if (tb1->ty == TY::Taarray && tb2->ty == TY::Taarray)
451 /* Use _aaEqual() for associative arrays. */
452 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
453 build_typeinfo (e, tb1),
454 build_expr (e->e1),
455 build_expr (e->e2));
457 if (e->op == EXP::notEqual)
458 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
460 this->result_ = result;
462 else
464 /* For operands of other types, equality is defined as the bit pattern
465 of the type matches exactly. */
466 tree t1 = build_expr (e->e1);
467 tree t2 = build_expr (e->e2);
469 this->result_ = d_convert (build_ctype (e->type),
470 build_boolop (code, t1, t2));
474 /* Build an `in' expression. This is a condition to see if an element
475 exists in an associative array. The result is a pointer to the
476 element, or null if false. */
478 void visit (InExp *e)
480 Type *tb2 = e->e2->type->toBasetype ();
481 Type *tkey = tb2->isTypeAArray ()->index->toBasetype ();
482 tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
484 /* Build a call to _aaInX(). */
485 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
486 build_expr (e->e2),
487 build_typeinfo (e, tkey),
488 build_address (key));
491 /* Build a relational expression. The result type is bool. */
493 void visit (CmpExp *e)
495 Type *tb1 = e->e1->type->toBasetype ();
496 Type *tb2 = e->e2->type->toBasetype ();
498 tree result;
499 tree_code code;
501 switch (e->op)
503 case EXP::lessOrEqual:
504 code = LE_EXPR;
505 break;
507 case EXP::lessThan:
508 code = LT_EXPR;
509 break;
511 case EXP::greaterOrEqual:
512 code = GE_EXPR;
513 break;
515 case EXP::greaterThan:
516 code = GT_EXPR;
517 break;
519 default:
520 gcc_unreachable ();
523 /* For static and dynamic arrays, the relational op is turned into a
524 library call. It is not lowered during codegen. */
525 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
526 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
528 error ("cannot handle comparison of type %<%s == %s%>",
529 tb1->toChars (), tb2->toChars ());
530 gcc_unreachable ();
533 /* Simple comparison. */
534 result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
535 this->result_ = d_convert (build_ctype (e->type), result);
538 /* Build a logical `and if' or `or if' expression. If the right operand
539 expression is void, then the resulting type is void. Otherwise the
540 result is bool. */
542 void visit (LogicalExp *e)
544 tree_code code = (e->op == EXP::andAnd) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
546 if (e->e2->type->toBasetype ()->ty != TY::Tvoid)
548 tree t1 = build_expr (e->e1);
549 tree t2 = build_expr (e->e2);
551 t1 = convert_for_condition (t1, e->e1->type);
552 t2 = convert_for_condition (t2, e->e2->type);
554 this->result_ = d_convert (build_ctype (e->type),
555 build_boolop (code, t1, t2));
557 else
559 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
560 tree t2 = build_expr_dtor (e->e2);
562 /* Invert condition for logical or if expression. */
563 if (e->op == EXP::orOr)
564 t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);
566 this->result_ = build_condition (build_ctype (e->type),
567 t1, t2, void_node);
571 /* Build a binary operand expression. Operands go through usual arithmetic
572 conversions to bring them to a common type before evaluating. */
574 void visit (BinExp *e)
576 tree_code code;
578 switch (e->op)
580 case EXP::add:
581 case EXP::min:
582 if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
583 || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
585 /* If the result is complex, then we can shortcut binary_op.
586 Frontend should have already validated types and sizes. */
587 tree t1 = build_expr (e->e1);
588 tree t2 = build_expr (e->e2);
590 if (e->op == EXP::min)
591 t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
593 if (e->e1->type->isreal ())
594 this->result_ = complex_expr (build_ctype (e->type), t1, t2);
595 else
596 this->result_ = complex_expr (build_ctype (e->type), t2, t1);
598 return;
600 else
601 code = (e->op == EXP::add)
602 ? PLUS_EXPR : MINUS_EXPR;
603 break;
605 case EXP::mul:
606 code = MULT_EXPR;
607 break;
609 case EXP::div:
610 /* Determine if the div expression is a lowered pointer diff operation.
611 The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */
612 if (MinExp *me = e->e1->isMinExp ())
614 if (me->e1->type->ty == TY::Tpointer
615 && me->e2->type->ty == TY::Tpointer
616 && e->e2->op == EXP::int64)
618 code = EXACT_DIV_EXPR;
619 break;
623 code = e->e1->type->isintegral ()
624 ? TRUNC_DIV_EXPR : RDIV_EXPR;
625 break;
627 case EXP::mod:
628 code = e->e1->type->isfloating ()
629 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
630 break;
632 case EXP::and_:
633 code = BIT_AND_EXPR;
634 break;
636 case EXP::or_:
637 code = BIT_IOR_EXPR;
638 break;
640 case EXP::xor_:
641 code = BIT_XOR_EXPR;
642 break;
644 case EXP::leftShift:
645 code = LSHIFT_EXPR;
646 break;
648 case EXP::rightShift:
649 code = RSHIFT_EXPR;
650 break;
652 case EXP::unsignedRightShift:
653 code = UNSIGNED_RSHIFT_EXPR;
654 break;
656 default:
657 gcc_unreachable ();
660 this->result_ = binary_op (code, build_ctype (e->type),
661 build_expr (e->e1), build_expr (e->e2));
665 /* Build a concat expression, which concatenates two or more arrays of the
666 same type, producing a dynamic array with the result. If one operand
667 is an element type, that element is converted to an array of length 1. */
669 void visit (CatExp *e)
671 Type *tb1 = e->e1->type->toBasetype ();
672 Type *tb2 = e->e2->type->toBasetype ();
673 Type *etype;
675 if (tb1->ty == TY::Tarray || tb1->ty == TY::Tsarray)
676 etype = tb1->nextOf ();
677 else
678 etype = tb2->nextOf ();
680 tree result;
682 if (e->e1->op == EXP::concatenate)
684 /* Flatten multiple concatenations to an array.
685 So the expression ((a ~ b) ~ c) becomes [a, b, c] */
686 int ndims = 2;
688 for (Expression *ex = e->e1; ex->op == EXP::concatenate;)
690 if (ex->op == EXP::concatenate)
692 ex = ex->isCatExp ()->e1;
693 ndims++;
697 /* Store all concatenation args to a temporary byte[][ndims] array. */
698 Type *targselem = Type::tint8->arrayOf ();
699 tree var = build_local_temp (make_array_type (targselem, ndims));
701 /* Loop through each concatenation from right to left. */
702 vec <constructor_elt, va_gc> *elms = NULL;
703 CatExp *ce = e;
704 int dim = ndims - 1;
706 for (Expression *oe = ce->e2; oe != NULL;
707 (ce->e1->op != EXP::concatenate
708 ? (oe = ce->e1)
709 : (ce = ce->e1->isCatExp (), oe = ce->e2)))
711 tree arg = d_array_convert (etype, oe);
712 tree index = size_int (dim);
713 CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));
715 /* Finished pushing all arrays. */
716 if (oe == ce->e1)
717 break;
719 dim -= 1;
722 /* Check there is no logic bug in constructing byte[][] of arrays. */
723 gcc_assert (dim == 0);
724 tree init = build_constructor (TREE_TYPE (var), elms);
725 var = compound_expr (modify_expr (var, init), var);
727 tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
728 size_int (ndims), build_address (var));
730 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
731 build_typeinfo (e, e->type), arrs);
733 else
735 /* Handle single concatenation (a ~ b). */
736 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
737 build_typeinfo (e, e->type),
738 d_array_convert (etype, e->e1),
739 d_array_convert (etype, e->e2));
742 this->result_ = result;
745 /* Build an assignment operator expression. The right operand is implicitly
746 converted to the type of the left operand, and assigned to it. */
748 void visit (BinAssignExp *e)
750 tree_code code;
751 Expression *e1b = e->e1;
753 switch (e->op)
755 case EXP::addAssign:
756 code = PLUS_EXPR;
757 break;
759 case EXP::minAssign:
760 code = MINUS_EXPR;
761 break;
763 case EXP::mulAssign:
764 code = MULT_EXPR;
765 break;
767 case EXP::divAssign:
768 code = e->e1->type->isintegral ()
769 ? TRUNC_DIV_EXPR : RDIV_EXPR;
770 break;
772 case EXP::modAssign:
773 code = e->e1->type->isfloating ()
774 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
775 break;
777 case EXP::andAssign:
778 code = BIT_AND_EXPR;
779 break;
781 case EXP::orAssign:
782 code = BIT_IOR_EXPR;
783 break;
785 case EXP::xorAssign:
786 code = BIT_XOR_EXPR;
787 break;
789 case EXP::powAssign:
790 gcc_unreachable ();
792 case EXP::leftShiftAssign:
793 code = LSHIFT_EXPR;
794 break;
796 case EXP::rightShiftAssign:
797 case EXP::unsignedRightShiftAssign:
798 /* Use the original lhs type before it was promoted. The left operand
799 of `>>>=' does not undergo integral promotions before shifting.
800 Strip off casts just incase anyway. */
801 while (e1b->op == EXP::cast_)
803 CastExp *ce = e1b->isCastExp ();
804 gcc_assert (same_type_p (ce->type, ce->to));
805 e1b = ce->e1;
807 code = (e->op == EXP::rightShiftAssign) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
808 break;
810 default:
811 gcc_unreachable ();
814 tree exp = binop_assignment (code, e1b, e->e2);
815 this->result_ = convert_expr (exp, e1b->type, e->type);
818 /* Build a concat assignment expression. The right operand is appended
819 to the left operand. */
821 void visit (CatAssignExp *e)
823 Type *tb1 = e->e1->type->toBasetype ();
824 Type *tb2 = e->e2->type->toBasetype ();
825 Type *etype = tb1->nextOf ()->toBasetype ();
827 /* Save the address of `e1', so it can be evaluated first.
828 As all D run-time library functions for concat assignments update `e1'
829 in-place and then return its value, the saved address can also be used as
830 the result of this expression as well. */
831 tree lhs = build_expr (e->e1);
832 tree lexpr = stabilize_expr (&lhs);
833 tree ptr = d_save_expr (build_address (lhs));
834 tree result = NULL_TREE;
836 if (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar
837 && (etype->ty == TY::Tchar || etype->ty == TY::Twchar))
839 /* Append a dchar to a char[] or wchar[]:
840 The assignment is handled by the D run-time library, so only
841 need to call `_d_arrayappend[cw]d(&e1, e2)' */
842 libcall_fn libcall = (etype->ty == TY::Tchar)
843 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
845 result = build_libcall (libcall, e->type, 2,
846 ptr, build_expr (e->e2));
848 else
850 gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray);
852 if ((tb2->ty == TY::Tarray || tb2->ty == TY::Tsarray)
853 && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
855 /* Append an array to another array:
856 The assignment is handled by the D run-time library, so only
857 need to call `_d_arrayappendT(ti, &e1, e2)' */
858 result = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
859 build_typeinfo (e->loc, e->type),
860 ptr, d_array_convert (e->e2));
862 else if (same_type_p (etype, tb2))
864 /* Append an element to an array:
865 The assignment is generated inline, so need to handle temporaries
866 here, and ensure that they are evaluated in the correct order.
868 The generated code should end up being equivalent to:
869 _d_arrayappendcTX(ti, &e1, 1)[e1.length - 1] = e2
871 tree callexp = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
872 build_typeinfo (e->loc, e->type),
873 ptr, size_one_node);
874 callexp = d_save_expr (callexp);
876 /* Assign e2 to last element. */
877 tree offexp = d_array_length (callexp);
878 offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
879 offexp, size_one_node);
881 tree ptrexp = d_array_ptr (callexp);
882 ptrexp = void_okay_p (ptrexp);
883 ptrexp = build_array_index (ptrexp, offexp);
885 /* Evaluate expression before appending. */
886 tree rhs = build_expr (e->e2);
887 tree rexpr = stabilize_expr (&rhs);
889 if (TREE_CODE (rhs) == CALL_EXPR)
890 rhs = force_target_expr (rhs);
892 result = modify_expr (build_deref (ptrexp), rhs);
893 result = compound_expr (rexpr, result);
895 else
896 gcc_unreachable ();
899 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
900 result = compound_expr (compound_expr (lexpr, ptr), result);
901 this->result_ = compound_expr (result, build_deref (ptr));
904 /* Build an assignment expression. The right operand is implicitly
905 converted to the type of the left operand, and assigned to it. */
907 void visit (AssignExp *e)
909 /* First, handle special assignment semantics. */
911 /* Look for array.length = n; */
912 if (e->e1->op == EXP::arrayLength)
914 /* This case should have been rewritten to `_d_arraysetlengthT` in the
915 semantic phase. */
916 gcc_unreachable ();
919 /* Look for exp = noreturn; */
920 if (e->e2->type->isTypeNoreturn ())
922 /* If the RHS is a `noreturn' expression, there is no point generating
923 any code for the assignment, just evaluate side effects. */
924 tree t1 = build_expr (e->e1);
925 tree t2 = build_expr (e->e2);
926 this->result_ = compound_expr (t1, t2);
927 return;
930 /* Look for array[] = n; */
931 if (e->e1->op == EXP::slice)
933 SliceExp *se = e->e1->isSliceExp ();
934 Type *stype = se->e1->type->toBasetype ();
935 Type *etype = stype->nextOf ()->toBasetype ();
937 /* Determine if we need to run postblit or dtor. */
938 bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
939 bool destructor = needs_dtor (etype);
941 if (e->memset == MemorySet::blockAssign)
943 /* Set a range of elements to one value. */
944 tree t1 = build_expr (e->e1);
945 tree t2 = build_expr (e->e2);
946 tree result;
948 /* Extract any array bounds checks from the slice expression. */
949 tree init = stabilize_expr (&t1);
950 t1 = d_save_expr (t1);
952 if ((postblit || destructor) && e->op != EXP::blit)
954 /* Need to call postblit/destructor as part of assignment.
955 Construction has already been handled by the front-end. */
956 gcc_assert (e->op != EXP::construct);
958 /* So we can call postblits on const/immutable objects. */
959 Type *tm = etype->unSharedOf ()->mutableOf ();
960 tree ti = build_typeinfo (e, tm);
962 /* Generate: _d_arraysetassign (t1.ptr, &t2, t1.length, ti); */
963 result = build_libcall (LIBCALL_ARRAYSETASSIGN, Type::tvoid, 4,
964 d_array_ptr (t1),
965 build_address (t2),
966 d_array_length (t1), ti);
968 else if (integer_zerop (t2))
970 tree size = size_mult_expr (d_array_length (t1),
971 size_int (etype->size ()));
972 result = build_memset_call (d_array_ptr (t1), size);
974 else
975 result = build_array_set (d_array_ptr (t1),
976 d_array_length (t1), t2);
978 result = compound_expr (init, result);
979 this->result_ = compound_expr (result, t1);
981 else
983 /* Perform a memcpy operation. */
984 gcc_assert (e->e2->type->ty != TY::Tpointer);
986 if (!postblit && !destructor)
988 tree t1 = d_save_expr (d_array_convert (e->e1));
989 tree t2 = d_save_expr (d_array_convert (e->e2));
991 /* References to array data. */
992 tree t1ptr = d_array_ptr (t1);
993 tree t1len = d_array_length (t1);
994 tree t2ptr = d_array_ptr (t2);
996 /* Generate: memcpy(to, from, size) */
997 tree size = size_mult_expr (t1len, size_int (etype->size ()));
998 tree result = build_memcpy_call (t1ptr, t2ptr, size);
1000 /* Insert check that array lengths match and do not overlap. */
1001 if (array_bounds_check ())
1003 /* tlencmp = (t1len == t2len) */
1004 tree t2len = d_array_length (t2);
1005 tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len);
1007 /* toverlap = (t1ptr + size <= t2ptr
1008 || t2ptr + size <= t1ptr) */
1009 tree t1ptrcmp = build_boolop (LE_EXPR,
1010 build_offset (t1ptr, size),
1011 t2ptr);
1012 tree t2ptrcmp = build_boolop (LE_EXPR,
1013 build_offset (t2ptr, size),
1014 t1ptr);
1015 tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp,
1016 t2ptrcmp);
1018 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */
1019 tree tassert = build_array_bounds_call (e->loc);
1020 tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR,
1021 tlencmp, toverlap);
1023 result = build_condition (void_type_node, tboundscheck,
1024 result, tassert);
1027 this->result_ = compound_expr (result, t1);
1029 else if ((postblit || destructor)
1030 && e->op != EXP::blit && e->op != EXP::construct)
1032 /* Generate: _d_arrayassign(ti, from, to); */
1033 this->result_ = build_libcall (LIBCALL_ARRAYASSIGN, e->type, 3,
1034 build_typeinfo (e, etype),
1035 d_array_convert (e->e2),
1036 d_array_convert (e->e1));
1038 else
1040 /* Generate: _d_arraycopy() */
1041 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
1042 size_int (etype->size ()),
1043 d_array_convert (e->e2),
1044 d_array_convert (e->e1));
1048 return;
1051 /* Look for reference initializations. */
1052 if (e->memset == MemorySet::referenceInit)
1054 gcc_assert (e->op == EXP::construct || e->op == EXP::blit);
1055 gcc_assert (e->e1->op == EXP::variable);
1057 Declaration *decl = e->e1->isVarExp ()->var;
1058 if (decl->storage_class & (STCout | STCref))
1060 tree t2 = convert_for_assignment (build_expr (e->e2),
1061 e->e2->type, e->e1->type);
1062 tree t1 = build_expr (e->e1);
1063 /* Want reference to lhs, not indirect ref. */
1064 t1 = TREE_OPERAND (t1, 0);
1065 t2 = build_address (t2);
1067 this->result_ = indirect_ref (build_ctype (e->type),
1068 build_assign (INIT_EXPR, t1, t2));
1069 return;
1073 /* Other types of assignments that may require post construction. */
1074 Type *tb1 = e->e1->type->toBasetype ();
1075 tree_code modifycode = (e->op == EXP::construct) ? INIT_EXPR : MODIFY_EXPR;
1077 /* Look for struct assignment. */
1078 if (tb1->ty == TY::Tstruct)
1080 tree t1 = build_expr (e->e1);
1081 tree t2 = convert_for_assignment (build_expr (e->e2, false, true),
1082 e->e2->type, e->e1->type);
1083 StructDeclaration *sd = tb1->isTypeStruct ()->sym;
1085 /* Look for struct = 0. */
1086 if (e->e2->op == EXP::int64)
1088 /* Use memset to fill struct. */
1089 gcc_assert (e->op == EXP::blit);
1090 tree result = build_memset_call (t1);
1092 /* Maybe set-up hidden pointer to outer scope context. */
1093 if (sd->isNested ())
1095 tree field = get_symbol_decl (sd->vthis);
1096 tree value = build_vthis (sd);
1098 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1099 result = compound_expr (result, vthis_exp);
1102 this->result_ = compound_expr (result, t1);
1104 else
1106 /* Simple struct literal assignment. */
1107 tree init = NULL_TREE;
1109 /* Fill any alignment holes in the struct using memset. */
1110 if ((e->op == EXP::construct
1111 || (e->e2->op == EXP::structLiteral && e->op == EXP::blit))
1112 && (sd->isUnionDeclaration () || !identity_compare_p (sd)))
1114 t1 = stabilize_reference (t1);
1115 init = build_memset_call (t1);
1118 /* Elide generating assignment if init is all zeroes. */
1119 if (init != NULL_TREE && initializer_zerop (t2))
1120 this->result_ = compound_expr (init, t1);
1121 else
1123 tree result = build_assign (modifycode, t1, t2);
1124 this->result_ = compound_expr (init, result);
1128 return;
1131 /* Look for static array assignment. */
1132 if (tb1->ty == TY::Tsarray)
1134 /* Look for array = 0. */
1135 if (e->e2->op == EXP::int64)
1137 /* Use memset to fill the array. */
1138 gcc_assert (e->op == EXP::blit);
1139 this->result_ = build_memset_call (build_expr (e->e1));
1140 return;
1143 Type *etype = tb1->nextOf ();
1144 gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray);
1146 /* Determine if we need to run postblit. */
1147 const bool postblit = needs_postblit (etype);
1148 const bool destructor = needs_dtor (etype);
1149 const bool lvalue = lvalue_p (e->e2);
1151 /* Optimize static array assignment with array literal. Even if the
1152 elements in rhs are all rvalues and don't have to call postblits,
1153 this assignment should call dtors on old assigned elements. */
1154 if ((!postblit && !destructor)
1155 || (e->op == EXP::construct && e->e2->op == EXP::arrayLiteral)
1156 || (e->op == EXP::construct && !lvalue && postblit)
1157 || (e->op == EXP::blit || e->e1->type->size () == 0))
1159 tree t1 = build_expr (e->e1);
1160 tree t2 = convert_for_assignment (build_expr (e->e2),
1161 e->e2->type, e->e1->type);
1163 this->result_ = build_assign (modifycode, t1, t2);
1164 return;
1167 /* All other kinds of lvalue or rvalue static array assignment.
1168 Array construction has already been handled by the front-end. */
1169 gcc_assert (e->op != EXP::construct);
1171 /* Generate: _d_arrayassign_l()
1172 or: _d_arrayassign_r() */
1173 libcall_fn libcall = (lvalue)
1174 ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
1175 tree elembuf = build_local_temp (build_ctype (etype));
1176 Type *arrtype = (e->type->ty == TY::Tsarray)
1177 ? etype->arrayOf () : e->type;
1178 tree result = build_libcall (libcall, arrtype, 4,
1179 build_typeinfo (e, etype),
1180 d_array_convert (e->e2),
1181 d_array_convert (e->e1),
1182 build_address (elembuf));
1184 /* Cast the libcall result back to a static array. */
1185 if (e->type->ty == TY::Tsarray)
1186 result = indirect_ref (build_ctype (e->type),
1187 d_array_ptr (result));
1189 this->result_ = result;
1190 return;
1193 /* Simple assignment. */
1194 tree t1 = build_expr (e->e1);
1195 tree t2 = convert_for_assignment (build_expr (e->e2),
1196 e->e2->type, e->e1->type);
1198 this->result_ = build_assign (modifycode, t1, t2);
1201 /* Build a throw expression. */
1203 void visit (ThrowExp *e)
1205 tree arg = build_expr_dtor (e->e1);
1206 this->result_ = build_libcall (LIBCALL_THROW, Type::tvoid, 1, arg);
1209 /* Build a postfix expression. */
1211 void visit (PostExp *e)
1213 tree result;
1215 if (e->op == EXP::plusPlus)
1217 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1218 build_expr (e->e1), build_expr (e->e2));
1220 else if (e->op == EXP::minusMinus)
1222 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1223 build_expr (e->e1), build_expr (e->e2));
1225 else
1226 gcc_unreachable ();
1228 TREE_SIDE_EFFECTS (result) = 1;
1229 this->result_ = result;
1232 /* Build an index expression. */
1234 void visit (IndexExp *e)
1236 Type *tb1 = e->e1->type->toBasetype ();
1238 if (tb1->ty == TY::Taarray)
1240 /* Get the key for the associative array. */
1241 Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
1242 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1243 libcall_fn libcall;
1244 tree tinfo, ptr;
1246 if (e->modifiable)
1248 libcall = LIBCALL_AAGETY;
1249 ptr = build_address (build_expr (e->e1));
1250 tinfo = build_typeinfo (e, tb1->unSharedOf ()->mutableOf ());
1252 else
1254 libcall = LIBCALL_AAGETRVALUEX;
1255 ptr = build_expr (e->e1);
1256 tinfo = build_typeinfo (e, tkey);
1259 /* Index the associative array. */
1260 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1261 ptr, tinfo,
1262 size_int (tb1->nextOf ()->size ()),
1263 build_address (key));
1265 if (!e->indexIsInBounds && array_bounds_check ())
1267 tree tassert = build_array_bounds_call (e->loc);
1269 result = d_save_expr (result);
1270 result = build_condition (TREE_TYPE (result),
1271 d_truthvalue_conversion (result),
1272 result, tassert);
1275 this->result_ = indirect_ref (build_ctype (e->type), result);
1277 else
1279 /* Get the data pointer and length for static and dynamic arrays. */
1280 tree array = d_save_expr (build_expr (e->e1));
1281 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1283 tree length = NULL_TREE;
1284 if (tb1->ty != TY::Tpointer)
1285 length = get_array_length (array, tb1);
1286 else
1287 gcc_assert (e->lengthVar == NULL);
1289 /* The __dollar variable just becomes a placeholder for the
1290 actual length. */
1291 if (e->lengthVar)
1292 e->lengthVar->csym = length;
1294 /* Generate the index. */
1295 tree index = build_expr (e->e2);
1297 /* If it's a static array and the index is constant, the front end has
1298 already checked the bounds. */
1299 if (tb1->ty != TY::Tpointer)
1300 index = build_bounds_index_condition (e, index, length);
1302 /* Index the .ptr. */
1303 ptr = void_okay_p (ptr);
1304 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1305 build_array_index (ptr, index));
1309 /* Build a comma expression. The type is the type of the right operand. */
1311 void visit (CommaExp *e)
1313 tree t1 = build_expr (e->e1);
1314 tree t2 = build_expr (e->e2);
1315 tree type = e->type ? build_ctype (e->type) : void_type_node;
1317 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1320 /* Build an array length expression. Returns the number of elements
1321 in the array. The result is of type size_t. */
1323 void visit (ArrayLengthExp *e)
1325 if (e->e1->type->toBasetype ()->ty == TY::Tarray)
1326 this->result_ = d_array_length (build_expr (e->e1));
1327 else
1329 /* Static arrays have already been handled by the front-end. */
1330 error ("unexpected type for array length: %qs", e->type->toChars ());
1331 this->result_ = error_mark_node;
1335 /* Build a delegate pointer expression. This will return the frame
1336 pointer value as a type void*. */
1338 void visit (DelegatePtrExp *e)
1340 tree t1 = build_expr (e->e1);
1341 this->result_ = delegate_object (t1);
1344 /* Build a delegate function pointer expression. This will return the
1345 function pointer value as a function type. */
1347 void visit (DelegateFuncptrExp *e)
1349 tree t1 = build_expr (e->e1);
1350 this->result_ = delegate_method (t1);
1353 /* Build a slice expression. */
1355 void visit (SliceExp *e)
1357 Type *tb = e->type->toBasetype ();
1358 Type *tb1 = e->e1->type->toBasetype ();
1359 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray);
1361 /* Use convert-to-dynamic-array code if possible. */
1362 if (!e->lwr)
1364 tree result = build_expr (e->e1);
1365 if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
1366 result = convert_expr (result, e->e1->type, e->type);
1368 this->result_ = result;
1369 return;
1371 else
1372 gcc_assert (e->upr != NULL);
1374 /* Get the data pointer and length for static and dynamic arrays. */
1375 tree array = d_save_expr (build_expr (e->e1));
1376 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1377 tree length = NULL_TREE;
1379 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1380 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1381 if (tb1->ty != TY::Tpointer)
1382 length = get_array_length (array, tb1);
1383 else
1384 gcc_assert (e->lengthVar == NULL);
1386 /* The __dollar variable just becomes a placeholder for the
1387 actual length. */
1388 if (e->lengthVar)
1389 e->lengthVar->csym = length;
1391 /* Generate upper and lower bounds. */
1392 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1393 tree upr_tree = d_save_expr (build_expr (e->upr));
1395 /* If the upper bound has any side effects, then the lower bound should be
1396 copied to a temporary always. */
1397 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1398 lwr_tree = save_expr (lwr_tree);
1400 /* Adjust the .ptr offset. */
1401 if (!integer_zerop (lwr_tree))
1403 tree ptrtype = TREE_TYPE (ptr);
1404 ptr = build_array_index (void_okay_p (ptr), lwr_tree);
1405 ptr = build_nop (ptrtype, ptr);
1408 /* Nothing more to do for static arrays, their bounds checking has been
1409 done at compile-time. */
1410 if (tb->ty == TY::Tsarray)
1412 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1413 return;
1415 else
1416 gcc_assert (tb->ty == TY::Tarray);
1418 /* Generate bounds checking code. */
1419 tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree,
1420 length);
1421 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1422 this->result_ = compound_expr (array, result);
1425 /* Build a cast expression, which converts the given unary expression to the
1426 type of result. */
1428 void visit (CastExp *e)
1430 Type *ebtype = e->e1->type->toBasetype ();
1431 Type *tbtype = e->to->toBasetype ();
1432 tree result = build_expr (e->e1, this->constp_, this->literalp_);
1434 /* Just evaluate e1 if it has any side effects. */
1435 if (tbtype->ty == TY::Tvoid)
1436 this->result_ = build_nop (build_ctype (tbtype), result);
1437 else
1438 this->result_ = convert_for_rvalue (result, ebtype, tbtype);
1441 /* Build a delete expression. */
1443 void visit (DeleteExp *e)
1445 tree t1 = build_expr (e->e1);
1446 Type *tb1 = e->e1->type->toBasetype ();
1448 if (tb1->ty == TY::Tclass)
1450 /* For class object references, if there is a destructor for that class,
1451 the destructor is called for the object instance. */
1452 gcc_assert (e->e1->op == EXP::variable);
1454 VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
1455 gcc_assert (v && v->onstack ());
1457 libcall_fn libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1458 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1460 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1461 return;
1463 else
1465 error ("don%'t know how to delete %qs", e->e1->toChars ());
1466 this->result_ = error_mark_node;
1470 /* Build a remove expression, which removes a particular key from an
1471 associative array. */
1473 void visit (RemoveExp *e)
1475 /* Check that the array is actually an associative array. */
1476 if (e->e1->type->toBasetype ()->ty == TY::Taarray)
1478 Type *tb = e->e1->type->toBasetype ();
1479 Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
1480 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1482 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1483 build_expr (e->e1),
1484 build_typeinfo (e, tkey),
1485 build_address (index));
1487 else
1489 error ("%qs is not an associative array", e->e1->toChars ());
1490 this->result_ = error_mark_node;
1494 /* Build an unary not expression. */
1496 void visit (NotExp *e)
1498 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1499 /* Need to convert to boolean type or this will fail. */
1500 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1502 this->result_ = d_convert (build_ctype (e->type), result);
1505 /* Build a compliment expression, where all the bits in the value are
1506 complemented. Note: unlike in C, the usual integral promotions
1507 are not performed prior to the complement operation. */
1509 void visit (ComExp *e)
1511 TY ty1 = e->e1->type->toBasetype ()->ty;
1512 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1514 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1515 build_expr (e->e1));
1518 /* Build an unary negation expression. */
1520 void visit (NegExp *e)
1522 TY ty1 = e->e1->type->toBasetype ()->ty;
1523 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
1525 tree type = build_ctype (e->type);
1526 tree expr = build_expr (e->e1);
1528 /* If the operation needs excess precision. */
1529 tree eptype = excess_precision_type (type);
1530 if (eptype != NULL_TREE)
1531 expr = d_convert (eptype, expr);
1532 else
1533 eptype = type;
1535 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1536 this->result_ = d_convert (type, ret);
1539 /* Build a pointer index expression. */
1541 void visit (PtrExp *e)
1543 Type *tnext = NULL;
1544 size_t offset;
1545 tree result;
1547 if (e->e1->op == EXP::add)
1549 AddExp *ae = e->e1->isAddExp ();
1550 if (ae->e1->op == EXP::address
1551 && ae->e2->isConst () && ae->e2->type->isintegral ())
1553 Expression *ex = ae->e1->isAddrExp ()->e1;
1554 tnext = ex->type->toBasetype ();
1555 result = build_expr (ex);
1556 offset = ae->e2->toUInteger ();
1559 else if (e->e1->op == EXP::symbolOffset)
1561 SymOffExp *se = e->e1->isSymOffExp ();
1562 if (!declaration_reference_p (se->var))
1564 tnext = se->var->type->toBasetype ();
1565 result = get_decl_tree (se->var);
1566 offset = se->offset;
1570 /* Produce better code by converting *(#record + n) to
1571 COMPONENT_REFERENCE. Otherwise, the variable will always be
1572 allocated in memory because its address is taken. */
1573 if (tnext && tnext->ty == TY::Tstruct)
1575 StructDeclaration *sd = tnext->isTypeStruct ()->sym;
1577 for (size_t i = 0; i < sd->fields.length; i++)
1579 VarDeclaration *field = sd->fields[i];
1581 if (field->offset == offset
1582 && same_type_p (field->type, e->type))
1584 /* Catch errors, backend will ICE otherwise. */
1585 if (error_operand_p (result))
1586 this->result_ = result;
1587 else
1589 result = component_ref (result, get_symbol_decl (field));
1590 this->result_ = result;
1592 return;
1594 else if (field->offset > offset)
1595 break;
1599 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1602 /* Build an unary address expression. */
1604 void visit (AddrExp *e)
1606 tree type = build_ctype (e->type);
1607 tree exp;
1609 /* The frontend optimizer can convert const symbol into a struct literal.
1610 Taking the address of a struct literal is otherwise illegal. */
1611 if (e->e1->op == EXP::structLiteral)
1613 StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
1614 gcc_assert (sle != NULL);
1616 /* Build the reference symbol, the decl is built first as the
1617 initializer may have recursive references. */
1618 if (!sle->sym)
1620 sle->sym = build_artificial_decl (build_ctype (sle->type),
1621 NULL_TREE, "S");
1622 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1623 d_pushdecl (sle->sym);
1624 rest_of_decl_compilation (sle->sym, 1, 0);
1627 exp = sle->sym;
1629 else
1630 exp = build_expr (e->e1, this->constp_, this->literalp_);
1632 TREE_CONSTANT (exp) = 0;
1633 this->result_ = d_convert (type, build_address (exp));
1636 /* Build a function call expression. */
1638 void visit (CallExp *e)
1640 Type *tb = e->e1->type->toBasetype ();
1641 Expression *e1b = e->e1;
1643 tree callee = NULL_TREE;
1644 tree object = NULL_TREE;
1645 tree cleanup = NULL_TREE;
1646 tree returnvalue = NULL_TREE;
1647 TypeFunction *tf = NULL;
1649 /* Calls to delegates can sometimes look like this. */
1650 if (e1b->op == EXP::comma)
1652 e1b = e1b->isCommaExp ()->e2;
1653 gcc_assert (e1b->op == EXP::variable);
1655 Declaration *var = e1b->isVarExp ()->var;
1656 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1659 if (e1b->op == EXP::dotVariable && tb->ty != TY::Tdelegate)
1661 DotVarExp *dve = e1b->isDotVarExp ();
1663 /* Don't modify the static initializer for struct literals. */
1664 if (dve->e1->op == EXP::structLiteral)
1666 StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
1667 sle->useStaticInit = false;
1670 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1671 if (fd != NULL)
1673 /* Get the correct callee from the DotVarExp object. */
1674 tree fndecl = get_symbol_decl (fd);
1675 AggregateDeclaration *ad = fd->isThis ();
1677 /* Static method; ignore the object instance. */
1678 if (!ad)
1679 callee = build_address (fndecl);
1680 else
1682 tree thisexp = build_expr (dve->e1);
1684 /* When constructing temporaries, if the constructor throws,
1685 then the object is destructed even though it is not a fully
1686 constructed object yet. And so this call will need to be
1687 moved inside the TARGET_EXPR_INITIAL slot. */
1688 if (fd->isCtorDeclaration ()
1689 && TREE_CODE (thisexp) == COMPOUND_EXPR
1690 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1691 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1693 cleanup = TREE_OPERAND (thisexp, 0);
1694 thisexp = TREE_OPERAND (thisexp, 1);
1697 if (TREE_CODE (thisexp) == CONSTRUCTOR)
1698 thisexp = force_target_expr (thisexp);
1700 /* Want reference to `this' object. */
1701 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1702 thisexp = build_address (thisexp);
1704 /* Make the callee a virtual call. */
1705 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1707 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1708 tree thistype = build_ctype (ad->handleType ());
1709 thisexp = build_nop (thistype, d_save_expr (thisexp));
1710 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1712 else
1713 fndecl = build_address (fndecl);
1715 /* C++ constructors return void, even though front-end semantic
1716 treats them as implicitly returning `this'. Set returnvalue
1717 to override the result of this expression. */
1718 if (fd->isCtorDeclaration ())
1720 thisexp = d_save_expr (thisexp);
1721 returnvalue = thisexp;
1724 callee = build_method_call (fndecl, thisexp, fd->type);
1729 if (callee == NULL_TREE)
1730 callee = build_expr (e1b);
1732 if (METHOD_CALL_EXPR (callee))
1734 /* This could be a delegate expression (TY == Tdelegate), but not
1735 actually a delegate variable. */
1736 if (e1b->op == EXP::dotVariable)
1738 /* This gets the true function type, getting the function type
1739 from e1->type can sometimes be incorrect, such as when calling
1740 a `ref' return function. */
1741 tf = get_function_type (e1b->isDotVarExp ()->var->type);
1743 else
1744 tf = get_function_type (tb);
1746 extract_from_method_call (callee, callee, object);
1748 else if (tb->ty == TY::Tdelegate)
1750 /* Delegate call, extract .object and .funcptr from var. */
1751 callee = d_save_expr (callee);
1752 tf = get_function_type (tb);
1753 object = delegate_object (callee);
1754 callee = delegate_method (callee);
1756 else if (e1b->op == EXP::variable)
1758 FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
1759 gcc_assert (fd != NULL);
1760 tf = get_function_type (fd->type);
1762 if (fd->isNested ())
1764 /* Maybe re-evaluate symbol storage treating `fd' as public. */
1765 if (call_by_alias_p (d_function_chain->function, fd))
1766 TREE_PUBLIC (callee) = 1;
1768 object = get_frame_for_symbol (fd);
1770 else if (fd->needThis ())
1772 error_at (make_location_t (e1b->loc),
1773 "need %<this%> to access member %qs", fd->toChars ());
1774 /* Continue compiling... */
1775 object = null_pointer_node;
1778 else
1780 /* Normal direct function call. */
1781 tf = get_function_type (tb);
1784 gcc_assert (tf != NULL);
1786 /* Now we have the type, callee and maybe object reference,
1787 build the call expression. */
1788 tree exp = d_build_call (tf, callee, object, e->arguments);
1790 if (returnvalue != NULL_TREE)
1791 exp = compound_expr (exp, returnvalue);
1793 if (tf->isref ())
1794 exp = build_deref (exp);
1796 /* Some library calls are defined to return a generic type.
1797 this->type is the real type we want to return. */
1798 if (e->type->isTypeBasic ())
1799 exp = d_convert (build_ctype (e->type), exp);
1801 /* If this call was found to be a constructor for a temporary with a
1802 cleanup, then move the call inside the TARGET_EXPR. */
1803 if (cleanup != NULL_TREE)
1805 tree init = TARGET_EXPR_INITIAL (cleanup);
1806 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1808 /* Keep the return value outside the TARGET_EXPR. */
1809 if (returnvalue != NULL_TREE)
1810 cleanup = compound_expr (cleanup, TREE_OPERAND (exp, 1));
1812 exp = cleanup;
1815 this->result_ = exp;
1818 /* Build a delegate expression. */
1820 void visit (DelegateExp *e)
1822 if (e->func->semanticRun == PASS::semantic3done)
1824 /* Add the function as nested function if it belongs to this module.
1825 ie: it is a member of this module, or it is a template instance. */
1826 Dsymbol *owner = e->func->toParent ();
1827 while (!owner->isTemplateInstance () && owner->toParent ())
1828 owner = owner->toParent ();
1829 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1830 build_decl_tree (e->func);
1833 tree fndecl;
1834 tree object;
1836 if (e->func->isNested () && !e->func->isThis ())
1838 if (e->e1->op == EXP::null_)
1839 object = build_expr (e->e1);
1840 else
1841 object = get_frame_for_symbol (e->func);
1843 fndecl = build_address (get_symbol_decl (e->func));
1845 else
1847 if (!e->func->isThis ())
1849 error ("delegates are only for non-static functions");
1850 this->result_ = error_mark_node;
1851 return;
1854 object = build_expr (e->e1);
1856 /* Want reference to `this' object. */
1857 if (e->e1->type->ty != TY::Tclass && e->e1->type->ty != TY::Tpointer)
1858 object = build_address (object);
1860 /* Object reference could be the outer `this' field of a class or
1861 closure of type `void*'. Cast it to the right type. */
1862 if (e->e1->type->ty == TY::Tclass)
1863 object = d_convert (build_ctype (e->e1->type), object);
1865 fndecl = get_symbol_decl (e->func);
1867 /* Get pointer to function out of the virtual table. */
1868 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1869 && e->e1->op != EXP::super_ && e->e1->op != EXP::dotType)
1871 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1872 object = d_save_expr (object);
1873 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1875 else
1876 fndecl = build_address (fndecl);
1879 this->result_ = build_method_call (fndecl, object, e->type);
1882 /* Build a type component expression. */
1884 void visit (DotTypeExp *e)
1886 /* Just a pass through to underlying expression. */
1887 this->result_ = build_expr (e->e1);
1890 /* Build a component reference expression. */
1892 void visit (DotVarExp *e)
1894 VarDeclaration *vd = e->var->isVarDeclaration ();
1896 /* This could also be a function, but relying on that being taken
1897 care of by the visitor interface for CallExp. */
1898 if (vd != NULL)
1900 if (!vd->isField ())
1901 this->result_ = get_decl_tree (vd);
1902 else
1904 tree object = build_expr (e->e1);
1905 Type *tb = e->e1->type->toBasetype ();
1907 if (tb->ty != TY::Tstruct)
1908 object = build_deref (object);
1910 /* __complex is represented as a struct in the front-end, but
1911 underlying is really a complex type. */
1912 if (e->e1->type->ty == TY::Tenum
1913 && e->e1->type->isTypeEnum ()->sym->isSpecial ())
1914 object = underlying_complex_expr (build_ctype (tb), object);
1916 this->result_ = component_ref (object, get_symbol_decl (vd));
1919 else
1921 error ("%qs is not a field, but a %qs",
1922 e->var->toChars (), e->var->kind ());
1923 this->result_ = error_mark_node;
1927 /* Build an assert expression, used to declare conditions that must hold at
1928 that a given point in the program. */
1930 void visit (AssertExp *e)
1932 Type *tb1 = e->e1->type->toBasetype ();
1933 tree arg = build_expr (e->e1);
1934 tree tmsg = NULL_TREE;
1935 tree assert_pass = void_node;
1936 tree assert_fail;
1938 if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ())
1940 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1941 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1942 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1943 libcall_fn libcall;
1945 if (e->msg)
1947 tmsg = build_expr_dtor (e->msg);
1948 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1950 else
1951 libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP;
1953 /* Build a call to _d_assert(). */
1954 assert_fail = build_assert_call (e->loc, libcall, tmsg);
1956 if (global.params.useInvariants == CHECKENABLEon)
1958 /* If the condition is a D class or struct object with an invariant,
1959 call it if the condition result is true. */
1960 if (tb1->ty == TY::Tclass)
1962 ClassDeclaration *cd = tb1->isClassHandle ();
1963 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
1965 arg = d_save_expr (arg);
1966 assert_pass = build_libcall (LIBCALL_INVARIANT,
1967 Type::tvoid, 1, arg);
1970 else if (tb1->ty == TY::Tpointer
1971 && tb1->nextOf ()->ty == TY::Tstruct)
1973 StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
1974 if (sd->inv != NULL)
1976 Expressions args;
1977 arg = d_save_expr (arg);
1978 assert_pass = d_build_call_expr (sd->inv, arg, &args);
1983 else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
1985 /* Generate: __builtin_trap() */
1986 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
1987 assert_fail = build_call_expr (fn, 0);
1989 else
1991 /* Assert contracts are turned off. */
1992 this->result_ = void_node;
1993 return;
1996 /* Build condition that we are asserting in this contract. */
1997 tree condition = convert_for_condition (arg, e->e1->type);
1999 /* We expect the condition to always be true, as what happens if an assert
2000 contract is false is undefined behavior. */
2001 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
2002 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
2003 tree pred_type = TREE_VALUE (arg_types);
2004 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
2006 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
2007 build_int_cst (expected_type, 1));
2008 condition = d_truthvalue_conversion (condition);
2010 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
2013 /* Build a declaration expression. */
2015 void visit (DeclarationExp *e)
2017 /* Compile the declaration. */
2018 push_stmt_list ();
2019 build_decl_tree (e->declaration);
2020 tree result = pop_stmt_list ();
2022 /* Construction of an array for typesafe-variadic function arguments
2023 can cause an empty STMT_LIST here. This can causes problems
2024 during gimplification. */
2025 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
2026 result = build_empty_stmt (input_location);
2028 this->result_ = result;
2031 /* Build a typeid expression. Returns an instance of class TypeInfo
2032 corresponding to. */
2034 void visit (TypeidExp *e)
2036 if (Type *tid = isType (e->obj))
2038 tree ti = build_typeinfo (e, tid);
2040 /* If the typeinfo is at an offset. */
2041 if (tid->vtinfo->offset)
2042 ti = build_offset (ti, size_int (tid->vtinfo->offset));
2044 this->result_ = build_nop (build_ctype (e->type), ti);
2046 else if (Expression *tid = isExpression (e->obj))
2048 Type *type = tid->type->toBasetype ();
2049 assert (type->ty == TY::Tclass);
2051 /* Generate **classptr to get the classinfo. */
2052 tree ci = build_expr (tid);
2053 ci = indirect_ref (ptr_type_node, ci);
2054 ci = indirect_ref (ptr_type_node, ci);
2056 /* Add extra indirection for interfaces. */
2057 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
2058 ci = indirect_ref (ptr_type_node, ci);
2060 this->result_ = build_nop (build_ctype (e->type), ci);
2062 else
2063 gcc_unreachable ();
2066 /* Build a function/lambda expression. */
2068 void visit (FuncExp *e)
2070 Type *ftype = e->type->toBasetype ();
2072 /* This check is for lambda's, remove `vthis' as function isn't nested. */
2073 if (e->fd->tok == TOK::reserved && ftype->ty == TY::Tpointer)
2075 e->fd->tok = TOK::function_;
2076 e->fd->vthis = NULL;
2079 /* Compile the function literal body. */
2080 build_decl_tree (e->fd);
2082 /* If nested, this will be a trampoline. */
2083 if (e->fd->isNested ())
2085 tree func = build_address (get_symbol_decl (e->fd));
2086 tree object;
2088 if (this->constp_)
2090 /* Static delegate variables have no context pointer. */
2091 object = null_pointer_node;
2092 this->result_ = build_method_call (func, object, e->fd->type);
2093 TREE_CONSTANT (this->result_) = 1;
2095 else
2097 object = get_frame_for_symbol (e->fd);
2098 this->result_ = build_method_call (func, object, e->fd->type);
2101 else
2103 this->result_ = build_nop (build_ctype (e->type),
2104 build_address (get_symbol_decl (e->fd)));
2108 /* Build a halt expression. */
2110 void visit (HaltExp *)
2112 /* Should we use trap() or abort()? */
2113 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2114 this->result_ = build_call_expr (ttrap, 0);
2117 /* Build a symbol pointer offset expression. */
2119 void visit (SymOffExp *e)
2121 /* Build the address and offset of the symbol. */
2122 size_t soffset = e->isSymOffExp ()->offset;
2123 tree result = get_decl_tree (e->var);
2124 TREE_USED (result) = 1;
2126 if (declaration_reference_p (e->var))
2127 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2128 else
2129 result = build_address (result);
2131 if (!soffset)
2132 result = d_convert (build_ctype (e->type), result);
2133 else
2135 tree offset = size_int (soffset);
2136 result = build_nop (build_ctype (e->type),
2137 build_offset (result, offset));
2140 this->result_ = result;
2143 /* Build a variable expression. */
2145 void visit (VarExp *e)
2147 if (e->var->needThis ())
2149 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2150 this->result_ = error_mark_node;
2151 return;
2153 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2155 /* __ctfe is always false at run-time. */
2156 this->result_ = integer_zero_node;
2157 return;
2160 /* This check is same as is done in FuncExp for lambdas. */
2161 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2162 if (fld != NULL)
2164 if (fld->tok == TOK::reserved)
2166 fld->tok = TOK::function_;
2167 fld->vthis = NULL;
2170 /* Compiler the function literal body. */
2171 build_decl_tree (fld);
2174 if (this->constp_)
2176 /* Want the initializer, not the expression. */
2177 VarDeclaration *var = e->var->isVarDeclaration ();
2178 SymbolDeclaration *sdecl = e->var->isSymbolDeclaration ();
2179 tree init = NULL_TREE;
2181 if (var && (var->isConst () || var->isImmutable ())
2182 && e->type->toBasetype ()->ty != TY::Tsarray && var->_init)
2184 if (var->inuse)
2185 error_at (make_location_t (e->loc), "recursive reference %qs",
2186 e->toChars ());
2187 else
2189 var->inuse++;
2190 init = build_expr (initializerToExpression (var->_init), true);
2191 var->inuse--;
2194 else if (sdecl && sdecl->dsym)
2196 if (StructDeclaration *sd = sdecl->dsym->isStructDeclaration ())
2197 init = layout_struct_initializer (sd);
2198 else if (ClassDeclaration *cd = sdecl->dsym->isClassDeclaration ())
2199 init = layout_class_initializer (cd);
2200 else
2201 gcc_unreachable ();
2203 else
2204 error_at (make_location_t (e->loc), "non-constant expression %qs",
2205 e->toChars ());
2207 if (init != NULL_TREE)
2208 this->result_ = init;
2209 else
2210 this->result_ = error_mark_node;
2212 else
2214 tree result = get_decl_tree (e->var);
2215 TREE_USED (result) = 1;
2217 /* The variable expression generated for `__traits(initSymbol)'. */
2218 if (SymbolDeclaration *sd = e->var->isSymbolDeclaration ())
2220 if (e->type->isTypeDArray ())
2222 /* Generate a slice for non-zero initialized aggregates,
2223 otherwise create an empty array. */
2224 gcc_assert (e->type == Type::tvoid->arrayOf ()->constOf ());
2226 tree type = build_ctype (e->type);
2227 tree length = size_int (sd->dsym->structsize);
2228 tree ptr = (sd->dsym->isStructDeclaration ()
2229 && sd->dsym->type->isZeroInit (e->loc))
2230 ? null_pointer_node : build_address (result);
2232 this->result_ = d_array_value (type, length, ptr);
2233 return;
2237 /* For variables that are references - currently only out/inout
2238 arguments; objects don't count - evaluating the variable means
2239 we want what it refers to. */
2240 if (declaration_reference_p (e->var))
2241 result = indirect_ref (build_ctype (e->var->type), result);
2243 this->result_ = result;
2247 /* Build a this variable expression. */
2249 void visit (ThisExp *e)
2251 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2252 tree result = NULL_TREE;
2254 if (e->var)
2255 result = get_decl_tree (e->var);
2256 else
2258 gcc_assert (fd && fd->vthis);
2259 result = get_decl_tree (fd->vthis);
2262 if (e->type->ty == TY::Tstruct)
2263 result = build_deref (result);
2265 this->result_ = result;
2268 /* Build a new expression, which allocates memory either on the garbage
2269 collected heap or by using a class or struct specific allocator. */
2271 void visit (NewExp *e)
2273 Type *tb = e->type->toBasetype ();
2274 tree result;
2276 if (tb->ty == TY::Tclass)
2278 /* Allocating a new class. */
2279 tb = e->newtype->toBasetype ();
2281 ClassDeclaration *cd = tb->isTypeClass ()->sym;
2282 tree type = build_ctype (tb);
2283 tree setup_exp = NULL_TREE;
2284 tree new_call;
2286 if (e->onstack)
2288 /* If being used as an initializer for a local variable with scope
2289 storage class, then the instance is allocated on the stack
2290 rather than the heap or using the class specific allocator. */
2291 tree var = build_local_temp (TREE_TYPE (type));
2292 new_call = build_nop (type, build_address (var));
2293 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2295 else
2297 /* Generate: _d_newclass() */
2298 tree arg = build_address (get_classinfo_decl (cd));
2299 libcall_fn libcall = (global.params.ehnogc && e->thrownew)
2300 ? LIBCALL_NEWTHROW : LIBCALL_NEWCLASS;
2301 new_call = build_libcall (libcall, tb, 1, arg);
2304 /* Set the context pointer for nested classes. */
2305 if (cd->isNested ())
2307 tree field = get_symbol_decl (cd->vthis);
2308 tree value = NULL_TREE;
2310 if (e->thisexp)
2312 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2313 /* The class or function we're nested in. */
2314 Dsymbol *outer = cd->toParentLocal ();
2316 value = build_expr (e->thisexp);
2318 if (outer != tcd)
2320 ClassDeclaration *ocd = outer->isClassDeclaration ();
2321 int offset = 0;
2322 gcc_assert (ocd->isBaseOf (tcd, &offset));
2323 /* Could just add offset... */
2324 value = convert_expr (value, e->thisexp->type, ocd->type);
2327 else
2328 value = build_vthis (cd);
2330 if (value != NULL_TREE)
2332 /* Generate: (new())->vthis = this; */
2333 new_call = d_save_expr (new_call);
2334 field = component_ref (build_deref (new_call), field);
2335 setup_exp = compound_expr (setup_exp,
2336 modify_expr (field, value));
2339 new_call = compound_expr (setup_exp, new_call);
2341 /* Call the class constructor. */
2342 if (e->member)
2343 result = d_build_call_expr (e->member, new_call, e->arguments);
2344 else
2345 result = new_call;
2347 if (e->argprefix)
2348 result = compound_expr (build_expr (e->argprefix), result);
2350 else if (tb->ty == TY::Tpointer
2351 && tb->nextOf ()->toBasetype ()->ty == TY::Tstruct)
2353 /* Allocating memory for a new struct. */
2354 Type *htype = e->newtype->toBasetype ();
2355 gcc_assert (!e->onstack);
2357 TypeStruct *stype = htype->isTypeStruct ();
2358 StructDeclaration *sd = stype->sym;
2359 tree new_call;
2361 /* Cannot new an opaque struct. */
2362 if (sd->size (e->loc) == 0)
2364 this->result_ = d_convert (build_ctype (e->type),
2365 integer_zero_node);
2366 return;
2369 /* Generate: _d_newitemT() */
2370 libcall_fn libcall = htype->isZeroInit ()
2371 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2372 tree arg = build_typeinfo (e, e->newtype);
2373 new_call = build_libcall (libcall, tb, 1, arg);
2375 if (e->member || !e->arguments)
2377 /* Set the context pointer for nested structs. */
2378 if (sd->isNested ())
2380 tree value = build_vthis (sd);
2381 tree field = get_symbol_decl (sd->vthis);
2382 tree type = build_ctype (stype);
2384 new_call = d_save_expr (new_call);
2385 field = component_ref (indirect_ref (type, new_call), field);
2386 new_call = compound_expr (modify_expr (field, value), new_call);
2389 /* Call the struct constructor. */
2390 if (e->member)
2391 result = d_build_call_expr (e->member, new_call, e->arguments);
2392 else
2393 result = new_call;
2395 else
2397 /* If we have a user supplied initializer, then set-up with a
2398 struct literal. */
2399 if (e->arguments != NULL && sd->fields.length != 0)
2401 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2402 e->arguments,
2403 htype);
2404 new_call = d_save_expr (new_call);
2405 se->type = sd->type;
2406 se->sym = new_call;
2407 result = compound_expr (build_expr (se), new_call);
2409 else
2410 result = new_call;
2413 if (e->argprefix)
2414 result = compound_expr (build_expr (e->argprefix), result);
2416 else if (tb->ty == TY::Tarray)
2418 /* Allocating memory for a new D array. */
2419 tb = e->newtype->toBasetype ();
2420 TypeDArray *tarray = tb->isTypeDArray ();
2422 gcc_assert (e->arguments && e->arguments->length >= 1);
2424 if (e->arguments->length == 1)
2426 /* Single dimension array allocations. */
2427 Expression *arg = (*e->arguments)[0];
2429 if (tarray->next->size () == 0)
2431 /* Array element size is unknown. */
2432 this->result_ = d_array_value (build_ctype (e->type),
2433 size_int (0), null_pointer_node);
2434 return;
2437 libcall_fn libcall = tarray->next->isZeroInit ()
2438 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
2439 result = build_libcall (libcall, tb, 2,
2440 build_typeinfo (e, e->type),
2441 build_expr (arg));
2443 else
2445 /* Multidimensional array allocations. */
2446 tree tarray = make_array_type (Type::tsize_t, e->arguments->length);
2447 tree var = build_local_temp (tarray);
2448 vec <constructor_elt, va_gc> *elms = NULL;
2450 /* Get the base element type for the array, generating the
2451 initializer for the dims parameter along the way. */
2452 Type *telem = e->newtype->toBasetype ();
2453 for (size_t i = 0; i < e->arguments->length; i++)
2455 Expression *arg = (*e->arguments)[i];
2456 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2458 gcc_assert (telem->ty == TY::Tarray);
2459 telem = telem->toBasetype ()->nextOf ();
2460 gcc_assert (telem);
2463 /* Initialize the temporary. */
2464 tree init = modify_expr (var, build_constructor (tarray, elms));
2465 var = compound_expr (init, var);
2467 /* Generate: _d_newarraymTX(ti, dims)
2468 or: _d_newarraymiTX(ti, dims) */
2469 libcall_fn libcall = telem->isZeroInit ()
2470 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2472 tree tinfo = build_typeinfo (e, e->type);
2473 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2474 size_int (e->arguments->length),
2475 build_address (var));
2477 result = build_libcall (libcall, tb, 2, tinfo, dims);
2480 if (e->argprefix)
2481 result = compound_expr (build_expr (e->argprefix), result);
2483 else if (tb->ty == TY::Tpointer)
2485 /* Allocating memory for a new pointer. */
2486 TypePointer *tpointer = tb->isTypePointer ();
2488 if (tpointer->next->size () == 0)
2490 /* Pointer element size is unknown. */
2491 this->result_ = d_convert (build_ctype (e->type),
2492 integer_zero_node);
2493 return;
2496 libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
2497 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2499 tree arg = build_typeinfo (e, e->newtype);
2500 result = build_libcall (libcall, tb, 1, arg);
2502 if (e->arguments && e->arguments->length == 1)
2504 result = d_save_expr (result);
2505 tree init = modify_expr (build_deref (result),
2506 build_expr ((*e->arguments)[0]));
2507 result = compound_expr (init, result);
2510 if (e->argprefix)
2511 result = compound_expr (build_expr (e->argprefix), result);
2513 else
2514 gcc_unreachable ();
2516 this->result_ = convert_expr (result, tb, e->type);
2519 /* Build an integer literal. */
2521 void visit (IntegerExp *e)
2523 tree ctype = build_ctype (e->type->toBasetype ());
2524 this->result_ = build_integer_cst (e->value, ctype);
2527 /* Build a floating-point literal. */
2529 void visit (RealExp *e)
2531 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2534 /* Build a complex literal. */
2536 void visit (ComplexExp *e)
2538 Type *tnext;
2540 switch (e->type->toBasetype ()->ty)
2542 case TY::Tcomplex32:
2543 tnext = (TypeBasic *) Type::tfloat32;
2544 break;
2546 case TY::Tcomplex64:
2547 tnext = (TypeBasic *) Type::tfloat64;
2548 break;
2550 case TY::Tcomplex80:
2551 tnext = (TypeBasic *) Type::tfloat80;
2552 break;
2554 default:
2555 gcc_unreachable ();
2558 this->result_ = build_complex (build_ctype (e->type),
2559 build_float_cst (creall (e->value), tnext),
2560 build_float_cst (cimagl (e->value), tnext));
2563 /* Build a string literal, all strings are null terminated except for
2564 static arrays. */
2566 void visit (StringExp *e)
2568 Type *tb = e->type->toBasetype ();
2569 tree type = build_ctype (e->type);
2571 if (tb->ty == TY::Tsarray)
2573 /* Turn the string into a constructor for the static array. */
2574 vec <constructor_elt, va_gc> *elms = NULL;
2575 vec_safe_reserve (elms, e->len);
2576 tree etype = TREE_TYPE (type);
2578 for (size_t i = 0; i < e->len; i++)
2580 tree value = build_integer_cst (e->getCodeUnit (i), etype);
2581 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2584 tree ctor = build_constructor (type, elms);
2585 TREE_CONSTANT (ctor) = 1;
2586 this->result_ = ctor;
2588 else
2590 /* Copy the string contents to a null terminated string. */
2591 dinteger_t length = (e->len * e->sz);
2592 char *string = XALLOCAVEC (char, length + 1);
2593 if (length > 0)
2594 memcpy (string, e->string, length);
2595 string[length] = '\0';
2597 /* String value and type includes the null terminator. */
2598 tree value = build_string (length, string);
2599 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2600 value = build_address (value);
2602 if (tb->ty == TY::Tarray)
2603 value = d_array_value (type, size_int (e->len), value);
2605 TREE_CONSTANT (value) = 1;
2606 this->result_ = d_convert (type, value);
2610 /* Build a tuple literal. Just an argument list that may have
2611 side effects that need evaluation. */
2613 void visit (TupleExp *e)
2615 tree result = NULL_TREE;
2617 if (e->e0)
2618 result = build_expr (e->e0, this->constp_, true);
2620 for (size_t i = 0; i < e->exps->length; ++i)
2622 Expression *exp = (*e->exps)[i];
2623 result = compound_expr (result, build_expr (exp, this->constp_, true));
2626 if (result == NULL_TREE)
2627 result = void_node;
2629 this->result_ = result;
2632 /* Build an array literal. The common type of the all elements is taken to
2633 be the type of the array element, and all elements are implicitly
2634 converted to that type. */
2636 void visit (ArrayLiteralExp *e)
2638 Type *tb = e->type->toBasetype ();
2640 /* Implicitly convert void[n] to ubyte[n]. */
2641 if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid)
2642 tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());
2644 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray
2645 || tb->ty == TY::Tpointer);
2647 /* Handle empty array literals. */
2648 if (e->elements->length == 0)
2650 if (tb->ty == TY::Tarray)
2651 this->result_ = d_array_value (build_ctype (e->type),
2652 size_int (0), null_pointer_node);
2653 else
2654 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2655 NULL);
2657 return;
2660 /* Build an expression that assigns the expressions in ELEMENTS to
2661 a constructor. */
2662 vec <constructor_elt, va_gc> *elms = NULL;
2663 vec_safe_reserve (elms, e->elements->length);
2664 bool constant_p = true;
2665 tree saved_elems = NULL_TREE;
2667 Type *etype = tb->nextOf ();
2668 tree satype = make_array_type (etype, e->elements->length);
2670 for (size_t i = 0; i < e->elements->length; i++)
2672 Expression *expr = e->getElement (i);
2673 tree value = build_expr (expr, this->constp_, true);
2675 /* Only append nonzero values, the backend will zero out the rest
2676 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2677 if (!initializer_zerop (value))
2679 if (!TREE_CONSTANT (value))
2680 constant_p = false;
2682 /* Split construction of values out of the constructor if there
2683 may be side effects. */
2684 tree init = stabilize_expr (&value);
2685 if (init != NULL_TREE)
2686 saved_elems = compound_expr (saved_elems, init);
2688 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2689 convert_expr (value, expr->type, etype));
2693 /* Now return the constructor as the correct type. For static arrays there
2694 is nothing else to do. For dynamic arrays, return a two field struct.
2695 For pointers, return the address. */
2696 tree ctor = build_constructor (satype, elms);
2697 tree type = build_ctype (e->type);
2699 /* Nothing else to do for static arrays. */
2700 if (tb->ty == TY::Tsarray || this->constp_)
2702 /* Can't take the address of the constructor, so create an anonymous
2703 static symbol, and then refer to it. */
2704 if (tb->ty != TY::Tsarray)
2706 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2707 ctor = build_address (decl);
2708 if (tb->ty == TY::Tarray)
2709 ctor = d_array_value (type, size_int (e->elements->length), ctor);
2711 d_pushdecl (decl);
2712 rest_of_decl_compilation (decl, 1, 0);
2715 /* If the array literal is readonly or static. */
2716 if (constant_p)
2717 TREE_CONSTANT (ctor) = 1;
2718 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2719 TREE_STATIC (ctor) = 1;
2721 /* Use memset to fill any alignment holes in the array. */
2722 if (!this->constp_ && !this->literalp_)
2724 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
2726 if (ts != NULL && (!identity_compare_p (ts->sym)
2727 || ts->sym->isUnionDeclaration ()))
2729 tree var = build_local_temp (TREE_TYPE (ctor));
2730 tree init = build_memset_call (var);
2731 /* Evaluate memset() first, then any saved elements. */
2732 saved_elems = compound_expr (init, saved_elems);
2733 ctor = compound_expr (modify_expr (var, ctor), var);
2737 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2739 else
2741 /* Allocate space on the memory managed heap. */
2742 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2743 etype->pointerTo (), 2,
2744 build_typeinfo (e, etype->arrayOf ()),
2745 size_int (e->elements->length));
2746 mem = d_save_expr (mem);
2748 /* Now copy the constructor into memory. */
2749 tree size = size_mult_expr (size_int (e->elements->length),
2750 size_int (tb->nextOf ()->size ()));
2752 tree result = build_memcpy_call (mem, build_address (ctor), size);
2754 /* Return the array pointed to by MEM. */
2755 result = compound_expr (result, mem);
2757 if (tb->ty == TY::Tarray)
2758 result = d_array_value (type, size_int (e->elements->length), result);
2760 this->result_ = compound_expr (saved_elems, result);
2764 /* Build an associative array literal. The common type of the all keys is
2765 taken to be the key type, and common type of all values the value type.
2766 All keys and values are then implicitly converted as needed. */
2768 void visit (AssocArrayLiteralExp *e)
2770 /* Want the mutable type for typeinfo reference. */
2771 Type *tb = e->type->toBasetype ()->mutableOf ();
2773 /* Handle empty assoc array literals. */
2774 TypeAArray *ta = tb->isTypeAArray ();
2775 if (e->keys->length == 0)
2777 this->result_ = build_constructor (build_ctype (ta), NULL);
2778 return;
2781 /* Build an expression that assigns all expressions in KEYS
2782 to a constructor. */
2783 tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
2784 e->keys, this->constp_);
2785 tree init = stabilize_expr (&akeys);
2787 /* Do the same with all expressions in VALUES. */
2788 tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
2789 e->values, this->constp_);
2790 init = compound_expr (init, stabilize_expr (&avals));
2792 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2793 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2794 size_int (e->keys->length),
2795 build_address (akeys));
2796 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2797 size_int (e->values->length),
2798 build_address (avals));
2800 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2801 build_typeinfo (e, ta), keys, vals);
2803 /* Return an associative array pointed to by MEM. */
2804 tree aatype = build_ctype (ta);
2805 vec <constructor_elt, va_gc> *ce = NULL;
2806 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2808 tree result = build_nop (build_ctype (e->type),
2809 build_constructor (aatype, ce));
2810 this->result_ = compound_expr (init, result);
2813 /* Build a struct literal. */
2815 void visit (StructLiteralExp *e)
2817 /* Handle empty struct literals. */
2818 if (e->elements == NULL || e->sd->fields.length == 0)
2820 this->result_ = build_constructor (build_ctype (e->type), NULL);
2821 return;
2824 /* Building sinit trees are delayed until after frontend semantic
2825 processing has complete. Build the static initializer now. */
2826 if (e->useStaticInit && !this->constp_)
2828 tree init = aggregate_initializer_decl (e->sd);
2830 /* If initializing a symbol, don't forget to set it. */
2831 if (e->sym != NULL)
2833 tree var = build_deref (e->sym);
2834 init = compound_expr (modify_expr (var, init), var);
2837 this->result_ = init;
2838 return;
2841 /* Build a constructor that assigns the expressions in ELEMENTS
2842 at each field index that has been filled in. */
2843 vec <constructor_elt, va_gc> *ve = NULL;
2844 tree saved_elems = NULL_TREE;
2846 /* CTFE may fill the hidden pointer by NullExp. */
2847 gcc_assert (e->elements->length <= e->sd->fields.length);
2849 Type *tb = e->type->toBasetype ();
2850 gcc_assert (tb->ty == TY::Tstruct);
2852 for (size_t i = 0; i < e->elements->length; i++)
2854 Expression *exp = (*e->elements)[i];
2855 if (!exp)
2856 continue;
2858 VarDeclaration *field = e->sd->fields[i];
2859 Type *type = exp->type->toBasetype ();
2860 Type *ftype = field->type->toBasetype ();
2861 tree value = NULL_TREE;
2863 if (ftype->ty == TY::Tsarray && !same_type_p (type, ftype))
2865 /* Initialize a static array with a single element. */
2866 tree elem = build_expr (exp, this->constp_, true);
2867 saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
2868 elem = d_save_expr (elem);
2870 if (initializer_zerop (elem))
2871 value = build_constructor (build_ctype (ftype), NULL);
2872 else
2873 value = build_array_from_val (ftype, elem);
2875 else
2877 value = convert_expr (build_expr (exp, this->constp_, true),
2878 exp->type, field->type);
2881 /* Split construction of values out of the constructor. */
2882 saved_elems = compound_expr (saved_elems, stabilize_expr (&value));
2884 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2887 /* Maybe setup hidden pointer to outer scope context. */
2888 if (e->sd->isNested () && e->elements->length != e->sd->fields.length
2889 && this->constp_ == false)
2891 tree field = get_symbol_decl (e->sd->vthis);
2892 tree value = build_vthis (e->sd);
2893 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2894 gcc_assert (e->useStaticInit == false);
2897 /* Build a constructor in the correct shape of the aggregate type. */
2898 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2900 /* Nothing more to do for constant literals. */
2901 if (this->constp_)
2903 /* If the struct literal is a valid for static data. */
2904 if (TREE_CONSTANT (ctor)
2905 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2906 TREE_STATIC (ctor) = 1;
2908 this->result_ = compound_expr (saved_elems, ctor);
2909 return;
2912 /* Construct the struct literal for run-time. */
2913 if (e->sym != NULL)
2915 /* Store the result in a symbol to initialize the literal. */
2916 tree var = build_deref (e->sym);
2917 ctor = compound_expr (modify_expr (var, ctor), var);
2919 else if (!this->literalp_)
2921 /* Use memset to fill any alignment holes in the object. */
2922 if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
2924 tree var = build_local_temp (TREE_TYPE (ctor));
2925 tree init = build_memset_call (var);
2926 /* Evaluate memset() first, then any saved element constructors. */
2927 saved_elems = compound_expr (init, saved_elems);
2928 ctor = compound_expr (modify_expr (var, ctor), var);
2932 this->result_ = compound_expr (saved_elems, ctor);
2935 /* Build a null literal. */
2937 void visit (NullExp *e)
2939 this->result_ = build_typeof_null_value (e->type);
2942 /* Build a vector literal. */
2944 void visit (VectorExp *e)
2946 /* First handle array literal expressions. */
2947 if (e->e1->op == EXP::arrayLiteral)
2949 ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
2950 vec <constructor_elt, va_gc> *elms = NULL;
2951 bool constant_p = true;
2952 tree type = build_ctype (e->type);
2954 vec_safe_reserve (elms, ale->elements->length);
2955 for (size_t i = 0; i < ale->elements->length; i++)
2957 Expression *expr = ale->getElement (i);
2958 tree value = d_convert (TREE_TYPE (type),
2959 build_expr (expr, this->constp_, true));
2960 if (!CONSTANT_CLASS_P (value))
2961 constant_p = false;
2963 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2966 /* Build a VECTOR_CST from a constant vector constructor. */
2967 if (constant_p)
2968 this->result_ = build_vector_from_ctor (type, elms);
2969 else
2970 this->result_ = build_constructor (type, elms);
2972 else if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
2974 /* Build a vector representation from a static array. */
2975 this->result_ = convert_expr (build_expr (e->e1, this->constp_),
2976 e->e1->type, e->type);
2978 else
2980 /* Build constructor from single value. */
2981 tree type = build_ctype (e->type);
2982 tree value = d_convert (TREE_TYPE (type),
2983 build_expr (e->e1, this->constp_, true));
2984 this->result_ = build_vector_from_val (type, value);
2988 /* Build a static array representation of a vector expression. */
2990 void visit (VectorArrayExp *e)
2992 this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
2993 e->e1->type, e->type);
2996 /* Build a static class literal, return its reference. */
2998 void visit (ClassReferenceExp *e)
3000 /* The result of build_new_class_expr is a RECORD_TYPE, we want
3001 the reference. */
3002 tree var = build_address (build_new_class_expr (e));
3004 /* If the type of this literal is an interface, the we must add the
3005 interface offset to symbol. */
3006 if (this->constp_)
3008 TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
3009 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
3011 if (to != NULL)
3013 ClassDeclaration *from = e->originalClass ();
3014 int offset = 0;
3016 gcc_assert (to->isBaseOf (from, &offset) != 0);
3018 if (offset != 0)
3019 var = build_offset (var, size_int (offset));
3023 this->result_ = var;
3026 /* Build an uninitialized value, generated from void initializers. */
3028 void visit (VoidInitExp *e)
3030 /* The front-end only generates these for the initializer of globals.
3031 Represent `void' as zeroes, regardless of the type's default value. */
3032 gcc_assert (this->constp_);
3033 this->result_ = build_zero_cst (build_ctype (e->type));
3036 /* These expressions are mainly just a placeholders in the frontend.
3037 We shouldn't see them here. */
3039 void visit (ScopeExp *e)
3041 error_at (make_location_t (e->loc), "%qs is not an expression",
3042 e->toChars ());
3043 this->result_ = error_mark_node;
3046 void visit (TypeExp *e)
3048 error_at (make_location_t (e->loc), "type %qs is not an expression",
3049 e->toChars ());
3050 this->result_ = error_mark_node;
3055 /* Main entry point for ExprVisitor interface to generate code for
3056 the Expression AST class E. If CONST_P is true, then E is a
3057 constant expression. If LITERAL_P is true, then E is a value used
3058 in the initialization of another literal. */
3060 tree
3061 build_expr (Expression *e, bool const_p, bool literal_p)
3063 ExprVisitor v = ExprVisitor (const_p, literal_p);
3064 location_t saved_location = input_location;
3066 input_location = make_location_t (e->loc);
3067 e->accept (&v);
3068 tree expr = v.result ();
3069 input_location = saved_location;
3071 /* Check if initializer expression is valid constant. */
3072 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3074 error_at (make_location_t (e->loc), "non-constant expression %qs",
3075 e->toChars ());
3076 return error_mark_node;
3079 return expr;
3082 /* Same as build_expr, but also calls destructors on any temporaries. */
3084 tree
3085 build_expr_dtor (Expression *e)
3087 /* Codegen can be improved by determining if no exceptions can be thrown
3088 between the ctor and dtor, and eliminating the ctor and dtor. */
3089 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3090 tree result = build_expr (e);
3092 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3094 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3095 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3098 return result;
3101 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3103 tree
3104 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3106 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3107 tree result = build_expr (e);
3109 /* Convert for initializing the DECL_RESULT. */
3110 if (tf->isref ())
3112 /* If we are returning a reference, take the address. */
3113 result = convert_expr (result, e->type, type);
3114 result = build_address (result);
3116 else
3117 result = convert_for_rvalue (result, e->type, type);
3119 /* The decl to store the return expression. */
3120 tree decl = DECL_RESULT (cfun->decl);
3122 /* Split comma expressions, so that the result is returned directly. */
3123 tree expr = stabilize_expr (&result);
3124 result = build_assign (INIT_EXPR, decl, result);
3125 result = compound_expr (expr, return_expr (result));
3127 /* May nest the return expression inside the try/finally expression. */
3128 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3130 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3131 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3134 return result;