comparison dmd/cast.c @ 1:c53b6e3fe49a trunk

[svn r5] Initial commit. Most things are very rough.
author lindquist
date Sat, 01 Sep 2007 21:43:27 +0200
parents
children 788401029ecf
comparison
equal deleted inserted replaced
0:a9e71648e74d 1:c53b6e3fe49a
1
2 // Copyright (c) 1999-2006 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include <stdio.h>
11 #include <assert.h>
12
13 #if _WIN32 || IN_GCC || IN_LLVM
14 #include "mem.h"
15 #else
16 #include "../root/mem.h"
17 #endif
18
19 #include "expression.h"
20 #include "mtype.h"
21 #include "utf.h"
22 #include "declaration.h"
23 #include "aggregate.h"
24
25 /* ==================== implicitCast ====================== */
26
27 /**************************************
28 * Do an implicit cast.
29 * Issue error if it can't be done.
30 */
31
32 Expression *Expression::implicitCastTo(Scope *sc, Type *t)
33 {
34 //printf("implicitCastTo(%s) => %s\n", type->toChars(), t->toChars());
35 if (implicitConvTo(t))
36 {
37 if (global.params.warnings &&
38 Type::impcnvWarn[type->toBasetype()->ty][t->toBasetype()->ty] &&
39 op != TOKint64)
40 {
41 Expression *e = optimize(WANTflags | WANTvalue);
42
43 if (e->op == TOKint64)
44 return e->implicitCastTo(sc, t);
45
46 fprintf(stdmsg, "warning - ");
47 error("implicit conversion of expression (%s) of type %s to %s can cause loss of data",
48 toChars(), type->toChars(), t->toChars());
49 }
50 return castTo(sc, t);
51 }
52
53 Expression *e = optimize(WANTflags | WANTvalue);
54 if (e != this)
55 return e->implicitCastTo(sc, t);
56
57 #if 0
58 print();
59 type->print();
60 printf("to:\n");
61 t->print();
62 printf("%p %p type: %s to: %s\n", type->deco, t->deco, type->deco, t->deco);
63 //printf("%p %p %p\n", type->next->arrayOf(), type, t);
64 fflush(stdout);
65 #endif
66 if (!t->deco)
67 { /* Can happen with:
68 * enum E { One }
69 * class A
70 * { static void fork(EDG dg) { dg(E.One); }
71 * alias void delegate(E) EDG;
72 * }
73 * Should eventually make it work.
74 */
75 error("forward reference to type %s", t->toChars());
76 }
77 else if (t->reliesOnTident())
78 error("forward reference to type %s", t->reliesOnTident()->toChars());
79
80 error("cannot implicitly convert expression (%s) of type %s to %s",
81 toChars(), type->toChars(), t->toChars());
82 return castTo(sc, t);
83 }
84
85 /*******************************************
86 * Return !=0 if we can implicitly convert this to type t.
87 * Don't do the actual cast.
88 */
89
90 MATCH Expression::implicitConvTo(Type *t)
91 {
92 #if 0
93 printf("Expression::implicitConvTo(this=%s, type=%s, t=%s)\n",
94 toChars(), type->toChars(), t->toChars());
95 #endif
96 if (!type)
97 { error("%s is not an expression", toChars());
98 type = Type::terror;
99 }
100 if (t->ty == Tbit && isBit())
101 return MATCHconvert;
102 Expression *e = optimize(WANTvalue | WANTflags);
103 if (e != this)
104 { //printf("optimzed to %s\n", e->toChars());
105 return e->implicitConvTo(t);
106 }
107 MATCH match = type->implicitConvTo(t);
108 if (match)
109 return match;
110 #if 0
111 Type *tb = t->toBasetype();
112 if (tb->ty == Tdelegate)
113 { TypeDelegate *td = (TypeDelegate *)tb;
114 TypeFunction *tf = (TypeFunction *)td->next;
115
116 if (!tf->varargs &&
117 !(tf->arguments && tf->arguments->dim)
118 )
119 {
120 match = type->implicitConvTo(tf->next);
121 if (match)
122 return match;
123 if (tf->next->toBasetype()->ty == Tvoid)
124 return MATCHconvert;
125 }
126 }
127 #endif
128 return MATCHnomatch;
129 }
130
131
132 MATCH IntegerExp::implicitConvTo(Type *t)
133 {
134 #if 0
135 printf("IntegerExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
136 toChars(), type->toChars(), t->toChars());
137 #endif
138 if (type->equals(t))
139 return MATCHexact;
140
141 enum TY ty = type->toBasetype()->ty;
142 enum TY toty = t->toBasetype()->ty;
143
144 if (type->implicitConvTo(t) == MATCHnomatch && t->ty == Tenum)
145 {
146 return MATCHnomatch;
147 }
148
149 switch (ty)
150 {
151 case Tbit:
152 case Tbool:
153 value &= 1;
154 ty = Tint32;
155 break;
156
157 case Tint8:
158 value = (signed char)value;
159 ty = Tint32;
160 break;
161
162 case Tchar:
163 case Tuns8:
164 value &= 0xFF;
165 ty = Tint32;
166 break;
167
168 case Tint16:
169 value = (short)value;
170 ty = Tint32;
171 break;
172
173 case Tuns16:
174 case Twchar:
175 value &= 0xFFFF;
176 ty = Tint32;
177 break;
178
179 case Tint32:
180 value = (int)value;
181 break;
182
183 case Tuns32:
184 case Tdchar:
185 value &= 0xFFFFFFFF;
186 ty = Tuns32;
187 break;
188
189 default:
190 break;
191 }
192
193 // Only allow conversion if no change in value
194 switch (toty)
195 {
196 case Tbit:
197 case Tbool:
198 if ((value & 1) != value)
199 goto Lno;
200 goto Lyes;
201
202 case Tint8:
203 if ((signed char)value != value)
204 goto Lno;
205 goto Lyes;
206
207 case Tchar:
208 case Tuns8:
209 //printf("value = %llu %llu\n", (integer_t)(unsigned char)value, value);
210 if ((unsigned char)value != value)
211 goto Lno;
212 goto Lyes;
213
214 case Tint16:
215 if ((short)value != value)
216 goto Lno;
217 goto Lyes;
218
219 case Tuns16:
220 if ((unsigned short)value != value)
221 goto Lno;
222 goto Lyes;
223
224 case Tint32:
225 if (ty == Tuns32)
226 {
227 }
228 else if ((int)value != value)
229 goto Lno;
230 goto Lyes;
231
232 case Tuns32:
233 if (ty == Tint32)
234 {
235 }
236 else if ((unsigned)value != value)
237 goto Lno;
238 goto Lyes;
239
240 case Tdchar:
241 if (value > 0x10FFFFUL)
242 goto Lno;
243 goto Lyes;
244
245 case Twchar:
246 if ((unsigned short)value != value)
247 goto Lno;
248 goto Lyes;
249
250 case Tfloat32:
251 {
252 volatile float f;
253 if (type->isunsigned())
254 {
255 f = (float)value;
256 if (f != value)
257 goto Lno;
258 }
259 else
260 {
261 f = (float)(long long)value;
262 if (f != (long long)value)
263 goto Lno;
264 }
265 goto Lyes;
266 }
267
268 case Tfloat64:
269 {
270 volatile double f;
271 if (type->isunsigned())
272 {
273 f = (double)value;
274 if (f != value)
275 goto Lno;
276 }
277 else
278 {
279 f = (double)(long long)value;
280 if (f != (long long)value)
281 goto Lno;
282 }
283 goto Lyes;
284 }
285
286 case Tfloat80:
287 {
288 volatile long double f;
289 if (type->isunsigned())
290 {
291 f = (long double)value;
292 if (f != value)
293 goto Lno;
294 }
295 else
296 {
297 f = (long double)(long long)value;
298 if (f != (long long)value)
299 goto Lno;
300 }
301 goto Lyes;
302 }
303 }
304 return Expression::implicitConvTo(t);
305
306 Lyes:
307 //printf("MATCHconvert\n");
308 return MATCHconvert;
309
310 Lno:
311 //printf("MATCHnomatch\n");
312 return MATCHnomatch;
313 }
314
315 MATCH NullExp::implicitConvTo(Type *t)
316 {
317 #if 0
318 printf("NullExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
319 toChars(), type->toChars(), t->toChars());
320 #endif
321 if (this->type->equals(t))
322 return MATCHexact;
323 // NULL implicitly converts to any pointer type or dynamic array
324 if (type->ty == Tpointer && type->next->ty == Tvoid)
325 {
326 if (t->ty == Ttypedef)
327 t = ((TypeTypedef *)t)->sym->basetype;
328 if (t->ty == Tpointer || t->ty == Tarray ||
329 t->ty == Taarray || t->ty == Tclass ||
330 t->ty == Tdelegate)
331 return committed ? MATCHconvert : MATCHexact;
332 }
333 return Expression::implicitConvTo(t);
334 }
335
336 MATCH StringExp::implicitConvTo(Type *t)
337 { MATCH m;
338
339 #if 0
340 printf("StringExp::implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n",
341 toChars(), committed, type->toChars(), t->toChars());
342 #endif
343 if (!committed)
344 {
345 if (!committed && t->ty == Tpointer && t->next->ty == Tvoid)
346 {
347 return MATCHnomatch;
348 }
349 if (type->ty == Tsarray || type->ty == Tarray || type->ty == Tpointer)
350 {
351 if (type->next->ty == Tchar)
352 {
353 switch (t->ty)
354 {
355 case Tsarray:
356 if (type->ty == Tsarray &&
357 ((TypeSArray *)type)->dim->toInteger() !=
358 ((TypeSArray *)t)->dim->toInteger())
359 return MATCHnomatch;
360 goto L1;
361 case Tarray:
362 goto L1;
363 case Tpointer:
364 L1:
365 if (t->next->ty == Tchar)
366 return MATCHexact;
367 else if (t->next->ty == Twchar)
368 return MATCHexact;
369 else if (t->next->ty == Tdchar)
370 return MATCHexact;
371 break;
372 }
373 }
374 }
375 }
376 return Expression::implicitConvTo(t);
377 #if 0
378 m = (MATCH)type->implicitConvTo(t);
379 if (m)
380 {
381 return m;
382 }
383
384 return MATCHnomatch;
385 #endif
386 }
387
388 MATCH ArrayLiteralExp::implicitConvTo(Type *t)
389 { MATCH result = MATCHexact;
390
391 Type *typeb = type->toBasetype();
392 Type *tb = t->toBasetype();
393 if ((tb->ty == Tarray || tb->ty == Tsarray) &&
394 (typeb->ty == Tarray || typeb->ty == Tsarray))
395 {
396 if (tb->ty == Tsarray)
397 { TypeSArray *tsa = (TypeSArray *)tb;
398 if (elements->dim != tsa->dim->toInteger())
399 result = MATCHnomatch;
400 }
401
402 for (int i = 0; i < elements->dim; i++)
403 { Expression *e = (Expression *)elements->data[i];
404 MATCH m = (MATCH)e->implicitConvTo(tb->next);
405 if (m < result)
406 result = m; // remember worst match
407 if (result == MATCHnomatch)
408 break; // no need to check for worse
409 }
410 return result;
411 }
412 else
413 return Expression::implicitConvTo(t);
414 }
415
416 MATCH AssocArrayLiteralExp::implicitConvTo(Type *t)
417 { MATCH result = MATCHexact;
418
419 Type *typeb = type->toBasetype();
420 Type *tb = t->toBasetype();
421 if (tb->ty == Taarray && typeb->ty == Taarray)
422 {
423 for (size_t i = 0; i < keys->dim; i++)
424 { Expression *e = (Expression *)keys->data[i];
425 MATCH m = (MATCH)e->implicitConvTo(((TypeAArray *)tb)->key);
426 if (m < result)
427 result = m; // remember worst match
428 if (result == MATCHnomatch)
429 break; // no need to check for worse
430 e = (Expression *)values->data[i];
431 m = (MATCH)e->implicitConvTo(tb->next);
432 if (m < result)
433 result = m; // remember worst match
434 if (result == MATCHnomatch)
435 break; // no need to check for worse
436 }
437 return result;
438 }
439 else
440 return Expression::implicitConvTo(t);
441 }
442
443 MATCH AddrExp::implicitConvTo(Type *t)
444 {
445 #if 0
446 printf("AddrExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
447 toChars(), type->toChars(), t->toChars());
448 #endif
449 MATCH result;
450
451 result = type->implicitConvTo(t);
452 //printf("\tresult = %d\n", result);
453
454 if (result == MATCHnomatch)
455 {
456 // Look for pointers to functions where the functions are overloaded.
457 VarExp *ve;
458 FuncDeclaration *f;
459
460 t = t->toBasetype();
461 if (type->ty == Tpointer && type->next->ty == Tfunction &&
462 t->ty == Tpointer && t->next->ty == Tfunction &&
463 e1->op == TOKvar)
464 {
465 ve = (VarExp *)e1;
466 f = ve->var->isFuncDeclaration();
467 if (f && f->overloadExactMatch(t->next))
468 result = MATCHexact;
469 }
470 }
471 //printf("\tresult = %d\n", result);
472 return result;
473 }
474
475 MATCH SymOffExp::implicitConvTo(Type *t)
476 {
477 #if 0
478 printf("SymOffExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
479 toChars(), type->toChars(), t->toChars());
480 #endif
481 MATCH result;
482
483 result = type->implicitConvTo(t);
484 //printf("\tresult = %d\n", result);
485
486 if (result == MATCHnomatch)
487 {
488 // Look for pointers to functions where the functions are overloaded.
489 FuncDeclaration *f;
490
491 t = t->toBasetype();
492 if (type->ty == Tpointer && type->next->ty == Tfunction &&
493 t->ty == Tpointer && t->next->ty == Tfunction)
494 {
495 f = var->isFuncDeclaration();
496 if (f && f->overloadExactMatch(t->next))
497 result = MATCHexact;
498 }
499 }
500 //printf("\tresult = %d\n", result);
501 return result;
502 }
503
504 MATCH DelegateExp::implicitConvTo(Type *t)
505 {
506 #if 0
507 printf("DelegateExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
508 toChars(), type->toChars(), t->toChars());
509 #endif
510 MATCH result;
511
512 result = type->implicitConvTo(t);
513
514 if (result == 0)
515 {
516 // Look for pointers to functions where the functions are overloaded.
517 FuncDeclaration *f;
518
519 t = t->toBasetype();
520 if (type->ty == Tdelegate && type->next->ty == Tfunction &&
521 t->ty == Tdelegate && t->next->ty == Tfunction)
522 {
523 if (func && func->overloadExactMatch(t->next))
524 result = MATCHexact;
525 }
526 }
527 return result;
528 }
529
530 MATCH CondExp::implicitConvTo(Type *t)
531 {
532 MATCH m1;
533 MATCH m2;
534
535 m1 = e1->implicitConvTo(t);
536 m2 = e2->implicitConvTo(t);
537
538 // Pick the worst match
539 return (m1 < m2) ? m1 : m2;
540 }
541
542
543 /* ==================== castTo ====================== */
544
545 /**************************************
546 * Do an explicit cast.
547 */
548
549 Expression *Expression::castTo(Scope *sc, Type *t)
550 { Expression *e;
551 Type *tb;
552
553 //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars());
554 #if 0
555 printf("Expression::castTo(this=%s, type=%s, t=%s)\n",
556 toChars(), type->toChars(), t->toChars());
557 #endif
558 e = this;
559 tb = t->toBasetype();
560 type = type->toBasetype();
561 if (tb != type)
562 {
563 if (tb->ty == Tbit && isBit())
564 ;
565
566 // Do (type *) cast of (type [dim])
567 else if (tb->ty == Tpointer &&
568 type->ty == Tsarray
569 )
570 {
571 //printf("Converting [dim] to *\n");
572
573 if (type->size(loc) == 0)
574 e = new NullExp(loc);
575 else
576 e = new AddrExp(loc, e);
577 }
578 #if 0
579 else if (tb->ty == Tdelegate && type->ty != Tdelegate)
580 {
581 TypeDelegate *td = (TypeDelegate *)tb;
582 TypeFunction *tf = (TypeFunction *)td->next;
583 return toDelegate(sc, tf->next);
584 }
585 #endif
586 else
587 {
588 e = new CastExp(loc, e, tb);
589 }
590 }
591 e->type = t;
592 //printf("Returning: %s\n", e->toChars());
593 return e;
594 }
595
596
597 Expression *RealExp::castTo(Scope *sc, Type *t)
598 {
599 if (type->isreal() && t->isreal())
600 type = t;
601 else if (type->isimaginary() && t->isimaginary())
602 type = t;
603 else
604 return Expression::castTo(sc, t);
605 return this;
606 }
607
608
609 Expression *ComplexExp::castTo(Scope *sc, Type *t)
610 {
611 if (type->iscomplex() && t->iscomplex())
612 type = t;
613 else
614 return Expression::castTo(sc, t);
615 return this;
616 }
617
618
619 Expression *NullExp::castTo(Scope *sc, Type *t)
620 { Expression *e;
621 Type *tb;
622
623 //printf("NullExp::castTo(t = %p)\n", t);
624 committed = 1;
625 e = this;
626 tb = t->toBasetype();
627 type = type->toBasetype();
628 if (tb != type)
629 {
630 // NULL implicitly converts to any pointer type or dynamic array
631 if (type->ty == Tpointer && type->next->ty == Tvoid &&
632 (tb->ty == Tpointer || tb->ty == Tarray || tb->ty == Taarray ||
633 tb->ty == Tdelegate))
634 {
635 #if 0
636 if (tb->ty == Tdelegate)
637 { TypeDelegate *td = (TypeDelegate *)tb;
638 TypeFunction *tf = (TypeFunction *)td->next;
639
640 if (!tf->varargs &&
641 !(tf->arguments && tf->arguments->dim)
642 )
643 {
644 return Expression::castTo(sc, t);
645 }
646 }
647 #endif
648 }
649 else
650 {
651 return Expression::castTo(sc, t);
652 //e = new CastExp(loc, e, tb);
653 }
654 }
655 e->type = t;
656 return e;
657 }
658
659 Expression *StringExp::castTo(Scope *sc, Type *t)
660 {
661 StringExp *se;
662 Type *tb;
663 int unique;
664
665 //printf("StringExp::castTo(t = %s), '%s' committed = %d\n", t->toChars(), toChars(), committed);
666
667 if (!committed && t->ty == Tpointer && t->next->ty == Tvoid)
668 {
669 error("cannot convert string literal to void*");
670 }
671
672 tb = t->toBasetype();
673 //printf("\ttype = %s\n", type->toChars());
674 if (tb->ty == Tdelegate && type->toBasetype()->ty != Tdelegate)
675 return Expression::castTo(sc, t);
676
677 se = this;
678 unique = 0;
679 if (!committed)
680 {
681 // Copy when committing the type
682 void *s;
683
684 s = (unsigned char *)mem.malloc((len + 1) * sz);
685 memcpy(s, string, (len + 1) * sz);
686 se = new StringExp(loc, s, len);
687 se->type = type;
688 se->sz = sz;
689 se->committed = 0;
690 unique = 1; // this is the only instance
691 }
692 se->type = type->toBasetype();
693 if (tb == se->type)
694 { se->type = t;
695 se->committed = 1;
696 return se;
697 }
698
699 if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer)
700 { se->committed = 1;
701 goto Lcast;
702 }
703 if (se->type->ty != Tsarray && se->type->ty != Tarray && se->type->ty != Tpointer)
704 { se->committed = 1;
705 goto Lcast;
706 }
707
708 if (se->committed == 1)
709 {
710 if (se->type->next->size() == tb->next->size())
711 { se->type = t;
712 return se;
713 }
714 goto Lcast;
715 }
716
717 se->committed = 1;
718
719 int tfty;
720 int ttty;
721 char *p;
722 size_t u;
723 unsigned c;
724 size_t newlen;
725
726 #define X(tf,tt) ((tf) * 256 + (tt))
727 {
728 OutBuffer buffer;
729 newlen = 0;
730 tfty = se->type->next->toBasetype()->ty;
731 ttty = tb->next->toBasetype()->ty;
732 switch (X(tfty, ttty))
733 {
734 case X(Tchar, Tchar):
735 case X(Twchar,Twchar):
736 case X(Tdchar,Tdchar):
737 break;
738
739 case X(Tchar, Twchar):
740 for (u = 0; u < len;)
741 {
742 p = utf_decodeChar((unsigned char *)se->string, len, &u, &c);
743 if (p)
744 error("%s", p);
745 else
746 buffer.writeUTF16(c);
747 }
748 newlen = buffer.offset / 2;
749 buffer.writeUTF16(0);
750 goto L1;
751
752 case X(Tchar, Tdchar):
753 for (u = 0; u < len;)
754 {
755 p = utf_decodeChar((unsigned char *)se->string, len, &u, &c);
756 if (p)
757 error("%s", p);
758 buffer.write4(c);
759 newlen++;
760 }
761 buffer.write4(0);
762 goto L1;
763
764 case X(Twchar,Tchar):
765 for (u = 0; u < len;)
766 {
767 p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c);
768 if (p)
769 error("%s", p);
770 else
771 buffer.writeUTF8(c);
772 }
773 newlen = buffer.offset;
774 buffer.writeUTF8(0);
775 goto L1;
776
777 case X(Twchar,Tdchar):
778 for (u = 0; u < len;)
779 {
780 p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c);
781 if (p)
782 error("%s", p);
783 buffer.write4(c);
784 newlen++;
785 }
786 buffer.write4(0);
787 goto L1;
788
789 case X(Tdchar,Tchar):
790 for (u = 0; u < len; u++)
791 {
792 c = ((unsigned *)se->string)[u];
793 if (!utf_isValidDchar(c))
794 error("invalid UCS-32 char \\U%08x", c);
795 else
796 buffer.writeUTF8(c);
797 newlen++;
798 }
799 newlen = buffer.offset;
800 buffer.writeUTF8(0);
801 goto L1;
802
803 case X(Tdchar,Twchar):
804 for (u = 0; u < len; u++)
805 {
806 c = ((unsigned *)se->string)[u];
807 if (!utf_isValidDchar(c))
808 error("invalid UCS-32 char \\U%08x", c);
809 else
810 buffer.writeUTF16(c);
811 newlen++;
812 }
813 newlen = buffer.offset / 2;
814 buffer.writeUTF16(0);
815 goto L1;
816
817 L1:
818 if (!unique)
819 se = new StringExp(loc, NULL, 0);
820 se->string = buffer.extractData();
821 se->len = newlen;
822 se->sz = tb->next->size();
823 break;
824
825 default:
826 if (se->type->next->size() == tb->next->size())
827 { se->type = t;
828 return se;
829 }
830 goto Lcast;
831 }
832 }
833 #undef X
834
835 // See if need to truncate or extend the literal
836 if (tb->ty == Tsarray)
837 {
838 int dim2 = ((TypeSArray *)tb)->dim->toInteger();
839
840 //printf("dim from = %d, to = %d\n", se->len, dim2);
841
842 // Changing dimensions
843 if (dim2 != se->len)
844 {
845 unsigned newsz = se->sz;
846
847 if (unique && dim2 < se->len)
848 { se->len = dim2;
849 // Add terminating 0
850 memset((unsigned char *)se->string + dim2 * newsz, 0, newsz);
851 }
852 else
853 {
854 // Copy when changing the string literal
855 void *s;
856 int d;
857
858 d = (dim2 < se->len) ? dim2 : se->len;
859 s = (unsigned char *)mem.malloc((dim2 + 1) * newsz);
860 memcpy(s, se->string, d * newsz);
861 // Extend with 0, add terminating 0
862 memset((char *)s + d * newsz, 0, (dim2 + 1 - d) * newsz);
863 se = new StringExp(loc, s, dim2);
864 se->committed = 1; // it now has a firm type
865 se->sz = newsz;
866 }
867 }
868 }
869 se->type = t;
870 return se;
871
872 Lcast:
873 Expression *e = new CastExp(loc, se, t);
874 e->type = t;
875 return e;
876 }
877
878 Expression *AddrExp::castTo(Scope *sc, Type *t)
879 {
880 Type *tb;
881
882 #if 0
883 printf("AddrExp::castTo(this=%s, type=%s, t=%s)\n",
884 toChars(), type->toChars(), t->toChars());
885 #endif
886 Expression *e = this;
887
888 tb = t->toBasetype();
889 type = type->toBasetype();
890 if (tb != type)
891 {
892 // Look for pointers to functions where the functions are overloaded.
893 VarExp *ve;
894 FuncDeclaration *f;
895
896 if (type->ty == Tpointer && type->next->ty == Tfunction &&
897 tb->ty == Tpointer && tb->next->ty == Tfunction &&
898 e1->op == TOKvar)
899 {
900 ve = (VarExp *)e1;
901 f = ve->var->isFuncDeclaration();
902 if (f)
903 {
904 f = f->overloadExactMatch(tb->next);
905 if (f)
906 {
907 e = new VarExp(loc, f);
908 e->type = f->type;
909 e = new AddrExp(loc, e);
910 e->type = t;
911 return e;
912 }
913 }
914 }
915 e = Expression::castTo(sc, t);
916 }
917 e->type = t;
918 return e;
919 }
920
921
922 Expression *TupleExp::castTo(Scope *sc, Type *t)
923 {
924 for (size_t i = 0; i < exps->dim; i++)
925 { Expression *e = (Expression *)exps->data[i];
926 e = e->castTo(sc, t);
927 exps->data[i] = (void *)e;
928 }
929 return this;
930 }
931
932
933 Expression *ArrayLiteralExp::castTo(Scope *sc, Type *t)
934 {
935 Type *typeb = type->toBasetype();
936 Type *tb = t->toBasetype();
937 if ((tb->ty == Tarray || tb->ty == Tsarray) &&
938 (typeb->ty == Tarray || typeb->ty == Tsarray) &&
939 tb->next->toBasetype()->ty != Tvoid)
940 {
941 if (tb->ty == Tsarray)
942 { TypeSArray *tsa = (TypeSArray *)tb;
943 if (elements->dim != tsa->dim->toInteger())
944 goto L1;
945 }
946
947 for (int i = 0; i < elements->dim; i++)
948 { Expression *e = (Expression *)elements->data[i];
949 e = e->castTo(sc, tb->next);
950 elements->data[i] = (void *)e;
951 }
952 type = t;
953 return this;
954 }
955 if (tb->ty == Tpointer && typeb->ty == Tsarray)
956 {
957 type = typeb->next->pointerTo();
958 }
959 L1:
960 return Expression::castTo(sc, t);
961 }
962
963 Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t)
964 {
965 Type *typeb = type->toBasetype();
966 Type *tb = t->toBasetype();
967 if (tb->ty == Taarray && typeb->ty == Taarray &&
968 tb->next->toBasetype()->ty != Tvoid)
969 {
970 assert(keys->dim == values->dim);
971 for (size_t i = 0; i < keys->dim; i++)
972 { Expression *e = (Expression *)values->data[i];
973 e = e->castTo(sc, tb->next);
974 values->data[i] = (void *)e;
975
976 e = (Expression *)keys->data[i];
977 e = e->castTo(sc, ((TypeAArray *)tb)->key);
978 keys->data[i] = (void *)e;
979 }
980 type = t;
981 return this;
982 }
983 L1:
984 return Expression::castTo(sc, t);
985 }
986
987 Expression *SymOffExp::castTo(Scope *sc, Type *t)
988 {
989 Type *tb;
990
991 #if 0
992 printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n",
993 toChars(), type->toChars(), t->toChars());
994 #endif
995 Expression *e = this;
996
997 tb = t->toBasetype();
998 type = type->toBasetype();
999 if (tb != type)
1000 {
1001 // Look for pointers to functions where the functions are overloaded.
1002 FuncDeclaration *f;
1003
1004 if (type->ty == Tpointer && type->next->ty == Tfunction &&
1005 tb->ty == Tpointer && tb->next->ty == Tfunction)
1006 {
1007 f = var->isFuncDeclaration();
1008 if (f)
1009 {
1010 f = f->overloadExactMatch(tb->next);
1011 if (f)
1012 {
1013 e = new SymOffExp(loc, f, 0);
1014 e->type = t;
1015 return e;
1016 }
1017 }
1018 }
1019 e = Expression::castTo(sc, t);
1020 }
1021 e->type = t;
1022 return e;
1023 }
1024
1025 Expression *DelegateExp::castTo(Scope *sc, Type *t)
1026 {
1027 Type *tb;
1028 #if 0
1029 printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n",
1030 toChars(), type->toChars(), t->toChars());
1031 #endif
1032 Expression *e = this;
1033 static char msg[] = "cannot form delegate due to covariant return type";
1034
1035 tb = t->toBasetype();
1036 type = type->toBasetype();
1037 if (tb != type)
1038 {
1039 // Look for delegates to functions where the functions are overloaded.
1040 FuncDeclaration *f;
1041
1042 if (type->ty == Tdelegate && type->next->ty == Tfunction &&
1043 tb->ty == Tdelegate && tb->next->ty == Tfunction)
1044 {
1045 if (func)
1046 {
1047 f = func->overloadExactMatch(tb->next);
1048 if (f)
1049 { int offset;
1050 if (f->tintro && f->tintro->next->isBaseOf(f->type->next, &offset) && offset)
1051 error("%s", msg);
1052 e = new DelegateExp(loc, e1, f);
1053 e->type = t;
1054 return e;
1055 }
1056 if (func->tintro)
1057 error("%s", msg);
1058 }
1059 }
1060 e = Expression::castTo(sc, t);
1061 }
1062 else
1063 { int offset;
1064
1065 if (func->tintro && func->tintro->next->isBaseOf(func->type->next, &offset) && offset)
1066 error("%s", msg);
1067 }
1068 e->type = t;
1069 return e;
1070 }
1071
1072 Expression *CondExp::castTo(Scope *sc, Type *t)
1073 {
1074 Expression *e = this;
1075
1076 if (type != t)
1077 {
1078 if (1 || e1->op == TOKstring || e2->op == TOKstring)
1079 { e = new CondExp(loc, econd, e1->castTo(sc, t), e2->castTo(sc, t));
1080 e->type = t;
1081 }
1082 else
1083 e = Expression::castTo(sc, t);
1084 }
1085 return e;
1086 }
1087
1088 /* ==================== ====================== */
1089
1090 /****************************************
1091 * Scale addition/subtraction to/from pointer.
1092 */
1093
1094 Expression *BinExp::scaleFactor(Scope *sc)
1095 { d_uns64 stride;
1096 Type *t1b = e1->type->toBasetype();
1097 Type *t2b = e2->type->toBasetype();
1098
1099 if (t1b->ty == Tpointer && t2b->isintegral())
1100 { // Need to adjust operator by the stride
1101 // Replace (ptr + int) with (ptr + (int * stride))
1102 Type *t = Type::tptrdiff_t;
1103
1104 stride = t1b->next->size();
1105 if (!t->equals(t2b))
1106 e2 = e2->castTo(sc, t);
1107 // LLVMDC: llvm uses typesafe pointer arithmetic
1108 #if !IN_LLVM
1109 if (t1b->next->isbit())
1110 // BUG: should add runtime check for misaligned offsets
1111 // This perhaps should be done by rewriting as &p[i]
1112 // and letting back end do it.
1113 e2 = new UshrExp(loc, e2, new IntegerExp(0, 3, t));
1114 else
1115 e2 = new MulExp(loc, e2, new IntegerExp(0, stride, t));
1116 #endif
1117 e2->type = t;
1118 type = e1->type;
1119 }
1120 else if (t2b->ty && t1b->isintegral())
1121 { // Need to adjust operator by the stride
1122 // Replace (int + ptr) with (ptr + (int * stride))
1123 Type *t = Type::tptrdiff_t;
1124 Expression *e;
1125
1126 stride = t2b->next->size();
1127 if (!t->equals(t1b))
1128 e = e1->castTo(sc, t);
1129 else
1130 e = e1;
1131 if (t2b->next->isbit())
1132 // BUG: should add runtime check for misaligned offsets
1133 e = new UshrExp(loc, e, new IntegerExp(0, 3, t));
1134 else
1135 e = new MulExp(loc, e, new IntegerExp(0, stride, t));
1136 e->type = t;
1137 type = e2->type;
1138 e1 = e2;
1139 e2 = e;
1140 }
1141 return this;
1142 }
1143
1144 /************************************
1145 * Bring leaves to common type.
1146 */
1147
1148 Expression *BinExp::typeCombine(Scope *sc)
1149 {
1150 Type *t1;
1151 Type *t2;
1152 Type *t;
1153 TY ty;
1154
1155 //printf("BinExp::typeCombine()\n");
1156 //dump(0);
1157
1158 e1 = e1->integralPromotions(sc);
1159 e2 = e2->integralPromotions(sc);
1160
1161 // BUG: do toBasetype()
1162 t1 = e1->type;
1163 t2 = e2->type;
1164 assert(t1);
1165
1166 //if (t1) printf("\tt1 = %s\n", t1->toChars());
1167 //if (t2) printf("\tt2 = %s\n", t2->toChars());
1168 #ifdef DEBUG
1169 if (!t2) printf("\te2 = '%s'\n", e2->toChars());
1170 #endif
1171 assert(t2);
1172
1173 Type *t1b = t1->toBasetype();
1174 Type *t2b = t2->toBasetype();
1175
1176 ty = (TY)Type::impcnvResult[t1b->ty][t2b->ty];
1177 if (ty != Terror)
1178 { TY ty1;
1179 TY ty2;
1180
1181 ty1 = (TY)Type::impcnvType1[t1b->ty][t2b->ty];
1182 ty2 = (TY)Type::impcnvType2[t1b->ty][t2b->ty];
1183
1184 if (t1b->ty == ty1) // if no promotions
1185 {
1186 if (t1 == t2)
1187 {
1188 if (!type)
1189 type = t1;
1190 return this;
1191 }
1192
1193 if (t1b == t2b)
1194 {
1195 if (!type)
1196 type = t1b;
1197 return this;
1198 }
1199 }
1200
1201 if (!type)
1202 type = Type::basic[ty];
1203
1204 t1 = Type::basic[ty1];
1205 t2 = Type::basic[ty2];
1206 e1 = e1->castTo(sc, t1);
1207 e2 = e2->castTo(sc, t2);
1208 #if 0
1209 if (type != Type::basic[ty])
1210 { t = type;
1211 type = Type::basic[ty];
1212 return castTo(sc, t);
1213 }
1214 #endif
1215 //printf("after typeCombine():\n");
1216 //dump(0);
1217 //printf("ty = %d, ty1 = %d, ty2 = %d\n", ty, ty1, ty2);
1218 return this;
1219 }
1220
1221 t = t1;
1222 if (t1 == t2)
1223 {
1224 if ((t1->ty == Tstruct || t1->ty == Tclass) &&
1225 (op == TOKmin || op == TOKadd))
1226 goto Lincompatible;
1227 }
1228 else if (t1->isintegral() && t2->isintegral())
1229 {
1230 printf("t1 = %s, t2 = %s\n", t1->toChars(), t2->toChars());
1231 int sz1 = t1->size();
1232 int sz2 = t2->size();
1233 int sign1 = t1->isunsigned() == 0;
1234 int sign2 = t2->isunsigned() == 0;
1235
1236 if (sign1 == sign2)
1237 {
1238 if (sz1 < sz2)
1239 goto Lt2;
1240 else
1241 goto Lt1;
1242 }
1243 if (!sign1)
1244 {
1245 if (sz1 >= sz2)
1246 goto Lt1;
1247 else
1248 goto Lt2;
1249 }
1250 else
1251 {
1252 if (sz2 >= sz1)
1253 goto Lt2;
1254 else
1255 goto Lt1;
1256 }
1257 }
1258 else if (t1->ty == Tpointer && t2->ty == Tpointer)
1259 {
1260 // Bring pointers to compatible type
1261 Type *t1n = t1->next;
1262 Type *t2n = t2->next;
1263
1264 //t1->print();
1265 //t2->print();
1266 //if (t1n == t2n) *(char *)0 = 0;
1267 assert(t1n != t2n);
1268 if (t1n->ty == Tvoid) // pointers to void are always compatible
1269 t = t2;
1270 else if (t2n->ty == Tvoid)
1271 ;
1272 else if (t1n->ty == Tclass && t2n->ty == Tclass)
1273 { ClassDeclaration *cd1 = t1n->isClassHandle();
1274 ClassDeclaration *cd2 = t2n->isClassHandle();
1275 int offset;
1276
1277 if (cd1->isBaseOf(cd2, &offset))
1278 {
1279 if (offset)
1280 e2 = e2->castTo(sc, t);
1281 }
1282 else if (cd2->isBaseOf(cd1, &offset))
1283 {
1284 t = t2;
1285 if (offset)
1286 e1 = e1->castTo(sc, t);
1287 }
1288 else
1289 goto Lincompatible;
1290 }
1291 else
1292 goto Lincompatible;
1293 }
1294 else if ((t1->ty == Tsarray || t1->ty == Tarray) &&
1295 e2->op == TOKnull && t2->ty == Tpointer && t2->next->ty == Tvoid)
1296 {
1297 goto Lx1;
1298 }
1299 else if ((t2->ty == Tsarray || t2->ty == Tarray) &&
1300 e1->op == TOKnull && t1->ty == Tpointer && t1->next->ty == Tvoid)
1301 {
1302 goto Lx2;
1303 }
1304 else if ((t1->ty == Tsarray || t1->ty == Tarray) && t1->implicitConvTo(t2))
1305 {
1306 goto Lt2;
1307 }
1308 else if ((t2->ty == Tsarray || t2->ty == Tarray) && t2->implicitConvTo(t1))
1309 {
1310 goto Lt1;
1311 }
1312 else if (t1->ty == Tclass || t2->ty == Tclass)
1313 { int i1;
1314 int i2;
1315
1316 i1 = e2->implicitConvTo(t1);
1317 i2 = e1->implicitConvTo(t2);
1318
1319 if (i1 && i2)
1320 {
1321 // We have the case of class vs. void*, so pick class
1322 if (t1->ty == Tpointer)
1323 i1 = 0;
1324 else if (t2->ty == Tpointer)
1325 i2 = 0;
1326 }
1327
1328 if (i2)
1329 {
1330 goto Lt2;
1331 }
1332 else if (i1)
1333 {
1334 goto Lt1;
1335 }
1336 else
1337 goto Lincompatible;
1338 }
1339 else if ((e1->op == TOKstring || e1->op == TOKnull) && e1->implicitConvTo(t2))
1340 {
1341 goto Lt2;
1342 }
1343 //else if (e2->op == TOKstring) { printf("test2\n"); }
1344 else if ((e2->op == TOKstring || e2->op == TOKnull) && e2->implicitConvTo(t1))
1345 {
1346 goto Lt1;
1347 }
1348 else if (t1->ty == Tsarray && t2->ty == Tsarray &&
1349 e2->implicitConvTo(t1->next->arrayOf()))
1350 {
1351 Lx1:
1352 t = t1->next->arrayOf();
1353 e1 = e1->castTo(sc, t);
1354 e2 = e2->castTo(sc, t);
1355 }
1356 else if (t1->ty == Tsarray && t2->ty == Tsarray &&
1357 e1->implicitConvTo(t2->next->arrayOf()))
1358 {
1359 Lx2:
1360 t = t2->next->arrayOf();
1361 e1 = e1->castTo(sc, t);
1362 e2 = e2->castTo(sc, t);
1363 }
1364 else
1365 {
1366 Lincompatible:
1367 incompatibleTypes();
1368 }
1369 Lret:
1370 if (!type)
1371 type = t;
1372 //dump(0);
1373 return this;
1374
1375
1376 Lt1:
1377 e2 = e2->castTo(sc, t1);
1378 t = t1;
1379 goto Lret;
1380
1381 Lt2:
1382 e1 = e1->castTo(sc, t2);
1383 t = t2;
1384 goto Lret;
1385 }
1386
1387 /***********************************
1388 * Do integral promotions (convertchk).
1389 * Don't convert <array of> to <pointer to>
1390 */
1391
1392 Expression *Expression::integralPromotions(Scope *sc)
1393 { Expression *e;
1394
1395 e = this;
1396 switch (type->toBasetype()->ty)
1397 {
1398 case Tvoid:
1399 error("void has no value");
1400 break;
1401
1402 case Tint8:
1403 case Tuns8:
1404 case Tint16:
1405 case Tuns16:
1406 case Tbit:
1407 case Tbool:
1408 case Tchar:
1409 case Twchar:
1410 e = e->castTo(sc, Type::tint32);
1411 break;
1412
1413 case Tdchar:
1414 e = e->castTo(sc, Type::tuns32);
1415 break;
1416 }
1417 return e;
1418 }
1419