Merge dmd upstream e2fe2687b
[official-gcc.git] / gcc / d / dmd / constfold.c
blobc3df013d802393cc804e76fbbc32659cbdae8e8f
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/constfold.c
9 */
11 #include "root/dsystem.h" // mem{cpy|set|cmp}()
13 #ifndef IN_GCC
14 #include <math.h>
15 #endif
17 #include "root/rmem.h"
18 #include "root/root.h"
19 #include "root/port.h"
21 #include "errors.h"
22 #include "mtype.h"
23 #include "expression.h"
24 #include "aggregate.h"
25 #include "declaration.h"
26 #include "utf.h"
27 #include "ctfe.h"
28 #include "target.h"
30 int RealEquals(real_t x1, real_t x2);
32 Expression *expType(Type *type, Expression *e)
34 if (type != e->type)
36 e = e->copy();
37 e->type = type;
39 return e;
42 /* ================================== isConst() ============================== */
44 int isConst(Expression *e)
46 //printf("Expression::isConst(): %s\n", e->toChars());
47 switch (e->op)
49 case TOKint64:
50 case TOKfloat64:
51 case TOKcomplex80:
52 return 1;
53 case TOKnull:
54 return 0;
55 case TOKsymoff:
56 return 2;
57 default:
58 return 0;
60 assert(0);
61 return 0;
64 /* =============================== constFold() ============================== */
66 /* The constFold() functions were redundant with the optimize() ones,
67 * and so have been folded in with them.
70 /* ========================================================================== */
72 UnionExp Neg(Type *type, Expression *e1)
74 UnionExp ue;
75 Loc loc = e1->loc;
77 if (e1->type->isreal())
79 new(&ue) RealExp(loc, -e1->toReal(), type);
81 else if (e1->type->isimaginary())
83 new(&ue) RealExp(loc, -e1->toImaginary(), type);
85 else if (e1->type->iscomplex())
87 new(&ue) ComplexExp(loc, -e1->toComplex(), type);
89 else
91 new(&ue) IntegerExp(loc, -e1->toInteger(), type);
93 return ue;
96 UnionExp Com(Type *type, Expression *e1)
98 UnionExp ue;
99 Loc loc = e1->loc;
101 new(&ue) IntegerExp(loc, ~e1->toInteger(), type);
102 return ue;
105 UnionExp Not(Type *type, Expression *e1)
107 UnionExp ue;
108 Loc loc = e1->loc;
110 new(&ue) IntegerExp(loc, e1->isBool(false) ? 1 : 0, type);
111 return ue;
114 UnionExp Bool(Type *type, Expression *e1)
116 UnionExp ue;
117 Loc loc = e1->loc;
119 new(&ue) IntegerExp(loc, e1->isBool(true) ? 1 : 0, type);
120 return ue;
123 UnionExp Add(Loc loc, Type *type, Expression *e1, Expression *e2)
125 UnionExp ue;
127 if (type->isreal())
129 new(&ue) RealExp(loc, e1->toReal() + e2->toReal(), type);
131 else if (type->isimaginary())
133 new(&ue) RealExp(loc, e1->toImaginary() + e2->toImaginary(), type);
135 else if (type->iscomplex())
137 // This rigamarole is necessary so that -0.0 doesn't get
138 // converted to +0.0 by doing an extraneous add with +0.0
139 complex_t c1 = complex_t(CTFloat::zero);
140 real_t r1 = CTFloat::zero;
141 real_t i1 = CTFloat::zero;
143 complex_t c2 = complex_t(CTFloat::zero);
144 real_t r2 = CTFloat::zero;
145 real_t i2 = CTFloat::zero;
147 complex_t v = complex_t(CTFloat::zero);
148 int x;
150 if (e1->type->isreal())
152 r1 = e1->toReal();
153 x = 0;
155 else if (e1->type->isimaginary())
157 i1 = e1->toImaginary();
158 x = 3;
160 else
162 c1 = e1->toComplex();
163 x = 6;
166 if (e2->type->isreal())
168 r2 = e2->toReal();
170 else if (e2->type->isimaginary())
172 i2 = e2->toImaginary();
173 x += 1;
175 else
177 c2 = e2->toComplex();
178 x += 2;
181 switch (x)
183 case 0 + 0:
184 v = complex_t(r1 + r2);
185 break;
186 case 0 + 1:
187 v = complex_t(r1, i2);
188 break;
189 case 0 + 2:
190 v = complex_t(r1 + creall(c2), cimagl(c2));
191 break;
192 case 3 + 0:
193 v = complex_t(r2, i1);
194 break;
195 case 3 + 1:
196 v = complex_t(CTFloat::zero, i1 + i2);
197 break;
198 case 3 + 2:
199 v = complex_t(creall(c2), i1 + cimagl(c2));
200 break;
201 case 6 + 0:
202 v = complex_t(creall(c1) + r2, cimagl(c2));
203 break;
204 case 6 + 1:
205 v = complex_t(creall(c1), cimagl(c1) + i2);
206 break;
207 case 6 + 2:
208 v = c1 + c2;
209 break;
210 default:
211 assert(0);
213 new(&ue) ComplexExp(loc, v, type);
215 else if (e1->op == TOKsymoff)
217 SymOffExp *soe = (SymOffExp *)e1;
218 new(&ue) SymOffExp(loc, soe->var, soe->offset + e2->toInteger());
219 ue.exp()->type = type;
221 else if (e2->op == TOKsymoff)
223 SymOffExp *soe = (SymOffExp *)e2;
224 new(&ue) SymOffExp(loc, soe->var, soe->offset + e1->toInteger());
225 ue.exp()->type = type;
227 else
228 new(&ue) IntegerExp(loc, e1->toInteger() + e2->toInteger(), type);
229 return ue;
233 UnionExp Min(Loc loc, Type *type, Expression *e1, Expression *e2)
235 UnionExp ue;
237 if (type->isreal())
239 new(&ue) RealExp(loc, e1->toReal() - e2->toReal(), type);
241 else if (type->isimaginary())
243 new(&ue) RealExp(loc, e1->toImaginary() - e2->toImaginary(), type);
245 else if (type->iscomplex())
247 // This rigamarole is necessary so that -0.0 doesn't get
248 // converted to +0.0 by doing an extraneous add with +0.0
249 complex_t c1 = complex_t(CTFloat::zero);
250 real_t r1 = CTFloat::zero;
251 real_t i1 = CTFloat::zero;
253 complex_t c2 = complex_t(CTFloat::zero);
254 real_t r2 = CTFloat::zero;
255 real_t i2 = CTFloat::zero;
257 complex_t v = complex_t(CTFloat::zero);
258 int x;
260 if (e1->type->isreal())
262 r1 = e1->toReal();
263 x = 0;
265 else if (e1->type->isimaginary())
267 i1 = e1->toImaginary();
268 x = 3;
270 else
272 c1 = e1->toComplex();
273 x = 6;
276 if (e2->type->isreal())
278 r2 = e2->toReal();
280 else if (e2->type->isimaginary())
282 i2 = e2->toImaginary();
283 x += 1;
285 else
287 c2 = e2->toComplex();
288 x += 2;
291 switch (x)
293 case 0 + 0:
294 v = complex_t(r1 - r2);
295 break;
296 case 0 + 1:
297 v = complex_t(r1, -i2);
298 break;
299 case 0 + 2:
300 v = complex_t(r1 - creall(c2), -cimagl(c2));
301 break;
302 case 3 + 0:
303 v = complex_t(-r2, i1);
304 break;
305 case 3 + 1:
306 v = complex_t(CTFloat::zero, i1 - i2);
307 break;
308 case 3 + 2:
309 v = complex_t(-creall(c2), i1 - cimagl(c2));
310 break;
311 case 6 + 0:
312 v = complex_t(creall(c1) - r2, cimagl(c1));
313 break;
314 case 6 + 1:
315 v = complex_t(creall(c1), cimagl(c1) - i2);
316 break;
317 case 6 + 2:
318 v = c1 - c2;
319 break;
320 default:
321 assert(0);
323 new(&ue) ComplexExp(loc, v, type);
325 else if (e1->op == TOKsymoff)
327 SymOffExp *soe = (SymOffExp *)e1;
328 new(&ue) SymOffExp(loc, soe->var, soe->offset - e2->toInteger());
329 ue.exp()->type = type;
331 else
333 new(&ue) IntegerExp(loc, e1->toInteger() - e2->toInteger(), type);
335 return ue;
338 UnionExp Mul(Loc loc, Type *type, Expression *e1, Expression *e2)
340 UnionExp ue;
342 if (type->isfloating())
344 complex_t c = complex_t(CTFloat::zero);
345 real_t r;
347 if (e1->type->isreal())
349 r = e1->toReal();
350 c = e2->toComplex();
351 c = complex_t(r * creall(c), r * cimagl(c));
353 else if (e1->type->isimaginary())
355 r = e1->toImaginary();
356 c = e2->toComplex();
357 c = complex_t(-r * cimagl(c), r * creall(c));
359 else if (e2->type->isreal())
361 r = e2->toReal();
362 c = e1->toComplex();
363 c = complex_t(r * creall(c), r * cimagl(c));
365 else if (e2->type->isimaginary())
367 r = e2->toImaginary();
368 c = e1->toComplex();
369 c = complex_t(-r * cimagl(c), r * creall(c));
371 else
372 c = e1->toComplex() * e2->toComplex();
374 if (type->isreal())
375 new(&ue) RealExp(loc, creall(c), type);
376 else if (type->isimaginary())
377 new(&ue) RealExp(loc, cimagl(c), type);
378 else if (type->iscomplex())
379 new(&ue) ComplexExp(loc, c, type);
380 else
381 assert(0);
383 else
385 new(&ue) IntegerExp(loc, e1->toInteger() * e2->toInteger(), type);
387 return ue;
390 UnionExp Div(Loc loc, Type *type, Expression *e1, Expression *e2)
392 UnionExp ue;
394 if (type->isfloating())
396 complex_t c = complex_t(CTFloat::zero);
397 real_t r;
399 //e1->type->print();
400 //e2->type->print();
401 if (e2->type->isreal())
403 if (e1->type->isreal())
405 new(&ue) RealExp(loc, e1->toReal() / e2->toReal(), type);
406 return ue;
408 r = e2->toReal();
409 c = e1->toComplex();
410 c = complex_t(creall(c) / r, cimagl(c) / r);
412 else if (e2->type->isimaginary())
414 r = e2->toImaginary();
415 c = e1->toComplex();
416 c = complex_t(cimagl(c) / r, -creall(c) / r);
418 else
420 c = e1->toComplex() / e2->toComplex();
423 if (type->isreal())
424 new(&ue) RealExp(loc, creall(c), type);
425 else if (type->isimaginary())
426 new(&ue) RealExp(loc, cimagl(c), type);
427 else if (type->iscomplex())
428 new(&ue) ComplexExp(loc, c, type);
429 else
430 assert(0);
432 else
434 sinteger_t n1;
435 sinteger_t n2;
436 sinteger_t n;
438 n1 = e1->toInteger();
439 n2 = e2->toInteger();
440 if (n2 == 0)
442 e2->error("divide by 0");
443 new(&ue) ErrorExp();
444 return ue;
446 if (n2 == -1 && !type->isunsigned())
448 // Check for int.min / -1
449 if ((dinteger_t)n1 == 0xFFFFFFFF80000000ULL && type->toBasetype()->ty != Tint64)
451 e2->error("integer overflow: int.min / -1");
452 new(&ue) ErrorExp();
453 return ue;
455 else if ((dinteger_t)n1 == 0x8000000000000000LL) // long.min / -1
457 e2->error("integer overflow: long.min / -1");
458 new(&ue) ErrorExp();
459 return ue;
462 if (e1->type->isunsigned() || e2->type->isunsigned())
463 n = ((dinteger_t) n1) / ((dinteger_t) n2);
464 else
465 n = n1 / n2;
466 new(&ue) IntegerExp(loc, n, type);
468 return ue;
471 UnionExp Mod(Loc loc, Type *type, Expression *e1, Expression *e2)
473 UnionExp ue;
475 if (type->isfloating())
477 complex_t c = complex_t(CTFloat::zero);
479 if (e2->type->isreal())
481 real_t r2 = e2->toReal();
483 #ifdef IN_GCC
484 c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2);
485 #else
486 c = complex_t(::fmodl(e1->toReal(), r2), ::fmodl(e1->toImaginary(), r2));
487 #endif
489 else if (e2->type->isimaginary())
491 real_t i2 = e2->toImaginary();
493 #ifdef IN_GCC
494 c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2);
495 #else
496 c = complex_t(::fmodl(e1->toReal(), i2), ::fmodl(e1->toImaginary(), i2));
497 #endif
499 else
500 assert(0);
502 if (type->isreal())
503 new(&ue) RealExp(loc, creall(c), type);
504 else if (type->isimaginary())
505 new(&ue) RealExp(loc, cimagl(c), type);
506 else if (type->iscomplex())
507 new(&ue) ComplexExp(loc, c, type);
508 else
509 assert(0);
511 else
513 sinteger_t n1;
514 sinteger_t n2;
515 sinteger_t n;
517 n1 = e1->toInteger();
518 n2 = e2->toInteger();
519 if (n2 == 0)
521 e2->error("divide by 0");
522 new(&ue) ErrorExp();
523 return ue;
525 if (n2 == -1 && !type->isunsigned())
527 // Check for int.min % -1
528 if ((dinteger_t)n1 == 0xFFFFFFFF80000000ULL && type->toBasetype()->ty != Tint64)
530 e2->error("integer overflow: int.min %% -1");
531 new(&ue) ErrorExp();
532 return ue;
534 else if ((dinteger_t)n1 == 0x8000000000000000LL) // long.min % -1
536 e2->error("integer overflow: long.min %% -1");
537 new(&ue) ErrorExp();
538 return ue;
541 if (e1->type->isunsigned() || e2->type->isunsigned())
542 n = ((dinteger_t) n1) % ((dinteger_t) n2);
543 else
544 n = n1 % n2;
545 new(&ue) IntegerExp(loc, n, type);
547 return ue;
550 UnionExp Pow(Loc loc, Type *type, Expression *e1, Expression *e2)
552 UnionExp ue;
554 // Handle integer power operations.
555 if (e2->type->isintegral())
557 dinteger_t n = e2->toInteger();
558 bool neg;
560 if (!e2->type->isunsigned() && (sinteger_t)n < 0)
562 if (e1->type->isintegral())
564 new(&ue) CTFEExp(TOKcantexp);
565 return ue;
568 // Don't worry about overflow, from now on n is unsigned.
569 neg = true;
570 n = -n;
572 else
573 neg = false;
575 UnionExp ur, uv;
576 if (e1->type->iscomplex())
578 new(&ur) ComplexExp(loc, e1->toComplex(), e1->type);
579 new(&uv) ComplexExp(loc, complex_t(CTFloat::one), e1->type);
581 else if (e1->type->isfloating())
583 new(&ur) RealExp(loc, e1->toReal(), e1->type);
584 new(&uv) RealExp(loc, CTFloat::one, e1->type);
586 else
588 new(&ur) IntegerExp(loc, e1->toInteger(), e1->type);
589 new(&uv) IntegerExp(loc, 1, e1->type);
592 Expression* r = ur.exp();
593 Expression* v = uv.exp();
594 while (n != 0)
596 if (n & 1)
598 // v = v * r;
599 uv = Mul(loc, v->type, v, r);
601 n >>= 1;
602 // r = r * r
603 ur = Mul(loc, r->type, r, r);
606 if (neg)
608 // ue = 1.0 / v
609 UnionExp one;
610 new(&one) RealExp(loc, CTFloat::one, v->type);
611 uv = Div(loc, v->type, one.exp(), v);
614 if (type->iscomplex())
615 new(&ue) ComplexExp(loc, v->toComplex(), type);
616 else if (type->isintegral())
617 new(&ue) IntegerExp(loc, v->toInteger(), type);
618 else
619 new(&ue) RealExp(loc, v->toReal(), type);
621 else if (e2->type->isfloating())
623 // x ^^ y for x < 0 and y not an integer is not defined; so set result as NaN
624 if (e1->toReal() < CTFloat::zero)
626 new(&ue) RealExp(loc, Target::RealProperties::nan, type);
628 else
629 new(&ue) CTFEExp(TOKcantexp);
631 else
632 new(&ue) CTFEExp(TOKcantexp);
634 return ue;
637 UnionExp Shl(Loc loc, Type *type, Expression *e1, Expression *e2)
639 UnionExp ue;
640 new(&ue) IntegerExp(loc, e1->toInteger() << e2->toInteger(), type);
641 return ue;
644 UnionExp Shr(Loc loc, Type *type, Expression *e1, Expression *e2)
646 UnionExp ue;
647 dinteger_t value = e1->toInteger();
648 dinteger_t dcount = e2->toInteger();
649 assert(dcount <= 0xFFFFFFFF);
650 unsigned count = (unsigned)dcount;
651 switch (e1->type->toBasetype()->ty)
653 case Tint8:
654 value = (d_int8)(value) >> count;
655 break;
657 case Tuns8:
658 case Tchar:
659 value = (d_uns8)(value) >> count;
660 break;
662 case Tint16:
663 value = (d_int16)(value) >> count;
664 break;
666 case Tuns16:
667 case Twchar:
668 value = (d_uns16)(value) >> count;
669 break;
671 case Tint32:
672 value = (d_int32)(value) >> count;
673 break;
675 case Tuns32:
676 case Tdchar:
677 value = (d_uns32)(value) >> count;
678 break;
680 case Tint64:
681 value = (d_int64)(value) >> count;
682 break;
684 case Tuns64:
685 value = (d_uns64)(value) >> count;
686 break;
688 case Terror:
689 new(&ue) ErrorExp();
690 return ue;
692 default:
693 assert(0);
695 new(&ue) IntegerExp(loc, value, type);
696 return ue;
699 UnionExp Ushr(Loc loc, Type *type, Expression *e1, Expression *e2)
701 UnionExp ue;
702 dinteger_t value = e1->toInteger();
703 dinteger_t dcount = e2->toInteger();
704 assert(dcount <= 0xFFFFFFFF);
705 unsigned count = (unsigned)dcount;
706 switch (e1->type->toBasetype()->ty)
708 case Tint8:
709 case Tuns8:
710 case Tchar:
711 // Possible only with >>>=. >>> always gets promoted to int.
712 value = (value & 0xFF) >> count;
713 break;
715 case Tint16:
716 case Tuns16:
717 case Twchar:
718 // Possible only with >>>=. >>> always gets promoted to int.
719 value = (value & 0xFFFF) >> count;
720 break;
722 case Tint32:
723 case Tuns32:
724 case Tdchar:
725 value = (value & 0xFFFFFFFF) >> count;
726 break;
728 case Tint64:
729 case Tuns64:
730 value = (d_uns64)(value) >> count;
731 break;
733 case Terror:
734 new(&ue) ErrorExp();
735 return ue;
737 default:
738 assert(0);
740 new(&ue) IntegerExp(loc, value, type);
741 return ue;
744 UnionExp And(Loc loc, Type *type, Expression *e1, Expression *e2)
746 UnionExp ue;
747 new(&ue) IntegerExp(loc, e1->toInteger() & e2->toInteger(), type);
748 return ue;
751 UnionExp Or(Loc loc, Type *type, Expression *e1, Expression *e2)
753 UnionExp ue;
754 new(&ue) IntegerExp(loc, e1->toInteger() | e2->toInteger(), type);
755 return ue;
758 UnionExp Xor(Loc loc, Type *type, Expression *e1, Expression *e2)
760 UnionExp ue;
761 new(&ue) IntegerExp(loc, e1->toInteger() ^ e2->toInteger(), type);
762 return ue;
765 /* Also returns TOKcantexp if cannot be computed.
767 UnionExp Equal(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2)
769 UnionExp ue;
770 int cmp = 0;
771 real_t r1;
772 real_t r2;
774 //printf("Equal(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
776 assert(op == TOKequal || op == TOKnotequal);
778 if (e1->op == TOKnull)
780 if (e2->op == TOKnull)
781 cmp = 1;
782 else if (e2->op == TOKstring)
784 StringExp *es2 = (StringExp *)e2;
785 cmp = (0 == es2->len);
787 else if (e2->op == TOKarrayliteral)
789 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
790 cmp = !es2->elements || (0 == es2->elements->dim);
792 else
794 new(&ue) CTFEExp(TOKcantexp);
795 return ue;
798 else if (e2->op == TOKnull)
800 if (e1->op == TOKstring)
802 StringExp *es1 = (StringExp *)e1;
803 cmp = (0 == es1->len);
805 else if (e1->op == TOKarrayliteral)
807 ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
808 cmp = !es1->elements || (0 == es1->elements->dim);
810 else
812 new(&ue) CTFEExp(TOKcantexp);
813 return ue;
816 else if (e1->op == TOKstring && e2->op == TOKstring)
818 StringExp *es1 = (StringExp *)e1;
819 StringExp *es2 = (StringExp *)e2;
821 if (es1->sz != es2->sz)
823 assert(global.errors);
824 new(&ue) CTFEExp(TOKcantexp);
825 return ue;
827 if (es1->len == es2->len &&
828 memcmp(es1->string, es2->string, es1->sz * es1->len) == 0)
829 cmp = 1;
830 else
831 cmp = 0;
833 else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral)
835 ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
836 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
838 if ((!es1->elements || !es1->elements->dim) &&
839 (!es2->elements || !es2->elements->dim))
840 cmp = 1; // both arrays are empty
841 else if (!es1->elements || !es2->elements)
842 cmp = 0;
843 else if (es1->elements->dim != es2->elements->dim)
844 cmp = 0;
845 else
847 for (size_t i = 0; i < es1->elements->dim; i++)
849 Expression *ee1 = es1->getElement(i);
850 Expression *ee2 = es2->getElement(i);
851 ue = Equal(TOKequal, loc, Type::tint32, ee1, ee2);
852 if (CTFEExp::isCantExp(ue.exp()))
853 return ue;
854 cmp = (int)ue.exp()->toInteger();
855 if (cmp == 0)
856 break;
860 else if (e1->op == TOKarrayliteral && e2->op == TOKstring)
862 // Swap operands and use common code
863 Expression *etmp = e1;
864 e1 = e2;
865 e2 = etmp;
866 goto Lsa;
868 else if (e1->op == TOKstring && e2->op == TOKarrayliteral)
870 Lsa:
871 StringExp *es1 = (StringExp *)e1;
872 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
873 size_t dim1 = es1->len;
874 size_t dim2 = es2->elements ? es2->elements->dim : 0;
875 if (dim1 != dim2)
876 cmp = 0;
877 else
879 cmp = 1; // if dim1 winds up being 0
880 for (size_t i = 0; i < dim1; i++)
882 uinteger_t c = es1->charAt(i);
883 Expression *ee2 = es2->getElement(i);
884 if (ee2->isConst() != 1)
886 new(&ue) CTFEExp(TOKcantexp);
887 return ue;
889 cmp = (c == ee2->toInteger());
890 if (cmp == 0)
891 break;
895 else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral)
897 StructLiteralExp *es1 = (StructLiteralExp *)e1;
898 StructLiteralExp *es2 = (StructLiteralExp *)e2;
900 if (es1->sd != es2->sd)
901 cmp = 0;
902 else if ((!es1->elements || !es1->elements->dim) &&
903 (!es2->elements || !es2->elements->dim))
904 cmp = 1; // both arrays are empty
905 else if (!es1->elements || !es2->elements)
906 cmp = 0;
907 else if (es1->elements->dim != es2->elements->dim)
908 cmp = 0;
909 else
911 cmp = 1;
912 for (size_t i = 0; i < es1->elements->dim; i++)
914 Expression *ee1 = (*es1->elements)[i];
915 Expression *ee2 = (*es2->elements)[i];
917 if (ee1 == ee2)
918 continue;
919 if (!ee1 || !ee2)
921 cmp = 0;
922 break;
924 ue = Equal(TOKequal, loc, Type::tint32, ee1, ee2);
925 if (ue.exp()->op == TOKcantexp)
926 return ue;
927 cmp = (int)ue.exp()->toInteger();
928 if (cmp == 0)
929 break;
933 else if (e1->isConst() != 1 || e2->isConst() != 1)
935 new(&ue) CTFEExp(TOKcantexp);
936 return ue;
938 else if (e1->type->isreal())
940 r1 = e1->toReal();
941 r2 = e2->toReal();
942 goto L1;
944 else if (e1->type->isimaginary())
946 r1 = e1->toImaginary();
947 r2 = e2->toImaginary();
949 if (CTFloat::isNaN(r1) || CTFloat::isNaN(r2)) // if unordered
951 cmp = 0;
953 else
955 cmp = (r1 == r2);
958 else if (e1->type->iscomplex())
960 cmp = e1->toComplex() == e2->toComplex();
962 else if (e1->type->isintegral() || e1->type->toBasetype()->ty == Tpointer)
964 cmp = (e1->toInteger() == e2->toInteger());
966 else
968 new(&ue) CTFEExp(TOKcantexp);
969 return ue;
972 if (op == TOKnotequal)
973 cmp ^= 1;
974 new(&ue) IntegerExp(loc, cmp, type);
975 return ue;
978 UnionExp Identity(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2)
980 UnionExp ue;
981 int cmp;
983 if (e1->op == TOKnull)
985 cmp = (e2->op == TOKnull);
987 else if (e2->op == TOKnull)
989 cmp = 0;
991 else if (e1->op == TOKsymoff && e2->op == TOKsymoff)
993 SymOffExp *es1 = (SymOffExp *)e1;
994 SymOffExp *es2 = (SymOffExp *)e2;
996 cmp = (es1->var == es2->var && es1->offset == es2->offset);
998 else
1000 if (e1->type->isreal())
1002 cmp = RealEquals(e1->toReal(), e2->toReal());
1004 else if (e1->type->isimaginary())
1006 cmp = RealEquals(e1->toImaginary(), e2->toImaginary());
1008 else if (e1->type->iscomplex())
1010 complex_t v1 = e1->toComplex();
1011 complex_t v2 = e2->toComplex();
1012 cmp = RealEquals(creall(v1), creall(v2)) &&
1013 RealEquals(cimagl(v1), cimagl(v1));
1015 else
1017 ue = Equal((op == TOKidentity) ? TOKequal : TOKnotequal, loc, type, e1, e2);
1018 return ue;
1021 if (op == TOKnotidentity)
1022 cmp ^= 1;
1023 new(&ue) IntegerExp(loc, cmp, type);
1024 return ue;
1028 UnionExp Cmp(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2)
1030 UnionExp ue;
1031 dinteger_t n;
1032 real_t r1;
1033 real_t r2;
1035 //printf("Cmp(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1037 if (e1->op == TOKstring && e2->op == TOKstring)
1039 StringExp *es1 = (StringExp *)e1;
1040 StringExp *es2 = (StringExp *)e2;
1041 size_t sz = es1->sz;
1042 assert(sz == es2->sz);
1044 size_t len = es1->len;
1045 if (es2->len < len)
1046 len = es2->len;
1048 int rawCmp = memcmp(es1->string, es2->string, sz * len);
1049 if (rawCmp == 0)
1050 rawCmp = (int)(es1->len - es2->len);
1051 n = specificCmp(op, rawCmp);
1053 else if (e1->isConst() != 1 || e2->isConst() != 1)
1055 new(&ue) CTFEExp(TOKcantexp);
1056 return ue;
1058 else if (e1->type->isreal())
1060 r1 = e1->toReal();
1061 r2 = e2->toReal();
1062 goto L1;
1064 else if (e1->type->isimaginary())
1066 r1 = e1->toImaginary();
1067 r2 = e2->toImaginary();
1069 n = realCmp(op, r1, r2);
1071 else if (e1->type->iscomplex())
1073 assert(0);
1075 else
1077 sinteger_t n1;
1078 sinteger_t n2;
1080 n1 = e1->toInteger();
1081 n2 = e2->toInteger();
1082 if (e1->type->isunsigned() || e2->type->isunsigned())
1083 n = intUnsignedCmp(op, n1, n2);
1084 else
1085 n = intSignedCmp(op, n1, n2);
1087 new(&ue) IntegerExp(loc, n, type);
1088 return ue;
1091 /* Also returns TOKcantexp if cannot be computed.
1092 * to: type to cast to
1093 * type: type to paint the result
1096 UnionExp Cast(Loc loc, Type *type, Type *to, Expression *e1)
1098 UnionExp ue;
1099 Type *tb = to->toBasetype();
1100 Type *typeb = type->toBasetype();
1102 //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars());
1103 //printf("\te1->type = %s\n", e1->type->toChars());
1104 if (e1->type->equals(type) && type->equals(to))
1106 new(&ue) UnionExp(e1);
1107 return ue;
1110 if (e1->op == TOKvector && ((TypeVector *)e1->type)->basetype->equals(type) && type->equals(to))
1112 Expression *ex = ((VectorExp *)e1)->e1;
1113 new(&ue) UnionExp(ex);
1114 return ue;
1117 if (e1->type->implicitConvTo(to) >= MATCHconst ||
1118 to->implicitConvTo(e1->type) >= MATCHconst)
1120 goto L1;
1123 // Allow covariant converions of delegates
1124 // (Perhaps implicit conversion from pure to impure should be a MATCHconst,
1125 // then we wouldn't need this extra check.)
1126 if (e1->type->toBasetype()->ty == Tdelegate &&
1127 e1->type->implicitConvTo(to) == MATCHconvert)
1129 goto L1;
1132 /* Allow casting from one string type to another
1134 if (e1->op == TOKstring)
1136 if (tb->ty == Tarray && typeb->ty == Tarray &&
1137 tb->nextOf()->size() == typeb->nextOf()->size())
1139 goto L1;
1143 if (e1->op == TOKarrayliteral && typeb == tb)
1146 Expression *ex = expType(to, e1);
1147 new(&ue) UnionExp(ex);
1148 return ue;
1151 if (e1->isConst() != 1)
1153 new(&ue) CTFEExp(TOKcantexp);
1155 else if (tb->ty == Tbool)
1157 new(&ue) IntegerExp(loc, e1->toInteger() != 0, type);
1159 else if (type->isintegral())
1161 if (e1->type->isfloating())
1163 dinteger_t result;
1164 real_t r = e1->toReal();
1166 switch (typeb->ty)
1168 case Tint8:
1169 result = (d_int8)(sinteger_t)r;
1170 break;
1171 case Tchar:
1172 case Tuns8:
1173 result = (d_uns8)(dinteger_t)r;
1174 break;
1175 case Tint16:
1176 result = (d_int16)(sinteger_t)r;
1177 break;
1178 case Twchar:
1179 case Tuns16:
1180 result = (d_uns16)(dinteger_t)r;
1181 break;
1182 case Tint32:
1183 result = (d_int32)r;
1184 break;
1185 case Tdchar:
1186 case Tuns32:
1187 result = (d_uns32)r;
1188 break;
1189 case Tint64:
1190 result = (d_int64)r;
1191 break;
1192 case Tuns64:
1193 result = (d_uns64)r;
1194 break;
1195 default:
1196 assert(0);
1199 new(&ue) IntegerExp(loc, result, type);
1201 else if (type->isunsigned())
1202 new(&ue) IntegerExp(loc, e1->toUInteger(), type);
1203 else
1204 new(&ue) IntegerExp(loc, e1->toInteger(), type);
1206 else if (tb->isreal())
1208 real_t value = e1->toReal();
1210 new(&ue) RealExp(loc, value, type);
1212 else if (tb->isimaginary())
1214 real_t value = e1->toImaginary();
1216 new(&ue) RealExp(loc, value, type);
1218 else if (tb->iscomplex())
1220 complex_t value = e1->toComplex();
1222 new(&ue) ComplexExp(loc, value, type);
1224 else if (tb->isscalar())
1226 new(&ue) IntegerExp(loc, e1->toInteger(), type);
1228 else if (tb->ty == Tvoid)
1230 new(&ue) CTFEExp(TOKcantexp);
1232 else if (tb->ty == Tstruct && e1->op == TOKint64)
1234 // Struct = 0;
1235 StructDeclaration *sd = tb->toDsymbol(NULL)->isStructDeclaration();
1236 assert(sd);
1237 Expressions *elements = new Expressions;
1238 for (size_t i = 0; i < sd->fields.dim; i++)
1240 VarDeclaration *v = sd->fields[i];
1241 UnionExp zero;
1242 new(&zero) IntegerExp(0);
1243 ue = Cast(loc, v->type, v->type, zero.exp());
1244 if (ue.exp()->op == TOKcantexp)
1245 return ue;
1246 elements->push(ue.exp()->copy());
1248 new(&ue) StructLiteralExp(loc, sd, elements);
1249 ue.exp()->type = type;
1251 else
1253 if (type != Type::terror)
1255 // have to change to Internal Compiler Error
1256 // all invalid casts should be handled already in Expression::castTo().
1257 error(loc, "cannot cast %s to %s", e1->type->toChars(), type->toChars());
1259 new(&ue) ErrorExp();
1261 return ue;
1265 UnionExp ArrayLength(Type *type, Expression *e1)
1267 UnionExp ue;
1268 Loc loc = e1->loc;
1270 if (e1->op == TOKstring)
1272 StringExp *es1 = (StringExp *)e1;
1274 new(&ue) IntegerExp(loc, es1->len, type);
1276 else if (e1->op == TOKarrayliteral)
1278 ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1279 size_t dim = ale->elements ? ale->elements->dim : 0;
1281 new(&ue) IntegerExp(loc, dim, type);
1283 else if (e1->op == TOKassocarrayliteral)
1285 AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e1;
1286 size_t dim = ale->keys->dim;
1288 new(&ue) IntegerExp(loc, dim, type);
1290 else if (e1->type->toBasetype()->ty == Tsarray)
1292 Expression *e = ((TypeSArray *)e1->type->toBasetype())->dim;
1293 new(&ue) UnionExp(e);
1295 else
1296 new(&ue) CTFEExp(TOKcantexp);
1297 return ue;
1300 /* Also return TOKcantexp if this fails
1302 UnionExp Index(Type *type, Expression *e1, Expression *e2)
1304 UnionExp ue;
1305 Loc loc = e1->loc;
1307 //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1308 assert(e1->type);
1309 if (e1->op == TOKstring && e2->op == TOKint64)
1311 StringExp *es1 = (StringExp *)e1;
1312 uinteger_t i = e2->toInteger();
1314 if (i >= es1->len)
1316 e1->error("string index %llu is out of bounds [0 .. %llu]", i, (ulonglong)es1->len);
1317 new(&ue) ErrorExp();
1319 else
1321 new(&ue) IntegerExp(loc, es1->charAt(i), type);
1324 else if (e1->type->toBasetype()->ty == Tsarray && e2->op == TOKint64)
1326 TypeSArray *tsa = (TypeSArray *)e1->type->toBasetype();
1327 uinteger_t length = tsa->dim->toInteger();
1328 uinteger_t i = e2->toInteger();
1330 if (i >= length)
1332 e1->error("array index %llu is out of bounds %s[0 .. %llu]", i, e1->toChars(), length);
1333 new(&ue) ErrorExp();
1335 else if (e1->op == TOKarrayliteral)
1337 ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1338 Expression *e = ale->getElement((size_t)i);
1339 e->type = type;
1340 e->loc = loc;
1341 if (hasSideEffect(e))
1342 new(&ue) CTFEExp(TOKcantexp);
1343 else
1344 new(&ue) UnionExp(e);
1346 else
1347 new(&ue) CTFEExp(TOKcantexp);
1349 else if (e1->type->toBasetype()->ty == Tarray && e2->op == TOKint64)
1351 uinteger_t i = e2->toInteger();
1353 if (e1->op == TOKarrayliteral)
1355 ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1356 if (i >= ale->elements->dim)
1358 e1->error("array index %llu is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim);
1359 new(&ue) ErrorExp();
1361 else
1363 Expression *e = ale->getElement((size_t)i);
1364 e->type = type;
1365 e->loc = loc;
1366 if (hasSideEffect(e))
1367 new(&ue) CTFEExp(TOKcantexp);
1368 else
1369 new(&ue) UnionExp(e);
1372 else
1373 new(&ue) CTFEExp(TOKcantexp);
1375 else if (e1->op == TOKassocarrayliteral)
1377 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e1;
1378 /* Search the keys backwards, in case there are duplicate keys
1380 for (size_t i = ae->keys->dim; i;)
1382 i--;
1383 Expression *ekey = (*ae->keys)[i];
1384 ue = Equal(TOKequal, loc, Type::tbool, ekey, e2);
1385 if (CTFEExp::isCantExp(ue.exp()))
1386 return ue;
1387 if (ue.exp()->isBool(true))
1389 Expression *e = (*ae->values)[i];
1390 e->type = type;
1391 e->loc = loc;
1392 if (hasSideEffect(e))
1393 new(&ue) CTFEExp(TOKcantexp);
1394 else
1395 new(&ue) UnionExp(e);
1396 return ue;
1399 new(&ue) CTFEExp(TOKcantexp);
1401 else
1402 new(&ue) CTFEExp(TOKcantexp);
1403 return ue;
1406 /* Also return TOKcantexp if this fails
1408 UnionExp Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
1410 UnionExp ue;
1411 Loc loc = e1->loc;
1413 if (e1->op == TOKstring && lwr->op == TOKint64 && upr->op == TOKint64)
1415 StringExp *es1 = (StringExp *)e1;
1416 uinteger_t ilwr = lwr->toInteger();
1417 uinteger_t iupr = upr->toInteger();
1419 if (iupr > es1->len || ilwr > iupr)
1421 e1->error("string slice [%llu .. %llu] is out of bounds", ilwr, iupr);
1422 new(&ue) ErrorExp();
1424 else
1426 size_t len = (size_t)(iupr - ilwr);
1427 unsigned char sz = es1->sz;
1429 void *s = mem.xmalloc((len + 1) * sz);
1430 memcpy((char *)s, (char *)es1->string + ilwr * sz, len * sz);
1431 memset((char *)s + len * sz, 0, sz);
1433 new(&ue) StringExp(loc, s, len, es1->postfix);
1434 StringExp *es = (StringExp *)ue.exp();
1435 es->sz = sz;
1436 es->committed = es1->committed;
1437 es->type = type;
1440 else if (e1->op == TOKarrayliteral &&
1441 lwr->op == TOKint64 && upr->op == TOKint64 &&
1442 !hasSideEffect(e1))
1444 ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
1445 uinteger_t ilwr = lwr->toInteger();
1446 uinteger_t iupr = upr->toInteger();
1448 if (iupr > es1->elements->dim || ilwr > iupr)
1450 e1->error("array slice [%llu .. %llu] is out of bounds", ilwr, iupr);
1451 new(&ue) ErrorExp();
1453 else
1455 Expressions *elements = new Expressions();
1456 elements->setDim((size_t)(iupr - ilwr));
1457 memcpy(elements->tdata(),
1458 es1->elements->tdata() + ilwr,
1459 (size_t)(iupr - ilwr) * sizeof((*es1->elements)[0]));
1460 new(&ue) ArrayLiteralExp(e1->loc, elements);
1461 ue.exp()->type = type;
1464 else
1465 new(&ue) CTFEExp(TOKcantexp);
1466 assert(ue.exp()->type);
1467 return ue;
1470 /* Set a slice of char/integer array literal 'existingAE' from a string 'newval'.
1471 * existingAE[firstIndex..firstIndex+newval.length] = newval.
1473 void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *newval, size_t firstIndex)
1475 size_t newlen = newval->len;
1476 size_t sz = newval->sz;
1477 void *s = newval->string;
1478 Type *elemType = existingAE->type->nextOf();
1479 for (size_t j = 0; j < newlen; j++)
1481 dinteger_t val;
1482 switch (sz)
1484 case 1: val = (( utf8_t *)s)[j]; break;
1485 case 2: val = ((utf16_t *)s)[j]; break;
1486 case 4: val = ((utf32_t *)s)[j]; break;
1487 default: assert(0); break;
1489 (*existingAE->elements)[j + firstIndex]
1490 = new IntegerExp(newval->loc, val, elemType);
1494 /* Set a slice of string 'existingSE' from a char array literal 'newae'.
1495 * existingSE[firstIndex..firstIndex+newae.length] = newae.
1497 void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, size_t firstIndex)
1499 void *s = existingSE->string;
1500 for (size_t j = 0; j < newae->elements->dim; j++)
1502 unsigned val = (unsigned)newae->getElement(j)->toInteger();
1503 switch (existingSE->sz)
1505 case 1: (( utf8_t *)s)[j + firstIndex] = ( utf8_t)val; break;
1506 case 2: ((utf16_t *)s)[j + firstIndex] = (utf16_t)val; break;
1507 case 4: ((utf32_t *)s)[j + firstIndex] = (utf32_t)val; break;
1508 default: assert(0); break;
1513 /* Set a slice of string 'existingSE' from a string 'newstr'.
1514 * existingSE[firstIndex..firstIndex+newstr.length] = newstr.
1516 void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, size_t firstIndex)
1518 void *s = existingSE->string;
1519 size_t sz = existingSE->sz;
1520 assert(sz == newstr->sz);
1521 memcpy((char *)s + firstIndex * sz, newstr->string, sz * newstr->len);
1524 /* Compare a string slice with another string slice.
1525 * Conceptually equivalent to memcmp( se1[lo1..lo1+len], se2[lo2..lo2+len])
1527 int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len)
1529 void *s1 = se1->string;
1530 void *s2 = se2->string;
1531 size_t sz = se1->sz;
1532 assert(sz == se2->sz);
1533 return memcmp((char *)s1 + sz * lo1, (char *)s2 + sz * lo2, sz * len);
1536 /* Compare a string slice with an array literal slice
1537 * Conceptually equivalent to memcmp( se1[lo1..lo1+len], ae2[lo2..lo2+len])
1539 int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len)
1541 void *s = se1->string;
1542 size_t sz = se1->sz;
1544 for (size_t j = 0; j < len; j++)
1546 unsigned val2 = (unsigned)ae2->getElement(j + lo2)->toInteger();
1547 unsigned val1;
1548 switch (sz)
1550 case 1: val1 = (( utf8_t *)s)[j + lo1]; break;
1551 case 2: val1 = ((utf16_t *)s)[j + lo1]; break;
1552 case 4: val1 = ((utf32_t *)s)[j + lo1]; break;
1553 default: assert(0); break;
1555 int c = val1 - val2;
1556 if (c)
1557 return c;
1559 return 0;
1562 /* Also return TOKcantexp if this fails
1564 UnionExp Cat(Type *type, Expression *e1, Expression *e2)
1566 UnionExp ue;
1567 Expression *e = CTFEExp::cantexp;
1568 Loc loc = e1->loc;
1569 Type *t;
1570 Type *t1 = e1->type->toBasetype();
1571 Type *t2 = e2->type->toBasetype();
1573 //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1574 //printf("\tt1 = %s, t2 = %s, type = %s\n", t1->toChars(), t2->toChars(), type->toChars());
1576 if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral))
1578 e = e2;
1579 t = t1;
1580 goto L2;
1582 else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull)
1584 e = e1;
1585 t = t2;
1587 Type *tn = e->type->toBasetype();
1588 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
1590 // Create a StringExp
1591 if (t->nextOf())
1592 t = t->nextOf()->toBasetype();
1593 unsigned char sz = (unsigned char)t->size();
1595 dinteger_t v = e->toInteger();
1597 size_t len = (t->ty == tn->ty) ? 1 : utf_codeLength(sz, (dchar_t)v);
1598 void *s = mem.xmalloc((len + 1) * sz);
1599 if (t->ty == tn->ty)
1600 Port::valcpy(s, v, sz);
1601 else
1602 utf_encode(sz, s, (dchar_t)v);
1604 // Add terminating 0
1605 memset((char *)s + len * sz, 0, sz);
1607 new(&ue) StringExp(loc, s, len);
1608 StringExp *es = (StringExp *)ue.exp();
1609 es->sz = sz;
1610 es->committed = 1;
1612 else
1614 // Create an ArrayLiteralExp
1615 Expressions *elements = new Expressions();
1616 elements->push(e);
1617 new(&ue) ArrayLiteralExp(e->loc, elements);
1619 ue.exp()->type = type;
1620 assert(ue.exp()->type);
1621 return ue;
1623 else if (e1->op == TOKnull && e2->op == TOKnull)
1625 if (type == e1->type)
1627 // Handle null ~= null
1628 if (t1->ty == Tarray && t2 == t1->nextOf())
1630 new(&ue) ArrayLiteralExp(e1->loc, e2);
1631 ue.exp()->type = type;
1632 assert(ue.exp()->type);
1633 return ue;
1635 else
1637 new(&ue) UnionExp(e1);
1638 assert(ue.exp()->type);
1639 return ue;
1642 if (type == e2->type)
1644 new(&ue) UnionExp(e2);
1645 assert(ue.exp()->type);
1646 return ue;
1648 new(&ue) NullExp(e1->loc, type);
1649 assert(ue.exp()->type);
1650 return ue;
1652 else if (e1->op == TOKstring && e2->op == TOKstring)
1654 // Concatenate the strings
1655 StringExp *es1 = (StringExp *)e1;
1656 StringExp *es2 = (StringExp *)e2;
1657 size_t len = es1->len + es2->len;
1658 unsigned char sz = es1->sz;
1660 if (sz != es2->sz)
1662 /* Can happen with:
1663 * auto s = "foo"d ~ "bar"c;
1665 assert(global.errors);
1666 new(&ue) CTFEExp(TOKcantexp);
1667 assert(ue.exp()->type);
1668 return ue;
1670 void *s = mem.xmalloc((len + 1) * sz);
1671 memcpy((char *)s, es1->string, es1->len * sz);
1672 memcpy((char *)s + es1->len * sz, es2->string, es2->len * sz);
1674 // Add terminating 0
1675 memset((char *)s + len * sz, 0, sz);
1677 new(&ue) StringExp(loc, s, len);
1678 StringExp *es = (StringExp *)ue.exp();
1679 es->sz = sz;
1680 es->committed = es1->committed | es2->committed;
1681 es->type = type;
1682 assert(ue.exp()->type);
1683 return ue;
1685 else if (e2->op == TOKstring && e1->op == TOKarrayliteral &&
1686 t1->nextOf()->isintegral())
1688 // [chars] ~ string --> [chars]
1689 StringExp *es = (StringExp *)e2;
1690 ArrayLiteralExp *ea = (ArrayLiteralExp *)e1;
1691 size_t len = es->len + ea->elements->dim;
1692 Expressions * elems = new Expressions;
1693 elems->setDim(len);
1694 for (size_t i= 0; i < ea->elements->dim; ++i)
1696 (*elems)[i] = ea->getElement(i);
1698 new(&ue) ArrayLiteralExp(e1->loc, elems);
1699 ArrayLiteralExp *dest = (ArrayLiteralExp *)ue.exp();
1700 dest->type = type;
1701 sliceAssignArrayLiteralFromString(dest, es, ea->elements->dim);
1702 assert(ue.exp()->type);
1703 return ue;
1705 else if (e1->op == TOKstring && e2->op == TOKarrayliteral &&
1706 t2->nextOf()->isintegral())
1708 // string ~ [chars] --> [chars]
1709 StringExp *es = (StringExp *)e1;
1710 ArrayLiteralExp *ea = (ArrayLiteralExp *)e2;
1711 size_t len = es->len + ea->elements->dim;
1712 Expressions * elems = new Expressions;
1713 elems->setDim(len);
1714 for (size_t i= 0; i < ea->elements->dim; ++i)
1716 (*elems)[es->len + i] = ea->getElement(i);
1718 new(&ue) ArrayLiteralExp(e1->loc, elems);
1719 ArrayLiteralExp *dest = (ArrayLiteralExp *)ue.exp();
1720 dest->type = type;
1721 sliceAssignArrayLiteralFromString(dest, es, 0);
1722 assert(ue.exp()->type);
1723 return ue;
1725 else if (e1->op == TOKstring && e2->op == TOKint64)
1727 // string ~ char --> string
1728 StringExp *es1 = (StringExp *)e1;
1729 StringExp *es;
1730 unsigned char sz = es1->sz;
1731 dinteger_t v = e2->toInteger();
1733 // Is it a concatentation of homogenous types?
1734 // (char[] ~ char, wchar[]~wchar, or dchar[]~dchar)
1735 bool homoConcat = (sz == t2->size());
1736 size_t len = es1->len;
1737 len += homoConcat ? 1 : utf_codeLength(sz, (dchar_t)v);
1739 void *s = mem.xmalloc((len + 1) * sz);
1740 memcpy(s, es1->string, es1->len * sz);
1741 if (homoConcat)
1742 Port::valcpy((char *)s + (sz * es1->len), v, sz);
1743 else
1744 utf_encode(sz, (char *)s + (sz * es1->len), (dchar_t)v);
1746 // Add terminating 0
1747 memset((char *)s + len * sz, 0, sz);
1749 new(&ue) StringExp(loc, s, len);
1750 es = (StringExp *)ue.exp();
1751 es->sz = sz;
1752 es->committed = es1->committed;
1753 es->type = type;
1754 assert(ue.exp()->type);
1755 return ue;
1757 else if (e1->op == TOKint64 && e2->op == TOKstring)
1759 // Concatenate the strings
1760 StringExp *es2 = (StringExp *)e2;
1761 size_t len = 1 + es2->len;
1762 unsigned char sz = es2->sz;
1763 dinteger_t v = e1->toInteger();
1765 void *s = mem.xmalloc((len + 1) * sz);
1766 memcpy((char *)s, &v, sz);
1767 memcpy((char *)s + sz, es2->string, es2->len * sz);
1769 // Add terminating 0
1770 memset((char *)s + len * sz, 0, sz);
1772 new(&ue) StringExp(loc, s, len);
1773 StringExp *es = (StringExp *)ue.exp();
1774 es->sz = sz;
1775 es->committed = es2->committed;
1776 es->type = type;
1777 assert(ue.exp()->type);
1778 return ue;
1780 else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral &&
1781 t1->nextOf()->equals(t2->nextOf()))
1783 // Concatenate the arrays
1784 Expressions *elems = ArrayLiteralExp::copyElements(e1, e2);
1786 new(&ue) ArrayLiteralExp(e1->loc, elems);
1788 e = ue.exp();
1789 if (type->toBasetype()->ty == Tsarray)
1791 e->type = t1->nextOf()->sarrayOf(elems->dim);
1793 else
1794 e->type = type;
1795 assert(ue.exp()->type);
1796 return ue;
1798 else if (e1->op == TOKarrayliteral && e2->op == TOKnull &&
1799 t1->nextOf()->equals(t2->nextOf()))
1801 e = e1;
1802 goto L3;
1804 else if (e1->op == TOKnull && e2->op == TOKarrayliteral &&
1805 t1->nextOf()->equals(t2->nextOf()))
1807 e = e2;
1809 // Concatenate the array with null
1810 Expressions *elems = ArrayLiteralExp::copyElements(e);
1812 new(&ue) ArrayLiteralExp(e->loc, elems);
1814 e = ue.exp();
1815 if (type->toBasetype()->ty == Tsarray)
1817 e->type = t1->nextOf()->sarrayOf(elems->dim);
1819 else
1820 e->type = type;
1821 assert(ue.exp()->type);
1822 return ue;
1824 else if ((e1->op == TOKarrayliteral || e1->op == TOKnull) &&
1825 e1->type->toBasetype()->nextOf() &&
1826 e1->type->toBasetype()->nextOf()->equals(e2->type))
1828 Expressions *elems = (e1->op == TOKarrayliteral)
1829 ? ArrayLiteralExp::copyElements(e1) : new Expressions();
1830 elems->push(e2);
1832 new(&ue) ArrayLiteralExp(e1->loc, elems);
1834 e = ue.exp();
1835 if (type->toBasetype()->ty == Tsarray)
1837 e->type = e2->type->sarrayOf(elems->dim);
1839 else
1840 e->type = type;
1841 assert(ue.exp()->type);
1842 return ue;
1844 else if (e2->op == TOKarrayliteral &&
1845 e2->type->toBasetype()->nextOf()->equals(e1->type))
1847 Expressions *elems = ArrayLiteralExp::copyElements(e1, e2);
1849 new(&ue) ArrayLiteralExp(e2->loc, elems);
1851 e = ue.exp();
1852 if (type->toBasetype()->ty == Tsarray)
1854 e->type = e1->type->sarrayOf(elems->dim);
1856 else
1857 e->type = type;
1858 assert(ue.exp()->type);
1859 return ue;
1861 else if (e1->op == TOKnull && e2->op == TOKstring)
1863 t = e1->type;
1864 e = e2;
1865 goto L1;
1867 else if (e1->op == TOKstring && e2->op == TOKnull)
1869 e = e1;
1870 t = e2->type;
1872 Type *tb = t->toBasetype();
1873 if (tb->ty == Tarray && tb->nextOf()->equivalent(e->type))
1875 Expressions *expressions = new Expressions();
1876 expressions->push(e);
1877 new(&ue) ArrayLiteralExp(loc, expressions);
1878 e = ue.exp();
1879 e->type = t;
1881 else
1883 new(&ue) UnionExp(e);
1884 e = ue.exp();
1886 if (!e->type->equals(type))
1888 StringExp *se = (StringExp *)e->copy();
1889 e = se->castTo(NULL, type);
1890 new(&ue) UnionExp(e);
1891 e = ue.exp();
1894 else
1895 new(&ue) CTFEExp(TOKcantexp);
1896 assert(ue.exp()->type);
1897 return ue;
1900 UnionExp Ptr(Type *type, Expression *e1)
1902 //printf("Ptr(e1 = %s)\n", e1->toChars());
1903 UnionExp ue;
1904 if (e1->op == TOKadd)
1906 AddExp *ae = (AddExp *)e1;
1907 if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64)
1909 AddrExp *ade = (AddrExp *)ae->e1;
1910 if (ade->e1->op == TOKstructliteral)
1912 StructLiteralExp *se = (StructLiteralExp *)ade->e1;
1913 unsigned offset = (unsigned)ae->e2->toInteger();
1914 Expression *e = se->getField(type, offset);
1915 if (e)
1917 new(&ue) UnionExp(e);
1918 return ue;
1923 new(&ue) CTFEExp(TOKcantexp);
1924 return ue;