]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/expr.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / d / expr.cc
CommitLineData
b4c522fa 1/* expr.cc -- Lower D frontend expressions to GCC trees.
7adcbafe 2 Copyright (C) 2015-2022 Free Software Foundation, Inc.
b4c522fa
IB
3
4GCC is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 3, or (at your option)
7any later version.
8
9GCC is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along 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
dc60d676 46/* Determine if type T is a struct that has a postblit. */
b4c522fa 47
dc60d676
IB
48static bool
49needs_postblit (Type *t)
b4c522fa 50{
dc60d676 51 t = t->baseElemOf ();
b4c522fa 52
dc60d676
IB
53 if (TypeStruct *ts = t->isTypeStruct ())
54 {
55 if (ts->sym->postblit)
56 return true;
57 }
b4c522fa 58
dc60d676
IB
59 return false;
60}
b4c522fa 61
dc60d676 62/* Determine if type T is a struct that has a destructor. */
b4c522fa 63
dc60d676
IB
64static bool
65needs_dtor (Type *t)
66{
67 t = t->baseElemOf ();
b4c522fa 68
dc60d676
IB
69 if (TypeStruct *ts = t->isTypeStruct ())
70 {
71 if (ts->sym->dtor)
72 return true;
73 }
b4c522fa 74
dc60d676
IB
75 return false;
76}
b4c522fa 77
dc60d676 78/* Determine if expression E is a suitable lvalue. */
b4c522fa 79
dc60d676
IB
80static bool
81lvalue_p (Expression *e)
82{
83 SliceExp *se = e->isSliceExp ();
84 if (se != NULL && se->e1->isLvalue ())
85 return true;
b4c522fa 86
dc60d676
IB
87 CastExp *ce = e->isCastExp ();
88 if (ce != NULL && ce->e1->isLvalue ())
89 return true;
b4c522fa 90
9c7d5e88 91 return (e->op != EXP::slice && e->isLvalue ());
dc60d676 92}
b4c522fa 93
dc60d676
IB
94/* Build an expression of code CODE, data type TYPE, and operands ARG0 and
95 ARG1. Perform relevant conversions needed for correct code operations. */
b4c522fa 96
dc60d676
IB
97static tree
98binary_op (tree_code code, tree type, tree arg0, tree arg1)
99{
100 tree t0 = TREE_TYPE (arg0);
101 tree t1 = TREE_TYPE (arg1);
102 tree ret = NULL_TREE;
103
dc60d676
IB
104 /* Deal with float mod expressions immediately. */
105 if (code == FLOAT_MOD_EXPR)
106 return build_float_modulus (type, arg0, arg1);
107
108 if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
109 return build_nop (type, build_offset_op (code, arg0, arg1));
110
111 if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
112 return build_nop (type, build_offset_op (code, arg1, arg0));
113
114 if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
115 {
116 gcc_assert (code == MINUS_EXPR);
117 tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
118
119 /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
120 pointers. If some platform cannot provide that, or has a larger
121 ptrdiff_type to support differences larger than half the address
122 space, cast the pointers to some larger integer type and do the
123 computations in that type. */
124 if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
125 ret = fold_build2 (MINUS_EXPR, ptrtype,
126 d_convert (ptrtype, arg0),
127 d_convert (ptrtype, arg1));
128 else
129 ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
130 }
dc60d676
IB
131 else
132 {
133 /* If the operation needs excess precision. */
134 tree eptype = excess_precision_type (type);
135 if (eptype != NULL_TREE)
136 {
137 arg0 = d_convert (eptype, arg0);
138 arg1 = d_convert (eptype, arg1);
139 }
140 else
141 {
142 /* Front-end does not do this conversion and GCC does not
143 always do it right. */
144 if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
145 arg1 = d_convert (t0, arg1);
146 else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
147 arg0 = d_convert (t1, arg0);
148
149 eptype = type;
150 }
151
54ec50ba 152 ret = build2 (code, eptype, arg0, arg1);
dc60d676
IB
153 }
154
155 return d_convert (type, ret);
156}
157
158/* Build a binary expression of code CODE, assigning the result into E1. */
159
160static tree
161binop_assignment (tree_code code, Expression *e1, Expression *e2)
162{
163 /* Skip casts for lhs assignment. */
164 Expression *e1b = e1;
9c7d5e88 165 while (e1b->op == EXP::cast_)
dc60d676
IB
166 {
167 CastExp *ce = e1b->isCastExp ();
168 gcc_assert (same_type_p (ce->type, ce->to));
169 e1b = ce->e1;
170 }
171
172 /* Stabilize LHS for assignment. */
173 tree lhs = build_expr (e1b);
174 tree lexpr = stabilize_expr (&lhs);
175
176 /* The LHS expression could be an assignment, to which its operation gets
177 lost during gimplification. */
178 if (TREE_CODE (lhs) == MODIFY_EXPR)
179 {
180 /* If LHS has side effects, call stabilize_reference on it, so it can
181 be evaluated multiple times. */
182 if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
183 lhs = build_assign (MODIFY_EXPR,
184 stabilize_reference (TREE_OPERAND (lhs, 0)),
185 TREE_OPERAND (lhs, 1));
186
187 lexpr = compound_expr (lexpr, lhs);
188 lhs = TREE_OPERAND (lhs, 0);
189 }
190
191 lhs = stabilize_reference (lhs);
192
193 /* Save RHS, to ensure that the expression is evaluated before LHS. */
194 tree rhs = build_expr (e2);
195 tree rexpr = d_save_expr (rhs);
196
197 rhs = binary_op (code, build_ctype (e1->type),
198 convert_expr (lhs, e1b->type, e1->type), rexpr);
199 if (TREE_SIDE_EFFECTS (rhs))
200 rhs = compound_expr (rexpr, rhs);
201
202 tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
203 return compound_expr (lexpr, expr);
204}
b4c522fa 205
dc60d676
IB
206/* Implements the visitor interface to build the GCC trees of all Expression
207 AST classes emitted from the D Front-end.
208 All visit methods accept one parameter E, which holds the frontend AST
209 of the expression to compile. They also don't return any value, instead
210 generated code is cached in RESULT_ and returned from the caller. */
b4c522fa 211
dc60d676
IB
212class ExprVisitor : public Visitor
213{
214 using Visitor::visit;
b4c522fa 215
dc60d676
IB
216 tree result_;
217 bool constp_;
2ac51bdf 218 bool literalp_;
b4c522fa
IB
219
220public:
2ac51bdf 221 ExprVisitor (bool constp, bool literalp)
b4c522fa
IB
222 {
223 this->result_ = NULL_TREE;
224 this->constp_ = constp;
2ac51bdf 225 this->literalp_ = literalp;
b4c522fa
IB
226 }
227
228 tree result (void)
229 {
230 return this->result_;
231 }
232
233 /* Visitor interfaces, each Expression class should have
234 overridden the default. */
235
236 void visit (Expression *)
237 {
238 gcc_unreachable ();
239 }
240
241 /* Build a conditional expression. If either the second or third
242 expression is void, then the resulting type is void. Otherwise
243 they are implicitly converted to a common type. */
244
245 void visit (CondExp *e)
246 {
247 tree cond = convert_for_condition (build_expr (e->econd),
248 e->econd->type);
249 tree t1 = build_expr (e->e1);
250 tree t2 = build_expr (e->e2);
251
5fee5ec3 252 if (e->type->ty != TY::Tvoid)
b4c522fa
IB
253 {
254 t1 = convert_expr (t1, e->e1->type, e->type);
255 t2 = convert_expr (t2, e->e2->type, e->type);
256 }
257
258 this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
259 }
260
261 /* Build an identity comparison expression. Operands go through the
262 usual conversions to bring them to a common type before comparison.
263 The result type is bool. */
264
265 void visit (IdentityExp *e)
266 {
9c7d5e88 267 tree_code code = (e->op == EXP::identity) ? EQ_EXPR : NE_EXPR;
b4c522fa
IB
268 Type *tb1 = e->e1->type->toBasetype ();
269 Type *tb2 = e->e2->type->toBasetype ();
270
5fee5ec3
IB
271 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
272 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
b4c522fa
IB
273 {
274 /* For static and dynamic arrays, identity is defined as referring to
275 the same array elements and the same number of elements. */
276 tree t1 = d_array_convert (e->e1);
277 tree t2 = d_array_convert (e->e2);
278 this->result_ = d_convert (build_ctype (e->type),
279 build_boolop (code, t1, t2));
280 }
5fee5ec3 281 else if (tb1->isfloating () && tb1->ty != TY::Tvector)
b4c522fa
IB
282 {
283 /* For floating-point values, identity is defined as the bits in the
284 operands being identical. */
285 tree t1 = d_save_expr (build_expr (e->e1));
286 tree t2 = d_save_expr (build_expr (e->e2));
287
70d87497
JP
288 if (!tb1->iscomplex ())
289 this->result_ = build_float_identity (code, t1, t2);
290 else
291 {
292 /* Compare the real and imaginary parts separately. */
293 tree req = build_float_identity (code, real_part (t1),
294 real_part (t2));
295 tree ieq = build_float_identity (code, imaginary_part (t1),
296 imaginary_part (t2));
297
298 if (code == EQ_EXPR)
299 this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
300 else
301 this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
302 }
b4c522fa 303 }
89fdaf5a 304 else if (TypeStruct *ts = tb1->isTypeStruct ())
b4c522fa
IB
305 {
306 /* For struct objects, identity is defined as bits in operands being
307 identical also. Alignment holes in structs are ignored. */
b4c522fa
IB
308 tree t1 = build_expr (e->e1);
309 tree t2 = build_expr (e->e2);
310
311 gcc_assert (same_type_p (tb1, tb2));
312
89fdaf5a 313 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
b4c522fa
IB
314 }
315 else
316 {
317 /* For operands of other types, identity is defined as being the
318 same as equality expressions. */
319 tree t1 = build_expr (e->e1);
320 tree t2 = build_expr (e->e2);
321 this->result_ = d_convert (build_ctype (e->type),
322 build_boolop (code, t1, t2));
323 }
324 }
325
326 /* Build an equality expression, which compare the two operands for either
327 equality or inequality. Operands go through the usual conversions to bring
328 them to a common type before comparison. The result type is bool. */
329
330 void visit (EqualExp *e)
331 {
332 Type *tb1 = e->e1->type->toBasetype ();
333 Type *tb2 = e->e2->type->toBasetype ();
9c7d5e88 334 tree_code code = (e->op == EXP::equal) ? EQ_EXPR : NE_EXPR;
b4c522fa 335
5fee5ec3
IB
336 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
337 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
b4c522fa
IB
338 {
339 /* For static and dynamic arrays, equality is defined as the lengths of
340 the arrays matching, and all the elements are equal. */
341 Type *t1elem = tb1->nextOf ()->toBasetype ();
342 Type *t2elem = tb1->nextOf ()->toBasetype ();
343
344 /* Check if comparisons of arrays can be optimized using memcmp.
345 This will inline EQ expressions as:
346 e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
347 Or when generating a NE expression:
348 e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */
5fee5ec3
IB
349 if ((t1elem->isintegral () || t1elem->ty == TY::Tvoid
350 || (t1elem->ty == TY::Tstruct
351 && !t1elem->isTypeStruct ()->sym->xeq))
b4c522fa
IB
352 && t1elem->ty == t2elem->ty)
353 {
354 tree t1 = d_array_convert (e->e1);
355 tree t2 = d_array_convert (e->e2);
356 tree result;
357
358 /* Make temporaries to prevent multiple evaluations. */
359 tree t1saved = d_save_expr (t1);
360 tree t2saved = d_save_expr (t2);
361
362 /* Length of arrays, for comparisons done before calling memcmp. */
363 tree t1len = d_array_length (t1saved);
364 tree t2len = d_array_length (t2saved);
365
366 /* Reference to array data. */
367 tree t1ptr = d_array_ptr (t1saved);
368 tree t2ptr = d_array_ptr (t2saved);
369
370 /* Compare arrays using memcmp if possible, otherwise for structs,
371 each field is compared inline. */
5fee5ec3 372 if (t1elem->ty != TY::Tstruct
89fdaf5a 373 || identity_compare_p (t1elem->isTypeStruct ()->sym))
b4c522fa
IB
374 {
375 tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
b4c522fa 376
ab0edbcb 377 result = build_memcmp_call (t1ptr, t2ptr, size);
b4c522fa
IB
378 result = build_boolop (code, result, integer_zero_node);
379 }
380 else
381 {
89fdaf5a 382 StructDeclaration *sd = t1elem->isTypeStruct ()->sym;
b4c522fa
IB
383
384 result = build_array_struct_comparison (code, sd, t1len,
385 t1ptr, t2ptr);
386 }
387
388 /* Check array length first before passing to memcmp.
389 For equality expressions, this becomes:
390 (e1.length == 0 || memcmp);
391 Otherwise for inequality:
392 (e1.length != 0 && memcmp); */
393 tree tsizecmp = build_boolop (code, t1len, size_zero_node);
9c7d5e88 394 if (e->op == EXP::equal)
b4c522fa
IB
395 result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
396 else
397 result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
398
399 /* Finally, check if lengths of both arrays match if dynamic.
400 The frontend should have already guaranteed that static arrays
401 have same size. */
5fee5ec3 402 if (tb1->ty == TY::Tsarray && tb2->ty == TY::Tsarray)
b4c522fa
IB
403 gcc_assert (tb1->size () == tb2->size ());
404 else
405 {
406 tree tlencmp = build_boolop (code, t1len, t2len);
9c7d5e88 407 if (e->op == EXP::equal)
b4c522fa
IB
408 result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
409 else
410 result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
411 }
412
413 /* Ensure left-to-right order of evaluation. */
414 if (TREE_SIDE_EFFECTS (t2))
415 result = compound_expr (t2saved, result);
416
417 if (TREE_SIDE_EFFECTS (t1))
418 result = compound_expr (t1saved, result);
419
420 this->result_ = result;
421 }
422 else
423 {
424 /* Use _adEq2() to compare each element. */
425 Type *t1array = t1elem->arrayOf ();
426 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
427 d_array_convert (e->e1),
428 d_array_convert (e->e2),
c0aebc60 429 build_typeinfo (e->loc, t1array));
b4c522fa 430
9c7d5e88 431 if (e->op == EXP::notEqual)
b4c522fa
IB
432 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
433
434 this->result_ = result;
435 }
436 }
89fdaf5a 437 else if (TypeStruct *ts = tb1->isTypeStruct ())
b4c522fa
IB
438 {
439 /* Equality for struct objects means the logical product of all
440 equality results of the corresponding object fields. */
b4c522fa
IB
441 tree t1 = build_expr (e->e1);
442 tree t2 = build_expr (e->e2);
443
444 gcc_assert (same_type_p (tb1, tb2));
445
89fdaf5a 446 this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
b4c522fa 447 }
5fee5ec3 448 else if (tb1->ty == TY::Taarray && tb2->ty == TY::Taarray)
b4c522fa
IB
449 {
450 /* Use _aaEqual() for associative arrays. */
b4c522fa 451 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
89fdaf5a 452 build_typeinfo (e->loc, tb1),
b4c522fa
IB
453 build_expr (e->e1),
454 build_expr (e->e2));
455
9c7d5e88 456 if (e->op == EXP::notEqual)
b4c522fa
IB
457 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
458
459 this->result_ = result;
460 }
461 else
462 {
463 /* For operands of other types, equality is defined as the bit pattern
464 of the type matches exactly. */
465 tree t1 = build_expr (e->e1);
466 tree t2 = build_expr (e->e2);
467
468 this->result_ = d_convert (build_ctype (e->type),
469 build_boolop (code, t1, t2));
470 }
471 }
472
473 /* Build an `in' expression. This is a condition to see if an element
474 exists in an associative array. The result is a pointer to the
475 element, or null if false. */
476
477 void visit (InExp *e)
478 {
479 Type *tb2 = e->e2->type->toBasetype ();
89fdaf5a 480 Type *tkey = tb2->isTypeAArray ()->index->toBasetype ();
b4c522fa
IB
481 tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
482
483 /* Build a call to _aaInX(). */
484 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
485 build_expr (e->e2),
c0aebc60 486 build_typeinfo (e->loc, tkey),
b4c522fa
IB
487 build_address (key));
488 }
489
490 /* Build a relational expression. The result type is bool. */
491
492 void visit (CmpExp *e)
493 {
494 Type *tb1 = e->e1->type->toBasetype ();
495 Type *tb2 = e->e2->type->toBasetype ();
496
497 tree result;
498 tree_code code;
499
500 switch (e->op)
501 {
9c7d5e88 502 case EXP::lessOrEqual:
b4c522fa
IB
503 code = LE_EXPR;
504 break;
505
9c7d5e88 506 case EXP::lessThan:
b4c522fa
IB
507 code = LT_EXPR;
508 break;
509
9c7d5e88 510 case EXP::greaterOrEqual:
b4c522fa
IB
511 code = GE_EXPR;
512 break;
513
9c7d5e88 514 case EXP::greaterThan:
b4c522fa
IB
515 code = GT_EXPR;
516 break;
517
518 default:
519 gcc_unreachable ();
520 }
521
5fee5ec3
IB
522 /* For static and dynamic arrays, the relational op is turned into a
523 library call. It is not lowered during codegen. */
524 if ((tb1->ty == TY::Tsarray || tb1->ty == TY::Tarray)
525 && (tb2->ty == TY::Tsarray || tb2->ty == TY::Tarray))
b4c522fa 526 {
5fee5ec3
IB
527 error ("cannot handle comparison of type %<%s == %s%>",
528 tb1->toChars (), tb2->toChars ());
529 gcc_unreachable ();
b4c522fa
IB
530 }
531
532 /* Simple comparison. */
533 result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
534 this->result_ = d_convert (build_ctype (e->type), result);
535 }
536
49a09af1
IB
537 /* Build a logical `and if' or `or if' expression. If the right operand
538 expression is void, then the resulting type is void. Otherwise the
539 result is bool. */
b4c522fa 540
49a09af1 541 void visit (LogicalExp *e)
b4c522fa 542 {
9c7d5e88 543 tree_code code = (e->op == EXP::andAnd) ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;
49a09af1 544
5fee5ec3 545 if (e->e2->type->toBasetype ()->ty != TY::Tvoid)
b4c522fa
IB
546 {
547 tree t1 = build_expr (e->e1);
548 tree t2 = build_expr (e->e2);
549
550 t1 = convert_for_condition (t1, e->e1->type);
551 t2 = convert_for_condition (t2, e->e2->type);
552
553 this->result_ = d_convert (build_ctype (e->type),
49a09af1 554 build_boolop (code, t1, t2));
b4c522fa
IB
555 }
556 else
557 {
558 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
559 tree t2 = build_expr_dtor (e->e2);
560
49a09af1 561 /* Invert condition for logical or if expression. */
9c7d5e88 562 if (e->op == EXP::orOr)
49a09af1 563 t1 = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);
b4c522fa
IB
564
565 this->result_ = build_condition (build_ctype (e->type),
49a09af1 566 t1, t2, void_node);
b4c522fa
IB
567 }
568 }
569
570 /* Build a binary operand expression. Operands go through usual arithmetic
571 conversions to bring them to a common type before evaluating. */
572
573 void visit (BinExp *e)
574 {
575 tree_code code;
576
577 switch (e->op)
578 {
9c7d5e88
IB
579 case EXP::add:
580 case EXP::min:
b4c522fa
IB
581 if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
582 || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
583 {
584 /* If the result is complex, then we can shortcut binary_op.
585 Frontend should have already validated types and sizes. */
586 tree t1 = build_expr (e->e1);
587 tree t2 = build_expr (e->e2);
588
9c7d5e88 589 if (e->op == EXP::min)
b4c522fa
IB
590 t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
591
592 if (e->e1->type->isreal ())
593 this->result_ = complex_expr (build_ctype (e->type), t1, t2);
594 else
595 this->result_ = complex_expr (build_ctype (e->type), t2, t1);
596
597 return;
598 }
599 else
9c7d5e88 600 code = (e->op == EXP::add)
b4c522fa
IB
601 ? PLUS_EXPR : MINUS_EXPR;
602 break;
603
9c7d5e88 604 case EXP::mul:
b4c522fa
IB
605 code = MULT_EXPR;
606 break;
607
9c7d5e88 608 case EXP::div:
3a3fda11
IB
609 /* Determine if the div expression is a lowered pointer diff operation.
610 The front-end rewrites `(p1 - p2)' into `(p1 - p2) / stride'. */
611 if (MinExp *me = e->e1->isMinExp ())
612 {
5fee5ec3
IB
613 if (me->e1->type->ty == TY::Tpointer
614 && me->e2->type->ty == TY::Tpointer
9c7d5e88 615 && e->e2->op == EXP::int64)
3a3fda11
IB
616 {
617 code = EXACT_DIV_EXPR;
618 break;
619 }
620 }
621
b4c522fa
IB
622 code = e->e1->type->isintegral ()
623 ? TRUNC_DIV_EXPR : RDIV_EXPR;
624 break;
625
9c7d5e88 626 case EXP::mod:
b4c522fa
IB
627 code = e->e1->type->isfloating ()
628 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
629 break;
630
9c7d5e88 631 case EXP::and_:
b4c522fa
IB
632 code = BIT_AND_EXPR;
633 break;
634
9c7d5e88 635 case EXP::or_:
b4c522fa
IB
636 code = BIT_IOR_EXPR;
637 break;
638
9c7d5e88 639 case EXP::xor_:
b4c522fa
IB
640 code = BIT_XOR_EXPR;
641 break;
642
9c7d5e88 643 case EXP::leftShift:
b4c522fa
IB
644 code = LSHIFT_EXPR;
645 break;
646
9c7d5e88 647 case EXP::rightShift:
b4c522fa
IB
648 code = RSHIFT_EXPR;
649 break;
650
9c7d5e88 651 case EXP::unsignedRightShift:
b4c522fa
IB
652 code = UNSIGNED_RSHIFT_EXPR;
653 break;
654
655 default:
656 gcc_unreachable ();
657 }
658
dc60d676
IB
659 this->result_ = binary_op (code, build_ctype (e->type),
660 build_expr (e->e1), build_expr (e->e2));
b4c522fa
IB
661 }
662
663
664 /* Build a concat expression, which concatenates two or more arrays of the
665 same type, producing a dynamic array with the result. If one operand
666 is an element type, that element is converted to an array of length 1. */
667
668 void visit (CatExp *e)
669 {
670 Type *tb1 = e->e1->type->toBasetype ();
671 Type *tb2 = e->e2->type->toBasetype ();
672 Type *etype;
673
5fee5ec3 674 if (tb1->ty == TY::Tarray || tb1->ty == TY::Tsarray)
b4c522fa
IB
675 etype = tb1->nextOf ();
676 else
677 etype = tb2->nextOf ();
678
b4c522fa
IB
679 tree result;
680
9c7d5e88 681 if (e->e1->op == EXP::concatenate)
b4c522fa
IB
682 {
683 /* Flatten multiple concatenations to an array.
684 So the expression ((a ~ b) ~ c) becomes [a, b, c] */
685 int ndims = 2;
686
9c7d5e88 687 for (Expression *ex = e->e1; ex->op == EXP::concatenate;)
b4c522fa 688 {
9c7d5e88 689 if (ex->op == EXP::concatenate)
b4c522fa 690 {
d873350a 691 ex = ex->isCatExp ()->e1;
b4c522fa
IB
692 ndims++;
693 }
694 }
695
696 /* Store all concatenation args to a temporary byte[][ndims] array. */
697 Type *targselem = Type::tint8->arrayOf ();
0af711e1 698 tree var = build_local_temp (make_array_type (targselem, ndims));
b4c522fa
IB
699
700 /* Loop through each concatenation from right to left. */
af3c19f0 701 vec <constructor_elt, va_gc> *elms = NULL;
b4c522fa
IB
702 CatExp *ce = e;
703 int dim = ndims - 1;
704
705 for (Expression *oe = ce->e2; oe != NULL;
9c7d5e88 706 (ce->e1->op != EXP::concatenate
b4c522fa 707 ? (oe = ce->e1)
d873350a 708 : (ce = ce->e1->isCatExp (), oe = ce->e2)))
b4c522fa 709 {
0af711e1 710 tree arg = d_array_convert (etype, oe);
b4c522fa
IB
711 tree index = size_int (dim);
712 CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));
713
714 /* Finished pushing all arrays. */
715 if (oe == ce->e1)
716 break;
717
718 dim -= 1;
719 }
720
721 /* Check there is no logic bug in constructing byte[][] of arrays. */
722 gcc_assert (dim == 0);
0af711e1
IB
723 tree init = build_constructor (TREE_TYPE (var), elms);
724 var = compound_expr (modify_expr (var, init), var);
b4c522fa
IB
725
726 tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
727 size_int (ndims), build_address (var));
728
729 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
c0aebc60 730 build_typeinfo (e->loc, e->type), arrs);
b4c522fa
IB
731 }
732 else
733 {
734 /* Handle single concatenation (a ~ b). */
735 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
c0aebc60 736 build_typeinfo (e->loc, e->type),
0af711e1
IB
737 d_array_convert (etype, e->e1),
738 d_array_convert (etype, e->e2));
b4c522fa
IB
739 }
740
b4c522fa
IB
741 this->result_ = result;
742 }
743
744 /* Build an assignment operator expression. The right operand is implicitly
745 converted to the type of the left operand, and assigned to it. */
746
747 void visit (BinAssignExp *e)
748 {
749 tree_code code;
750 Expression *e1b = e->e1;
751
752 switch (e->op)
753 {
9c7d5e88 754 case EXP::addAssign:
b4c522fa
IB
755 code = PLUS_EXPR;
756 break;
757
9c7d5e88 758 case EXP::minAssign:
b4c522fa
IB
759 code = MINUS_EXPR;
760 break;
761
9c7d5e88 762 case EXP::mulAssign:
b4c522fa
IB
763 code = MULT_EXPR;
764 break;
765
9c7d5e88 766 case EXP::divAssign:
b4c522fa
IB
767 code = e->e1->type->isintegral ()
768 ? TRUNC_DIV_EXPR : RDIV_EXPR;
769 break;
770
9c7d5e88 771 case EXP::modAssign:
b4c522fa
IB
772 code = e->e1->type->isfloating ()
773 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
774 break;
775
9c7d5e88 776 case EXP::andAssign:
b4c522fa
IB
777 code = BIT_AND_EXPR;
778 break;
779
9c7d5e88 780 case EXP::orAssign:
b4c522fa
IB
781 code = BIT_IOR_EXPR;
782 break;
783
9c7d5e88 784 case EXP::xorAssign:
b4c522fa
IB
785 code = BIT_XOR_EXPR;
786 break;
787
9c7d5e88 788 case EXP::powAssign:
b4c522fa
IB
789 gcc_unreachable ();
790
9c7d5e88 791 case EXP::leftShiftAssign:
b4c522fa
IB
792 code = LSHIFT_EXPR;
793 break;
794
9c7d5e88
IB
795 case EXP::rightShiftAssign:
796 case EXP::unsignedRightShiftAssign:
b4c522fa
IB
797 /* Use the original lhs type before it was promoted. The left operand
798 of `>>>=' does not undergo integral promotions before shifting.
799 Strip off casts just incase anyway. */
9c7d5e88 800 while (e1b->op == EXP::cast_)
b4c522fa 801 {
d873350a 802 CastExp *ce = e1b->isCastExp ();
b4c522fa
IB
803 gcc_assert (same_type_p (ce->type, ce->to));
804 e1b = ce->e1;
805 }
9c7d5e88 806 code = (e->op == EXP::rightShiftAssign) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
b4c522fa
IB
807 break;
808
809 default:
810 gcc_unreachable ();
811 }
812
dc60d676 813 tree exp = binop_assignment (code, e1b, e->e2);
b4c522fa
IB
814 this->result_ = convert_expr (exp, e1b->type, e->type);
815 }
816
817 /* Build a concat assignment expression. The right operand is appended
d5029d45 818 to the left operand. */
b4c522fa
IB
819
820 void visit (CatAssignExp *e)
821 {
822 Type *tb1 = e->e1->type->toBasetype ();
823 Type *tb2 = e->e2->type->toBasetype ();
824 Type *etype = tb1->nextOf ()->toBasetype ();
825
23045f8b
IB
826 /* Save the address of `e1', so it can be evaluated first.
827 As all D run-time library functions for concat assignments update `e1'
828 in-place and then return its value, the saved address can also be used as
829 the result of this expression as well. */
830 tree lhs = build_expr (e->e1);
831 tree lexpr = stabilize_expr (&lhs);
832 tree ptr = d_save_expr (build_address (lhs));
833 tree result = NULL_TREE;
834
5fee5ec3
IB
835 if (tb1->ty == TY::Tarray && tb2->ty == TY::Tdchar
836 && (etype->ty == TY::Tchar || etype->ty == TY::Twchar))
b4c522fa 837 {
23045f8b
IB
838 /* Append a dchar to a char[] or wchar[]:
839 The assignment is handled by the D run-time library, so only
840 need to call `_d_arrayappend[cw]d(&e1, e2)' */
5fee5ec3 841 libcall_fn libcall = (etype->ty == TY::Tchar)
b4c522fa
IB
842 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
843
23045f8b
IB
844 result = build_libcall (libcall, e->type, 2,
845 ptr, build_expr (e->e2));
b4c522fa
IB
846 }
847 else
848 {
5fee5ec3 849 gcc_assert (tb1->ty == TY::Tarray || tb2->ty == TY::Tsarray);
b4c522fa 850
5fee5ec3 851 if ((tb2->ty == TY::Tarray || tb2->ty == TY::Tsarray)
b4c522fa
IB
852 && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
853 {
23045f8b
IB
854 /* Append an array to another array:
855 The assignment is handled by the D run-time library, so only
856 need to call `_d_arrayappendT(ti, &e1, e2)' */
857 result = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
858 build_typeinfo (e->loc, e->type),
859 ptr, d_array_convert (e->e2));
b4c522fa
IB
860 }
861 else if (same_type_p (etype, tb2))
862 {
23045f8b
IB
863 /* Append an element to an array:
864 The assignment is generated inline, so need to handle temporaries
865 here, and ensure that they are evaluated in the correct order.
866
867 The generated code should end up being equivalent to:
868 _d_arrayappendcTX(ti, &e1, 1)[e1.length - 1] = e2
869 */
870 tree callexp = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
871 build_typeinfo (e->loc, e->type),
872 ptr, size_one_node);
873 callexp = d_save_expr (callexp);
b4c522fa
IB
874
875 /* Assign e2 to last element. */
23045f8b 876 tree offexp = d_array_length (callexp);
b4c522fa
IB
877 offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
878 offexp, size_one_node);
b4c522fa 879
23045f8b 880 tree ptrexp = d_array_ptr (callexp);
b4c522fa
IB
881 ptrexp = void_okay_p (ptrexp);
882 ptrexp = build_array_index (ptrexp, offexp);
883
884 /* Evaluate expression before appending. */
23045f8b
IB
885 tree rhs = build_expr (e->e2);
886 tree rexpr = stabilize_expr (&rhs);
798bdfa0 887
23045f8b
IB
888 if (TREE_CODE (rhs) == CALL_EXPR)
889 rhs = force_target_expr (rhs);
b4c522fa 890
23045f8b
IB
891 result = modify_expr (build_deref (ptrexp), rhs);
892 result = compound_expr (rexpr, result);
b4c522fa
IB
893 }
894 else
895 gcc_unreachable ();
896 }
23045f8b
IB
897
898 /* Construct in order: ptr = &e1, _d_arrayappend(ptr, e2), *ptr; */
899 result = compound_expr (compound_expr (lexpr, ptr), result);
900 this->result_ = compound_expr (result, build_deref (ptr));
b4c522fa
IB
901 }
902
903 /* Build an assignment expression. The right operand is implicitly
904 converted to the type of the left operand, and assigned to it. */
905
906 void visit (AssignExp *e)
907 {
908 /* First, handle special assignment semantics. */
909
910 /* Look for array.length = n; */
9c7d5e88 911 if (e->e1->op == EXP::arrayLength)
b4c522fa 912 {
5fee5ec3
IB
913 /* This case should have been rewritten to `_d_arraysetlengthT` in the
914 semantic phase. */
915 gcc_unreachable ();
b4c522fa
IB
916 }
917
918 /* Look for array[] = n; */
9c7d5e88 919 if (e->e1->op == EXP::slice)
b4c522fa 920 {
d873350a 921 SliceExp *se = e->e1->isSliceExp ();
b4c522fa
IB
922 Type *stype = se->e1->type->toBasetype ();
923 Type *etype = stype->nextOf ()->toBasetype ();
924
925 /* Determine if we need to run postblit or dtor. */
dc60d676
IB
926 bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
927 bool destructor = needs_dtor (etype);
b4c522fa 928
5fee5ec3 929 if (e->memset == MemorySet::blockAssign)
b4c522fa
IB
930 {
931 /* Set a range of elements to one value. */
5fee5ec3 932 tree t1 = build_expr (e->e1);
b4c522fa
IB
933 tree t2 = build_expr (e->e2);
934 tree result;
935
5fee5ec3
IB
936 /* Extract any array bounds checks from the slice expression. */
937 tree init = stabilize_expr (&t1);
938 t1 = d_save_expr (t1);
939
9c7d5e88 940 if ((postblit || destructor) && e->op != EXP::blit)
b4c522fa 941 {
9c7d5e88
IB
942 /* Need to call postblit/destructor as part of assignment.
943 Construction has already been handled by the front-end. */
944 gcc_assert (e->op != EXP::construct);
945
b4c522fa 946 /* So we can call postblits on const/immutable objects. */
c0aebc60
IB
947 Type *tm = etype->unSharedOf ()->mutableOf ();
948 tree ti = build_typeinfo (e->loc, tm);
b4c522fa 949
9c7d5e88
IB
950 /* Generate: _d_arraysetassign (t1.ptr, &t2, t1.length, ti); */
951 result = build_libcall (LIBCALL_ARRAYSETASSIGN, Type::tvoid, 4,
5fee5ec3
IB
952 d_array_ptr (t1),
953 build_address (t2),
954 d_array_length (t1), ti);
b4c522fa 955 }
5fee5ec3 956 else if (integer_zerop (t2))
b4c522fa 957 {
b4c522fa
IB
958 tree size = size_mult_expr (d_array_length (t1),
959 size_int (etype->size ()));
ab0edbcb 960 result = build_memset_call (d_array_ptr (t1), size);
b4c522fa
IB
961 }
962 else
963 result = build_array_set (d_array_ptr (t1),
964 d_array_length (t1), t2);
965
5fee5ec3 966 result = compound_expr (init, result);
b4c522fa
IB
967 this->result_ = compound_expr (result, t1);
968 }
969 else
970 {
971 /* Perform a memcpy operation. */
5fee5ec3 972 gcc_assert (e->e2->type->ty != TY::Tpointer);
b4c522fa 973
febd7c43 974 if (!postblit && !destructor)
b4c522fa
IB
975 {
976 tree t1 = d_save_expr (d_array_convert (e->e1));
febd7c43
IB
977 tree t2 = d_save_expr (d_array_convert (e->e2));
978
979 /* References to array data. */
980 tree t1ptr = d_array_ptr (t1);
981 tree t1len = d_array_length (t1);
982 tree t2ptr = d_array_ptr (t2);
983
984 /* Generate: memcpy(to, from, size) */
985 tree size = size_mult_expr (t1len, size_int (etype->size ()));
986 tree result = build_memcpy_call (t1ptr, t2ptr, size);
987
988 /* Insert check that array lengths match and do not overlap. */
989 if (array_bounds_check ())
990 {
991 /* tlencmp = (t1len == t2len) */
992 tree t2len = d_array_length (t2);
993 tree tlencmp = build_boolop (EQ_EXPR, t1len, t2len);
994
995 /* toverlap = (t1ptr + size <= t2ptr
996 || t2ptr + size <= t1ptr) */
997 tree t1ptrcmp = build_boolop (LE_EXPR,
998 build_offset (t1ptr, size),
999 t2ptr);
1000 tree t2ptrcmp = build_boolop (LE_EXPR,
1001 build_offset (t2ptr, size),
1002 t1ptr);
1003 tree toverlap = build_boolop (TRUTH_ORIF_EXPR, t1ptrcmp,
1004 t2ptrcmp);
1005
1006 /* (tlencmp && toverlap) ? memcpy() : _d_arraybounds() */
1007 tree tassert = build_array_bounds_call (e->loc);
1008 tree tboundscheck = build_boolop (TRUTH_ANDIF_EXPR,
1009 tlencmp, toverlap);
1010
1011 result = build_condition (void_type_node, tboundscheck,
1012 result, tassert);
1013 }
1014
b4c522fa
IB
1015 this->result_ = compound_expr (result, t1);
1016 }
9c7d5e88
IB
1017 else if ((postblit || destructor)
1018 && e->op != EXP::blit && e->op != EXP::construct)
b4c522fa 1019 {
9c7d5e88
IB
1020 /* Generate: _d_arrayassign(ti, from, to); */
1021 this->result_ = build_libcall (LIBCALL_ARRAYASSIGN, e->type, 3,
c0aebc60 1022 build_typeinfo (e->loc, etype),
b4c522fa
IB
1023 d_array_convert (e->e2),
1024 d_array_convert (e->e1));
1025 }
1026 else
1027 {
1028 /* Generate: _d_arraycopy() */
1029 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
1030 size_int (etype->size ()),
1031 d_array_convert (e->e2),
1032 d_array_convert (e->e1));
1033 }
1034 }
1035
1036 return;
1037 }
1038
1039 /* Look for reference initializations. */
5fee5ec3 1040 if (e->memset == MemorySet::referenceInit)
b4c522fa 1041 {
9c7d5e88
IB
1042 gcc_assert (e->op == EXP::construct || e->op == EXP::blit);
1043 gcc_assert (e->e1->op == EXP::variable);
b4c522fa 1044
d873350a 1045 Declaration *decl = e->e1->isVarExp ()->var;
b4c522fa
IB
1046 if (decl->storage_class & (STCout | STCref))
1047 {
1048 tree t2 = convert_for_assignment (build_expr (e->e2),
1049 e->e2->type, e->e1->type);
1050 tree t1 = build_expr (e->e1);
1051 /* Want reference to lhs, not indirect ref. */
1052 t1 = TREE_OPERAND (t1, 0);
1053 t2 = build_address (t2);
1054
1055 this->result_ = indirect_ref (build_ctype (e->type),
1056 build_assign (INIT_EXPR, t1, t2));
1057 return;
1058 }
1059 }
1060
1061 /* Other types of assignments that may require post construction. */
1062 Type *tb1 = e->e1->type->toBasetype ();
9c7d5e88 1063 tree_code modifycode = (e->op == EXP::construct) ? INIT_EXPR : MODIFY_EXPR;
b4c522fa
IB
1064
1065 /* Look for struct assignment. */
5fee5ec3 1066 if (tb1->ty == TY::Tstruct)
b4c522fa
IB
1067 {
1068 tree t1 = build_expr (e->e1);
2ac51bdf 1069 tree t2 = convert_for_assignment (build_expr (e->e2, false, true),
b4c522fa 1070 e->e2->type, e->e1->type);
89fdaf5a 1071 StructDeclaration *sd = tb1->isTypeStruct ()->sym;
b4c522fa
IB
1072
1073 /* Look for struct = 0. */
9c7d5e88 1074 if (e->e2->op == EXP::int64)
b4c522fa
IB
1075 {
1076 /* Use memset to fill struct. */
9c7d5e88 1077 gcc_assert (e->op == EXP::blit);
ab0edbcb 1078 tree result = build_memset_call (t1);
b4c522fa
IB
1079
1080 /* Maybe set-up hidden pointer to outer scope context. */
1081 if (sd->isNested ())
1082 {
1083 tree field = get_symbol_decl (sd->vthis);
1084 tree value = build_vthis (sd);
1085
1086 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1087 result = compound_expr (result, vthis_exp);
1088 }
1089
1090 this->result_ = compound_expr (result, t1);
1091 }
1092 else
e8e0acba
IB
1093 {
1094 /* Simple struct literal assignment. */
1095 tree init = NULL_TREE;
1096
1097 /* Fill any alignment holes in the struct using memset. */
9c7d5e88
IB
1098 if ((e->op == EXP::construct
1099 || (e->e2->op == EXP::structLiteral && e->op == EXP::blit))
2ac51bdf
IB
1100 && (sd->isUnionDeclaration () || !identity_compare_p (sd)))
1101 {
1102 t1 = stabilize_reference (t1);
1103 init = build_memset_call (t1);
1104 }
e8e0acba 1105
2ac51bdf
IB
1106 /* Elide generating assignment if init is all zeroes. */
1107 if (init != NULL_TREE && initializer_zerop (t2))
1108 this->result_ = compound_expr (init, t1);
1109 else
1110 {
1111 tree result = build_assign (modifycode, t1, t2);
1112 this->result_ = compound_expr (init, result);
1113 }
e8e0acba 1114 }
b4c522fa
IB
1115
1116 return;
1117 }
1118
1119 /* Look for static array assignment. */
5fee5ec3 1120 if (tb1->ty == TY::Tsarray)
b4c522fa
IB
1121 {
1122 /* Look for array = 0. */
9c7d5e88 1123 if (e->e2->op == EXP::int64)
b4c522fa
IB
1124 {
1125 /* Use memset to fill the array. */
9c7d5e88 1126 gcc_assert (e->op == EXP::blit);
ab0edbcb 1127 this->result_ = build_memset_call (build_expr (e->e1));
b4c522fa
IB
1128 return;
1129 }
1130
1131 Type *etype = tb1->nextOf ();
5fee5ec3 1132 gcc_assert (e->e2->type->toBasetype ()->ty == TY::Tsarray);
b4c522fa
IB
1133
1134 /* Determine if we need to run postblit. */
9c7d5e88
IB
1135 const bool postblit = needs_postblit (etype);
1136 const bool destructor = needs_dtor (etype);
1137 const bool lvalue = lvalue_p (e->e2);
b4c522fa 1138
c18db639
IB
1139 /* Optimize static array assignment with array literal. Even if the
1140 elements in rhs are all rvalues and don't have to call postblits,
1141 this assignment should call dtors on old assigned elements. */
b4c522fa 1142 if ((!postblit && !destructor)
9c7d5e88
IB
1143 || (e->op == EXP::construct && e->e2->op == EXP::arrayLiteral)
1144 || (e->op == EXP::construct && !lvalue && postblit)
1145 || (e->op == EXP::blit || e->e1->type->size () == 0))
b4c522fa
IB
1146 {
1147 tree t1 = build_expr (e->e1);
1148 tree t2 = convert_for_assignment (build_expr (e->e2),
1149 e->e2->type, e->e1->type);
1150
1151 this->result_ = build_assign (modifycode, t1, t2);
1152 return;
1153 }
1154
9c7d5e88
IB
1155 /* All other kinds of lvalue or rvalue static array assignment.
1156 Array construction has already been handled by the front-end. */
1157 gcc_assert (e->op != EXP::construct);
1158
1159 /* Generate: _d_arrayassign_l()
1160 or: _d_arrayassign_r() */
1161 libcall_fn libcall = (lvalue)
1162 ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
1163 tree elembuf = build_local_temp (build_ctype (etype));
5fee5ec3
IB
1164 Type *arrtype = (e->type->ty == TY::Tsarray)
1165 ? etype->arrayOf () : e->type;
9c7d5e88
IB
1166 tree result = build_libcall (libcall, arrtype, 4,
1167 build_typeinfo (e->loc, etype),
1168 d_array_convert (e->e2),
1169 d_array_convert (e->e1),
1170 build_address (elembuf));
b4c522fa
IB
1171
1172 /* Cast the libcall result back to a static array. */
5fee5ec3 1173 if (e->type->ty == TY::Tsarray)
b4c522fa
IB
1174 result = indirect_ref (build_ctype (e->type),
1175 d_array_ptr (result));
1176
1177 this->result_ = result;
1178 return;
1179 }
1180
1181 /* Simple assignment. */
1182 tree t1 = build_expr (e->e1);
1183 tree t2 = convert_for_assignment (build_expr (e->e2),
1184 e->e2->type, e->e1->type);
1185
1186 this->result_ = build_assign (modifycode, t1, t2);
1187 }
1188
1189 /* Build a postfix expression. */
1190
1191 void visit (PostExp *e)
1192 {
1193 tree result;
1194
9c7d5e88 1195 if (e->op == EXP::plusPlus)
b4c522fa
IB
1196 {
1197 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1198 build_expr (e->e1), build_expr (e->e2));
1199 }
9c7d5e88 1200 else if (e->op == EXP::minusMinus)
b4c522fa
IB
1201 {
1202 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1203 build_expr (e->e1), build_expr (e->e2));
1204 }
1205 else
1206 gcc_unreachable ();
1207
1208 TREE_SIDE_EFFECTS (result) = 1;
1209 this->result_ = result;
1210 }
1211
1212 /* Build an index expression. */
1213
1214 void visit (IndexExp *e)
1215 {
1216 Type *tb1 = e->e1->type->toBasetype ();
1217
5fee5ec3 1218 if (tb1->ty == TY::Taarray)
b4c522fa
IB
1219 {
1220 /* Get the key for the associative array. */
89fdaf5a 1221 Type *tkey = tb1->isTypeAArray ()->index->toBasetype ();
b4c522fa
IB
1222 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1223 libcall_fn libcall;
1224 tree tinfo, ptr;
1225
1226 if (e->modifiable)
1227 {
1228 libcall = LIBCALL_AAGETY;
1229 ptr = build_address (build_expr (e->e1));
c0aebc60 1230 tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());
b4c522fa
IB
1231 }
1232 else
1233 {
1234 libcall = LIBCALL_AAGETRVALUEX;
1235 ptr = build_expr (e->e1);
c0aebc60 1236 tinfo = build_typeinfo (e->loc, tkey);
b4c522fa
IB
1237 }
1238
1239 /* Index the associative array. */
1240 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1241 ptr, tinfo,
1242 size_int (tb1->nextOf ()->size ()),
1243 build_address (key));
1244
1245 if (!e->indexIsInBounds && array_bounds_check ())
1246 {
f267a310 1247 tree tassert = build_array_bounds_call (e->loc);
c0aebc60 1248
b4c522fa
IB
1249 result = d_save_expr (result);
1250 result = build_condition (TREE_TYPE (result),
1251 d_truthvalue_conversion (result),
1252 result, tassert);
1253 }
1254
1255 this->result_ = indirect_ref (build_ctype (e->type), result);
1256 }
1257 else
1258 {
1259 /* Get the data pointer and length for static and dynamic arrays. */
1260 tree array = d_save_expr (build_expr (e->e1));
1261 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1262
1263 tree length = NULL_TREE;
5fee5ec3 1264 if (tb1->ty != TY::Tpointer)
b4c522fa
IB
1265 length = get_array_length (array, tb1);
1266 else
1267 gcc_assert (e->lengthVar == NULL);
1268
1269 /* The __dollar variable just becomes a placeholder for the
1270 actual length. */
1271 if (e->lengthVar)
1272 e->lengthVar->csym = length;
1273
1274 /* Generate the index. */
1275 tree index = build_expr (e->e2);
1276
1277 /* If it's a static array and the index is constant, the front end has
1278 already checked the bounds. */
5fee5ec3 1279 if (tb1->ty != TY::Tpointer)
766f5f87 1280 index = build_bounds_index_condition (e, index, length);
b4c522fa
IB
1281
1282 /* Index the .ptr. */
1283 ptr = void_okay_p (ptr);
1284 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1285 build_array_index (ptr, index));
1286 }
1287 }
1288
1289 /* Build a comma expression. The type is the type of the right operand. */
1290
1291 void visit (CommaExp *e)
1292 {
1293 tree t1 = build_expr (e->e1);
1294 tree t2 = build_expr (e->e2);
1295 tree type = e->type ? build_ctype (e->type) : void_type_node;
1296
1297 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1298 }
1299
1300 /* Build an array length expression. Returns the number of elements
1301 in the array. The result is of type size_t. */
1302
1303 void visit (ArrayLengthExp *e)
1304 {
5fee5ec3 1305 if (e->e1->type->toBasetype ()->ty == TY::Tarray)
b4c522fa
IB
1306 this->result_ = d_array_length (build_expr (e->e1));
1307 else
1308 {
1309 /* Static arrays have already been handled by the front-end. */
1310 error ("unexpected type for array length: %qs", e->type->toChars ());
1311 this->result_ = error_mark_node;
1312 }
1313 }
1314
1315 /* Build a delegate pointer expression. This will return the frame
1316 pointer value as a type void*. */
1317
1318 void visit (DelegatePtrExp *e)
1319 {
1320 tree t1 = build_expr (e->e1);
1321 this->result_ = delegate_object (t1);
1322 }
1323
1324 /* Build a delegate function pointer expression. This will return the
1325 function pointer value as a function type. */
1326
1327 void visit (DelegateFuncptrExp *e)
1328 {
1329 tree t1 = build_expr (e->e1);
1330 this->result_ = delegate_method (t1);
1331 }
1332
1333 /* Build a slice expression. */
1334
1335 void visit (SliceExp *e)
1336 {
1337 Type *tb = e->type->toBasetype ();
1338 Type *tb1 = e->e1->type->toBasetype ();
5fee5ec3 1339 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray);
b4c522fa
IB
1340
1341 /* Use convert-to-dynamic-array code if possible. */
1342 if (!e->lwr)
1343 {
1344 tree result = build_expr (e->e1);
5fee5ec3 1345 if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
b4c522fa
IB
1346 result = convert_expr (result, e->e1->type, e->type);
1347
1348 this->result_ = result;
1349 return;
1350 }
1351 else
1352 gcc_assert (e->upr != NULL);
1353
1354 /* Get the data pointer and length for static and dynamic arrays. */
1355 tree array = d_save_expr (build_expr (e->e1));
1356 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1357 tree length = NULL_TREE;
1358
1359 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1360 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
5fee5ec3 1361 if (tb1->ty != TY::Tpointer)
b4c522fa
IB
1362 length = get_array_length (array, tb1);
1363 else
1364 gcc_assert (e->lengthVar == NULL);
1365
1366 /* The __dollar variable just becomes a placeholder for the
1367 actual length. */
1368 if (e->lengthVar)
1369 e->lengthVar->csym = length;
1370
1371 /* Generate upper and lower bounds. */
1372 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1373 tree upr_tree = d_save_expr (build_expr (e->upr));
1374
1375 /* If the upper bound has any side effects, then the lower bound should be
1376 copied to a temporary always. */
1377 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1378 lwr_tree = save_expr (lwr_tree);
1379
1380 /* Adjust the .ptr offset. */
1381 if (!integer_zerop (lwr_tree))
1382 {
1383 tree ptrtype = TREE_TYPE (ptr);
1384 ptr = build_array_index (void_okay_p (ptr), lwr_tree);
1385 ptr = build_nop (ptrtype, ptr);
1386 }
b4c522fa
IB
1387
1388 /* Nothing more to do for static arrays, their bounds checking has been
1389 done at compile-time. */
5fee5ec3 1390 if (tb->ty == TY::Tsarray)
b4c522fa
IB
1391 {
1392 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1393 return;
1394 }
1395 else
5fee5ec3 1396 gcc_assert (tb->ty == TY::Tarray);
b4c522fa
IB
1397
1398 /* Generate bounds checking code. */
766f5f87
IB
1399 tree newlength = build_bounds_slice_condition (e, lwr_tree, upr_tree,
1400 length);
b4c522fa
IB
1401 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1402 this->result_ = compound_expr (array, result);
1403 }
1404
1405 /* Build a cast expression, which converts the given unary expression to the
1406 type of result. */
1407
1408 void visit (CastExp *e)
1409 {
1410 Type *ebtype = e->e1->type->toBasetype ();
1411 Type *tbtype = e->to->toBasetype ();
2ac51bdf 1412 tree result = build_expr (e->e1, this->constp_, this->literalp_);
b4c522fa
IB
1413
1414 /* Just evaluate e1 if it has any side effects. */
5fee5ec3 1415 if (tbtype->ty == TY::Tvoid)
b4c522fa
IB
1416 this->result_ = build_nop (build_ctype (tbtype), result);
1417 else
5c9b7408 1418 this->result_ = convert_for_rvalue (result, ebtype, tbtype);
b4c522fa
IB
1419 }
1420
1421 /* Build a delete expression. */
1422
1423 void visit (DeleteExp *e)
1424 {
1425 tree t1 = build_expr (e->e1);
1426 Type *tb1 = e->e1->type->toBasetype ();
1427
5fee5ec3 1428 if (tb1->ty == TY::Tclass)
b4c522fa
IB
1429 {
1430 /* For class object references, if there is a destructor for that class,
1431 the destructor is called for the object instance. */
1432 libcall_fn libcall;
1433
9c7d5e88 1434 if (e->e1->op == EXP::variable)
b4c522fa 1435 {
d873350a 1436 VarDeclaration *v = e->e1->isVarExp ()->var->isVarDeclaration ();
b4c522fa
IB
1437 if (v && v->onstack)
1438 {
1439 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1440 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1441
1442 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1443 return;
1444 }
1445 }
1446
1447 /* Otherwise, the garbage collector is called to immediately free the
1448 memory allocated for the class instance. */
1449 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1450 ? LIBCALL_DELINTERFACE : LIBCALL_DELCLASS;
1451
1452 t1 = build_address (t1);
1453 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1454 }
5fee5ec3 1455 else if (tb1->ty == TY::Tarray)
b4c522fa
IB
1456 {
1457 /* For dynamic arrays, the garbage collector is called to immediately
1458 release the memory. */
1459 Type *telem = tb1->nextOf ()->baseElemOf ();
1460 tree ti = null_pointer_node;
1461
89fdaf5a 1462 if (TypeStruct *ts = telem->isTypeStruct ())
b4c522fa
IB
1463 {
1464 /* Might need to run destructor on array contents. */
b4c522fa 1465 if (ts->sym->dtor)
c0aebc60 1466 ti = build_typeinfo (e->loc, tb1->nextOf ());
b4c522fa
IB
1467 }
1468
1469 /* Generate: _delarray_t (&t1, ti); */
1470 this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,
1471 build_address (t1), ti);
1472 }
5fee5ec3 1473 else if (tb1->ty == TY::Tpointer)
b4c522fa
IB
1474 {
1475 /* For pointers to a struct instance, if the struct has overloaded
1476 operator delete, then that operator is called. */
1477 t1 = build_address (t1);
89fdaf5a 1478 Type *tnext = tb1->isTypePointer ()->next->toBasetype ();
b4c522fa 1479
b3f58f87
IB
1480 /* This case should have been rewritten to `_d_delstruct` in the
1481 semantic phase. */
89fdaf5a 1482 if (TypeStruct *ts = tnext->isTypeStruct ())
b3f58f87 1483 gcc_assert (!ts->sym->dtor);
b4c522fa
IB
1484
1485 /* Otherwise, the garbage collector is called to immediately free the
1486 memory allocated for the pointer. */
1487 this->result_ = build_libcall (LIBCALL_DELMEMORY, Type::tvoid, 1, t1);
1488 }
1489 else
1490 {
a9c697b8 1491 error ("don%'t know how to delete %qs", e->e1->toChars ());
b4c522fa
IB
1492 this->result_ = error_mark_node;
1493 }
1494 }
1495
1496 /* Build a remove expression, which removes a particular key from an
1497 associative array. */
1498
1499 void visit (RemoveExp *e)
1500 {
1501 /* Check that the array is actually an associative array. */
5fee5ec3 1502 if (e->e1->type->toBasetype ()->ty == TY::Taarray)
b4c522fa
IB
1503 {
1504 Type *tb = e->e1->type->toBasetype ();
89fdaf5a 1505 Type *tkey = tb->isTypeAArray ()->index->toBasetype ();
b4c522fa
IB
1506 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1507
1508 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1509 build_expr (e->e1),
c0aebc60 1510 build_typeinfo (e->loc, tkey),
b4c522fa
IB
1511 build_address (index));
1512 }
1513 else
1514 {
1515 error ("%qs is not an associative array", e->e1->toChars ());
1516 this->result_ = error_mark_node;
1517 }
1518 }
1519
1520 /* Build an unary not expression. */
1521
1522 void visit (NotExp *e)
1523 {
1524 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1525 /* Need to convert to boolean type or this will fail. */
1526 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1527
1528 this->result_ = d_convert (build_ctype (e->type), result);
1529 }
1530
1531 /* Build a compliment expression, where all the bits in the value are
1532 complemented. Note: unlike in C, the usual integral promotions
1533 are not performed prior to the complement operation. */
1534
1535 void visit (ComExp *e)
1536 {
1537 TY ty1 = e->e1->type->toBasetype ()->ty;
5fee5ec3 1538 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
b4c522fa
IB
1539
1540 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1541 build_expr (e->e1));
1542 }
1543
1544 /* Build an unary negation expression. */
1545
1546 void visit (NegExp *e)
1547 {
1548 TY ty1 = e->e1->type->toBasetype ()->ty;
5fee5ec3 1549 gcc_assert (ty1 != TY::Tarray && ty1 != TY::Tsarray);
b4c522fa
IB
1550
1551 tree type = build_ctype (e->type);
1552 tree expr = build_expr (e->e1);
1553
1554 /* If the operation needs excess precision. */
1555 tree eptype = excess_precision_type (type);
1556 if (eptype != NULL_TREE)
1557 expr = d_convert (eptype, expr);
1558 else
1559 eptype = type;
1560
1561 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1562 this->result_ = d_convert (type, ret);
1563 }
1564
1565 /* Build a pointer index expression. */
1566
1567 void visit (PtrExp *e)
1568 {
1569 Type *tnext = NULL;
1570 size_t offset;
1571 tree result;
1572
9c7d5e88 1573 if (e->e1->op == EXP::add)
b4c522fa 1574 {
d873350a 1575 AddExp *ae = e->e1->isAddExp ();
9c7d5e88 1576 if (ae->e1->op == EXP::address
d873350a 1577 && ae->e2->isConst () && ae->e2->type->isintegral ())
b4c522fa 1578 {
d873350a
IB
1579 Expression *ex = ae->e1->isAddrExp ()->e1;
1580 tnext = ex->type->toBasetype ();
1581 result = build_expr (ex);
1582 offset = ae->e2->toUInteger ();
b4c522fa
IB
1583 }
1584 }
9c7d5e88 1585 else if (e->e1->op == EXP::symbolOffset)
b4c522fa 1586 {
d873350a 1587 SymOffExp *se = e->e1->isSymOffExp ();
b4c522fa
IB
1588 if (!declaration_reference_p (se->var))
1589 {
1590 tnext = se->var->type->toBasetype ();
1591 result = get_decl_tree (se->var);
1592 offset = se->offset;
1593 }
1594 }
1595
1596 /* Produce better code by converting *(#record + n) to
1597 COMPONENT_REFERENCE. Otherwise, the variable will always be
1598 allocated in memory because its address is taken. */
5fee5ec3 1599 if (tnext && tnext->ty == TY::Tstruct)
b4c522fa 1600 {
89fdaf5a 1601 StructDeclaration *sd = tnext->isTypeStruct ()->sym;
b4c522fa 1602
2cbc99d1 1603 for (size_t i = 0; i < sd->fields.length; i++)
b4c522fa
IB
1604 {
1605 VarDeclaration *field = sd->fields[i];
1606
1607 if (field->offset == offset
1608 && same_type_p (field->type, e->type))
1609 {
1610 /* Catch errors, backend will ICE otherwise. */
1611 if (error_operand_p (result))
1612 this->result_ = result;
1613 else
1614 {
1615 result = component_ref (result, get_symbol_decl (field));
1616 this->result_ = result;
1617 }
1618 return;
1619 }
1620 else if (field->offset > offset)
1621 break;
1622 }
1623 }
1624
1625 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1626 }
1627
1628 /* Build an unary address expression. */
1629
1630 void visit (AddrExp *e)
1631 {
1632 tree type = build_ctype (e->type);
1633 tree exp;
1634
1635 /* The frontend optimizer can convert const symbol into a struct literal.
1636 Taking the address of a struct literal is otherwise illegal. */
9c7d5e88 1637 if (e->e1->op == EXP::structLiteral)
b4c522fa 1638 {
d873350a 1639 StructLiteralExp *sle = e->e1->isStructLiteralExp ()->origin;
b4c522fa
IB
1640 gcc_assert (sle != NULL);
1641
1642 /* Build the reference symbol, the decl is built first as the
1643 initializer may have recursive references. */
1644 if (!sle->sym)
1645 {
1646 sle->sym = build_artificial_decl (build_ctype (sle->type),
1647 NULL_TREE, "S");
1648 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1649 d_pushdecl (sle->sym);
1650 rest_of_decl_compilation (sle->sym, 1, 0);
1651 }
1652
1653 exp = sle->sym;
1654 }
1655 else
2ac51bdf 1656 exp = build_expr (e->e1, this->constp_, this->literalp_);
b4c522fa
IB
1657
1658 TREE_CONSTANT (exp) = 0;
1659 this->result_ = d_convert (type, build_address (exp));
1660 }
1661
1662 /* Build a function call expression. */
1663
1664 void visit (CallExp *e)
1665 {
1666 Type *tb = e->e1->type->toBasetype ();
1667 Expression *e1b = e->e1;
1668
1669 tree callee = NULL_TREE;
1670 tree object = NULL_TREE;
1671 tree cleanup = NULL_TREE;
7616ed63 1672 tree returnvalue = NULL_TREE;
b4c522fa
IB
1673 TypeFunction *tf = NULL;
1674
1675 /* Calls to delegates can sometimes look like this. */
9c7d5e88 1676 if (e1b->op == EXP::comma)
b4c522fa 1677 {
d873350a 1678 e1b = e1b->isCommaExp ()->e2;
9c7d5e88 1679 gcc_assert (e1b->op == EXP::variable);
b4c522fa 1680
d873350a 1681 Declaration *var = e1b->isVarExp ()->var;
b4c522fa
IB
1682 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1683 }
1684
9c7d5e88 1685 if (e1b->op == EXP::dotVariable && tb->ty != TY::Tdelegate)
b4c522fa 1686 {
d873350a 1687 DotVarExp *dve = e1b->isDotVarExp ();
b4c522fa
IB
1688
1689 /* Don't modify the static initializer for struct literals. */
9c7d5e88 1690 if (dve->e1->op == EXP::structLiteral)
b4c522fa 1691 {
d873350a 1692 StructLiteralExp *sle = dve->e1->isStructLiteralExp ();
b4c522fa
IB
1693 sle->useStaticInit = false;
1694 }
1695
1696 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1697 if (fd != NULL)
1698 {
1699 /* Get the correct callee from the DotVarExp object. */
1700 tree fndecl = get_symbol_decl (fd);
1701 AggregateDeclaration *ad = fd->isThis ();
1702
1703 /* Static method; ignore the object instance. */
1704 if (!ad)
1705 callee = build_address (fndecl);
1706 else
1707 {
1708 tree thisexp = build_expr (dve->e1);
1709
1710 /* When constructing temporaries, if the constructor throws,
1711 then the object is destructed even though it is not a fully
1712 constructed object yet. And so this call will need to be
1713 moved inside the TARGET_EXPR_INITIAL slot. */
1714 if (fd->isCtorDeclaration ()
1715 && TREE_CODE (thisexp) == COMPOUND_EXPR
1716 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1717 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1718 {
1719 cleanup = TREE_OPERAND (thisexp, 0);
1720 thisexp = TREE_OPERAND (thisexp, 1);
1721 }
1722
87e36d9b
IB
1723 if (TREE_CODE (thisexp) == CONSTRUCTOR)
1724 thisexp = force_target_expr (thisexp);
1725
cdbf48be 1726 /* Want reference to `this' object. */
b4c522fa
IB
1727 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1728 thisexp = build_address (thisexp);
1729
1730 /* Make the callee a virtual call. */
1731 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1732 {
1733 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1734 tree thistype = build_ctype (ad->handleType ());
1735 thisexp = build_nop (thistype, d_save_expr (thisexp));
1736 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1737 }
1738 else
1739 fndecl = build_address (fndecl);
1740
7616ed63
IB
1741 /* C++ constructors return void, even though front-end semantic
1742 treats them as implicitly returning `this'. Set returnvalue
1743 to override the result of this expression. */
0fb57034 1744 if (fd->isCtorDeclaration ())
7616ed63
IB
1745 {
1746 thisexp = d_save_expr (thisexp);
1747 returnvalue = thisexp;
1748 }
1749
b4c522fa
IB
1750 callee = build_method_call (fndecl, thisexp, fd->type);
1751 }
1752 }
1753 }
1754
1755 if (callee == NULL_TREE)
1756 callee = build_expr (e1b);
1757
1758 if (METHOD_CALL_EXPR (callee))
1759 {
1760 /* This could be a delegate expression (TY == Tdelegate), but not
1761 actually a delegate variable. */
9c7d5e88 1762 if (e1b->op == EXP::dotVariable)
b4c522fa
IB
1763 {
1764 /* This gets the true function type, getting the function type
1765 from e1->type can sometimes be incorrect, such as when calling
cdbf48be 1766 a `ref' return function. */
d873350a 1767 tf = get_function_type (e1b->isDotVarExp ()->var->type);
b4c522fa
IB
1768 }
1769 else
1770 tf = get_function_type (tb);
1771
1772 extract_from_method_call (callee, callee, object);
1773 }
5fee5ec3 1774 else if (tb->ty == TY::Tdelegate)
b4c522fa
IB
1775 {
1776 /* Delegate call, extract .object and .funcptr from var. */
1777 callee = d_save_expr (callee);
1778 tf = get_function_type (tb);
1779 object = delegate_object (callee);
1780 callee = delegate_method (callee);
1781 }
9c7d5e88 1782 else if (e1b->op == EXP::variable)
b4c522fa 1783 {
d873350a 1784 FuncDeclaration *fd = e1b->isVarExp ()->var->isFuncDeclaration ();
b4c522fa
IB
1785 gcc_assert (fd != NULL);
1786 tf = get_function_type (fd->type);
1787
1788 if (fd->isNested ())
1789 {
cdbf48be 1790 /* Maybe re-evaluate symbol storage treating `fd' as public. */
b4c522fa
IB
1791 if (call_by_alias_p (d_function_chain->function, fd))
1792 TREE_PUBLIC (callee) = 1;
1793
1794 object = get_frame_for_symbol (fd);
1795 }
1796 else if (fd->needThis ())
1797 {
1798 error_at (make_location_t (e1b->loc),
1799 "need %<this%> to access member %qs", fd->toChars ());
1800 /* Continue compiling... */
1801 object = null_pointer_node;
1802 }
1803 }
1804 else
1805 {
1806 /* Normal direct function call. */
1807 tf = get_function_type (tb);
1808 }
1809
1810 gcc_assert (tf != NULL);
1811
1812 /* Now we have the type, callee and maybe object reference,
1813 build the call expression. */
1814 tree exp = d_build_call (tf, callee, object, e->arguments);
1815
7616ed63
IB
1816 if (returnvalue != NULL_TREE)
1817 exp = compound_expr (exp, returnvalue);
1818
5fee5ec3 1819 if (tf->isref ())
b4c522fa
IB
1820 exp = build_deref (exp);
1821
1822 /* Some library calls are defined to return a generic type.
1823 this->type is the real type we want to return. */
1824 if (e->type->isTypeBasic ())
1825 exp = d_convert (build_ctype (e->type), exp);
1826
1827 /* If this call was found to be a constructor for a temporary with a
df3fbd59 1828 cleanup, then move the call inside the TARGET_EXPR. */
b4c522fa
IB
1829 if (cleanup != NULL_TREE)
1830 {
1831 tree init = TARGET_EXPR_INITIAL (cleanup);
b4c522fa 1832 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
0fb57034
IB
1833
1834 /* Keep the return value outside the TARGET_EXPR. */
1835 if (returnvalue != NULL_TREE)
1836 cleanup = compound_expr (cleanup, TREE_OPERAND (exp, 1));
1837
b4c522fa
IB
1838 exp = cleanup;
1839 }
1840
1841 this->result_ = exp;
1842 }
1843
1844 /* Build a delegate expression. */
1845
1846 void visit (DelegateExp *e)
1847 {
0fb57034 1848 if (e->func->semanticRun == PASS::semantic3done)
b4c522fa
IB
1849 {
1850 /* Add the function as nested function if it belongs to this module.
1851 ie: it is a member of this module, or it is a template instance. */
1852 Dsymbol *owner = e->func->toParent ();
1853 while (!owner->isTemplateInstance () && owner->toParent ())
1854 owner = owner->toParent ();
1855 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1856 build_decl_tree (e->func);
1857 }
1858
1859 tree fndecl;
1860 tree object;
1861
5fee5ec3 1862 if (e->func->isNested () && !e->func->isThis ())
b4c522fa 1863 {
9c7d5e88 1864 if (e->e1->op == EXP::null_)
b4c522fa
IB
1865 object = build_expr (e->e1);
1866 else
1867 object = get_frame_for_symbol (e->func);
1868
1869 fndecl = build_address (get_symbol_decl (e->func));
1870 }
1871 else
1872 {
1873 if (!e->func->isThis ())
1874 {
1875 error ("delegates are only for non-static functions");
1876 this->result_ = error_mark_node;
1877 return;
1878 }
1879
1880 object = build_expr (e->e1);
1881
1882 /* Want reference to `this' object. */
5fee5ec3 1883 if (e->e1->type->ty != TY::Tclass && e->e1->type->ty != TY::Tpointer)
b4c522fa
IB
1884 object = build_address (object);
1885
1886 /* Object reference could be the outer `this' field of a class or
1887 closure of type `void*'. Cast it to the right type. */
5fee5ec3 1888 if (e->e1->type->ty == TY::Tclass)
b4c522fa
IB
1889 object = d_convert (build_ctype (e->e1->type), object);
1890
1891 fndecl = get_symbol_decl (e->func);
1892
1893 /* Get pointer to function out of the virtual table. */
1894 if (e->func->isVirtual () && !e->func->isFinalFunc ()
9c7d5e88 1895 && e->e1->op != EXP::super_ && e->e1->op != EXP::dotType)
b4c522fa
IB
1896 {
1897 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1898 object = d_save_expr (object);
1899 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1900 }
1901 else
1902 fndecl = build_address (fndecl);
1903 }
1904
1905 this->result_ = build_method_call (fndecl, object, e->type);
1906 }
1907
1908 /* Build a type component expression. */
1909
1910 void visit (DotTypeExp *e)
1911 {
1912 /* Just a pass through to underlying expression. */
1913 this->result_ = build_expr (e->e1);
1914 }
1915
1916 /* Build a component reference expression. */
1917
1918 void visit (DotVarExp *e)
1919 {
1920 VarDeclaration *vd = e->var->isVarDeclaration ();
1921
1922 /* This could also be a function, but relying on that being taken
1923 care of by the visitor interface for CallExp. */
1924 if (vd != NULL)
1925 {
1926 if (!vd->isField ())
1927 this->result_ = get_decl_tree (vd);
1928 else
1929 {
1930 tree object = build_expr (e->e1);
1931
5fee5ec3 1932 if (e->e1->type->toBasetype ()->ty != TY::Tstruct)
b4c522fa
IB
1933 object = build_deref (object);
1934
1935 this->result_ = component_ref (object, get_symbol_decl (vd));
1936 }
1937 }
1938 else
1939 {
1940 error ("%qs is not a field, but a %qs",
1941 e->var->toChars (), e->var->kind ());
1942 this->result_ = error_mark_node;
1943 }
1944 }
1945
1946 /* Build an assert expression, used to declare conditions that must hold at
1947 that a given point in the program. */
1948
1949 void visit (AssertExp *e)
1950 {
1951 Type *tb1 = e->e1->type->toBasetype ();
1952 tree arg = build_expr (e->e1);
1953 tree tmsg = NULL_TREE;
1954 tree assert_pass = void_node;
1955 tree assert_fail;
1956
766f5f87 1957 if (global.params.useAssert == CHECKENABLEon && !checkaction_trap_p ())
b4c522fa
IB
1958 {
1959 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1960 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1961 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1962 libcall_fn libcall;
1963
1964 if (e->msg)
1965 {
1966 tmsg = build_expr_dtor (e->msg);
1967 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1968 }
1969 else
766f5f87 1970 libcall = unittest_p ? LIBCALL_UNITTESTP : LIBCALL_ASSERTP;
b4c522fa
IB
1971
1972 /* Build a call to _d_assert(). */
766f5f87 1973 assert_fail = build_assert_call (e->loc, libcall, tmsg);
b4c522fa 1974
0cdc55f5 1975 if (global.params.useInvariants == CHECKENABLEon)
b4c522fa
IB
1976 {
1977 /* If the condition is a D class or struct object with an invariant,
1978 call it if the condition result is true. */
5fee5ec3 1979 if (tb1->ty == TY::Tclass)
b4c522fa
IB
1980 {
1981 ClassDeclaration *cd = tb1->isClassHandle ();
1982 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
1983 {
1984 arg = d_save_expr (arg);
1985 assert_pass = build_libcall (LIBCALL_INVARIANT,
1986 Type::tvoid, 1, arg);
1987 }
1988 }
5fee5ec3
IB
1989 else if (tb1->ty == TY::Tpointer
1990 && tb1->nextOf ()->ty == TY::Tstruct)
b4c522fa 1991 {
89fdaf5a 1992 StructDeclaration *sd = tb1->nextOf ()->isTypeStruct ()->sym;
b4c522fa
IB
1993 if (sd->inv != NULL)
1994 {
1995 Expressions args;
1996 arg = d_save_expr (arg);
1997 assert_pass = d_build_call_expr (sd->inv, arg, &args);
1998 }
1999 }
2000 }
2001 }
766f5f87 2002 else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
c0aebc60
IB
2003 {
2004 /* Generate: __builtin_trap() */
2005 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
2006 assert_fail = build_call_expr (fn, 0);
2007 }
b4c522fa
IB
2008 else
2009 {
5ad4eab2
IB
2010 /* Assert contracts are turned off. */
2011 this->result_ = void_node;
2012 return;
b4c522fa
IB
2013 }
2014
2015 /* Build condition that we are asserting in this contract. */
2016 tree condition = convert_for_condition (arg, e->e1->type);
2017
2018 /* We expect the condition to always be true, as what happens if an assert
2019 contract is false is undefined behavior. */
2020 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
2021 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
2022 tree pred_type = TREE_VALUE (arg_types);
2023 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
2024
2025 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
2026 build_int_cst (expected_type, 1));
2027 condition = d_truthvalue_conversion (condition);
2028
2029 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
2030 }
2031
2032 /* Build a declaration expression. */
2033
2034 void visit (DeclarationExp *e)
2035 {
2036 /* Compile the declaration. */
2037 push_stmt_list ();
2038 build_decl_tree (e->declaration);
2039 tree result = pop_stmt_list ();
2040
2041 /* Construction of an array for typesafe-variadic function arguments
2042 can cause an empty STMT_LIST here. This can causes problems
2043 during gimplification. */
2044 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
2045 result = build_empty_stmt (input_location);
2046
2047 this->result_ = result;
2048 }
2049
2050 /* Build a typeid expression. Returns an instance of class TypeInfo
2051 corresponding to. */
2052
2053 void visit (TypeidExp *e)
2054 {
2055 if (Type *tid = isType (e->obj))
2056 {
c0aebc60 2057 tree ti = build_typeinfo (e->loc, tid);
b4c522fa
IB
2058
2059 /* If the typeinfo is at an offset. */
2060 if (tid->vtinfo->offset)
2061 ti = build_offset (ti, size_int (tid->vtinfo->offset));
2062
2063 this->result_ = build_nop (build_ctype (e->type), ti);
2064 }
2065 else if (Expression *tid = isExpression (e->obj))
2066 {
2067 Type *type = tid->type->toBasetype ();
5fee5ec3 2068 assert (type->ty == TY::Tclass);
b4c522fa
IB
2069
2070 /* Generate **classptr to get the classinfo. */
2071 tree ci = build_expr (tid);
2072 ci = indirect_ref (ptr_type_node, ci);
2073 ci = indirect_ref (ptr_type_node, ci);
2074
2075 /* Add extra indirection for interfaces. */
89fdaf5a 2076 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
b4c522fa
IB
2077 ci = indirect_ref (ptr_type_node, ci);
2078
2079 this->result_ = build_nop (build_ctype (e->type), ci);
2080 }
2081 else
2082 gcc_unreachable ();
2083 }
2084
2085 /* Build a function/lambda expression. */
2086
2087 void visit (FuncExp *e)
2088 {
2089 Type *ftype = e->type->toBasetype ();
2090
cdbf48be 2091 /* This check is for lambda's, remove `vthis' as function isn't nested. */
9c7d5e88 2092 if (e->fd->tok == TOK::reserved && ftype->ty == TY::Tpointer)
b4c522fa 2093 {
9c7d5e88 2094 e->fd->tok = TOK::function_;
b4c522fa
IB
2095 e->fd->vthis = NULL;
2096 }
2097
2098 /* Compile the function literal body. */
2099 build_decl_tree (e->fd);
2100
2101 /* If nested, this will be a trampoline. */
2102 if (e->fd->isNested ())
2103 {
2104 tree func = build_address (get_symbol_decl (e->fd));
2105 tree object;
2106
2107 if (this->constp_)
2108 {
2109 /* Static delegate variables have no context pointer. */
2110 object = null_pointer_node;
2111 this->result_ = build_method_call (func, object, e->fd->type);
2112 TREE_CONSTANT (this->result_) = 1;
2113 }
2114 else
2115 {
2116 object = get_frame_for_symbol (e->fd);
2117 this->result_ = build_method_call (func, object, e->fd->type);
2118 }
2119 }
2120 else
2121 {
2122 this->result_ = build_nop (build_ctype (e->type),
2123 build_address (get_symbol_decl (e->fd)));
2124 }
2125 }
2126
2127 /* Build a halt expression. */
2128
2129 void visit (HaltExp *)
2130 {
2131 /* Should we use trap() or abort()? */
2132 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
2133 this->result_ = build_call_expr (ttrap, 0);
2134 }
2135
2136 /* Build a symbol pointer offset expression. */
2137
2138 void visit (SymOffExp *e)
2139 {
2140 /* Build the address and offset of the symbol. */
d873350a 2141 size_t soffset = e->isSymOffExp ()->offset;
b4c522fa
IB
2142 tree result = get_decl_tree (e->var);
2143 TREE_USED (result) = 1;
2144
2145 if (declaration_reference_p (e->var))
2146 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
2147 else
2148 result = build_address (result);
2149
2150 if (!soffset)
2151 result = d_convert (build_ctype (e->type), result);
2152 else
2153 {
2154 tree offset = size_int (soffset);
2155 result = build_nop (build_ctype (e->type),
2156 build_offset (result, offset));
2157 }
2158
2159 this->result_ = result;
2160 }
2161
2162 /* Build a variable expression. */
2163
2164 void visit (VarExp *e)
2165 {
2166 if (e->var->needThis ())
2167 {
2168 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
2169 this->result_ = error_mark_node;
2170 return;
2171 }
2172 else if (e->var->ident == Identifier::idPool ("__ctfe"))
2173 {
2174 /* __ctfe is always false at run-time. */
2175 this->result_ = integer_zero_node;
2176 return;
2177 }
2178
2179 /* This check is same as is done in FuncExp for lambdas. */
2180 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
2181 if (fld != NULL)
2182 {
9c7d5e88 2183 if (fld->tok == TOK::reserved)
b4c522fa 2184 {
9c7d5e88 2185 fld->tok = TOK::function_;
b4c522fa
IB
2186 fld->vthis = NULL;
2187 }
2188
2189 /* Compiler the function literal body. */
2190 build_decl_tree (fld);
2191 }
2192
2193 if (this->constp_)
2194 {
2195 /* Want the initializer, not the expression. */
2196 VarDeclaration *var = e->var->isVarDeclaration ();
9c7d5e88 2197 SymbolDeclaration *sdecl = e->var->isSymbolDeclaration ();
b4c522fa
IB
2198 tree init = NULL_TREE;
2199
2200 if (var && (var->isConst () || var->isImmutable ())
5fee5ec3 2201 && e->type->toBasetype ()->ty != TY::Tsarray && var->_init)
b4c522fa
IB
2202 {
2203 if (var->inuse)
2204 error_at (make_location_t (e->loc), "recursive reference %qs",
2205 e->toChars ());
2206 else
2207 {
2208 var->inuse++;
2209 init = build_expr (initializerToExpression (var->_init), true);
2210 var->inuse--;
2211 }
2212 }
9c7d5e88
IB
2213 else if (sdecl && sdecl->dsym)
2214 {
2215 if (StructDeclaration *sd = sdecl->dsym->isStructDeclaration ())
2216 init = layout_struct_initializer (sd);
2217 else if (ClassDeclaration *cd = sdecl->dsym->isClassDeclaration ())
2218 init = layout_class_initializer (cd);
2219 else
2220 gcc_unreachable ();
2221 }
b4c522fa
IB
2222 else
2223 error_at (make_location_t (e->loc), "non-constant expression %qs",
2224 e->toChars ());
2225
2226 if (init != NULL_TREE)
2227 this->result_ = init;
2228 else
2229 this->result_ = error_mark_node;
2230 }
2231 else
2232 {
2233 tree result = get_decl_tree (e->var);
2234 TREE_USED (result) = 1;
2235
9c7d5e88
IB
2236 /* The variable expression generated for `__traits(initSymbol)'. */
2237 if (SymbolDeclaration *sd = e->var->isSymbolDeclaration ())
2238 {
2239 if (e->type->isTypeDArray ())
2240 {
2241 /* Generate a slice for non-zero initialized aggregates,
2242 otherwise create an empty array. */
2243 gcc_assert (e->type == Type::tvoid->arrayOf ()->constOf ());
2244
2245 tree type = build_ctype (e->type);
2246 tree length = size_int (sd->dsym->structsize);
2247 tree ptr = (sd->dsym->isStructDeclaration ()
2248 && sd->dsym->type->isZeroInit (e->loc))
2249 ? null_pointer_node : build_address (result);
2250
2251 this->result_ = d_array_value (type, length, ptr);
2252 return;
2253 }
2254 }
2255
b4c522fa
IB
2256 /* For variables that are references - currently only out/inout
2257 arguments; objects don't count - evaluating the variable means
2258 we want what it refers to. */
2259 if (declaration_reference_p (e->var))
2260 result = indirect_ref (build_ctype (e->var->type), result);
2261
2262 this->result_ = result;
2263 }
2264 }
2265
2266 /* Build a this variable expression. */
2267
2268 void visit (ThisExp *e)
2269 {
2270 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
2271 tree result = NULL_TREE;
2272
2273 if (e->var)
2274 result = get_decl_tree (e->var);
2275 else
2276 {
2277 gcc_assert (fd && fd->vthis);
2278 result = get_decl_tree (fd->vthis);
2279 }
2280
5fee5ec3 2281 if (e->type->ty == TY::Tstruct)
b4c522fa
IB
2282 result = build_deref (result);
2283
2284 this->result_ = result;
2285 }
2286
2287 /* Build a new expression, which allocates memory either on the garbage
2288 collected heap or by using a class or struct specific allocator. */
2289
2290 void visit (NewExp *e)
2291 {
2292 Type *tb = e->type->toBasetype ();
2293 tree result;
2294
5fee5ec3 2295 if (tb->ty == TY::Tclass)
b4c522fa
IB
2296 {
2297 /* Allocating a new class. */
2298 tb = e->newtype->toBasetype ();
b4c522fa 2299
89fdaf5a 2300 ClassDeclaration *cd = tb->isTypeClass ()->sym;
b4c522fa
IB
2301 tree type = build_ctype (tb);
2302 tree setup_exp = NULL_TREE;
2303 tree new_call;
2304
2305 if (e->onstack)
2306 {
2307 /* If being used as an initializer for a local variable with scope
2308 storage class, then the instance is allocated on the stack
2309 rather than the heap or using the class specific allocator. */
2310 tree var = build_local_temp (TREE_TYPE (type));
2311 new_call = build_nop (type, build_address (var));
2312 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
2313 }
b4c522fa
IB
2314 else
2315 {
2316 /* Generate: _d_newclass() */
2317 tree arg = build_address (get_classinfo_decl (cd));
5fee5ec3
IB
2318 libcall_fn libcall = (global.params.ehnogc && e->thrownew)
2319 ? LIBCALL_NEWTHROW : LIBCALL_NEWCLASS;
2320 new_call = build_libcall (libcall, tb, 1, arg);
b4c522fa
IB
2321 }
2322
2323 /* Set the context pointer for nested classes. */
2324 if (cd->isNested ())
2325 {
2326 tree field = get_symbol_decl (cd->vthis);
2327 tree value = NULL_TREE;
2328
2329 if (e->thisexp)
2330 {
2331 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
5fee5ec3
IB
2332 /* The class or function we're nested in. */
2333 Dsymbol *outer = cd->toParentLocal ();
b4c522fa
IB
2334
2335 value = build_expr (e->thisexp);
5fee5ec3 2336
b4c522fa
IB
2337 if (outer != tcd)
2338 {
2339 ClassDeclaration *ocd = outer->isClassDeclaration ();
5fee5ec3 2340 int offset = 0;
b4c522fa
IB
2341 gcc_assert (ocd->isBaseOf (tcd, &offset));
2342 /* Could just add offset... */
2343 value = convert_expr (value, e->thisexp->type, ocd->type);
2344 }
2345 }
2346 else
2347 value = build_vthis (cd);
2348
2349 if (value != NULL_TREE)
2350 {
2351 /* Generate: (new())->vthis = this; */
2352 new_call = d_save_expr (new_call);
2353 field = component_ref (build_deref (new_call), field);
2354 setup_exp = compound_expr (setup_exp,
2355 modify_expr (field, value));
2356 }
2357 }
2358 new_call = compound_expr (setup_exp, new_call);
2359
2360 /* Call the class constructor. */
2361 if (e->member)
2362 result = d_build_call_expr (e->member, new_call, e->arguments);
2363 else
2364 result = new_call;
2365
2366 if (e->argprefix)
2367 result = compound_expr (build_expr (e->argprefix), result);
2368 }
5fee5ec3
IB
2369 else if (tb->ty == TY::Tpointer
2370 && tb->nextOf ()->toBasetype ()->ty == TY::Tstruct)
b4c522fa
IB
2371 {
2372 /* Allocating memory for a new struct. */
2373 Type *htype = e->newtype->toBasetype ();
b4c522fa
IB
2374 gcc_assert (!e->onstack);
2375
89fdaf5a 2376 TypeStruct *stype = htype->isTypeStruct ();
b4c522fa
IB
2377 StructDeclaration *sd = stype->sym;
2378 tree new_call;
2379
2380 /* Cannot new an opaque struct. */
2381 if (sd->size (e->loc) == 0)
2382 {
2383 this->result_ = d_convert (build_ctype (e->type),
2384 integer_zero_node);
2385 return;
2386 }
2387
5fee5ec3
IB
2388 /* Generate: _d_newitemT() */
2389 libcall_fn libcall = htype->isZeroInit ()
2390 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2391 tree arg = build_typeinfo (e->loc, e->newtype);
2392 new_call = build_libcall (libcall, tb, 1, arg);
b4c522fa
IB
2393
2394 if (e->member || !e->arguments)
2395 {
2396 /* Set the context pointer for nested structs. */
2397 if (sd->isNested ())
2398 {
2399 tree value = build_vthis (sd);
2400 tree field = get_symbol_decl (sd->vthis);
2401 tree type = build_ctype (stype);
2402
2403 new_call = d_save_expr (new_call);
2404 field = component_ref (indirect_ref (type, new_call), field);
2405 new_call = compound_expr (modify_expr (field, value), new_call);
2406 }
2407
2408 /* Call the struct constructor. */
2409 if (e->member)
2410 result = d_build_call_expr (e->member, new_call, e->arguments);
2411 else
2412 result = new_call;
2413 }
2414 else
2415 {
2416 /* If we have a user supplied initializer, then set-up with a
2417 struct literal. */
2cbc99d1 2418 if (e->arguments != NULL && sd->fields.length != 0)
b4c522fa
IB
2419 {
2420 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
2421 e->arguments,
2422 htype);
2423 new_call = d_save_expr (new_call);
2424 se->type = sd->type;
2425 se->sym = new_call;
2426 result = compound_expr (build_expr (se), new_call);
2427 }
2428 else
2429 result = new_call;
2430 }
2431
2432 if (e->argprefix)
2433 result = compound_expr (build_expr (e->argprefix), result);
2434 }
5fee5ec3 2435 else if (tb->ty == TY::Tarray)
b4c522fa
IB
2436 {
2437 /* Allocating memory for a new D array. */
2438 tb = e->newtype->toBasetype ();
89fdaf5a 2439 TypeDArray *tarray = tb->isTypeDArray ();
b4c522fa 2440
2cbc99d1 2441 gcc_assert (e->arguments && e->arguments->length >= 1);
b4c522fa 2442
2cbc99d1 2443 if (e->arguments->length == 1)
b4c522fa
IB
2444 {
2445 /* Single dimension array allocations. */
2446 Expression *arg = (*e->arguments)[0];
2447
2448 if (tarray->next->size () == 0)
2449 {
2450 /* Array element size is unknown. */
2451 this->result_ = d_array_value (build_ctype (e->type),
2452 size_int (0), null_pointer_node);
2453 return;
2454 }
2455
2456 libcall_fn libcall = tarray->next->isZeroInit ()
2457 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
2458 result = build_libcall (libcall, tb, 2,
c0aebc60 2459 build_typeinfo (e->loc, e->type),
b4c522fa
IB
2460 build_expr (arg));
2461 }
2462 else
2463 {
2464 /* Multidimensional array allocations. */
2cbc99d1 2465 tree tarray = make_array_type (Type::tsize_t, e->arguments->length);
0af711e1 2466 tree var = build_local_temp (tarray);
af3c19f0 2467 vec <constructor_elt, va_gc> *elms = NULL;
b4c522fa 2468
0af711e1
IB
2469 /* Get the base element type for the array, generating the
2470 initializer for the dims parameter along the way. */
2471 Type *telem = e->newtype->toBasetype ();
2cbc99d1 2472 for (size_t i = 0; i < e->arguments->length; i++)
b4c522fa
IB
2473 {
2474 Expression *arg = (*e->arguments)[i];
2475 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
2476
5fee5ec3 2477 gcc_assert (telem->ty == TY::Tarray);
b4c522fa
IB
2478 telem = telem->toBasetype ()->nextOf ();
2479 gcc_assert (telem);
2480 }
2481
0af711e1
IB
2482 /* Initialize the temporary. */
2483 tree init = modify_expr (var, build_constructor (tarray, elms));
2484 var = compound_expr (init, var);
b4c522fa
IB
2485
2486 /* Generate: _d_newarraymTX(ti, dims)
2487 or: _d_newarraymiTX(ti, dims) */
2488 libcall_fn libcall = telem->isZeroInit ()
2489 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
2490
c0aebc60 2491 tree tinfo = build_typeinfo (e->loc, e->type);
b4c522fa 2492 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
2cbc99d1 2493 size_int (e->arguments->length),
b4c522fa
IB
2494 build_address (var));
2495
2496 result = build_libcall (libcall, tb, 2, tinfo, dims);
b4c522fa
IB
2497 }
2498
2499 if (e->argprefix)
2500 result = compound_expr (build_expr (e->argprefix), result);
2501 }
5fee5ec3 2502 else if (tb->ty == TY::Tpointer)
b4c522fa
IB
2503 {
2504 /* Allocating memory for a new pointer. */
89fdaf5a 2505 TypePointer *tpointer = tb->isTypePointer ();
b4c522fa
IB
2506
2507 if (tpointer->next->size () == 0)
2508 {
2509 /* Pointer element size is unknown. */
2510 this->result_ = d_convert (build_ctype (e->type),
2511 integer_zero_node);
2512 return;
2513 }
2514
2515 libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
2516 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
2517
c0aebc60 2518 tree arg = build_typeinfo (e->loc, e->newtype);
b4c522fa
IB
2519 result = build_libcall (libcall, tb, 1, arg);
2520
2cbc99d1 2521 if (e->arguments && e->arguments->length == 1)
b4c522fa
IB
2522 {
2523 result = d_save_expr (result);
2524 tree init = modify_expr (build_deref (result),
2525 build_expr ((*e->arguments)[0]));
2526 result = compound_expr (init, result);
2527 }
2528
2529 if (e->argprefix)
2530 result = compound_expr (build_expr (e->argprefix), result);
2531 }
2532 else
2533 gcc_unreachable ();
2534
2535 this->result_ = convert_expr (result, tb, e->type);
2536 }
2537
2538 /* Build an integer literal. */
2539
2540 void visit (IntegerExp *e)
2541 {
2542 tree ctype = build_ctype (e->type->toBasetype ());
2543 this->result_ = build_integer_cst (e->value, ctype);
2544 }
2545
2546 /* Build a floating-point literal. */
2547
2548 void visit (RealExp *e)
2549 {
2550 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
2551 }
2552
2553 /* Build a complex literal. */
2554
2555 void visit (ComplexExp *e)
2556 {
2557 Type *tnext;
2558
2559 switch (e->type->toBasetype ()->ty)
2560 {
5fee5ec3 2561 case TY::Tcomplex32:
b4c522fa
IB
2562 tnext = (TypeBasic *) Type::tfloat32;
2563 break;
2564
5fee5ec3 2565 case TY::Tcomplex64:
b4c522fa
IB
2566 tnext = (TypeBasic *) Type::tfloat64;
2567 break;
2568
5fee5ec3 2569 case TY::Tcomplex80:
b4c522fa
IB
2570 tnext = (TypeBasic *) Type::tfloat80;
2571 break;
2572
2573 default:
2574 gcc_unreachable ();
2575 }
2576
2577 this->result_ = build_complex (build_ctype (e->type),
2578 build_float_cst (creall (e->value), tnext),
2579 build_float_cst (cimagl (e->value), tnext));
2580 }
2581
2582 /* Build a string literal, all strings are null terminated except for
2583 static arrays. */
2584
2585 void visit (StringExp *e)
2586 {
2587 Type *tb = e->type->toBasetype ();
2588 tree type = build_ctype (e->type);
2589
5fee5ec3 2590 if (tb->ty == TY::Tsarray)
b4c522fa
IB
2591 {
2592 /* Turn the string into a constructor for the static array. */
af3c19f0 2593 vec <constructor_elt, va_gc> *elms = NULL;
b4c522fa
IB
2594 vec_safe_reserve (elms, e->len);
2595 tree etype = TREE_TYPE (type);
2596
2597 for (size_t i = 0; i < e->len; i++)
2598 {
2599 tree value = build_integer_cst (e->charAt (i), etype);
2600 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2601 }
2602
2603 tree ctor = build_constructor (type, elms);
2604 TREE_CONSTANT (ctor) = 1;
2605 this->result_ = ctor;
2606 }
2607 else
2608 {
2609 /* Copy the string contents to a null terminated string. */
2610 dinteger_t length = (e->len * e->sz);
2611 char *string = XALLOCAVEC (char, length + 1);
5791bf7a
ML
2612 if (length > 0)
2613 memcpy (string, e->string, length);
b4c522fa
IB
2614 string[length] = '\0';
2615
2616 /* String value and type includes the null terminator. */
2617 tree value = build_string (length, string);
2618 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
2619 value = build_address (value);
2620
5fee5ec3 2621 if (tb->ty == TY::Tarray)
b4c522fa
IB
2622 value = d_array_value (type, size_int (e->len), value);
2623
2624 TREE_CONSTANT (value) = 1;
2625 this->result_ = d_convert (type, value);
2626 }
2627 }
2628
2629 /* Build a tuple literal. Just an argument list that may have
2630 side effects that need evaluation. */
2631
2632 void visit (TupleExp *e)
2633 {
2634 tree result = NULL_TREE;
2635
2636 if (e->e0)
2ac51bdf 2637 result = build_expr (e->e0, this->constp_, true);
b4c522fa 2638
2cbc99d1 2639 for (size_t i = 0; i < e->exps->length; ++i)
b4c522fa
IB
2640 {
2641 Expression *exp = (*e->exps)[i];
2ac51bdf 2642 result = compound_expr (result, build_expr (exp, this->constp_, true));
b4c522fa
IB
2643 }
2644
2645 if (result == NULL_TREE)
2646 result = void_node;
2647
2648 this->result_ = result;
2649 }
2650
2651 /* Build an array literal. The common type of the all elements is taken to
2652 be the type of the array element, and all elements are implicitly
2653 converted to that type. */
2654
2655 void visit (ArrayLiteralExp *e)
2656 {
2657 Type *tb = e->type->toBasetype ();
2658
2659 /* Implicitly convert void[n] to ubyte[n]. */
5fee5ec3 2660 if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid)
89fdaf5a 2661 tb = Type::tuns8->sarrayOf (tb->isTypeSArray ()->dim->toUInteger ());
b4c522fa 2662
5fee5ec3
IB
2663 gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray
2664 || tb->ty == TY::Tpointer);
b4c522fa
IB
2665
2666 /* Handle empty array literals. */
2cbc99d1 2667 if (e->elements->length == 0)
b4c522fa 2668 {
5fee5ec3 2669 if (tb->ty == TY::Tarray)
b4c522fa
IB
2670 this->result_ = d_array_value (build_ctype (e->type),
2671 size_int (0), null_pointer_node);
2672 else
2673 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
2674 NULL);
2675
2676 return;
2677 }
2678
2679 /* Build an expression that assigns the expressions in ELEMENTS to
2680 a constructor. */
af3c19f0 2681 vec <constructor_elt, va_gc> *elms = NULL;
2cbc99d1 2682 vec_safe_reserve (elms, e->elements->length);
b4c522fa
IB
2683 bool constant_p = true;
2684 tree saved_elems = NULL_TREE;
2685
2686 Type *etype = tb->nextOf ();
2cbc99d1 2687 tree satype = make_array_type (etype, e->elements->length);
b4c522fa 2688
2cbc99d1 2689 for (size_t i = 0; i < e->elements->length; i++)
b4c522fa
IB
2690 {
2691 Expression *expr = e->getElement (i);
2ac51bdf 2692 tree value = build_expr (expr, this->constp_, true);
b4c522fa
IB
2693
2694 /* Only append nonzero values, the backend will zero out the rest
2695 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
2696 if (!initializer_zerop (value))
2697 {
2698 if (!TREE_CONSTANT (value))
2699 constant_p = false;
2700
2701 /* Split construction of values out of the constructor if there
2702 may be side effects. */
2703 tree init = stabilize_expr (&value);
2704 if (init != NULL_TREE)
2705 saved_elems = compound_expr (saved_elems, init);
2706
2707 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
2708 convert_expr (value, expr->type, etype));
2709 }
2710 }
2711
2712 /* Now return the constructor as the correct type. For static arrays there
2713 is nothing else to do. For dynamic arrays, return a two field struct.
2714 For pointers, return the address. */
2715 tree ctor = build_constructor (satype, elms);
2716 tree type = build_ctype (e->type);
2717
2718 /* Nothing else to do for static arrays. */
5fee5ec3 2719 if (tb->ty == TY::Tsarray || this->constp_)
b4c522fa
IB
2720 {
2721 /* Can't take the address of the constructor, so create an anonymous
2722 static symbol, and then refer to it. */
5fee5ec3 2723 if (tb->ty != TY::Tsarray)
b4c522fa
IB
2724 {
2725 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
2726 ctor = build_address (decl);
5fee5ec3 2727 if (tb->ty == TY::Tarray)
2cbc99d1 2728 ctor = d_array_value (type, size_int (e->elements->length), ctor);
b4c522fa
IB
2729
2730 d_pushdecl (decl);
2731 rest_of_decl_compilation (decl, 1, 0);
2732 }
2733
2734 /* If the array literal is readonly or static. */
2735 if (constant_p)
2736 TREE_CONSTANT (ctor) = 1;
2737 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2738 TREE_STATIC (ctor) = 1;
2739
2ac51bdf
IB
2740 /* Use memset to fill any alignment holes in the array. */
2741 if (!this->constp_ && !this->literalp_)
2742 {
2743 TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
2744
2745 if (ts != NULL && (!identity_compare_p (ts->sym)
2746 || ts->sym->isUnionDeclaration ()))
2747 {
2748 tree var = build_local_temp (TREE_TYPE (ctor));
2749 tree init = build_memset_call (var);
2750 /* Evaluate memset() first, then any saved elements. */
2751 saved_elems = compound_expr (init, saved_elems);
2752 ctor = compound_expr (modify_expr (var, ctor), var);
2753 }
2754 }
2755
b4c522fa
IB
2756 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
2757 }
2758 else
2759 {
2760 /* Allocate space on the memory managed heap. */
2761 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
2762 etype->pointerTo (), 2,
c0aebc60 2763 build_typeinfo (e->loc, etype->arrayOf ()),
2cbc99d1 2764 size_int (e->elements->length));
b4c522fa
IB
2765 mem = d_save_expr (mem);
2766
2767 /* Now copy the constructor into memory. */
2cbc99d1 2768 tree size = size_mult_expr (size_int (e->elements->length),
b4c522fa
IB
2769 size_int (tb->nextOf ()->size ()));
2770
ab0edbcb 2771 tree result = build_memcpy_call (mem, build_address (ctor), size);
b4c522fa
IB
2772
2773 /* Return the array pointed to by MEM. */
2774 result = compound_expr (result, mem);
2775
5fee5ec3 2776 if (tb->ty == TY::Tarray)
2cbc99d1 2777 result = d_array_value (type, size_int (e->elements->length), result);
b4c522fa
IB
2778
2779 this->result_ = compound_expr (saved_elems, result);
2780 }
2781 }
2782
2783 /* Build an associative array literal. The common type of the all keys is
2784 taken to be the key type, and common type of all values the value type.
2785 All keys and values are then implicitly converted as needed. */
2786
2787 void visit (AssocArrayLiteralExp *e)
2788 {
2789 /* Want the mutable type for typeinfo reference. */
2790 Type *tb = e->type->toBasetype ()->mutableOf ();
b4c522fa
IB
2791
2792 /* Handle empty assoc array literals. */
89fdaf5a 2793 TypeAArray *ta = tb->isTypeAArray ();
2cbc99d1 2794 if (e->keys->length == 0)
b4c522fa
IB
2795 {
2796 this->result_ = build_constructor (build_ctype (ta), NULL);
2797 return;
2798 }
2799
2800 /* Build an expression that assigns all expressions in KEYS
2801 to a constructor. */
7508a7e9
IB
2802 tree akeys = build_array_from_exprs (ta->index->sarrayOf (e->keys->length),
2803 e->keys, this->constp_);
2804 tree init = stabilize_expr (&akeys);
b4c522fa
IB
2805
2806 /* Do the same with all expressions in VALUES. */
7508a7e9
IB
2807 tree avals = build_array_from_exprs (ta->next->sarrayOf (e->values->length),
2808 e->values, this->constp_);
2809 init = compound_expr (init, stabilize_expr (&avals));
b4c522fa
IB
2810
2811 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
2812 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
275bef5f
IB
2813 size_int (e->keys->length),
2814 build_address (akeys));
b4c522fa 2815 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
2cbc99d1 2816 size_int (e->values->length),
b4c522fa
IB
2817 build_address (avals));
2818
2819 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
c0aebc60 2820 build_typeinfo (e->loc, ta), keys, vals);
b4c522fa
IB
2821
2822 /* Return an associative array pointed to by MEM. */
2823 tree aatype = build_ctype (ta);
af3c19f0 2824 vec <constructor_elt, va_gc> *ce = NULL;
b4c522fa
IB
2825 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
2826
7508a7e9
IB
2827 tree result = build_nop (build_ctype (e->type),
2828 build_constructor (aatype, ce));
2829 this->result_ = compound_expr (init, result);
b4c522fa
IB
2830 }
2831
2832 /* Build a struct literal. */
2833
2834 void visit (StructLiteralExp *e)
2835 {
2836 /* Handle empty struct literals. */
2cbc99d1 2837 if (e->elements == NULL || e->sd->fields.length == 0)
b4c522fa
IB
2838 {
2839 this->result_ = build_constructor (build_ctype (e->type), NULL);
2840 return;
2841 }
2842
2843 /* Building sinit trees are delayed until after frontend semantic
2844 processing has complete. Build the static initializer now. */
2845 if (e->useStaticInit && !this->constp_)
2846 {
87e36d9b
IB
2847 tree init = aggregate_initializer_decl (e->sd);
2848
2849 /* If initializing a symbol, don't forget to set it. */
2850 if (e->sym != NULL)
2851 {
2852 tree var = build_deref (e->sym);
2853 init = compound_expr (modify_expr (var, init), var);
2854 }
2855
2856 this->result_ = init;
b4c522fa
IB
2857 return;
2858 }
2859
2860 /* Build a constructor that assigns the expressions in ELEMENTS
2861 at each field index that has been filled in. */
af3c19f0 2862 vec <constructor_elt, va_gc> *ve = NULL;
b4c522fa
IB
2863 tree saved_elems = NULL_TREE;
2864
2865 /* CTFE may fill the hidden pointer by NullExp. */
2cbc99d1 2866 gcc_assert (e->elements->length <= e->sd->fields.length);
b4c522fa
IB
2867
2868 Type *tb = e->type->toBasetype ();
5fee5ec3 2869 gcc_assert (tb->ty == TY::Tstruct);
b4c522fa 2870
2cbc99d1 2871 for (size_t i = 0; i < e->elements->length; i++)
b4c522fa
IB
2872 {
2873 Expression *exp = (*e->elements)[i];
2874 if (!exp)
2875 continue;
2876
2877 VarDeclaration *field = e->sd->fields[i];
2878 Type *type = exp->type->toBasetype ();
2879 Type *ftype = field->type->toBasetype ();
2880 tree value = NULL_TREE;
2881
5fee5ec3 2882 if (ftype->ty == TY::Tsarray && !same_type_p (type, ftype))
b4c522fa
IB
2883 {
2884 /* Initialize a static array with a single element. */
2ac51bdf
IB
2885 tree elem = build_expr (exp, this->constp_, true);
2886 saved_elems = compound_expr (saved_elems, stabilize_expr (&elem));
b4c522fa
IB
2887 elem = d_save_expr (elem);
2888
2889 if (initializer_zerop (elem))
2890 value = build_constructor (build_ctype (ftype), NULL);
2891 else
2892 value = build_array_from_val (ftype, elem);
2893 }
2894 else
2895 {
2ac51bdf 2896 value = convert_expr (build_expr (exp, this->constp_, true),
b4c522fa
IB
2897 exp->type, field->type);
2898 }
2899
2900 /* Split construction of values out of the constructor. */
2ac51bdf 2901 saved_elems = compound_expr (saved_elems, stabilize_expr (&value));
b4c522fa
IB
2902
2903 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
2904 }
2905
2906 /* Maybe setup hidden pointer to outer scope context. */
2cbc99d1 2907 if (e->sd->isNested () && e->elements->length != e->sd->fields.length
b4c522fa
IB
2908 && this->constp_ == false)
2909 {
2910 tree field = get_symbol_decl (e->sd->vthis);
2911 tree value = build_vthis (e->sd);
2912 CONSTRUCTOR_APPEND_ELT (ve, field, value);
2913 gcc_assert (e->useStaticInit == false);
2914 }
2915
2916 /* Build a constructor in the correct shape of the aggregate type. */
2917 tree ctor = build_struct_literal (build_ctype (e->type), ve);
2918
2919 /* Nothing more to do for constant literals. */
2920 if (this->constp_)
2921 {
2922 /* If the struct literal is a valid for static data. */
2923 if (TREE_CONSTANT (ctor)
2924 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
2925 TREE_STATIC (ctor) = 1;
2926
2927 this->result_ = compound_expr (saved_elems, ctor);
2928 return;
2929 }
2930
2ac51bdf 2931 /* Construct the struct literal for run-time. */
b4c522fa
IB
2932 if (e->sym != NULL)
2933 {
2ac51bdf 2934 /* Store the result in a symbol to initialize the literal. */
b4c522fa
IB
2935 tree var = build_deref (e->sym);
2936 ctor = compound_expr (modify_expr (var, ctor), var);
b4c522fa 2937 }
2ac51bdf 2938 else if (!this->literalp_)
b4c522fa 2939 {
2ac51bdf
IB
2940 /* Use memset to fill any alignment holes in the object. */
2941 if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
2942 {
2943 tree var = build_local_temp (TREE_TYPE (ctor));
2944 tree init = build_memset_call (var);
2945 /* Evaluate memset() first, then any saved element constructors. */
2946 saved_elems = compound_expr (init, saved_elems);
2947 ctor = compound_expr (modify_expr (var, ctor), var);
2948 }
b4c522fa 2949 }
2ac51bdf
IB
2950
2951 this->result_ = compound_expr (saved_elems, ctor);
b4c522fa
IB
2952 }
2953
2954 /* Build a null literal. */
2955
2956 void visit (NullExp *e)
2957 {
5e95646e 2958 this->result_ = build_typeof_null_value (e->type);
b4c522fa
IB
2959 }
2960
2961 /* Build a vector literal. */
2962
2963 void visit (VectorExp *e)
2964 {
2965 tree type = build_ctype (e->type);
b4c522fa
IB
2966
2967 /* First handle array literal expressions. */
9c7d5e88 2968 if (e->e1->op == EXP::arrayLiteral)
b4c522fa 2969 {
d873350a 2970 ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
af3c19f0 2971 vec <constructor_elt, va_gc> *elms = NULL;
b4c522fa
IB
2972 bool constant_p = true;
2973
2cbc99d1
IB
2974 vec_safe_reserve (elms, ale->elements->length);
2975 for (size_t i = 0; i < ale->elements->length; i++)
b4c522fa
IB
2976 {
2977 Expression *expr = ale->getElement (i);
2ac51bdf
IB
2978 tree value = d_convert (TREE_TYPE (type),
2979 build_expr (expr, this->constp_, true));
b4c522fa
IB
2980 if (!CONSTANT_CLASS_P (value))
2981 constant_p = false;
2982
2983 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
2984 }
2985
2986 /* Build a VECTOR_CST from a constant vector constructor. */
2987 if (constant_p)
2988 this->result_ = build_vector_from_ctor (type, elms);
2989 else
2990 this->result_ = build_constructor (type, elms);
2991 }
2992 else
2993 {
2994 /* Build constructor from single value. */
2ac51bdf
IB
2995 tree value = d_convert (TREE_TYPE (type),
2996 build_expr (e->e1, this->constp_, true));
2997 this->result_ = build_vector_from_val (type, value);
b4c522fa
IB
2998 }
2999 }
3000
b9da0278
IB
3001 /* Build a static array representation of a vector expression. */
3002
3003 void visit (VectorArrayExp *e)
3004 {
2ac51bdf 3005 this->result_ = convert_expr (build_expr (e->e1, this->constp_, true),
b9da0278
IB
3006 e->e1->type, e->type);
3007 }
3008
b4c522fa
IB
3009 /* Build a static class literal, return its reference. */
3010
3011 void visit (ClassReferenceExp *e)
3012 {
3013 /* The result of build_new_class_expr is a RECORD_TYPE, we want
3014 the reference. */
3015 tree var = build_address (build_new_class_expr (e));
3016
3017 /* If the type of this literal is an interface, the we must add the
3018 interface offset to symbol. */
3019 if (this->constp_)
3020 {
89fdaf5a 3021 TypeClass *tc = e->type->toBasetype ()->isTypeClass ();
b4c522fa
IB
3022 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
3023
3024 if (to != NULL)
3025 {
3026 ClassDeclaration *from = e->originalClass ();
3027 int offset = 0;
3028
3029 gcc_assert (to->isBaseOf (from, &offset) != 0);
3030
3031 if (offset != 0)
3032 var = build_offset (var, size_int (offset));
3033 }
3034 }
3035
3036 this->result_ = var;
3037 }
3038
3039 /* These expressions are mainly just a placeholders in the frontend.
3040 We shouldn't see them here. */
3041
3042 void visit (ScopeExp *e)
3043 {
3044 error_at (make_location_t (e->loc), "%qs is not an expression",
3045 e->toChars ());
3046 this->result_ = error_mark_node;
3047 }
3048
3049 void visit (TypeExp *e)
3050 {
3051 error_at (make_location_t (e->loc), "type %qs is not an expression",
3052 e->toChars ());
3053 this->result_ = error_mark_node;
3054 }
3055};
3056
3057
3058/* Main entry point for ExprVisitor interface to generate code for
3059 the Expression AST class E. If CONST_P is true, then E is a
2ac51bdf
IB
3060 constant expression. If LITERAL_P is true, then E is a value used
3061 in the initialization of another literal. */
b4c522fa
IB
3062
3063tree
2ac51bdf 3064build_expr (Expression *e, bool const_p, bool literal_p)
b4c522fa 3065{
2ac51bdf 3066 ExprVisitor v = ExprVisitor (const_p, literal_p);
b4c522fa
IB
3067 location_t saved_location = input_location;
3068
3069 input_location = make_location_t (e->loc);
3070 e->accept (&v);
3071 tree expr = v.result ();
3072 input_location = saved_location;
3073
3074 /* Check if initializer expression is valid constant. */
3075 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
3076 {
3077 error_at (make_location_t (e->loc), "non-constant expression %qs",
3078 e->toChars ());
3079 return error_mark_node;
3080 }
3081
3082 return expr;
3083}
3084
3085/* Same as build_expr, but also calls destructors on any temporaries. */
3086
3087tree
3088build_expr_dtor (Expression *e)
3089{
3090 /* Codegen can be improved by determining if no exceptions can be thrown
3091 between the ctor and dtor, and eliminating the ctor and dtor. */
3092 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3093 tree result = build_expr (e);
3094
3095 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3096 {
3097 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3098 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3099 }
3100
3101 return result;
3102}
3103
3104/* Same as build_expr_dtor, but handles the result of E as a return value. */
3105
3106tree
3107build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
3108{
3109 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
3110 tree result = build_expr (e);
3111
3112 /* Convert for initializing the DECL_RESULT. */
5fee5ec3 3113 if (tf->isref ())
5c9b7408
IB
3114 {
3115 /* If we are returning a reference, take the address. */
3116 result = convert_expr (result, e->type, type);
3117 result = build_address (result);
3118 }
3119 else
3120 result = convert_for_rvalue (result, e->type, type);
b4c522fa
IB
3121
3122 /* The decl to store the return expression. */
3123 tree decl = DECL_RESULT (cfun->decl);
3124
3125 /* Split comma expressions, so that the result is returned directly. */
3126 tree expr = stabilize_expr (&result);
3127 result = build_assign (INIT_EXPR, decl, result);
3128 result = compound_expr (expr, return_expr (result));
3129
3130 /* May nest the return expression inside the try/finally expression. */
3131 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
3132 {
3133 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
3134 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
3135 }
3136
3137 return result;
3138}
3139