Scan dynamic libraries for GC roots
[delight/core.git] / dmd2 / constfold.c
blobcb47021652bda373e2c2c8c9de3148bb6cfbf658
2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2007 by Digital Mars
4 // All Rights Reserved
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
11 /* NOTE: This file has been patched from the original DMD distribution to
12 work with the GDC compiler.
14 Modified by David Friedman, September 2004
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <assert.h>
20 #include <math.h>
22 #if __DMC__
23 #include <complex.h>
24 #endif
26 #include "mem.h"
27 #include "root.h"
29 #include "mtype.h"
30 #include "expression.h"
31 #include "aggregate.h"
32 #include "declaration.h"
34 #ifdef IN_GCC
35 #include "d-gcc-real.h"
36 #endif
38 static real_t zero; // work around DMC bug for now
40 #define LOG 0
42 Expression *expType(Type *type, Expression *e)
44 if (type != e->type)
46 e = e->copy();
47 e->type = type;
49 return e;
52 /* ================================== isConst() ============================== */
54 int Expression::isConst()
56 //printf("Expression::isConst(): %s\n", toChars());
57 return 0;
60 int IntegerExp::isConst()
62 return 1;
65 int RealExp::isConst()
67 return 1;
70 int ComplexExp::isConst()
72 return 1;
75 int SymOffExp::isConst()
77 return 2;
80 /* =============================== constFold() ============================== */
82 /* The constFold() functions were redundant with the optimize() ones,
83 * and so have been folded in with them.
86 /* ========================================================================== */
88 Expression *Neg(Type *type, Expression *e1)
89 { Expression *e;
90 Loc loc = e1->loc;
92 if (e1->type->isreal())
94 e = new RealExp(loc, -e1->toReal(), type);
96 else if (e1->type->isimaginary())
98 e = new RealExp(loc, -e1->toImaginary(), type);
100 else if (e1->type->iscomplex())
102 e = new ComplexExp(loc, -e1->toComplex(), type);
104 else
105 e = new IntegerExp(loc, -e1->toInteger(), type);
106 return e;
109 Expression *Com(Type *type, Expression *e1)
110 { Expression *e;
111 Loc loc = e1->loc;
113 e = new IntegerExp(loc, ~e1->toInteger(), type);
114 return e;
117 Expression *Not(Type *type, Expression *e1)
118 { Expression *e;
119 Loc loc = e1->loc;
121 e = new IntegerExp(loc, e1->isBool(0), type);
122 return e;
125 Expression *Bool(Type *type, Expression *e1)
126 { Expression *e;
127 Loc loc = e1->loc;
129 e = new IntegerExp(loc, e1->isBool(1), type);
130 return e;
133 Expression *Add(Type *type, Expression *e1, Expression *e2)
134 { Expression *e;
135 Loc loc = e1->loc;
137 #if LOG
138 printf("Add(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
139 #endif
140 if (type->isreal())
142 e = new RealExp(loc, e1->toReal() + e2->toReal(), type);
144 else if (type->isimaginary())
146 e = new RealExp(loc, e1->toImaginary() + e2->toImaginary(), type);
148 else if (type->iscomplex())
150 // This rigamarole is necessary so that -0.0 doesn't get
151 // converted to +0.0 by doing an extraneous add with +0.0
152 complex_t c1;
153 real_t r1;
154 real_t i1;
156 complex_t c2;
157 real_t r2;
158 real_t i2;
160 complex_t v;
161 int x;
163 if (e1->type->isreal())
164 { r1 = e1->toReal();
165 x = 0;
167 else if (e1->type->isimaginary())
168 { i1 = e1->toImaginary();
169 x = 3;
171 else
172 { c1 = e1->toComplex();
173 x = 6;
176 if (e2->type->isreal())
177 { r2 = e2->toReal();
179 else if (e2->type->isimaginary())
180 { i2 = e2->toImaginary();
181 x += 1;
183 else
184 { c2 = e2->toComplex();
185 x += 2;
188 switch (x)
190 #if __DMC__
191 case 0+0: v = (complex_t) (r1 + r2); break;
192 case 0+1: v = r1 + i2 * I; break;
193 case 0+2: v = r1 + c2; break;
194 case 3+0: v = i1 * I + r2; break;
195 case 3+1: v = (complex_t) ((i1 + i2) * I); break;
196 case 3+2: v = i1 * I + c2; break;
197 case 6+0: v = c1 + r2; break;
198 case 6+1: v = c1 + i2 * I; break;
199 case 6+2: v = c1 + c2; break;
200 #else
201 case 0+0: v = complex_t(r1 + r2, 0); break;
202 case 0+1: v = complex_t(r1, i2); break;
203 case 0+2: v = complex_t(r1 + creall(c2), cimagl(c2)); break;
204 case 3+0: v = complex_t(r2, i1); break;
205 case 3+1: v = complex_t(0, i1 + i2); break;
206 case 3+2: v = complex_t(creall(c2), i1 + cimagl(c2)); break;
207 case 6+0: v = complex_t(creall(c1) + r2, cimagl(c2)); break;
208 case 6+1: v = complex_t(creall(c1), cimagl(c1) + i2); break;
209 case 6+2: v = c1 + c2; break;
210 #endif
211 default: assert(0);
213 e = new ComplexExp(loc, v, type);
215 else if (e1->op == TOKsymoff)
217 SymOffExp *soe = (SymOffExp *)e1;
218 e = new SymOffExp(loc, soe->var, soe->offset + e2->toInteger());
219 e->type = type;
221 else if (e2->op == TOKsymoff)
223 SymOffExp *soe = (SymOffExp *)e2;
224 e = new SymOffExp(loc, soe->var, soe->offset + e1->toInteger());
225 e->type = type;
227 else
228 e = new IntegerExp(loc, e1->toInteger() + e2->toInteger(), type);
229 return e;
233 Expression *Min(Type *type, Expression *e1, Expression *e2)
234 { Expression *e;
235 Loc loc = e1->loc;
237 if (type->isreal())
239 e = new RealExp(loc, e1->toReal() - e2->toReal(), type);
241 else if (type->isimaginary())
243 e = new 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;
250 real_t r1;
251 real_t i1;
253 complex_t c2;
254 real_t r2;
255 real_t i2;
257 complex_t v;
258 int x;
260 if (e1->type->isreal())
261 { r1 = e1->toReal();
262 x = 0;
264 else if (e1->type->isimaginary())
265 { i1 = e1->toImaginary();
266 x = 3;
268 else
269 { c1 = e1->toComplex();
270 x = 6;
273 if (e2->type->isreal())
274 { r2 = e2->toReal();
276 else if (e2->type->isimaginary())
277 { i2 = e2->toImaginary();
278 x += 1;
280 else
281 { c2 = e2->toComplex();
282 x += 2;
285 switch (x)
287 #if __DMC__
288 case 0+0: v = (complex_t) (r1 - r2); break;
289 case 0+1: v = r1 - i2 * I; break;
290 case 0+2: v = r1 - c2; break;
291 case 3+0: v = i1 * I - r2; break;
292 case 3+1: v = (complex_t) ((i1 - i2) * I); break;
293 case 3+2: v = i1 * I - c2; break;
294 case 6+0: v = c1 - r2; break;
295 case 6+1: v = c1 - i2 * I; break;
296 case 6+2: v = c1 - c2; break;
297 #else
298 case 0+0: v = complex_t(r1 - r2, 0); break;
299 case 0+1: v = complex_t(r1, -i2); break;
300 case 0+2: v = complex_t(r1 - creall(c2), -cimagl(c2)); break;
301 case 3+0: v = complex_t(-r2, i1); break;
302 case 3+1: v = complex_t(0, i1 - i2); break;
303 case 3+2: v = complex_t(-creall(c2), i1 - cimagl(c2)); break;
304 case 6+0: v = complex_t(creall(c1) - r2, cimagl(c1)); break;
305 case 6+1: v = complex_t(creall(c1), cimagl(c1) - i2); break;
306 case 6+2: v = c1 - c2; break;
307 #endif
308 default: assert(0);
310 e = new ComplexExp(loc, v, type);
312 else if (e1->op == TOKsymoff)
314 SymOffExp *soe = (SymOffExp *)e1;
315 e = new SymOffExp(loc, soe->var, soe->offset - e2->toInteger());
316 e->type = type;
318 else
320 e = new IntegerExp(loc, e1->toInteger() - e2->toInteger(), type);
322 return e;
325 Expression *Mul(Type *type, Expression *e1, Expression *e2)
326 { Expression *e;
327 Loc loc = e1->loc;
329 if (type->isfloating())
330 { complex_t c;
331 #ifdef IN_GCC
332 real_t r;
333 #else
334 d_float80 r;
335 #endif
337 if (e1->type->isreal())
339 #if __DMC__
340 c = e1->toReal() * e2->toComplex();
341 #else
342 r = e1->toReal();
343 c = e2->toComplex();
344 c = complex_t(r * creall(c), r * cimagl(c));
345 #endif
347 else if (e1->type->isimaginary())
349 #if __DMC__
350 c = e1->toImaginary() * I * e2->toComplex();
351 #else
352 r = e1->toImaginary();
353 c = e2->toComplex();
354 c = complex_t(-r * cimagl(c), r * creall(c));
355 #endif
357 else if (e2->type->isreal())
359 #if __DMC__
360 c = e2->toReal() * e1->toComplex();
361 #else
362 r = e2->toReal();
363 c = e1->toComplex();
364 c = complex_t(r * creall(c), r * cimagl(c));
365 #endif
367 else if (e2->type->isimaginary())
369 #if __DMC__
370 c = e1->toComplex() * e2->toImaginary() * I;
371 #else
372 r = e2->toImaginary();
373 c = e1->toComplex();
374 c = complex_t(-r * cimagl(c), r * creall(c));
375 #endif
377 else
378 c = e1->toComplex() * e2->toComplex();
380 if (type->isreal())
381 e = new RealExp(loc, creall(c), type);
382 else if (type->isimaginary())
383 e = new RealExp(loc, cimagl(c), type);
384 else if (type->iscomplex())
385 e = new ComplexExp(loc, c, type);
386 else
387 assert(0);
389 else
391 e = new IntegerExp(loc, e1->toInteger() * e2->toInteger(), type);
393 return e;
396 Expression *Div(Type *type, Expression *e1, Expression *e2)
397 { Expression *e;
398 Loc loc = e1->loc;
400 if (type->isfloating())
401 { complex_t c;
402 #ifdef IN_GCC
403 real_t r;
404 #else
405 d_float80 r;
406 #endif
408 //e1->type->print();
409 //e2->type->print();
410 if (e2->type->isreal())
412 if (e1->type->isreal())
414 e = new RealExp(loc, e1->toReal() / e2->toReal(), type);
415 return e;
417 #if __DMC__
418 //r = e2->toReal();
419 //c = e1->toComplex();
420 //printf("(%Lg + %Lgi) / %Lg\n", creall(c), cimagl(c), r);
422 c = e1->toComplex() / e2->toReal();
423 #else
424 r = e2->toReal();
425 c = e1->toComplex();
426 c = complex_t(creall(c) / r, cimagl(c) / r);
427 #endif
429 else if (e2->type->isimaginary())
431 #if __DMC__
432 //r = e2->toImaginary();
433 //c = e1->toComplex();
434 //printf("(%Lg + %Lgi) / %Lgi\n", creall(c), cimagl(c), r);
436 c = e1->toComplex() / (e2->toImaginary() * I);
437 #else
438 r = e2->toImaginary();
439 c = e1->toComplex();
440 c = complex_t(cimagl(c) / r, -creall(c) / r);
441 #endif
443 else
445 c = e1->toComplex() / e2->toComplex();
448 if (type->isreal())
449 e = new RealExp(loc, creall(c), type);
450 else if (type->isimaginary())
451 e = new RealExp(loc, cimagl(c), type);
452 else if (type->iscomplex())
453 e = new ComplexExp(loc, c, type);
454 else
455 assert(0);
457 else
458 { sinteger_t n1;
459 sinteger_t n2;
460 sinteger_t n;
462 n1 = e1->toInteger();
463 n2 = e2->toInteger();
464 if (n2 == 0)
465 { e2->error("divide by 0");
466 e2 = new IntegerExp(0, 1, e2->type);
467 n2 = 1;
469 if (e1->type->isunsigned() || e2->type->isunsigned())
470 n = ((d_uns64) n1) / ((d_uns64) n2);
471 else
472 n = n1 / n2;
473 e = new IntegerExp(loc, n, type);
475 return e;
478 Expression *Mod(Type *type, Expression *e1, Expression *e2)
479 { Expression *e;
480 Loc loc = e1->loc;
482 if (type->isfloating())
484 complex_t c;
486 if (e2->type->isreal())
487 { real_t r2 = e2->toReal();
489 #ifdef __DMC__
490 c = fmodl(e1->toReal(), r2) + fmodl(e1->toImaginary(), r2) * I;
491 #elif defined(IN_GCC)
492 c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2);
493 #else
494 c = complex_t(fmodl(e1->toReal(), r2), fmodl(e1->toImaginary(), r2));
495 #endif
497 else if (e2->type->isimaginary())
498 { real_t i2 = e2->toImaginary();
500 #ifdef __DMC__
501 c = fmodl(e1->toReal(), i2) + fmodl(e1->toImaginary(), i2) * I;
502 #elif defined(IN_GCC)
503 c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2);
504 #else
505 c = complex_t(fmodl(e1->toReal(), i2), fmodl(e1->toImaginary(), i2));
506 #endif
508 else
509 assert(0);
511 if (type->isreal())
512 e = new RealExp(loc, creall(c), type);
513 else if (type->isimaginary())
514 e = new RealExp(loc, cimagl(c), type);
515 else if (type->iscomplex())
516 e = new ComplexExp(loc, c, type);
517 else
518 assert(0);
520 else
521 { sinteger_t n1;
522 sinteger_t n2;
523 sinteger_t n;
525 n1 = e1->toInteger();
526 n2 = e2->toInteger();
527 if (n2 == 0)
528 { e2->error("divide by 0");
529 e2 = new IntegerExp(0, 1, e2->type);
530 n2 = 1;
532 if (e1->type->isunsigned() || e2->type->isunsigned())
533 n = ((d_uns64) n1) % ((d_uns64) n2);
534 else
535 n = n1 % n2;
536 e = new IntegerExp(loc, n, type);
538 return e;
541 Expression *Shl(Type *type, Expression *e1, Expression *e2)
542 { Expression *e;
543 Loc loc = e1->loc;
545 e = new IntegerExp(loc, e1->toInteger() << e2->toInteger(), type);
546 return e;
549 Expression *Shr(Type *type, Expression *e1, Expression *e2)
550 { Expression *e;
551 Loc loc = e1->loc;
552 unsigned count;
553 integer_t value;
555 value = e1->toInteger();
556 count = e2->toInteger();
557 switch (e1->type->toBasetype()->ty)
559 case Tint8:
560 value = (d_int8)(value) >> count;
561 break;
563 case Tuns8:
564 value = (d_uns8)(value) >> count;
565 break;
567 case Tint16:
568 value = (d_int16)(value) >> count;
569 break;
571 case Tuns16:
572 value = (d_uns16)(value) >> count;
573 break;
575 case Tint32:
576 value = (d_int32)(value) >> count;
577 break;
579 case Tuns32:
580 value = (d_uns32)(value) >> count;
581 break;
583 case Tint64:
584 value = (d_int64)(value) >> count;
585 break;
587 case Tuns64:
588 value = (d_uns64)(value) >> count;
589 break;
591 default:
592 assert(0);
594 e = new IntegerExp(loc, value, type);
595 return e;
598 Expression *Ushr(Type *type, Expression *e1, Expression *e2)
599 { Expression *e;
600 Loc loc = e1->loc;
601 unsigned count;
602 integer_t value;
604 value = e1->toInteger();
605 count = e2->toInteger();
606 switch (e1->type->toBasetype()->ty)
608 case Tint8:
609 case Tuns8:
610 assert(0); // no way to trigger this
611 value = (value & 0xFF) >> count;
612 break;
614 case Tint16:
615 case Tuns16:
616 assert(0); // no way to trigger this
617 value = (value & 0xFFFF) >> count;
618 break;
620 case Tint32:
621 case Tuns32:
622 value = (value & 0xFFFFFFFF) >> count;
623 break;
625 case Tint64:
626 case Tuns64:
627 value = (d_uns64)(value) >> count;
628 break;
630 default:
631 assert(0);
633 e = new IntegerExp(loc, value, type);
634 return e;
637 Expression *And(Type *type, Expression *e1, Expression *e2)
638 { Expression *e;
639 Loc loc = e1->loc;
641 e = new IntegerExp(loc, e1->toInteger() & e2->toInteger(), type);
642 return e;
645 Expression *Or(Type *type, Expression *e1, Expression *e2)
646 { Expression *e;
647 Loc loc = e1->loc;
649 e = new IntegerExp(loc, e1->toInteger() | e2->toInteger(), type);
650 return e;
653 Expression *Xor(Type *type, Expression *e1, Expression *e2)
654 { Expression *e;
655 Loc loc = e1->loc;
657 e = new IntegerExp(loc, e1->toInteger() ^ e2->toInteger(), type);
658 return e;
661 /* Also returns EXP_CANT_INTERPRET if cannot be computed.
663 Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2)
664 { Expression *e;
665 Loc loc = e1->loc;
666 int cmp;
667 real_t r1;
668 real_t r2;
670 //printf("Equal(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
672 assert(op == TOKequal || op == TOKnotequal);
674 if (e1->op == TOKnull)
676 if (e2->op == TOKnull)
677 cmp = 1;
678 else if (e2->op == TOKstring)
679 { StringExp *es2 = (StringExp *)e2;
680 cmp = (0 == es2->len);
682 else if (e2->op == TOKarrayliteral)
683 { ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
684 cmp = !es2->elements || (0 == es2->elements->dim);
686 else
687 return EXP_CANT_INTERPRET;
689 else if (e2->op == TOKnull)
691 if (e1->op == TOKstring)
692 { StringExp *es1 = (StringExp *)e1;
693 cmp = (0 == es1->len);
695 else if (e1->op == TOKarrayliteral)
696 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
697 cmp = !es1->elements || (0 == es1->elements->dim);
699 else
700 return EXP_CANT_INTERPRET;
702 else if (e1->op == TOKstring && e2->op == TOKstring)
703 { StringExp *es1 = (StringExp *)e1;
704 StringExp *es2 = (StringExp *)e2;
706 assert(es1->sz == es2->sz);
707 if (es1->len == es2->len &&
708 memcmp(es1->string, es2->string, es1->sz * es1->len) == 0)
709 cmp = 1;
710 else
711 cmp = 0;
713 else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral)
714 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
715 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
717 if ((!es1->elements || !es1->elements->dim) &&
718 (!es2->elements || !es2->elements->dim))
719 cmp = 1; // both arrays are empty
720 else if (!es1->elements || !es2->elements)
721 cmp = 0;
722 else if (es1->elements->dim != es2->elements->dim)
723 cmp = 0;
724 else
726 for (size_t i = 0; i < es1->elements->dim; i++)
727 { Expression *ee1 = (Expression *)es1->elements->data[i];
728 Expression *ee2 = (Expression *)es2->elements->data[i];
730 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2);
731 if (v == EXP_CANT_INTERPRET)
732 return EXP_CANT_INTERPRET;
733 cmp = v->toInteger();
734 if (cmp == 0)
735 break;
739 else if (e1->op == TOKarrayliteral && e2->op == TOKstring)
740 { // Swap operands and use common code
741 Expression *e = e1;
742 e1 = e2;
743 e2 = e;
744 goto Lsa;
746 else if (e1->op == TOKstring && e2->op == TOKarrayliteral)
748 Lsa:
749 StringExp *es1 = (StringExp *)e1;
750 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
751 size_t dim1 = es1->len;
752 size_t dim2 = es2->elements ? es2->elements->dim : 0;
753 if (dim1 != dim2)
754 cmp = 0;
755 else
757 for (size_t i = 0; i < dim1; i++)
759 uinteger_t c = es1->charAt(i);
760 Expression *ee2 = (Expression *)es2->elements->data[i];
761 if (ee2->isConst() != 1)
762 return EXP_CANT_INTERPRET;
763 cmp = (c == ee2->toInteger());
764 if (cmp == 0)
765 break;
769 else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral)
770 { StructLiteralExp *es1 = (StructLiteralExp *)e1;
771 StructLiteralExp *es2 = (StructLiteralExp *)e2;
773 if (es1->sd != es2->sd)
774 cmp = 0;
775 else if ((!es1->elements || !es1->elements->dim) &&
776 (!es2->elements || !es2->elements->dim))
777 cmp = 1; // both arrays are empty
778 else if (!es1->elements || !es2->elements)
779 cmp = 0;
780 else if (es1->elements->dim != es2->elements->dim)
781 cmp = 0;
782 else
784 cmp = 1;
785 for (size_t i = 0; i < es1->elements->dim; i++)
786 { Expression *ee1 = (Expression *)es1->elements->data[i];
787 Expression *ee2 = (Expression *)es2->elements->data[i];
789 if (ee1 == ee2)
790 continue;
791 if (!ee1 || !ee2)
792 { cmp = 0;
793 break;
795 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2);
796 if (v == EXP_CANT_INTERPRET)
797 return EXP_CANT_INTERPRET;
798 cmp = v->toInteger();
799 if (cmp == 0)
800 break;
804 #if 0 // Should handle this
805 else if (e1->op == TOKarrayliteral && e2->op == TOKstring)
808 #endif
809 else if (e1->isConst() != 1 || e2->isConst() != 1)
810 return EXP_CANT_INTERPRET;
811 else if (e1->type->isreal())
813 r1 = e1->toReal();
814 r2 = e2->toReal();
815 goto L1;
817 else if (e1->type->isimaginary())
819 r1 = e1->toImaginary();
820 r2 = e2->toImaginary();
822 #if __DMC__
823 cmp = (r1 == r2);
824 #else
825 # if IN_GCC
826 if (r1.isNan() || r2.isNan()) // if unordered
827 # else
828 if (isnan(r1) || isnan(r2)) // if unordered
829 # endif
831 cmp = 0;
833 else
835 cmp = (r1 == r2);
837 #endif
839 else if (e1->type->iscomplex())
841 cmp = e1->toComplex() == e2->toComplex();
843 else if (e1->type->isintegral())
845 cmp = (e1->toInteger() == e2->toInteger());
847 else
848 return EXP_CANT_INTERPRET;
849 if (op == TOKnotequal)
850 cmp ^= 1;
851 e = new IntegerExp(loc, cmp, type);
852 return e;
855 Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2)
856 { Expression *e;
857 Loc loc = e1->loc;
858 int cmp;
860 if (e1->op == TOKnull && e2->op == TOKnull)
862 cmp = 1;
864 else if (e1->op == TOKsymoff && e2->op == TOKsymoff)
866 SymOffExp *es1 = (SymOffExp *)e1;
867 SymOffExp *es2 = (SymOffExp *)e2;
869 cmp = (es1->var == es2->var && es1->offset == es2->offset);
871 else if (e1->isConst() == 1 && e2->isConst() == 1)
872 return Equal((op == TOKidentity) ? TOKequal : TOKnotequal,
873 type, e1, e2);
874 else
875 assert(0);
876 if (op == TOKnotidentity)
877 cmp ^= 1;
878 return new IntegerExp(loc, cmp, type);
882 Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2)
883 { Expression *e;
884 Loc loc = e1->loc;
885 integer_t n;
886 real_t r1;
887 real_t r2;
889 //printf("Cmp(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
891 if (e1->op == TOKstring && e2->op == TOKstring)
892 { StringExp *es1 = (StringExp *)e1;
893 StringExp *es2 = (StringExp *)e2;
894 size_t sz = es1->sz;
895 assert(sz == es2->sz);
897 size_t len = es1->len;
898 if (es2->len < len)
899 len = es2->len;
901 int cmp = 0;
902 if (sz == 1)
903 cmp = memcmp(es1->string, es2->string, sz * len);
904 else if (sz == 2)
906 const d_uns16 * p1 = (const d_uns16 *) es1->string;
907 const d_uns16 * p2 = (const d_uns16 *) es2->string;
908 for (size_t i = 0; i < len; ++i)
909 if (p1[i] > p2[i])
910 { cmp = 1; break; }
911 else if (p1[i] < p2[i])
912 { cmp = -1; break; }
914 else if (sz == 4)
916 const d_uns32 * p1 = (const d_uns32 *) es1->string;
917 const d_uns32 * p2 = (const d_uns32 *) es2->string;
918 for (size_t i = 0; i < len; ++i)
919 if (p1[i] > p2[i])
920 { cmp = 1; break; }
921 else if (p1[i] < p2[i])
922 { cmp = -1; break; }
924 else
925 assert(0);
927 if (cmp == 0)
928 cmp = es1->len - es2->len;
930 switch (op)
932 case TOKlt: n = cmp < 0; break;
933 case TOKle: n = cmp <= 0; break;
934 case TOKgt: n = cmp > 0; break;
935 case TOKge: n = cmp >= 0; break;
937 case TOKleg: n = 1; break;
938 case TOKlg: n = cmp != 0; break;
939 case TOKunord: n = 0; break;
940 case TOKue: n = cmp == 0; break;
941 case TOKug: n = cmp > 0; break;
942 case TOKuge: n = cmp >= 0; break;
943 case TOKul: n = cmp < 0; break;
944 case TOKule: n = cmp <= 0; break;
946 default:
947 assert(0);
950 else if (e1->isConst() != 1 || e2->isConst() != 1)
951 return EXP_CANT_INTERPRET;
952 else if (e1->type->isreal())
954 r1 = e1->toReal();
955 r2 = e2->toReal();
956 goto L1;
958 else if (e1->type->isimaginary())
960 r1 = e1->toImaginary();
961 r2 = e2->toImaginary();
963 #if __DMC__
964 // DMC is the only compiler I know of that handles NAN arguments
965 // correctly in comparisons.
966 switch (op)
968 case TOKlt: n = r1 < r2; break;
969 case TOKle: n = r1 <= r2; break;
970 case TOKgt: n = r1 > r2; break;
971 case TOKge: n = r1 >= r2; break;
973 case TOKleg: n = r1 <>= r2; break;
974 case TOKlg: n = r1 <> r2; break;
975 case TOKunord: n = r1 !<>= r2; break;
976 case TOKue: n = r1 !<> r2; break;
977 case TOKug: n = r1 !<= r2; break;
978 case TOKuge: n = r1 !< r2; break;
979 case TOKul: n = r1 !>= r2; break;
980 case TOKule: n = r1 !> r2; break;
982 default:
983 assert(0);
985 #else
986 // Don't rely on compiler, handle NAN arguments separately
987 #if IN_GCC
988 if (r1.isNan() || r2.isNan()) // if unordered
989 #else
990 if (isnan(r1) || isnan(r2)) // if unordered
991 #endif
993 switch (op)
995 case TOKlt: n = 0; break;
996 case TOKle: n = 0; break;
997 case TOKgt: n = 0; break;
998 case TOKge: n = 0; break;
1000 case TOKleg: n = 0; break;
1001 case TOKlg: n = 0; break;
1002 case TOKunord: n = 1; break;
1003 case TOKue: n = 1; break;
1004 case TOKug: n = 1; break;
1005 case TOKuge: n = 1; break;
1006 case TOKul: n = 1; break;
1007 case TOKule: n = 1; break;
1009 default:
1010 assert(0);
1013 else
1015 switch (op)
1017 case TOKlt: n = r1 < r2; break;
1018 case TOKle: n = r1 <= r2; break;
1019 case TOKgt: n = r1 > r2; break;
1020 case TOKge: n = r1 >= r2; break;
1022 case TOKleg: n = 1; break;
1023 case TOKlg: n = r1 != r2; break;
1024 case TOKunord: n = 0; break;
1025 case TOKue: n = r1 == r2; break;
1026 case TOKug: n = r1 > r2; break;
1027 case TOKuge: n = r1 >= r2; break;
1028 case TOKul: n = r1 < r2; break;
1029 case TOKule: n = r1 <= r2; break;
1031 default:
1032 assert(0);
1035 #endif
1037 else if (e1->type->iscomplex())
1039 assert(0);
1041 else
1042 { sinteger_t n1;
1043 sinteger_t n2;
1045 n1 = e1->toInteger();
1046 n2 = e2->toInteger();
1047 if (e1->type->isunsigned() || e2->type->isunsigned())
1049 switch (op)
1051 case TOKlt: n = ((d_uns64) n1) < ((d_uns64) n2); break;
1052 case TOKle: n = ((d_uns64) n1) <= ((d_uns64) n2); break;
1053 case TOKgt: n = ((d_uns64) n1) > ((d_uns64) n2); break;
1054 case TOKge: n = ((d_uns64) n1) >= ((d_uns64) n2); break;
1056 case TOKleg: n = 1; break;
1057 case TOKlg: n = ((d_uns64) n1) != ((d_uns64) n2); break;
1058 case TOKunord: n = 0; break;
1059 case TOKue: n = ((d_uns64) n1) == ((d_uns64) n2); break;
1060 case TOKug: n = ((d_uns64) n1) > ((d_uns64) n2); break;
1061 case TOKuge: n = ((d_uns64) n1) >= ((d_uns64) n2); break;
1062 case TOKul: n = ((d_uns64) n1) < ((d_uns64) n2); break;
1063 case TOKule: n = ((d_uns64) n1) <= ((d_uns64) n2); break;
1065 default:
1066 assert(0);
1069 else
1071 switch (op)
1073 case TOKlt: n = n1 < n2; break;
1074 case TOKle: n = n1 <= n2; break;
1075 case TOKgt: n = n1 > n2; break;
1076 case TOKge: n = n1 >= n2; break;
1078 case TOKleg: n = 1; break;
1079 case TOKlg: n = n1 != n2; break;
1080 case TOKunord: n = 0; break;
1081 case TOKue: n = n1 == n2; break;
1082 case TOKug: n = n1 > n2; break;
1083 case TOKuge: n = n1 >= n2; break;
1084 case TOKul: n = n1 < n2; break;
1085 case TOKule: n = n1 <= n2; break;
1087 default:
1088 assert(0);
1092 e = new IntegerExp(loc, n, type);
1093 return e;
1096 /* Also returns EXP_CANT_INTERPRET if cannot be computed.
1097 * to: type to cast to
1098 * type: type to paint the result
1101 Expression *Cast(Type *type, Type *to, Expression *e1)
1102 { Expression *e = EXP_CANT_INTERPRET;
1103 Loc loc = e1->loc;
1105 //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars());
1106 //printf("\te1->type = %s\n", e1->type->toChars());
1107 if (e1->type->equals(type) && type->equals(to))
1108 return e1;
1109 if (e1->type->implicitConvTo(to) >= MATCHconst ||
1110 to->implicitConvTo(e1->type) >= MATCHconst)
1111 return expType(to, e1);
1113 if (e1->isConst() != 1)
1114 return EXP_CANT_INTERPRET;
1116 Type *tb = to->toBasetype();
1117 if (tb->ty == Tbool)
1118 e = new IntegerExp(loc, e1->toInteger() != 0, type);
1119 else if (type->isintegral())
1121 if (e1->type->isfloating())
1122 { integer_t result;
1123 #ifdef IN_GCC
1124 Type * rt = e1->type;
1125 if (rt->iscomplex())
1127 switch (rt->toBasetype()->ty)
1129 case Tcomplex32: rt = Type::tfloat32; break;
1130 case Tcomplex64: rt = Type::tfloat64; break;
1131 case Tcomplex80: rt = Type::tfloat80; break;
1132 default: assert(0);
1135 d_int64 r = e1->toReal().toInt(rt, type);
1136 #else
1137 real_t r = e1->toReal();
1138 #endif
1140 switch (type->toBasetype()->ty)
1142 case Tint8: result = (d_int8)r; break;
1143 case Tchar:
1144 case Tuns8: result = (d_uns8)r; break;
1145 case Tint16: result = (d_int16)r; break;
1146 case Twchar:
1147 case Tuns16: result = (d_uns16)r; break;
1148 case Tint32: result = (d_int32)r; break;
1149 case Tdchar:
1150 case Tuns32: result = (d_uns32)r; break;
1151 case Tint64: result = (d_int64)r; break;
1152 case Tuns64: result = (d_uns64)r; break;
1153 default:
1154 assert(0);
1157 e = new IntegerExp(loc, result, type);
1159 else if (type->isunsigned())
1160 e = new IntegerExp(loc, e1->toUInteger(), type);
1161 else
1162 e = new IntegerExp(loc, e1->toInteger(), type);
1164 else if (tb->isreal())
1165 { real_t value = e1->toReal();
1167 e = new RealExp(loc, value, type);
1169 else if (tb->isimaginary())
1170 { real_t value = e1->toImaginary();
1172 e = new RealExp(loc, value, type);
1174 else if (tb->iscomplex())
1175 { complex_t value = e1->toComplex();
1177 e = new ComplexExp(loc, value, type);
1179 else if (tb->isscalar())
1180 e = new IntegerExp(loc, e1->toInteger(), type);
1181 else if (tb->ty == Tvoid)
1182 e = EXP_CANT_INTERPRET;
1183 else if (tb->ty == Tstruct && e1->op == TOKint64)
1184 { // Struct = 0;
1185 StructDeclaration *sd = tb->toDsymbol(NULL)->isStructDeclaration();
1186 assert(sd);
1187 Expressions *elements = new Expressions;
1188 for (size_t i = 0; i < sd->fields.dim; i++)
1189 { Dsymbol *s = (Dsymbol *)sd->fields.data[i];
1190 VarDeclaration *v = s->isVarDeclaration();
1191 assert(v);
1193 Expression *exp = new IntegerExp(0);
1194 exp = Cast(v->type, v->type, exp);
1195 if (exp == EXP_CANT_INTERPRET)
1196 return exp;
1197 elements->push(exp);
1199 e = new StructLiteralExp(loc, sd, elements);
1200 e->type = type;
1202 else
1204 error(loc, "cannot cast %s to %s", e1->type->toChars(), type->toChars());
1205 e = new IntegerExp(loc, 0, type);
1207 return e;
1211 Expression *ArrayLength(Type *type, Expression *e1)
1212 { Expression *e;
1213 Loc loc = e1->loc;
1215 if (e1->op == TOKstring)
1216 { StringExp *es1 = (StringExp *)e1;
1218 e = new IntegerExp(loc, es1->len, type);
1220 else if (e1->op == TOKarrayliteral)
1221 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1222 size_t dim;
1224 dim = ale->elements ? ale->elements->dim : 0;
1225 e = new IntegerExp(loc, dim, type);
1227 else if (e1->op == TOKassocarrayliteral)
1228 { AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e1;
1229 size_t dim = ale->keys->dim;
1231 e = new IntegerExp(loc, dim, type);
1233 else
1234 e = EXP_CANT_INTERPRET;
1235 return e;
1238 /* Also return EXP_CANT_INTERPRET if this fails
1240 Expression *Index(Type *type, Expression *e1, Expression *e2)
1241 { Expression *e = EXP_CANT_INTERPRET;
1242 Loc loc = e1->loc;
1244 //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1245 assert(e1->type);
1246 if (e1->op == TOKstring && e2->op == TOKint64)
1247 { StringExp *es1 = (StringExp *)e1;
1248 uinteger_t i = e2->toInteger();
1250 if (i >= es1->len)
1251 e1->error("string index %"PRIuMAX" is out of bounds [0 .. %"PRIuSIZE"]", i, es1->len);
1252 else
1253 { unsigned value = es1->charAt(i);
1254 e = new IntegerExp(loc, value, type);
1257 else if (e1->type->toBasetype()->ty == Tsarray && e2->op == TOKint64)
1258 { TypeSArray *tsa = (TypeSArray *)e1->type->toBasetype();
1259 uinteger_t length = tsa->dim->toInteger();
1260 uinteger_t i = e2->toInteger();
1262 if (i >= length)
1263 { e2->error("array index %"PRIuMAX" is out of bounds %s[0 .. %"PRIuMAX"]", i, e1->toChars(), length);
1265 else if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2))
1266 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1267 e = (Expression *)ale->elements->data[i];
1268 e->type = type;
1271 else if (e1->type->toBasetype()->ty == Tarray && e2->op == TOKint64)
1273 uinteger_t i = e2->toInteger();
1275 if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2))
1276 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
1277 if (i >= ale->elements->dim)
1278 { e2->error("array index %ju is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim);
1280 else
1281 { e = (Expression *)ale->elements->data[i];
1282 e->type = type;
1286 else if (e1->op == TOKassocarrayliteral && !e1->checkSideEffect(2))
1288 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e1;
1289 /* Search the keys backwards, in case there are duplicate keys
1291 for (size_t i = ae->keys->dim; i;)
1293 i--;
1294 Expression *ekey = (Expression *)ae->keys->data[i];
1295 Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2);
1296 if (ex == EXP_CANT_INTERPRET)
1297 return ex;
1298 if (ex->isBool(TRUE))
1299 { e = (Expression *)ae->values->data[i];
1300 e->type = type;
1301 break;
1305 return e;
1308 /* Also return EXP_CANT_INTERPRET if this fails
1310 Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
1311 { Expression *e = EXP_CANT_INTERPRET;
1312 Loc loc = e1->loc;
1314 #if LOG
1315 printf("Slice()\n");
1316 if (lwr)
1317 { printf("\te1 = %s\n", e1->toChars());
1318 printf("\tlwr = %s\n", lwr->toChars());
1319 printf("\tupr = %s\n", upr->toChars());
1321 #endif
1322 if (e1->op == TOKstring && lwr->op == TOKint64 && upr->op == TOKint64)
1323 { StringExp *es1 = (StringExp *)e1;
1324 uinteger_t ilwr = lwr->toInteger();
1325 uinteger_t iupr = upr->toInteger();
1327 if (iupr > es1->len || ilwr > iupr)
1328 e1->error("string slice [%"PRIuMAX" .. %"PRIuMAX"] is out of bounds", ilwr, iupr);
1329 else
1330 { integer_t value;
1331 void *s;
1332 size_t len = iupr - ilwr;
1333 int sz = es1->sz;
1334 StringExp *es;
1336 s = mem.malloc((len + 1) * sz);
1337 memcpy((unsigned char *)s, (unsigned char *)es1->string + ilwr * sz, len * sz);
1338 memset((unsigned char *)s + len * sz, 0, sz);
1340 es = new StringExp(loc, s, len, es1->postfix);
1341 es->sz = sz;
1342 es->committed = 1;
1343 es->type = type;
1344 e = es;
1347 else if (e1->op == TOKarrayliteral &&
1348 lwr->op == TOKint64 && upr->op == TOKint64 &&
1349 !e1->checkSideEffect(2))
1350 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
1351 uinteger_t ilwr = lwr->toInteger();
1352 uinteger_t iupr = upr->toInteger();
1354 if (iupr > es1->elements->dim || ilwr > iupr)
1355 e1->error("array slice [%"PRIuMAX" .. %"PRIuMAX"] is out of bounds", ilwr, iupr);
1356 else
1358 Expressions *elements = new Expressions();
1359 elements->setDim(iupr - ilwr);
1360 memcpy(elements->data,
1361 es1->elements->data + ilwr,
1362 (iupr - ilwr) * sizeof(es1->elements->data[0]));
1363 e = new ArrayLiteralExp(e1->loc, elements);
1364 e->type = type;
1367 return e;
1370 /* Also return EXP_CANT_INTERPRET if this fails
1372 Expression *Cat(Type *type, Expression *e1, Expression *e2)
1373 { Expression *e = EXP_CANT_INTERPRET;
1374 Loc loc = e1->loc;
1375 Type *t;
1376 Type *t1 = e1->type->toBasetype();
1377 Type *t2 = e2->type->toBasetype();
1379 //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
1380 //printf("\tt1 = %s, t2 = %s\n", t1->toChars(), t2->toChars());
1382 if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral))
1383 { e = e2;
1384 goto L2;
1386 else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull)
1387 { e = e1;
1389 Type *tn = e->type->toBasetype();
1390 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
1392 // Create a StringExp
1393 void *s;
1394 StringExp *es;
1395 size_t len = 1;
1396 int sz = tn->size();
1397 integer_t v = e->toInteger();
1399 s = mem.malloc((len + 1) * sz);
1400 switch (sz)
1402 case 1: *(d_uns8*)s = v; break;
1403 case 2: *(d_uns16*)s = v; break;
1404 case 4: *(d_uns32*)s = v; break;
1405 default: assert(0);
1408 // Add terminating 0
1409 memset((unsigned char *)s + len * sz, 0, sz);
1411 es = new StringExp(loc, s, len);
1412 es->sz = sz;
1413 es->committed = 1;
1414 e = es;
1416 else
1417 { // Create an ArrayLiteralExp
1418 Expressions *elements = new Expressions();
1419 elements->push(e);
1420 e = new ArrayLiteralExp(e->loc, elements);
1422 e->type = type;
1423 return e;
1425 else if (e1->op == TOKstring && e2->op == TOKstring)
1427 // Concatenate the strings
1428 void *s;
1429 StringExp *es1 = (StringExp *)e1;
1430 StringExp *es2 = (StringExp *)e2;
1431 StringExp *es;
1432 Type *t;
1433 size_t len = es1->len + es2->len;
1434 int sz = es1->sz;
1436 assert(sz == es2->sz);
1437 s = mem.malloc((len + 1) * sz);
1438 memcpy(s, es1->string, es1->len * sz);
1439 memcpy((unsigned char *)s + es1->len * sz, es2->string, es2->len * sz);
1441 // Add terminating 0
1442 memset((unsigned char *)s + len * sz, 0, sz);
1444 es = new StringExp(loc, s, len);
1445 es->sz = sz;
1446 es->committed = es1->committed | es2->committed;
1447 if (es1->committed)
1448 t = es1->type;
1449 else
1450 t = es2->type;
1451 es->type = type;
1452 e = es;
1454 else if (e1->op == TOKstring && e2->op == TOKint64)
1456 // Concatenate the strings
1457 void *s;
1458 void *sch;
1459 StringExp *es1 = (StringExp *)e1;
1460 StringExp *es;
1461 Type *t;
1462 size_t len = es1->len + 1;
1463 int sz = es1->sz;
1464 integer_t v = e2->toInteger();
1466 s = mem.malloc((len + 1) * sz);
1467 memcpy(s, es1->string, es1->len * sz);
1468 sch = (unsigned char *)s + es1->len * sz;
1469 switch (sz)
1471 case 1: *(d_uns8*)sch = v; break;
1472 case 2: *(d_uns16*)sch = v; break;
1473 case 4: *(d_uns32*)sch = v; break;
1474 default: assert(0);
1477 // Add terminating 0
1478 memset((unsigned char *)s + len * sz, 0, sz);
1480 es = new StringExp(loc, s, len);
1481 es->sz = sz;
1482 es->committed = es1->committed;
1483 t = es1->type;
1484 es->type = type;
1485 e = es;
1487 else if (e1->op == TOKint64 && e2->op == TOKstring)
1489 // Concatenate the strings
1490 void *s;
1491 StringExp *es2 = (StringExp *)e2;
1492 StringExp *es;
1493 Type *t;
1494 size_t len = 1 + es2->len;
1495 int sz = es2->sz;
1496 integer_t v = e1->toInteger();
1498 s = mem.malloc((len + 1) * sz);
1499 switch (sz)
1501 case 1: *(d_uns8*)s = v; break;
1502 case 2: *(d_uns16*)s = v; break;
1503 case 4: *(d_uns32*)s = v; break;
1504 default: assert(0);
1506 memcpy((unsigned char *)s + sz, es2->string, es2->len * sz);
1508 // Add terminating 0
1509 memset((unsigned char *)s + len * sz, 0, sz);
1511 es = new StringExp(loc, s, len);
1512 es->sz = sz;
1513 es->committed = es2->committed;
1514 t = es2->type;
1515 es->type = type;
1516 e = es;
1518 else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral &&
1519 t1->nextOf()->equals(t2->nextOf()))
1521 // Concatenate the arrays
1522 ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
1523 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
1525 es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy());
1526 es1->elements->insert(es1->elements->dim, es2->elements);
1527 e = es1;
1529 if (type->toBasetype()->ty == Tsarray)
1531 e->type = new TypeSArray(t1->nextOf(), new IntegerExp(0, es1->elements->dim, Type::tindex));
1532 e->type = e->type->semantic(loc, NULL);
1534 else
1535 e->type = type;
1537 else if (e1->op == TOKarrayliteral &&
1538 e1->type->toBasetype()->nextOf()->equals(e2->type))
1540 ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
1542 es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy());
1543 es1->elements->push(e2);
1544 e = es1;
1546 if (type->toBasetype()->ty == Tsarray)
1548 e->type = new TypeSArray(e2->type, new IntegerExp(0, es1->elements->dim, Type::tindex));
1549 e->type = e->type->semantic(loc, NULL);
1551 else
1552 e->type = type;
1554 else if (e2->op == TOKarrayliteral &&
1555 e2->type->toBasetype()->nextOf()->equals(e1->type))
1557 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
1559 es2 = new ArrayLiteralExp(es2->loc, (Expressions *)es2->elements->copy());
1560 es2->elements->shift(e1);
1561 e = es2;
1563 if (type->toBasetype()->ty == Tsarray)
1565 e->type = new TypeSArray(e1->type, new IntegerExp(0, es2->elements->dim, Type::tindex));
1566 e->type = e->type->semantic(loc, NULL);
1568 else
1569 e->type = type;
1571 else if (e1->op == TOKnull && e2->op == TOKstring)
1573 t = e1->type;
1574 e = e2;
1575 goto L1;
1577 else if (e1->op == TOKstring && e2->op == TOKnull)
1578 { e = e1;
1579 t = e2->type;
1581 Type *tb = t->toBasetype();
1582 if (tb->ty == Tarray && tb->nextOf()->equals(e->type))
1583 { Expressions *expressions = new Expressions();
1584 expressions->push(e);
1585 e = new ArrayLiteralExp(loc, expressions);
1586 e->type = t;
1588 if (!e->type->equals(type))
1589 { StringExp *se = (StringExp *)e->copy();
1590 e = se->castTo(NULL, type);
1593 return e;
1596 Expression *Ptr(Type *type, Expression *e1)
1598 //printf("Ptr(e1 = %s)\n", e1->toChars());
1599 if (e1->op == TOKadd)
1600 { AddExp *ae = (AddExp *)e1;
1601 if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64)
1602 { AddrExp *ade = (AddrExp *)ae->e1;
1603 if (ade->e1->op == TOKstructliteral)
1604 { StructLiteralExp *se = (StructLiteralExp *)ade->e1;
1605 unsigned offset = ae->e2->toInteger();
1606 Expression *e = se->getField(type, offset);
1607 if (!e)
1608 e = EXP_CANT_INTERPRET;
1609 return e;
1613 return EXP_CANT_INTERPRET;