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
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
);