comparison gcc/d/expr.cc @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* expr.cc -- Lower D frontend expressions to GCC trees.
2 Copyright (C) 2015-2020 Free Software Foundation, Inc.
3
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
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.
13
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/>. */
17
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
21
22 #include "dmd/aggregate.h"
23 #include "dmd/ctfe.h"
24 #include "dmd/declaration.h"
25 #include "dmd/expression.h"
26 #include "dmd/identifier.h"
27 #include "dmd/init.h"
28 #include "dmd/module.h"
29 #include "dmd/mtype.h"
30 #include "dmd/template.h"
31
32 #include "tree.h"
33 #include "fold-const.h"
34 #include "diagnostic.h"
35 #include "langhooks.h"
36 #include "tm.h"
37 #include "function.h"
38 #include "toplev.h"
39 #include "varasm.h"
40 #include "predict.h"
41 #include "stor-layout.h"
42
43 #include "d-tree.h"
44
45
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. */
51
52 class ExprVisitor : public Visitor
53 {
54 using Visitor::visit;
55
56 tree result_;
57 bool constp_;
58
59 /* Determine if type is a struct that has a postblit. */
60
61 bool needs_postblit (Type *t)
62 {
63 t = t->baseElemOf ();
64
65 if (t->ty == Tstruct)
66 {
67 StructDeclaration *sd = ((TypeStruct *) t)->sym;
68 if (sd->postblit)
69 return true;
70 }
71
72 return false;
73 }
74
75 /* Determine if type is a struct that has a destructor. */
76
77 bool needs_dtor (Type *t)
78 {
79 t = t->baseElemOf ();
80
81 if (t->ty == Tstruct)
82 {
83 StructDeclaration *sd = ((TypeStruct *) t)->sym;
84 if (sd->dtor)
85 return true;
86 }
87
88 return false;
89 }
90
91 /* Determine if expression is suitable lvalue. */
92
93 bool lvalue_p (Expression *e)
94 {
95 return ((e->op != TOKslice && e->isLvalue ())
96 || (e->op == TOKslice && ((UnaExp *) e)->e1->isLvalue ())
97 || (e->op == TOKcast && ((UnaExp *) e)->e1->isLvalue ()));
98 }
99
100 /* Build an expression of code CODE, data type TYPE, and operands ARG0 and
101 ARG1. Perform relevant conversions needed for correct code operations. */
102
103 tree binary_op (tree_code code, tree type, tree arg0, tree arg1)
104 {
105 tree t0 = TREE_TYPE (arg0);
106 tree t1 = TREE_TYPE (arg1);
107 tree ret = NULL_TREE;
108
109 bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1);
110
111 /* Deal with float mod expressions immediately. */
112 if (code == FLOAT_MOD_EXPR)
113 return build_float_modulus (type, arg0, arg1);
114
115 if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
116 return build_nop (type, build_offset_op (code, arg0, arg1));
117
118 if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
119 return build_nop (type, build_offset_op (code, arg1, arg0));
120
121 if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
122 {
123 gcc_assert (code == MINUS_EXPR);
124 tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
125
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));
135 else
136 ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
137 }
138 else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp))
139 {
140 tree inttype = (unsignedp)
141 ? d_unsigned_type (type) : d_signed_type (type);
142 ret = fold_build2 (code, inttype, arg0, arg1);
143 }
144 else
145 {
146 /* If the operation needs excess precision. */
147 tree eptype = excess_precision_type (type);
148 if (eptype != NULL_TREE)
149 {
150 arg0 = d_convert (eptype, arg0);
151 arg1 = d_convert (eptype, arg1);
152 }
153 else
154 {
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);
161
162 eptype = type;
163 }
164
165 ret = fold_build2 (code, eptype, arg0, arg1);
166 }
167
168 return d_convert (type, ret);
169 }
170
171 /* Build a binary expression of code CODE, assigning the result into E1. */
172
173 tree binop_assignment (tree_code code, Expression *e1, Expression *e2)
174 {
175 /* Skip casts for lhs assignment. */
176 Expression *e1b = e1;
177 while (e1b->op == TOKcast)
178 {
179 CastExp *ce = (CastExp *) e1b;
180 gcc_assert (same_type_p (ce->type, ce->to));
181 e1b = ce->e1;
182 }
183
184 /* Stabilize LHS for assignment. */
185 tree lhs = build_expr (e1b);
186 tree lexpr = stabilize_expr (&lhs);
187
188 /* The LHS expression could be an assignment, to which its operation gets
189 lost during gimplification. */
190 if (TREE_CODE (lhs) == MODIFY_EXPR)
191 {
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));
198
199 lexpr = compound_expr (lexpr, lhs);
200 lhs = TREE_OPERAND (lhs, 0);
201 }
202
203 lhs = stabilize_reference (lhs);
204
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);
208
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);
213
214 tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
215 return compound_expr (lexpr, expr);
216 }
217
218 public:
219 ExprVisitor (bool constp)
220 {
221 this->result_ = NULL_TREE;
222 this->constp_ = constp;
223 }
224
225 tree result (void)
226 {
227 return this->result_;
228 }
229
230 /* Visitor interfaces, each Expression class should have
231 overridden the default. */
232
233 void visit (Expression *)
234 {
235 gcc_unreachable ();
236 }
237
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. */
241
242 void visit (CondExp *e)
243 {
244 tree cond = convert_for_condition (build_expr (e->econd),
245 e->econd->type);
246 tree t1 = build_expr (e->e1);
247 tree t2 = build_expr (e->e2);
248
249 if (e->type->ty != Tvoid)
250 {
251 t1 = convert_expr (t1, e->e1->type, e->type);
252 t2 = convert_expr (t2, e->e2->type, e->type);
253 }
254
255 this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
256 }
257
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. */
261
262 void visit (IdentityExp *e)
263 {
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 ();
267
268 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
269 && (tb2->ty == Tsarray || tb2->ty == Tarray))
270 {
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));
277 }
278 else if (tb1->isfloating () && tb1->ty != Tvector)
279 {
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));
284
285 if (!tb1->iscomplex ())
286 this->result_ = build_float_identity (code, t1, t2);
287 else
288 {
289 /* Compare the real and imaginary parts separately. */
290 tree req = build_float_identity (code, real_part (t1),
291 real_part (t2));
292 tree ieq = build_float_identity (code, imaginary_part (t1),
293 imaginary_part (t2));
294
295 if (code == EQ_EXPR)
296 this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
297 else
298 this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
299 }
300 }
301 else if (tb1->ty == Tstruct)
302 {
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);
308
309 gcc_assert (same_type_p (tb1, tb2));
310
311 this->result_ = build_struct_comparison (code, sd, t1, t2);
312 }
313 else
314 {
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));
321 }
322 }
323
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. */
327
328 void visit (EqualExp *e)
329 {
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;
333
334 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
335 && (tb2->ty == Tsarray || tb2->ty == Tarray))
336 {
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 ();
341
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)
350 {
351 tree t1 = d_array_convert (e->e1);
352 tree t2 = d_array_convert (e->e2);
353 tree result;
354
355 /* Make temporaries to prevent multiple evaluations. */
356 tree t1saved = d_save_expr (t1);
357 tree t2saved = d_save_expr (t2);
358
359 /* Length of arrays, for comparisons done before calling memcmp. */
360 tree t1len = d_array_length (t1saved);
361 tree t2len = d_array_length (t2saved);
362
363 /* Reference to array data. */
364 tree t1ptr = d_array_ptr (t1saved);
365 tree t2ptr = d_array_ptr (t2saved);
366
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))
371 {
372 tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
373 tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
374
375 result = build_call_expr (tmemcmp, 3, t1ptr, t2ptr, size);
376 result = build_boolop (code, result, integer_zero_node);
377 }
378 else
379 {
380 StructDeclaration *sd = ((TypeStruct *) t1elem)->sym;
381
382 result = build_array_struct_comparison (code, sd, t1len,
383 t1ptr, t2ptr);
384 }
385
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);
394 else
395 result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
396
397 /* Finally, check if lengths of both arrays match if dynamic.
398 The frontend should have already guaranteed that static arrays
399 have same size. */
400 if (tb1->ty == Tsarray && tb2->ty == Tsarray)
401 gcc_assert (tb1->size () == tb2->size ());
402 else
403 {
404 tree tlencmp = build_boolop (code, t1len, t2len);
405 if (e->op == TOKequal)
406 result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
407 else
408 result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
409 }
410
411 /* Ensure left-to-right order of evaluation. */
412 if (TREE_SIDE_EFFECTS (t2))
413 result = compound_expr (t2saved, result);
414
415 if (TREE_SIDE_EFFECTS (t1))
416 result = compound_expr (t1saved, result);
417
418 this->result_ = result;
419 }
420 else
421 {
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));
428
429 if (e->op == TOKnotequal)
430 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
431
432 this->result_ = result;
433 }
434 }
435 else if (tb1->ty == Tstruct)
436 {
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);
442
443 gcc_assert (same_type_p (tb1, tb2));
444
445 this->result_ = build_struct_comparison (code, sd, t1, t2);
446 }
447 else if (tb1->ty == Taarray && tb2->ty == Taarray)
448 {
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),
453 build_expr (e->e1),
454 build_expr (e->e2));
455
456 if (e->op == TOKnotequal)
457 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
458
459 this->result_ = result;
460 }
461 else
462 {
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);
467
468 this->result_ = d_convert (build_ctype (e->type),
469 build_boolop (code, t1, t2));
470 }
471 }
472
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. */
476
477 void visit (InExp *e)
478 {
479 Type *tb2 = e->e2->type->toBasetype ();
480 gcc_assert (tb2->ty == Taarray);
481
482 Type *tkey = ((TypeAArray *) tb2)->index->toBasetype ();
483 tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
484
485 /* Build a call to _aaInX(). */
486 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
487 build_expr (e->e2),
488 build_typeinfo (e->loc, tkey),
489 build_address (key));
490 }
491
492 /* Build a relational expression. The result type is bool. */
493
494 void visit (CmpExp *e)
495 {
496 Type *tb1 = e->e1->type->toBasetype ();
497 Type *tb2 = e->e2->type->toBasetype ();
498
499 tree result;
500 tree_code code;
501
502 switch (e->op)
503 {
504 case TOKle:
505 code = LE_EXPR;
506 break;
507
508 case TOKlt:
509 code = LT_EXPR;
510 break;
511
512 case TOKge:
513 code = GE_EXPR;
514 break;
515
516 case TOKgt:
517 code = GT_EXPR;
518 break;
519
520 default:
521 gcc_unreachable ();
522 }
523
524 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
525 && (tb2->ty == Tsarray || tb2->ty == Tarray))
526 {
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 ();
532
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);
538
539 this->result_ = d_convert (build_ctype (e->type), result);
540 return;
541 }
542
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);
546 }
547
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. */
550
551 void visit (AndAndExp *e)
552 {
553 if (e->e2->type->toBasetype ()->ty != Tvoid)
554 {
555 tree t1 = build_expr (e->e1);
556 tree t2 = build_expr (e->e2);
557
558 t1 = convert_for_condition (t1, e->e1->type);
559 t2 = convert_for_condition (t2, e->e2->type);
560
561 this->result_ = d_convert (build_ctype (e->type),
562 build_boolop (TRUTH_ANDIF_EXPR, t1, t2));
563 }
564 else
565 {
566 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
567 tree t2 = build_expr_dtor (e->e2);
568
569 this->result_ = build_condition (build_ctype (e->type),
570 t1, t2, void_node);
571 }
572 }
573
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. */
576
577 void visit (OrOrExp *e)
578 {
579 if (e->e2->type->toBasetype ()->ty != Tvoid)
580 {
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);
583
584 this->result_ = d_convert (build_ctype (e->type),
585 build_boolop (TRUTH_ORIF_EXPR, t1, t2));
586 }
587 else
588 {
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);
592
593 this->result_ = build_condition (build_ctype (e->type),
594 cond, t2, void_node);
595 }
596 }
597
598 /* Build a binary operand expression. Operands go through usual arithmetic
599 conversions to bring them to a common type before evaluating. */
600
601 void visit (BinExp *e)
602 {
603 tree_code code;
604
605 switch (e->op)
606 {
607 case TOKadd:
608 case TOKmin:
609 if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
610 || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
611 {
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);
616
617 if (e->op == TOKmin)
618 t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
619
620 if (e->e1->type->isreal ())
621 this->result_ = complex_expr (build_ctype (e->type), t1, t2);
622 else
623 this->result_ = complex_expr (build_ctype (e->type), t2, t1);
624
625 return;
626 }
627 else
628 code = (e->op == TOKadd)
629 ? PLUS_EXPR : MINUS_EXPR;
630 break;
631
632 case TOKmul:
633 code = MULT_EXPR;
634 break;
635
636 case TOKdiv:
637 code = e->e1->type->isintegral ()
638 ? TRUNC_DIV_EXPR : RDIV_EXPR;
639 break;
640
641 case TOKmod:
642 code = e->e1->type->isfloating ()
643 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
644 break;
645
646 case TOKand:
647 code = BIT_AND_EXPR;
648 break;
649
650 case TOKor:
651 code = BIT_IOR_EXPR;
652 break;
653
654 case TOKxor:
655 code = BIT_XOR_EXPR;
656 break;
657
658 case TOKshl:
659 code = LSHIFT_EXPR;
660 break;
661
662 case TOKshr:
663 code = RSHIFT_EXPR;
664 break;
665
666 case TOKushr:
667 code = UNSIGNED_RSHIFT_EXPR;
668 break;
669
670 default:
671 gcc_unreachable ();
672 }
673
674 this->result_ = this->binary_op (code, build_ctype (e->type),
675 build_expr (e->e1), build_expr (e->e2));
676 }
677
678
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. */
682
683 void visit (CatExp *e)
684 {
685 Type *tb1 = e->e1->type->toBasetype ();
686 Type *tb2 = e->e2->type->toBasetype ();
687 Type *etype;
688
689 if (tb1->ty == Tarray || tb1->ty == Tsarray)
690 etype = tb1->nextOf ();
691 else
692 etype = tb2->nextOf ();
693
694 vec<tree, va_gc> *elemvars = NULL;
695 tree result;
696
697 if (e->e1->op == TOKcat)
698 {
699 /* Flatten multiple concatenations to an array.
700 So the expression ((a ~ b) ~ c) becomes [a, b, c] */
701 int ndims = 2;
702
703 for (Expression *ex = e->e1; ex->op == TOKcat;)
704 {
705 if (ex->op == TOKcat)
706 {
707 ex = ((CatExp *) ex)->e1;
708 ndims++;
709 }
710 }
711
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);
717
718 /* Loop through each concatenation from right to left. */
719 vec<constructor_elt, va_gc> *elms = NULL;
720 CatExp *ce = e;
721 int dim = ndims - 1;
722
723 for (Expression *oe = ce->e2; oe != NULL;
724 (ce->e1->op != TOKcat
725 ? (oe = ce->e1)
726 : (ce = (CatExp *)ce->e1, oe = ce->e2)))
727 {
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));
731
732 /* Finished pushing all arrays. */
733 if (oe == ce->e1)
734 break;
735
736 dim -= 1;
737 }
738
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;
743
744 tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
745 size_int (ndims), build_address (var));
746
747 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
748 build_typeinfo (e->loc, e->type), arrs);
749 }
750 else
751 {
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));
757 }
758
759 for (size_t i = 0; i < vec_safe_length (elemvars); ++i)
760 result = bind_expr ((*elemvars)[i], result);
761
762 this->result_ = result;
763 }
764
765 /* Build an assignment operator expression. The right operand is implicitly
766 converted to the type of the left operand, and assigned to it. */
767
768 void visit (BinAssignExp *e)
769 {
770 tree_code code;
771 Expression *e1b = e->e1;
772
773 switch (e->op)
774 {
775 case TOKaddass:
776 code = PLUS_EXPR;
777 break;
778
779 case TOKminass:
780 code = MINUS_EXPR;
781 break;
782
783 case TOKmulass:
784 code = MULT_EXPR;
785 break;
786
787 case TOKdivass:
788 code = e->e1->type->isintegral ()
789 ? TRUNC_DIV_EXPR : RDIV_EXPR;
790 break;
791
792 case TOKmodass:
793 code = e->e1->type->isfloating ()
794 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
795 break;
796
797 case TOKandass:
798 code = BIT_AND_EXPR;
799 break;
800
801 case TOKorass:
802 code = BIT_IOR_EXPR;
803 break;
804
805 case TOKxorass:
806 code = BIT_XOR_EXPR;
807 break;
808
809 case TOKpowass:
810 gcc_unreachable ();
811
812 case TOKshlass:
813 code = LSHIFT_EXPR;
814 break;
815
816 case TOKshrass:
817 case TOKushrass:
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)
822 {
823 CastExp *ce = (CastExp *) e1b;
824 gcc_assert (same_type_p (ce->type, ce->to));
825 e1b = ce->e1;
826 }
827 code = (e->op == TOKshrass) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
828 break;
829
830 default:
831 gcc_unreachable ();
832 }
833
834 tree exp = this->binop_assignment (code, e1b, e->e2);
835 this->result_ = convert_expr (exp, e1b->type, e->type);
836 }
837
838 /* Build a concat assignment expression. The right operand is appended
839 to the the left operand. */
840
841 void visit (CatAssignExp *e)
842 {
843 Type *tb1 = e->e1->type->toBasetype ();
844 Type *tb2 = e->e2->type->toBasetype ();
845 Type *etype = tb1->nextOf ()->toBasetype ();
846
847 if (tb1->ty == Tarray && tb2->ty == Tdchar
848 && (etype->ty == Tchar || etype->ty == Twchar))
849 {
850 /* Append a dchar to a char[] or wchar[] */
851 libcall_fn libcall = (etype->ty == Tchar)
852 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
853
854 this->result_ = build_libcall (libcall, e->type, 2,
855 build_address (build_expr (e->e1)),
856 build_expr (e->e2));
857 }
858 else
859 {
860 gcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray);
861
862 tree tinfo = build_typeinfo (e->loc, e->type);
863 tree ptr = build_address (build_expr (e->e1));
864
865 if ((tb2->ty == Tarray || tb2->ty == Tsarray)
866 && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
867 {
868 /* Append an array. */
869 this->result_ = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
870 tinfo, ptr, d_array_convert (e->e2));
871
872 }
873 else if (same_type_p (etype, tb2))
874 {
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);
879
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);
885
886 tree ptrexp = d_array_ptr (result);
887 ptrexp = void_okay_p (ptrexp);
888 ptrexp = build_array_index (ptrexp, offexp);
889
890 /* Evaluate expression before appending. */
891 tree t2 = build_expr (e->e2);
892 tree expr = stabilize_expr (&t2);
893
894 t2 = d_save_expr (t2);
895 result = modify_expr (build_deref (ptrexp), t2);
896 result = compound_expr (t2, result);
897
898 this->result_ = compound_expr (expr, result);
899 }
900 else
901 gcc_unreachable ();
902 }
903 }
904
905 /* Build an assignment expression. The right operand is implicitly
906 converted to the type of the left operand, and assigned to it. */
907
908 void visit (AssignExp *e)
909 {
910 /* First, handle special assignment semantics. */
911
912 /* Look for array.length = n; */
913 if (e->e1->op == TOKarraylength)
914 {
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,
918 Type::tsize_t);
919 tree ptr = build_address (build_expr (ale->e1));
920
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;
925
926 tree result = build_libcall (libcall, ale->e1->type, 3,
927 build_typeinfo (ale->loc, ale->e1->type),
928 newlength, ptr);
929
930 this->result_ = d_array_length (result);
931 return;
932 }
933
934 /* Look for array[] = n; */
935 if (e->e1->op == TOKslice)
936 {
937 SliceExp *se = (SliceExp *) e->e1;
938 Type *stype = se->e1->type->toBasetype ();
939 Type *etype = stype->nextOf ()->toBasetype ();
940
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);
944
945 if (e->memset & blockAssign)
946 {
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);
950 tree result;
951
952 if ((postblit || destructor) && e->op != TOKblit)
953 {
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);
959
960 tree result = build_libcall (libcall, Type::tvoid, 4,
961 d_array_ptr (t1),
962 build_address (t2),
963 d_array_length (t1), ti);
964 this->result_ = compound_expr (result, t1);
965 return;
966 }
967
968 if (integer_zerop (t2))
969 {
970 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
971 tree size = size_mult_expr (d_array_length (t1),
972 size_int (etype->size ()));
973
974 result = build_call_expr (tmemset, 3, d_array_ptr (t1),
975 integer_zero_node, size);
976 }
977 else
978 result = build_array_set (d_array_ptr (t1),
979 d_array_length (t1), t2);
980
981 this->result_ = compound_expr (result, t1);
982 }
983 else
984 {
985 /* Perform a memcpy operation. */
986 gcc_assert (e->e2->type->ty != Tpointer);
987
988 if (!postblit && !destructor && !array_bounds_check ())
989 {
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 ()));
995
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);
999 }
1000 else if ((postblit || destructor) && e->op != TOKblit)
1001 {
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;
1006
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));
1011 }
1012 else
1013 {
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));
1019 }
1020 }
1021
1022 return;
1023 }
1024
1025 /* Look for reference initializations. */
1026 if (e->memset & referenceInit)
1027 {
1028 gcc_assert (e->op == TOKconstruct || e->op == TOKblit);
1029 gcc_assert (e->e1->op == TOKvar);
1030
1031 Declaration *decl = ((VarExp *) e->e1)->var;
1032 if (decl->storage_class & (STCout | STCref))
1033 {
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);
1040
1041 this->result_ = indirect_ref (build_ctype (e->type),
1042 build_assign (INIT_EXPR, t1, t2));
1043 return;
1044 }
1045 }
1046
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;
1050
1051 /* Look for struct assignment. */
1052 if (tb1->ty == Tstruct)
1053 {
1054 tree t1 = build_expr (e->e1);
1055 tree t2 = convert_for_assignment (build_expr (e->e2),
1056 e->e2->type, e->e1->type);
1057
1058 /* Look for struct = 0. */
1059 if (e->e2->op == TOKint64)
1060 {
1061 /* Use memset to fill struct. */
1062 gcc_assert (e->op == TOKblit);
1063 StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
1064
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));
1068
1069 /* Maybe set-up hidden pointer to outer scope context. */
1070 if (sd->isNested ())
1071 {
1072 tree field = get_symbol_decl (sd->vthis);
1073 tree value = build_vthis (sd);
1074
1075 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1076 result = compound_expr (result, vthis_exp);
1077 }
1078
1079 this->result_ = compound_expr (result, t1);
1080 }
1081 else
1082 this->result_ = build_assign (modifycode, t1, t2);
1083
1084 return;
1085 }
1086
1087 /* Look for static array assignment. */
1088 if (tb1->ty == Tsarray)
1089 {
1090 /* Look for array = 0. */
1091 if (e->e2->op == TOKint64)
1092 {
1093 /* Use memset to fill the array. */
1094 gcc_assert (e->op == TOKblit);
1095
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 ());
1100
1101 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1102 this->result_ = build_call_expr (tmemset, 3, build_address (t1),
1103 t2, size);
1104 return;
1105 }
1106
1107 Type *etype = tb1->nextOf ();
1108 gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);
1109
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);
1114
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))
1121 {
1122 tree t1 = build_expr (e->e1);
1123 tree t2 = convert_for_assignment (build_expr (e->e2),
1124 e->e2->type, e->e1->type);
1125
1126 this->result_ = build_assign (modifycode, t1, t2);
1127 return;
1128 }
1129
1130 Type *arrtype = (e->type->ty == Tsarray) ? etype->arrayOf () : e->type;
1131 tree result;
1132
1133 if (e->op == TOKconstruct)
1134 {
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));
1140 }
1141 else
1142 {
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));
1148
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));
1154 }
1155
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));
1160
1161 this->result_ = result;
1162 return;
1163 }
1164
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);
1169
1170 this->result_ = build_assign (modifycode, t1, t2);
1171 }
1172
1173 /* Build a postfix expression. */
1174
1175 void visit (PostExp *e)
1176 {
1177 tree result;
1178
1179 if (e->op == TOKplusplus)
1180 {
1181 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1182 build_expr (e->e1), build_expr (e->e2));
1183 }
1184 else if (e->op == TOKminusminus)
1185 {
1186 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1187 build_expr (e->e1), build_expr (e->e2));
1188 }
1189 else
1190 gcc_unreachable ();
1191
1192 TREE_SIDE_EFFECTS (result) = 1;
1193 this->result_ = result;
1194 }
1195
1196 /* Build an index expression. */
1197
1198 void visit (IndexExp *e)
1199 {
1200 Type *tb1 = e->e1->type->toBasetype ();
1201
1202 if (tb1->ty == Taarray)
1203 {
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);
1207 libcall_fn libcall;
1208 tree tinfo, ptr;
1209
1210 if (e->modifiable)
1211 {
1212 libcall = LIBCALL_AAGETY;
1213 ptr = build_address (build_expr (e->e1));
1214 tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());
1215 }
1216 else
1217 {
1218 libcall = LIBCALL_AAGETRVALUEX;
1219 ptr = build_expr (e->e1);
1220 tinfo = build_typeinfo (e->loc, tkey);
1221 }
1222
1223 /* Index the associative array. */
1224 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1225 ptr, tinfo,
1226 size_int (tb1->nextOf ()->size ()),
1227 build_address (key));
1228
1229 if (!e->indexIsInBounds && array_bounds_check ())
1230 {
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);
1234
1235 result = d_save_expr (result);
1236 result = build_condition (TREE_TYPE (result),
1237 d_truthvalue_conversion (result),
1238 result, tassert);
1239 }
1240
1241 this->result_ = indirect_ref (build_ctype (e->type), result);
1242 }
1243 else
1244 {
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 ());
1248
1249 tree length = NULL_TREE;
1250 if (tb1->ty != Tpointer)
1251 length = get_array_length (array, tb1);
1252 else
1253 gcc_assert (e->lengthVar == NULL);
1254
1255 /* The __dollar variable just becomes a placeholder for the
1256 actual length. */
1257 if (e->lengthVar)
1258 e->lengthVar->csym = length;
1259
1260 /* Generate the index. */
1261 tree index = build_expr (e->e2);
1262
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);
1267
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));
1272 }
1273 }
1274
1275 /* Build a comma expression. The type is the type of the right operand. */
1276
1277 void visit (CommaExp *e)
1278 {
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;
1282
1283 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1284 }
1285
1286 /* Build an array length expression. Returns the number of elements
1287 in the array. The result is of type size_t. */
1288
1289 void visit (ArrayLengthExp *e)
1290 {
1291 if (e->e1->type->toBasetype ()->ty == Tarray)
1292 this->result_ = d_array_length (build_expr (e->e1));
1293 else
1294 {
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;
1298 }
1299 }
1300
1301 /* Build a delegate pointer expression. This will return the frame
1302 pointer value as a type void*. */
1303
1304 void visit (DelegatePtrExp *e)
1305 {
1306 tree t1 = build_expr (e->e1);
1307 this->result_ = delegate_object (t1);
1308 }
1309
1310 /* Build a delegate function pointer expression. This will return the
1311 function pointer value as a function type. */
1312
1313 void visit (DelegateFuncptrExp *e)
1314 {
1315 tree t1 = build_expr (e->e1);
1316 this->result_ = delegate_method (t1);
1317 }
1318
1319 /* Build a slice expression. */
1320
1321 void visit (SliceExp *e)
1322 {
1323 Type *tb = e->type->toBasetype ();
1324 Type *tb1 = e->e1->type->toBasetype ();
1325 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray);
1326
1327 /* Use convert-to-dynamic-array code if possible. */
1328 if (!e->lwr)
1329 {
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);
1333
1334 this->result_ = result;
1335 return;
1336 }
1337 else
1338 gcc_assert (e->upr != NULL);
1339
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;
1344
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);
1349 else
1350 gcc_assert (e->lengthVar == NULL);
1351
1352 /* The __dollar variable just becomes a placeholder for the
1353 actual length. */
1354 if (e->lengthVar)
1355 e->lengthVar->csym = length;
1356
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));
1360
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);
1365
1366 /* Adjust the .ptr offset. */
1367 if (!integer_zerop (lwr_tree))
1368 {
1369 tree ptrtype = TREE_TYPE (ptr);
1370 ptr = build_array_index (void_okay_p (ptr), lwr_tree);
1371 ptr = build_nop (ptrtype, ptr);
1372 }
1373 else
1374 lwr_tree = NULL_TREE;
1375
1376 /* Nothing more to do for static arrays, their bounds checking has been
1377 done at compile-time. */
1378 if (tb->ty == Tsarray)
1379 {
1380 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1381 return;
1382 }
1383 else
1384 gcc_assert (tb->ty == Tarray);
1385
1386 /* Generate bounds checking code. */
1387 tree newlength;
1388
1389 if (!e->upperIsInBounds)
1390 {
1391 if (length)
1392 {
1393 newlength = build_bounds_condition (e->upr->loc, upr_tree,
1394 length, true);
1395 }
1396 else
1397 {
1398 /* Still need to check bounds lwr <= upr for pointers. */
1399 gcc_assert (tb1->ty == Tpointer);
1400 newlength = upr_tree;
1401 }
1402 }
1403 else
1404 newlength = upr_tree;
1405
1406 if (lwr_tree)
1407 {
1408 /* Enforces lwr <= upr. No need to check lwr <= length as
1409 we've already ensured that upr <= length. */
1410 if (!e->lowerIsLessThanUpper)
1411 {
1412 tree cond = build_bounds_condition (e->lwr->loc, lwr_tree,
1413 upr_tree, true);
1414
1415 /* When bounds checking is off, the index value is
1416 returned directly. */
1417 if (cond != lwr_tree)
1418 newlength = compound_expr (cond, newlength);
1419 }
1420
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);
1425 }
1426
1427 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1428 this->result_ = compound_expr (array, result);
1429 }
1430
1431 /* Build a cast expression, which converts the given unary expression to the
1432 type of result. */
1433
1434 void visit (CastExp *e)
1435 {
1436 Type *ebtype = e->e1->type->toBasetype ();
1437 Type *tbtype = e->to->toBasetype ();
1438 tree result = build_expr (e->e1, this->constp_);
1439
1440 /* Just evaluate e1 if it has any side effects. */
1441 if (tbtype->ty == Tvoid)
1442 this->result_ = build_nop (build_ctype (tbtype), result);
1443 else
1444 this->result_ = convert_expr (result, ebtype, tbtype);
1445 }
1446
1447 /* Build a delete expression. */
1448
1449 void visit (DeleteExp *e)
1450 {
1451 tree t1 = build_expr (e->e1);
1452 Type *tb1 = e->e1->type->toBasetype ();
1453
1454 if (tb1->ty == Tclass)
1455 {
1456 /* For class object references, if there is a destructor for that class,
1457 the destructor is called for the object instance. */
1458 libcall_fn libcall;
1459
1460 if (e->e1->op == TOKvar)
1461 {
1462 VarDeclaration *v = ((VarExp *) e->e1)->var->isVarDeclaration ();
1463 if (v && v->onstack)
1464 {
1465 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1466 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1467
1468 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1469 return;
1470 }
1471 }
1472
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;
1477
1478 t1 = build_address (t1);
1479 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1480 }
1481 else if (tb1->ty == Tarray)
1482 {
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;
1487
1488 if (telem->ty == Tstruct)
1489 {
1490 /* Might need to run destructor on array contents. */
1491 TypeStruct *ts = (TypeStruct *) telem;
1492 if (ts->sym->dtor)
1493 ti = build_typeinfo (e->loc, tb1->nextOf ());
1494 }
1495
1496 /* Generate: _delarray_t (&t1, ti); */
1497 this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,
1498 build_address (t1), ti);
1499 }
1500 else if (tb1->ty == Tpointer)
1501 {
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 ();
1506
1507 if (tnext->ty == Tstruct)
1508 {
1509 TypeStruct *ts = (TypeStruct *)tnext;
1510 if (ts->sym->dtor)
1511 {
1512 tree ti = build_typeinfo (e->loc, tnext);
1513 this->result_ = build_libcall (LIBCALL_DELSTRUCT, Type::tvoid,
1514 2, t1, ti);
1515 return;
1516 }
1517 }
1518
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);
1522 }
1523 else
1524 {
1525 error ("don%'t know how to delete %qs", e->e1->toChars ());
1526 this->result_ = error_mark_node;
1527 }
1528 }
1529
1530 /* Build a remove expression, which removes a particular key from an
1531 associative array. */
1532
1533 void visit (RemoveExp *e)
1534 {
1535 /* Check that the array is actually an associative array. */
1536 if (e->e1->type->toBasetype ()->ty == Taarray)
1537 {
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);
1541
1542 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1543 build_expr (e->e1),
1544 build_typeinfo (e->loc, tkey),
1545 build_address (index));
1546 }
1547 else
1548 {
1549 error ("%qs is not an associative array", e->e1->toChars ());
1550 this->result_ = error_mark_node;
1551 }
1552 }
1553
1554 /* Build an unary not expression. */
1555
1556 void visit (NotExp *e)
1557 {
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);
1561
1562 this->result_ = d_convert (build_ctype (e->type), result);
1563 }
1564
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. */
1568
1569 void visit (ComExp *e)
1570 {
1571 TY ty1 = e->e1->type->toBasetype ()->ty;
1572 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1573
1574 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1575 build_expr (e->e1));
1576 }
1577
1578 /* Build an unary negation expression. */
1579
1580 void visit (NegExp *e)
1581 {
1582 TY ty1 = e->e1->type->toBasetype ()->ty;
1583 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1584
1585 tree type = build_ctype (e->type);
1586 tree expr = build_expr (e->e1);
1587
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);
1592 else
1593 eptype = type;
1594
1595 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1596 this->result_ = d_convert (type, ret);
1597 }
1598
1599 /* Build a pointer index expression. */
1600
1601 void visit (PtrExp *e)
1602 {
1603 Type *tnext = NULL;
1604 size_t offset;
1605 tree result;
1606
1607 if (e->e1->op == TOKadd)
1608 {
1609 BinExp *be = (BinExp *) e->e1;
1610 if (be->e1->op == TOKaddress
1611 && be->e2->isConst () && be->e2->type->isintegral ())
1612 {
1613 Expression *ae = ((AddrExp *) be->e1)->e1;
1614 tnext = ae->type->toBasetype ();
1615 result = build_expr (ae);
1616 offset = be->e2->toUInteger ();
1617 }
1618 }
1619 else if (e->e1->op == TOKsymoff)
1620 {
1621 SymOffExp *se = (SymOffExp *) e->e1;
1622 if (!declaration_reference_p (se->var))
1623 {
1624 tnext = se->var->type->toBasetype ();
1625 result = get_decl_tree (se->var);
1626 offset = se->offset;
1627 }
1628 }
1629
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)
1634 {
1635 StructDeclaration *sd = ((TypeStruct *) tnext)->sym;
1636
1637 for (size_t i = 0; i < sd->fields.dim; i++)
1638 {
1639 VarDeclaration *field = sd->fields[i];
1640
1641 if (field->offset == offset
1642 && same_type_p (field->type, e->type))
1643 {
1644 /* Catch errors, backend will ICE otherwise. */
1645 if (error_operand_p (result))
1646 this->result_ = result;
1647 else
1648 {
1649 result = component_ref (result, get_symbol_decl (field));
1650 this->result_ = result;
1651 }
1652 return;
1653 }
1654 else if (field->offset > offset)
1655 break;
1656 }
1657 }
1658
1659 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1660 }
1661
1662 /* Build an unary address expression. */
1663
1664 void visit (AddrExp *e)
1665 {
1666 tree type = build_ctype (e->type);
1667 tree exp;
1668
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)
1672 {
1673 StructLiteralExp *sle = ((StructLiteralExp *) e->e1)->origin;
1674 gcc_assert (sle != NULL);
1675
1676 /* Build the reference symbol, the decl is built first as the
1677 initializer may have recursive references. */
1678 if (!sle->sym)
1679 {
1680 sle->sym = build_artificial_decl (build_ctype (sle->type),
1681 NULL_TREE, "S");
1682 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1683 d_pushdecl (sle->sym);
1684 rest_of_decl_compilation (sle->sym, 1, 0);
1685 }
1686
1687 exp = sle->sym;
1688 }
1689 else
1690 exp = build_expr (e->e1, this->constp_);
1691
1692 TREE_CONSTANT (exp) = 0;
1693 this->result_ = d_convert (type, build_address (exp));
1694 }
1695
1696 /* Build a function call expression. */
1697
1698 void visit (CallExp *e)
1699 {
1700 Type *tb = e->e1->type->toBasetype ();
1701 Expression *e1b = e->e1;
1702
1703 tree callee = NULL_TREE;
1704 tree object = NULL_TREE;
1705 tree cleanup = NULL_TREE;
1706 TypeFunction *tf = NULL;
1707
1708 /* Calls to delegates can sometimes look like this. */
1709 if (e1b->op == TOKcomma)
1710 {
1711 e1b = ((CommaExp *) e1b)->e2;
1712 gcc_assert (e1b->op == TOKvar);
1713
1714 Declaration *var = ((VarExp *) e1b)->var;
1715 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1716 }
1717
1718 if (e1b->op == TOKdotvar && tb->ty != Tdelegate)
1719 {
1720 DotVarExp *dve = (DotVarExp *) e1b;
1721
1722 /* Don't modify the static initializer for struct literals. */
1723 if (dve->e1->op == TOKstructliteral)
1724 {
1725 StructLiteralExp *sle = (StructLiteralExp *) dve->e1;
1726 sle->useStaticInit = false;
1727 }
1728
1729 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1730 if (fd != NULL)
1731 {
1732 /* Get the correct callee from the DotVarExp object. */
1733 tree fndecl = get_symbol_decl (fd);
1734 AggregateDeclaration *ad = fd->isThis ();
1735
1736 /* Static method; ignore the object instance. */
1737 if (!ad)
1738 callee = build_address (fndecl);
1739 else
1740 {
1741 tree thisexp = build_expr (dve->e1);
1742
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)))
1751 {
1752 cleanup = TREE_OPERAND (thisexp, 0);
1753 thisexp = TREE_OPERAND (thisexp, 1);
1754 }
1755
1756 /* Want reference to 'this' object. */
1757 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1758 thisexp = build_address (thisexp);
1759
1760 /* Make the callee a virtual call. */
1761 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1762 {
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);
1767 }
1768 else
1769 fndecl = build_address (fndecl);
1770
1771 callee = build_method_call (fndecl, thisexp, fd->type);
1772 }
1773 }
1774 }
1775
1776 if (callee == NULL_TREE)
1777 callee = build_expr (e1b);
1778
1779 if (METHOD_CALL_EXPR (callee))
1780 {
1781 /* This could be a delegate expression (TY == Tdelegate), but not
1782 actually a delegate variable. */
1783 if (e1b->op == TOKdotvar)
1784 {
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);
1789 }
1790 else
1791 tf = get_function_type (tb);
1792
1793 extract_from_method_call (callee, callee, object);
1794 }
1795 else if (tb->ty == Tdelegate)
1796 {
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);
1802 }
1803 else if (e1b->op == TOKvar)
1804 {
1805 FuncDeclaration *fd = ((VarExp *) e1b)->var->isFuncDeclaration ();
1806 gcc_assert (fd != NULL);
1807 tf = get_function_type (fd->type);
1808
1809 if (fd->isNested ())
1810 {
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;
1814
1815 object = get_frame_for_symbol (fd);
1816 }
1817 else if (fd->needThis ())
1818 {
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;
1823 }
1824 }
1825 else
1826 {
1827 /* Normal direct function call. */
1828 tf = get_function_type (tb);
1829 }
1830
1831 gcc_assert (tf != NULL);
1832
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);
1836
1837 if (tf->isref)
1838 exp = build_deref (exp);
1839
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);
1844
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)
1849 {
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);
1854
1855 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1856 exp = cleanup;
1857 }
1858
1859 this->result_ = exp;
1860 }
1861
1862 /* Build a delegate expression. */
1863
1864 void visit (DelegateExp *e)
1865 {
1866 if (e->func->semanticRun == PASSsemantic3done)
1867 {
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);
1875 }
1876
1877 tree fndecl;
1878 tree object;
1879
1880 if (e->func->isNested ())
1881 {
1882 if (e->e1->op == TOKnull)
1883 object = build_expr (e->e1);
1884 else
1885 object = get_frame_for_symbol (e->func);
1886
1887 fndecl = build_address (get_symbol_decl (e->func));
1888 }
1889 else
1890 {
1891 if (!e->func->isThis ())
1892 {
1893 error ("delegates are only for non-static functions");
1894 this->result_ = error_mark_node;
1895 return;
1896 }
1897
1898 object = build_expr (e->e1);
1899
1900 /* Want reference to `this' object. */
1901 if (e->e1->type->ty != Tclass && e->e1->type->ty != Tpointer)
1902 object = build_address (object);
1903
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);
1908
1909 fndecl = get_symbol_decl (e->func);
1910
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)
1914 {
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);
1918 }
1919 else
1920 fndecl = build_address (fndecl);
1921 }
1922
1923 this->result_ = build_method_call (fndecl, object, e->type);
1924 }
1925
1926 /* Build a type component expression. */
1927
1928 void visit (DotTypeExp *e)
1929 {
1930 /* Just a pass through to underlying expression. */
1931 this->result_ = build_expr (e->e1);
1932 }
1933
1934 /* Build a component reference expression. */
1935
1936 void visit (DotVarExp *e)
1937 {
1938 VarDeclaration *vd = e->var->isVarDeclaration ();
1939
1940 /* This could also be a function, but relying on that being taken
1941 care of by the visitor interface for CallExp. */
1942 if (vd != NULL)
1943 {
1944 if (!vd->isField ())
1945 this->result_ = get_decl_tree (vd);
1946 else
1947 {
1948 tree object = build_expr (e->e1);
1949
1950 if (e->e1->type->toBasetype ()->ty != Tstruct)
1951 object = build_deref (object);
1952
1953 this->result_ = component_ref (object, get_symbol_decl (vd));
1954 }
1955 }
1956 else
1957 {
1958 error ("%qs is not a field, but a %qs",
1959 e->var->toChars (), e->var->kind ());
1960 this->result_ = error_mark_node;
1961 }
1962 }
1963
1964 /* Build an assert expression, used to declare conditions that must hold at
1965 that a given point in the program. */
1966
1967 void visit (AssertExp *e)
1968 {
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;
1973 tree assert_fail;
1974
1975 if (global.params.useAssert
1976 && global.params.checkAction == CHECKACTION_D)
1977 {
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 ();
1981 libcall_fn libcall;
1982
1983 if (e->msg)
1984 {
1985 tmsg = build_expr_dtor (e->msg);
1986 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1987 }
1988 else
1989 libcall = unittest_p ? LIBCALL_UNITTEST : LIBCALL_ASSERT;
1990
1991 /* Build a call to _d_assert(). */
1992 assert_fail = d_assert_call (e->loc, libcall, tmsg);
1993
1994 if (global.params.useInvariants)
1995 {
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)
1999 {
2000 ClassDeclaration *cd = tb1->isClassHandle ();
2001 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
2002 {
2003 arg = d_save_expr (arg);
2004 assert_pass = build_libcall (LIBCALL_INVARIANT,
2005 Type::tvoid, 1, arg);
2006 }
2007 }
2008 else if (tb1->ty == Tpointer && tb1->nextOf ()->ty == Tstruct)
2009 {
2010 StructDeclaration *sd = ((TypeStruct *) tb1->nextOf ())->sym;
2011 if (sd->inv != NULL)
2012 {
2013 Expressions args;
2014 arg = d_save_expr (arg);
2015 assert_pass = d_build_call_expr (sd->inv, arg, &args);
2016 }
2017 }
2018 }
2019 }
2020 else if (global.params.useAssert
2021 && global.params.checkAction == CHECKACTION_C)
2022 {
2023 /* Generate: __builtin_trap() */
2024 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
2025 assert_fail = build_call_expr (fn, 0);
2026 }
2027 else
2028 {
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))
2032 {
2033 this->result_ = void_node;
2034 return;
2035 }
2036
2037 assert_fail = build_predict_expr (PRED_NORETURN, NOT_TAKEN);
2038 }
2039
2040 /* Build condition that we are asserting in this contract. */
2041 tree condition = convert_for_condition (arg, e->e1->type);
2042
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));
2049
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);
2053
2054 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
2055 }
2056
2057 /* Build a declaration expression. */
2058
2059 void visit (DeclarationExp *e)
2060 {
2061 /* Compile the declaration. */
2062 push_stmt_list ();
2063 build_decl_tree (e->declaration);
2064 tree result = pop_stmt_list ();
2065
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);
2071
2072 this->result_ = result;
2073 }
2074
2075 /* Build a typeid expression. Returns an instance of class TypeInfo
2076 corresponding to. */
2077
2078 void visit (TypeidExp *e)
2079 {
2080 if (Type *tid = isType (e->obj))
2081 {
2082 tree ti = build_typeinfo (e->loc, tid);
2083
2084 /* If the typeinfo is at an offset. */
2085 if (tid->vtinfo->offset)
2086 ti = build_offset (ti, size_int (tid->vtinfo->offset));
2087
2088 this->result_ = build_nop (build_ctype (e->type), ti);
2089 }
2090 else if (Expression *tid = isExpression (e->obj))
2091 {
2092 Type *type = tid->type->toBasetype ();
2093 assert (type->ty == Tclass);
2094
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);
2099
2100 /* Add extra indirection for interfaces. */
2101 if (((TypeClass *) type)->sym->isInterfaceDeclaration ())
2102 ci = indirect_ref (ptr_type_node, ci);
2103
2104 this->result_ = build_nop (build_ctype (e->type), ci);
2105 }
2106 else
2107 gcc_unreachable ();
2108 }
2109
2110 /* Build a function/lambda expression. */
2111
2112 void visit (FuncExp *e)
2113 {
2114 Type *ftype = e->type->toBasetype ();
2115
2116 /* This check is for lambda's, remove 'vthis' as function isn't nested. */
2117 if (e->fd->tok == TOKreserved && ftype->ty == Tpointer)
2118 {
2119 e->fd->tok = TOKfunction;
2120 e->fd->vthis = NULL;
2121 }
2122
2123 /* Compile the function literal body. */
2124 build_decl_tree (e->fd);
2125
2126 /* If nested, this will be a trampoline. */
2127 if (e->fd->isNested ())
2128 {
2129 tree func = build_address (get_symbol_decl (e->fd));
2130 tree object;
2131
2132 if (this->constp_)
2133 {
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;
2138 }
2139 else
2140 {
2141 object = get_frame_for_symbol (e->fd);
2142 this->result_ = build_method_call (func, object, e->fd->type);
2143 }
2144 }
2145 else
2146 {
2147 this->result_ = build_nop (build_ctype (e->type),
2148 build_address (get_symbol_decl (e->fd)));
2149 }
2150 }
2151
2152 /* Build a halt expression. */
2153
2154 void visit (HaltExp *)
2155 {
2156 /* Should we use trap() or abort()? */
2157 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2158 this->result_ = build_call_expr (ttrap, 0);
2159 }
2160
2161 /* Build a symbol pointer offset expression. */
2162
2163 void visit (SymOffExp *e)
2164 {
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;
2169
2170 if (declaration_reference_p (e->var))
2171 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2172 else
2173 result = build_address (result);
2174
2175 if (!soffset)
2176 result = d_convert (build_ctype (e->type), result);
2177 else
2178 {
2179 tree offset = size_int (soffset);
2180 result = build_nop (build_ctype (e->type),
2181 build_offset (result, offset));
2182 }
2183
2184 this->result_ = result;
2185 }
2186
2187 /* Build a variable expression. */
2188
2189 void visit (VarExp *e)
2190 {
2191 if (e->var->needThis ())
2192 {
2193 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2194 this->result_ = error_mark_node;
2195 return;
2196 }
2197 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2198 {
2199 /* __ctfe is always false at run-time. */
2200 this->result_ = integer_zero_node;
2201 return;
2202 }
2203
2204 /* This check is same as is done in FuncExp for lambdas. */
2205 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2206 if (fld != NULL)
2207 {
2208 if (fld->tok == TOKreserved)
2209 {
2210 fld->tok = TOKfunction;
2211 fld->vthis = NULL;
2212 }
2213
2214 /* Compiler the function literal body. */
2215 build_decl_tree (fld);
2216 }
2217
2218 if (this->constp_)
2219 {
2220 /* Want the initializer, not the expression. */
2221 VarDeclaration *var = e->var->isVarDeclaration ();
2222 SymbolDeclaration *sd = e->var->isSymbolDeclaration ();
2223 tree init = NULL_TREE;
2224
2225 if (var && (var->isConst () || var->isImmutable ())
2226 && e->type->toBasetype ()->ty != Tsarray && var->_init)
2227 {
2228 if (var->inuse)
2229 error_at (make_location_t (e->loc), "recursive reference %qs",
2230 e->toChars ());
2231 else
2232 {
2233 var->inuse++;
2234 init = build_expr (initializerToExpression (var->_init), true);
2235 var->inuse--;
2236 }
2237 }
2238 else if (sd && sd->dsym)
2239 init = layout_struct_initializer (sd->dsym);
2240 else
2241 error_at (make_location_t (e->loc), "non-constant expression %qs",
2242 e->toChars ());
2243
2244 if (init != NULL_TREE)
2245 this->result_ = init;
2246 else
2247 this->result_ = error_mark_node;
2248 }
2249 else
2250 {
2251 tree result = get_decl_tree (e->var);
2252 TREE_USED (result) = 1;
2253
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);
2259
2260 this->result_ = result;
2261 }
2262 }
2263
2264 /* Build a this variable expression. */
2265
2266 void visit (ThisExp *e)
2267 {
2268 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2269 tree result = NULL_TREE;
2270
2271 if (e->var)
2272 result = get_decl_tree (e->var);
2273 else
2274 {
2275 gcc_assert (fd && fd->vthis);
2276 result = get_decl_tree (fd->vthis);
2277 }
2278
2279 if (e->type->ty == Tstruct)
2280 result = build_deref (result);
2281
2282 this->result_ = result;
2283 }
2284
2285 /* Build a new expression, which allocates memory either on the garbage
2286 collected heap or by using a class or struct specific allocator. */
2287
2288 void visit (NewExp *e)
2289 {
2290 Type *tb = e->type->toBasetype ();
2291 tree result;
2292
2293 if (e->allocator)
2294 gcc_assert (e->newargs);
2295
2296 if (tb->ty == Tclass)
2297 {
2298 /* Allocating a new class. */
2299 tb = e->newtype->toBasetype ();
2300 gcc_assert (tb->ty == Tclass);
2301
2302 ClassDeclaration *cd = ((TypeClass *) tb)->sym;
2303 tree type = build_ctype (tb);
2304 tree setup_exp = NULL_TREE;
2305 tree new_call;
2306
2307 if (e->onstack)
2308 {
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));
2315 }
2316 else if (e->allocator)
2317 {
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));
2324 }
2325 else
2326 {
2327 /* Generate: _d_newclass() */
2328 tree arg = build_address (get_classinfo_decl (cd));
2329 new_call = build_libcall (LIBCALL_NEWCLASS, tb, 1, arg);
2330 }
2331
2332 /* Set the context pointer for nested classes. */
2333 if (cd->isNested ())
2334 {
2335 tree field = get_symbol_decl (cd->vthis);
2336 tree value = NULL_TREE;
2337
2338 if (e->thisexp)
2339 {
2340 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2341 Dsymbol *outer = cd->toParent2 ();
2342 int offset = 0;
2343
2344 value = build_expr (e->thisexp);
2345 if (outer != tcd)
2346 {
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);
2351 }
2352 }
2353 else
2354 value = build_vthis (cd);
2355
2356 if (value != NULL_TREE)
2357 {
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));
2363 }
2364 }
2365 new_call = compound_expr (setup_exp, new_call);
2366
2367 /* Call the class constructor. */
2368 if (e->member)
2369 result = d_build_call_expr (e->member, new_call, e->arguments);
2370 else
2371 result = new_call;
2372
2373 if (e->argprefix)
2374 result = compound_expr (build_expr (e->argprefix), result);
2375 }
2376 else if (tb->ty == Tpointer && tb->nextOf ()->toBasetype ()->ty == Tstruct)
2377 {
2378 /* Allocating memory for a new struct. */
2379 Type *htype = e->newtype->toBasetype ();
2380 gcc_assert (htype->ty == Tstruct);
2381 gcc_assert (!e->onstack);
2382
2383 TypeStruct *stype = (TypeStruct *) htype;
2384 StructDeclaration *sd = stype->sym;
2385 tree new_call;
2386
2387 /* Cannot new an opaque struct. */
2388 if (sd->size (e->loc) == 0)
2389 {
2390 this->result_ = d_convert (build_ctype (e->type),
2391 integer_zero_node);
2392 return;
2393 }
2394
2395 if (e->allocator)
2396 {
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);
2400 }
2401 else
2402 {
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);
2408 }
2409
2410 if (e->member || !e->arguments)
2411 {
2412 /* Set the context pointer for nested structs. */
2413 if (sd->isNested ())
2414 {
2415 tree value = build_vthis (sd);
2416 tree field = get_symbol_decl (sd->vthis);
2417 tree type = build_ctype (stype);
2418
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);
2422 }
2423
2424 /* Call the struct constructor. */
2425 if (e->member)
2426 result = d_build_call_expr (e->member, new_call, e->arguments);
2427 else
2428 result = new_call;
2429 }
2430 else
2431 {
2432 /* If we have a user supplied initializer, then set-up with a
2433 struct literal. */
2434 if (e->arguments != NULL && sd->fields.dim != 0)
2435 {
2436 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2437 e->arguments,
2438 htype);
2439 new_call = d_save_expr (new_call);
2440 se->type = sd->type;
2441 se->sym = new_call;
2442 result = compound_expr (build_expr (se), new_call);
2443 }
2444 else
2445 result = new_call;
2446 }
2447
2448 if (e->argprefix)
2449 result = compound_expr (build_expr (e->argprefix), result);
2450 }
2451 else if (tb->ty == Tarray)
2452 {
2453 /* Allocating memory for a new D array. */
2454 tb = e->newtype->toBasetype ();
2455 gcc_assert (tb->ty == Tarray);
2456 TypeDArray *tarray = (TypeDArray *) tb;
2457
2458 gcc_assert (!e->allocator);
2459 gcc_assert (e->arguments && e->arguments->dim >= 1);
2460
2461 if (e->arguments->dim == 1)
2462 {
2463 /* Single dimension array allocations. */
2464 Expression *arg = (*e->arguments)[0];
2465
2466 if (tarray->next->size () == 0)
2467 {
2468 /* Array element size is unknown. */
2469 this->result_ = d_array_value (build_ctype (e->type),
2470 size_int (0), null_pointer_node);
2471 return;
2472 }
2473
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),
2478 build_expr (arg));
2479 }
2480 else
2481 {
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);
2488
2489 for (size_t i = 0; i < e->arguments->dim; i++)
2490 {
2491 Expression *arg = (*e->arguments)[i];
2492 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2493
2494 gcc_assert (telem->ty == Tarray);
2495 telem = telem->toBasetype ()->nextOf ();
2496 gcc_assert (telem);
2497 }
2498
2499 CONSTRUCTOR_ELTS (init) = elms;
2500 DECL_INITIAL (var) = init;
2501
2502 /* Generate: _d_newarraymTX(ti, dims)
2503 or: _d_newarraymiTX(ti, dims) */
2504 libcall_fn libcall = telem->isZeroInit ()
2505 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2506
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));
2511
2512 result = build_libcall (libcall, tb, 2, tinfo, dims);
2513 result = bind_expr (var, result);
2514 }
2515
2516 if (e->argprefix)
2517 result = compound_expr (build_expr (e->argprefix), result);
2518 }
2519 else if (tb->ty == Tpointer)
2520 {
2521 /* Allocating memory for a new pointer. */
2522 TypePointer *tpointer = (TypePointer *) tb;
2523
2524 if (tpointer->next->size () == 0)
2525 {
2526 /* Pointer element size is unknown. */
2527 this->result_ = d_convert (build_ctype (e->type),
2528 integer_zero_node);
2529 return;
2530 }
2531
2532 libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
2533 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2534
2535 tree arg = build_typeinfo (e->loc, e->newtype);
2536 result = build_libcall (libcall, tb, 1, arg);
2537
2538 if (e->arguments && e->arguments->dim == 1)
2539 {
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);
2544 }
2545
2546 if (e->argprefix)
2547 result = compound_expr (build_expr (e->argprefix), result);
2548 }
2549 else
2550 gcc_unreachable ();
2551
2552 this->result_ = convert_expr (result, tb, e->type);
2553 }
2554
2555 /* Build an integer literal. */
2556
2557 void visit (IntegerExp *e)
2558 {
2559 tree ctype = build_ctype (e->type->toBasetype ());
2560 this->result_ = build_integer_cst (e->value, ctype);
2561 }
2562
2563 /* Build a floating-point literal. */
2564
2565 void visit (RealExp *e)
2566 {
2567 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2568 }
2569
2570 /* Build a complex literal. */
2571
2572 void visit (ComplexExp *e)
2573 {
2574 Type *tnext;
2575
2576 switch (e->type->toBasetype ()->ty)
2577 {
2578 case Tcomplex32:
2579 tnext = (TypeBasic *) Type::tfloat32;
2580 break;
2581
2582 case Tcomplex64:
2583 tnext = (TypeBasic *) Type::tfloat64;
2584 break;
2585
2586 case Tcomplex80:
2587 tnext = (TypeBasic *) Type::tfloat80;
2588 break;
2589
2590 default:
2591 gcc_unreachable ();
2592 }
2593
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));
2597 }
2598
2599 /* Build a string literal, all strings are null terminated except for
2600 static arrays. */
2601
2602 void visit (StringExp *e)
2603 {
2604 Type *tb = e->type->toBasetype ();
2605 tree type = build_ctype (e->type);
2606
2607 if (tb->ty == Tsarray)
2608 {
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);
2613
2614 for (size_t i = 0; i < e->len; i++)
2615 {
2616 tree value = build_integer_cst (e->charAt (i), etype);
2617 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2618 }
2619
2620 tree ctor = build_constructor (type, elms);
2621 TREE_CONSTANT (ctor) = 1;
2622 this->result_ = ctor;
2623 }
2624 else
2625 {
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';
2631
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);
2636
2637 if (tb->ty == Tarray)
2638 value = d_array_value (type, size_int (e->len), value);
2639
2640 TREE_CONSTANT (value) = 1;
2641 this->result_ = d_convert (type, value);
2642 }
2643 }
2644
2645 /* Build a tuple literal. Just an argument list that may have
2646 side effects that need evaluation. */
2647
2648 void visit (TupleExp *e)
2649 {
2650 tree result = NULL_TREE;
2651
2652 if (e->e0)
2653 result = build_expr (e->e0);
2654
2655 for (size_t i = 0; i < e->exps->dim; ++i)
2656 {
2657 Expression *exp = (*e->exps)[i];
2658 result = compound_expr (result, build_expr (exp));
2659 }
2660
2661 if (result == NULL_TREE)
2662 result = void_node;
2663
2664 this->result_ = result;
2665 }
2666
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. */
2670
2671 void visit (ArrayLiteralExp *e)
2672 {
2673 Type *tb = e->type->toBasetype ();
2674
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 ());
2678
2679 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tpointer);
2680
2681 /* Handle empty array literals. */
2682 if (e->elements->dim == 0)
2683 {
2684 if (tb->ty == Tarray)
2685 this->result_ = d_array_value (build_ctype (e->type),
2686 size_int (0), null_pointer_node);
2687 else
2688 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2689 NULL);
2690
2691 return;
2692 }
2693
2694 /* Build an expression that assigns the expressions in ELEMENTS to
2695 a constructor. */
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;
2700
2701 Type *etype = tb->nextOf ();
2702 tree satype = make_array_type (etype, e->elements->dim);
2703
2704 for (size_t i = 0; i < e->elements->dim; i++)
2705 {
2706 Expression *expr = e->getElement (i);
2707 tree value = build_expr (expr, this->constp_);
2708
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))
2712 {
2713 if (!TREE_CONSTANT (value))
2714 constant_p = false;
2715
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);
2721
2722 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2723 convert_expr (value, expr->type, etype));
2724 }
2725 }
2726
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);
2732
2733 /* Nothing else to do for static arrays. */
2734 if (tb->ty == Tsarray || this->constp_)
2735 {
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)
2739 {
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);
2744
2745 d_pushdecl (decl);
2746 rest_of_decl_compilation (decl, 1, 0);
2747 }
2748
2749 /* If the array literal is readonly or static. */
2750 if (constant_p)
2751 TREE_CONSTANT (ctor) = 1;
2752 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2753 TREE_STATIC (ctor) = 1;
2754
2755 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2756 }
2757 else
2758 {
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);
2765
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 ()));
2770
2771 tree result = build_call_expr (tmemcpy, 3, mem,
2772 build_address (ctor), size);
2773
2774 /* Return the array pointed to by MEM. */
2775 result = compound_expr (result, mem);
2776
2777 if (tb->ty == Tarray)
2778 result = d_array_value (type, size_int (e->elements->dim), result);
2779
2780 this->result_ = compound_expr (saved_elems, result);
2781 }
2782 }
2783
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. */
2787
2788 void visit (AssocArrayLiteralExp *e)
2789 {
2790 /* Want the mutable type for typeinfo reference. */
2791 Type *tb = e->type->toBasetype ()->mutableOf ();
2792 gcc_assert (tb->ty == Taarray);
2793
2794 /* Handle empty assoc array literals. */
2795 TypeAArray *ta = (TypeAArray *) tb;
2796 if (e->keys->dim == 0)
2797 {
2798 this->result_ = build_constructor (build_ctype (ta), NULL);
2799 return;
2800 }
2801
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++)
2807 {
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));
2812 }
2813 tree tkeys = make_array_type (ta->index, e->keys->dim);
2814 tree akeys = build_constructor (tkeys, kelts);
2815
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++)
2820 {
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));
2825 }
2826 tree tvals = make_array_type (ta->next, e->values->dim);
2827 tree avals = build_constructor (tvals, velts);
2828
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));
2835
2836 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2837 build_typeinfo (e->loc, ta), keys, vals);
2838
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);
2843
2844 this->result_ = build_nop (build_ctype (e->type),
2845 build_constructor (aatype, ce));
2846 }
2847
2848 /* Build a struct literal. */
2849
2850 void visit (StructLiteralExp *e)
2851 {
2852 /* Handle empty struct literals. */
2853 if (e->elements == NULL || e->sd->fields.dim == 0)
2854 {
2855 this->result_ = build_constructor (build_ctype (e->type), NULL);
2856 return;
2857 }
2858
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_)
2862 {
2863 this->result_ = aggregate_initializer_decl (e->sd);
2864 return;
2865 }
2866
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;
2871
2872 /* CTFE may fill the hidden pointer by NullExp. */
2873 gcc_assert (e->elements->dim <= e->sd->fields.dim);
2874
2875 Type *tb = e->type->toBasetype ();
2876 gcc_assert (tb->ty == Tstruct);
2877
2878 for (size_t i = 0; i < e->elements->dim; i++)
2879 {
2880 Expression *exp = (*e->elements)[i];
2881 if (!exp)
2882 continue;
2883
2884 VarDeclaration *field = e->sd->fields[i];
2885 Type *type = exp->type->toBasetype ();
2886 Type *ftype = field->type->toBasetype ();
2887 tree value = NULL_TREE;
2888
2889 if (ftype->ty == Tsarray && !same_type_p (type, ftype))
2890 {
2891 /* Initialize a static array with a single element. */
2892 tree elem = build_expr (exp, this->constp_);
2893 elem = d_save_expr (elem);
2894
2895 if (initializer_zerop (elem))
2896 value = build_constructor (build_ctype (ftype), NULL);
2897 else
2898 value = build_array_from_val (ftype, elem);
2899 }
2900 else
2901 {
2902 value = convert_expr (build_expr (exp, this->constp_),
2903 exp->type, field->type);
2904 }
2905
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);
2910
2911 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2912 }
2913
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)
2917 {
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);
2922 }
2923
2924 /* Build a constructor in the correct shape of the aggregate type. */
2925 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2926
2927 /* Nothing more to do for constant literals. */
2928 if (this->constp_)
2929 {
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;
2934
2935 this->result_ = compound_expr (saved_elems, ctor);
2936 return;
2937 }
2938
2939 if (e->sym != NULL)
2940 {
2941 tree var = build_deref (e->sym);
2942 ctor = compound_expr (modify_expr (var, ctor), var);
2943 this->result_ = compound_expr (saved_elems, ctor);
2944 }
2945 else if (e->sd->isUnionDeclaration ())
2946 {
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),
2951 size_zero_node,
2952 size_int (e->sd->structsize));
2953
2954 init = compound_expr (init, saved_elems);
2955 init = compound_expr (init, modify_expr (var, ctor));
2956 this->result_ = compound_expr (init, var);
2957 }
2958 else
2959 this->result_ = compound_expr (saved_elems, ctor);
2960 }
2961
2962 /* Build a null literal. */
2963
2964 void visit (NullExp *e)
2965 {
2966 this->result_ = build_typeof_null_value (e->type);
2967 }
2968
2969 /* Build a vector literal. */
2970
2971 void visit (VectorExp *e)
2972 {
2973 tree type = build_ctype (e->type);
2974 tree etype = TREE_TYPE (type);
2975
2976 /* First handle array literal expressions. */
2977 if (e->e1->op == TOKarrayliteral)
2978 {
2979 ArrayLiteralExp *ale = ((ArrayLiteralExp *) e->e1);
2980 vec<constructor_elt, va_gc> *elms = NULL;
2981 bool constant_p = true;
2982
2983 vec_safe_reserve (elms, ale->elements->dim);
2984 for (size_t i = 0; i < ale->elements->dim; i++)
2985 {
2986 Expression *expr = ale->getElement (i);
2987 tree value = d_convert (etype, build_expr (expr, this->constp_));
2988 if (!CONSTANT_CLASS_P (value))
2989 constant_p = false;
2990
2991 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2992 }
2993
2994 /* Build a VECTOR_CST from a constant vector constructor. */
2995 if (constant_p)
2996 this->result_ = build_vector_from_ctor (type, elms);
2997 else
2998 this->result_ = build_constructor (type, elms);
2999 }
3000 else
3001 {
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);
3005 }
3006 }
3007
3008 /* Build a static array representation of a vector expression. */
3009
3010 void visit (VectorArrayExp *e)
3011 {
3012 this->result_ = convert_expr (build_expr (e->e1, this->constp_),
3013 e->e1->type, e->type);
3014 }
3015
3016 /* Build a static class literal, return its reference. */
3017
3018 void visit (ClassReferenceExp *e)
3019 {
3020 /* The result of build_new_class_expr is a RECORD_TYPE, we want
3021 the reference. */
3022 tree var = build_address (build_new_class_expr (e));
3023
3024 /* If the type of this literal is an interface, the we must add the
3025 interface offset to symbol. */
3026 if (this->constp_)
3027 {
3028 TypeClass *tc = (TypeClass *) e->type;
3029 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
3030
3031 if (to != NULL)
3032 {
3033 ClassDeclaration *from = e->originalClass ();
3034 int offset = 0;
3035
3036 gcc_assert (to->isBaseOf (from, &offset) != 0);
3037
3038 if (offset != 0)
3039 var = build_offset (var, size_int (offset));
3040 }
3041 }
3042
3043 this->result_ = var;
3044 }
3045
3046 /* These expressions are mainly just a placeholders in the frontend.
3047 We shouldn't see them here. */
3048
3049 void visit (ScopeExp *e)
3050 {
3051 error_at (make_location_t (e->loc), "%qs is not an expression",
3052 e->toChars ());
3053 this->result_ = error_mark_node;
3054 }
3055
3056 void visit (TypeExp *e)
3057 {
3058 error_at (make_location_t (e->loc), "type %qs is not an expression",
3059 e->toChars ());
3060 this->result_ = error_mark_node;
3061 }
3062 };
3063
3064
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. */
3068
3069 tree
3070 build_expr (Expression *e, bool const_p)
3071 {
3072 ExprVisitor v = ExprVisitor (const_p);
3073 location_t saved_location = input_location;
3074
3075 input_location = make_location_t (e->loc);
3076 e->accept (&v);
3077 tree expr = v.result ();
3078 input_location = saved_location;
3079
3080 /* Check if initializer expression is valid constant. */
3081 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3082 {
3083 error_at (make_location_t (e->loc), "non-constant expression %qs",
3084 e->toChars ());
3085 return error_mark_node;
3086 }
3087
3088 return expr;
3089 }
3090
3091 /* Same as build_expr, but also calls destructors on any temporaries. */
3092
3093 tree
3094 build_expr_dtor (Expression *e)
3095 {
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);
3100
3101 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3102 {
3103 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3104 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3105 }
3106
3107 return result;
3108 }
3109
3110 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3111
3112 tree
3113 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3114 {
3115 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3116 tree result = build_expr (e);
3117
3118 /* Convert for initializing the DECL_RESULT. */
3119 result = convert_expr (result, e->type, type);
3120
3121 /* If we are returning a reference, take the address. */
3122 if (tf->isref)
3123 result = build_address (result);
3124
3125 /* The decl to store the return expression. */
3126 tree decl = DECL_RESULT (cfun->decl);
3127
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));
3132
3133 /* May nest the return expression inside the try/finally expression. */
3134 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3135 {
3136 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3137 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3138 }
3139
3140 return result;
3141 }
3142