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)
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
*)
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
),
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
);
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
);
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
);
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
);
383 StructDeclaration
*sd
= t1elem
->isTypeStruct ()->sym
;
385 result
= build_array_struct_comparison (code
, sd
, t1len
,
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
);
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
403 if (tb1
->ty
== TY::Tsarray
&& tb2
->ty
== TY::Tsarray
)
404 gcc_assert (tb1
->size () == tb2
->size ());
407 tree tlencmp
= build_boolop (code
, t1len
, t2len
);
408 if (e
->op
== EXP::equal
)
409 result
= build_boolop (TRUTH_ANDIF_EXPR
, tlencmp
, result
);
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
;
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
),
457 if (e
->op
== EXP::notEqual
)
458 result
= build1 (TRUTH_NOT_EXPR
, build_ctype (e
->type
), result
);
460 this->result_
= result
;
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,
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 ();
503 case EXP::lessOrEqual
:
511 case EXP::greaterOrEqual
:
515 case EXP::greaterThan
:
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 ());
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
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
));
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
),
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
)
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
);
596 this->result_
= complex_expr (build_ctype (e
->type
), t2
, t1
);
601 code
= (e
->op
== EXP::add
)
602 ? PLUS_EXPR
: MINUS_EXPR
;
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
;
623 code
= e
->e1
->type
->isintegral ()
624 ? TRUNC_DIV_EXPR
: RDIV_EXPR
;
628 code
= e
->e1
->type
->isfloating ()
629 ? FLOAT_MOD_EXPR
: TRUNC_MOD_EXPR
;
648 case EXP::rightShift
:
652 case EXP::unsignedRightShift
:
653 code
= UNSIGNED_RSHIFT_EXPR
;
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 ();
675 if (tb1
->ty
== TY::Tarray
|| tb1
->ty
== TY::Tsarray
)
676 etype
= tb1
->nextOf ();
678 etype
= tb2
->nextOf ();
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] */
688 for (Expression
*ex
= e
->e1
; ex
->op
== EXP::concatenate
;)
690 if (ex
->op
== EXP::concatenate
)
692 ex
= ex
->isCatExp ()->e1
;
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
;
706 for (Expression
*oe
= ce
->e2
; oe
!= NULL
;
707 (ce
->e1
->op
!= EXP::concatenate
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. */
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
);
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
)
751 Expression
*e1b
= e
->e1
;
768 code
= e
->e1
->type
->isintegral ()
769 ? TRUNC_DIV_EXPR
: RDIV_EXPR
;
773 code
= e
->e1
->type
->isfloating ()
774 ? FLOAT_MOD_EXPR
: TRUNC_MOD_EXPR
;
792 case EXP::leftShiftAssign
:
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
));
807 code
= (e
->op
== EXP::rightShiftAssign
) ? RSHIFT_EXPR
: UNSIGNED_RSHIFT_EXPR
;
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
));
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
),
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
);
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
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
);
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
);
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,
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
);
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
);
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
),
1012 tree t2ptrcmp
= build_boolop (LE_EXPR
,
1013 build_offset (t2ptr
, size
),
1015 tree toverlap
= build_boolop (TRUTH_ORIF_EXPR
, t1ptrcmp
,
1018 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */
1019 tree tassert
= build_array_bounds_call (e
->loc
);
1020 tree tboundscheck
= build_boolop (TRUTH_ANDIF_EXPR
,
1023 result
= build_condition (void_type_node
, tboundscheck
,
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
));
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
));
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
));
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
);
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
);
1123 tree result
= build_assign (modifycode
, t1
, t2
);
1124 this->result_
= compound_expr (init
, result
);
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
));
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
);
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
;
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
)
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
));
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
);
1248 libcall
= LIBCALL_AAGETY
;
1249 ptr
= build_address (build_expr (e
->e1
));
1250 tinfo
= build_typeinfo (e
, tb1
->unSharedOf ()->mutableOf ());
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,
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
),
1275 this->result_
= indirect_ref (build_ctype (e
->type
), result
);
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
);
1287 gcc_assert (e
->lengthVar
== NULL
);
1289 /* The __dollar variable just becomes a placeholder for the
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
));
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. */
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
;
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
);
1384 gcc_assert (e
->lengthVar
== NULL
);
1386 /* The __dollar variable just becomes a placeholder for the
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
);
1416 gcc_assert (tb
->ty
== TY::Tarray
);
1418 /* Generate bounds checking code. */
1419 tree newlength
= build_bounds_slice_condition (e
, lwr_tree
, upr_tree
,
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
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
);
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
);
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,
1484 build_typeinfo (e
, tkey
),
1485 build_address (index
));
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
);
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
)
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
;
1589 result
= component_ref (result
, get_symbol_decl (field
));
1590 this->result_
= result
;
1594 else if (field
->offset
> offset
)
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
);
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. */
1620 sle
->sym
= build_artificial_decl (build_ctype (sle
->type
),
1622 DECL_INITIAL (sle
->sym
) = build_expr (sle
, true);
1623 d_pushdecl (sle
->sym
);
1624 rest_of_decl_compilation (sle
->sym
, 1, 0);
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 ();
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. */
1679 callee
= build_address (fndecl
);
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
);
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
);
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
;
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
);
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));
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
);
1836 if (e
->func
->isNested () && !e
->func
->isThis ())
1838 if (e
->e1
->op
== EXP::null_
)
1839 object
= build_expr (e
->e1
);
1841 object
= get_frame_for_symbol (e
->func
);
1843 fndecl
= build_address (get_symbol_decl (e
->func
));
1847 if (!e
->func
->isThis ())
1849 error ("delegates are only for non-static functions");
1850 this->result_
= error_mark_node
;
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
);
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. */
1900 if (!vd
->isField ())
1901 this->result_
= get_decl_tree (vd
);
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
));
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
;
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 ();
1947 tmsg
= build_expr_dtor (e
->msg
);
1948 libcall
= unittest_p
? LIBCALL_UNITTEST_MSG
: LIBCALL_ASSERT_MSG
;
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
)
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);
1991 /* Assert contracts are turned off. */
1992 this->result_
= void_node
;
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. */
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
);
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
));
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;
2097 object
= get_frame_for_symbol (e
->fd
);
2098 this->result_
= build_method_call (func
, object
, e
->fd
->type
);
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
)));
2129 result
= build_address (result
);
2132 result
= d_convert (build_ctype (e
->type
), result
);
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
;
2153 else if (e
->var
->ident
== Identifier::idPool ("__ctfe"))
2155 /* __ctfe is always false at run-time. */
2156 this->result_
= integer_zero_node
;
2160 /* This check is same as is done in FuncExp for lambdas. */
2161 FuncLiteralDeclaration
*fld
= e
->var
->isFuncLiteralDeclaration ();
2164 if (fld
->tok
== TOK::reserved
)
2166 fld
->tok
= TOK::function_
;
2170 /* Compiler the function literal body. */
2171 build_decl_tree (fld
);
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
)
2185 error_at (make_location_t (e
->loc
), "recursive reference %qs",
2190 init
= build_expr (initializerToExpression (var
->_init
), true);
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
);
2204 error_at (make_location_t (e
->loc
), "non-constant expression %qs",
2207 if (init
!= NULL_TREE
)
2208 this->result_
= init
;
2210 this->result_
= error_mark_node
;
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
);
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
;
2255 result
= get_decl_tree (e
->var
);
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 ();
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
;
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
));
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
;
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
);
2320 ClassDeclaration
*ocd
= outer
->isClassDeclaration ();
2322 gcc_assert (ocd
->isBaseOf (tcd
, &offset
));
2323 /* Could just add offset... */
2324 value
= convert_expr (value
, e
->thisexp
->type
, ocd
->type
);
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. */
2343 result
= d_build_call_expr (e
->member
, new_call
, e
->arguments
);
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
;
2361 /* Cannot new an opaque struct. */
2362 if (sd
->size (e
->loc
) == 0)
2364 this->result_
= d_convert (build_ctype (e
->type
),
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. */
2391 result
= d_build_call_expr (e
->member
, new_call
, e
->arguments
);
2397 /* If we have a user supplied initializer, then set-up with a
2399 if (e
->arguments
!= NULL
&& sd
->fields
.length
!= 0)
2401 StructLiteralExp
*se
= StructLiteralExp::create (e
->loc
, sd
,
2404 new_call
= d_save_expr (new_call
);
2405 se
->type
= sd
->type
;
2407 result
= compound_expr (build_expr (se
), new_call
);
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
);
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
),
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 ();
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
);
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
),
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
);
2511 result
= compound_expr (build_expr (e
->argprefix
), result
);
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
)
2540 switch (e
->type
->toBasetype ()->ty
)
2542 case TY::Tcomplex32
:
2543 tnext
= (TypeBasic
*) Type::tfloat32
;
2546 case TY::Tcomplex64
:
2547 tnext
= (TypeBasic
*) Type::tfloat64
;
2550 case TY::Tcomplex80
:
2551 tnext
= (TypeBasic
*) Type::tfloat80
;
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
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
;
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);
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
;
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
)
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
);
2654 this->result_
= build_constructor (make_array_type (tb
->nextOf (), 0),
2660 /* Build an expression that assigns the expressions in ELEMENTS to
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
))
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
);
2712 rest_of_decl_compilation (decl
, 1, 0);
2715 /* If the array literal is readonly or static. */
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
));
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
);
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
);
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. */
2833 tree var
= build_deref (e
->sym
);
2834 init
= compound_expr (modify_expr (var
, init
), var
);
2837 this->result_
= init
;
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
];
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
);
2873 value
= build_array_from_val (ftype
, elem
);
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. */
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
);
2912 /* Construct the struct literal for run-time. */
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
))
2963 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), value
);
2966 /* Build a VECTOR_CST from a constant vector constructor. */
2968 this->result_
= build_vector_from_ctor (type
, elms
);
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
);
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
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. */
3008 TypeClass
*tc
= e
->type
->toBasetype ()->isTypeClass ();
3009 InterfaceDeclaration
*to
= tc
->sym
->isInterfaceDeclaration ();
3013 ClassDeclaration
*from
= e
->originalClass ();
3016 gcc_assert (to
->isBaseOf (from
, &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",
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",
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. */
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
);
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",
3076 return error_mark_node
;
3082 /* Same as build_expr, but also calls destructors on any temporaries. */
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
);
3101 /* Same as build_expr_dtor, but handles the result of E as a return value. */
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. */
3112 /* If we are returning a reference, take the address. */
3113 result
= convert_expr (result
, e
->type
, type
);
3114 result
= build_address (result
);
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
);