1 /* expr.cc -- Lower D frontend expressions to GCC trees.
2 Copyright (C) 2015-2019 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 if (!tb1
->iscomplex ())
286 this->result_
= build_float_identity (code
, t1
, t2
);
289 /* Compare the real and imaginary parts separately. */
290 tree req
= build_float_identity (code
, real_part (t1
),
292 tree ieq
= build_float_identity (code
, imaginary_part (t1
),
293 imaginary_part (t2
));
296 this->result_
= build_boolop (TRUTH_ANDIF_EXPR
, req
, ieq
);
298 this->result_
= build_boolop (TRUTH_ORIF_EXPR
, req
, ieq
);
301 else if (tb1
->ty
== Tstruct
)
303 /* For struct objects, identity is defined as bits in operands being
304 identical also. Alignment holes in structs are ignored. */
305 StructDeclaration
*sd
= ((TypeStruct
*) tb1
)->sym
;
306 tree t1
= build_expr (e
->e1
);
307 tree t2
= build_expr (e
->e2
);
309 gcc_assert (same_type_p (tb1
, tb2
));
311 this->result_
= build_struct_comparison (code
, sd
, t1
, t2
);
315 /* For operands of other types, identity is defined as being the
316 same as equality expressions. */
317 tree t1
= build_expr (e
->e1
);
318 tree t2
= build_expr (e
->e2
);
319 this->result_
= d_convert (build_ctype (e
->type
),
320 build_boolop (code
, t1
, t2
));
324 /* Build an equality expression, which compare the two operands for either
325 equality or inequality. Operands go through the usual conversions to bring
326 them to a common type before comparison. The result type is bool. */
328 void visit (EqualExp
*e
)
330 Type
*tb1
= e
->e1
->type
->toBasetype ();
331 Type
*tb2
= e
->e2
->type
->toBasetype ();
332 tree_code code
= (e
->op
== TOKequal
) ? EQ_EXPR
: NE_EXPR
;
334 if ((tb1
->ty
== Tsarray
|| tb1
->ty
== Tarray
)
335 && (tb2
->ty
== Tsarray
|| tb2
->ty
== Tarray
))
337 /* For static and dynamic arrays, equality is defined as the lengths of
338 the arrays matching, and all the elements are equal. */
339 Type
*t1elem
= tb1
->nextOf ()->toBasetype ();
340 Type
*t2elem
= tb1
->nextOf ()->toBasetype ();
342 /* Check if comparisons of arrays can be optimized using memcmp.
343 This will inline EQ expressions as:
344 e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
345 Or when generating a NE expression:
346 e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */
347 if ((t1elem
->isintegral () || t1elem
->ty
== Tvoid
348 || (t1elem
->ty
== Tstruct
&& !((TypeStruct
*)t1elem
)->sym
->xeq
))
349 && t1elem
->ty
== t2elem
->ty
)
351 tree t1
= d_array_convert (e
->e1
);
352 tree t2
= d_array_convert (e
->e2
);
355 /* Make temporaries to prevent multiple evaluations. */
356 tree t1saved
= d_save_expr (t1
);
357 tree t2saved
= d_save_expr (t2
);
359 /* Length of arrays, for comparisons done before calling memcmp. */
360 tree t1len
= d_array_length (t1saved
);
361 tree t2len
= d_array_length (t2saved
);
363 /* Reference to array data. */
364 tree t1ptr
= d_array_ptr (t1saved
);
365 tree t2ptr
= d_array_ptr (t2saved
);
367 /* Compare arrays using memcmp if possible, otherwise for structs,
368 each field is compared inline. */
369 if (t1elem
->ty
!= Tstruct
370 || identity_compare_p (((TypeStruct
*) t1elem
)->sym
))
372 tree size
= size_mult_expr (t1len
, size_int (t1elem
->size ()));
373 tree tmemcmp
= builtin_decl_explicit (BUILT_IN_MEMCMP
);
375 result
= build_call_expr (tmemcmp
, 3, t1ptr
, t2ptr
, size
);
376 result
= build_boolop (code
, result
, integer_zero_node
);
380 StructDeclaration
*sd
= ((TypeStruct
*) t1elem
)->sym
;
382 result
= build_array_struct_comparison (code
, sd
, t1len
,
386 /* Check array length first before passing to memcmp.
387 For equality expressions, this becomes:
388 (e1.length == 0 || memcmp);
389 Otherwise for inequality:
390 (e1.length != 0 && memcmp); */
391 tree tsizecmp
= build_boolop (code
, t1len
, size_zero_node
);
392 if (e
->op
== TOKequal
)
393 result
= build_boolop (TRUTH_ORIF_EXPR
, tsizecmp
, result
);
395 result
= build_boolop (TRUTH_ANDIF_EXPR
, tsizecmp
, result
);
397 /* Finally, check if lengths of both arrays match if dynamic.
398 The frontend should have already guaranteed that static arrays
400 if (tb1
->ty
== Tsarray
&& tb2
->ty
== Tsarray
)
401 gcc_assert (tb1
->size () == tb2
->size ());
404 tree tlencmp
= build_boolop (code
, t1len
, t2len
);
405 if (e
->op
== TOKequal
)
406 result
= build_boolop (TRUTH_ANDIF_EXPR
, tlencmp
, result
);
408 result
= build_boolop (TRUTH_ORIF_EXPR
, tlencmp
, result
);
411 /* Ensure left-to-right order of evaluation. */
412 if (TREE_SIDE_EFFECTS (t2
))
413 result
= compound_expr (t2saved
, result
);
415 if (TREE_SIDE_EFFECTS (t1
))
416 result
= compound_expr (t1saved
, result
);
418 this->result_
= result
;
422 /* Use _adEq2() to compare each element. */
423 Type
*t1array
= t1elem
->arrayOf ();
424 tree result
= build_libcall (LIBCALL_ADEQ2
, e
->type
, 3,
425 d_array_convert (e
->e1
),
426 d_array_convert (e
->e2
),
427 build_typeinfo (e
->loc
, t1array
));
429 if (e
->op
== TOKnotequal
)
430 result
= build1 (TRUTH_NOT_EXPR
, build_ctype (e
->type
), result
);
432 this->result_
= result
;
435 else if (tb1
->ty
== Tstruct
)
437 /* Equality for struct objects means the logical product of all
438 equality results of the corresponding object fields. */
439 StructDeclaration
*sd
= ((TypeStruct
*) tb1
)->sym
;
440 tree t1
= build_expr (e
->e1
);
441 tree t2
= build_expr (e
->e2
);
443 gcc_assert (same_type_p (tb1
, tb2
));
445 this->result_
= build_struct_comparison (code
, sd
, t1
, t2
);
447 else if (tb1
->ty
== Taarray
&& tb2
->ty
== Taarray
)
449 /* Use _aaEqual() for associative arrays. */
450 TypeAArray
*taa1
= (TypeAArray
*) tb1
;
451 tree result
= build_libcall (LIBCALL_AAEQUAL
, e
->type
, 3,
452 build_typeinfo (e
->loc
, taa1
),
456 if (e
->op
== TOKnotequal
)
457 result
= build1 (TRUTH_NOT_EXPR
, build_ctype (e
->type
), result
);
459 this->result_
= result
;
463 /* For operands of other types, equality is defined as the bit pattern
464 of the type matches exactly. */
465 tree t1
= build_expr (e
->e1
);
466 tree t2
= build_expr (e
->e2
);
468 this->result_
= d_convert (build_ctype (e
->type
),
469 build_boolop (code
, t1
, t2
));
473 /* Build an `in' expression. This is a condition to see if an element
474 exists in an associative array. The result is a pointer to the
475 element, or null if false. */
477 void visit (InExp
*e
)
479 Type
*tb2
= e
->e2
->type
->toBasetype ();
480 gcc_assert (tb2
->ty
== Taarray
);
482 Type
*tkey
= ((TypeAArray
*) tb2
)->index
->toBasetype ();
483 tree key
= convert_expr (build_expr (e
->e1
), e
->e1
->type
, tkey
);
485 /* Build a call to _aaInX(). */
486 this->result_
= build_libcall (LIBCALL_AAINX
, e
->type
, 3,
488 build_typeinfo (e
->loc
, tkey
),
489 build_address (key
));
492 /* Build a relational expression. The result type is bool. */
494 void visit (CmpExp
*e
)
496 Type
*tb1
= e
->e1
->type
->toBasetype ();
497 Type
*tb2
= e
->e2
->type
->toBasetype ();
524 if ((tb1
->ty
== Tsarray
|| tb1
->ty
== Tarray
)
525 && (tb2
->ty
== Tsarray
|| tb2
->ty
== Tarray
))
527 /* For static and dynamic arrays, the result of the relational op is
528 the result of the operator applied to the first non-equal element
529 of the array. If two arrays compare equal, but are of different
530 lengths, the shorter array compares as less than the longer. */
531 Type
*telem
= tb1
->nextOf ()->toBasetype ();
533 tree call
= build_libcall (LIBCALL_ADCMP2
, Type::tint32
, 3,
534 d_array_convert (e
->e1
),
535 d_array_convert (e
->e2
),
536 build_typeinfo (e
->loc
, telem
->arrayOf ()));
537 result
= build_boolop (code
, call
, integer_zero_node
);
539 this->result_
= d_convert (build_ctype (e
->type
), result
);
543 /* Simple comparison. */
544 result
= build_boolop (code
, build_expr (e
->e1
), build_expr (e
->e2
));
545 this->result_
= d_convert (build_ctype (e
->type
), result
);
548 /* Build an `and if' expression. If the right operand expression is void,
549 then the resulting type is void. Otherwise the result is bool. */
551 void visit (AndAndExp
*e
)
553 if (e
->e2
->type
->toBasetype ()->ty
!= Tvoid
)
555 tree t1
= build_expr (e
->e1
);
556 tree t2
= build_expr (e
->e2
);
558 t1
= convert_for_condition (t1
, e
->e1
->type
);
559 t2
= convert_for_condition (t2
, e
->e2
->type
);
561 this->result_
= d_convert (build_ctype (e
->type
),
562 build_boolop (TRUTH_ANDIF_EXPR
, t1
, t2
));
566 tree t1
= convert_for_condition (build_expr (e
->e1
), e
->e1
->type
);
567 tree t2
= build_expr_dtor (e
->e2
);
569 this->result_
= build_condition (build_ctype (e
->type
),
574 /* Build an `or if' expression. If the right operand expression is void,
575 then the resulting type is void. Otherwise the result is bool. */
577 void visit (OrOrExp
*e
)
579 if (e
->e2
->type
->toBasetype ()->ty
!= Tvoid
)
581 tree t1
= convert_for_condition (build_expr (e
->e1
), e
->e1
->type
);
582 tree t2
= convert_for_condition (build_expr (e
->e2
), e
->e2
->type
);
584 this->result_
= d_convert (build_ctype (e
->type
),
585 build_boolop (TRUTH_ORIF_EXPR
, t1
, t2
));
589 tree t1
= convert_for_condition (build_expr (e
->e1
), e
->e1
->type
);
590 tree t2
= build_expr_dtor (e
->e2
);
591 tree cond
= build1 (TRUTH_NOT_EXPR
, d_bool_type
, t1
);
593 this->result_
= build_condition (build_ctype (e
->type
),
594 cond
, t2
, void_node
);
598 /* Build a binary operand expression. Operands go through usual arithmetic
599 conversions to bring them to a common type before evaluating. */
601 void visit (BinExp
*e
)
609 if ((e
->e1
->type
->isreal () && e
->e2
->type
->isimaginary ())
610 || (e
->e1
->type
->isimaginary () && e
->e2
->type
->isreal ()))
612 /* If the result is complex, then we can shortcut binary_op.
613 Frontend should have already validated types and sizes. */
614 tree t1
= build_expr (e
->e1
);
615 tree t2
= build_expr (e
->e2
);
618 t2
= build1 (NEGATE_EXPR
, TREE_TYPE (t2
), t2
);
620 if (e
->e1
->type
->isreal ())
621 this->result_
= complex_expr (build_ctype (e
->type
), t1
, t2
);
623 this->result_
= complex_expr (build_ctype (e
->type
), t2
, t1
);
628 code
= (e
->op
== TOKadd
)
629 ? PLUS_EXPR
: MINUS_EXPR
;
637 code
= e
->e1
->type
->isintegral ()
638 ? TRUNC_DIV_EXPR
: RDIV_EXPR
;
642 code
= e
->e1
->type
->isfloating ()
643 ? FLOAT_MOD_EXPR
: TRUNC_MOD_EXPR
;
667 code
= UNSIGNED_RSHIFT_EXPR
;
674 this->result_
= this->binary_op (code
, build_ctype (e
->type
),
675 build_expr (e
->e1
), build_expr (e
->e2
));
679 /* Build a concat expression, which concatenates two or more arrays of the
680 same type, producing a dynamic array with the result. If one operand
681 is an element type, that element is converted to an array of length 1. */
683 void visit (CatExp
*e
)
685 Type
*tb1
= e
->e1
->type
->toBasetype ();
686 Type
*tb2
= e
->e2
->type
->toBasetype ();
689 if (tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
)
690 etype
= tb1
->nextOf ();
692 etype
= tb2
->nextOf ();
694 vec
<tree
, va_gc
> *elemvars
= NULL
;
697 if (e
->e1
->op
== TOKcat
)
699 /* Flatten multiple concatenations to an array.
700 So the expression ((a ~ b) ~ c) becomes [a, b, c] */
703 for (Expression
*ex
= e
->e1
; ex
->op
== TOKcat
;)
705 if (ex
->op
== TOKcat
)
707 ex
= ((CatExp
*) ex
)->e1
;
712 /* Store all concatenation args to a temporary byte[][ndims] array. */
713 Type
*targselem
= Type::tint8
->arrayOf ();
714 tree var
= create_temporary_var (make_array_type (targselem
, ndims
));
715 tree init
= build_constructor (TREE_TYPE (var
), NULL
);
716 vec_safe_push (elemvars
, var
);
718 /* Loop through each concatenation from right to left. */
719 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
723 for (Expression
*oe
= ce
->e2
; oe
!= NULL
;
724 (ce
->e1
->op
!= TOKcat
726 : (ce
= (CatExp
*)ce
->e1
, oe
= ce
->e2
)))
728 tree arg
= d_array_convert (etype
, oe
, &elemvars
);
729 tree index
= size_int (dim
);
730 CONSTRUCTOR_APPEND_ELT (elms
, index
, d_save_expr (arg
));
732 /* Finished pushing all arrays. */
739 /* Check there is no logic bug in constructing byte[][] of arrays. */
740 gcc_assert (dim
== 0);
741 CONSTRUCTOR_ELTS (init
) = elms
;
742 DECL_INITIAL (var
) = init
;
744 tree arrs
= d_array_value (build_ctype (targselem
->arrayOf ()),
745 size_int (ndims
), build_address (var
));
747 result
= build_libcall (LIBCALL_ARRAYCATNTX
, e
->type
, 2,
748 build_typeinfo (e
->loc
, e
->type
), arrs
);
752 /* Handle single concatenation (a ~ b). */
753 result
= build_libcall (LIBCALL_ARRAYCATT
, e
->type
, 3,
754 build_typeinfo (e
->loc
, e
->type
),
755 d_array_convert (etype
, e
->e1
, &elemvars
),
756 d_array_convert (etype
, e
->e2
, &elemvars
));
759 for (size_t i
= 0; i
< vec_safe_length (elemvars
); ++i
)
760 result
= bind_expr ((*elemvars
)[i
], result
);
762 this->result_
= result
;
765 /* Build an assignment operator expression. The right operand is implicitly
766 converted to the type of the left operand, and assigned to it. */
768 void visit (BinAssignExp
*e
)
771 Expression
*e1b
= e
->e1
;
788 code
= e
->e1
->type
->isintegral ()
789 ? TRUNC_DIV_EXPR
: RDIV_EXPR
;
793 code
= e
->e1
->type
->isfloating ()
794 ? FLOAT_MOD_EXPR
: TRUNC_MOD_EXPR
;
818 /* Use the original lhs type before it was promoted. The left operand
819 of `>>>=' does not undergo integral promotions before shifting.
820 Strip off casts just incase anyway. */
821 while (e1b
->op
== TOKcast
)
823 CastExp
*ce
= (CastExp
*) e1b
;
824 gcc_assert (same_type_p (ce
->type
, ce
->to
));
827 code
= (e
->op
== TOKshrass
) ? RSHIFT_EXPR
: UNSIGNED_RSHIFT_EXPR
;
834 tree exp
= this->binop_assignment (code
, e1b
, e
->e2
);
835 this->result_
= convert_expr (exp
, e1b
->type
, e
->type
);
838 /* Build a concat assignment expression. The right operand is appended
839 to the the left operand. */
841 void visit (CatAssignExp
*e
)
843 Type
*tb1
= e
->e1
->type
->toBasetype ();
844 Type
*tb2
= e
->e2
->type
->toBasetype ();
845 Type
*etype
= tb1
->nextOf ()->toBasetype ();
847 if (tb1
->ty
== Tarray
&& tb2
->ty
== Tdchar
848 && (etype
->ty
== Tchar
|| etype
->ty
== Twchar
))
850 /* Append a dchar to a char[] or wchar[] */
851 libcall_fn libcall
= (etype
->ty
== Tchar
)
852 ? LIBCALL_ARRAYAPPENDCD
: LIBCALL_ARRAYAPPENDWD
;
854 this->result_
= build_libcall (libcall
, e
->type
, 2,
855 build_address (build_expr (e
->e1
)),
860 gcc_assert (tb1
->ty
== Tarray
|| tb2
->ty
== Tsarray
);
862 tree tinfo
= build_typeinfo (e
->loc
, e
->type
);
863 tree ptr
= build_address (build_expr (e
->e1
));
865 if ((tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
866 && same_type_p (etype
, tb2
->nextOf ()->toBasetype ()))
868 /* Append an array. */
869 this->result_
= build_libcall (LIBCALL_ARRAYAPPENDT
, e
->type
, 3,
870 tinfo
, ptr
, d_array_convert (e
->e2
));
873 else if (same_type_p (etype
, tb2
))
875 /* Append an element. */
876 tree result
= build_libcall (LIBCALL_ARRAYAPPENDCTX
, e
->type
, 3,
877 tinfo
, ptr
, size_one_node
);
878 result
= d_save_expr (result
);
880 /* Assign e2 to last element. */
881 tree offexp
= d_array_length (result
);
882 offexp
= build2 (MINUS_EXPR
, TREE_TYPE (offexp
),
883 offexp
, size_one_node
);
884 offexp
= d_save_expr (offexp
);
886 tree ptrexp
= d_array_ptr (result
);
887 ptrexp
= void_okay_p (ptrexp
);
888 ptrexp
= build_array_index (ptrexp
, offexp
);
890 /* Evaluate expression before appending. */
891 tree t2
= build_expr (e
->e2
);
892 tree expr
= stabilize_expr (&t2
);
894 t2
= d_save_expr (t2
);
895 result
= modify_expr (build_deref (ptrexp
), t2
);
896 result
= compound_expr (t2
, result
);
898 this->result_
= compound_expr (expr
, result
);
905 /* Build an assignment expression. The right operand is implicitly
906 converted to the type of the left operand, and assigned to it. */
908 void visit (AssignExp
*e
)
910 /* First, handle special assignment semantics. */
912 /* Look for array.length = n; */
913 if (e
->e1
->op
== TOKarraylength
)
915 /* Assignment to an array's length property; resize the array. */
916 ArrayLengthExp
*ale
= (ArrayLengthExp
*) e
->e1
;
917 tree newlength
= convert_expr (build_expr (e
->e2
), e
->e2
->type
,
919 tree ptr
= build_address (build_expr (ale
->e1
));
921 /* Don't want the basetype for the element type. */
922 Type
*etype
= ale
->e1
->type
->toBasetype ()->nextOf ();
923 libcall_fn libcall
= etype
->isZeroInit ()
924 ? LIBCALL_ARRAYSETLENGTHT
: LIBCALL_ARRAYSETLENGTHIT
;
926 tree result
= build_libcall (libcall
, ale
->e1
->type
, 3,
927 build_typeinfo (ale
->loc
, ale
->e1
->type
),
930 this->result_
= d_array_length (result
);
934 /* Look for array[] = n; */
935 if (e
->e1
->op
== TOKslice
)
937 SliceExp
*se
= (SliceExp
*) e
->e1
;
938 Type
*stype
= se
->e1
->type
->toBasetype ();
939 Type
*etype
= stype
->nextOf ()->toBasetype ();
941 /* Determine if we need to run postblit or dtor. */
942 bool postblit
= this->needs_postblit (etype
) && this->lvalue_p (e
->e2
);
943 bool destructor
= this->needs_dtor (etype
);
945 if (e
->memset
& blockAssign
)
947 /* Set a range of elements to one value. */
948 tree t1
= d_save_expr (build_expr (e
->e1
));
949 tree t2
= build_expr (e
->e2
);
952 if ((postblit
|| destructor
) && e
->op
!= TOKblit
)
954 libcall_fn libcall
= (e
->op
== TOKconstruct
)
955 ? LIBCALL_ARRAYSETCTOR
: LIBCALL_ARRAYSETASSIGN
;
956 /* So we can call postblits on const/immutable objects. */
957 Type
*tm
= etype
->unSharedOf ()->mutableOf ();
958 tree ti
= build_typeinfo (e
->loc
, tm
);
960 tree result
= build_libcall (libcall
, Type::tvoid
, 4,
963 d_array_length (t1
), ti
);
964 this->result_
= compound_expr (result
, t1
);
968 if (integer_zerop (t2
))
970 tree tmemset
= builtin_decl_explicit (BUILT_IN_MEMSET
);
971 tree size
= size_mult_expr (d_array_length (t1
),
972 size_int (etype
->size ()));
974 result
= build_call_expr (tmemset
, 3, d_array_ptr (t1
),
975 integer_zero_node
, size
);
978 result
= build_array_set (d_array_ptr (t1
),
979 d_array_length (t1
), t2
);
981 this->result_
= compound_expr (result
, t1
);
985 /* Perform a memcpy operation. */
986 gcc_assert (e
->e2
->type
->ty
!= Tpointer
);
988 if (!postblit
&& !destructor
&& !array_bounds_check ())
990 tree t1
= d_save_expr (d_array_convert (e
->e1
));
991 tree t2
= d_array_convert (e
->e2
);
992 tree tmemcpy
= builtin_decl_explicit (BUILT_IN_MEMCPY
);
993 tree size
= size_mult_expr (d_array_length (t1
),
994 size_int (etype
->size ()));
996 tree result
= build_call_expr (tmemcpy
, 3, d_array_ptr (t1
),
997 d_array_ptr (t2
), size
);
998 this->result_
= compound_expr (result
, t1
);
1000 else if ((postblit
|| destructor
) && e
->op
!= TOKblit
)
1002 /* Generate: _d_arrayassign(ti, from, to)
1003 or: _d_arrayctor(ti, from, to) */
1004 libcall_fn libcall
= (e
->op
== TOKconstruct
)
1005 ? LIBCALL_ARRAYCTOR
: LIBCALL_ARRAYASSIGN
;
1007 this->result_
= build_libcall (libcall
, e
->type
, 3,
1008 build_typeinfo (e
->loc
, etype
),
1009 d_array_convert (e
->e2
),
1010 d_array_convert (e
->e1
));
1014 /* Generate: _d_arraycopy() */
1015 this->result_
= build_libcall (LIBCALL_ARRAYCOPY
, e
->type
, 3,
1016 size_int (etype
->size ()),
1017 d_array_convert (e
->e2
),
1018 d_array_convert (e
->e1
));
1025 /* Look for reference initializations. */
1026 if (e
->memset
& referenceInit
)
1028 gcc_assert (e
->op
== TOKconstruct
|| e
->op
== TOKblit
);
1029 gcc_assert (e
->e1
->op
== TOKvar
);
1031 Declaration
*decl
= ((VarExp
*) e
->e1
)->var
;
1032 if (decl
->storage_class
& (STCout
| STCref
))
1034 tree t2
= convert_for_assignment (build_expr (e
->e2
),
1035 e
->e2
->type
, e
->e1
->type
);
1036 tree t1
= build_expr (e
->e1
);
1037 /* Want reference to lhs, not indirect ref. */
1038 t1
= TREE_OPERAND (t1
, 0);
1039 t2
= build_address (t2
);
1041 this->result_
= indirect_ref (build_ctype (e
->type
),
1042 build_assign (INIT_EXPR
, t1
, t2
));
1047 /* Other types of assignments that may require post construction. */
1048 Type
*tb1
= e
->e1
->type
->toBasetype ();
1049 tree_code modifycode
= (e
->op
== TOKconstruct
) ? INIT_EXPR
: MODIFY_EXPR
;
1051 /* Look for struct assignment. */
1052 if (tb1
->ty
== Tstruct
)
1054 tree t1
= build_expr (e
->e1
);
1055 tree t2
= convert_for_assignment (build_expr (e
->e2
),
1056 e
->e2
->type
, e
->e1
->type
);
1058 /* Look for struct = 0. */
1059 if (e
->e2
->op
== TOKint64
)
1061 /* Use memset to fill struct. */
1062 gcc_assert (e
->op
== TOKblit
);
1063 StructDeclaration
*sd
= ((TypeStruct
*) tb1
)->sym
;
1065 tree tmemset
= builtin_decl_explicit (BUILT_IN_MEMSET
);
1066 tree result
= build_call_expr (tmemset
, 3, build_address (t1
),
1067 t2
, size_int (sd
->structsize
));
1069 /* Maybe set-up hidden pointer to outer scope context. */
1070 if (sd
->isNested ())
1072 tree field
= get_symbol_decl (sd
->vthis
);
1073 tree value
= build_vthis (sd
);
1075 tree vthis_exp
= modify_expr (component_ref (t1
, field
), value
);
1076 result
= compound_expr (result
, vthis_exp
);
1079 this->result_
= compound_expr (result
, t1
);
1082 this->result_
= build_assign (modifycode
, t1
, t2
);
1087 /* Look for static array assignment. */
1088 if (tb1
->ty
== Tsarray
)
1090 /* Look for array = 0. */
1091 if (e
->e2
->op
== TOKint64
)
1093 /* Use memset to fill the array. */
1094 gcc_assert (e
->op
== TOKblit
);
1096 tree t1
= build_expr (e
->e1
);
1097 tree t2
= convert_for_assignment (build_expr (e
->e2
),
1098 e
->e2
->type
, e
->e1
->type
);
1099 tree size
= size_int (e
->e1
->type
->size ());
1101 tree tmemset
= builtin_decl_explicit (BUILT_IN_MEMSET
);
1102 this->result_
= build_call_expr (tmemset
, 3, build_address (t1
),
1107 Type
*etype
= tb1
->nextOf ();
1108 gcc_assert (e
->e2
->type
->toBasetype ()->ty
== Tsarray
);
1110 /* Determine if we need to run postblit. */
1111 bool postblit
= this->needs_postblit (etype
);
1112 bool destructor
= this->needs_dtor (etype
);
1113 bool lvalue_p
= this->lvalue_p (e
->e2
);
1115 /* Even if the elements in rhs are all rvalues and don't have
1116 to call postblits, this assignment should call dtors on old
1117 assigned elements. */
1118 if ((!postblit
&& !destructor
)
1119 || (e
->op
== TOKconstruct
&& !lvalue_p
&& postblit
)
1120 || (e
->op
== TOKblit
|| e
->e1
->type
->size () == 0))
1122 tree t1
= build_expr (e
->e1
);
1123 tree t2
= convert_for_assignment (build_expr (e
->e2
),
1124 e
->e2
->type
, e
->e1
->type
);
1126 this->result_
= build_assign (modifycode
, t1
, t2
);
1130 Type
*arrtype
= (e
->type
->ty
== Tsarray
) ? etype
->arrayOf () : e
->type
;
1133 if (e
->op
== TOKconstruct
)
1135 /* Generate: _d_arrayctor(ti, from, to) */
1136 result
= build_libcall (LIBCALL_ARRAYCTOR
, arrtype
, 3,
1137 build_typeinfo (e
->loc
, etype
),
1138 d_array_convert (e
->e2
),
1139 d_array_convert (e
->e1
));
1143 /* Generate: _d_arrayassign_l()
1144 or: _d_arrayassign_r() */
1145 libcall_fn libcall
= (lvalue_p
)
1146 ? LIBCALL_ARRAYASSIGN_L
: LIBCALL_ARRAYASSIGN_R
;
1147 tree elembuf
= build_local_temp (build_ctype (etype
));
1149 result
= build_libcall (libcall
, arrtype
, 4,
1150 build_typeinfo (e
->loc
, etype
),
1151 d_array_convert (e
->e2
),
1152 d_array_convert (e
->e1
),
1153 build_address (elembuf
));
1156 /* Cast the libcall result back to a static array. */
1157 if (e
->type
->ty
== Tsarray
)
1158 result
= indirect_ref (build_ctype (e
->type
),
1159 d_array_ptr (result
));
1161 this->result_
= result
;
1165 /* Simple assignment. */
1166 tree t1
= build_expr (e
->e1
);
1167 tree t2
= convert_for_assignment (build_expr (e
->e2
),
1168 e
->e2
->type
, e
->e1
->type
);
1170 this->result_
= build_assign (modifycode
, t1
, t2
);
1173 /* Build a postfix expression. */
1175 void visit (PostExp
*e
)
1179 if (e
->op
== TOKplusplus
)
1181 result
= build2 (POSTINCREMENT_EXPR
, build_ctype (e
->type
),
1182 build_expr (e
->e1
), build_expr (e
->e2
));
1184 else if (e
->op
== TOKminusminus
)
1186 result
= build2 (POSTDECREMENT_EXPR
, build_ctype (e
->type
),
1187 build_expr (e
->e1
), build_expr (e
->e2
));
1192 TREE_SIDE_EFFECTS (result
) = 1;
1193 this->result_
= result
;
1196 /* Build an index expression. */
1198 void visit (IndexExp
*e
)
1200 Type
*tb1
= e
->e1
->type
->toBasetype ();
1202 if (tb1
->ty
== Taarray
)
1204 /* Get the key for the associative array. */
1205 Type
*tkey
= ((TypeAArray
*) tb1
)->index
->toBasetype ();
1206 tree key
= convert_expr (build_expr (e
->e2
), e
->e2
->type
, tkey
);
1212 libcall
= LIBCALL_AAGETY
;
1213 ptr
= build_address (build_expr (e
->e1
));
1214 tinfo
= build_typeinfo (e
->loc
, tb1
->unSharedOf ()->mutableOf ());
1218 libcall
= LIBCALL_AAGETRVALUEX
;
1219 ptr
= build_expr (e
->e1
);
1220 tinfo
= build_typeinfo (e
->loc
, tkey
);
1223 /* Index the associative array. */
1224 tree result
= build_libcall (libcall
, e
->type
->pointerTo (), 4,
1226 size_int (tb1
->nextOf ()->size ()),
1227 build_address (key
));
1229 if (!e
->indexIsInBounds
&& array_bounds_check ())
1231 tree tassert
= (global
.params
.checkAction
== CHECKACTION_D
)
1232 ? d_assert_call (e
->loc
, LIBCALL_ARRAY_BOUNDS
)
1233 : build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
1235 result
= d_save_expr (result
);
1236 result
= build_condition (TREE_TYPE (result
),
1237 d_truthvalue_conversion (result
),
1241 this->result_
= indirect_ref (build_ctype (e
->type
), result
);
1245 /* Get the data pointer and length for static and dynamic arrays. */
1246 tree array
= d_save_expr (build_expr (e
->e1
));
1247 tree ptr
= convert_expr (array
, tb1
, tb1
->nextOf ()->pointerTo ());
1249 tree length
= NULL_TREE
;
1250 if (tb1
->ty
!= Tpointer
)
1251 length
= get_array_length (array
, tb1
);
1253 gcc_assert (e
->lengthVar
== NULL
);
1255 /* The __dollar variable just becomes a placeholder for the
1258 e
->lengthVar
->csym
= length
;
1260 /* Generate the index. */
1261 tree index
= build_expr (e
->e2
);
1263 /* If it's a static array and the index is constant, the front end has
1264 already checked the bounds. */
1265 if (tb1
->ty
!= Tpointer
&& !e
->indexIsInBounds
)
1266 index
= build_bounds_condition (e
->e2
->loc
, index
, length
, false);
1268 /* Index the .ptr. */
1269 ptr
= void_okay_p (ptr
);
1270 this->result_
= indirect_ref (TREE_TYPE (TREE_TYPE (ptr
)),
1271 build_array_index (ptr
, index
));
1275 /* Build a comma expression. The type is the type of the right operand. */
1277 void visit (CommaExp
*e
)
1279 tree t1
= build_expr (e
->e1
);
1280 tree t2
= build_expr (e
->e2
);
1281 tree type
= e
->type
? build_ctype (e
->type
) : void_type_node
;
1283 this->result_
= build2 (COMPOUND_EXPR
, type
, t1
, t2
);
1286 /* Build an array length expression. Returns the number of elements
1287 in the array. The result is of type size_t. */
1289 void visit (ArrayLengthExp
*e
)
1291 if (e
->e1
->type
->toBasetype ()->ty
== Tarray
)
1292 this->result_
= d_array_length (build_expr (e
->e1
));
1295 /* Static arrays have already been handled by the front-end. */
1296 error ("unexpected type for array length: %qs", e
->type
->toChars ());
1297 this->result_
= error_mark_node
;
1301 /* Build a delegate pointer expression. This will return the frame
1302 pointer value as a type void*. */
1304 void visit (DelegatePtrExp
*e
)
1306 tree t1
= build_expr (e
->e1
);
1307 this->result_
= delegate_object (t1
);
1310 /* Build a delegate function pointer expression. This will return the
1311 function pointer value as a function type. */
1313 void visit (DelegateFuncptrExp
*e
)
1315 tree t1
= build_expr (e
->e1
);
1316 this->result_
= delegate_method (t1
);
1319 /* Build a slice expression. */
1321 void visit (SliceExp
*e
)
1323 Type
*tb
= e
->type
->toBasetype ();
1324 Type
*tb1
= e
->e1
->type
->toBasetype ();
1325 gcc_assert (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
);
1327 /* Use convert-to-dynamic-array code if possible. */
1330 tree result
= build_expr (e
->e1
);
1331 if (e
->e1
->type
->toBasetype ()->ty
== Tsarray
)
1332 result
= convert_expr (result
, e
->e1
->type
, e
->type
);
1334 this->result_
= result
;
1338 gcc_assert (e
->upr
!= NULL
);
1340 /* Get the data pointer and length for static and dynamic arrays. */
1341 tree array
= d_save_expr (build_expr (e
->e1
));
1342 tree ptr
= convert_expr (array
, tb1
, tb1
->nextOf ()->pointerTo ());
1343 tree length
= NULL_TREE
;
1345 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1346 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1347 if (tb1
->ty
!= Tpointer
)
1348 length
= get_array_length (array
, tb1
);
1350 gcc_assert (e
->lengthVar
== NULL
);
1352 /* The __dollar variable just becomes a placeholder for the
1355 e
->lengthVar
->csym
= length
;
1357 /* Generate upper and lower bounds. */
1358 tree lwr_tree
= d_save_expr (build_expr (e
->lwr
));
1359 tree upr_tree
= d_save_expr (build_expr (e
->upr
));
1361 /* If the upper bound has any side effects, then the lower bound should be
1362 copied to a temporary always. */
1363 if (TREE_CODE (upr_tree
) == SAVE_EXPR
&& TREE_CODE (lwr_tree
) != SAVE_EXPR
)
1364 lwr_tree
= save_expr (lwr_tree
);
1366 /* Adjust the .ptr offset. */
1367 if (!integer_zerop (lwr_tree
))
1369 tree ptrtype
= TREE_TYPE (ptr
);
1370 ptr
= build_array_index (void_okay_p (ptr
), lwr_tree
);
1371 ptr
= build_nop (ptrtype
, ptr
);
1374 lwr_tree
= NULL_TREE
;
1376 /* Nothing more to do for static arrays, their bounds checking has been
1377 done at compile-time. */
1378 if (tb
->ty
== Tsarray
)
1380 this->result_
= indirect_ref (build_ctype (e
->type
), ptr
);
1384 gcc_assert (tb
->ty
== Tarray
);
1386 /* Generate bounds checking code. */
1389 if (!e
->upperIsInBounds
)
1393 newlength
= build_bounds_condition (e
->upr
->loc
, upr_tree
,
1398 /* Still need to check bounds lwr <= upr for pointers. */
1399 gcc_assert (tb1
->ty
== Tpointer
);
1400 newlength
= upr_tree
;
1404 newlength
= upr_tree
;
1408 /* Enforces lwr <= upr. No need to check lwr <= length as
1409 we've already ensured that upr <= length. */
1410 if (!e
->lowerIsLessThanUpper
)
1412 tree cond
= build_bounds_condition (e
->lwr
->loc
, lwr_tree
,
1415 /* When bounds checking is off, the index value is
1416 returned directly. */
1417 if (cond
!= lwr_tree
)
1418 newlength
= compound_expr (cond
, newlength
);
1421 /* Need to ensure lwr always gets evaluated first, as it may be a
1422 function call. Generates (lwr, upr) - lwr. */
1423 newlength
= fold_build2 (MINUS_EXPR
, TREE_TYPE (newlength
),
1424 compound_expr (lwr_tree
, newlength
), lwr_tree
);
1427 tree result
= d_array_value (build_ctype (e
->type
), newlength
, ptr
);
1428 this->result_
= compound_expr (array
, result
);
1431 /* Build a cast expression, which converts the given unary expression to the
1434 void visit (CastExp
*e
)
1436 Type
*ebtype
= e
->e1
->type
->toBasetype ();
1437 Type
*tbtype
= e
->to
->toBasetype ();
1438 tree result
= build_expr (e
->e1
, this->constp_
);
1440 /* Just evaluate e1 if it has any side effects. */
1441 if (tbtype
->ty
== Tvoid
)
1442 this->result_
= build_nop (build_ctype (tbtype
), result
);
1444 this->result_
= convert_expr (result
, ebtype
, tbtype
);
1447 /* Build a delete expression. */
1449 void visit (DeleteExp
*e
)
1451 tree t1
= build_expr (e
->e1
);
1452 Type
*tb1
= e
->e1
->type
->toBasetype ();
1454 if (tb1
->ty
== Tclass
)
1456 /* For class object references, if there is a destructor for that class,
1457 the destructor is called for the object instance. */
1460 if (e
->e1
->op
== TOKvar
)
1462 VarDeclaration
*v
= ((VarExp
*) e
->e1
)->var
->isVarDeclaration ();
1463 if (v
&& v
->onstack
)
1465 libcall
= tb1
->isClassHandle ()->isInterfaceDeclaration ()
1466 ? LIBCALL_CALLINTERFACEFINALIZER
: LIBCALL_CALLFINALIZER
;
1468 this->result_
= build_libcall (libcall
, Type::tvoid
, 1, t1
);
1473 /* Otherwise, the garbage collector is called to immediately free the
1474 memory allocated for the class instance. */
1475 libcall
= tb1
->isClassHandle ()->isInterfaceDeclaration ()
1476 ? LIBCALL_DELINTERFACE
: LIBCALL_DELCLASS
;
1478 t1
= build_address (t1
);
1479 this->result_
= build_libcall (libcall
, Type::tvoid
, 1, t1
);
1481 else if (tb1
->ty
== Tarray
)
1483 /* For dynamic arrays, the garbage collector is called to immediately
1484 release the memory. */
1485 Type
*telem
= tb1
->nextOf ()->baseElemOf ();
1486 tree ti
= null_pointer_node
;
1488 if (telem
->ty
== Tstruct
)
1490 /* Might need to run destructor on array contents. */
1491 TypeStruct
*ts
= (TypeStruct
*) telem
;
1493 ti
= build_typeinfo (e
->loc
, tb1
->nextOf ());
1496 /* Generate: _delarray_t (&t1, ti); */
1497 this->result_
= build_libcall (LIBCALL_DELARRAYT
, Type::tvoid
, 2,
1498 build_address (t1
), ti
);
1500 else if (tb1
->ty
== Tpointer
)
1502 /* For pointers to a struct instance, if the struct has overloaded
1503 operator delete, then that operator is called. */
1504 t1
= build_address (t1
);
1505 Type
*tnext
= ((TypePointer
*)tb1
)->next
->toBasetype ();
1507 if (tnext
->ty
== Tstruct
)
1509 TypeStruct
*ts
= (TypeStruct
*)tnext
;
1512 tree ti
= build_typeinfo (e
->loc
, tnext
);
1513 this->result_
= build_libcall (LIBCALL_DELSTRUCT
, Type::tvoid
,
1519 /* Otherwise, the garbage collector is called to immediately free the
1520 memory allocated for the pointer. */
1521 this->result_
= build_libcall (LIBCALL_DELMEMORY
, Type::tvoid
, 1, t1
);
1525 error ("don't know how to delete %qs", e
->e1
->toChars ());
1526 this->result_
= error_mark_node
;
1530 /* Build a remove expression, which removes a particular key from an
1531 associative array. */
1533 void visit (RemoveExp
*e
)
1535 /* Check that the array is actually an associative array. */
1536 if (e
->e1
->type
->toBasetype ()->ty
== Taarray
)
1538 Type
*tb
= e
->e1
->type
->toBasetype ();
1539 Type
*tkey
= ((TypeAArray
*) tb
)->index
->toBasetype ();
1540 tree index
= convert_expr (build_expr (e
->e2
), e
->e2
->type
, tkey
);
1542 this->result_
= build_libcall (LIBCALL_AADELX
, Type::tbool
, 3,
1544 build_typeinfo (e
->loc
, tkey
),
1545 build_address (index
));
1549 error ("%qs is not an associative array", e
->e1
->toChars ());
1550 this->result_
= error_mark_node
;
1554 /* Build an unary not expression. */
1556 void visit (NotExp
*e
)
1558 tree result
= convert_for_condition (build_expr (e
->e1
), e
->e1
->type
);
1559 /* Need to convert to boolean type or this will fail. */
1560 result
= fold_build1 (TRUTH_NOT_EXPR
, d_bool_type
, result
);
1562 this->result_
= d_convert (build_ctype (e
->type
), result
);
1565 /* Build a compliment expression, where all the bits in the value are
1566 complemented. Note: unlike in C, the usual integral promotions
1567 are not performed prior to the complement operation. */
1569 void visit (ComExp
*e
)
1571 TY ty1
= e
->e1
->type
->toBasetype ()->ty
;
1572 gcc_assert (ty1
!= Tarray
&& ty1
!= Tsarray
);
1574 this->result_
= fold_build1 (BIT_NOT_EXPR
, build_ctype (e
->type
),
1575 build_expr (e
->e1
));
1578 /* Build an unary negation expression. */
1580 void visit (NegExp
*e
)
1582 TY ty1
= e
->e1
->type
->toBasetype ()->ty
;
1583 gcc_assert (ty1
!= Tarray
&& ty1
!= Tsarray
);
1585 tree type
= build_ctype (e
->type
);
1586 tree expr
= build_expr (e
->e1
);
1588 /* If the operation needs excess precision. */
1589 tree eptype
= excess_precision_type (type
);
1590 if (eptype
!= NULL_TREE
)
1591 expr
= d_convert (eptype
, expr
);
1595 tree ret
= fold_build1 (NEGATE_EXPR
, eptype
, expr
);
1596 this->result_
= d_convert (type
, ret
);
1599 /* Build a pointer index expression. */
1601 void visit (PtrExp
*e
)
1607 if (e
->e1
->op
== TOKadd
)
1609 BinExp
*be
= (BinExp
*) e
->e1
;
1610 if (be
->e1
->op
== TOKaddress
1611 && be
->e2
->isConst () && be
->e2
->type
->isintegral ())
1613 Expression
*ae
= ((AddrExp
*) be
->e1
)->e1
;
1614 tnext
= ae
->type
->toBasetype ();
1615 result
= build_expr (ae
);
1616 offset
= be
->e2
->toUInteger ();
1619 else if (e
->e1
->op
== TOKsymoff
)
1621 SymOffExp
*se
= (SymOffExp
*) e
->e1
;
1622 if (!declaration_reference_p (se
->var
))
1624 tnext
= se
->var
->type
->toBasetype ();
1625 result
= get_decl_tree (se
->var
);
1626 offset
= se
->offset
;
1630 /* Produce better code by converting *(#record + n) to
1631 COMPONENT_REFERENCE. Otherwise, the variable will always be
1632 allocated in memory because its address is taken. */
1633 if (tnext
&& tnext
->ty
== Tstruct
)
1635 StructDeclaration
*sd
= ((TypeStruct
*) tnext
)->sym
;
1637 for (size_t i
= 0; i
< sd
->fields
.dim
; i
++)
1639 VarDeclaration
*field
= sd
->fields
[i
];
1641 if (field
->offset
== offset
1642 && same_type_p (field
->type
, e
->type
))
1644 /* Catch errors, backend will ICE otherwise. */
1645 if (error_operand_p (result
))
1646 this->result_
= result
;
1649 result
= component_ref (result
, get_symbol_decl (field
));
1650 this->result_
= result
;
1654 else if (field
->offset
> offset
)
1659 this->result_
= indirect_ref (build_ctype (e
->type
), build_expr (e
->e1
));
1662 /* Build an unary address expression. */
1664 void visit (AddrExp
*e
)
1666 tree type
= build_ctype (e
->type
);
1669 /* The frontend optimizer can convert const symbol into a struct literal.
1670 Taking the address of a struct literal is otherwise illegal. */
1671 if (e
->e1
->op
== TOKstructliteral
)
1673 StructLiteralExp
*sle
= ((StructLiteralExp
*) e
->e1
)->origin
;
1674 gcc_assert (sle
!= NULL
);
1676 /* Build the reference symbol, the decl is built first as the
1677 initializer may have recursive references. */
1680 sle
->sym
= build_artificial_decl (build_ctype (sle
->type
),
1682 DECL_INITIAL (sle
->sym
) = build_expr (sle
, true);
1683 d_pushdecl (sle
->sym
);
1684 rest_of_decl_compilation (sle
->sym
, 1, 0);
1690 exp
= build_expr (e
->e1
, this->constp_
);
1692 TREE_CONSTANT (exp
) = 0;
1693 this->result_
= d_convert (type
, build_address (exp
));
1696 /* Build a function call expression. */
1698 void visit (CallExp
*e
)
1700 Type
*tb
= e
->e1
->type
->toBasetype ();
1701 Expression
*e1b
= e
->e1
;
1703 tree callee
= NULL_TREE
;
1704 tree object
= NULL_TREE
;
1705 tree cleanup
= NULL_TREE
;
1706 TypeFunction
*tf
= NULL
;
1708 /* Calls to delegates can sometimes look like this. */
1709 if (e1b
->op
== TOKcomma
)
1711 e1b
= ((CommaExp
*) e1b
)->e2
;
1712 gcc_assert (e1b
->op
== TOKvar
);
1714 Declaration
*var
= ((VarExp
*) e1b
)->var
;
1715 gcc_assert (var
->isFuncDeclaration () && !var
->needThis ());
1718 if (e1b
->op
== TOKdotvar
&& tb
->ty
!= Tdelegate
)
1720 DotVarExp
*dve
= (DotVarExp
*) e1b
;
1722 /* Don't modify the static initializer for struct literals. */
1723 if (dve
->e1
->op
== TOKstructliteral
)
1725 StructLiteralExp
*sle
= (StructLiteralExp
*) dve
->e1
;
1726 sle
->useStaticInit
= false;
1729 FuncDeclaration
*fd
= dve
->var
->isFuncDeclaration ();
1732 /* Get the correct callee from the DotVarExp object. */
1733 tree fndecl
= get_symbol_decl (fd
);
1734 AggregateDeclaration
*ad
= fd
->isThis ();
1736 /* Static method; ignore the object instance. */
1738 callee
= build_address (fndecl
);
1741 tree thisexp
= build_expr (dve
->e1
);
1743 /* When constructing temporaries, if the constructor throws,
1744 then the object is destructed even though it is not a fully
1745 constructed object yet. And so this call will need to be
1746 moved inside the TARGET_EXPR_INITIAL slot. */
1747 if (fd
->isCtorDeclaration ()
1748 && TREE_CODE (thisexp
) == COMPOUND_EXPR
1749 && TREE_CODE (TREE_OPERAND (thisexp
, 0)) == TARGET_EXPR
1750 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp
, 0)))
1752 cleanup
= TREE_OPERAND (thisexp
, 0);
1753 thisexp
= TREE_OPERAND (thisexp
, 1);
1756 /* Want reference to 'this' object. */
1757 if (!POINTER_TYPE_P (TREE_TYPE (thisexp
)))
1758 thisexp
= build_address (thisexp
);
1760 /* Make the callee a virtual call. */
1761 if (fd
->isVirtual () && !fd
->isFinalFunc () && !e
->directcall
)
1763 tree fntype
= build_pointer_type (TREE_TYPE (fndecl
));
1764 tree thistype
= build_ctype (ad
->handleType ());
1765 thisexp
= build_nop (thistype
, d_save_expr (thisexp
));
1766 fndecl
= build_vindex_ref (thisexp
, fntype
, fd
->vtblIndex
);
1769 fndecl
= build_address (fndecl
);
1771 callee
= build_method_call (fndecl
, thisexp
, fd
->type
);
1776 if (callee
== NULL_TREE
)
1777 callee
= build_expr (e1b
);
1779 if (METHOD_CALL_EXPR (callee
))
1781 /* This could be a delegate expression (TY == Tdelegate), but not
1782 actually a delegate variable. */
1783 if (e1b
->op
== TOKdotvar
)
1785 /* This gets the true function type, getting the function type
1786 from e1->type can sometimes be incorrect, such as when calling
1787 a 'ref' return function. */
1788 tf
= get_function_type (((DotVarExp
*) e1b
)->var
->type
);
1791 tf
= get_function_type (tb
);
1793 extract_from_method_call (callee
, callee
, object
);
1795 else if (tb
->ty
== Tdelegate
)
1797 /* Delegate call, extract .object and .funcptr from var. */
1798 callee
= d_save_expr (callee
);
1799 tf
= get_function_type (tb
);
1800 object
= delegate_object (callee
);
1801 callee
= delegate_method (callee
);
1803 else if (e1b
->op
== TOKvar
)
1805 FuncDeclaration
*fd
= ((VarExp
*) e1b
)->var
->isFuncDeclaration ();
1806 gcc_assert (fd
!= NULL
);
1807 tf
= get_function_type (fd
->type
);
1809 if (fd
->isNested ())
1811 /* Maybe re-evaluate symbol storage treating 'fd' as public. */
1812 if (call_by_alias_p (d_function_chain
->function
, fd
))
1813 TREE_PUBLIC (callee
) = 1;
1815 object
= get_frame_for_symbol (fd
);
1817 else if (fd
->needThis ())
1819 error_at (make_location_t (e1b
->loc
),
1820 "need %<this%> to access member %qs", fd
->toChars ());
1821 /* Continue compiling... */
1822 object
= null_pointer_node
;
1827 /* Normal direct function call. */
1828 tf
= get_function_type (tb
);
1831 gcc_assert (tf
!= NULL
);
1833 /* Now we have the type, callee and maybe object reference,
1834 build the call expression. */
1835 tree exp
= d_build_call (tf
, callee
, object
, e
->arguments
);
1838 exp
= build_deref (exp
);
1840 /* Some library calls are defined to return a generic type.
1841 this->type is the real type we want to return. */
1842 if (e
->type
->isTypeBasic ())
1843 exp
= d_convert (build_ctype (e
->type
), exp
);
1845 /* If this call was found to be a constructor for a temporary with a
1846 cleanup, then move the call inside the TARGET_EXPR. The original
1847 initializer is turned into an assignment, to keep its side effect. */
1848 if (cleanup
!= NULL_TREE
)
1850 tree init
= TARGET_EXPR_INITIAL (cleanup
);
1851 tree slot
= TARGET_EXPR_SLOT (cleanup
);
1852 d_mark_addressable (slot
);
1853 init
= build_assign (INIT_EXPR
, slot
, init
);
1855 TARGET_EXPR_INITIAL (cleanup
) = compound_expr (init
, exp
);
1859 this->result_
= exp
;
1862 /* Build a delegate expression. */
1864 void visit (DelegateExp
*e
)
1866 if (e
->func
->semanticRun
== PASSsemantic3done
)
1868 /* Add the function as nested function if it belongs to this module.
1869 ie: it is a member of this module, or it is a template instance. */
1870 Dsymbol
*owner
= e
->func
->toParent ();
1871 while (!owner
->isTemplateInstance () && owner
->toParent ())
1872 owner
= owner
->toParent ();
1873 if (owner
->isTemplateInstance () || owner
== d_function_chain
->module
)
1874 build_decl_tree (e
->func
);
1880 if (e
->func
->isNested ())
1882 if (e
->e1
->op
== TOKnull
)
1883 object
= build_expr (e
->e1
);
1885 object
= get_frame_for_symbol (e
->func
);
1887 fndecl
= build_address (get_symbol_decl (e
->func
));
1891 if (!e
->func
->isThis ())
1893 error ("delegates are only for non-static functions");
1894 this->result_
= error_mark_node
;
1898 object
= build_expr (e
->e1
);
1900 /* Want reference to `this' object. */
1901 if (e
->e1
->type
->ty
!= Tclass
&& e
->e1
->type
->ty
!= Tpointer
)
1902 object
= build_address (object
);
1904 /* Object reference could be the outer `this' field of a class or
1905 closure of type `void*'. Cast it to the right type. */
1906 if (e
->e1
->type
->ty
== Tclass
)
1907 object
= d_convert (build_ctype (e
->e1
->type
), object
);
1909 fndecl
= get_symbol_decl (e
->func
);
1911 /* Get pointer to function out of the virtual table. */
1912 if (e
->func
->isVirtual () && !e
->func
->isFinalFunc ()
1913 && e
->e1
->op
!= TOKsuper
&& e
->e1
->op
!= TOKdottype
)
1915 tree fntype
= build_pointer_type (TREE_TYPE (fndecl
));
1916 object
= d_save_expr (object
);
1917 fndecl
= build_vindex_ref (object
, fntype
, e
->func
->vtblIndex
);
1920 fndecl
= build_address (fndecl
);
1923 this->result_
= build_method_call (fndecl
, object
, e
->type
);
1926 /* Build a type component expression. */
1928 void visit (DotTypeExp
*e
)
1930 /* Just a pass through to underlying expression. */
1931 this->result_
= build_expr (e
->e1
);
1934 /* Build a component reference expression. */
1936 void visit (DotVarExp
*e
)
1938 VarDeclaration
*vd
= e
->var
->isVarDeclaration ();
1940 /* This could also be a function, but relying on that being taken
1941 care of by the visitor interface for CallExp. */
1944 if (!vd
->isField ())
1945 this->result_
= get_decl_tree (vd
);
1948 tree object
= build_expr (e
->e1
);
1950 if (e
->e1
->type
->toBasetype ()->ty
!= Tstruct
)
1951 object
= build_deref (object
);
1953 this->result_
= component_ref (object
, get_symbol_decl (vd
));
1958 error ("%qs is not a field, but a %qs",
1959 e
->var
->toChars (), e
->var
->kind ());
1960 this->result_
= error_mark_node
;
1964 /* Build an assert expression, used to declare conditions that must hold at
1965 that a given point in the program. */
1967 void visit (AssertExp
*e
)
1969 Type
*tb1
= e
->e1
->type
->toBasetype ();
1970 tree arg
= build_expr (e
->e1
);
1971 tree tmsg
= NULL_TREE
;
1972 tree assert_pass
= void_node
;
1975 if (global
.params
.useAssert
1976 && global
.params
.checkAction
== CHECKACTION_D
)
1978 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1979 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1980 bool unittest_p
= d_function_chain
->function
->isUnitTestDeclaration ();
1985 tmsg
= build_expr_dtor (e
->msg
);
1986 libcall
= unittest_p
? LIBCALL_UNITTEST_MSG
: LIBCALL_ASSERT_MSG
;
1989 libcall
= unittest_p
? LIBCALL_UNITTEST
: LIBCALL_ASSERT
;
1991 /* Build a call to _d_assert(). */
1992 assert_fail
= d_assert_call (e
->loc
, libcall
, tmsg
);
1994 if (global
.params
.useInvariants
)
1996 /* If the condition is a D class or struct object with an invariant,
1997 call it if the condition result is true. */
1998 if (tb1
->ty
== Tclass
)
2000 ClassDeclaration
*cd
= tb1
->isClassHandle ();
2001 if (!cd
->isInterfaceDeclaration () && !cd
->isCPPclass ())
2003 arg
= d_save_expr (arg
);
2004 assert_pass
= build_libcall (LIBCALL_INVARIANT
,
2005 Type::tvoid
, 1, arg
);
2008 else if (tb1
->ty
== Tpointer
&& tb1
->nextOf ()->ty
== Tstruct
)
2010 StructDeclaration
*sd
= ((TypeStruct
*) tb1
->nextOf ())->sym
;
2011 if (sd
->inv
!= NULL
)
2014 arg
= d_save_expr (arg
);
2015 assert_pass
= d_build_call_expr (sd
->inv
, arg
, &args
);
2020 else if (global
.params
.useAssert
2021 && global
.params
.checkAction
== CHECKACTION_C
)
2023 /* Generate: __builtin_trap() */
2024 tree fn
= builtin_decl_explicit (BUILT_IN_TRAP
);
2025 assert_fail
= build_call_expr (fn
, 0);
2029 /* Assert contracts are turned off, if the contract condition has no
2030 side effects can still use it as a predicate for the optimizer. */
2031 if (TREE_SIDE_EFFECTS (arg
))
2033 this->result_
= void_node
;
2037 assert_fail
= build_predict_expr (PRED_NORETURN
, NOT_TAKEN
);
2040 /* Build condition that we are asserting in this contract. */
2041 tree condition
= convert_for_condition (arg
, e
->e1
->type
);
2043 /* We expect the condition to always be true, as what happens if an assert
2044 contract is false is undefined behavior. */
2045 tree fn
= builtin_decl_explicit (BUILT_IN_EXPECT
);
2046 tree arg_types
= TYPE_ARG_TYPES (TREE_TYPE (fn
));
2047 tree pred_type
= TREE_VALUE (arg_types
);
2048 tree expected_type
= TREE_VALUE (TREE_CHAIN (arg_types
));
2050 condition
= build_call_expr (fn
, 2, d_convert (pred_type
, condition
),
2051 build_int_cst (expected_type
, 1));
2052 condition
= d_truthvalue_conversion (condition
);
2054 this->result_
= build_vcondition (condition
, assert_pass
, assert_fail
);
2057 /* Build a declaration expression. */
2059 void visit (DeclarationExp
*e
)
2061 /* Compile the declaration. */
2063 build_decl_tree (e
->declaration
);
2064 tree result
= pop_stmt_list ();
2066 /* Construction of an array for typesafe-variadic function arguments
2067 can cause an empty STMT_LIST here. This can causes problems
2068 during gimplification. */
2069 if (TREE_CODE (result
) == STATEMENT_LIST
&& !STATEMENT_LIST_HEAD (result
))
2070 result
= build_empty_stmt (input_location
);
2072 this->result_
= result
;
2075 /* Build a typeid expression. Returns an instance of class TypeInfo
2076 corresponding to. */
2078 void visit (TypeidExp
*e
)
2080 if (Type
*tid
= isType (e
->obj
))
2082 tree ti
= build_typeinfo (e
->loc
, tid
);
2084 /* If the typeinfo is at an offset. */
2085 if (tid
->vtinfo
->offset
)
2086 ti
= build_offset (ti
, size_int (tid
->vtinfo
->offset
));
2088 this->result_
= build_nop (build_ctype (e
->type
), ti
);
2090 else if (Expression
*tid
= isExpression (e
->obj
))
2092 Type
*type
= tid
->type
->toBasetype ();
2093 assert (type
->ty
== Tclass
);
2095 /* Generate **classptr to get the classinfo. */
2096 tree ci
= build_expr (tid
);
2097 ci
= indirect_ref (ptr_type_node
, ci
);
2098 ci
= indirect_ref (ptr_type_node
, ci
);
2100 /* Add extra indirection for interfaces. */
2101 if (((TypeClass
*) type
)->sym
->isInterfaceDeclaration ())
2102 ci
= indirect_ref (ptr_type_node
, ci
);
2104 this->result_
= build_nop (build_ctype (e
->type
), ci
);
2110 /* Build a function/lambda expression. */
2112 void visit (FuncExp
*e
)
2114 Type
*ftype
= e
->type
->toBasetype ();
2116 /* This check is for lambda's, remove 'vthis' as function isn't nested. */
2117 if (e
->fd
->tok
== TOKreserved
&& ftype
->ty
== Tpointer
)
2119 e
->fd
->tok
= TOKfunction
;
2120 e
->fd
->vthis
= NULL
;
2123 /* Compile the function literal body. */
2124 build_decl_tree (e
->fd
);
2126 /* If nested, this will be a trampoline. */
2127 if (e
->fd
->isNested ())
2129 tree func
= build_address (get_symbol_decl (e
->fd
));
2134 /* Static delegate variables have no context pointer. */
2135 object
= null_pointer_node
;
2136 this->result_
= build_method_call (func
, object
, e
->fd
->type
);
2137 TREE_CONSTANT (this->result_
) = 1;
2141 object
= get_frame_for_symbol (e
->fd
);
2142 this->result_
= build_method_call (func
, object
, e
->fd
->type
);
2147 this->result_
= build_nop (build_ctype (e
->type
),
2148 build_address (get_symbol_decl (e
->fd
)));
2152 /* Build a halt expression. */
2154 void visit (HaltExp
*)
2156 /* Should we use trap() or abort()? */
2157 tree ttrap
= builtin_decl_explicit (BUILT_IN_TRAP
);
2158 this->result_
= build_call_expr (ttrap
, 0);
2161 /* Build a symbol pointer offset expression. */
2163 void visit (SymOffExp
*e
)
2165 /* Build the address and offset of the symbol. */
2166 size_t soffset
= ((SymOffExp
*) e
)->offset
;
2167 tree result
= get_decl_tree (e
->var
);
2168 TREE_USED (result
) = 1;
2170 if (declaration_reference_p (e
->var
))
2171 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result
)));
2173 result
= build_address (result
);
2176 result
= d_convert (build_ctype (e
->type
), result
);
2179 tree offset
= size_int (soffset
);
2180 result
= build_nop (build_ctype (e
->type
),
2181 build_offset (result
, offset
));
2184 this->result_
= result
;
2187 /* Build a variable expression. */
2189 void visit (VarExp
*e
)
2191 if (e
->var
->needThis ())
2193 error ("need %<this%> to access member %qs", e
->var
->ident
->toChars ());
2194 this->result_
= error_mark_node
;
2197 else if (e
->var
->ident
== Identifier::idPool ("__ctfe"))
2199 /* __ctfe is always false at run-time. */
2200 this->result_
= integer_zero_node
;
2204 /* This check is same as is done in FuncExp for lambdas. */
2205 FuncLiteralDeclaration
*fld
= e
->var
->isFuncLiteralDeclaration ();
2208 if (fld
->tok
== TOKreserved
)
2210 fld
->tok
= TOKfunction
;
2214 /* Compiler the function literal body. */
2215 build_decl_tree (fld
);
2220 /* Want the initializer, not the expression. */
2221 VarDeclaration
*var
= e
->var
->isVarDeclaration ();
2222 SymbolDeclaration
*sd
= e
->var
->isSymbolDeclaration ();
2223 tree init
= NULL_TREE
;
2225 if (var
&& (var
->isConst () || var
->isImmutable ())
2226 && e
->type
->toBasetype ()->ty
!= Tsarray
&& var
->_init
)
2229 error_at (make_location_t (e
->loc
), "recursive reference %qs",
2234 init
= build_expr (initializerToExpression (var
->_init
), true);
2238 else if (sd
&& sd
->dsym
)
2239 init
= layout_struct_initializer (sd
->dsym
);
2241 error_at (make_location_t (e
->loc
), "non-constant expression %qs",
2244 if (init
!= NULL_TREE
)
2245 this->result_
= init
;
2247 this->result_
= error_mark_node
;
2251 tree result
= get_decl_tree (e
->var
);
2252 TREE_USED (result
) = 1;
2254 /* For variables that are references - currently only out/inout
2255 arguments; objects don't count - evaluating the variable means
2256 we want what it refers to. */
2257 if (declaration_reference_p (e
->var
))
2258 result
= indirect_ref (build_ctype (e
->var
->type
), result
);
2260 this->result_
= result
;
2264 /* Build a this variable expression. */
2266 void visit (ThisExp
*e
)
2268 FuncDeclaration
*fd
= d_function_chain
? d_function_chain
->function
: NULL
;
2269 tree result
= NULL_TREE
;
2272 result
= get_decl_tree (e
->var
);
2275 gcc_assert (fd
&& fd
->vthis
);
2276 result
= get_decl_tree (fd
->vthis
);
2279 if (e
->type
->ty
== Tstruct
)
2280 result
= build_deref (result
);
2282 this->result_
= result
;
2285 /* Build a new expression, which allocates memory either on the garbage
2286 collected heap or by using a class or struct specific allocator. */
2288 void visit (NewExp
*e
)
2290 Type
*tb
= e
->type
->toBasetype ();
2294 gcc_assert (e
->newargs
);
2296 if (tb
->ty
== Tclass
)
2298 /* Allocating a new class. */
2299 tb
= e
->newtype
->toBasetype ();
2300 gcc_assert (tb
->ty
== Tclass
);
2302 ClassDeclaration
*cd
= ((TypeClass
*) tb
)->sym
;
2303 tree type
= build_ctype (tb
);
2304 tree setup_exp
= NULL_TREE
;
2309 /* If being used as an initializer for a local variable with scope
2310 storage class, then the instance is allocated on the stack
2311 rather than the heap or using the class specific allocator. */
2312 tree var
= build_local_temp (TREE_TYPE (type
));
2313 new_call
= build_nop (type
, build_address (var
));
2314 setup_exp
= modify_expr (var
, aggregate_initializer_decl (cd
));
2316 else if (e
->allocator
)
2318 /* Call class allocator, and copy the initializer into memory. */
2319 new_call
= d_build_call_expr (e
->allocator
, NULL_TREE
, e
->newargs
);
2320 new_call
= d_save_expr (new_call
);
2321 new_call
= build_nop (type
, new_call
);
2322 setup_exp
= modify_expr (build_deref (new_call
),
2323 aggregate_initializer_decl (cd
));
2327 /* Generate: _d_newclass() */
2328 tree arg
= build_address (get_classinfo_decl (cd
));
2329 new_call
= build_libcall (LIBCALL_NEWCLASS
, tb
, 1, arg
);
2332 /* Set the context pointer for nested classes. */
2333 if (cd
->isNested ())
2335 tree field
= get_symbol_decl (cd
->vthis
);
2336 tree value
= NULL_TREE
;
2340 ClassDeclaration
*tcd
= e
->thisexp
->type
->isClassHandle ();
2341 Dsymbol
*outer
= cd
->toParent2 ();
2344 value
= build_expr (e
->thisexp
);
2347 ClassDeclaration
*ocd
= outer
->isClassDeclaration ();
2348 gcc_assert (ocd
->isBaseOf (tcd
, &offset
));
2349 /* Could just add offset... */
2350 value
= convert_expr (value
, e
->thisexp
->type
, ocd
->type
);
2354 value
= build_vthis (cd
);
2356 if (value
!= NULL_TREE
)
2358 /* Generate: (new())->vthis = this; */
2359 new_call
= d_save_expr (new_call
);
2360 field
= component_ref (build_deref (new_call
), field
);
2361 setup_exp
= compound_expr (setup_exp
,
2362 modify_expr (field
, value
));
2365 new_call
= compound_expr (setup_exp
, new_call
);
2367 /* Call the class constructor. */
2369 result
= d_build_call_expr (e
->member
, new_call
, e
->arguments
);
2374 result
= compound_expr (build_expr (e
->argprefix
), result
);
2376 else if (tb
->ty
== Tpointer
&& tb
->nextOf ()->toBasetype ()->ty
== Tstruct
)
2378 /* Allocating memory for a new struct. */
2379 Type
*htype
= e
->newtype
->toBasetype ();
2380 gcc_assert (htype
->ty
== Tstruct
);
2381 gcc_assert (!e
->onstack
);
2383 TypeStruct
*stype
= (TypeStruct
*) htype
;
2384 StructDeclaration
*sd
= stype
->sym
;
2387 /* Cannot new an opaque struct. */
2388 if (sd
->size (e
->loc
) == 0)
2390 this->result_
= d_convert (build_ctype (e
->type
),
2397 /* Call struct allocator. */
2398 new_call
= d_build_call_expr (e
->allocator
, NULL_TREE
, e
->newargs
);
2399 new_call
= build_nop (build_ctype (tb
), new_call
);
2403 /* Generate: _d_newitemT() */
2404 libcall_fn libcall
= htype
->isZeroInit ()
2405 ? LIBCALL_NEWITEMT
: LIBCALL_NEWITEMIT
;
2406 tree arg
= build_typeinfo (e
->loc
, e
->newtype
);
2407 new_call
= build_libcall (libcall
, tb
, 1, arg
);
2410 if (e
->member
|| !e
->arguments
)
2412 /* Set the context pointer for nested structs. */
2413 if (sd
->isNested ())
2415 tree value
= build_vthis (sd
);
2416 tree field
= get_symbol_decl (sd
->vthis
);
2417 tree type
= build_ctype (stype
);
2419 new_call
= d_save_expr (new_call
);
2420 field
= component_ref (indirect_ref (type
, new_call
), field
);
2421 new_call
= compound_expr (modify_expr (field
, value
), new_call
);
2424 /* Call the struct constructor. */
2426 result
= d_build_call_expr (e
->member
, new_call
, e
->arguments
);
2432 /* If we have a user supplied initializer, then set-up with a
2434 if (e
->arguments
!= NULL
&& sd
->fields
.dim
!= 0)
2436 StructLiteralExp
*se
= StructLiteralExp::create (e
->loc
, sd
,
2439 new_call
= d_save_expr (new_call
);
2440 se
->type
= sd
->type
;
2442 result
= compound_expr (build_expr (se
), new_call
);
2449 result
= compound_expr (build_expr (e
->argprefix
), result
);
2451 else if (tb
->ty
== Tarray
)
2453 /* Allocating memory for a new D array. */
2454 tb
= e
->newtype
->toBasetype ();
2455 gcc_assert (tb
->ty
== Tarray
);
2456 TypeDArray
*tarray
= (TypeDArray
*) tb
;
2458 gcc_assert (!e
->allocator
);
2459 gcc_assert (e
->arguments
&& e
->arguments
->dim
>= 1);
2461 if (e
->arguments
->dim
== 1)
2463 /* Single dimension array allocations. */
2464 Expression
*arg
= (*e
->arguments
)[0];
2466 if (tarray
->next
->size () == 0)
2468 /* Array element size is unknown. */
2469 this->result_
= d_array_value (build_ctype (e
->type
),
2470 size_int (0), null_pointer_node
);
2474 libcall_fn libcall
= tarray
->next
->isZeroInit ()
2475 ? LIBCALL_NEWARRAYT
: LIBCALL_NEWARRAYIT
;
2476 result
= build_libcall (libcall
, tb
, 2,
2477 build_typeinfo (e
->loc
, e
->type
),
2482 /* Multidimensional array allocations. */
2483 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
2484 Type
*telem
= e
->newtype
->toBasetype ();
2485 tree tarray
= make_array_type (Type::tsize_t
, e
->arguments
->dim
);
2486 tree var
= create_temporary_var (tarray
);
2487 tree init
= build_constructor (TREE_TYPE (var
), NULL
);
2489 for (size_t i
= 0; i
< e
->arguments
->dim
; i
++)
2491 Expression
*arg
= (*e
->arguments
)[i
];
2492 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), build_expr (arg
));
2494 gcc_assert (telem
->ty
== Tarray
);
2495 telem
= telem
->toBasetype ()->nextOf ();
2499 CONSTRUCTOR_ELTS (init
) = elms
;
2500 DECL_INITIAL (var
) = init
;
2502 /* Generate: _d_newarraymTX(ti, dims)
2503 or: _d_newarraymiTX(ti, dims) */
2504 libcall_fn libcall
= telem
->isZeroInit ()
2505 ? LIBCALL_NEWARRAYMTX
: LIBCALL_NEWARRAYMITX
;
2507 tree tinfo
= build_typeinfo (e
->loc
, e
->type
);
2508 tree dims
= d_array_value (build_ctype (Type::tsize_t
->arrayOf ()),
2509 size_int (e
->arguments
->dim
),
2510 build_address (var
));
2512 result
= build_libcall (libcall
, tb
, 2, tinfo
, dims
);
2513 result
= bind_expr (var
, result
);
2517 result
= compound_expr (build_expr (e
->argprefix
), result
);
2519 else if (tb
->ty
== Tpointer
)
2521 /* Allocating memory for a new pointer. */
2522 TypePointer
*tpointer
= (TypePointer
*) tb
;
2524 if (tpointer
->next
->size () == 0)
2526 /* Pointer element size is unknown. */
2527 this->result_
= d_convert (build_ctype (e
->type
),
2532 libcall_fn libcall
= tpointer
->next
->isZeroInit (e
->loc
)
2533 ? LIBCALL_NEWITEMT
: LIBCALL_NEWITEMIT
;
2535 tree arg
= build_typeinfo (e
->loc
, e
->newtype
);
2536 result
= build_libcall (libcall
, tb
, 1, arg
);
2538 if (e
->arguments
&& e
->arguments
->dim
== 1)
2540 result
= d_save_expr (result
);
2541 tree init
= modify_expr (build_deref (result
),
2542 build_expr ((*e
->arguments
)[0]));
2543 result
= compound_expr (init
, result
);
2547 result
= compound_expr (build_expr (e
->argprefix
), result
);
2552 this->result_
= convert_expr (result
, tb
, e
->type
);
2555 /* Build an integer literal. */
2557 void visit (IntegerExp
*e
)
2559 tree ctype
= build_ctype (e
->type
->toBasetype ());
2560 this->result_
= build_integer_cst (e
->value
, ctype
);
2563 /* Build a floating-point literal. */
2565 void visit (RealExp
*e
)
2567 this->result_
= build_float_cst (e
->value
, e
->type
->toBasetype ());
2570 /* Build a complex literal. */
2572 void visit (ComplexExp
*e
)
2576 switch (e
->type
->toBasetype ()->ty
)
2579 tnext
= (TypeBasic
*) Type::tfloat32
;
2583 tnext
= (TypeBasic
*) Type::tfloat64
;
2587 tnext
= (TypeBasic
*) Type::tfloat80
;
2594 this->result_
= build_complex (build_ctype (e
->type
),
2595 build_float_cst (creall (e
->value
), tnext
),
2596 build_float_cst (cimagl (e
->value
), tnext
));
2599 /* Build a string literal, all strings are null terminated except for
2602 void visit (StringExp
*e
)
2604 Type
*tb
= e
->type
->toBasetype ();
2605 tree type
= build_ctype (e
->type
);
2607 if (tb
->ty
== Tsarray
)
2609 /* Turn the string into a constructor for the static array. */
2610 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
2611 vec_safe_reserve (elms
, e
->len
);
2612 tree etype
= TREE_TYPE (type
);
2614 for (size_t i
= 0; i
< e
->len
; i
++)
2616 tree value
= build_integer_cst (e
->charAt (i
), etype
);
2617 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), value
);
2620 tree ctor
= build_constructor (type
, elms
);
2621 TREE_CONSTANT (ctor
) = 1;
2622 this->result_
= ctor
;
2626 /* Copy the string contents to a null terminated string. */
2627 dinteger_t length
= (e
->len
* e
->sz
);
2628 char *string
= XALLOCAVEC (char, length
+ 1);
2629 memcpy (string
, e
->string
, length
);
2630 string
[length
] = '\0';
2632 /* String value and type includes the null terminator. */
2633 tree value
= build_string (length
, string
);
2634 TREE_TYPE (value
) = make_array_type (tb
->nextOf (), length
+ 1);
2635 value
= build_address (value
);
2637 if (tb
->ty
== Tarray
)
2638 value
= d_array_value (type
, size_int (e
->len
), value
);
2640 TREE_CONSTANT (value
) = 1;
2641 this->result_
= d_convert (type
, value
);
2645 /* Build a tuple literal. Just an argument list that may have
2646 side effects that need evaluation. */
2648 void visit (TupleExp
*e
)
2650 tree result
= NULL_TREE
;
2653 result
= build_expr (e
->e0
);
2655 for (size_t i
= 0; i
< e
->exps
->dim
; ++i
)
2657 Expression
*exp
= (*e
->exps
)[i
];
2658 result
= compound_expr (result
, build_expr (exp
));
2661 if (result
== NULL_TREE
)
2664 this->result_
= result
;
2667 /* Build an array literal. The common type of the all elements is taken to
2668 be the type of the array element, and all elements are implicitly
2669 converted to that type. */
2671 void visit (ArrayLiteralExp
*e
)
2673 Type
*tb
= e
->type
->toBasetype ();
2675 /* Implicitly convert void[n] to ubyte[n]. */
2676 if (tb
->ty
== Tsarray
&& tb
->nextOf ()->toBasetype ()->ty
== Tvoid
)
2677 tb
= Type::tuns8
->sarrayOf (((TypeSArray
*) tb
)->dim
->toUInteger ());
2679 gcc_assert (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
|| tb
->ty
== Tpointer
);
2681 /* Handle empty array literals. */
2682 if (e
->elements
->dim
== 0)
2684 if (tb
->ty
== Tarray
)
2685 this->result_
= d_array_value (build_ctype (e
->type
),
2686 size_int (0), null_pointer_node
);
2688 this->result_
= build_constructor (make_array_type (tb
->nextOf (), 0),
2694 /* Build an expression that assigns the expressions in ELEMENTS to
2696 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
2697 vec_safe_reserve (elms
, e
->elements
->dim
);
2698 bool constant_p
= true;
2699 tree saved_elems
= NULL_TREE
;
2701 Type
*etype
= tb
->nextOf ();
2702 tree satype
= make_array_type (etype
, e
->elements
->dim
);
2704 for (size_t i
= 0; i
< e
->elements
->dim
; i
++)
2706 Expression
*expr
= e
->getElement (i
);
2707 tree value
= build_expr (expr
, this->constp_
);
2709 /* Only append nonzero values, the backend will zero out the rest
2710 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2711 if (!initializer_zerop (value
))
2713 if (!TREE_CONSTANT (value
))
2716 /* Split construction of values out of the constructor if there
2717 may be side effects. */
2718 tree init
= stabilize_expr (&value
);
2719 if (init
!= NULL_TREE
)
2720 saved_elems
= compound_expr (saved_elems
, init
);
2722 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
),
2723 convert_expr (value
, expr
->type
, etype
));
2727 /* Now return the constructor as the correct type. For static arrays there
2728 is nothing else to do. For dynamic arrays, return a two field struct.
2729 For pointers, return the address. */
2730 tree ctor
= build_constructor (satype
, elms
);
2731 tree type
= build_ctype (e
->type
);
2733 /* Nothing else to do for static arrays. */
2734 if (tb
->ty
== Tsarray
|| this->constp_
)
2736 /* Can't take the address of the constructor, so create an anonymous
2737 static symbol, and then refer to it. */
2738 if (tb
->ty
!= Tsarray
)
2740 tree decl
= build_artificial_decl (TREE_TYPE (ctor
), ctor
, "A");
2741 ctor
= build_address (decl
);
2742 if (tb
->ty
== Tarray
)
2743 ctor
= d_array_value (type
, size_int (e
->elements
->dim
), ctor
);
2746 rest_of_decl_compilation (decl
, 1, 0);
2749 /* If the array literal is readonly or static. */
2751 TREE_CONSTANT (ctor
) = 1;
2752 if (constant_p
&& initializer_constant_valid_p (ctor
, TREE_TYPE (ctor
)))
2753 TREE_STATIC (ctor
) = 1;
2755 this->result_
= compound_expr (saved_elems
, d_convert (type
, ctor
));
2759 /* Allocate space on the memory managed heap. */
2760 tree mem
= build_libcall (LIBCALL_ARRAYLITERALTX
,
2761 etype
->pointerTo (), 2,
2762 build_typeinfo (e
->loc
, etype
->arrayOf ()),
2763 size_int (e
->elements
->dim
));
2764 mem
= d_save_expr (mem
);
2766 /* Now copy the constructor into memory. */
2767 tree tmemcpy
= builtin_decl_explicit (BUILT_IN_MEMCPY
);
2768 tree size
= size_mult_expr (size_int (e
->elements
->dim
),
2769 size_int (tb
->nextOf ()->size ()));
2771 tree result
= build_call_expr (tmemcpy
, 3, mem
,
2772 build_address (ctor
), size
);
2774 /* Return the array pointed to by MEM. */
2775 result
= compound_expr (result
, mem
);
2777 if (tb
->ty
== Tarray
)
2778 result
= d_array_value (type
, size_int (e
->elements
->dim
), result
);
2780 this->result_
= compound_expr (saved_elems
, result
);
2784 /* Build an associative array literal. The common type of the all keys is
2785 taken to be the key type, and common type of all values the value type.
2786 All keys and values are then implicitly converted as needed. */
2788 void visit (AssocArrayLiteralExp
*e
)
2790 /* Want the mutable type for typeinfo reference. */
2791 Type
*tb
= e
->type
->toBasetype ()->mutableOf ();
2792 gcc_assert (tb
->ty
== Taarray
);
2794 /* Handle empty assoc array literals. */
2795 TypeAArray
*ta
= (TypeAArray
*) tb
;
2796 if (e
->keys
->dim
== 0)
2798 this->result_
= build_constructor (build_ctype (ta
), NULL
);
2802 /* Build an expression that assigns all expressions in KEYS
2803 to a constructor. */
2804 vec
<constructor_elt
, va_gc
> *kelts
= NULL
;
2805 vec_safe_reserve (kelts
, e
->keys
->dim
);
2806 for (size_t i
= 0; i
< e
->keys
->dim
; i
++)
2808 Expression
*key
= (*e
->keys
)[i
];
2809 tree t
= build_expr (key
);
2810 CONSTRUCTOR_APPEND_ELT (kelts
, size_int (i
),
2811 convert_expr (t
, key
->type
, ta
->index
));
2813 tree tkeys
= make_array_type (ta
->index
, e
->keys
->dim
);
2814 tree akeys
= build_constructor (tkeys
, kelts
);
2816 /* Do the same with all expressions in VALUES. */
2817 vec
<constructor_elt
, va_gc
> *velts
= NULL
;
2818 vec_safe_reserve (velts
, e
->values
->dim
);
2819 for (size_t i
= 0; i
< e
->values
->dim
; i
++)
2821 Expression
*value
= (*e
->values
)[i
];
2822 tree t
= build_expr (value
);
2823 CONSTRUCTOR_APPEND_ELT (velts
, size_int (i
),
2824 convert_expr (t
, value
->type
, ta
->next
));
2826 tree tvals
= make_array_type (ta
->next
, e
->values
->dim
);
2827 tree avals
= build_constructor (tvals
, velts
);
2829 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2830 tree keys
= d_array_value (build_ctype (ta
->index
->arrayOf ()),
2831 size_int (e
->keys
->dim
), build_address (akeys
));
2832 tree vals
= d_array_value (build_ctype (ta
->next
->arrayOf ()),
2833 size_int (e
->values
->dim
),
2834 build_address (avals
));
2836 tree mem
= build_libcall (LIBCALL_ASSOCARRAYLITERALTX
, Type::tvoidptr
, 3,
2837 build_typeinfo (e
->loc
, ta
), keys
, vals
);
2839 /* Return an associative array pointed to by MEM. */
2840 tree aatype
= build_ctype (ta
);
2841 vec
<constructor_elt
, va_gc
> *ce
= NULL
;
2842 CONSTRUCTOR_APPEND_ELT (ce
, TYPE_FIELDS (aatype
), mem
);
2844 this->result_
= build_nop (build_ctype (e
->type
),
2845 build_constructor (aatype
, ce
));
2848 /* Build a struct literal. */
2850 void visit (StructLiteralExp
*e
)
2852 /* Handle empty struct literals. */
2853 if (e
->elements
== NULL
|| e
->sd
->fields
.dim
== 0)
2855 this->result_
= build_constructor (build_ctype (e
->type
), NULL
);
2859 /* Building sinit trees are delayed until after frontend semantic
2860 processing has complete. Build the static initializer now. */
2861 if (e
->useStaticInit
&& !this->constp_
)
2863 this->result_
= aggregate_initializer_decl (e
->sd
);
2867 /* Build a constructor that assigns the expressions in ELEMENTS
2868 at each field index that has been filled in. */
2869 vec
<constructor_elt
, va_gc
> *ve
= NULL
;
2870 tree saved_elems
= NULL_TREE
;
2872 /* CTFE may fill the hidden pointer by NullExp. */
2873 gcc_assert (e
->elements
->dim
<= e
->sd
->fields
.dim
);
2875 Type
*tb
= e
->type
->toBasetype ();
2876 gcc_assert (tb
->ty
== Tstruct
);
2878 for (size_t i
= 0; i
< e
->elements
->dim
; i
++)
2880 Expression
*exp
= (*e
->elements
)[i
];
2884 VarDeclaration
*field
= e
->sd
->fields
[i
];
2885 Type
*type
= exp
->type
->toBasetype ();
2886 Type
*ftype
= field
->type
->toBasetype ();
2887 tree value
= NULL_TREE
;
2889 if (ftype
->ty
== Tsarray
&& !same_type_p (type
, ftype
))
2891 /* Initialize a static array with a single element. */
2892 tree elem
= build_expr (exp
, this->constp_
);
2893 elem
= d_save_expr (elem
);
2895 if (initializer_zerop (elem
))
2896 value
= build_constructor (build_ctype (ftype
), NULL
);
2898 value
= build_array_from_val (ftype
, elem
);
2902 value
= convert_expr (build_expr (exp
, this->constp_
),
2903 exp
->type
, field
->type
);
2906 /* Split construction of values out of the constructor. */
2907 tree init
= stabilize_expr (&value
);
2908 if (init
!= NULL_TREE
)
2909 saved_elems
= compound_expr (saved_elems
, init
);
2911 CONSTRUCTOR_APPEND_ELT (ve
, get_symbol_decl (field
), value
);
2914 /* Maybe setup hidden pointer to outer scope context. */
2915 if (e
->sd
->isNested () && e
->elements
->dim
!= e
->sd
->fields
.dim
2916 && this->constp_
== false)
2918 tree field
= get_symbol_decl (e
->sd
->vthis
);
2919 tree value
= build_vthis (e
->sd
);
2920 CONSTRUCTOR_APPEND_ELT (ve
, field
, value
);
2921 gcc_assert (e
->useStaticInit
== false);
2924 /* Build a constructor in the correct shape of the aggregate type. */
2925 tree ctor
= build_struct_literal (build_ctype (e
->type
), ve
);
2927 /* Nothing more to do for constant literals. */
2930 /* If the struct literal is a valid for static data. */
2931 if (TREE_CONSTANT (ctor
)
2932 && initializer_constant_valid_p (ctor
, TREE_TYPE (ctor
)))
2933 TREE_STATIC (ctor
) = 1;
2935 this->result_
= compound_expr (saved_elems
, ctor
);
2941 tree var
= build_deref (e
->sym
);
2942 ctor
= compound_expr (modify_expr (var
, ctor
), var
);
2943 this->result_
= compound_expr (saved_elems
, ctor
);
2945 else if (e
->sd
->isUnionDeclaration ())
2947 /* For unions, use memset to fill holes in the object. */
2948 tree var
= build_local_temp (TREE_TYPE (ctor
));
2949 tree tmemset
= builtin_decl_explicit (BUILT_IN_MEMSET
);
2950 tree init
= build_call_expr (tmemset
, 3, build_address (var
),
2952 size_int (e
->sd
->structsize
));
2954 init
= compound_expr (init
, saved_elems
);
2955 init
= compound_expr (init
, modify_expr (var
, ctor
));
2956 this->result_
= compound_expr (init
, var
);
2959 this->result_
= compound_expr (saved_elems
, ctor
);
2962 /* Build a null literal. */
2964 void visit (NullExp
*e
)
2966 this->result_
= build_typeof_null_value (e
->type
);
2969 /* Build a vector literal. */
2971 void visit (VectorExp
*e
)
2973 tree type
= build_ctype (e
->type
);
2974 tree etype
= TREE_TYPE (type
);
2976 /* First handle array literal expressions. */
2977 if (e
->e1
->op
== TOKarrayliteral
)
2979 ArrayLiteralExp
*ale
= ((ArrayLiteralExp
*) e
->e1
);
2980 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
2981 bool constant_p
= true;
2983 vec_safe_reserve (elms
, ale
->elements
->dim
);
2984 for (size_t i
= 0; i
< ale
->elements
->dim
; i
++)
2986 Expression
*expr
= ale
->getElement (i
);
2987 tree value
= d_convert (etype
, build_expr (expr
, this->constp_
));
2988 if (!CONSTANT_CLASS_P (value
))
2991 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), value
);
2994 /* Build a VECTOR_CST from a constant vector constructor. */
2996 this->result_
= build_vector_from_ctor (type
, elms
);
2998 this->result_
= build_constructor (type
, elms
);
3002 /* Build constructor from single value. */
3003 tree val
= d_convert (etype
, build_expr (e
->e1
, this->constp_
));
3004 this->result_
= build_vector_from_val (type
, val
);
3008 /* Build a static array representation of a vector expression. */
3010 void visit (VectorArrayExp
*e
)
3012 this->result_
= convert_expr (build_expr (e
->e1
, this->constp_
),
3013 e
->e1
->type
, e
->type
);
3016 /* Build a static class literal, return its reference. */
3018 void visit (ClassReferenceExp
*e
)
3020 /* The result of build_new_class_expr is a RECORD_TYPE, we want
3022 tree var
= build_address (build_new_class_expr (e
));
3024 /* If the type of this literal is an interface, the we must add the
3025 interface offset to symbol. */
3028 TypeClass
*tc
= (TypeClass
*) e
->type
;
3029 InterfaceDeclaration
*to
= tc
->sym
->isInterfaceDeclaration ();
3033 ClassDeclaration
*from
= e
->originalClass ();
3036 gcc_assert (to
->isBaseOf (from
, &offset
) != 0);
3039 var
= build_offset (var
, size_int (offset
));
3043 this->result_
= var
;
3046 /* These expressions are mainly just a placeholders in the frontend.
3047 We shouldn't see them here. */
3049 void visit (ScopeExp
*e
)
3051 error_at (make_location_t (e
->loc
), "%qs is not an expression",
3053 this->result_
= error_mark_node
;
3056 void visit (TypeExp
*e
)
3058 error_at (make_location_t (e
->loc
), "type %qs is not an expression",
3060 this->result_
= error_mark_node
;
3065 /* Main entry point for ExprVisitor interface to generate code for
3066 the Expression AST class E. If CONST_P is true, then E is a
3067 constant expression. */
3070 build_expr (Expression
*e
, bool const_p
)
3072 ExprVisitor v
= ExprVisitor (const_p
);
3073 location_t saved_location
= input_location
;
3075 input_location
= make_location_t (e
->loc
);
3077 tree expr
= v
.result ();
3078 input_location
= saved_location
;
3080 /* Check if initializer expression is valid constant. */
3081 if (const_p
&& !initializer_constant_valid_p (expr
, TREE_TYPE (expr
)))
3083 error_at (make_location_t (e
->loc
), "non-constant expression %qs",
3085 return error_mark_node
;
3091 /* Same as build_expr, but also calls destructors on any temporaries. */
3094 build_expr_dtor (Expression
*e
)
3096 /* Codegen can be improved by determining if no exceptions can be thrown
3097 between the ctor and dtor, and eliminating the ctor and dtor. */
3098 size_t saved_vars
= vec_safe_length (d_function_chain
->vars_in_scope
);
3099 tree result
= build_expr (e
);
3101 if (saved_vars
!= vec_safe_length (d_function_chain
->vars_in_scope
))
3103 result
= fold_build_cleanup_point_expr (TREE_TYPE (result
), result
);
3104 vec_safe_truncate (d_function_chain
->vars_in_scope
, saved_vars
);
3110 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3113 build_return_dtor (Expression
*e
, Type
*type
, TypeFunction
*tf
)
3115 size_t saved_vars
= vec_safe_length (d_function_chain
->vars_in_scope
);
3116 tree result
= build_expr (e
);
3118 /* Convert for initializing the DECL_RESULT. */
3119 result
= convert_expr (result
, e
->type
, type
);
3121 /* If we are returning a reference, take the address. */
3123 result
= build_address (result
);
3125 /* The decl to store the return expression. */
3126 tree decl
= DECL_RESULT (cfun
->decl
);
3128 /* Split comma expressions, so that the result is returned directly. */
3129 tree expr
= stabilize_expr (&result
);
3130 result
= build_assign (INIT_EXPR
, decl
, result
);
3131 result
= compound_expr (expr
, return_expr (result
));
3133 /* May nest the return expression inside the try/finally expression. */
3134 if (saved_vars
!= vec_safe_length (d_function_chain
->vars_in_scope
))
3136 result
= fold_build_cleanup_point_expr (TREE_TYPE (result
), result
);
3137 vec_safe_truncate (d_function_chain
->vars_in_scope
, saved_vars
);