1 /* expr.cc -- Lower D frontend expressions to GCC trees.
2 Copyright (C) 2015-2023 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)
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/>. */
20 #include "coretypes.h"
22 #include "dmd/aggregate.h"
24 #include "dmd/declaration.h"
26 #include "dmd/expression.h"
27 #include "dmd/identifier.h"
29 #include "dmd/module.h"
30 #include "dmd/mtype.h"
31 #include "dmd/template.h"
34 #include "fold-const.h"
35 #include "diagnostic.h"
36 #include "langhooks.h"
42 #include "stor-layout.h"
47 /* Determine if type T is a struct that has a postblit. */
50 needs_postblit (Type
*t
)
54 if (TypeStruct
*ts
= t
->isTypeStruct ())
56 if (ts
->sym
->postblit
)
63 /* Determine if type T is a struct that has a destructor. */
70 if (TypeStruct
*ts
= t
->isTypeStruct ())
79 /* Determine if expression E is a suitable lvalue. */
82 lvalue_p (Expression
*e
)
84 SliceExp
*se
= e
->isSliceExp ();
85 if (se
!= NULL
&& se
->e1
->isLvalue ())
88 CastExp
*ce
= e
->isCastExp ();
89 if (ce
!= NULL
&& ce
->e1
->isLvalue ())
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. */
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
));
130 ret
= fold_build2 (POINTER_DIFF_EXPR
, ptrtype
, arg0
, arg1
);
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
);
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
);
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. */
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
));
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
;
222 ExprVisitor (bool constp
, bool literalp
)
224 this->result_
= NULL_TREE
;
225 this->constp_
= constp
;
226 this->literalp_
= literalp
;
231 return this->result_
;
234 /* Visitor interfaces, each Expression class should have
235 overridden the default. */
237 void visit (Expression
*) final override
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
) final override
248 tree cond
= convert_for_condition (build_expr (e
->econd
),
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
) final override
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
);
293 /* Compare the real and imaginary parts separately. */
294 tree req
= build_float_identity (code
, real_part (t1
),
296 tree ieq
= build_float_identity (code
, imaginary_part (t1
),
297 imaginary_part (t2
));
300 this->result_
= build_boolop (TRUTH_ANDIF_EXPR
, req
, ieq
);
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 if (tb1
->ty
== TY::Tvector
&& tb2
->ty
== TY::Tvector
)
318 /* For vectors, identity is defined as all values being equal. */
319 tree t1
= build_expr (e
->e1
);
320 tree t2
= build_expr (e
->e2
);
321 tree mask
= build_boolop (code
, t1
, t2
);
323 /* To reinterpret the vector comparison as a boolean expression, bitcast
324 the bitmask result and generate an additional integer comparison. */
325 opt_scalar_int_mode mode
=
326 int_mode_for_mode (TYPE_MODE (TREE_TYPE (mask
)));
327 gcc_assert (mode
.exists ());
329 tree type
= lang_hooks
.types
.type_for_mode (mode
.require (), 1);
330 if (type
== NULL_TREE
)
331 type
= make_unsigned_type (GET_MODE_BITSIZE (mode
.require ()));
333 /* In `t1 is t2', all mask bits must be set for vectors to be equal.
334 Otherwise any bit set is enough for vectors to be not-equal. */
335 tree mask_eq
= (code
== EQ_EXPR
)
336 ? build_all_ones_cst (type
) : build_zero_cst (type
);
338 this->result_
= build_boolop (code
, mask_eq
,
339 build_vconvert (type
, mask
));
343 /* For operands of other types, identity is defined as being the
344 same as equality expressions. */
345 tree t1
= build_expr (e
->e1
);
346 tree t2
= build_expr (e
->e2
);
347 this->result_
= d_convert (build_ctype (e
->type
),
348 build_boolop (code
, t1
, t2
));
352 /* Build an equality expression, which compare the two operands for either
353 equality or inequality. Operands go through the usual conversions to bring
354 them to a common type before comparison. The result type is bool. */
356 void visit (EqualExp
*e
) final override
358 Type
*tb1
= e
->e1
->type
->toBasetype ();
359 Type
*tb2
= e
->e2
->type
->toBasetype ();
360 tree_code code
= (e
->op
== EXP::equal
) ? EQ_EXPR
: NE_EXPR
;
362 if ((tb1
->ty
== TY::Tsarray
|| tb1
->ty
== TY::Tarray
)
363 && (tb2
->ty
== TY::Tsarray
|| tb2
->ty
== TY::Tarray
))
365 /* For static and dynamic arrays, equality is defined as the lengths of
366 the arrays matching, and all the elements are equal. */
367 Type
*t1elem
= tb1
->nextOf ()->toBasetype ();
368 Type
*t2elem
= tb1
->nextOf ()->toBasetype ();
370 /* Check if comparisons of arrays can be optimized using memcmp.
371 This will inline EQ expressions as:
372 e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
373 Or when generating a NE expression:
374 e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */
375 if ((t1elem
->isintegral () || t1elem
->ty
== TY::Tvoid
376 || (t1elem
->ty
== TY::Tstruct
377 && !t1elem
->isTypeStruct ()->sym
->xeq
))
378 && t1elem
->ty
== t2elem
->ty
)
380 tree t1
= d_array_convert (e
->e1
);
381 tree t2
= d_array_convert (e
->e2
);
384 /* Make temporaries to prevent multiple evaluations. */
385 tree t1saved
= d_save_expr (t1
);
386 tree t2saved
= d_save_expr (t2
);
388 /* Length of arrays, for comparisons done before calling memcmp. */
389 tree t1len
= d_array_length (t1saved
);
390 tree t2len
= d_array_length (t2saved
);
392 /* Reference to array data. */
393 tree t1ptr
= d_array_ptr (t1saved
);
394 tree t2ptr
= d_array_ptr (t2saved
);
396 /* Compare arrays using memcmp if possible, otherwise for structs,
397 each field is compared inline. */
398 if (t1elem
->ty
!= TY::Tstruct
399 || identity_compare_p (t1elem
->isTypeStruct ()->sym
))
401 tree size
= size_mult_expr (t1len
, size_int (t1elem
->size ()));
403 result
= build_memcmp_call (t1ptr
, t2ptr
, size
);
404 result
= build_boolop (code
, result
, integer_zero_node
);
408 StructDeclaration
*sd
= t1elem
->isTypeStruct ()->sym
;
410 result
= build_array_struct_comparison (code
, sd
, t1len
,
414 /* Check array length first before passing to memcmp.
415 For equality expressions, this becomes:
416 (e1.length == 0 || memcmp);
417 Otherwise for inequality:
418 (e1.length != 0 && memcmp); */
419 tree tsizecmp
= build_boolop (code
, t1len
, size_zero_node
);
420 if (e
->op
== EXP::equal
)
421 result
= build_boolop (TRUTH_ORIF_EXPR
, tsizecmp
, result
);
423 result
= build_boolop (TRUTH_ANDIF_EXPR
, tsizecmp
, result
);
425 /* Finally, check if lengths of both arrays match if dynamic.
426 The frontend should have already guaranteed that static arrays
428 if (tb1
->ty
== TY::Tsarray
&& tb2
->ty
== TY::Tsarray
)
429 gcc_assert (tb1
->size () == tb2
->size ());
432 tree tlencmp
= build_boolop (code
, t1len
, t2len
);
433 if (e
->op
== EXP::equal
)
434 result
= build_boolop (TRUTH_ANDIF_EXPR
, tlencmp
, result
);
436 result
= build_boolop (TRUTH_ORIF_EXPR
, tlencmp
, result
);
439 /* Ensure left-to-right order of evaluation. */
440 if (TREE_SIDE_EFFECTS (t2
))
441 result
= compound_expr (t2saved
, result
);
443 if (TREE_SIDE_EFFECTS (t1
))
444 result
= compound_expr (t1saved
, result
);
446 this->result_
= result
;
450 /* Use _adEq2() to compare each element. */
451 Type
*t1array
= t1elem
->arrayOf ();
452 tree result
= build_libcall (LIBCALL_ADEQ2
, e
->type
, 3,
453 d_array_convert (e
->e1
),
454 d_array_convert (e
->e2
),
455 build_typeinfo (e
, t1array
));
457 if (e
->op
== EXP::notEqual
)
458 result
= build1 (TRUTH_NOT_EXPR
, build_ctype (e
->type
), result
);
460 this->result_
= result
;
463 else if (TypeStruct
*ts
= tb1
->isTypeStruct ())
465 /* Equality for struct objects means the logical product of all
466 equality results of the corresponding object fields. */
467 tree t1
= build_expr (e
->e1
);
468 tree t2
= build_expr (e
->e2
);
470 gcc_assert (same_type_p (tb1
, tb2
));
472 this->result_
= build_struct_comparison (code
, ts
->sym
, t1
, t2
);
474 else if (tb1
->ty
== TY::Taarray
&& tb2
->ty
== TY::Taarray
)
476 /* Use _aaEqual() for associative arrays. */
477 tree result
= build_libcall (LIBCALL_AAEQUAL
, e
->type
, 3,
478 build_typeinfo (e
, tb1
),
482 if (e
->op
== EXP::notEqual
)
483 result
= build1 (TRUTH_NOT_EXPR
, build_ctype (e
->type
), result
);
485 this->result_
= result
;
489 /* For operands of other types, equality is defined as the bit pattern
490 of the type matches exactly. */
491 tree t1
= build_expr (e
->e1
);
492 tree t2
= build_expr (e
->e2
);
494 this->result_
= d_convert (build_ctype (e
->type
),
495 build_boolop (code
, t1
, t2
));
499 /* Build an `in' expression. This is a condition to see if an element
500 exists in an associative array. The result is a pointer to the
501 element, or null if false. */
503 void visit (InExp
*e
) final override
505 Type
*tb2
= e
->e2
->type
->toBasetype ();
506 Type
*tkey
= tb2
->isTypeAArray ()->index
->toBasetype ();
507 tree key
= convert_expr (build_expr (e
->e1
), e
->e1
->type
, tkey
);
509 /* Build a call to _aaInX(). */
510 this->result_
= build_libcall (LIBCALL_AAINX
, e
->type
, 3,
512 build_typeinfo (e
, tkey
),
513 build_address (key
));
516 /* Build a relational expression. The result type is bool. */
518 void visit (CmpExp
*e
) final override
520 Type
*tb1
= e
->e1
->type
->toBasetype ();
521 Type
*tb2
= e
->e2
->type
->toBasetype ();
528 case EXP::lessOrEqual
:
536 case EXP::greaterOrEqual
:
540 case EXP::greaterThan
:
548 /* For static and dynamic arrays, the relational op is turned into a
549 library call. It is not lowered during codegen. */
550 if ((tb1
->ty
== TY::Tsarray
|| tb1
->ty
== TY::Tarray
)
551 && (tb2
->ty
== TY::Tsarray
|| tb2
->ty
== TY::Tarray
))
553 error ("cannot handle comparison of type %<%s == %s%>",
554 tb1
->toChars (), tb2
->toChars ());
558 /* Simple comparison. */
559 result
= build_boolop (code
, build_expr (e
->e1
), build_expr (e
->e2
));
560 this->result_
= d_convert (build_ctype (e
->type
), result
);
563 /* Build a logical `and if' or `or if' expression. If the right operand
564 expression is void, then the resulting type is void. Otherwise the
567 void visit (LogicalExp
*e
) final override
569 tree_code code
= (e
->op
== EXP::andAnd
) ? TRUTH_ANDIF_EXPR
: TRUTH_ORIF_EXPR
;
571 if (e
->e2
->type
->toBasetype ()->ty
!= TY::Tvoid
)
573 tree t1
= build_expr (e
->e1
);
574 tree t2
= build_expr (e
->e2
);
576 t1
= convert_for_condition (t1
, e
->e1
->type
);
577 t2
= convert_for_condition (t2
, e
->e2
->type
);
579 this->result_
= d_convert (build_ctype (e
->type
),
580 build_boolop (code
, t1
, t2
));
584 tree t1
= convert_for_condition (build_expr (e
->e1
), e
->e1
->type
);
585 tree t2
= build_expr_dtor (e
->e2
);
587 /* Invert condition for logical or if expression. */
588 if (e
->op
== EXP::orOr
)
589 t1
= build1 (TRUTH_NOT_EXPR
, d_bool_type
, t1
);
591 this->result_
= build_condition (build_ctype (e
->type
),
596 /* Build a binary operand expression. Operands go through usual arithmetic
597 conversions to bring them to a common type before evaluating. */
599 void visit (BinExp
*e
) final override
607 if ((e
->e1
->type
->isreal () && e
->e2
->type
->isimaginary ())
608 || (e
->e1
->type
->isimaginary () && e
->e2
->type
->isreal ()))
610 /* If the result is complex, then we can shortcut binary_op.
611 Frontend should have already validated types and sizes. */
612 tree t1
= build_expr (e
->e1
);
613 tree t2
= build_expr (e
->e2
);
615 if (e
->op
== EXP::min
)
616 t2
= build1 (NEGATE_EXPR
, TREE_TYPE (t2
), t2
);
618 if (e
->e1
->type
->isreal ())
619 this->result_
= complex_expr (build_ctype (e
->type
), t1
, t2
);
621 this->result_
= complex_expr (build_ctype (e
->type
), t2
, t1
);
626 code
= (e
->op
== EXP::add
)
627 ? PLUS_EXPR
: MINUS_EXPR
;
635 /* Determine if the div expression is a lowered pointer diff operation.
636 The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */
637 if (MinExp
*me
= e
->e1
->isMinExp ())
639 if (me
->e1
->type
->ty
== TY::Tpointer
640 && me
->e2
->type
->ty
== TY::Tpointer
641 && e
->e2
->op
== EXP::int64
)
643 code
= EXACT_DIV_EXPR
;
648 code
= e
->e1
->type
->isintegral ()
649 ? TRUNC_DIV_EXPR
: RDIV_EXPR
;
653 code
= e
->e1
->type
->isfloating ()
654 ? FLOAT_MOD_EXPR
: TRUNC_MOD_EXPR
;
673 case EXP::rightShift
:
677 case EXP::unsignedRightShift
:
678 code
= UNSIGNED_RSHIFT_EXPR
;
685 this->result_
= binary_op (code
, build_ctype (e
->type
),
686 build_expr (e
->e1
), build_expr (e
->e2
));
690 /* Build a concat expression, which concatenates two or more arrays of the
691 same type, producing a dynamic array with the result. If one operand
692 is an element type, that element is converted to an array of length 1. */
694 void visit (CatExp
*e
) final override
696 Type
*tb1
= e
->e1
->type
->toBasetype ();
697 Type
*tb2
= e
->e2
->type
->toBasetype ();
700 if (tb1
->ty
== TY::Tarray
|| tb1
->ty
== TY::Tsarray
)
701 etype
= tb1
->nextOf ();
703 etype
= tb2
->nextOf ();
707 if (e
->e1
->op
== EXP::concatenate
)
709 /* Flatten multiple concatenations to an array.
710 So the expression ((a ~ b) ~ c) becomes [a, b, c] */
713 for (Expression
*ex
= e
->e1
; ex
->op
== EXP::concatenate
;)
715 if (ex
->op
== EXP::concatenate
)
717 ex
= ex
->isCatExp ()->e1
;
722 /* Store all concatenation args to a temporary byte[][ndims] array. */
723 Type
*targselem
= Type::tint8
->arrayOf ();
724 tree var
= build_local_temp (make_array_type (targselem
, ndims
));
726 /* Loop through each concatenation from right to left. */
727 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
731 for (Expression
*oe
= ce
->e2
; oe
!= NULL
;
732 (ce
->e1
->op
!= EXP::concatenate
734 : (ce
= ce
->e1
->isCatExp (), oe
= ce
->e2
)))
736 tree arg
= d_array_convert (etype
, oe
);
737 tree index
= size_int (dim
);
738 CONSTRUCTOR_APPEND_ELT (elms
, index
, d_save_expr (arg
));
740 /* Finished pushing all arrays. */
747 /* Check there is no logic bug in constructing byte[][] of arrays. */
748 gcc_assert (dim
== 0);
749 tree init
= build_constructor (TREE_TYPE (var
), elms
);
750 var
= compound_expr (modify_expr (var
, init
), var
);
752 tree arrs
= d_array_value (build_ctype (targselem
->arrayOf ()),
753 size_int (ndims
), build_address (var
));
755 result
= build_libcall (LIBCALL_ARRAYCATNTX
, e
->type
, 2,
756 build_typeinfo (e
, e
->type
), arrs
);
760 /* Handle single concatenation (a ~ b). */
761 result
= build_libcall (LIBCALL_ARRAYCATT
, e
->type
, 3,
762 build_typeinfo (e
, e
->type
),
763 d_array_convert (etype
, e
->e1
),
764 d_array_convert (etype
, e
->e2
));
767 this->result_
= result
;
770 /* Build an assignment operator expression. The right operand is implicitly
771 converted to the type of the left operand, and assigned to it. */
773 void visit (BinAssignExp
*e
) final override
776 Expression
*e1b
= e
->e1
;
793 code
= e
->e1
->type
->isintegral ()
794 ? TRUNC_DIV_EXPR
: RDIV_EXPR
;
798 code
= e
->e1
->type
->isfloating ()
799 ? FLOAT_MOD_EXPR
: TRUNC_MOD_EXPR
;
817 case EXP::leftShiftAssign
:
821 case EXP::rightShiftAssign
:
822 case EXP::unsignedRightShiftAssign
:
823 /* Use the original lhs type before it was promoted. The left operand
824 of `>>>=' does not undergo integral promotions before shifting.
825 Strip off casts just incase anyway. */
826 while (e1b
->op
== EXP::cast_
)
828 CastExp
*ce
= e1b
->isCastExp ();
829 gcc_assert (same_type_p (ce
->type
, ce
->to
));
832 code
= (e
->op
== EXP::rightShiftAssign
) ? RSHIFT_EXPR
: UNSIGNED_RSHIFT_EXPR
;
839 tree exp
= binop_assignment (code
, e1b
, e
->e2
);
840 this->result_
= convert_expr (exp
, e1b
->type
, e
->type
);
843 /* Build a concat assignment expression. The right operand is appended
844 to the left operand. */
846 void visit (CatAssignExp
*e
) final override
848 Type
*tb1
= e
->e1
->type
->toBasetype ();
849 Type
*tb2
= e
->e2
->type
->toBasetype ();
850 Type
*etype
= tb1
->nextOf ()->toBasetype ();
852 /* Save the address of `e1', so it can be evaluated first.
853 As all D run-time library functions for concat assignments update `e1'
854 in-place and then return its value, the saved address can also be used as
855 the result of this expression as well. */
856 tree lhs
= build_expr (e
->e1
);
857 tree lexpr
= stabilize_expr (&lhs
);
858 tree ptr
= d_save_expr (build_address (lhs
));
859 tree result
= NULL_TREE
;
861 if (tb1
->ty
== TY::Tarray
&& tb2
->ty
== TY::Tdchar
862 && (etype
->ty
== TY::Tchar
|| etype
->ty
== TY::Twchar
))
864 /* Append a dchar to a char[] or wchar[]:
865 The assignment is handled by the D run-time library, so only
866 need to call `_d_arrayappend[cw]d(&e1, e2)' */
867 libcall_fn libcall
= (etype
->ty
== TY::Tchar
)
868 ? LIBCALL_ARRAYAPPENDCD
: LIBCALL_ARRAYAPPENDWD
;
870 result
= build_libcall (libcall
, e
->type
, 2,
871 ptr
, build_expr (e
->e2
));
875 /* Appending an element or array to another array has already been
876 handled by the front-end. */
877 gcc_assert (tb1
->ty
== TY::Tarray
|| tb2
->ty
== TY::Tsarray
);
881 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
882 result
= compound_expr (compound_expr (lexpr
, ptr
), result
);
883 this->result_
= compound_expr (result
, build_deref (ptr
));
886 /* Build an assignment expression. The right operand is implicitly
887 converted to the type of the left operand, and assigned to it. */
889 void visit (AssignExp
*e
) final override
891 /* First, handle special assignment semantics. */
893 /* Look for array.length = n; */
894 if (e
->e1
->op
== EXP::arrayLength
)
896 /* This case should have been rewritten to `_d_arraysetlengthT` in the
901 /* Look for exp = noreturn; */
902 if (e
->e2
->type
->isTypeNoreturn ())
904 /* If the RHS is a `noreturn' expression, there is no point generating
905 any code for the assignment, just evaluate side effects. */
906 tree t1
= build_expr (e
->e1
);
907 tree t2
= build_expr (e
->e2
);
908 this->result_
= compound_expr (t1
, t2
);
912 /* Look for array[] = n; */
913 if (e
->e1
->op
== EXP::slice
)
915 SliceExp
*se
= e
->e1
->isSliceExp ();
916 Type
*stype
= se
->e1
->type
->toBasetype ();
917 Type
*etype
= stype
->nextOf ()->toBasetype ();
919 /* Determine if we need to run postblit or dtor. */
920 bool postblit
= needs_postblit (etype
) && lvalue_p (e
->e2
);
921 bool destructor
= needs_dtor (etype
);
923 if (e
->memset
== MemorySet::blockAssign
)
925 /* Set a range of elements to one value. */
926 tree t1
= build_expr (e
->e1
);
927 tree t2
= build_expr (e
->e2
);
930 /* Extract any array bounds checks from the slice expression. */
931 tree init
= stabilize_expr (&t1
);
932 t1
= d_save_expr (t1
);
934 if ((postblit
|| destructor
) && e
->op
!= EXP::blit
)
936 /* This case should have been rewritten to `_d_arraysetassign`
937 in the semantic phase. */
941 if (integer_zerop (t2
))
943 tree size
= size_mult_expr (d_array_length (t1
),
944 size_int (etype
->size ()));
945 result
= build_memset_call (d_array_ptr (t1
), size
);
948 result
= build_array_set (d_array_ptr (t1
),
949 d_array_length (t1
), t2
);
951 result
= compound_expr (init
, result
);
952 this->result_
= compound_expr (result
, t1
);
956 /* Perform a memcpy operation. */
957 gcc_assert (e
->e2
->type
->ty
!= TY::Tpointer
);
959 if (!postblit
&& !destructor
)
961 tree t1
= d_save_expr (d_array_convert (e
->e1
));
962 tree t2
= d_save_expr (d_array_convert (e
->e2
));
964 /* References to array data. */
965 tree t1ptr
= d_array_ptr (t1
);
966 tree t1len
= d_array_length (t1
);
967 tree t2ptr
= d_array_ptr (t2
);
969 /* Generate: memcpy(to, from, size) */
970 tree size
= size_mult_expr (t1len
, size_int (etype
->size ()));
971 tree result
= build_memcpy_call (t1ptr
, t2ptr
, size
);
973 /* Insert check that array lengths match and do not overlap. */
974 if (array_bounds_check ())
976 /* tlencmp = (t1len == t2len) */
977 tree t2len
= d_array_length (t2
);
978 tree tlencmp
= build_boolop (EQ_EXPR
, t1len
, t2len
);
980 /* toverlap = (t1ptr + size <= t2ptr
981 || t2ptr + size <= t1ptr) */
982 tree t1ptrcmp
= build_boolop (LE_EXPR
,
983 build_offset (t1ptr
, size
),
985 tree t2ptrcmp
= build_boolop (LE_EXPR
,
986 build_offset (t2ptr
, size
),
988 tree toverlap
= build_boolop (TRUTH_ORIF_EXPR
, t1ptrcmp
,
991 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */
992 tree tassert
= build_array_bounds_call (e
->loc
);
993 tree tboundscheck
= build_boolop (TRUTH_ANDIF_EXPR
,
996 result
= build_condition (void_type_node
, tboundscheck
,
1000 this->result_
= compound_expr (result
, t1
);
1002 else if ((postblit
|| destructor
)
1003 && e
->op
!= EXP::blit
&& e
->op
!= EXP::construct
)
1005 /* Assigning to a non-trivially copyable array has already been
1006 handled by the front-end. */
1011 /* Generate: _d_arraycopy() */
1012 this->result_
= build_libcall (LIBCALL_ARRAYCOPY
, e
->type
, 3,
1013 size_int (etype
->size ()),
1014 d_array_convert (e
->e2
),
1015 d_array_convert (e
->e1
));
1022 /* Look for reference initializations. */
1023 if (e
->memset
== MemorySet::referenceInit
)
1025 gcc_assert (e
->op
== EXP::construct
|| e
->op
== EXP::blit
);
1026 gcc_assert (e
->e1
->op
== EXP::variable
);
1028 Declaration
*decl
= e
->e1
->isVarExp ()->var
;
1029 if (decl
->storage_class
& (STCout
| STCref
))
1031 tree t2
= convert_for_assignment (build_expr (e
->e2
),
1032 e
->e2
->type
, e
->e1
->type
);
1033 tree t1
= build_expr (e
->e1
);
1034 /* Want reference to lhs, not indirect ref. */
1035 t1
= TREE_OPERAND (t1
, 0);
1036 t2
= build_address (t2
);
1038 this->result_
= indirect_ref (build_ctype (e
->type
),
1039 build_assign (INIT_EXPR
, t1
, t2
));
1044 /* Other types of assignments that may require post construction. */
1045 Type
*tb1
= e
->e1
->type
->toBasetype ();
1046 tree_code modifycode
= (e
->op
== EXP::construct
) ? INIT_EXPR
: MODIFY_EXPR
;
1048 /* Look for struct assignment. */
1049 if (tb1
->ty
== TY::Tstruct
)
1051 tree t1
= build_expr (e
->e1
);
1052 tree t2
= convert_for_assignment (build_expr (e
->e2
, false, true),
1053 e
->e2
->type
, e
->e1
->type
);
1054 StructDeclaration
*sd
= tb1
->isTypeStruct ()->sym
;
1056 /* Look for struct = 0. */
1057 if (e
->e2
->op
== EXP::int64
)
1059 /* Use memset to fill struct. */
1060 gcc_assert (e
->op
== EXP::blit
);
1061 tree result
= build_memset_call (t1
);
1063 /* Maybe set-up hidden pointer to outer scope context. */
1064 if (sd
->isNested ())
1066 tree field
= get_symbol_decl (sd
->vthis
);
1067 tree value
= build_vthis (sd
);
1069 tree vthis_exp
= modify_expr (component_ref (t1
, field
), value
);
1070 result
= compound_expr (result
, vthis_exp
);
1073 this->result_
= compound_expr (result
, t1
);
1077 /* Simple struct literal assignment. */
1078 tree init
= NULL_TREE
;
1080 /* Fill any alignment holes in the struct using memset. */
1081 if ((e
->op
== EXP::construct
1082 || (e
->e2
->op
== EXP::structLiteral
&& e
->op
== EXP::blit
))
1083 && (sd
->isUnionDeclaration () || !identity_compare_p (sd
)))
1085 t1
= stabilize_reference (t1
);
1086 init
= build_memset_call (t1
);
1089 /* Elide generating assignment if init is all zeroes. */
1090 if (init
!= NULL_TREE
&& initializer_zerop (t2
))
1091 this->result_
= compound_expr (init
, t1
);
1094 tree result
= build_assign (modifycode
, t1
, t2
);
1095 this->result_
= compound_expr (init
, result
);
1102 /* Look for static array assignment. */
1103 if (tb1
->ty
== TY::Tsarray
)
1105 /* Look for array = 0. */
1106 if (e
->e2
->op
== EXP::int64
)
1108 /* Use memset to fill the array. */
1109 gcc_assert (e
->op
== EXP::blit
);
1110 this->result_
= build_memset_call (build_expr (e
->e1
));
1114 Type
*etype
= tb1
->nextOf ();
1115 gcc_assert (e
->e2
->type
->toBasetype ()->ty
== TY::Tsarray
);
1117 /* Determine if we need to run postblit. */
1118 const bool postblit
= needs_postblit (etype
);
1119 const bool destructor
= needs_dtor (etype
);
1120 const bool lvalue
= lvalue_p (e
->e2
);
1122 /* Optimize static array assignment with array literal. Even if the
1123 elements in rhs are all rvalues and don't have to call postblits,
1124 this assignment should call dtors on old assigned elements. */
1125 if ((!postblit
&& !destructor
)
1126 || (e
->op
== EXP::construct
&& e
->e2
->op
== EXP::arrayLiteral
)
1127 || (e
->op
== EXP::construct
&& e
->e2
->op
== EXP::call
)
1128 || (e
->op
== EXP::construct
&& !lvalue
&& postblit
)
1129 || (e
->op
== EXP::blit
|| e
->e1
->type
->size () == 0))
1131 tree t1
= build_expr (e
->e1
);
1132 tree t2
= convert_for_assignment (build_expr (e
->e2
),
1133 e
->e2
->type
, e
->e1
->type
);
1135 this->result_
= build_assign (modifycode
, t1
, t2
);
1139 /* All other kinds of lvalue or rvalue static array assignment.
1140 Array construction has already been handled by the front-end. */
1141 gcc_assert (e
->op
!= EXP::construct
);
1145 /* Simple assignment. */
1146 tree t1
= build_expr (e
->e1
);
1147 tree t2
= convert_for_assignment (build_expr (e
->e2
),
1148 e
->e2
->type
, e
->e1
->type
);
1150 this->result_
= build_assign (modifycode
, t1
, t2
);
1153 /* Build a throw expression. */
1155 void visit (ThrowExp
*e
) final override
1157 tree arg
= build_expr_dtor (e
->e1
);
1158 this->result_
= build_libcall (LIBCALL_THROW
, Type::tvoid
, 1, arg
);
1161 /* Build a postfix expression. */
1163 void visit (PostExp
*e
) final override
1167 if (e
->op
== EXP::plusPlus
)
1169 result
= build2 (POSTINCREMENT_EXPR
, build_ctype (e
->type
),
1170 build_expr (e
->e1
), build_expr (e
->e2
));
1172 else if (e
->op
== EXP::minusMinus
)
1174 result
= build2 (POSTDECREMENT_EXPR
, build_ctype (e
->type
),
1175 build_expr (e
->e1
), build_expr (e
->e2
));
1180 TREE_SIDE_EFFECTS (result
) = 1;
1181 this->result_
= result
;
1184 /* Build an index expression. */
1186 void visit (IndexExp
*e
) final override
1188 Type
*tb1
= e
->e1
->type
->toBasetype ();
1190 if (tb1
->ty
== TY::Taarray
)
1192 /* Get the key for the associative array. */
1193 Type
*tkey
= tb1
->isTypeAArray ()->index
->toBasetype ();
1194 tree key
= convert_expr (build_expr (e
->e2
), e
->e2
->type
, tkey
);
1200 libcall
= LIBCALL_AAGETY
;
1201 ptr
= build_address (build_expr (e
->e1
));
1202 tinfo
= build_typeinfo (e
, tb1
->unSharedOf ()->mutableOf ());
1206 libcall
= LIBCALL_AAGETRVALUEX
;
1207 ptr
= build_expr (e
->e1
);
1208 tinfo
= build_typeinfo (e
, tkey
);
1211 /* Index the associative array. */
1212 tree result
= build_libcall (libcall
, e
->type
->pointerTo (), 4,
1214 size_int (tb1
->nextOf ()->size ()),
1215 build_address (key
));
1217 if (!e
->indexIsInBounds
&& array_bounds_check ())
1219 tree tassert
= build_array_bounds_call (e
->loc
);
1221 result
= d_save_expr (result
);
1222 result
= build_condition (TREE_TYPE (result
),
1223 d_truthvalue_conversion (result
),
1227 this->result_
= indirect_ref (build_ctype (e
->type
), result
);
1231 /* Get the array and length for static and dynamic arrays. */
1232 tree array
= d_save_expr (build_expr (e
->e1
));
1234 tree length
= NULL_TREE
;
1235 if (tb1
->ty
!= TY::Tpointer
)
1236 length
= get_array_length (array
, tb1
);
1238 gcc_assert (e
->lengthVar
== NULL
);
1240 /* The __dollar variable just becomes a placeholder for the
1243 e
->lengthVar
->csym
= length
;
1245 /* Generate the index. */
1246 tree index
= build_expr (e
->e2
);
1248 /* If it's a static array and the index is constant, the front end has
1249 already checked the bounds. */
1250 if (tb1
->ty
!= TY::Tpointer
)
1251 index
= build_bounds_index_condition (e
, index
, length
);
1253 /* Convert vectors to their underlying array type. */
1254 if (VECTOR_TYPE_P (TREE_TYPE (array
)))
1257 build_array_type_nelts (TREE_TYPE (TREE_TYPE (array
)),
1258 TYPE_VECTOR_SUBPARTS (TREE_TYPE (array
)));
1259 d_mark_addressable (array
, false);
1260 array
= build1 (VIEW_CONVERT_EXPR
, array_type
, array
);
1263 if (TREE_CODE (TREE_TYPE (array
)) == ARRAY_TYPE
)
1265 /* Generate `array[index]'. When the index is non-constant, we must
1266 mark the array as addressable because we'll need to do pointer
1267 arithmetic on its address. */
1268 if (TREE_CODE (index
) != INTEGER_CST
)
1269 d_mark_addressable (array
);
1271 this->result_
= build4 (ARRAY_REF
, TREE_TYPE (TREE_TYPE (array
)),
1272 array
, index
, NULL_TREE
, NULL_TREE
);
1276 /* Generate `array.ptr[index]'. */
1277 tree ptr
= convert_expr (array
, tb1
, tb1
->nextOf ()->pointerTo ());
1278 ptr
= void_okay_p (ptr
);
1279 this->result_
= indirect_ref (TREE_TYPE (TREE_TYPE (ptr
)),
1280 build_pointer_index (ptr
, index
));
1285 /* Build a comma expression. The type is the type of the right operand. */
1287 void visit (CommaExp
*e
) final override
1289 tree t1
= build_expr (e
->e1
);
1290 tree t2
= build_expr (e
->e2
);
1291 tree type
= e
->type
? build_ctype (e
->type
) : void_type_node
;
1293 this->result_
= build2 (COMPOUND_EXPR
, type
, t1
, t2
);
1296 /* Build an array length expression. Returns the number of elements
1297 in the array. The result is of type size_t. */
1299 void visit (ArrayLengthExp
*e
) final override
1301 if (e
->e1
->type
->toBasetype ()->ty
== TY::Tarray
)
1302 this->result_
= d_array_length (build_expr (e
->e1
));
1305 /* Static arrays have already been handled by the front-end. */
1306 error ("unexpected type for array length: %qs", e
->type
->toChars ());
1307 this->result_
= error_mark_node
;
1311 /* Build a delegate pointer expression. This will return the frame
1312 pointer value as a type void*. */
1314 void visit (DelegatePtrExp
*e
) final override
1316 tree t1
= build_expr (e
->e1
);
1317 this->result_
= delegate_object (t1
);
1320 /* Build a delegate function pointer expression. This will return the
1321 function pointer value as a function type. */
1323 void visit (DelegateFuncptrExp
*e
) final override
1325 tree t1
= build_expr (e
->e1
);
1326 this->result_
= delegate_method (t1
);
1329 /* Build a slice expression. */
1331 void visit (SliceExp
*e
) final override
1333 Type
*tb
= e
->type
->toBasetype ();
1334 Type
*tb1
= e
->e1
->type
->toBasetype ();
1335 gcc_assert (tb
->ty
== TY::Tarray
|| tb
->ty
== TY::Tsarray
);
1337 /* Use convert-to-dynamic-array code if possible. */
1340 tree result
= build_expr (e
->e1
);
1341 if (e
->e1
->type
->toBasetype ()->ty
== TY::Tsarray
)
1342 result
= convert_expr (result
, e
->e1
->type
, e
->type
);
1344 this->result_
= result
;
1348 gcc_assert (e
->upr
!= NULL
);
1350 /* Get the data pointer and length for static and dynamic arrays. */
1351 tree array
= d_save_expr (build_expr (e
->e1
));
1352 tree ptr
= convert_expr (array
, tb1
, tb1
->nextOf ()->pointerTo ());
1353 tree length
= NULL_TREE
;
1355 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1356 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1357 if (tb1
->ty
!= TY::Tpointer
)
1358 length
= get_array_length (array
, tb1
);
1360 gcc_assert (e
->lengthVar
== NULL
);
1362 /* The __dollar variable just becomes a placeholder for the
1365 e
->lengthVar
->csym
= length
;
1367 /* Generate upper and lower bounds. */
1368 tree lwr_tree
= d_save_expr (build_expr (e
->lwr
));
1369 tree upr_tree
= d_save_expr (build_expr (e
->upr
));
1371 /* If the upper bound has any side effects, then the lower bound should be
1372 copied to a temporary always. */
1373 if (TREE_CODE (upr_tree
) == SAVE_EXPR
&& TREE_CODE (lwr_tree
) != SAVE_EXPR
)
1374 lwr_tree
= save_expr (lwr_tree
);
1376 /* Adjust the .ptr offset. */
1377 if (!integer_zerop (lwr_tree
))
1379 tree ptrtype
= TREE_TYPE (ptr
);
1380 ptr
= build_pointer_index (void_okay_p (ptr
), lwr_tree
);
1381 ptr
= build_nop (ptrtype
, ptr
);
1384 /* Nothing more to do for static arrays, their bounds checking has been
1385 done at compile-time. */
1386 if (tb
->ty
== TY::Tsarray
)
1388 this->result_
= indirect_ref (build_ctype (e
->type
), ptr
);
1392 gcc_assert (tb
->ty
== TY::Tarray
);
1394 /* Generate bounds checking code. */
1395 tree newlength
= build_bounds_slice_condition (e
, lwr_tree
, upr_tree
,
1397 tree result
= d_array_value (build_ctype (e
->type
), newlength
, ptr
);
1398 this->result_
= compound_expr (array
, result
);
1401 /* Build a cast expression, which converts the given unary expression to the
1404 void visit (CastExp
*e
) final override
1406 Type
*ebtype
= e
->e1
->type
->toBasetype ();
1407 Type
*tbtype
= e
->to
->toBasetype ();
1408 tree result
= build_expr (e
->e1
, this->constp_
, this->literalp_
);
1410 /* Just evaluate e1 if it has any side effects. */
1411 if (tbtype
->ty
== TY::Tvoid
)
1412 this->result_
= build_nop (build_ctype (tbtype
), result
);
1414 this->result_
= convert_for_rvalue (result
, ebtype
, tbtype
);
1417 /* Build a delete expression. */
1419 void visit (DeleteExp
*e
) final override
1421 tree t1
= build_expr (e
->e1
);
1422 Type
*tb1
= e
->e1
->type
->toBasetype ();
1424 if (tb1
->ty
== TY::Tclass
)
1426 /* For class object references, if there is a destructor for that class,
1427 the destructor is called for the object instance. */
1428 gcc_assert (e
->e1
->op
== EXP::variable
);
1430 VarDeclaration
*v
= e
->e1
->isVarExp ()->var
->isVarDeclaration ();
1431 gcc_assert (v
&& v
->onstack ());
1433 libcall_fn libcall
= tb1
->isClassHandle ()->isInterfaceDeclaration ()
1434 ? LIBCALL_CALLINTERFACEFINALIZER
: LIBCALL_CALLFINALIZER
;
1436 this->result_
= build_libcall (libcall
, Type::tvoid
, 1, t1
);
1441 error ("don%'t know how to delete %qs", e
->e1
->toChars ());
1442 this->result_
= error_mark_node
;
1446 /* Build a remove expression, which removes a particular key from an
1447 associative array. */
1449 void visit (RemoveExp
*e
) final override
1451 /* Check that the array is actually an associative array. */
1452 if (e
->e1
->type
->toBasetype ()->ty
== TY::Taarray
)
1454 Type
*tb
= e
->e1
->type
->toBasetype ();
1455 Type
*tkey
= tb
->isTypeAArray ()->index
->toBasetype ();
1456 tree index
= convert_expr (build_expr (e
->e2
), e
->e2
->type
, tkey
);
1458 this->result_
= build_libcall (LIBCALL_AADELX
, Type::tbool
, 3,
1460 build_typeinfo (e
, tkey
),
1461 build_address (index
));
1465 error ("%qs is not an associative array", e
->e1
->toChars ());
1466 this->result_
= error_mark_node
;
1470 /* Build an unary not expression. */
1472 void visit (NotExp
*e
) final override
1474 tree result
= convert_for_condition (build_expr (e
->e1
), e
->e1
->type
);
1475 /* Need to convert to boolean type or this will fail. */
1476 result
= fold_build1 (TRUTH_NOT_EXPR
, d_bool_type
, result
);
1478 this->result_
= d_convert (build_ctype (e
->type
), result
);
1481 /* Build a compliment expression, where all the bits in the value are
1482 complemented. Note: unlike in C, the usual integral promotions
1483 are not performed prior to the complement operation. */
1485 void visit (ComExp
*e
) final override
1487 TY ty1
= e
->e1
->type
->toBasetype ()->ty
;
1488 gcc_assert (ty1
!= TY::Tarray
&& ty1
!= TY::Tsarray
);
1490 this->result_
= fold_build1 (BIT_NOT_EXPR
, build_ctype (e
->type
),
1491 build_expr (e
->e1
));
1494 /* Build an unary negation expression. */
1496 void visit (NegExp
*e
) final override
1498 TY ty1
= e
->e1
->type
->toBasetype ()->ty
;
1499 gcc_assert (ty1
!= TY::Tarray
&& ty1
!= TY::Tsarray
);
1501 tree type
= build_ctype (e
->type
);
1502 tree expr
= build_expr (e
->e1
);
1504 /* If the operation needs excess precision. */
1505 tree eptype
= excess_precision_type (type
);
1506 if (eptype
!= NULL_TREE
)
1507 expr
= d_convert (eptype
, expr
);
1511 tree ret
= fold_build1 (NEGATE_EXPR
, eptype
, expr
);
1512 this->result_
= d_convert (type
, ret
);
1515 /* Build a pointer index expression. */
1517 void visit (PtrExp
*e
) final override
1523 if (e
->e1
->op
== EXP::add
)
1525 AddExp
*ae
= e
->e1
->isAddExp ();
1526 if (ae
->e1
->op
== EXP::address
1527 && ae
->e2
->isConst () && ae
->e2
->type
->isintegral ())
1529 Expression
*ex
= ae
->e1
->isAddrExp ()->e1
;
1530 tnext
= ex
->type
->toBasetype ();
1531 result
= build_expr (ex
);
1532 offset
= ae
->e2
->toUInteger ();
1535 else if (e
->e1
->op
== EXP::symbolOffset
)
1537 SymOffExp
*se
= e
->e1
->isSymOffExp ();
1538 if (!declaration_reference_p (se
->var
))
1540 tnext
= se
->var
->type
->toBasetype ();
1541 result
= get_decl_tree (se
->var
);
1542 offset
= se
->offset
;
1546 /* Produce better code by converting *(#record + n) to
1547 COMPONENT_REFERENCE. Otherwise, the variable will always be
1548 allocated in memory because its address is taken. */
1549 if (tnext
&& tnext
->ty
== TY::Tstruct
)
1551 StructDeclaration
*sd
= tnext
->isTypeStruct ()->sym
;
1553 for (size_t i
= 0; i
< sd
->fields
.length
; i
++)
1555 VarDeclaration
*field
= sd
->fields
[i
];
1557 if (field
->offset
== offset
1558 && same_type_p (field
->type
, e
->type
))
1560 /* Catch errors, backend will ICE otherwise. */
1561 if (error_operand_p (result
))
1562 this->result_
= result
;
1565 result
= component_ref (result
, get_symbol_decl (field
));
1566 this->result_
= result
;
1570 else if (field
->offset
> offset
)
1575 this->result_
= indirect_ref (build_ctype (e
->type
), build_expr (e
->e1
));
1578 /* Build an unary address expression. */
1580 void visit (AddrExp
*e
) final override
1582 tree type
= build_ctype (e
->type
);
1585 /* The frontend optimizer can convert const symbol into a struct literal.
1586 Taking the address of a struct literal is otherwise illegal. */
1587 if (e
->e1
->op
== EXP::structLiteral
)
1589 StructLiteralExp
*sle
= e
->e1
->isStructLiteralExp ()->origin
;
1590 gcc_assert (sle
!= NULL
);
1592 /* Build the reference symbol, the decl is built first as the
1593 initializer may have recursive references. */
1596 sle
->sym
= build_artificial_decl (build_ctype (sle
->type
),
1598 DECL_INITIAL (sle
->sym
) = build_expr (sle
, true);
1599 d_pushdecl (sle
->sym
);
1600 rest_of_decl_compilation (sle
->sym
, 1, 0);
1606 exp
= build_expr (e
->e1
, this->constp_
, this->literalp_
);
1608 TREE_CONSTANT (exp
) = 0;
1609 this->result_
= d_convert (type
, build_address (exp
));
1612 /* Build a function call expression. */
1614 void visit (CallExp
*e
) final override
1616 Type
*tb
= e
->e1
->type
->toBasetype ();
1617 Expression
*e1b
= e
->e1
;
1619 tree callee
= NULL_TREE
;
1620 tree object
= NULL_TREE
;
1621 tree cleanup
= NULL_TREE
;
1622 tree returnvalue
= NULL_TREE
;
1623 TypeFunction
*tf
= NULL
;
1625 /* Calls to delegates can sometimes look like this. */
1626 if (e1b
->op
== EXP::comma
)
1628 e1b
= e1b
->isCommaExp ()->e2
;
1629 gcc_assert (e1b
->op
== EXP::variable
);
1631 Declaration
*var
= e1b
->isVarExp ()->var
;
1632 gcc_assert (var
->isFuncDeclaration () && !var
->needThis ());
1635 if (e1b
->op
== EXP::dotVariable
&& tb
->ty
!= TY::Tdelegate
)
1637 DotVarExp
*dve
= e1b
->isDotVarExp ();
1639 /* Don't modify the static initializer for struct literals. */
1640 if (dve
->e1
->op
== EXP::structLiteral
)
1642 StructLiteralExp
*sle
= dve
->e1
->isStructLiteralExp ();
1643 sle
->useStaticInit
= false;
1646 FuncDeclaration
*fd
= dve
->var
->isFuncDeclaration ();
1649 /* Get the correct callee from the DotVarExp object. */
1650 tree fndecl
= get_symbol_decl (fd
);
1651 AggregateDeclaration
*ad
= fd
->isThis ();
1653 /* Static method; ignore the object instance. */
1655 callee
= build_address (fndecl
);
1658 tree thisexp
= build_expr (dve
->e1
);
1660 /* When constructing temporaries, if the constructor throws,
1661 then the object is destructed even though it is not a fully
1662 constructed object yet. And so this call will need to be
1663 moved inside the TARGET_EXPR_INITIAL slot. */
1664 if (fd
->isCtorDeclaration ()
1665 && TREE_CODE (thisexp
) == COMPOUND_EXPR
1666 && TREE_CODE (TREE_OPERAND (thisexp
, 0)) == TARGET_EXPR
1667 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp
, 0)))
1669 cleanup
= TREE_OPERAND (thisexp
, 0);
1670 thisexp
= TREE_OPERAND (thisexp
, 1);
1673 if (TREE_CODE (thisexp
) == CONSTRUCTOR
)
1674 thisexp
= force_target_expr (thisexp
);
1676 /* Want reference to `this' object. */
1677 if (!POINTER_TYPE_P (TREE_TYPE (thisexp
)))
1678 thisexp
= build_address (thisexp
);
1680 /* Make the callee a virtual call. */
1681 if (fd
->isVirtual () && !fd
->isFinalFunc () && !e
->directcall
)
1683 tree fntype
= build_pointer_type (TREE_TYPE (fndecl
));
1684 tree thistype
= build_ctype (ad
->handleType ());
1685 thisexp
= build_nop (thistype
, d_save_expr (thisexp
));
1686 fndecl
= build_vindex_ref (thisexp
, fntype
, fd
->vtblIndex
);
1689 fndecl
= build_address (fndecl
);
1691 /* C++ constructors return void, even though front-end semantic
1692 treats them as implicitly returning `this'. Set returnvalue
1693 to override the result of this expression. */
1694 if (fd
->isCtorDeclaration ())
1696 thisexp
= d_save_expr (thisexp
);
1697 returnvalue
= thisexp
;
1700 callee
= build_method_call (fndecl
, thisexp
, fd
->type
);
1705 if (callee
== NULL_TREE
)
1706 callee
= build_expr (e1b
);
1708 if (METHOD_CALL_EXPR (callee
))
1710 /* This could be a delegate expression (TY == Tdelegate), but not
1711 actually a delegate variable. */
1712 if (e1b
->op
== EXP::dotVariable
)
1714 /* This gets the true function type, getting the function type
1715 from e1->type can sometimes be incorrect, such as when calling
1716 a `ref' return function. */
1717 tf
= get_function_type (e1b
->isDotVarExp ()->var
->type
);
1720 tf
= get_function_type (tb
);
1722 extract_from_method_call (callee
, callee
, object
);
1724 else if (tb
->ty
== TY::Tdelegate
)
1726 /* Delegate call, extract .object and .funcptr from var. */
1727 callee
= d_save_expr (callee
);
1728 tf
= get_function_type (tb
);
1729 object
= delegate_object (callee
);
1730 callee
= delegate_method (callee
);
1732 else if (e1b
->op
== EXP::variable
)
1734 FuncDeclaration
*fd
= e1b
->isVarExp ()->var
->isFuncDeclaration ();
1735 gcc_assert (fd
!= NULL
);
1736 tf
= get_function_type (fd
->type
);
1738 if (fd
->isNested ())
1740 /* Maybe re-evaluate symbol storage treating `fd' as public. */
1741 if (call_by_alias_p (d_function_chain
->function
, fd
))
1742 TREE_PUBLIC (callee
) = 1;
1744 object
= get_frame_for_symbol (fd
);
1746 else if (fd
->needThis ())
1748 error_at (make_location_t (e1b
->loc
),
1749 "need %<this%> to access member %qs", fd
->toChars ());
1750 /* Continue compiling... */
1751 object
= null_pointer_node
;
1756 /* Normal direct function call. */
1757 tf
= get_function_type (tb
);
1760 gcc_assert (tf
!= NULL
);
1762 /* Now we have the type, callee and maybe object reference,
1763 build the call expression. */
1764 tree exp
= d_build_call (tf
, callee
, object
, e
->arguments
);
1766 if (returnvalue
!= NULL_TREE
)
1767 exp
= compound_expr (exp
, returnvalue
);
1770 exp
= build_deref (exp
);
1772 /* Some library calls are defined to return a generic type.
1773 this->type is the real type we want to return. */
1774 if (e
->type
->isTypeBasic ())
1775 exp
= d_convert (build_ctype (e
->type
), exp
);
1777 /* If this call was found to be a constructor for a temporary with a
1778 cleanup, then move the call inside the TARGET_EXPR. */
1779 if (cleanup
!= NULL_TREE
)
1781 tree init
= TARGET_EXPR_INITIAL (cleanup
);
1782 TARGET_EXPR_INITIAL (cleanup
) = compound_expr (init
, exp
);
1784 /* Keep the return value outside the TARGET_EXPR. */
1785 if (returnvalue
!= NULL_TREE
)
1786 cleanup
= compound_expr (cleanup
, TREE_OPERAND (exp
, 1));
1791 this->result_
= exp
;
1794 /* Build a delegate expression. */
1796 void visit (DelegateExp
*e
) final override
1798 if (e
->func
->semanticRun
== PASS::semantic3done
)
1800 /* Add the function as nested function if it belongs to this module.
1801 ie: it is a member of this module, or it is a template instance. */
1802 Dsymbol
*owner
= e
->func
->toParent ();
1803 while (!owner
->isTemplateInstance () && owner
->toParent ())
1804 owner
= owner
->toParent ();
1805 if (owner
->isTemplateInstance () || owner
== d_function_chain
->module
)
1806 build_decl_tree (e
->func
);
1812 if (e
->func
->isNested () && !e
->func
->isThis ())
1814 if (e
->e1
->op
== EXP::null_
)
1815 object
= build_expr (e
->e1
);
1817 object
= get_frame_for_symbol (e
->func
);
1819 fndecl
= build_address (get_symbol_decl (e
->func
));
1823 if (!e
->func
->isThis ())
1825 error ("delegates are only for non-static functions");
1826 this->result_
= error_mark_node
;
1830 object
= build_expr (e
->e1
);
1832 /* Want reference to `this' object. */
1833 if (e
->e1
->type
->ty
!= TY::Tclass
&& e
->e1
->type
->ty
!= TY::Tpointer
)
1834 object
= build_address (object
);
1836 /* Object reference could be the outer `this' field of a class or
1837 closure of type `void*'. Cast it to the right type. */
1838 if (e
->e1
->type
->ty
== TY::Tclass
)
1839 object
= d_convert (build_ctype (e
->e1
->type
), object
);
1841 fndecl
= get_symbol_decl (e
->func
);
1843 /* Get pointer to function out of the virtual table. */
1844 if (e
->func
->isVirtual () && !e
->func
->isFinalFunc ()
1845 && e
->e1
->op
!= EXP::super_
&& e
->e1
->op
!= EXP::dotType
)
1847 tree fntype
= build_pointer_type (TREE_TYPE (fndecl
));
1848 object
= d_save_expr (object
);
1849 fndecl
= build_vindex_ref (object
, fntype
, e
->func
->vtblIndex
);
1852 fndecl
= build_address (fndecl
);
1855 this->result_
= build_method_call (fndecl
, object
, e
->type
);
1858 /* Build a type component expression. */
1860 void visit (DotTypeExp
*e
) final override
1862 /* Just a pass through to underlying expression. */
1863 this->result_
= build_expr (e
->e1
);
1866 /* Build a component reference expression. */
1868 void visit (DotVarExp
*e
) final override
1870 VarDeclaration
*vd
= e
->var
->isVarDeclaration ();
1872 /* This could also be a function, but relying on that being taken
1873 care of by the visitor interface for CallExp. */
1876 if (!vd
->isField ())
1877 this->result_
= get_decl_tree (vd
);
1880 tree object
= build_expr (e
->e1
);
1881 Type
*tb
= e
->e1
->type
->toBasetype ();
1883 if (tb
->ty
!= TY::Tstruct
)
1884 object
= build_deref (object
);
1886 /* __complex is represented as a struct in the front-end, but
1887 underlying is really a complex type. */
1888 if (e
->e1
->type
->ty
== TY::Tenum
1889 && e
->e1
->type
->isTypeEnum ()->sym
->isSpecial ())
1890 object
= underlying_complex_expr (build_ctype (tb
), object
);
1892 this->result_
= component_ref (object
, get_symbol_decl (vd
));
1897 error ("%qs is not a field, but a %qs",
1898 e
->var
->toChars (), e
->var
->kind ());
1899 this->result_
= error_mark_node
;
1903 /* Build an assert expression, used to declare conditions that must hold at
1904 that a given point in the program. */
1906 void visit (AssertExp
*e
) final override
1908 Type
*tb1
= e
->e1
->type
->toBasetype ();
1909 tree arg
= build_expr (e
->e1
);
1910 tree tmsg
= NULL_TREE
;
1911 tree assert_pass
= void_node
;
1914 if (global
.params
.useAssert
== CHECKENABLEon
&& !checkaction_trap_p ())
1916 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1917 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1918 bool unittest_p
= d_function_chain
->function
->isUnitTestDeclaration ();
1923 tmsg
= build_expr_dtor (e
->msg
);
1924 libcall
= unittest_p
? LIBCALL_UNITTEST_MSG
: LIBCALL_ASSERT_MSG
;
1927 libcall
= unittest_p
? LIBCALL_UNITTESTP
: LIBCALL_ASSERTP
;
1929 /* Build a call to _d_assert(). */
1930 assert_fail
= build_assert_call (e
->loc
, libcall
, tmsg
);
1932 if (global
.params
.useInvariants
== CHECKENABLEon
)
1934 /* If the condition is a D class or struct object with an invariant,
1935 call it if the condition result is true. */
1936 if (tb1
->ty
== TY::Tclass
)
1938 ClassDeclaration
*cd
= tb1
->isClassHandle ();
1939 if (!cd
->isInterfaceDeclaration () && !cd
->isCPPclass ())
1941 arg
= d_save_expr (arg
);
1942 assert_pass
= build_libcall (LIBCALL_INVARIANT
,
1943 Type::tvoid
, 1, arg
);
1946 else if (tb1
->ty
== TY::Tpointer
1947 && tb1
->nextOf ()->ty
== TY::Tstruct
)
1949 StructDeclaration
*sd
= tb1
->nextOf ()->isTypeStruct ()->sym
;
1950 if (sd
->inv
!= NULL
)
1953 arg
= d_save_expr (arg
);
1954 assert_pass
= d_build_call_expr (sd
->inv
, arg
, &args
);
1959 else if (global
.params
.useAssert
== CHECKENABLEon
&& checkaction_trap_p ())
1961 /* Generate: __builtin_trap() */
1962 tree fn
= builtin_decl_explicit (BUILT_IN_TRAP
);
1963 assert_fail
= build_call_expr (fn
, 0);
1967 /* Assert contracts are turned off. */
1968 this->result_
= void_node
;
1972 /* Build condition that we are asserting in this contract. */
1973 tree condition
= convert_for_condition (arg
, e
->e1
->type
);
1975 /* We expect the condition to always be true, as what happens if an assert
1976 contract is false is undefined behavior. */
1977 tree fn
= builtin_decl_explicit (BUILT_IN_EXPECT
);
1978 tree arg_types
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
1979 tree pred_type
= TREE_VALUE (arg_types
);
1980 tree expected_type
= TREE_VALUE (TREE_CHAIN (arg_types
));
1982 condition
= build_call_expr (fn
, 2, d_convert (pred_type
, condition
),
1983 build_int_cst (expected_type
, 1));
1984 condition
= d_truthvalue_conversion (condition
);
1986 this->result_
= build_vcondition (condition
, assert_pass
, assert_fail
);
1989 /* Build a declaration expression. */
1991 void visit (DeclarationExp
*e
) final override
1993 /* Compile the declaration. */
1995 build_decl_tree (e
->declaration
);
1996 tree result
= pop_stmt_list ();
1998 /* Construction of an array for typesafe-variadic function arguments
1999 can cause an empty STMT_LIST here. This can causes problems
2000 during gimplification. */
2001 if (TREE_CODE (result
) == STATEMENT_LIST
&& !STATEMENT_LIST_HEAD (result
))
2002 result
= build_empty_stmt (input_location
);
2004 this->result_
= result
;
2007 /* Build a typeid expression. Returns an instance of class TypeInfo
2008 corresponding to. */
2010 void visit (TypeidExp
*e
) final override
2012 if (Type
*tid
= isType (e
->obj
))
2014 tree ti
= build_typeinfo (e
, tid
);
2016 /* If the typeinfo is at an offset. */
2017 if (tid
->vtinfo
->offset
)
2018 ti
= build_offset (ti
, size_int (tid
->vtinfo
->offset
));
2020 this->result_
= build_nop (build_ctype (e
->type
), ti
);
2022 else if (Expression
*tid
= isExpression (e
->obj
))
2024 Type
*type
= tid
->type
->toBasetype ();
2025 assert (type
->ty
== TY::Tclass
);
2027 /* Generate **classptr to get the classinfo. */
2028 tree ci
= build_expr (tid
);
2029 ci
= indirect_ref (ptr_type_node
, ci
);
2030 ci
= indirect_ref (ptr_type_node
, ci
);
2032 /* Add extra indirection for interfaces. */
2033 if (type
->isTypeClass ()->sym
->isInterfaceDeclaration ())
2034 ci
= indirect_ref (ptr_type_node
, ci
);
2036 this->result_
= build_nop (build_ctype (e
->type
), ci
);
2042 /* Build a function/lambda expression. */
2044 void visit (FuncExp
*e
) final override
2046 Type
*ftype
= e
->type
->toBasetype ();
2048 /* This check is for lambda's, remove `vthis' as function isn't nested. */
2049 if (e
->fd
->tok
== TOK::reserved
&& ftype
->ty
== TY::Tpointer
)
2051 e
->fd
->tok
= TOK::function_
;
2052 e
->fd
->vthis
= NULL
;
2055 /* Compile the function literal body. */
2056 build_decl_tree (e
->fd
);
2058 /* If nested, this will be a trampoline. */
2059 if (e
->fd
->isNested ())
2061 tree func
= build_address (get_symbol_decl (e
->fd
));
2066 /* Static delegate variables have no context pointer. */
2067 object
= null_pointer_node
;
2068 this->result_
= build_method_call (func
, object
, e
->fd
->type
);
2069 TREE_CONSTANT (this->result_
) = 1;
2073 object
= get_frame_for_symbol (e
->fd
);
2074 this->result_
= build_method_call (func
, object
, e
->fd
->type
);
2079 this->result_
= build_nop (build_ctype (e
->type
),
2080 build_address (get_symbol_decl (e
->fd
)));
2084 /* Build a halt expression. */
2086 void visit (HaltExp
*) final override
2088 /* Should we use trap() or abort()? */
2089 tree ttrap
= builtin_decl_explicit (BUILT_IN_TRAP
);
2090 this->result_
= build_call_expr (ttrap
, 0);
2093 /* Build a symbol pointer offset expression. */
2095 void visit (SymOffExp
*e
) final override
2097 /* Build the address and offset of the symbol. */
2098 size_t soffset
= e
->isSymOffExp ()->offset
;
2099 tree result
= get_decl_tree (e
->var
);
2100 TREE_USED (result
) = 1;
2102 if (declaration_reference_p (e
->var
))
2103 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result
)));
2105 result
= build_address (result
);
2108 result
= d_convert (build_ctype (e
->type
), result
);
2111 tree offset
= size_int (soffset
);
2112 result
= build_nop (build_ctype (e
->type
),
2113 build_offset (result
, offset
));
2116 this->result_
= result
;
2119 /* Build a variable expression. */
2121 void visit (VarExp
*e
) final override
2123 if (e
->var
->needThis ())
2125 error ("need %<this%> to access member %qs", e
->var
->ident
->toChars ());
2126 this->result_
= error_mark_node
;
2129 else if (e
->var
->ident
== Identifier::idPool ("__ctfe"))
2131 /* __ctfe is always false at run-time. */
2132 this->result_
= integer_zero_node
;
2136 /* This check is same as is done in FuncExp for lambdas. */
2137 FuncLiteralDeclaration
*fld
= e
->var
->isFuncLiteralDeclaration ();
2140 if (fld
->tok
== TOK::reserved
)
2142 fld
->tok
= TOK::function_
;
2146 /* Compiler the function literal body. */
2147 build_decl_tree (fld
);
2152 /* Want the initializer, not the expression. */
2153 VarDeclaration
*var
= e
->var
->isVarDeclaration ();
2154 SymbolDeclaration
*sdecl
= e
->var
->isSymbolDeclaration ();
2155 tree init
= NULL_TREE
;
2157 if (var
&& (var
->isConst () || var
->isImmutable ())
2158 && e
->type
->toBasetype ()->ty
!= TY::Tsarray
&& var
->_init
)
2161 error_at (make_location_t (e
->loc
), "recursive reference %qs",
2166 init
= build_expr (initializerToExpression (var
->_init
), true);
2170 else if (sdecl
&& sdecl
->dsym
)
2172 if (StructDeclaration
*sd
= sdecl
->dsym
->isStructDeclaration ())
2173 init
= layout_struct_initializer (sd
);
2174 else if (ClassDeclaration
*cd
= sdecl
->dsym
->isClassDeclaration ())
2175 init
= layout_class_initializer (cd
);
2180 error_at (make_location_t (e
->loc
), "non-constant expression %qs",
2183 if (init
!= NULL_TREE
)
2184 this->result_
= init
;
2186 this->result_
= error_mark_node
;
2190 tree result
= get_decl_tree (e
->var
);
2191 TREE_USED (result
) = 1;
2193 /* The variable expression generated for `__traits(initSymbol)'. */
2194 if (SymbolDeclaration
*sd
= e
->var
->isSymbolDeclaration ())
2196 if (e
->type
->isTypeDArray ())
2198 /* Generate a slice for non-zero initialized aggregates,
2199 otherwise create an empty array. */
2200 gcc_assert (e
->type
== Type::tvoid
->arrayOf ()->constOf ());
2202 tree type
= build_ctype (e
->type
);
2203 tree length
= size_int (sd
->dsym
->structsize
);
2204 tree ptr
= (sd
->dsym
->isStructDeclaration ()
2205 && sd
->dsym
->type
->isZeroInit (e
->loc
))
2206 ? null_pointer_node
: build_address (result
);
2208 this->result_
= d_array_value (type
, length
, ptr
);
2213 /* For variables that are references - currently only out/inout
2214 arguments; objects don't count - evaluating the variable means
2215 we want what it refers to. */
2216 if (declaration_reference_p (e
->var
))
2217 result
= indirect_ref (build_ctype (e
->var
->type
), result
);
2219 this->result_
= result
;
2223 /* Build a this variable expression. */
2225 void visit (ThisExp
*e
) final override
2227 FuncDeclaration
*fd
= d_function_chain
? d_function_chain
->function
: NULL
;
2228 tree result
= NULL_TREE
;
2231 result
= get_decl_tree (e
->var
);
2234 gcc_assert (fd
&& fd
->vthis
);
2235 result
= get_decl_tree (fd
->vthis
);
2238 if (e
->type
->ty
== TY::Tstruct
)
2239 result
= build_deref (result
);
2241 this->result_
= result
;
2244 /* Build a new expression, which allocates memory either on the garbage
2245 collected heap or by using a class or struct specific allocator. */
2247 void visit (NewExp
*e
) final override
2249 Type
*tb
= e
->type
->toBasetype ();
2252 if (tb
->ty
== TY::Tclass
)
2254 /* Allocating a new class. */
2255 tb
= e
->newtype
->toBasetype ();
2257 ClassDeclaration
*cd
= tb
->isTypeClass ()->sym
;
2258 tree type
= build_ctype (tb
);
2259 tree setup_exp
= NULL_TREE
;
2264 /* If being used as an initializer for a local variable with scope
2265 storage class, then the instance is allocated on the stack
2266 rather than the heap or using the class specific allocator. */
2267 tree var
= build_local_temp (TREE_TYPE (type
));
2268 new_call
= build_nop (type
, build_address (var
));
2269 setup_exp
= modify_expr (var
, aggregate_initializer_decl (cd
));
2271 else if (global
.params
.ehnogc
&& e
->thrownew
)
2273 /* Allocating a `@nogc' Exception with `_d_newThrowable' has already
2274 been handled by the front-end. */
2279 /* Generate: _d_newclass() */
2280 new_call
= build_expr (e
->lowering
);
2283 /* Set the context pointer for nested classes. */
2284 if (cd
->isNested ())
2286 tree field
= get_symbol_decl (cd
->vthis
);
2287 tree value
= NULL_TREE
;
2291 ClassDeclaration
*tcd
= e
->thisexp
->type
->isClassHandle ();
2292 /* The class or function we're nested in. */
2293 Dsymbol
*outer
= cd
->toParentLocal ();
2295 value
= build_expr (e
->thisexp
);
2299 ClassDeclaration
*ocd
= outer
->isClassDeclaration ();
2301 gcc_assert (ocd
->isBaseOf (tcd
, &offset
));
2302 /* Could just add offset... */
2303 value
= convert_expr (value
, e
->thisexp
->type
, ocd
->type
);
2307 value
= build_vthis (cd
);
2309 if (value
!= NULL_TREE
)
2311 /* Generate: (new())->vthis = this; */
2312 new_call
= d_save_expr (new_call
);
2313 field
= component_ref (build_deref (new_call
), field
);
2314 setup_exp
= compound_expr (setup_exp
,
2315 modify_expr (field
, value
));
2318 new_call
= compound_expr (setup_exp
, new_call
);
2320 /* Call the class constructor. */
2322 result
= d_build_call_expr (e
->member
, new_call
, e
->arguments
);
2327 result
= compound_expr (build_expr (e
->argprefix
), result
);
2329 else if (tb
->ty
== TY::Tpointer
2330 && tb
->nextOf ()->toBasetype ()->ty
== TY::Tstruct
)
2332 /* Allocating memory for a new struct. */
2333 Type
*htype
= e
->newtype
->toBasetype ();
2334 gcc_assert (!e
->onstack
);
2336 TypeStruct
*stype
= htype
->isTypeStruct ();
2337 StructDeclaration
*sd
= stype
->sym
;
2340 /* Cannot new an opaque struct. */
2341 if (sd
->size (e
->loc
) == 0)
2343 this->result_
= d_convert (build_ctype (e
->type
),
2348 /* Generate: _d_newitemT() */
2349 libcall_fn libcall
= htype
->isZeroInit ()
2350 ? LIBCALL_NEWITEMT
: LIBCALL_NEWITEMIT
;
2351 tree arg
= build_typeinfo (e
, e
->newtype
);
2352 new_call
= build_libcall (libcall
, tb
, 1, arg
);
2354 if (e
->member
|| !e
->arguments
)
2356 /* Set the context pointer for nested structs. */
2357 if (sd
->isNested ())
2359 tree value
= build_vthis (sd
);
2360 tree field
= get_symbol_decl (sd
->vthis
);
2361 tree type
= build_ctype (stype
);
2363 new_call
= d_save_expr (new_call
);
2364 field
= component_ref (indirect_ref (type
, new_call
), field
);
2365 new_call
= compound_expr (modify_expr (field
, value
), new_call
);
2368 /* Call the struct constructor. */
2370 result
= d_build_call_expr (e
->member
, new_call
, e
->arguments
);
2376 /* If we have a user supplied initializer, then set-up with a
2378 if (e
->arguments
!= NULL
&& sd
->fields
.length
!= 0)
2380 StructLiteralExp
*se
= StructLiteralExp::create (e
->loc
, sd
,
2383 new_call
= d_save_expr (new_call
);
2384 se
->type
= sd
->type
;
2386 result
= compound_expr (build_expr (se
), new_call
);
2393 result
= compound_expr (build_expr (e
->argprefix
), result
);
2395 else if (tb
->ty
== TY::Tarray
)
2397 /* Allocating memory for a new D array. */
2398 tb
= e
->newtype
->toBasetype ();
2399 TypeDArray
*tarray
= tb
->isTypeDArray ();
2401 gcc_assert (e
->arguments
&& e
->arguments
->length
>= 1);
2403 if (e
->arguments
->length
== 1)
2405 /* Single dimension array allocations. */
2406 Expression
*arg
= (*e
->arguments
)[0];
2408 if (tarray
->next
->size () == 0)
2410 /* Array element size is unknown. */
2411 this->result_
= d_array_value (build_ctype (e
->type
),
2412 size_int (0), null_pointer_node
);
2416 libcall_fn libcall
= tarray
->next
->isZeroInit ()
2417 ? LIBCALL_NEWARRAYT
: LIBCALL_NEWARRAYIT
;
2418 result
= build_libcall (libcall
, tb
, 2,
2419 build_typeinfo (e
, e
->type
),
2424 /* Multidimensional array allocations. */
2425 tree tarray
= make_array_type (Type::tsize_t
, e
->arguments
->length
);
2426 tree var
= build_local_temp (tarray
);
2427 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
2429 /* Get the base element type for the array, generating the
2430 initializer for the dims parameter along the way. */
2431 Type
*telem
= e
->newtype
->toBasetype ();
2432 for (size_t i
= 0; i
< e
->arguments
->length
; i
++)
2434 Expression
*arg
= (*e
->arguments
)[i
];
2435 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), build_expr (arg
));
2437 gcc_assert (telem
->ty
== TY::Tarray
);
2438 telem
= telem
->toBasetype ()->nextOf ();
2442 /* Initialize the temporary. */
2443 tree init
= modify_expr (var
, build_constructor (tarray
, elms
));
2444 var
= compound_expr (init
, var
);
2446 /* Generate: _d_newarraymTX(ti, dims)
2447 or: _d_newarraymiTX(ti, dims) */
2448 libcall_fn libcall
= telem
->isZeroInit ()
2449 ? LIBCALL_NEWARRAYMTX
: LIBCALL_NEWARRAYMITX
;
2451 tree tinfo
= build_typeinfo (e
, e
->type
);
2452 tree dims
= d_array_value (build_ctype (Type::tsize_t
->arrayOf ()),
2453 size_int (e
->arguments
->length
),
2454 build_address (var
));
2456 result
= build_libcall (libcall
, tb
, 2, tinfo
, dims
);
2460 result
= compound_expr (build_expr (e
->argprefix
), result
);
2462 else if (tb
->ty
== TY::Tpointer
)
2464 /* Allocating memory for a new pointer. */
2465 TypePointer
*tpointer
= tb
->isTypePointer ();
2467 if (tpointer
->next
->size () == 0)
2469 /* Pointer element size is unknown. */
2470 this->result_
= d_convert (build_ctype (e
->type
),
2475 libcall_fn libcall
= tpointer
->next
->isZeroInit (e
->loc
)
2476 ? LIBCALL_NEWITEMT
: LIBCALL_NEWITEMIT
;
2478 tree arg
= build_typeinfo (e
, e
->newtype
);
2479 result
= build_libcall (libcall
, tb
, 1, arg
);
2481 if (e
->arguments
&& e
->arguments
->length
== 1)
2483 result
= d_save_expr (result
);
2484 tree init
= modify_expr (build_deref (result
),
2485 build_expr ((*e
->arguments
)[0]));
2486 result
= compound_expr (init
, result
);
2490 result
= compound_expr (build_expr (e
->argprefix
), result
);
2492 else if (tb
->ty
== TY::Taarray
)
2494 /* Allocating memory for a new associative array. */
2495 tree arg
= build_typeinfo (e
, e
->newtype
);
2496 tree mem
= build_libcall (LIBCALL_AANEW
, Type::tvoidptr
, 1, arg
);
2498 /* Return an associative array pointed to by MEM. */
2499 tree aatype
= build_ctype (tb
);
2500 vec
<constructor_elt
, va_gc
> *ce
= NULL
;
2501 CONSTRUCTOR_APPEND_ELT (ce
, TYPE_FIELDS (aatype
), mem
);
2503 result
= build_nop (build_ctype (e
->type
),
2504 build_constructor (aatype
, ce
));
2509 this->result_
= convert_expr (result
, tb
, e
->type
);
2512 /* Build an integer literal. */
2514 void visit (IntegerExp
*e
) final override
2516 tree ctype
= build_ctype (e
->type
->toBasetype ());
2517 this->result_
= build_integer_cst (e
->value
, ctype
);
2520 /* Build a floating-point literal. */
2522 void visit (RealExp
*e
) final override
2524 this->result_
= build_float_cst (e
->value
, e
->type
->toBasetype ());
2527 /* Build a complex literal. */
2529 void visit (ComplexExp
*e
) final override
2533 switch (e
->type
->toBasetype ()->ty
)
2535 case TY::Tcomplex32
:
2536 tnext
= (TypeBasic
*) Type::tfloat32
;
2539 case TY::Tcomplex64
:
2540 tnext
= (TypeBasic
*) Type::tfloat64
;
2543 case TY::Tcomplex80
:
2544 tnext
= (TypeBasic
*) Type::tfloat80
;
2551 this->result_
= build_complex (build_ctype (e
->type
),
2552 build_float_cst (creall (e
->value
), tnext
),
2553 build_float_cst (cimagl (e
->value
), tnext
));
2556 /* Build a string literal, all strings are null terminated except for
2559 void visit (StringExp
*e
) final override
2561 Type
*tb
= e
->type
->toBasetype ();
2562 tree type
= build_ctype (e
->type
);
2564 if (tb
->ty
== TY::Tsarray
)
2566 /* Turn the string into a constructor for the static array. */
2567 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
2568 vec_safe_reserve (elms
, e
->len
);
2569 tree etype
= TREE_TYPE (type
);
2571 for (size_t i
= 0; i
< e
->len
; i
++)
2573 tree value
= build_integer_cst (e
->getCodeUnit (i
), etype
);
2574 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), value
);
2577 tree ctor
= build_constructor (type
, elms
);
2578 TREE_CONSTANT (ctor
) = 1;
2579 this->result_
= ctor
;
2583 /* Copy the string contents to a null terminated string. */
2584 dinteger_t length
= (e
->len
* e
->sz
);
2585 char *string
= XALLOCAVEC (char, length
+ 1);
2587 memcpy (string
, e
->string
, length
);
2588 string
[length
] = '\0';
2590 /* String value and type includes the null terminator. */
2591 tree value
= build_string (length
, string
);
2592 TREE_TYPE (value
) = make_array_type (tb
->nextOf (), length
+ 1);
2593 value
= build_address (value
);
2595 if (tb
->ty
== TY::Tarray
)
2596 value
= d_array_value (type
, size_int (e
->len
), value
);
2598 TREE_CONSTANT (value
) = 1;
2599 this->result_
= d_convert (type
, value
);
2603 /* Build a tuple literal. Just an argument list that may have
2604 side effects that need evaluation. */
2606 void visit (TupleExp
*e
) final override
2608 tree result
= NULL_TREE
;
2611 result
= build_expr (e
->e0
, this->constp_
, true);
2613 for (size_t i
= 0; i
< e
->exps
->length
; ++i
)
2615 Expression
*exp
= (*e
->exps
)[i
];
2616 result
= compound_expr (result
, build_expr (exp
, this->constp_
, true));
2619 if (result
== NULL_TREE
)
2622 this->result_
= result
;
2625 /* Build an array literal. The common type of the all elements is taken to
2626 be the type of the array element, and all elements are implicitly
2627 converted to that type. */
2629 void visit (ArrayLiteralExp
*e
) final override
2631 Type
*tb
= e
->type
->toBasetype ();
2633 /* Implicitly convert void[n] to ubyte[n]. */
2634 if (tb
->ty
== TY::Tsarray
&& tb
->nextOf ()->toBasetype ()->ty
== TY::Tvoid
)
2635 tb
= Type::tuns8
->sarrayOf (tb
->isTypeSArray ()->dim
->toUInteger ());
2637 gcc_assert (tb
->ty
== TY::Tarray
|| tb
->ty
== TY::Tsarray
2638 || tb
->ty
== TY::Tpointer
);
2640 /* Handle empty array literals. */
2641 if (e
->elements
->length
== 0)
2643 if (tb
->ty
== TY::Tarray
)
2644 this->result_
= d_array_value (build_ctype (e
->type
),
2645 size_int (0), null_pointer_node
);
2647 this->result_
= build_constructor (make_array_type (tb
->nextOf (), 0),
2653 /* Build an expression that assigns the expressions in ELEMENTS to
2655 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
2656 vec_safe_reserve (elms
, e
->elements
->length
);
2657 bool constant_p
= true;
2658 tree saved_elems
= NULL_TREE
;
2660 Type
*etype
= tb
->nextOf ();
2661 tree satype
= make_array_type (etype
, e
->elements
->length
);
2663 for (size_t i
= 0; i
< e
->elements
->length
; i
++)
2665 Expression
*expr
= e
->getElement (i
);
2666 tree value
= build_expr (expr
, this->constp_
, true);
2668 /* Only append nonzero values, the backend will zero out the rest
2669 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2670 if (!initializer_zerop (value
))
2672 if (!TREE_CONSTANT (value
))
2675 /* Split construction of values out of the constructor if there
2676 may be side effects. */
2677 tree init
= stabilize_expr (&value
);
2678 if (init
!= NULL_TREE
)
2679 saved_elems
= compound_expr (saved_elems
, init
);
2681 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
),
2682 convert_expr (value
, expr
->type
, etype
));
2686 /* Now return the constructor as the correct type. For static arrays there
2687 is nothing else to do. For dynamic arrays, return a two field struct.
2688 For pointers, return the address. */
2689 tree ctor
= build_constructor (satype
, elms
);
2690 tree type
= build_ctype (e
->type
);
2692 /* Nothing else to do for static arrays. */
2693 if (tb
->ty
== TY::Tsarray
|| this->constp_
)
2695 /* Can't take the address of the constructor, so create an anonymous
2696 static symbol, and then refer to it. */
2697 if (tb
->ty
!= TY::Tsarray
)
2699 tree decl
= build_artificial_decl (TREE_TYPE (ctor
), ctor
, "A");
2700 ctor
= build_address (decl
);
2701 if (tb
->ty
== TY::Tarray
)
2702 ctor
= d_array_value (type
, size_int (e
->elements
->length
), ctor
);
2704 /* Immutable literals can be placed in rodata. */
2705 if (tb
->isImmutable ())
2706 TREE_READONLY (decl
) = 1;
2709 rest_of_decl_compilation (decl
, 1, 0);
2712 /* If the array literal is readonly or static. */
2714 TREE_CONSTANT (ctor
) = 1;
2715 if (constant_p
&& initializer_constant_valid_p (ctor
, TREE_TYPE (ctor
)))
2716 TREE_STATIC (ctor
) = 1;
2718 /* Use memset to fill any alignment holes in the array. */
2719 if (!this->constp_
&& !this->literalp_
)
2721 TypeStruct
*ts
= etype
->baseElemOf ()->isTypeStruct ();
2723 if (ts
!= NULL
&& (!identity_compare_p (ts
->sym
)
2724 || ts
->sym
->isUnionDeclaration ()))
2726 tree var
= build_local_temp (TREE_TYPE (ctor
));
2727 tree init
= build_memset_call (var
);
2728 /* Evaluate memset() first, then any saved elements. */
2729 saved_elems
= compound_expr (init
, saved_elems
);
2730 ctor
= compound_expr (modify_expr (var
, ctor
), var
);
2734 this->result_
= compound_expr (saved_elems
, d_convert (type
, ctor
));
2736 else if (e
->onstack
)
2738 /* Array literal for a `scope' dynamic array. */
2739 gcc_assert (tb
->ty
== TY::Tarray
);
2740 ctor
= force_target_expr (ctor
);
2741 this->result_
= d_array_value (type
, size_int (e
->elements
->length
),
2742 build_address (ctor
));
2746 /* Allocate space on the memory managed heap. */
2747 tree mem
= build_libcall (LIBCALL_ARRAYLITERALTX
,
2748 etype
->pointerTo (), 2,
2749 build_typeinfo (e
, etype
->arrayOf ()),
2750 size_int (e
->elements
->length
));
2751 mem
= d_save_expr (mem
);
2753 /* Now copy the constructor into memory. */
2754 tree size
= size_mult_expr (size_int (e
->elements
->length
),
2755 size_int (tb
->nextOf ()->size ()));
2757 tree result
= build_memcpy_call (mem
, build_address (ctor
), size
);
2759 /* Return the array pointed to by MEM. */
2760 result
= compound_expr (result
, mem
);
2762 if (tb
->ty
== TY::Tarray
)
2763 result
= d_array_value (type
, size_int (e
->elements
->length
), result
);
2765 this->result_
= compound_expr (saved_elems
, result
);
2769 /* Build an associative array literal. The common type of the all keys is
2770 taken to be the key type, and common type of all values the value type.
2771 All keys and values are then implicitly converted as needed. */
2773 void visit (AssocArrayLiteralExp
*e
) final override
2775 /* Want the mutable type for typeinfo reference. */
2776 Type
*tb
= e
->type
->toBasetype ()->mutableOf ();
2778 /* Handle empty assoc array literals. */
2779 TypeAArray
*ta
= tb
->isTypeAArray ();
2780 if (e
->keys
->length
== 0)
2782 this->result_
= build_constructor (build_ctype (ta
), NULL
);
2786 /* Build an expression that assigns all expressions in KEYS
2787 to a constructor. */
2788 tree akeys
= build_array_from_exprs (ta
->index
->sarrayOf (e
->keys
->length
),
2789 e
->keys
, this->constp_
);
2790 tree init
= stabilize_expr (&akeys
);
2792 /* Do the same with all expressions in VALUES. */
2793 tree avals
= build_array_from_exprs (ta
->next
->sarrayOf (e
->values
->length
),
2794 e
->values
, this->constp_
);
2795 init
= compound_expr (init
, stabilize_expr (&avals
));
2797 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2798 tree keys
= d_array_value (build_ctype (ta
->index
->arrayOf ()),
2799 size_int (e
->keys
->length
),
2800 build_address (akeys
));
2801 tree vals
= d_array_value (build_ctype (ta
->next
->arrayOf ()),
2802 size_int (e
->values
->length
),
2803 build_address (avals
));
2805 tree mem
= build_libcall (LIBCALL_ASSOCARRAYLITERALTX
, Type::tvoidptr
, 3,
2806 build_typeinfo (e
, ta
), keys
, vals
);
2808 /* Return an associative array pointed to by MEM. */
2809 tree aatype
= build_ctype (ta
);
2810 vec
<constructor_elt
, va_gc
> *ce
= NULL
;
2811 CONSTRUCTOR_APPEND_ELT (ce
, TYPE_FIELDS (aatype
), mem
);
2813 tree result
= build_nop (build_ctype (e
->type
),
2814 build_constructor (aatype
, ce
));
2815 this->result_
= compound_expr (init
, result
);
2818 /* Build a struct literal. */
2820 void visit (StructLiteralExp
*e
) final override
2822 /* Handle empty struct literals. */
2823 if (e
->elements
== NULL
|| e
->sd
->fields
.length
== 0)
2825 this->result_
= build_constructor (build_ctype (e
->type
), NULL
);
2829 /* Building sinit trees are delayed until after frontend semantic
2830 processing has complete. Build the static initializer now. */
2831 if (e
->useStaticInit
&& !this->constp_
)
2833 tree init
= aggregate_initializer_decl (e
->sd
);
2835 /* If initializing a symbol, don't forget to set it. */
2838 tree var
= build_deref (e
->sym
);
2839 init
= compound_expr (modify_expr (var
, init
), var
);
2842 this->result_
= init
;
2846 /* Build a constructor that assigns the expressions in ELEMENTS
2847 at each field index that has been filled in. */
2848 vec
<constructor_elt
, va_gc
> *ve
= NULL
;
2849 tree saved_elems
= NULL_TREE
;
2851 /* CTFE may fill the hidden pointer by NullExp. */
2852 gcc_assert (e
->elements
->length
<= e
->sd
->fields
.length
);
2854 Type
*tb
= e
->type
->toBasetype ();
2855 gcc_assert (tb
->ty
== TY::Tstruct
);
2857 for (size_t i
= 0; i
< e
->elements
->length
; i
++)
2859 Expression
*exp
= (*e
->elements
)[i
];
2863 VarDeclaration
*field
= e
->sd
->fields
[i
];
2864 Type
*type
= exp
->type
->toBasetype ();
2865 Type
*ftype
= field
->type
->toBasetype ();
2866 tree value
= NULL_TREE
;
2868 if (ftype
->ty
== TY::Tsarray
&& !same_type_p (type
, ftype
))
2870 /* Initialize a static array with a single element. */
2871 tree elem
= build_expr (exp
, this->constp_
, true);
2872 saved_elems
= compound_expr (saved_elems
, stabilize_expr (&elem
));
2873 elem
= d_save_expr (elem
);
2875 if (initializer_zerop (elem
))
2876 value
= build_constructor (build_ctype (ftype
), NULL
);
2878 value
= build_array_from_val (ftype
, elem
);
2882 value
= convert_expr (build_expr (exp
, this->constp_
, true),
2883 exp
->type
, field
->type
);
2886 /* Split construction of values out of the constructor. */
2887 saved_elems
= compound_expr (saved_elems
, stabilize_expr (&value
));
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
->length
!= e
->sd
->fields
.length
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. */
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
);
2917 /* Construct the struct literal for run-time. */
2920 /* Store the result in a symbol to initialize the literal. */
2921 tree var
= build_deref (e
->sym
);
2922 ctor
= compound_expr (modify_expr (var
, ctor
), var
);
2924 else if (!this->literalp_
)
2926 /* Use memset to fill any alignment holes in the object. */
2927 if (!identity_compare_p (e
->sd
) || e
->sd
->isUnionDeclaration ())
2929 tree var
= build_local_temp (TREE_TYPE (ctor
));
2930 tree init
= build_memset_call (var
);
2931 /* Evaluate memset() first, then any saved element constructors. */
2932 saved_elems
= compound_expr (init
, saved_elems
);
2933 ctor
= compound_expr (modify_expr (var
, ctor
), var
);
2937 this->result_
= compound_expr (saved_elems
, ctor
);
2940 /* Build a null literal. */
2942 void visit (NullExp
*e
) final override
2944 this->result_
= build_typeof_null_value (e
->type
);
2947 /* Build a vector literal. */
2949 void visit (VectorExp
*e
) final override
2951 /* First handle array literal expressions. */
2952 if (e
->e1
->op
== EXP::arrayLiteral
)
2954 ArrayLiteralExp
*ale
= e
->e1
->isArrayLiteralExp ();
2955 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
2956 bool constant_p
= true;
2957 tree type
= build_ctype (e
->type
);
2959 vec_safe_reserve (elms
, ale
->elements
->length
);
2960 for (size_t i
= 0; i
< ale
->elements
->length
; i
++)
2962 Expression
*expr
= ale
->getElement (i
);
2963 tree value
= d_convert (TREE_TYPE (type
),
2964 build_expr (expr
, this->constp_
, true));
2965 if (!CONSTANT_CLASS_P (value
))
2968 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), value
);
2971 /* Build a VECTOR_CST from a constant vector constructor. */
2973 this->result_
= build_vector_from_ctor (type
, elms
);
2975 this->result_
= build_constructor (type
, elms
);
2977 else if (e
->e1
->type
->toBasetype ()->ty
== TY::Tsarray
)
2979 /* Build a vector representation from a static array. */
2980 this->result_
= convert_expr (build_expr (e
->e1
, this->constp_
),
2981 e
->e1
->type
, e
->type
);
2985 /* Build constructor from single value. */
2986 tree type
= build_ctype (e
->type
);
2987 tree value
= d_convert (TREE_TYPE (type
),
2988 build_expr (e
->e1
, this->constp_
, true));
2989 this->result_
= build_vector_from_val (type
, value
);
2993 /* Build a static array representation of a vector expression. */
2995 void visit (VectorArrayExp
*e
) final override
2997 this->result_
= convert_expr (build_expr (e
->e1
, this->constp_
, true),
2998 e
->e1
->type
, e
->type
);
3001 /* Build a static class literal, return its reference. */
3003 void visit (ClassReferenceExp
*e
) final override
3005 /* The result of build_new_class_expr is a RECORD_TYPE, we want
3007 tree var
= build_address (build_new_class_expr (e
));
3009 /* If the type of this literal is an interface, the we must add the
3010 interface offset to symbol. */
3013 TypeClass
*tc
= e
->type
->toBasetype ()->isTypeClass ();
3014 InterfaceDeclaration
*to
= tc
->sym
->isInterfaceDeclaration ();
3018 ClassDeclaration
*from
= e
->originalClass ();
3021 gcc_assert (to
->isBaseOf (from
, &offset
) != 0);
3024 var
= build_offset (var
, size_int (offset
));
3028 this->result_
= var
;
3031 /* Build an uninitialized value, generated from void initializers. */
3033 void visit (VoidInitExp
*e
) final override
3035 /* The front-end only generates these for the initializer of globals.
3036 Represent `void' as zeroes, regardless of the type's default value. */
3037 gcc_assert (this->constp_
);
3038 this->result_
= build_zero_cst (build_ctype (e
->type
));
3041 /* These expressions are mainly just a placeholders in the frontend.
3042 We shouldn't see them here. */
3044 void visit (ScopeExp
*e
) final override
3046 error_at (make_location_t (e
->loc
), "%qs is not an expression",
3048 this->result_
= error_mark_node
;
3051 void visit (TypeExp
*e
) final override
3053 error_at (make_location_t (e
->loc
), "type %qs is not an expression",
3055 this->result_
= error_mark_node
;
3060 /* Main entry point for ExprVisitor interface to generate code for
3061 the Expression AST class E. If CONST_P is true, then E is a
3062 constant expression. If LITERAL_P is true, then E is a value used
3063 in the initialization of another literal. */
3066 build_expr (Expression
*e
, bool const_p
, bool literal_p
)
3068 ExprVisitor v
= ExprVisitor (const_p
, literal_p
);
3069 location_t saved_location
= input_location
;
3071 input_location
= make_location_t (e
->loc
);
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",
3081 return error_mark_node
;
3087 /* Same as build_expr, but also calls destructors on any temporaries. */
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
);
3106 /* Same as build_expr_dtor, but handles the result of E as a return value. */
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. */
3117 /* If we are returning a reference, take the address. */
3118 result
= convert_expr (result
, e
->type
, type
);
3119 result
= build_address (result
);
3122 result
= convert_for_rvalue (result
, e
->type
, type
);
3124 /* The decl to store the return expression. */
3125 tree decl
= DECL_RESULT (cfun
->decl
);
3127 /* Split comma expressions, so that the result is returned directly. */
3128 tree expr
= stabilize_expr (&result
);
3129 result
= build_assign (INIT_EXPR
, decl
, result
);
3130 result
= compound_expr (expr
, return_expr (result
));
3132 /* May nest the return expression inside the try/finally expression. */
3133 if (saved_vars
!= vec_safe_length (d_function_chain
->vars_in_scope
))
3135 result
= fold_build_cleanup_point_expr (TREE_TYPE (result
), result
);
3136 vec_safe_truncate (d_function_chain
->vars_in_scope
, saved_vars
);