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