2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2019 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
11 #include "root/dsystem.h" // mem{cpy|set|cmp}()
17 #include "root/rmem.h"
18 #include "root/root.h"
19 #include "root/port.h"
23 #include "expression.h"
24 #include "aggregate.h"
25 #include "declaration.h"
30 int RealEquals(real_t x1, real_t x2);
32 Expression *expType(Type *type, Expression *e)
42 /* ================================== isConst() ============================== */
44 int isConst(Expression *e)
46 //printf("Expression::isConst(): %s\n", e->toChars());
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)
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);
91 new(&ue) IntegerExp(loc, -e1->toInteger(), type);
96 UnionExp Com(Type *type, Expression *e1)
101 new(&ue) IntegerExp(loc, ~e1->toInteger(), type);
105 UnionExp Not(Type *type, Expression *e1)
110 new(&ue) IntegerExp(loc, e1->isBool(false) ? 1 : 0, type);
114 UnionExp Bool(Type *type, Expression *e1)
119 new(&ue) IntegerExp(loc, e1->isBool(true) ? 1 : 0, type);
123 UnionExp Add(Loc loc, Type *type, Expression *e1, Expression *e2)
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);
150 if (e1->type->isreal())
155 else if (e1->type->isimaginary())
157 i1 = e1->toImaginary();
162 c1 = e1->toComplex();
166 if (e2->type->isreal())
170 else if (e2->type->isimaginary())
172 i2 = e2->toImaginary();
177 c2 = e2->toComplex();
184 v = complex_t(r1 + r2);
187 v = complex_t(r1, i2);
190 v = complex_t(r1 + creall(c2), cimagl(c2));
193 v = complex_t(r2, i1);
196 v = complex_t(CTFloat::zero, i1 + i2);
199 v = complex_t(creall(c2), i1 + cimagl(c2));
202 v = complex_t(creall(c1) + r2, cimagl(c2));
205 v = complex_t(creall(c1), cimagl(c1) + i2);
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;
228 new(&ue) IntegerExp(loc, e1->toInteger() + e2->toInteger(), type);
233 UnionExp Min(Loc loc, Type *type, Expression *e1, Expression *e2)
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);
260 if (e1->type->isreal())
265 else if (e1->type->isimaginary())
267 i1 = e1->toImaginary();
272 c1 = e1->toComplex();
276 if (e2->type->isreal())
280 else if (e2->type->isimaginary())
282 i2 = e2->toImaginary();
287 c2 = e2->toComplex();
294 v = complex_t(r1 - r2);
297 v = complex_t(r1, -i2);
300 v = complex_t(r1 - creall(c2), -cimagl(c2));
303 v = complex_t(-r2, i1);
306 v = complex_t(CTFloat::zero, i1 - i2);
309 v = complex_t(-creall(c2), i1 - cimagl(c2));
312 v = complex_t(creall(c1) - r2, cimagl(c1));
315 v = complex_t(creall(c1), cimagl(c1) - i2);
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;
333 new(&ue) IntegerExp(loc, e1->toInteger() - e2->toInteger(), type);
338 UnionExp Mul(Loc loc, Type *type, Expression *e1, Expression *e2)
342 if (type->isfloating())
344 complex_t c = complex_t(CTFloat::zero);
347 if (e1->type->isreal())
351 c = complex_t(r * creall(c), r * cimagl(c));
353 else if (e1->type->isimaginary())
355 r = e1->toImaginary();
357 c = complex_t(-r * cimagl(c), r * creall(c));
359 else if (e2->type->isreal())
363 c = complex_t(r * creall(c), r * cimagl(c));
365 else if (e2->type->isimaginary())
367 r = e2->toImaginary();
369 c = complex_t(-r * cimagl(c), r * creall(c));
372 c = e1->toComplex() * e2->toComplex();
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);
385 new(&ue) IntegerExp(loc, e1->toInteger() * e2->toInteger(), type);
390 UnionExp Div(Loc loc, Type *type, Expression *e1, Expression *e2)
394 if (type->isfloating())
396 complex_t c = complex_t(CTFloat::zero);
401 if (e2->type->isreal())
403 if (e1->type->isreal())
405 new(&ue) RealExp(loc, e1->toReal() / e2->toReal(), type);
410 c = complex_t(creall(c) / r, cimagl(c) / r);
412 else if (e2->type->isimaginary())
414 r = e2->toImaginary();
416 c = complex_t(cimagl(c) / r, -creall(c) / r);
420 c = e1->toComplex() / e2->toComplex();
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);
438 n1 = e1->toInteger();
439 n2 = e2->toInteger();
442 e2->error("divide by 0");
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");
455 else if ((dinteger_t)n1 == 0x8000000000000000LL) // long.min / -1
457 e2->error("integer overflow: long.min / -1");
462 if (e1->type->isunsigned() || e2->type->isunsigned())
463 n = ((dinteger_t) n1) / ((dinteger_t) n2);
466 new(&ue) IntegerExp(loc, n, type);
471 UnionExp Mod(Loc loc, Type *type, Expression *e1, Expression *e2)
475 if (type->isfloating())
477 complex_t c = complex_t(CTFloat::zero);
479 if (e2->type->isreal())
481 real_t r2 = e2->toReal();
484 c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2);
486 c = complex_t(::fmodl(e1->toReal(), r2), ::fmodl(e1->toImaginary(), r2));
489 else if (e2->type->isimaginary())
491 real_t i2 = e2->toImaginary();
494 c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2);
496 c = complex_t(::fmodl(e1->toReal(), i2), ::fmodl(e1->toImaginary(), i2));
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);
517 n1 = e1->toInteger();
518 n2 = e2->toInteger();
521 e2->error("divide by 0");
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");
534 else if ((dinteger_t)n1 == 0x8000000000000000LL) // long.min % -1
536 e2->error("integer overflow: long.min %% -1");
541 if (e1->type->isunsigned() || e2->type->isunsigned())
542 n = ((dinteger_t) n1) % ((dinteger_t) n2);
545 new(&ue) IntegerExp(loc, n, type);
550 UnionExp Pow(Loc loc, Type *type, Expression *e1, Expression *e2)
554 // Handle integer power operations.
555 if (e2->type->isintegral())
557 dinteger_t n = e2->toInteger();
560 if (!e2->type->isunsigned() && (sinteger_t)n < 0)
562 if (e1->type->isintegral())
564 new(&ue) CTFEExp(TOKcantexp);
568 // Don't worry about overflow, from now on n is unsigned.
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);
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();
599 uv = Mul(loc, v->type, v, r);
603 ur = Mul(loc, r->type, r, r);
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);
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);
629 new(&ue) CTFEExp(TOKcantexp);
632 new(&ue) CTFEExp(TOKcantexp);
637 UnionExp Shl(Loc loc, Type *type, Expression *e1, Expression *e2)
640 new(&ue) IntegerExp(loc, e1->toInteger() << e2->toInteger(), type);
644 UnionExp Shr(Loc loc, Type *type, Expression *e1, Expression *e2)
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)
654 value = (d_int8)(value) >> count;
659 value = (d_uns8)(value) >> count;
663 value = (d_int16)(value) >> count;
668 value = (d_uns16)(value) >> count;
672 value = (d_int32)(value) >> count;
677 value = (d_uns32)(value) >> count;
681 value = (d_int64)(value) >> count;
685 value = (d_uns64)(value) >> count;
695 new(&ue) IntegerExp(loc, value, type);
699 UnionExp Ushr(Loc loc, Type *type, Expression *e1, Expression *e2)
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)
711 // Possible only with >>>=. >>> always gets promoted to int.
712 value = (value & 0xFF) >> count;
718 // Possible only with >>>=. >>> always gets promoted to int.
719 value = (value & 0xFFFF) >> count;
725 value = (value & 0xFFFFFFFF) >> count;
730 value = (d_uns64)(value) >> count;
740 new(&ue) IntegerExp(loc, value, type);
744 UnionExp And(Loc loc, Type *type, Expression *e1, Expression *e2)
747 new(&ue) IntegerExp(loc, e1->toInteger() & e2->toInteger(), type);
751 UnionExp Or(Loc loc, Type *type, Expression *e1, Expression *e2)
754 new(&ue) IntegerExp(loc, e1->toInteger() | e2->toInteger(), type);
758 UnionExp Xor(Loc loc, Type *type, Expression *e1, Expression *e2)
761 new(&ue) IntegerExp(loc, e1->toInteger() ^ e2->toInteger(), type);
765 /* Also returns TOKcantexp if cannot be computed.
767 UnionExp Equal(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2)
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)
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);
794 new(&ue) CTFEExp(TOKcantexp);
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);
812 new(&ue) CTFEExp(TOKcantexp);
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);
827 if (es1->len == es2->len &&
828 memcmp(es1->string, es2->string, es1->sz * es1->len) == 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)
843 else if (es1->elements->dim != es2->elements->dim)
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()))
854 cmp = (int)ue.exp()->toInteger();
860 else if (e1->op == TOKarrayliteral && e2->op == TOKstring)
862 // Swap operands and use common code
863 Expression *etmp = e1;
868 else if (e1->op == TOKstring && e2->op == TOKarrayliteral)
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;
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);
889 cmp = (c == ee2->toInteger());
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)
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)
907 else if (es1->elements->dim != es2->elements->dim)
912 for (size_t i = 0; i < es1->elements->dim; i++)
914 Expression *ee1 = (*es1->elements)[i];
915 Expression *ee2 = (*es2->elements)[i];
924 ue = Equal(TOKequal, loc, Type::tint32, ee1, ee2);
925 if (ue.exp()->op == TOKcantexp)
927 cmp = (int)ue.exp()->toInteger();
933 else if (e1->isConst() != 1 || e2->isConst() != 1)
935 new(&ue) CTFEExp(TOKcantexp);
938 else if (e1->type->isreal())
944 else if (e1->type->isimaginary())
946 r1 = e1->toImaginary();
947 r2 = e2->toImaginary();
949 if (CTFloat::isNaN(r1) || CTFloat::isNaN(r2)) // if unordered
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());
968 new(&ue) CTFEExp(TOKcantexp);
972 if (op == TOKnotequal)
974 new(&ue) IntegerExp(loc, cmp, type);
978 UnionExp Identity(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2)
983 if (e1->op == TOKnull)
985 cmp = (e2->op == TOKnull);
987 else if (e2->op == TOKnull)
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);
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));
1017 ue = Equal((op == TOKidentity) ? TOKequal : TOKnotequal, loc, type, e1, e2);
1021 if (op == TOKnotidentity)
1023 new(&ue) IntegerExp(loc, cmp, type);
1028 UnionExp Cmp(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2)
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;
1048 int rawCmp = memcmp(es1->string, es2->string, sz * len);
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);
1058 else if (e1->type->isreal())
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())
1080 n1 = e1->toInteger();
1081 n2 = e2->toInteger();
1082 if (e1->type->isunsigned() || e2->type->isunsigned())
1083 n = intUnsignedCmp(op, n1, n2);
1085 n = intSignedCmp(op, n1, n2);
1087 new(&ue) IntegerExp(loc, n, type);
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)
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);
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);
1117 if (e1->type->implicitConvTo(to) >= MATCHconst ||
1118 to->implicitConvTo(e1->type) >= MATCHconst)
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)
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())
1143 if (e1->op == TOKarrayliteral && typeb == tb)
1146 Expression *ex = expType(to, e1);
1147 new(&ue) UnionExp(ex);
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())
1164 real_t r = e1->toReal();
1169 result = (d_int8)(sinteger_t)r;
1173 result = (d_uns8)(dinteger_t)r;
1176 result = (d_int16)(sinteger_t)r;
1180 result = (d_uns16)(dinteger_t)r;
1183 result = (d_int32)r;
1187 result = (d_uns32)r;
1190 result = (d_int64)r;
1193 result = (d_uns64)r;
1199 new(&ue) IntegerExp(loc, result, type);
1201 else if (type->isunsigned())
1202 new(&ue) IntegerExp(loc, e1->toUInteger(), type);
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)
1235 StructDeclaration *sd = tb->toDsymbol(NULL)->isStructDeclaration();
1237 Expressions *elements = new Expressions;
1238 for (size_t i = 0; i < sd->fields.dim; i++)
1240 VarDeclaration *v = sd->fields[i];
1242 new(&zero) IntegerExp(0);
1243 ue = Cast(loc, v->type, v->type, zero.exp());
1244 if (ue.exp()->op == TOKcantexp)
1246 elements->push(ue.exp()->copy());
1248 new(&ue) StructLiteralExp(loc, sd, elements);
1249 ue.exp()->type = type;
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();
1265 UnionExp ArrayLength(Type *type, Expression *e1)
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);
1296 new(&ue) CTFEExp(TOKcantexp);
1300 /* Also return TOKcantexp if this fails
1302 UnionExp Index(Type *type, Expression *e1, Expression *e2)
1307 //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1309 if (e1->op == TOKstring && e2->op == TOKint64)
1311 StringExp *es1 = (StringExp *)e1;
1312 uinteger_t i = e2->toInteger();
1316 e1->error("string index %llu is out of bounds [0 .. %llu]", i, (ulonglong)es1->len);
1317 new(&ue) ErrorExp();
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();
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);
1341 if (hasSideEffect(e))
1342 new(&ue) CTFEExp(TOKcantexp);
1344 new(&ue) UnionExp(e);
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();
1363 Expression *e = ale->getElement((size_t)i);
1366 if (hasSideEffect(e))
1367 new(&ue) CTFEExp(TOKcantexp);
1369 new(&ue) UnionExp(e);
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;)
1383 Expression *ekey = (*ae->keys)[i];
1384 ue = Equal(TOKequal, loc, Type::tbool, ekey, e2);
1385 if (CTFEExp::isCantExp(ue.exp()))
1387 if (ue.exp()->isBool(true))
1389 Expression *e = (*ae->values)[i];
1392 if (hasSideEffect(e))
1393 new(&ue) CTFEExp(TOKcantexp);
1395 new(&ue) UnionExp(e);
1399 new(&ue) CTFEExp(TOKcantexp);
1402 new(&ue) CTFEExp(TOKcantexp);
1406 /* Also return TOKcantexp if this fails
1408 UnionExp Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
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();
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();
1436 es->committed = es1->committed;
1440 else if (e1->op == TOKarrayliteral &&
1441 lwr->op == TOKint64 && upr->op == TOKint64 &&
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();
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;
1465 new(&ue) CTFEExp(TOKcantexp);
1466 assert(ue.exp()->type);
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++)
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();
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;
1562 /* Also return TOKcantexp if this fails
1564 UnionExp Cat(Type *type, Expression *e1, Expression *e2)
1567 Expression *e = CTFEExp::cantexp;
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))
1582 else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull)
1587 Type *tn = e->type->toBasetype();
1588 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
1590 // Create a StringExp
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);
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();
1614 // Create an ArrayLiteralExp
1615 Expressions *elements = new Expressions();
1617 new(&ue) ArrayLiteralExp(e->loc, elements);
1619 ue.exp()->type = type;
1620 assert(ue.exp()->type);
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);
1637 new(&ue) UnionExp(e1);
1638 assert(ue.exp()->type);
1642 if (type == e2->type)
1644 new(&ue) UnionExp(e2);
1645 assert(ue.exp()->type);
1648 new(&ue) NullExp(e1->loc, type);
1649 assert(ue.exp()->type);
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;
1663 * auto s = "foo"d ~ "bar"c;
1665 assert(global.errors);
1666 new(&ue) CTFEExp(TOKcantexp);
1667 assert(ue.exp()->type);
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();
1680 es->committed = es1->committed | es2->committed;
1682 assert(ue.exp()->type);
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;
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();
1701 sliceAssignArrayLiteralFromString(dest, es, ea->elements->dim);
1702 assert(ue.exp()->type);
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;
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();
1721 sliceAssignArrayLiteralFromString(dest, es, 0);
1722 assert(ue.exp()->type);
1725 else if (e1->op == TOKstring && e2->op == TOKint64)
1727 // string ~ char --> string
1728 StringExp *es1 = (StringExp *)e1;
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);
1742 Port::valcpy((char *)s + (sz * es1->len), v, sz);
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();
1752 es->committed = es1->committed;
1754 assert(ue.exp()->type);
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();
1775 es->committed = es2->committed;
1777 assert(ue.exp()->type);
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);
1789 if (type->toBasetype()->ty == Tsarray)
1791 e->type = t1->nextOf()->sarrayOf(elems->dim);
1795 assert(ue.exp()->type);
1798 else if (e1->op == TOKarrayliteral && e2->op == TOKnull &&
1799 t1->nextOf()->equals(t2->nextOf()))
1804 else if (e1->op == TOKnull && e2->op == TOKarrayliteral &&
1805 t1->nextOf()->equals(t2->nextOf()))
1809 // Concatenate the array with null
1810 Expressions *elems = ArrayLiteralExp::copyElements(e);
1812 new(&ue) ArrayLiteralExp(e->loc, elems);
1815 if (type->toBasetype()->ty == Tsarray)
1817 e->type = t1->nextOf()->sarrayOf(elems->dim);
1821 assert(ue.exp()->type);
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();
1832 new(&ue) ArrayLiteralExp(e1->loc, elems);
1835 if (type->toBasetype()->ty == Tsarray)
1837 e->type = e2->type->sarrayOf(elems->dim);
1841 assert(ue.exp()->type);
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);
1852 if (type->toBasetype()->ty == Tsarray)
1854 e->type = e1->type->sarrayOf(elems->dim);
1858 assert(ue.exp()->type);
1861 else if (e1->op == TOKnull && e2->op == TOKstring)
1867 else if (e1->op == TOKstring && e2->op == TOKnull)
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);
1883 new(&ue) UnionExp(e);
1886 if (!e->type->equals(type))
1888 StringExp *se = (StringExp *)e->copy();
1889 e = se->castTo(NULL, type);
1890 new(&ue) UnionExp(e);
1895 new(&ue) CTFEExp(TOKcantexp);
1896 assert(ue.exp()->type);
1900 UnionExp Ptr(Type *type, Expression *e1)
1902 //printf("Ptr(e1 = %s)\n", e1->toChars());
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);
1917 new(&ue) UnionExp(e);
1923 new(&ue) CTFEExp(TOKcantexp);