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
needs_postblit(Type * t)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
needs_dtor(Type * t)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
lvalue_p(Expression * e)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
binary_op(tree_code code,tree type,tree arg0,tree arg1)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 = 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
binop_assignment(tree_code code,Expression * e1,Expression * e2)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:
ExprVisitor(bool constp)219 ExprVisitor (bool constp)
220 {
221 this->result_ = NULL_TREE;
222 this->constp_ = constp;
223 }
224
result(void)225 tree result (void)
226 {
227 return this->result_;
228 }
229
230 /* Visitor interfaces, each Expression class should have
231 overridden the default. */
232
visit(Expression *)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
visit(CondExp * e)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
visit(IdentityExp * e)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
visit(EqualExp * e)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
visit(InExp * e)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
visit(CmpExp * e)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
visit(AndAndExp * e)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
visit(OrOrExp * e)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
visit(BinExp * e)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
visit(CatExp * e)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 tree result;
695
696 if (e->e1->op == TOKcat)
697 {
698 /* Flatten multiple concatenations to an array.
699 So the expression ((a ~ b) ~ c) becomes [a, b, c] */
700 int ndims = 2;
701
702 for (Expression *ex = e->e1; ex->op == TOKcat;)
703 {
704 if (ex->op == TOKcat)
705 {
706 ex = ((CatExp *) ex)->e1;
707 ndims++;
708 }
709 }
710
711 /* Store all concatenation args to a temporary byte[][ndims] array. */
712 Type *targselem = Type::tint8->arrayOf ();
713 tree var = build_local_temp (make_array_type (targselem, ndims));
714
715 /* Loop through each concatenation from right to left. */
716 vec<constructor_elt, va_gc> *elms = NULL;
717 CatExp *ce = e;
718 int dim = ndims - 1;
719
720 for (Expression *oe = ce->e2; oe != NULL;
721 (ce->e1->op != TOKcat
722 ? (oe = ce->e1)
723 : (ce = (CatExp *)ce->e1, oe = ce->e2)))
724 {
725 tree arg = d_array_convert (etype, oe);
726 tree index = size_int (dim);
727 CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));
728
729 /* Finished pushing all arrays. */
730 if (oe == ce->e1)
731 break;
732
733 dim -= 1;
734 }
735
736 /* Check there is no logic bug in constructing byte[][] of arrays. */
737 gcc_assert (dim == 0);
738 tree init = build_constructor (TREE_TYPE (var), elms);
739 var = compound_expr (modify_expr (var, init), var);
740
741 tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
742 size_int (ndims), build_address (var));
743
744 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
745 build_typeinfo (e->loc, e->type), arrs);
746 }
747 else
748 {
749 /* Handle single concatenation (a ~ b). */
750 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
751 build_typeinfo (e->loc, e->type),
752 d_array_convert (etype, e->e1),
753 d_array_convert (etype, e->e2));
754 }
755
756 this->result_ = result;
757 }
758
759 /* Build an assignment operator expression. The right operand is implicitly
760 converted to the type of the left operand, and assigned to it. */
761
visit(BinAssignExp * e)762 void visit (BinAssignExp *e)
763 {
764 tree_code code;
765 Expression *e1b = e->e1;
766
767 switch (e->op)
768 {
769 case TOKaddass:
770 code = PLUS_EXPR;
771 break;
772
773 case TOKminass:
774 code = MINUS_EXPR;
775 break;
776
777 case TOKmulass:
778 code = MULT_EXPR;
779 break;
780
781 case TOKdivass:
782 code = e->e1->type->isintegral ()
783 ? TRUNC_DIV_EXPR : RDIV_EXPR;
784 break;
785
786 case TOKmodass:
787 code = e->e1->type->isfloating ()
788 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
789 break;
790
791 case TOKandass:
792 code = BIT_AND_EXPR;
793 break;
794
795 case TOKorass:
796 code = BIT_IOR_EXPR;
797 break;
798
799 case TOKxorass:
800 code = BIT_XOR_EXPR;
801 break;
802
803 case TOKpowass:
804 gcc_unreachable ();
805
806 case TOKshlass:
807 code = LSHIFT_EXPR;
808 break;
809
810 case TOKshrass:
811 case TOKushrass:
812 /* Use the original lhs type before it was promoted. The left operand
813 of `>>>=' does not undergo integral promotions before shifting.
814 Strip off casts just incase anyway. */
815 while (e1b->op == TOKcast)
816 {
817 CastExp *ce = (CastExp *) e1b;
818 gcc_assert (same_type_p (ce->type, ce->to));
819 e1b = ce->e1;
820 }
821 code = (e->op == TOKshrass) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
822 break;
823
824 default:
825 gcc_unreachable ();
826 }
827
828 tree exp = this->binop_assignment (code, e1b, e->e2);
829 this->result_ = convert_expr (exp, e1b->type, e->type);
830 }
831
832 /* Build a concat assignment expression. The right operand is appended
833 to the left operand. */
834
visit(CatAssignExp * e)835 void visit (CatAssignExp *e)
836 {
837 Type *tb1 = e->e1->type->toBasetype ();
838 Type *tb2 = e->e2->type->toBasetype ();
839 Type *etype = tb1->nextOf ()->toBasetype ();
840
841 /* Save the address of `e1', so it can be evaluated first.
842 As all D run-time library functions for concat assignments update `e1'
843 in-place and then return its value, the saved address can also be used as
844 the result of this expression as well. */
845 tree lhs = build_expr (e->e1);
846 tree lexpr = stabilize_expr (&lhs);
847 tree ptr = d_save_expr (build_address (lhs));
848 tree result = NULL_TREE;
849
850 if (tb1->ty == Tarray && tb2->ty == Tdchar
851 && (etype->ty == Tchar || etype->ty == Twchar))
852 {
853 /* Append a dchar to a char[] or wchar[]:
854 The assignment is handled by the D run-time library, so only
855 need to call `_d_arrayappend[cw]d(&e1, e2)' */
856 libcall_fn libcall = (etype->ty == Tchar)
857 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
858
859 result = build_libcall (libcall, e->type, 2,
860 ptr, build_expr (e->e2));
861 }
862 else
863 {
864 gcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray);
865
866 if ((tb2->ty == Tarray || tb2->ty == Tsarray)
867 && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
868 {
869 /* Append an array to another array:
870 The assignment is handled by the D run-time library, so only
871 need to call `_d_arrayappendT(ti, &e1, e2)' */
872 result = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
873 build_typeinfo (e->loc, e->type),
874 ptr, d_array_convert (e->e2));
875 }
876 else if (same_type_p (etype, tb2))
877 {
878 /* Append an element to an array:
879 The assignment is generated inline, so need to handle temporaries
880 here, and ensure that they are evaluated in the correct order.
881
882 The generated code should end up being equivalent to:
883 _d_arrayappendcTX(ti, &e1, 1)[e1.length - 1] = e2
884 */
885 tree callexp = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
886 build_typeinfo (e->loc, e->type),
887 ptr, size_one_node);
888 callexp = d_save_expr (callexp);
889
890 /* Assign e2 to last element. */
891 tree offexp = d_array_length (callexp);
892 offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
893 offexp, size_one_node);
894
895 tree ptrexp = d_array_ptr (callexp);
896 ptrexp = void_okay_p (ptrexp);
897 ptrexp = build_array_index (ptrexp, offexp);
898
899 /* Evaluate expression before appending. */
900 tree rhs = build_expr (e->e2);
901 tree rexpr = stabilize_expr (&rhs);
902
903 if (TREE_CODE (rhs) == CALL_EXPR)
904 rhs = force_target_expr (rhs);
905
906 result = modify_expr (build_deref (ptrexp), rhs);
907 result = compound_expr (rexpr, result);
908 }
909 else
910 gcc_unreachable ();
911 }
912
913 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
914 result = compound_expr (compound_expr (lexpr, ptr), result);
915 this->result_ = compound_expr (result, build_deref (ptr));
916 }
917
918 /* Build an assignment expression. The right operand is implicitly
919 converted to the type of the left operand, and assigned to it. */
920
visit(AssignExp * e)921 void visit (AssignExp *e)
922 {
923 /* First, handle special assignment semantics. */
924
925 /* Look for array.length = n; */
926 if (e->e1->op == TOKarraylength)
927 {
928 /* Assignment to an array's length property; resize the array. */
929 ArrayLengthExp *ale = (ArrayLengthExp *) e->e1;
930 tree newlength = convert_expr (build_expr (e->e2), e->e2->type,
931 Type::tsize_t);
932 tree ptr = build_address (build_expr (ale->e1));
933
934 /* Don't want the basetype for the element type. */
935 Type *etype = ale->e1->type->toBasetype ()->nextOf ();
936 libcall_fn libcall = etype->isZeroInit ()
937 ? LIBCALL_ARRAYSETLENGTHT : LIBCALL_ARRAYSETLENGTHIT;
938
939 tree result = build_libcall (libcall, ale->e1->type, 3,
940 build_typeinfo (ale->loc, ale->e1->type),
941 newlength, ptr);
942
943 this->result_ = d_array_length (result);
944 return;
945 }
946
947 /* Look for array[] = n; */
948 if (e->e1->op == TOKslice)
949 {
950 SliceExp *se = (SliceExp *) e->e1;
951 Type *stype = se->e1->type->toBasetype ();
952 Type *etype = stype->nextOf ()->toBasetype ();
953
954 /* Determine if we need to run postblit or dtor. */
955 bool postblit = this->needs_postblit (etype) && this->lvalue_p (e->e2);
956 bool destructor = this->needs_dtor (etype);
957
958 if (e->memset & blockAssign)
959 {
960 /* Set a range of elements to one value. */
961 tree t1 = d_save_expr (build_expr (e->e1));
962 tree t2 = build_expr (e->e2);
963 tree result;
964
965 if ((postblit || destructor) && e->op != TOKblit)
966 {
967 libcall_fn libcall = (e->op == TOKconstruct)
968 ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN;
969 /* So we can call postblits on const/immutable objects. */
970 Type *tm = etype->unSharedOf ()->mutableOf ();
971 tree ti = build_typeinfo (e->loc, tm);
972
973 tree result = build_libcall (libcall, Type::tvoid, 4,
974 d_array_ptr (t1),
975 build_address (t2),
976 d_array_length (t1), ti);
977 this->result_ = compound_expr (result, t1);
978 return;
979 }
980
981 if (integer_zerop (t2))
982 {
983 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
984 tree size = size_mult_expr (d_array_length (t1),
985 size_int (etype->size ()));
986
987 result = build_call_expr (tmemset, 3, d_array_ptr (t1),
988 integer_zero_node, size);
989 }
990 else
991 result = build_array_set (d_array_ptr (t1),
992 d_array_length (t1), t2);
993
994 this->result_ = compound_expr (result, t1);
995 }
996 else
997 {
998 /* Perform a memcpy operation. */
999 gcc_assert (e->e2->type->ty != Tpointer);
1000
1001 if (!postblit && !destructor && !array_bounds_check ())
1002 {
1003 tree t1 = d_save_expr (d_array_convert (e->e1));
1004 tree t2 = d_array_convert (e->e2);
1005 tree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);
1006 tree size = size_mult_expr (d_array_length (t1),
1007 size_int (etype->size ()));
1008
1009 tree result = build_call_expr (tmemcpy, 3, d_array_ptr (t1),
1010 d_array_ptr (t2), size);
1011 this->result_ = compound_expr (result, t1);
1012 }
1013 else if ((postblit || destructor) && e->op != TOKblit)
1014 {
1015 /* Generate: _d_arrayassign(ti, from, to)
1016 or: _d_arrayctor(ti, from, to) */
1017 libcall_fn libcall = (e->op == TOKconstruct)
1018 ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN;
1019
1020 this->result_ = build_libcall (libcall, e->type, 3,
1021 build_typeinfo (e->loc, etype),
1022 d_array_convert (e->e2),
1023 d_array_convert (e->e1));
1024 }
1025 else
1026 {
1027 /* Generate: _d_arraycopy() */
1028 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
1029 size_int (etype->size ()),
1030 d_array_convert (e->e2),
1031 d_array_convert (e->e1));
1032 }
1033 }
1034
1035 return;
1036 }
1037
1038 /* Look for reference initializations. */
1039 if (e->memset & referenceInit)
1040 {
1041 gcc_assert (e->op == TOKconstruct || e->op == TOKblit);
1042 gcc_assert (e->e1->op == TOKvar);
1043
1044 Declaration *decl = ((VarExp *) e->e1)->var;
1045 if (decl->storage_class & (STCout | STCref))
1046 {
1047 tree t2 = convert_for_assignment (build_expr (e->e2),
1048 e->e2->type, e->e1->type);
1049 tree t1 = build_expr (e->e1);
1050 /* Want reference to lhs, not indirect ref. */
1051 t1 = TREE_OPERAND (t1, 0);
1052 t2 = build_address (t2);
1053
1054 this->result_ = indirect_ref (build_ctype (e->type),
1055 build_assign (INIT_EXPR, t1, t2));
1056 return;
1057 }
1058 }
1059
1060 /* Other types of assignments that may require post construction. */
1061 Type *tb1 = e->e1->type->toBasetype ();
1062 tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR;
1063
1064 /* Look for struct assignment. */
1065 if (tb1->ty == Tstruct)
1066 {
1067 tree t1 = build_expr (e->e1);
1068 tree t2 = convert_for_assignment (build_expr (e->e2),
1069 e->e2->type, e->e1->type);
1070 StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
1071
1072 /* Look for struct = 0. */
1073 if (e->e2->op == TOKint64)
1074 {
1075 /* Use memset to fill struct. */
1076 gcc_assert (e->op == TOKblit);
1077 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1078 tree result = build_call_expr (tmemset, 3, build_address (t1),
1079 t2, size_int (sd->structsize));
1080
1081 /* Maybe set-up hidden pointer to outer scope context. */
1082 if (sd->isNested ())
1083 {
1084 tree field = get_symbol_decl (sd->vthis);
1085 tree value = build_vthis (sd);
1086
1087 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1088 result = compound_expr (result, vthis_exp);
1089 }
1090
1091 this->result_ = compound_expr (result, t1);
1092 }
1093 else
1094 {
1095 /* Simple struct literal assignment. */
1096 tree init = NULL_TREE;
1097
1098 /* Fill any alignment holes in the struct using memset. */
1099 if (e->op == TOKconstruct && !identity_compare_p (sd))
1100 {
1101 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1102 init = build_call_expr (tmemset, 3, build_address (t1),
1103 integer_zero_node,
1104 size_int (sd->structsize));
1105 }
1106
1107 tree result = build_assign (modifycode, t1, t2);
1108 this->result_ = compound_expr (init, result);
1109 }
1110
1111 return;
1112 }
1113
1114 /* Look for static array assignment. */
1115 if (tb1->ty == Tsarray)
1116 {
1117 /* Look for array = 0. */
1118 if (e->e2->op == TOKint64)
1119 {
1120 /* Use memset to fill the array. */
1121 gcc_assert (e->op == TOKblit);
1122
1123 tree t1 = build_expr (e->e1);
1124 tree t2 = convert_for_assignment (build_expr (e->e2),
1125 e->e2->type, e->e1->type);
1126 tree size = size_int (e->e1->type->size ());
1127
1128 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1129 this->result_ = build_call_expr (tmemset, 3, build_address (t1),
1130 t2, size);
1131 return;
1132 }
1133
1134 Type *etype = tb1->nextOf ();
1135 gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);
1136
1137 /* Determine if we need to run postblit. */
1138 bool postblit = this->needs_postblit (etype);
1139 bool destructor = this->needs_dtor (etype);
1140 bool lvalue_p = this->lvalue_p (e->e2);
1141
1142 /* Even if the elements in rhs are all rvalues and don't have
1143 to call postblits, this assignment should call dtors on old
1144 assigned elements. */
1145 if ((!postblit && !destructor)
1146 || (e->op == TOKconstruct && !lvalue_p && postblit)
1147 || (e->op == TOKblit || e->e1->type->size () == 0))
1148 {
1149 tree t1 = build_expr (e->e1);
1150 tree t2 = convert_for_assignment (build_expr (e->e2),
1151 e->e2->type, e->e1->type);
1152
1153 this->result_ = build_assign (modifycode, t1, t2);
1154 return;
1155 }
1156
1157 Type *arrtype = (e->type->ty == Tsarray) ? etype->arrayOf () : e->type;
1158 tree result;
1159
1160 if (e->op == TOKconstruct)
1161 {
1162 /* Generate: _d_arrayctor(ti, from, to) */
1163 result = build_libcall (LIBCALL_ARRAYCTOR, arrtype, 3,
1164 build_typeinfo (e->loc, etype),
1165 d_array_convert (e->e2),
1166 d_array_convert (e->e1));
1167 }
1168 else
1169 {
1170 /* Generate: _d_arrayassign_l()
1171 or: _d_arrayassign_r() */
1172 libcall_fn libcall = (lvalue_p)
1173 ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
1174 tree elembuf = build_local_temp (build_ctype (etype));
1175
1176 result = build_libcall (libcall, arrtype, 4,
1177 build_typeinfo (e->loc, etype),
1178 d_array_convert (e->e2),
1179 d_array_convert (e->e1),
1180 build_address (elembuf));
1181 }
1182
1183 /* Cast the libcall result back to a static array. */
1184 if (e->type->ty == Tsarray)
1185 result = indirect_ref (build_ctype (e->type),
1186 d_array_ptr (result));
1187
1188 this->result_ = result;
1189 return;
1190 }
1191
1192 /* Simple assignment. */
1193 tree t1 = build_expr (e->e1);
1194 tree t2 = convert_for_assignment (build_expr (e->e2),
1195 e->e2->type, e->e1->type);
1196
1197 this->result_ = build_assign (modifycode, t1, t2);
1198 }
1199
1200 /* Build a postfix expression. */
1201
visit(PostExp * e)1202 void visit (PostExp *e)
1203 {
1204 tree result;
1205
1206 if (e->op == TOKplusplus)
1207 {
1208 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1209 build_expr (e->e1), build_expr (e->e2));
1210 }
1211 else if (e->op == TOKminusminus)
1212 {
1213 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1214 build_expr (e->e1), build_expr (e->e2));
1215 }
1216 else
1217 gcc_unreachable ();
1218
1219 TREE_SIDE_EFFECTS (result) = 1;
1220 this->result_ = result;
1221 }
1222
1223 /* Build an index expression. */
1224
visit(IndexExp * e)1225 void visit (IndexExp *e)
1226 {
1227 Type *tb1 = e->e1->type->toBasetype ();
1228
1229 if (tb1->ty == Taarray)
1230 {
1231 /* Get the key for the associative array. */
1232 Type *tkey = ((TypeAArray *) tb1)->index->toBasetype ();
1233 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1234 libcall_fn libcall;
1235 tree tinfo, ptr;
1236
1237 if (e->modifiable)
1238 {
1239 libcall = LIBCALL_AAGETY;
1240 ptr = build_address (build_expr (e->e1));
1241 tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());
1242 }
1243 else
1244 {
1245 libcall = LIBCALL_AAGETRVALUEX;
1246 ptr = build_expr (e->e1);
1247 tinfo = build_typeinfo (e->loc, tkey);
1248 }
1249
1250 /* Index the associative array. */
1251 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1252 ptr, tinfo,
1253 size_int (tb1->nextOf ()->size ()),
1254 build_address (key));
1255
1256 if (!e->indexIsInBounds && array_bounds_check ())
1257 {
1258 tree tassert = (global.params.checkAction == CHECKACTION_D)
1259 ? d_assert_call (e->loc, LIBCALL_ARRAY_BOUNDS)
1260 : build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1261
1262 result = d_save_expr (result);
1263 result = build_condition (TREE_TYPE (result),
1264 d_truthvalue_conversion (result),
1265 result, tassert);
1266 }
1267
1268 this->result_ = indirect_ref (build_ctype (e->type), result);
1269 }
1270 else
1271 {
1272 /* Get the data pointer and length for static and dynamic arrays. */
1273 tree array = d_save_expr (build_expr (e->e1));
1274 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1275
1276 tree length = NULL_TREE;
1277 if (tb1->ty != Tpointer)
1278 length = get_array_length (array, tb1);
1279 else
1280 gcc_assert (e->lengthVar == NULL);
1281
1282 /* The __dollar variable just becomes a placeholder for the
1283 actual length. */
1284 if (e->lengthVar)
1285 e->lengthVar->csym = length;
1286
1287 /* Generate the index. */
1288 tree index = build_expr (e->e2);
1289
1290 /* If it's a static array and the index is constant, the front end has
1291 already checked the bounds. */
1292 if (tb1->ty != Tpointer && !e->indexIsInBounds)
1293 index = build_bounds_condition (e->e2->loc, index, length, false);
1294
1295 /* Index the .ptr. */
1296 ptr = void_okay_p (ptr);
1297 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1298 build_array_index (ptr, index));
1299 }
1300 }
1301
1302 /* Build a comma expression. The type is the type of the right operand. */
1303
visit(CommaExp * e)1304 void visit (CommaExp *e)
1305 {
1306 tree t1 = build_expr (e->e1);
1307 tree t2 = build_expr (e->e2);
1308 tree type = e->type ? build_ctype (e->type) : void_type_node;
1309
1310 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1311 }
1312
1313 /* Build an array length expression. Returns the number of elements
1314 in the array. The result is of type size_t. */
1315
visit(ArrayLengthExp * e)1316 void visit (ArrayLengthExp *e)
1317 {
1318 if (e->e1->type->toBasetype ()->ty == Tarray)
1319 this->result_ = d_array_length (build_expr (e->e1));
1320 else
1321 {
1322 /* Static arrays have already been handled by the front-end. */
1323 error ("unexpected type for array length: %qs", e->type->toChars ());
1324 this->result_ = error_mark_node;
1325 }
1326 }
1327
1328 /* Build a delegate pointer expression. This will return the frame
1329 pointer value as a type void*. */
1330
visit(DelegatePtrExp * e)1331 void visit (DelegatePtrExp *e)
1332 {
1333 tree t1 = build_expr (e->e1);
1334 this->result_ = delegate_object (t1);
1335 }
1336
1337 /* Build a delegate function pointer expression. This will return the
1338 function pointer value as a function type. */
1339
visit(DelegateFuncptrExp * e)1340 void visit (DelegateFuncptrExp *e)
1341 {
1342 tree t1 = build_expr (e->e1);
1343 this->result_ = delegate_method (t1);
1344 }
1345
1346 /* Build a slice expression. */
1347
visit(SliceExp * e)1348 void visit (SliceExp *e)
1349 {
1350 Type *tb = e->type->toBasetype ();
1351 Type *tb1 = e->e1->type->toBasetype ();
1352 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray);
1353
1354 /* Use convert-to-dynamic-array code if possible. */
1355 if (!e->lwr)
1356 {
1357 tree result = build_expr (e->e1);
1358 if (e->e1->type->toBasetype ()->ty == Tsarray)
1359 result = convert_expr (result, e->e1->type, e->type);
1360
1361 this->result_ = result;
1362 return;
1363 }
1364 else
1365 gcc_assert (e->upr != NULL);
1366
1367 /* Get the data pointer and length for static and dynamic arrays. */
1368 tree array = d_save_expr (build_expr (e->e1));
1369 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1370 tree length = NULL_TREE;
1371
1372 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1373 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1374 if (tb1->ty != Tpointer)
1375 length = get_array_length (array, tb1);
1376 else
1377 gcc_assert (e->lengthVar == NULL);
1378
1379 /* The __dollar variable just becomes a placeholder for the
1380 actual length. */
1381 if (e->lengthVar)
1382 e->lengthVar->csym = length;
1383
1384 /* Generate upper and lower bounds. */
1385 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1386 tree upr_tree = d_save_expr (build_expr (e->upr));
1387
1388 /* If the upper bound has any side effects, then the lower bound should be
1389 copied to a temporary always. */
1390 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1391 lwr_tree = save_expr (lwr_tree);
1392
1393 /* Adjust the .ptr offset. */
1394 if (!integer_zerop (lwr_tree))
1395 {
1396 tree ptrtype = TREE_TYPE (ptr);
1397 ptr = build_array_index (void_okay_p (ptr), lwr_tree);
1398 ptr = build_nop (ptrtype, ptr);
1399 }
1400 else
1401 lwr_tree = NULL_TREE;
1402
1403 /* Nothing more to do for static arrays, their bounds checking has been
1404 done at compile-time. */
1405 if (tb->ty == Tsarray)
1406 {
1407 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1408 return;
1409 }
1410 else
1411 gcc_assert (tb->ty == Tarray);
1412
1413 /* Generate bounds checking code. */
1414 tree newlength;
1415
1416 if (!e->upperIsInBounds)
1417 {
1418 if (length)
1419 {
1420 newlength = build_bounds_condition (e->upr->loc, upr_tree,
1421 length, true);
1422 }
1423 else
1424 {
1425 /* Still need to check bounds lwr <= upr for pointers. */
1426 gcc_assert (tb1->ty == Tpointer);
1427 newlength = upr_tree;
1428 }
1429 }
1430 else
1431 newlength = upr_tree;
1432
1433 if (lwr_tree)
1434 {
1435 /* Enforces lwr <= upr. No need to check lwr <= length as
1436 we've already ensured that upr <= length. */
1437 if (!e->lowerIsLessThanUpper)
1438 {
1439 tree cond = build_bounds_condition (e->lwr->loc, lwr_tree,
1440 upr_tree, true);
1441
1442 /* When bounds checking is off, the index value is
1443 returned directly. */
1444 if (cond != lwr_tree)
1445 newlength = compound_expr (cond, newlength);
1446 }
1447
1448 /* Need to ensure lwr always gets evaluated first, as it may be a
1449 function call. Generates (lwr, upr) - lwr. */
1450 newlength = fold_build2 (MINUS_EXPR, TREE_TYPE (newlength),
1451 compound_expr (lwr_tree, newlength), lwr_tree);
1452 }
1453
1454 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1455 this->result_ = compound_expr (array, result);
1456 }
1457
1458 /* Build a cast expression, which converts the given unary expression to the
1459 type of result. */
1460
visit(CastExp * e)1461 void visit (CastExp *e)
1462 {
1463 Type *ebtype = e->e1->type->toBasetype ();
1464 Type *tbtype = e->to->toBasetype ();
1465 tree result = build_expr (e->e1, this->constp_);
1466
1467 /* Just evaluate e1 if it has any side effects. */
1468 if (tbtype->ty == Tvoid)
1469 this->result_ = build_nop (build_ctype (tbtype), result);
1470 else
1471 this->result_ = convert_for_rvalue (result, ebtype, tbtype);
1472 }
1473
1474 /* Build a delete expression. */
1475
visit(DeleteExp * e)1476 void visit (DeleteExp *e)
1477 {
1478 tree t1 = build_expr (e->e1);
1479 Type *tb1 = e->e1->type->toBasetype ();
1480
1481 if (tb1->ty == Tclass)
1482 {
1483 /* For class object references, if there is a destructor for that class,
1484 the destructor is called for the object instance. */
1485 libcall_fn libcall;
1486
1487 if (e->e1->op == TOKvar)
1488 {
1489 VarDeclaration *v = ((VarExp *) e->e1)->var->isVarDeclaration ();
1490 if (v && v->onstack)
1491 {
1492 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1493 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1494
1495 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1496 return;
1497 }
1498 }
1499
1500 /* Otherwise, the garbage collector is called to immediately free the
1501 memory allocated for the class instance. */
1502 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1503 ? LIBCALL_DELINTERFACE : LIBCALL_DELCLASS;
1504
1505 t1 = build_address (t1);
1506 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1507 }
1508 else if (tb1->ty == Tarray)
1509 {
1510 /* For dynamic arrays, the garbage collector is called to immediately
1511 release the memory. */
1512 Type *telem = tb1->nextOf ()->baseElemOf ();
1513 tree ti = null_pointer_node;
1514
1515 if (telem->ty == Tstruct)
1516 {
1517 /* Might need to run destructor on array contents. */
1518 TypeStruct *ts = (TypeStruct *) telem;
1519 if (ts->sym->dtor)
1520 ti = build_typeinfo (e->loc, tb1->nextOf ());
1521 }
1522
1523 /* Generate: _delarray_t (&t1, ti); */
1524 this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,
1525 build_address (t1), ti);
1526 }
1527 else if (tb1->ty == Tpointer)
1528 {
1529 /* For pointers to a struct instance, if the struct has overloaded
1530 operator delete, then that operator is called. */
1531 t1 = build_address (t1);
1532 Type *tnext = ((TypePointer *)tb1)->next->toBasetype ();
1533
1534 if (tnext->ty == Tstruct)
1535 {
1536 TypeStruct *ts = (TypeStruct *)tnext;
1537 if (ts->sym->dtor)
1538 {
1539 tree ti = build_typeinfo (e->loc, tnext);
1540 this->result_ = build_libcall (LIBCALL_DELSTRUCT, Type::tvoid,
1541 2, t1, ti);
1542 return;
1543 }
1544 }
1545
1546 /* Otherwise, the garbage collector is called to immediately free the
1547 memory allocated for the pointer. */
1548 this->result_ = build_libcall (LIBCALL_DELMEMORY, Type::tvoid, 1, t1);
1549 }
1550 else
1551 {
1552 error ("don%'t know how to delete %qs", e->e1->toChars ());
1553 this->result_ = error_mark_node;
1554 }
1555 }
1556
1557 /* Build a remove expression, which removes a particular key from an
1558 associative array. */
1559
visit(RemoveExp * e)1560 void visit (RemoveExp *e)
1561 {
1562 /* Check that the array is actually an associative array. */
1563 if (e->e1->type->toBasetype ()->ty == Taarray)
1564 {
1565 Type *tb = e->e1->type->toBasetype ();
1566 Type *tkey = ((TypeAArray *) tb)->index->toBasetype ();
1567 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1568
1569 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1570 build_expr (e->e1),
1571 build_typeinfo (e->loc, tkey),
1572 build_address (index));
1573 }
1574 else
1575 {
1576 error ("%qs is not an associative array", e->e1->toChars ());
1577 this->result_ = error_mark_node;
1578 }
1579 }
1580
1581 /* Build an unary not expression. */
1582
visit(NotExp * e)1583 void visit (NotExp *e)
1584 {
1585 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1586 /* Need to convert to boolean type or this will fail. */
1587 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1588
1589 this->result_ = d_convert (build_ctype (e->type), result);
1590 }
1591
1592 /* Build a compliment expression, where all the bits in the value are
1593 complemented. Note: unlike in C, the usual integral promotions
1594 are not performed prior to the complement operation. */
1595
visit(ComExp * e)1596 void visit (ComExp *e)
1597 {
1598 TY ty1 = e->e1->type->toBasetype ()->ty;
1599 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1600
1601 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1602 build_expr (e->e1));
1603 }
1604
1605 /* Build an unary negation expression. */
1606
visit(NegExp * e)1607 void visit (NegExp *e)
1608 {
1609 TY ty1 = e->e1->type->toBasetype ()->ty;
1610 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1611
1612 tree type = build_ctype (e->type);
1613 tree expr = build_expr (e->e1);
1614
1615 /* If the operation needs excess precision. */
1616 tree eptype = excess_precision_type (type);
1617 if (eptype != NULL_TREE)
1618 expr = d_convert (eptype, expr);
1619 else
1620 eptype = type;
1621
1622 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1623 this->result_ = d_convert (type, ret);
1624 }
1625
1626 /* Build a pointer index expression. */
1627
visit(PtrExp * e)1628 void visit (PtrExp *e)
1629 {
1630 Type *tnext = NULL;
1631 size_t offset;
1632 tree result;
1633
1634 if (e->e1->op == TOKadd)
1635 {
1636 BinExp *be = (BinExp *) e->e1;
1637 if (be->e1->op == TOKaddress
1638 && be->e2->isConst () && be->e2->type->isintegral ())
1639 {
1640 Expression *ae = ((AddrExp *) be->e1)->e1;
1641 tnext = ae->type->toBasetype ();
1642 result = build_expr (ae);
1643 offset = be->e2->toUInteger ();
1644 }
1645 }
1646 else if (e->e1->op == TOKsymoff)
1647 {
1648 SymOffExp *se = (SymOffExp *) e->e1;
1649 if (!declaration_reference_p (se->var))
1650 {
1651 tnext = se->var->type->toBasetype ();
1652 result = get_decl_tree (se->var);
1653 offset = se->offset;
1654 }
1655 }
1656
1657 /* Produce better code by converting *(#record + n) to
1658 COMPONENT_REFERENCE. Otherwise, the variable will always be
1659 allocated in memory because its address is taken. */
1660 if (tnext && tnext->ty == Tstruct)
1661 {
1662 StructDeclaration *sd = ((TypeStruct *) tnext)->sym;
1663
1664 for (size_t i = 0; i < sd->fields.dim; i++)
1665 {
1666 VarDeclaration *field = sd->fields[i];
1667
1668 if (field->offset == offset
1669 && same_type_p (field->type, e->type))
1670 {
1671 /* Catch errors, backend will ICE otherwise. */
1672 if (error_operand_p (result))
1673 this->result_ = result;
1674 else
1675 {
1676 result = component_ref (result, get_symbol_decl (field));
1677 this->result_ = result;
1678 }
1679 return;
1680 }
1681 else if (field->offset > offset)
1682 break;
1683 }
1684 }
1685
1686 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1687 }
1688
1689 /* Build an unary address expression. */
1690
visit(AddrExp * e)1691 void visit (AddrExp *e)
1692 {
1693 tree type = build_ctype (e->type);
1694 tree exp;
1695
1696 /* The frontend optimizer can convert const symbol into a struct literal.
1697 Taking the address of a struct literal is otherwise illegal. */
1698 if (e->e1->op == TOKstructliteral)
1699 {
1700 StructLiteralExp *sle = ((StructLiteralExp *) e->e1)->origin;
1701 gcc_assert (sle != NULL);
1702
1703 /* Build the reference symbol, the decl is built first as the
1704 initializer may have recursive references. */
1705 if (!sle->sym)
1706 {
1707 sle->sym = build_artificial_decl (build_ctype (sle->type),
1708 NULL_TREE, "S");
1709 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1710 d_pushdecl (sle->sym);
1711 rest_of_decl_compilation (sle->sym, 1, 0);
1712 }
1713
1714 exp = sle->sym;
1715 }
1716 else
1717 exp = build_expr (e->e1, this->constp_);
1718
1719 TREE_CONSTANT (exp) = 0;
1720 this->result_ = d_convert (type, build_address (exp));
1721 }
1722
1723 /* Build a function call expression. */
1724
visit(CallExp * e)1725 void visit (CallExp *e)
1726 {
1727 Type *tb = e->e1->type->toBasetype ();
1728 Expression *e1b = e->e1;
1729
1730 tree callee = NULL_TREE;
1731 tree object = NULL_TREE;
1732 tree cleanup = NULL_TREE;
1733 TypeFunction *tf = NULL;
1734
1735 /* Calls to delegates can sometimes look like this. */
1736 if (e1b->op == TOKcomma)
1737 {
1738 e1b = ((CommaExp *) e1b)->e2;
1739 gcc_assert (e1b->op == TOKvar);
1740
1741 Declaration *var = ((VarExp *) e1b)->var;
1742 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1743 }
1744
1745 if (e1b->op == TOKdotvar && tb->ty != Tdelegate)
1746 {
1747 DotVarExp *dve = (DotVarExp *) e1b;
1748
1749 /* Don't modify the static initializer for struct literals. */
1750 if (dve->e1->op == TOKstructliteral)
1751 {
1752 StructLiteralExp *sle = (StructLiteralExp *) dve->e1;
1753 sle->useStaticInit = false;
1754 }
1755
1756 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1757 if (fd != NULL)
1758 {
1759 /* Get the correct callee from the DotVarExp object. */
1760 tree fndecl = get_symbol_decl (fd);
1761 AggregateDeclaration *ad = fd->isThis ();
1762
1763 /* Static method; ignore the object instance. */
1764 if (!ad)
1765 callee = build_address (fndecl);
1766 else
1767 {
1768 tree thisexp = build_expr (dve->e1);
1769
1770 /* When constructing temporaries, if the constructor throws,
1771 then the object is destructed even though it is not a fully
1772 constructed object yet. And so this call will need to be
1773 moved inside the TARGET_EXPR_INITIAL slot. */
1774 if (fd->isCtorDeclaration ()
1775 && TREE_CODE (thisexp) == COMPOUND_EXPR
1776 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1777 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1778 {
1779 cleanup = TREE_OPERAND (thisexp, 0);
1780 thisexp = TREE_OPERAND (thisexp, 1);
1781 }
1782
1783 /* Want reference to 'this' object. */
1784 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1785 thisexp = build_address (thisexp);
1786
1787 /* Make the callee a virtual call. */
1788 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1789 {
1790 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1791 tree thistype = build_ctype (ad->handleType ());
1792 thisexp = build_nop (thistype, d_save_expr (thisexp));
1793 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1794 }
1795 else
1796 fndecl = build_address (fndecl);
1797
1798 callee = build_method_call (fndecl, thisexp, fd->type);
1799 }
1800 }
1801 }
1802
1803 if (callee == NULL_TREE)
1804 callee = build_expr (e1b);
1805
1806 if (METHOD_CALL_EXPR (callee))
1807 {
1808 /* This could be a delegate expression (TY == Tdelegate), but not
1809 actually a delegate variable. */
1810 if (e1b->op == TOKdotvar)
1811 {
1812 /* This gets the true function type, getting the function type
1813 from e1->type can sometimes be incorrect, such as when calling
1814 a 'ref' return function. */
1815 tf = get_function_type (((DotVarExp *) e1b)->var->type);
1816 }
1817 else
1818 tf = get_function_type (tb);
1819
1820 extract_from_method_call (callee, callee, object);
1821 }
1822 else if (tb->ty == Tdelegate)
1823 {
1824 /* Delegate call, extract .object and .funcptr from var. */
1825 callee = d_save_expr (callee);
1826 tf = get_function_type (tb);
1827 object = delegate_object (callee);
1828 callee = delegate_method (callee);
1829 }
1830 else if (e1b->op == TOKvar)
1831 {
1832 FuncDeclaration *fd = ((VarExp *) e1b)->var->isFuncDeclaration ();
1833 gcc_assert (fd != NULL);
1834 tf = get_function_type (fd->type);
1835
1836 if (fd->isNested ())
1837 {
1838 /* Maybe re-evaluate symbol storage treating 'fd' as public. */
1839 if (call_by_alias_p (d_function_chain->function, fd))
1840 TREE_PUBLIC (callee) = 1;
1841
1842 object = get_frame_for_symbol (fd);
1843 }
1844 else if (fd->needThis ())
1845 {
1846 error_at (make_location_t (e1b->loc),
1847 "need %<this%> to access member %qs", fd->toChars ());
1848 /* Continue compiling... */
1849 object = null_pointer_node;
1850 }
1851 }
1852 else
1853 {
1854 /* Normal direct function call. */
1855 tf = get_function_type (tb);
1856 }
1857
1858 gcc_assert (tf != NULL);
1859
1860 /* Now we have the type, callee and maybe object reference,
1861 build the call expression. */
1862 tree exp = d_build_call (tf, callee, object, e->arguments);
1863
1864 if (tf->isref)
1865 exp = build_deref (exp);
1866
1867 /* Some library calls are defined to return a generic type.
1868 this->type is the real type we want to return. */
1869 if (e->type->isTypeBasic ())
1870 exp = d_convert (build_ctype (e->type), exp);
1871
1872 /* If this call was found to be a constructor for a temporary with a
1873 cleanup, then move the call inside the TARGET_EXPR. */
1874 if (cleanup != NULL_TREE)
1875 {
1876 tree init = TARGET_EXPR_INITIAL (cleanup);
1877 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1878 exp = cleanup;
1879 }
1880
1881 this->result_ = exp;
1882 }
1883
1884 /* Build a delegate expression. */
1885
visit(DelegateExp * e)1886 void visit (DelegateExp *e)
1887 {
1888 if (e->func->semanticRun == PASSsemantic3done)
1889 {
1890 /* Add the function as nested function if it belongs to this module.
1891 ie: it is a member of this module, or it is a template instance. */
1892 Dsymbol *owner = e->func->toParent ();
1893 while (!owner->isTemplateInstance () && owner->toParent ())
1894 owner = owner->toParent ();
1895 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1896 build_decl_tree (e->func);
1897 }
1898
1899 tree fndecl;
1900 tree object;
1901
1902 if (e->func->isNested ())
1903 {
1904 if (e->e1->op == TOKnull)
1905 object = build_expr (e->e1);
1906 else
1907 object = get_frame_for_symbol (e->func);
1908
1909 fndecl = build_address (get_symbol_decl (e->func));
1910 }
1911 else
1912 {
1913 if (!e->func->isThis ())
1914 {
1915 error ("delegates are only for non-static functions");
1916 this->result_ = error_mark_node;
1917 return;
1918 }
1919
1920 object = build_expr (e->e1);
1921
1922 /* Want reference to `this' object. */
1923 if (e->e1->type->ty != Tclass && e->e1->type->ty != Tpointer)
1924 object = build_address (object);
1925
1926 /* Object reference could be the outer `this' field of a class or
1927 closure of type `void*'. Cast it to the right type. */
1928 if (e->e1->type->ty == Tclass)
1929 object = d_convert (build_ctype (e->e1->type), object);
1930
1931 fndecl = get_symbol_decl (e->func);
1932
1933 /* Get pointer to function out of the virtual table. */
1934 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1935 && e->e1->op != TOKsuper && e->e1->op != TOKdottype)
1936 {
1937 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1938 object = d_save_expr (object);
1939 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1940 }
1941 else
1942 fndecl = build_address (fndecl);
1943 }
1944
1945 this->result_ = build_method_call (fndecl, object, e->type);
1946 }
1947
1948 /* Build a type component expression. */
1949
visit(DotTypeExp * e)1950 void visit (DotTypeExp *e)
1951 {
1952 /* Just a pass through to underlying expression. */
1953 this->result_ = build_expr (e->e1);
1954 }
1955
1956 /* Build a component reference expression. */
1957
visit(DotVarExp * e)1958 void visit (DotVarExp *e)
1959 {
1960 VarDeclaration *vd = e->var->isVarDeclaration ();
1961
1962 /* This could also be a function, but relying on that being taken
1963 care of by the visitor interface for CallExp. */
1964 if (vd != NULL)
1965 {
1966 if (!vd->isField ())
1967 this->result_ = get_decl_tree (vd);
1968 else
1969 {
1970 tree object = build_expr (e->e1);
1971
1972 if (e->e1->type->toBasetype ()->ty != Tstruct)
1973 object = build_deref (object);
1974
1975 this->result_ = component_ref (object, get_symbol_decl (vd));
1976 }
1977 }
1978 else
1979 {
1980 error ("%qs is not a field, but a %qs",
1981 e->var->toChars (), e->var->kind ());
1982 this->result_ = error_mark_node;
1983 }
1984 }
1985
1986 /* Build an assert expression, used to declare conditions that must hold at
1987 that a given point in the program. */
1988
visit(AssertExp * e)1989 void visit (AssertExp *e)
1990 {
1991 Type *tb1 = e->e1->type->toBasetype ();
1992 tree arg = build_expr (e->e1);
1993 tree tmsg = NULL_TREE;
1994 tree assert_pass = void_node;
1995 tree assert_fail;
1996
1997 if (global.params.useAssert
1998 && global.params.checkAction == CHECKACTION_D)
1999 {
2000 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
2001 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
2002 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
2003 libcall_fn libcall;
2004
2005 if (e->msg)
2006 {
2007 tmsg = build_expr_dtor (e->msg);
2008 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
2009 }
2010 else
2011 libcall = unittest_p ? LIBCALL_UNITTEST : LIBCALL_ASSERT;
2012
2013 /* Build a call to _d_assert(). */
2014 assert_fail = d_assert_call (e->loc, libcall, tmsg);
2015
2016 if (global.params.useInvariants)
2017 {
2018 /* If the condition is a D class or struct object with an invariant,
2019 call it if the condition result is true. */
2020 if (tb1->ty == Tclass)
2021 {
2022 ClassDeclaration *cd = tb1->isClassHandle ();
2023 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
2024 {
2025 arg = d_save_expr (arg);
2026 assert_pass = build_libcall (LIBCALL_INVARIANT,
2027 Type::tvoid, 1, arg);
2028 }
2029 }
2030 else if (tb1->ty == Tpointer && tb1->nextOf ()->ty == Tstruct)
2031 {
2032 StructDeclaration *sd = ((TypeStruct *) tb1->nextOf ())->sym;
2033 if (sd->inv != NULL)
2034 {
2035 Expressions args;
2036 arg = d_save_expr (arg);
2037 assert_pass = d_build_call_expr (sd->inv, arg, &args);
2038 }
2039 }
2040 }
2041 }
2042 else if (global.params.useAssert
2043 && global.params.checkAction == CHECKACTION_C)
2044 {
2045 /* Generate: __builtin_trap() */
2046 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
2047 assert_fail = build_call_expr (fn, 0);
2048 }
2049 else
2050 {
2051 /* Assert contracts are turned off, if the contract condition has no
2052 side effects can still use it as a predicate for the optimizer. */
2053 if (TREE_SIDE_EFFECTS (arg))
2054 {
2055 this->result_ = void_node;
2056 return;
2057 }
2058
2059 assert_fail = build_predict_expr (PRED_NORETURN, NOT_TAKEN);
2060 }
2061
2062 /* Build condition that we are asserting in this contract. */
2063 tree condition = convert_for_condition (arg, e->e1->type);
2064
2065 /* We expect the condition to always be true, as what happens if an assert
2066 contract is false is undefined behavior. */
2067 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
2068 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
2069 tree pred_type = TREE_VALUE (arg_types);
2070 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
2071
2072 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
2073 build_int_cst (expected_type, 1));
2074 condition = d_truthvalue_conversion (condition);
2075
2076 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
2077 }
2078
2079 /* Build a declaration expression. */
2080
visit(DeclarationExp * e)2081 void visit (DeclarationExp *e)
2082 {
2083 /* Compile the declaration. */
2084 push_stmt_list ();
2085 build_decl_tree (e->declaration);
2086 tree result = pop_stmt_list ();
2087
2088 /* Construction of an array for typesafe-variadic function arguments
2089 can cause an empty STMT_LIST here. This can causes problems
2090 during gimplification. */
2091 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
2092 result = build_empty_stmt (input_location);
2093
2094 this->result_ = result;
2095 }
2096
2097 /* Build a typeid expression. Returns an instance of class TypeInfo
2098 corresponding to. */
2099
visit(TypeidExp * e)2100 void visit (TypeidExp *e)
2101 {
2102 if (Type *tid = isType (e->obj))
2103 {
2104 tree ti = build_typeinfo (e->loc, tid);
2105
2106 /* If the typeinfo is at an offset. */
2107 if (tid->vtinfo->offset)
2108 ti = build_offset (ti, size_int (tid->vtinfo->offset));
2109
2110 this->result_ = build_nop (build_ctype (e->type), ti);
2111 }
2112 else if (Expression *tid = isExpression (e->obj))
2113 {
2114 Type *type = tid->type->toBasetype ();
2115 assert (type->ty == Tclass);
2116
2117 /* Generate **classptr to get the classinfo. */
2118 tree ci = build_expr (tid);
2119 ci = indirect_ref (ptr_type_node, ci);
2120 ci = indirect_ref (ptr_type_node, ci);
2121
2122 /* Add extra indirection for interfaces. */
2123 if (((TypeClass *) type)->sym->isInterfaceDeclaration ())
2124 ci = indirect_ref (ptr_type_node, ci);
2125
2126 this->result_ = build_nop (build_ctype (e->type), ci);
2127 }
2128 else
2129 gcc_unreachable ();
2130 }
2131
2132 /* Build a function/lambda expression. */
2133
visit(FuncExp * e)2134 void visit (FuncExp *e)
2135 {
2136 Type *ftype = e->type->toBasetype ();
2137
2138 /* This check is for lambda's, remove 'vthis' as function isn't nested. */
2139 if (e->fd->tok == TOKreserved && ftype->ty == Tpointer)
2140 {
2141 e->fd->tok = TOKfunction;
2142 e->fd->vthis = NULL;
2143 }
2144
2145 /* Compile the function literal body. */
2146 build_decl_tree (e->fd);
2147
2148 /* If nested, this will be a trampoline. */
2149 if (e->fd->isNested ())
2150 {
2151 tree func = build_address (get_symbol_decl (e->fd));
2152 tree object;
2153
2154 if (this->constp_)
2155 {
2156 /* Static delegate variables have no context pointer. */
2157 object = null_pointer_node;
2158 this->result_ = build_method_call (func, object, e->fd->type);
2159 TREE_CONSTANT (this->result_) = 1;
2160 }
2161 else
2162 {
2163 object = get_frame_for_symbol (e->fd);
2164 this->result_ = build_method_call (func, object, e->fd->type);
2165 }
2166 }
2167 else
2168 {
2169 this->result_ = build_nop (build_ctype (e->type),
2170 build_address (get_symbol_decl (e->fd)));
2171 }
2172 }
2173
2174 /* Build a halt expression. */
2175
visit(HaltExp *)2176 void visit (HaltExp *)
2177 {
2178 /* Should we use trap() or abort()? */
2179 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2180 this->result_ = build_call_expr (ttrap, 0);
2181 }
2182
2183 /* Build a symbol pointer offset expression. */
2184
visit(SymOffExp * e)2185 void visit (SymOffExp *e)
2186 {
2187 /* Build the address and offset of the symbol. */
2188 size_t soffset = ((SymOffExp *) e)->offset;
2189 tree result = get_decl_tree (e->var);
2190 TREE_USED (result) = 1;
2191
2192 if (declaration_reference_p (e->var))
2193 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2194 else
2195 result = build_address (result);
2196
2197 if (!soffset)
2198 result = d_convert (build_ctype (e->type), result);
2199 else
2200 {
2201 tree offset = size_int (soffset);
2202 result = build_nop (build_ctype (e->type),
2203 build_offset (result, offset));
2204 }
2205
2206 this->result_ = result;
2207 }
2208
2209 /* Build a variable expression. */
2210
visit(VarExp * e)2211 void visit (VarExp *e)
2212 {
2213 if (e->var->needThis ())
2214 {
2215 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2216 this->result_ = error_mark_node;
2217 return;
2218 }
2219 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2220 {
2221 /* __ctfe is always false at run-time. */
2222 this->result_ = integer_zero_node;
2223 return;
2224 }
2225
2226 /* This check is same as is done in FuncExp for lambdas. */
2227 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2228 if (fld != NULL)
2229 {
2230 if (fld->tok == TOKreserved)
2231 {
2232 fld->tok = TOKfunction;
2233 fld->vthis = NULL;
2234 }
2235
2236 /* Compiler the function literal body. */
2237 build_decl_tree (fld);
2238 }
2239
2240 if (this->constp_)
2241 {
2242 /* Want the initializer, not the expression. */
2243 VarDeclaration *var = e->var->isVarDeclaration ();
2244 SymbolDeclaration *sd = e->var->isSymbolDeclaration ();
2245 tree init = NULL_TREE;
2246
2247 if (var && (var->isConst () || var->isImmutable ())
2248 && e->type->toBasetype ()->ty != Tsarray && var->_init)
2249 {
2250 if (var->inuse)
2251 error_at (make_location_t (e->loc), "recursive reference %qs",
2252 e->toChars ());
2253 else
2254 {
2255 var->inuse++;
2256 init = build_expr (initializerToExpression (var->_init), true);
2257 var->inuse--;
2258 }
2259 }
2260 else if (sd && sd->dsym)
2261 init = layout_struct_initializer (sd->dsym);
2262 else
2263 error_at (make_location_t (e->loc), "non-constant expression %qs",
2264 e->toChars ());
2265
2266 if (init != NULL_TREE)
2267 this->result_ = init;
2268 else
2269 this->result_ = error_mark_node;
2270 }
2271 else
2272 {
2273 tree result = get_decl_tree (e->var);
2274 TREE_USED (result) = 1;
2275
2276 /* For variables that are references - currently only out/inout
2277 arguments; objects don't count - evaluating the variable means
2278 we want what it refers to. */
2279 if (declaration_reference_p (e->var))
2280 result = indirect_ref (build_ctype (e->var->type), result);
2281
2282 this->result_ = result;
2283 }
2284 }
2285
2286 /* Build a this variable expression. */
2287
visit(ThisExp * e)2288 void visit (ThisExp *e)
2289 {
2290 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2291 tree result = NULL_TREE;
2292
2293 if (e->var)
2294 result = get_decl_tree (e->var);
2295 else
2296 {
2297 gcc_assert (fd && fd->vthis);
2298 result = get_decl_tree (fd->vthis);
2299 }
2300
2301 if (e->type->ty == Tstruct)
2302 result = build_deref (result);
2303
2304 this->result_ = result;
2305 }
2306
2307 /* Build a new expression, which allocates memory either on the garbage
2308 collected heap or by using a class or struct specific allocator. */
2309
visit(NewExp * e)2310 void visit (NewExp *e)
2311 {
2312 Type *tb = e->type->toBasetype ();
2313 tree result;
2314
2315 if (e->allocator)
2316 gcc_assert (e->newargs);
2317
2318 if (tb->ty == Tclass)
2319 {
2320 /* Allocating a new class. */
2321 tb = e->newtype->toBasetype ();
2322 gcc_assert (tb->ty == Tclass);
2323
2324 ClassDeclaration *cd = ((TypeClass *) tb)->sym;
2325 tree type = build_ctype (tb);
2326 tree setup_exp = NULL_TREE;
2327 tree new_call;
2328
2329 if (e->onstack)
2330 {
2331 /* If being used as an initializer for a local variable with scope
2332 storage class, then the instance is allocated on the stack
2333 rather than the heap or using the class specific allocator. */
2334 tree var = build_local_temp (TREE_TYPE (type));
2335 new_call = build_nop (type, build_address (var));
2336 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2337 }
2338 else if (e->allocator)
2339 {
2340 /* Call class allocator, and copy the initializer into memory. */
2341 new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
2342 new_call = d_save_expr (new_call);
2343 new_call = build_nop (type, new_call);
2344 setup_exp = modify_expr (build_deref (new_call),
2345 aggregate_initializer_decl (cd));
2346 }
2347 else
2348 {
2349 /* Generate: _d_newclass() */
2350 tree arg = build_address (get_classinfo_decl (cd));
2351 new_call = build_libcall (LIBCALL_NEWCLASS, tb, 1, arg);
2352 }
2353
2354 /* Set the context pointer for nested classes. */
2355 if (cd->isNested ())
2356 {
2357 tree field = get_symbol_decl (cd->vthis);
2358 tree value = NULL_TREE;
2359
2360 if (e->thisexp)
2361 {
2362 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
2363 Dsymbol *outer = cd->toParent2 ();
2364 int offset = 0;
2365
2366 value = build_expr (e->thisexp);
2367 if (outer != tcd)
2368 {
2369 ClassDeclaration *ocd = outer->isClassDeclaration ();
2370 gcc_assert (ocd->isBaseOf (tcd, &offset));
2371 /* Could just add offset... */
2372 value = convert_expr (value, e->thisexp->type, ocd->type);
2373 }
2374 }
2375 else
2376 value = build_vthis (cd);
2377
2378 if (value != NULL_TREE)
2379 {
2380 /* Generate: (new())->vthis = this; */
2381 new_call = d_save_expr (new_call);
2382 field = component_ref (build_deref (new_call), field);
2383 setup_exp = compound_expr (setup_exp,
2384 modify_expr (field, value));
2385 }
2386 }
2387 new_call = compound_expr (setup_exp, new_call);
2388
2389 /* Call the class constructor. */
2390 if (e->member)
2391 result = d_build_call_expr (e->member, new_call, e->arguments);
2392 else
2393 result = new_call;
2394
2395 if (e->argprefix)
2396 result = compound_expr (build_expr (e->argprefix), result);
2397 }
2398 else if (tb->ty == Tpointer && tb->nextOf ()->toBasetype ()->ty == Tstruct)
2399 {
2400 /* Allocating memory for a new struct. */
2401 Type *htype = e->newtype->toBasetype ();
2402 gcc_assert (htype->ty == Tstruct);
2403 gcc_assert (!e->onstack);
2404
2405 TypeStruct *stype = (TypeStruct *) htype;
2406 StructDeclaration *sd = stype->sym;
2407 tree new_call;
2408
2409 /* Cannot new an opaque struct. */
2410 if (sd->size (e->loc) == 0)
2411 {
2412 this->result_ = d_convert (build_ctype (e->type),
2413 integer_zero_node);
2414 return;
2415 }
2416
2417 if (e->allocator)
2418 {
2419 /* Call struct allocator. */
2420 new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
2421 new_call = build_nop (build_ctype (tb), new_call);
2422 }
2423 else
2424 {
2425 /* Generate: _d_newitemT() */
2426 libcall_fn libcall = htype->isZeroInit ()
2427 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2428 tree arg = build_typeinfo (e->loc, e->newtype);
2429 new_call = build_libcall (libcall, tb, 1, arg);
2430 }
2431
2432 if (e->member || !e->arguments)
2433 {
2434 /* Set the context pointer for nested structs. */
2435 if (sd->isNested ())
2436 {
2437 tree value = build_vthis (sd);
2438 tree field = get_symbol_decl (sd->vthis);
2439 tree type = build_ctype (stype);
2440
2441 new_call = d_save_expr (new_call);
2442 field = component_ref (indirect_ref (type, new_call), field);
2443 new_call = compound_expr (modify_expr (field, value), new_call);
2444 }
2445
2446 /* Call the struct constructor. */
2447 if (e->member)
2448 result = d_build_call_expr (e->member, new_call, e->arguments);
2449 else
2450 result = new_call;
2451 }
2452 else
2453 {
2454 /* If we have a user supplied initializer, then set-up with a
2455 struct literal. */
2456 if (e->arguments != NULL && sd->fields.dim != 0)
2457 {
2458 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2459 e->arguments,
2460 htype);
2461 new_call = d_save_expr (new_call);
2462 se->type = sd->type;
2463 se->sym = new_call;
2464 result = compound_expr (build_expr (se), new_call);
2465 }
2466 else
2467 result = new_call;
2468 }
2469
2470 if (e->argprefix)
2471 result = compound_expr (build_expr (e->argprefix), result);
2472 }
2473 else if (tb->ty == Tarray)
2474 {
2475 /* Allocating memory for a new D array. */
2476 tb = e->newtype->toBasetype ();
2477 gcc_assert (tb->ty == Tarray);
2478 TypeDArray *tarray = (TypeDArray *) tb;
2479
2480 gcc_assert (!e->allocator);
2481 gcc_assert (e->arguments && e->arguments->dim >= 1);
2482
2483 if (e->arguments->dim == 1)
2484 {
2485 /* Single dimension array allocations. */
2486 Expression *arg = (*e->arguments)[0];
2487
2488 if (tarray->next->size () == 0)
2489 {
2490 /* Array element size is unknown. */
2491 this->result_ = d_array_value (build_ctype (e->type),
2492 size_int (0), null_pointer_node);
2493 return;
2494 }
2495
2496 libcall_fn libcall = tarray->next->isZeroInit ()
2497 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
2498 result = build_libcall (libcall, tb, 2,
2499 build_typeinfo (e->loc, e->type),
2500 build_expr (arg));
2501 }
2502 else
2503 {
2504 /* Multidimensional array allocations. */
2505 tree tarray = make_array_type (Type::tsize_t, e->arguments->dim);
2506 tree var = build_local_temp (tarray);
2507 vec<constructor_elt, va_gc> *elms = NULL;
2508
2509 /* Get the base element type for the array, generating the
2510 initializer for the dims parameter along the way. */
2511 Type *telem = e->newtype->toBasetype ();
2512 for (size_t i = 0; i < e->arguments->dim; i++)
2513 {
2514 Expression *arg = (*e->arguments)[i];
2515 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2516
2517 gcc_assert (telem->ty == Tarray);
2518 telem = telem->toBasetype ()->nextOf ();
2519 gcc_assert (telem);
2520 }
2521
2522 /* Initialize the temporary. */
2523 tree init = modify_expr (var, build_constructor (tarray, elms));
2524 var = compound_expr (init, var);
2525
2526 /* Generate: _d_newarraymTX(ti, dims)
2527 or: _d_newarraymiTX(ti, dims) */
2528 libcall_fn libcall = telem->isZeroInit ()
2529 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2530
2531 tree tinfo = build_typeinfo (e->loc, e->type);
2532 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2533 size_int (e->arguments->dim),
2534 build_address (var));
2535
2536 result = build_libcall (libcall, tb, 2, tinfo, dims);
2537 }
2538
2539 if (e->argprefix)
2540 result = compound_expr (build_expr (e->argprefix), result);
2541 }
2542 else if (tb->ty == Tpointer)
2543 {
2544 /* Allocating memory for a new pointer. */
2545 TypePointer *tpointer = (TypePointer *) tb;
2546
2547 if (tpointer->next->size () == 0)
2548 {
2549 /* Pointer element size is unknown. */
2550 this->result_ = d_convert (build_ctype (e->type),
2551 integer_zero_node);
2552 return;
2553 }
2554
2555 libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
2556 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2557
2558 tree arg = build_typeinfo (e->loc, e->newtype);
2559 result = build_libcall (libcall, tb, 1, arg);
2560
2561 if (e->arguments && e->arguments->dim == 1)
2562 {
2563 result = d_save_expr (result);
2564 tree init = modify_expr (build_deref (result),
2565 build_expr ((*e->arguments)[0]));
2566 result = compound_expr (init, result);
2567 }
2568
2569 if (e->argprefix)
2570 result = compound_expr (build_expr (e->argprefix), result);
2571 }
2572 else
2573 gcc_unreachable ();
2574
2575 this->result_ = convert_expr (result, tb, e->type);
2576 }
2577
2578 /* Build an integer literal. */
2579
visit(IntegerExp * e)2580 void visit (IntegerExp *e)
2581 {
2582 tree ctype = build_ctype (e->type->toBasetype ());
2583 this->result_ = build_integer_cst (e->value, ctype);
2584 }
2585
2586 /* Build a floating-point literal. */
2587
visit(RealExp * e)2588 void visit (RealExp *e)
2589 {
2590 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2591 }
2592
2593 /* Build a complex literal. */
2594
visit(ComplexExp * e)2595 void visit (ComplexExp *e)
2596 {
2597 Type *tnext;
2598
2599 switch (e->type->toBasetype ()->ty)
2600 {
2601 case Tcomplex32:
2602 tnext = (TypeBasic *) Type::tfloat32;
2603 break;
2604
2605 case Tcomplex64:
2606 tnext = (TypeBasic *) Type::tfloat64;
2607 break;
2608
2609 case Tcomplex80:
2610 tnext = (TypeBasic *) Type::tfloat80;
2611 break;
2612
2613 default:
2614 gcc_unreachable ();
2615 }
2616
2617 this->result_ = build_complex (build_ctype (e->type),
2618 build_float_cst (creall (e->value), tnext),
2619 build_float_cst (cimagl (e->value), tnext));
2620 }
2621
2622 /* Build a string literal, all strings are null terminated except for
2623 static arrays. */
2624
visit(StringExp * e)2625 void visit (StringExp *e)
2626 {
2627 Type *tb = e->type->toBasetype ();
2628 tree type = build_ctype (e->type);
2629
2630 if (tb->ty == Tsarray)
2631 {
2632 /* Turn the string into a constructor for the static array. */
2633 vec<constructor_elt, va_gc> *elms = NULL;
2634 vec_safe_reserve (elms, e->len);
2635 tree etype = TREE_TYPE (type);
2636
2637 for (size_t i = 0; i < e->len; i++)
2638 {
2639 tree value = build_integer_cst (e->charAt (i), etype);
2640 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2641 }
2642
2643 tree ctor = build_constructor (type, elms);
2644 TREE_CONSTANT (ctor) = 1;
2645 this->result_ = ctor;
2646 }
2647 else
2648 {
2649 /* Copy the string contents to a null terminated string. */
2650 dinteger_t length = (e->len * e->sz);
2651 char *string = XALLOCAVEC (char, length + 1);
2652 memcpy (string, e->string, length);
2653 string[length] = '\0';
2654
2655 /* String value and type includes the null terminator. */
2656 tree value = build_string (length, string);
2657 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2658 value = build_address (value);
2659
2660 if (tb->ty == Tarray)
2661 value = d_array_value (type, size_int (e->len), value);
2662
2663 TREE_CONSTANT (value) = 1;
2664 this->result_ = d_convert (type, value);
2665 }
2666 }
2667
2668 /* Build a tuple literal. Just an argument list that may have
2669 side effects that need evaluation. */
2670
visit(TupleExp * e)2671 void visit (TupleExp *e)
2672 {
2673 tree result = NULL_TREE;
2674
2675 if (e->e0)
2676 result = build_expr (e->e0);
2677
2678 for (size_t i = 0; i < e->exps->dim; ++i)
2679 {
2680 Expression *exp = (*e->exps)[i];
2681 result = compound_expr (result, build_expr (exp));
2682 }
2683
2684 if (result == NULL_TREE)
2685 result = void_node;
2686
2687 this->result_ = result;
2688 }
2689
2690 /* Build an array literal. The common type of the all elements is taken to
2691 be the type of the array element, and all elements are implicitly
2692 converted to that type. */
2693
visit(ArrayLiteralExp * e)2694 void visit (ArrayLiteralExp *e)
2695 {
2696 Type *tb = e->type->toBasetype ();
2697
2698 /* Implicitly convert void[n] to ubyte[n]. */
2699 if (tb->ty == Tsarray && tb->nextOf ()->toBasetype ()->ty == Tvoid)
2700 tb = Type::tuns8->sarrayOf (((TypeSArray *) tb)->dim->toUInteger ());
2701
2702 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tpointer);
2703
2704 /* Handle empty array literals. */
2705 if (e->elements->dim == 0)
2706 {
2707 if (tb->ty == Tarray)
2708 this->result_ = d_array_value (build_ctype (e->type),
2709 size_int (0), null_pointer_node);
2710 else
2711 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2712 NULL);
2713
2714 return;
2715 }
2716
2717 /* Build an expression that assigns the expressions in ELEMENTS to
2718 a constructor. */
2719 vec<constructor_elt, va_gc> *elms = NULL;
2720 vec_safe_reserve (elms, e->elements->dim);
2721 bool constant_p = true;
2722 tree saved_elems = NULL_TREE;
2723
2724 Type *etype = tb->nextOf ();
2725 tree satype = make_array_type (etype, e->elements->dim);
2726
2727 for (size_t i = 0; i < e->elements->dim; i++)
2728 {
2729 Expression *expr = e->getElement (i);
2730 tree value = build_expr (expr, this->constp_);
2731
2732 /* Only append nonzero values, the backend will zero out the rest
2733 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2734 if (!initializer_zerop (value))
2735 {
2736 if (!TREE_CONSTANT (value))
2737 constant_p = false;
2738
2739 /* Split construction of values out of the constructor if there
2740 may be side effects. */
2741 tree init = stabilize_expr (&value);
2742 if (init != NULL_TREE)
2743 saved_elems = compound_expr (saved_elems, init);
2744
2745 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2746 convert_expr (value, expr->type, etype));
2747 }
2748 }
2749
2750 /* Now return the constructor as the correct type. For static arrays there
2751 is nothing else to do. For dynamic arrays, return a two field struct.
2752 For pointers, return the address. */
2753 tree ctor = build_constructor (satype, elms);
2754 tree type = build_ctype (e->type);
2755
2756 /* Nothing else to do for static arrays. */
2757 if (tb->ty == Tsarray || this->constp_)
2758 {
2759 /* Can't take the address of the constructor, so create an anonymous
2760 static symbol, and then refer to it. */
2761 if (tb->ty != Tsarray)
2762 {
2763 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2764 ctor = build_address (decl);
2765 if (tb->ty == Tarray)
2766 ctor = d_array_value (type, size_int (e->elements->dim), ctor);
2767
2768 d_pushdecl (decl);
2769 rest_of_decl_compilation (decl, 1, 0);
2770 }
2771
2772 /* If the array literal is readonly or static. */
2773 if (constant_p)
2774 TREE_CONSTANT (ctor) = 1;
2775 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2776 TREE_STATIC (ctor) = 1;
2777
2778 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2779 }
2780 else
2781 {
2782 /* Allocate space on the memory managed heap. */
2783 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2784 etype->pointerTo (), 2,
2785 build_typeinfo (e->loc, etype->arrayOf ()),
2786 size_int (e->elements->dim));
2787 mem = d_save_expr (mem);
2788
2789 /* Now copy the constructor into memory. */
2790 tree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);
2791 tree size = size_mult_expr (size_int (e->elements->dim),
2792 size_int (tb->nextOf ()->size ()));
2793
2794 tree result = build_call_expr (tmemcpy, 3, mem,
2795 build_address (ctor), size);
2796
2797 /* Return the array pointed to by MEM. */
2798 result = compound_expr (result, mem);
2799
2800 if (tb->ty == Tarray)
2801 result = d_array_value (type, size_int (e->elements->dim), result);
2802
2803 this->result_ = compound_expr (saved_elems, result);
2804 }
2805 }
2806
2807 /* Build an associative array literal. The common type of the all keys is
2808 taken to be the key type, and common type of all values the value type.
2809 All keys and values are then implicitly converted as needed. */
2810
visit(AssocArrayLiteralExp * e)2811 void visit (AssocArrayLiteralExp *e)
2812 {
2813 /* Want the mutable type for typeinfo reference. */
2814 Type *tb = e->type->toBasetype ()->mutableOf ();
2815 gcc_assert (tb->ty == Taarray);
2816
2817 /* Handle empty assoc array literals. */
2818 TypeAArray *ta = (TypeAArray *) tb;
2819 if (e->keys->dim == 0)
2820 {
2821 this->result_ = build_constructor (build_ctype (ta), NULL);
2822 return;
2823 }
2824
2825 /* Build an expression that assigns all expressions in KEYS
2826 to a constructor. */
2827 vec<constructor_elt, va_gc> *kelts = NULL;
2828 vec_safe_reserve (kelts, e->keys->dim);
2829 for (size_t i = 0; i < e->keys->dim; i++)
2830 {
2831 Expression *key = (*e->keys)[i];
2832 tree t = build_expr (key);
2833 CONSTRUCTOR_APPEND_ELT (kelts, size_int (i),
2834 convert_expr (t, key->type, ta->index));
2835 }
2836 tree tkeys = make_array_type (ta->index, e->keys->dim);
2837 tree akeys = build_constructor (tkeys, kelts);
2838
2839 /* Do the same with all expressions in VALUES. */
2840 vec<constructor_elt, va_gc> *velts = NULL;
2841 vec_safe_reserve (velts, e->values->dim);
2842 for (size_t i = 0; i < e->values->dim; i++)
2843 {
2844 Expression *value = (*e->values)[i];
2845 tree t = build_expr (value);
2846 CONSTRUCTOR_APPEND_ELT (velts, size_int (i),
2847 convert_expr (t, value->type, ta->next));
2848 }
2849 tree tvals = make_array_type (ta->next, e->values->dim);
2850 tree avals = build_constructor (tvals, velts);
2851
2852 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2853 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
2854 size_int (e->keys->dim), build_address (akeys));
2855 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2856 size_int (e->values->dim),
2857 build_address (avals));
2858
2859 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
2860 build_typeinfo (e->loc, ta), keys, vals);
2861
2862 /* Return an associative array pointed to by MEM. */
2863 tree aatype = build_ctype (ta);
2864 vec<constructor_elt, va_gc> *ce = NULL;
2865 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2866
2867 this->result_ = build_nop (build_ctype (e->type),
2868 build_constructor (aatype, ce));
2869 }
2870
2871 /* Build a struct literal. */
2872
visit(StructLiteralExp * e)2873 void visit (StructLiteralExp *e)
2874 {
2875 /* Handle empty struct literals. */
2876 if (e->elements == NULL || e->sd->fields.dim == 0)
2877 {
2878 this->result_ = build_constructor (build_ctype (e->type), NULL);
2879 return;
2880 }
2881
2882 /* Building sinit trees are delayed until after frontend semantic
2883 processing has complete. Build the static initializer now. */
2884 if (e->useStaticInit && !this->constp_)
2885 {
2886 this->result_ = aggregate_initializer_decl (e->sd);
2887 return;
2888 }
2889
2890 /* Build a constructor that assigns the expressions in ELEMENTS
2891 at each field index that has been filled in. */
2892 vec<constructor_elt, va_gc> *ve = NULL;
2893 tree saved_elems = NULL_TREE;
2894
2895 /* CTFE may fill the hidden pointer by NullExp. */
2896 gcc_assert (e->elements->dim <= e->sd->fields.dim);
2897
2898 Type *tb = e->type->toBasetype ();
2899 gcc_assert (tb->ty == Tstruct);
2900
2901 for (size_t i = 0; i < e->elements->dim; i++)
2902 {
2903 Expression *exp = (*e->elements)[i];
2904 if (!exp)
2905 continue;
2906
2907 VarDeclaration *field = e->sd->fields[i];
2908 Type *type = exp->type->toBasetype ();
2909 Type *ftype = field->type->toBasetype ();
2910 tree value = NULL_TREE;
2911
2912 if (ftype->ty == Tsarray && !same_type_p (type, ftype))
2913 {
2914 /* Initialize a static array with a single element. */
2915 tree elem = build_expr (exp, this->constp_);
2916 elem = d_save_expr (elem);
2917
2918 if (initializer_zerop (elem))
2919 value = build_constructor (build_ctype (ftype), NULL);
2920 else
2921 value = build_array_from_val (ftype, elem);
2922 }
2923 else
2924 {
2925 value = convert_expr (build_expr (exp, this->constp_),
2926 exp->type, field->type);
2927 }
2928
2929 /* Split construction of values out of the constructor. */
2930 tree init = stabilize_expr (&value);
2931 if (init != NULL_TREE)
2932 saved_elems = compound_expr (saved_elems, init);
2933
2934 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2935 }
2936
2937 /* Maybe setup hidden pointer to outer scope context. */
2938 if (e->sd->isNested () && e->elements->dim != e->sd->fields.dim
2939 && this->constp_ == false)
2940 {
2941 tree field = get_symbol_decl (e->sd->vthis);
2942 tree value = build_vthis (e->sd);
2943 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2944 gcc_assert (e->useStaticInit == false);
2945 }
2946
2947 /* Build a constructor in the correct shape of the aggregate type. */
2948 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2949
2950 /* Nothing more to do for constant literals. */
2951 if (this->constp_)
2952 {
2953 /* If the struct literal is a valid for static data. */
2954 if (TREE_CONSTANT (ctor)
2955 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2956 TREE_STATIC (ctor) = 1;
2957
2958 this->result_ = compound_expr (saved_elems, ctor);
2959 return;
2960 }
2961
2962 if (e->sym != NULL)
2963 {
2964 tree var = build_deref (e->sym);
2965 ctor = compound_expr (modify_expr (var, ctor), var);
2966 this->result_ = compound_expr (saved_elems, ctor);
2967 }
2968 else if (e->sd->isUnionDeclaration ())
2969 {
2970 /* For unions, use memset to fill holes in the object. */
2971 tree var = build_local_temp (TREE_TYPE (ctor));
2972 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
2973 tree init = build_call_expr (tmemset, 3, build_address (var),
2974 size_zero_node,
2975 size_int (e->sd->structsize));
2976
2977 init = compound_expr (init, saved_elems);
2978 init = compound_expr (init, modify_expr (var, ctor));
2979 this->result_ = compound_expr (init, var);
2980 }
2981 else
2982 this->result_ = compound_expr (saved_elems, ctor);
2983 }
2984
2985 /* Build a null literal. */
2986
visit(NullExp * e)2987 void visit (NullExp *e)
2988 {
2989 this->result_ = build_typeof_null_value (e->type);
2990 }
2991
2992 /* Build a vector literal. */
2993
visit(VectorExp * e)2994 void visit (VectorExp *e)
2995 {
2996 tree type = build_ctype (e->type);
2997 tree etype = TREE_TYPE (type);
2998
2999 /* First handle array literal expressions. */
3000 if (e->e1->op == TOKarrayliteral)
3001 {
3002 ArrayLiteralExp *ale = ((ArrayLiteralExp *) e->e1);
3003 vec<constructor_elt, va_gc> *elms = NULL;
3004 bool constant_p = true;
3005
3006 vec_safe_reserve (elms, ale->elements->dim);
3007 for (size_t i = 0; i < ale->elements->dim; i++)
3008 {
3009 Expression *expr = ale->getElement (i);
3010 tree value = d_convert (etype, build_expr (expr, this->constp_));
3011 if (!CONSTANT_CLASS_P (value))
3012 constant_p = false;
3013
3014 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
3015 }
3016
3017 /* Build a VECTOR_CST from a constant vector constructor. */
3018 if (constant_p)
3019 this->result_ = build_vector_from_ctor (type, elms);
3020 else
3021 this->result_ = build_constructor (type, elms);
3022 }
3023 else
3024 {
3025 /* Build constructor from single value. */
3026 tree val = d_convert (etype, build_expr (e->e1, this->constp_));
3027 this->result_ = build_vector_from_val (type, val);
3028 }
3029 }
3030
3031 /* Build a static array representation of a vector expression. */
3032
visit(VectorArrayExp * e)3033 void visit (VectorArrayExp *e)
3034 {
3035 this->result_ = convert_expr (build_expr (e->e1, this->constp_),
3036 e->e1->type, e->type);
3037 }
3038
3039 /* Build a static class literal, return its reference. */
3040
visit(ClassReferenceExp * e)3041 void visit (ClassReferenceExp *e)
3042 {
3043 /* The result of build_new_class_expr is a RECORD_TYPE, we want
3044 the reference. */
3045 tree var = build_address (build_new_class_expr (e));
3046
3047 /* If the type of this literal is an interface, the we must add the
3048 interface offset to symbol. */
3049 if (this->constp_)
3050 {
3051 TypeClass *tc = (TypeClass *) e->type;
3052 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
3053
3054 if (to != NULL)
3055 {
3056 ClassDeclaration *from = e->originalClass ();
3057 int offset = 0;
3058
3059 gcc_assert (to->isBaseOf (from, &offset) != 0);
3060
3061 if (offset != 0)
3062 var = build_offset (var, size_int (offset));
3063 }
3064 }
3065
3066 this->result_ = var;
3067 }
3068
3069 /* These expressions are mainly just a placeholders in the frontend.
3070 We shouldn't see them here. */
3071
visit(ScopeExp * e)3072 void visit (ScopeExp *e)
3073 {
3074 error_at (make_location_t (e->loc), "%qs is not an expression",
3075 e->toChars ());
3076 this->result_ = error_mark_node;
3077 }
3078
visit(TypeExp * e)3079 void visit (TypeExp *e)
3080 {
3081 error_at (make_location_t (e->loc), "type %qs is not an expression",
3082 e->toChars ());
3083 this->result_ = error_mark_node;
3084 }
3085 };
3086
3087
3088 /* Main entry point for ExprVisitor interface to generate code for
3089 the Expression AST class E. If CONST_P is true, then E is a
3090 constant expression. */
3091
3092 tree
build_expr(Expression * e,bool const_p)3093 build_expr (Expression *e, bool const_p)
3094 {
3095 ExprVisitor v = ExprVisitor (const_p);
3096 location_t saved_location = input_location;
3097
3098 input_location = make_location_t (e->loc);
3099 e->accept (&v);
3100 tree expr = v.result ();
3101 input_location = saved_location;
3102
3103 /* Check if initializer expression is valid constant. */
3104 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3105 {
3106 error_at (make_location_t (e->loc), "non-constant expression %qs",
3107 e->toChars ());
3108 return error_mark_node;
3109 }
3110
3111 return expr;
3112 }
3113
3114 /* Same as build_expr, but also calls destructors on any temporaries. */
3115
3116 tree
build_expr_dtor(Expression * e)3117 build_expr_dtor (Expression *e)
3118 {
3119 /* Codegen can be improved by determining if no exceptions can be thrown
3120 between the ctor and dtor, and eliminating the ctor and dtor. */
3121 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3122 tree result = build_expr (e);
3123
3124 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3125 {
3126 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3127 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3128 }
3129
3130 return result;
3131 }
3132
3133 /* Same as build_expr_dtor, but handles the result of E as a return value. */
3134
3135 tree
build_return_dtor(Expression * e,Type * type,TypeFunction * tf)3136 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3137 {
3138 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3139 tree result = build_expr (e);
3140
3141 /* Convert for initializing the DECL_RESULT. */
3142 if (tf->isref)
3143 {
3144 /* If we are returning a reference, take the address. */
3145 result = convert_expr (result, e->type, type);
3146 result = build_address (result);
3147 }
3148 else
3149 result = convert_for_rvalue (result, e->type, type);
3150
3151 /* The decl to store the return expression. */
3152 tree decl = DECL_RESULT (cfun->decl);
3153
3154 /* Split comma expressions, so that the result is returned directly. */
3155 tree expr = stabilize_expr (&result);
3156 result = build_assign (INIT_EXPR, decl, result);
3157 result = compound_expr (expr, return_expr (result));
3158
3159 /* May nest the return expression inside the try/finally expression. */
3160 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3161 {
3162 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3163 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3164 }
3165
3166 return result;
3167 }
3168
3169