comparison dmd2/cast.c @ 758:f04dde6e882c

Added initial D2 support, D2 frontend and changes to codegen to make things compile.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 11 Nov 2008 01:38:48 +0100
parents
children 356e65836fb5
comparison
equal deleted inserted replaced
757:2c730d530c98 758:f04dde6e882c
1
2 // Copyright (c) 1999-2008 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("Expression::implicitCastTo(%s of type %s) => %s\n", toChars(), type->toChars(), t->toChars());
35
36 MATCH match = implicitConvTo(t);
37 if (match)
38 {
39 if (global.params.warnings &&
40 Type::impcnvWarn[type->toBasetype()->ty][t->toBasetype()->ty] &&
41 op != TOKint64)
42 {
43 Expression *e = optimize(WANTflags | WANTvalue);
44
45 if (e->op == TOKint64)
46 return e->implicitCastTo(sc, t);
47
48 warning("%s: implicit conversion of expression (%s) of type %s to %s can cause loss of data",
49 loc.toChars(), toChars(), type->toChars(), t->toChars());
50 }
51 #if DMDV2
52 if (match == MATCHconst && t == type->constOf())
53 {
54 Expression *e = copy();
55 e->type = t;
56 return e;
57 }
58 #endif
59 return castTo(sc, t);
60 }
61
62 Expression *e = optimize(WANTflags | WANTvalue);
63 if (e != this)
64 return e->implicitCastTo(sc, t);
65
66 #if 0
67 printf("ty = %d\n", type->ty);
68 print();
69 type->print();
70 printf("to:\n");
71 t->print();
72 printf("%p %p type: %s to: %s\n", type->deco, t->deco, type->deco, t->deco);
73 //printf("%p %p %p\n", type->nextOf()->arrayOf(), type, t);
74 fflush(stdout);
75 #endif
76 if (!t->deco)
77 { /* Can happen with:
78 * enum E { One }
79 * class A
80 * { static void fork(EDG dg) { dg(E.One); }
81 * alias void delegate(E) EDG;
82 * }
83 * Should eventually make it work.
84 */
85 error("forward reference to type %s", t->toChars());
86 }
87 else if (t->reliesOnTident())
88 error("forward reference to type %s", t->reliesOnTident()->toChars());
89
90 error("cannot implicitly convert expression (%s) of type %s to %s",
91 toChars(), type->toChars(), t->toChars());
92 return castTo(sc, t);
93 }
94
95 /*******************************************
96 * Return !=0 if we can implicitly convert this to type t.
97 * Don't do the actual cast.
98 */
99
100 MATCH Expression::implicitConvTo(Type *t)
101 {
102 #if 0
103 printf("Expression::implicitConvTo(this=%s, type=%s, t=%s)\n",
104 toChars(), type->toChars(), t->toChars());
105 #endif
106 //static int nest; if (++nest == 10) halt();
107 if (!type)
108 { error("%s is not an expression", toChars());
109 type = Type::terror;
110 }
111 Expression *e = optimize(WANTvalue | WANTflags);
112 if (e->type == t)
113 return MATCHexact;
114 if (e != this)
115 { //printf("\toptimized to %s of type %s\n", e->toChars(), e->type->toChars());
116 return e->implicitConvTo(t);
117 }
118 MATCH match = type->implicitConvTo(t);
119 if (match != MATCHnomatch)
120 return match;
121 #if 0
122 Type *tb = t->toBasetype();
123 if (tb->ty == Tdelegate)
124 { TypeDelegate *td = (TypeDelegate *)tb;
125 TypeFunction *tf = (TypeFunction *)td->nextOf();
126
127 if (!tf->varargs &&
128 !(tf->arguments && tf->arguments->dim)
129 )
130 {
131 match = type->implicitConvTo(tf->nextOf());
132 if (match)
133 return match;
134 if (tf->nextOf()->toBasetype()->ty == Tvoid)
135 return MATCHconvert;
136 }
137 }
138 #endif
139 return MATCHnomatch;
140 }
141
142
143 MATCH IntegerExp::implicitConvTo(Type *t)
144 {
145 #if 0
146 printf("IntegerExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
147 toChars(), type->toChars(), t->toChars());
148 #endif
149 MATCH m = type->implicitConvTo(t);
150 if (m >= MATCHconst)
151 return m;
152
153 TY ty = type->toBasetype()->ty;
154 TY toty = t->toBasetype()->ty;
155
156 if (m == MATCHnomatch && t->ty == Tenum)
157 goto Lno;
158
159 switch (ty)
160 {
161 case Tbit:
162 case Tbool:
163 value &= 1;
164 ty = Tint32;
165 break;
166
167 case Tint8:
168 value = (signed char)value;
169 ty = Tint32;
170 break;
171
172 case Tchar:
173 case Tuns8:
174 value &= 0xFF;
175 ty = Tint32;
176 break;
177
178 case Tint16:
179 value = (short)value;
180 ty = Tint32;
181 break;
182
183 case Tuns16:
184 case Twchar:
185 value &= 0xFFFF;
186 ty = Tint32;
187 break;
188
189 case Tint32:
190 value = (int)value;
191 break;
192
193 case Tuns32:
194 case Tdchar:
195 value &= 0xFFFFFFFF;
196 ty = Tuns32;
197 break;
198
199 default:
200 break;
201 }
202
203 // Only allow conversion if no change in value
204 switch (toty)
205 {
206 case Tbit:
207 case Tbool:
208 if ((value & 1) != value)
209 goto Lno;
210 goto Lyes;
211
212 case Tint8:
213 if ((signed char)value != value)
214 goto Lno;
215 goto Lyes;
216
217 case Tchar:
218 case Tuns8:
219 //printf("value = %llu %llu\n", (integer_t)(unsigned char)value, value);
220 if ((unsigned char)value != value)
221 goto Lno;
222 goto Lyes;
223
224 case Tint16:
225 if ((short)value != value)
226 goto Lno;
227 goto Lyes;
228
229 case Tuns16:
230 if ((unsigned short)value != value)
231 goto Lno;
232 goto Lyes;
233
234 case Tint32:
235 if (ty == Tuns32)
236 {
237 }
238 else if ((int)value != value)
239 goto Lno;
240 goto Lyes;
241
242 case Tuns32:
243 if (ty == Tint32)
244 {
245 }
246 else if ((unsigned)value != value)
247 goto Lno;
248 goto Lyes;
249
250 case Tdchar:
251 if (value > 0x10FFFFUL)
252 goto Lno;
253 goto Lyes;
254
255 case Twchar:
256 if ((unsigned short)value != value)
257 goto Lno;
258 goto Lyes;
259
260 case Tfloat32:
261 {
262 volatile float f;
263 if (type->isunsigned())
264 {
265 f = (float)value;
266 if (f != value)
267 goto Lno;
268 }
269 else
270 {
271 f = (float)(long long)value;
272 if (f != (long long)value)
273 goto Lno;
274 }
275 goto Lyes;
276 }
277
278 case Tfloat64:
279 {
280 volatile double f;
281 if (type->isunsigned())
282 {
283 f = (double)value;
284 if (f != value)
285 goto Lno;
286 }
287 else
288 {
289 f = (double)(long long)value;
290 if (f != (long long)value)
291 goto Lno;
292 }
293 goto Lyes;
294 }
295
296 case Tfloat80:
297 {
298 volatile long double f;
299 if (type->isunsigned())
300 {
301 f = (long double)value;
302 if (f != value)
303 goto Lno;
304 }
305 else
306 {
307 f = (long double)(long long)value;
308 if (f != (long long)value)
309 goto Lno;
310 }
311 goto Lyes;
312 }
313
314 case Tpointer:
315 //printf("type = %s\n", type->toBasetype()->toChars());
316 //printf("t = %s\n", t->toBasetype()->toChars());
317 if (ty == Tpointer &&
318 type->toBasetype()->nextOf()->ty == t->toBasetype()->nextOf()->ty)
319 { /* Allow things like:
320 * const char* P = cast(char *)3;
321 * char* q = P;
322 */
323 goto Lyes;
324 }
325 break;
326 }
327 return Expression::implicitConvTo(t);
328
329 Lyes:
330 //printf("MATCHconvert\n");
331 return MATCHconvert;
332
333 Lno:
334 //printf("MATCHnomatch\n");
335 return MATCHnomatch;
336 }
337
338 MATCH NullExp::implicitConvTo(Type *t)
339 {
340 #if 0
341 printf("NullExp::implicitConvTo(this=%s, type=%s, t=%s, committed = %d)\n",
342 toChars(), type->toChars(), t->toChars(), committed);
343 #endif
344 if (this->type->equals(t))
345 return MATCHexact;
346
347 /* Allow implicit conversions from invariant to mutable|const,
348 * and mutable to invariant. It works because, after all, a null
349 * doesn't actually point to anything.
350 */
351 if (t->invariantOf()->equals(type->invariantOf()))
352 return MATCHconst;
353
354 // NULL implicitly converts to any pointer type or dynamic array
355 if (type->ty == Tpointer && type->nextOf()->ty == Tvoid)
356 {
357 if (t->ty == Ttypedef)
358 t = ((TypeTypedef *)t)->sym->basetype;
359 if (t->ty == Tpointer || t->ty == Tarray ||
360 t->ty == Taarray || t->ty == Tclass ||
361 t->ty == Tdelegate)
362 return committed ? MATCHconvert : MATCHexact;
363 }
364 return Expression::implicitConvTo(t);
365 }
366
367 #if DMDV2
368 MATCH StructLiteralExp::implicitConvTo(Type *t)
369 {
370 #if 0
371 printf("StructLiteralExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
372 toChars(), type->toChars(), t->toChars());
373 #endif
374 MATCH m = Expression::implicitConvTo(t);
375 if (m != MATCHnomatch)
376 return m;
377 if (type->ty == t->ty && type->ty == Tstruct &&
378 ((TypeStruct *)type)->sym == ((TypeStruct *)t)->sym)
379 {
380 m = MATCHconst;
381 for (int i = 0; i < elements->dim; i++)
382 { Expression *e = (Expression *)elements->data[i];
383 Type *te = e->type;
384 if (t->mod == 0)
385 te = te->mutableOf();
386 else
387 { assert(t->mod == MODinvariant);
388 te = te->invariantOf();
389 }
390 MATCH m2 = e->implicitConvTo(te);
391 //printf("\t%s => %s, match = %d\n", e->toChars(), te->toChars(), m2);
392 if (m2 < m)
393 m = m2;
394 }
395 }
396 return m;
397 }
398 #endif
399
400 MATCH StringExp::implicitConvTo(Type *t)
401 { MATCH m;
402
403 #if 0
404 printf("StringExp::implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n",
405 toChars(), committed, type->toChars(), t->toChars());
406 #endif
407 if (!committed)
408 {
409 if (!committed && t->ty == Tpointer && t->nextOf()->ty == Tvoid)
410 {
411 return MATCHnomatch;
412 }
413 if (type->ty == Tsarray || type->ty == Tarray || type->ty == Tpointer)
414 {
415 TY tyn = type->nextOf()->ty;
416 if (tyn == Tchar || tyn == Twchar || tyn == Tdchar)
417 { Type *tn;
418 MATCH m;
419
420 switch (t->ty)
421 {
422 case Tsarray:
423 if (type->ty == Tsarray)
424 {
425 if (((TypeSArray *)type)->dim->toInteger() !=
426 ((TypeSArray *)t)->dim->toInteger())
427 return MATCHnomatch;
428 TY tynto = t->nextOf()->ty;
429 if (tynto == Tchar || tynto == Twchar || tynto == Tdchar)
430 return MATCHexact;
431 }
432 case Tarray:
433 case Tpointer:
434 tn = t->nextOf();
435 m = MATCHexact;
436 if (type->nextOf()->mod != tn->mod)
437 { if (!tn->isConst())
438 return MATCHnomatch;
439 m = MATCHconst;
440 }
441 switch (tn->ty)
442 {
443 case Tchar:
444 case Twchar:
445 case Tdchar:
446 return m;
447 }
448 break;
449 }
450 }
451 }
452 }
453 return Expression::implicitConvTo(t);
454 #if 0
455 m = (MATCH)type->implicitConvTo(t);
456 if (m)
457 {
458 return m;
459 }
460
461 return MATCHnomatch;
462 #endif
463 }
464
465 MATCH ArrayLiteralExp::implicitConvTo(Type *t)
466 { MATCH result = MATCHexact;
467
468 #if 0
469 printf("ArrayLiteralExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
470 toChars(), type->toChars(), t->toChars());
471 #endif
472 Type *typeb = type->toBasetype();
473 Type *tb = t->toBasetype();
474 if ((tb->ty == Tarray || tb->ty == Tsarray) &&
475 (typeb->ty == Tarray || typeb->ty == Tsarray))
476 {
477 if (tb->ty == Tsarray)
478 { TypeSArray *tsa = (TypeSArray *)tb;
479 if (elements->dim != tsa->dim->toInteger())
480 result = MATCHnomatch;
481 }
482
483 for (int i = 0; i < elements->dim; i++)
484 { Expression *e = (Expression *)elements->data[i];
485 MATCH m = (MATCH)e->implicitConvTo(tb->nextOf());
486 if (m < result)
487 result = m; // remember worst match
488 if (result == MATCHnomatch)
489 break; // no need to check for worse
490 }
491 return result;
492 }
493 else
494 return Expression::implicitConvTo(t);
495 }
496
497 MATCH AssocArrayLiteralExp::implicitConvTo(Type *t)
498 { MATCH result = MATCHexact;
499
500 Type *typeb = type->toBasetype();
501 Type *tb = t->toBasetype();
502 if (tb->ty == Taarray && typeb->ty == Taarray)
503 {
504 for (size_t i = 0; i < keys->dim; i++)
505 { Expression *e = (Expression *)keys->data[i];
506 MATCH m = (MATCH)e->implicitConvTo(((TypeAArray *)tb)->index);
507 if (m < result)
508 result = m; // remember worst match
509 if (result == MATCHnomatch)
510 break; // no need to check for worse
511 e = (Expression *)values->data[i];
512 m = (MATCH)e->implicitConvTo(tb->nextOf());
513 if (m < result)
514 result = m; // remember worst match
515 if (result == MATCHnomatch)
516 break; // no need to check for worse
517 }
518 return result;
519 }
520 else
521 return Expression::implicitConvTo(t);
522 }
523
524 MATCH AddrExp::implicitConvTo(Type *t)
525 {
526 #if 0
527 printf("AddrExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
528 toChars(), type->toChars(), t->toChars());
529 #endif
530 MATCH result;
531
532 result = type->implicitConvTo(t);
533 //printf("\tresult = %d\n", result);
534
535 if (result == MATCHnomatch)
536 {
537 // Look for pointers to functions where the functions are overloaded.
538
539 t = t->toBasetype();
540
541 if (e1->op == TOKoverloadset &&
542 (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction)
543 { OverExp *eo = (OverExp *)e1;
544 FuncDeclaration *f = NULL;
545 for (int i = 0; i < eo->vars->a.dim; i++)
546 { Dsymbol *s = (Dsymbol *)eo->vars->a.data[i];
547 FuncDeclaration *f2 = s->isFuncDeclaration();
548 assert(f2);
549 if (f2->overloadExactMatch(t->nextOf()))
550 { if (f)
551 /* Error if match in more than one overload set,
552 * even if one is a 'better' match than the other.
553 */
554 ScopeDsymbol::multiplyDefined(loc, f, f2);
555 else
556 f = f2;
557 result = MATCHexact;
558 }
559 }
560 }
561
562 if (type->ty == Tpointer && type->nextOf()->ty == Tfunction &&
563 t->ty == Tpointer && t->nextOf()->ty == Tfunction &&
564 e1->op == TOKvar)
565 {
566 // LDC: it happens for us
567 #if !IN_LLVM
568 /* I don't think this can ever happen -
569 * it should have been
570 * converted to a SymOffExp.
571 */
572 assert(0);
573 #endif
574 VarExp *ve = (VarExp *)e1;
575 FuncDeclaration *f = ve->var->isFuncDeclaration();
576 if (f && f->overloadExactMatch(t->nextOf()))
577 result = MATCHexact;
578 }
579 }
580 //printf("\tresult = %d\n", result);
581 return result;
582 }
583
584 MATCH SymOffExp::implicitConvTo(Type *t)
585 {
586 #if 0
587 printf("SymOffExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
588 toChars(), type->toChars(), t->toChars());
589 #endif
590 MATCH result;
591
592 result = type->implicitConvTo(t);
593 //printf("\tresult = %d\n", result);
594
595 if (result == MATCHnomatch)
596 {
597 // Look for pointers to functions where the functions are overloaded.
598 FuncDeclaration *f;
599
600 t = t->toBasetype();
601 if (type->ty == Tpointer && type->nextOf()->ty == Tfunction &&
602 (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction)
603 {
604 f = var->isFuncDeclaration();
605 if (f)
606 { f = f->overloadExactMatch(t->nextOf());
607 if (f)
608 { if ((t->ty == Tdelegate && (f->needThis() || f->isNested())) ||
609 (t->ty == Tpointer && !(f->needThis() || f->isNested())))
610 {
611 result = MATCHexact;
612 }
613 }
614 }
615 }
616 }
617 //printf("\tresult = %d\n", result);
618 return result;
619 }
620
621 MATCH DelegateExp::implicitConvTo(Type *t)
622 {
623 #if 0
624 printf("DelegateExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
625 toChars(), type->toChars(), t->toChars());
626 #endif
627 MATCH result;
628
629 result = type->implicitConvTo(t);
630
631 if (result == MATCHnomatch)
632 {
633 // Look for pointers to functions where the functions are overloaded.
634 FuncDeclaration *f;
635
636 t = t->toBasetype();
637 if (type->ty == Tdelegate && type->nextOf()->ty == Tfunction &&
638 t->ty == Tdelegate && t->nextOf()->ty == Tfunction)
639 {
640 if (func && func->overloadExactMatch(t->nextOf()))
641 result = MATCHexact;
642 }
643 }
644 return result;
645 }
646
647 MATCH CondExp::implicitConvTo(Type *t)
648 {
649 MATCH m1;
650 MATCH m2;
651
652 m1 = e1->implicitConvTo(t);
653 m2 = e2->implicitConvTo(t);
654
655 // Pick the worst match
656 return (m1 < m2) ? m1 : m2;
657 }
658
659
660 /* ==================== castTo ====================== */
661
662 /**************************************
663 * Do an explicit cast.
664 */
665
666 Expression *Expression::castTo(Scope *sc, Type *t)
667 {
668 //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars());
669 #if 0
670 printf("Expression::castTo(this=%s, type=%s, t=%s)\n",
671 toChars(), type->toChars(), t->toChars());
672 #endif
673 if (type == t)
674 return this;
675 Expression *e = this;
676 Type *tb = t->toBasetype();
677 Type *typeb = type->toBasetype();
678 if (tb != typeb)
679 {
680 // Do (type *) cast of (type [dim])
681 if (tb->ty == Tpointer &&
682 typeb->ty == Tsarray
683 )
684 {
685 //printf("Converting [dim] to *\n");
686
687 if (typeb->size(loc) == 0)
688 e = new NullExp(loc);
689 else
690 e = new AddrExp(loc, e);
691 }
692 #if 0
693 else if (tb->ty == Tdelegate && type->ty != Tdelegate)
694 {
695 TypeDelegate *td = (TypeDelegate *)tb;
696 TypeFunction *tf = (TypeFunction *)td->nextOf();
697 return toDelegate(sc, tf->nextOf());
698 }
699 #endif
700 else
701 {
702 e = new CastExp(loc, e, tb);
703 }
704 }
705 else
706 {
707 e = e->copy(); // because of COW for assignment to e->type
708 }
709 assert(e != this);
710 e->type = t;
711 //printf("Returning: %s\n", e->toChars());
712 return e;
713 }
714
715
716 Expression *RealExp::castTo(Scope *sc, Type *t)
717 { Expression *e = this;
718 if (type != t)
719 {
720 if ((type->isreal() && t->isreal()) ||
721 (type->isimaginary() && t->isimaginary())
722 )
723 { e = copy();
724 e->type = t;
725 }
726 else
727 e = Expression::castTo(sc, t);
728 }
729 return e;
730 }
731
732
733 Expression *ComplexExp::castTo(Scope *sc, Type *t)
734 { Expression *e = this;
735 if (type != t)
736 {
737 if (type->iscomplex() && t->iscomplex())
738 { e = copy();
739 e->type = t;
740 }
741 else
742 e = Expression::castTo(sc, t);
743 }
744 return e;
745 }
746
747
748 Expression *NullExp::castTo(Scope *sc, Type *t)
749 { NullExp *e;
750 Type *tb;
751
752 //printf("NullExp::castTo(t = %p)\n", t);
753 if (type == t)
754 {
755 committed = 1;
756 return this;
757 }
758 e = (NullExp *)copy();
759 e->committed = 1;
760 tb = t->toBasetype();
761 e->type = type->toBasetype();
762 if (tb != e->type)
763 {
764 // NULL implicitly converts to any pointer type or dynamic array
765 if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tvoid &&
766 (tb->ty == Tpointer || tb->ty == Tarray || tb->ty == Taarray ||
767 tb->ty == Tdelegate))
768 {
769 #if 0
770 if (tb->ty == Tdelegate)
771 { TypeDelegate *td = (TypeDelegate *)tb;
772 TypeFunction *tf = (TypeFunction *)td->nextOf();
773
774 if (!tf->varargs &&
775 !(tf->arguments && tf->arguments->dim)
776 )
777 {
778 return Expression::castTo(sc, t);
779 }
780 }
781 #endif
782 }
783 else
784 {
785 return e->Expression::castTo(sc, t);
786 }
787 }
788 e->type = t;
789 return e;
790 }
791
792 Expression *StringExp::castTo(Scope *sc, Type *t)
793 {
794 /* This follows copy-on-write; any changes to 'this'
795 * will result in a copy.
796 * The this->string member is considered immutable.
797 */
798 StringExp *se;
799 Type *tb;
800 int copied = 0;
801
802 //printf("StringExp::castTo(t = %s), '%s' committed = %d\n", t->toChars(), toChars(), committed);
803
804 if (!committed && t->ty == Tpointer && t->nextOf()->ty == Tvoid)
805 {
806 error("cannot convert string literal to void*");
807 }
808
809 se = this;
810 if (!committed)
811 { se = (StringExp *)copy();
812 se->committed = 1;
813 copied = 1;
814 }
815
816 if (type == t)
817 {
818 return se;
819 }
820
821 tb = t->toBasetype();
822 //printf("\ttype = %s\n", type->toChars());
823 if (tb->ty == Tdelegate && type->toBasetype()->ty != Tdelegate)
824 return Expression::castTo(sc, t);
825
826 Type *typeb = type->toBasetype();
827 if (typeb == tb)
828 {
829 if (!copied)
830 { se = (StringExp *)copy();
831 copied = 1;
832 }
833 se->type = t;
834 return se;
835 }
836
837 if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer)
838 { if (!copied)
839 { se = (StringExp *)copy();
840 copied = 1;
841 }
842 goto Lcast;
843 }
844 if (typeb->ty != Tsarray && typeb->ty != Tarray && typeb->ty != Tpointer)
845 { if (!copied)
846 { se = (StringExp *)copy();
847 copied = 1;
848 }
849 goto Lcast;
850 }
851
852 if (typeb->nextOf()->size() == tb->nextOf()->size())
853 {
854 if (!copied)
855 { se = (StringExp *)copy();
856 copied = 1;
857 }
858 if (tb->ty == Tsarray)
859 goto L2; // handle possible change in static array dimension
860 se->type = t;
861 return se;
862 }
863
864 if (committed)
865 goto Lcast;
866
867 #define X(tf,tt) ((tf) * 256 + (tt))
868 {
869 OutBuffer buffer;
870 size_t newlen = 0;
871 int tfty = typeb->nextOf()->toBasetype()->ty;
872 int ttty = tb->nextOf()->toBasetype()->ty;
873 switch (X(tfty, ttty))
874 {
875 case X(Tchar, Tchar):
876 case X(Twchar,Twchar):
877 case X(Tdchar,Tdchar):
878 break;
879
880 case X(Tchar, Twchar):
881 for (size_t u = 0; u < len;)
882 { unsigned c;
883 const char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c);
884 if (p)
885 error("%s", p);
886 else
887 buffer.writeUTF16(c);
888 }
889 newlen = buffer.offset / 2;
890 buffer.writeUTF16(0);
891 goto L1;
892
893 case X(Tchar, Tdchar):
894 for (size_t u = 0; u < len;)
895 { unsigned c;
896 const char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c);
897 if (p)
898 error("%s", p);
899 buffer.write4(c);
900 newlen++;
901 }
902 buffer.write4(0);
903 goto L1;
904
905 case X(Twchar,Tchar):
906 for (size_t u = 0; u < len;)
907 { unsigned c;
908 const char *p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c);
909 if (p)
910 error("%s", p);
911 else
912 buffer.writeUTF8(c);
913 }
914 newlen = buffer.offset;
915 buffer.writeUTF8(0);
916 goto L1;
917
918 case X(Twchar,Tdchar):
919 for (size_t u = 0; u < len;)
920 { unsigned c;
921 const char *p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c);
922 if (p)
923 error("%s", p);
924 buffer.write4(c);
925 newlen++;
926 }
927 buffer.write4(0);
928 goto L1;
929
930 case X(Tdchar,Tchar):
931 for (size_t u = 0; u < len; u++)
932 {
933 unsigned c = ((unsigned *)se->string)[u];
934 if (!utf_isValidDchar(c))
935 error("invalid UCS-32 char \\U%08x", c);
936 else
937 buffer.writeUTF8(c);
938 newlen++;
939 }
940 newlen = buffer.offset;
941 buffer.writeUTF8(0);
942 goto L1;
943
944 case X(Tdchar,Twchar):
945 for (size_t u = 0; u < len; u++)
946 {
947 unsigned c = ((unsigned *)se->string)[u];
948 if (!utf_isValidDchar(c))
949 error("invalid UCS-32 char \\U%08x", c);
950 else
951 buffer.writeUTF16(c);
952 newlen++;
953 }
954 newlen = buffer.offset / 2;
955 buffer.writeUTF16(0);
956 goto L1;
957
958 L1:
959 if (!copied)
960 { se = (StringExp *)copy();
961 copied = 1;
962 }
963 se->string = buffer.extractData();
964 se->len = newlen;
965 se->sz = tb->nextOf()->size();
966 break;
967
968 default:
969 assert(typeb->nextOf()->size() != tb->nextOf()->size());
970 goto Lcast;
971 }
972 }
973 #undef X
974 L2:
975 assert(copied);
976
977 // See if need to truncate or extend the literal
978 if (tb->ty == Tsarray)
979 {
980 int dim2 = ((TypeSArray *)tb)->dim->toInteger();
981
982 //printf("dim from = %d, to = %d\n", se->len, dim2);
983
984 // Changing dimensions
985 if (dim2 != se->len)
986 {
987 // Copy when changing the string literal
988 unsigned newsz = se->sz;
989 void *s;
990 int d;
991
992 d = (dim2 < se->len) ? dim2 : se->len;
993 s = (unsigned char *)mem.malloc((dim2 + 1) * newsz);
994 memcpy(s, se->string, d * newsz);
995 // Extend with 0, add terminating 0
996 memset((char *)s + d * newsz, 0, (dim2 + 1 - d) * newsz);
997 se->string = s;
998 se->len = dim2;
999 }
1000 }
1001 se->type = t;
1002 return se;
1003
1004 Lcast:
1005 Expression *e = new CastExp(loc, se, t);
1006 e->type = t; // so semantic() won't be run on e
1007 return e;
1008 }
1009
1010 Expression *AddrExp::castTo(Scope *sc, Type *t)
1011 {
1012 Type *tb;
1013
1014 #if 0
1015 printf("AddrExp::castTo(this=%s, type=%s, t=%s)\n",
1016 toChars(), type->toChars(), t->toChars());
1017 #endif
1018 Expression *e = this;
1019
1020 tb = t->toBasetype();
1021 type = type->toBasetype();
1022 if (tb != type)
1023 {
1024 // Look for pointers to functions where the functions are overloaded.
1025
1026 if (e1->op == TOKoverloadset &&
1027 (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction)
1028 { OverExp *eo = (OverExp *)e1;
1029 FuncDeclaration *f = NULL;
1030 for (int i = 0; i < eo->vars->a.dim; i++)
1031 { Dsymbol *s = (Dsymbol *)eo->vars->a.data[i];
1032 FuncDeclaration *f2 = s->isFuncDeclaration();
1033 assert(f2);
1034 if (f2->overloadExactMatch(t->nextOf()))
1035 { if (f)
1036 /* Error if match in more than one overload set,
1037 * even if one is a 'better' match than the other.
1038 */
1039 ScopeDsymbol::multiplyDefined(loc, f, f2);
1040 else
1041 f = f2;
1042 }
1043 }
1044 if (f)
1045 { f->tookAddressOf = 1;
1046 SymOffExp *se = new SymOffExp(loc, f, 0, 0);
1047 se->semantic(sc);
1048 // Let SymOffExp::castTo() do the heavy lifting
1049 return se->castTo(sc, t);
1050 }
1051 }
1052
1053
1054 if (type->ty == Tpointer && type->nextOf()->ty == Tfunction &&
1055 tb->ty == Tpointer && tb->nextOf()->ty == Tfunction &&
1056 e1->op == TOKvar)
1057 {
1058 VarExp *ve = (VarExp *)e1;
1059 FuncDeclaration *f = ve->var->isFuncDeclaration();
1060 if (f)
1061 {
1062 // LDC: not in ldc
1063 #if !IN_LLVM
1064 assert(0); // should be SymOffExp instead
1065 #endif
1066 f = f->overloadExactMatch(tb->nextOf());
1067 if (f)
1068 {
1069 e = new VarExp(loc, f);
1070 e->type = f->type;
1071 e = new AddrExp(loc, e);
1072 e->type = t;
1073 return e;
1074 }
1075 }
1076 }
1077 e = Expression::castTo(sc, t);
1078 }
1079 e->type = t;
1080 return e;
1081 }
1082
1083
1084 Expression *TupleExp::castTo(Scope *sc, Type *t)
1085 { TupleExp *e = (TupleExp *)copy();
1086 e->exps = (Expressions *)exps->copy();
1087 for (size_t i = 0; i < e->exps->dim; i++)
1088 { Expression *ex = (Expression *)e->exps->data[i];
1089 ex = ex->castTo(sc, t);
1090 e->exps->data[i] = (void *)ex;
1091 }
1092 return e;
1093 }
1094
1095
1096 Expression *ArrayLiteralExp::castTo(Scope *sc, Type *t)
1097 {
1098 #if 0
1099 printf("ArrayLiteralExp::castTo(this=%s, type=%s, => %s)\n",
1100 toChars(), type->toChars(), t->toChars());
1101 #endif
1102 if (type == t)
1103 return this;
1104 ArrayLiteralExp *e = this;
1105 Type *typeb = type->toBasetype();
1106 Type *tb = t->toBasetype();
1107 if ((tb->ty == Tarray || tb->ty == Tsarray) &&
1108 (typeb->ty == Tarray || typeb->ty == Tsarray) &&
1109 // Not trying to convert non-void[] to void[]
1110 !(tb->nextOf()->toBasetype()->ty == Tvoid && typeb->nextOf()->toBasetype()->ty != Tvoid))
1111 {
1112 if (tb->ty == Tsarray)
1113 { TypeSArray *tsa = (TypeSArray *)tb;
1114 if (elements->dim != tsa->dim->toInteger())
1115 goto L1;
1116 }
1117
1118 e = (ArrayLiteralExp *)copy();
1119 e->elements = (Expressions *)elements->copy();
1120 for (int i = 0; i < elements->dim; i++)
1121 { Expression *ex = (Expression *)elements->data[i];
1122 ex = ex->castTo(sc, tb->nextOf());
1123 e->elements->data[i] = (void *)ex;
1124 }
1125 e->type = t;
1126 return e;
1127 }
1128 if (tb->ty == Tpointer && typeb->ty == Tsarray)
1129 {
1130 e = (ArrayLiteralExp *)copy();
1131 e->type = typeb->nextOf()->pointerTo();
1132 }
1133 L1:
1134 return e->Expression::castTo(sc, t);
1135 }
1136
1137 Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t)
1138 {
1139 if (type == t)
1140 return this;
1141 AssocArrayLiteralExp *e = this;
1142 Type *typeb = type->toBasetype();
1143 Type *tb = t->toBasetype();
1144 if (tb->ty == Taarray && typeb->ty == Taarray &&
1145 tb->nextOf()->toBasetype()->ty != Tvoid)
1146 {
1147 e = (AssocArrayLiteralExp *)copy();
1148 e->keys = (Expressions *)keys->copy();
1149 e->values = (Expressions *)values->copy();
1150 assert(keys->dim == values->dim);
1151 for (size_t i = 0; i < keys->dim; i++)
1152 { Expression *ex = (Expression *)values->data[i];
1153 ex = ex->castTo(sc, tb->nextOf());
1154 e->values->data[i] = (void *)ex;
1155
1156 ex = (Expression *)keys->data[i];
1157 ex = ex->castTo(sc, ((TypeAArray *)tb)->index);
1158 e->keys->data[i] = (void *)ex;
1159 }
1160 e->type = t;
1161 return e;
1162 }
1163 L1:
1164 return e->Expression::castTo(sc, t);
1165 }
1166
1167 Expression *SymOffExp::castTo(Scope *sc, Type *t)
1168 {
1169 #if 0
1170 printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n",
1171 toChars(), type->toChars(), t->toChars());
1172 #endif
1173 if (type == t && hasOverloads == 0)
1174 return this;
1175 Expression *e;
1176 Type *tb = t->toBasetype();
1177 Type *typeb = type->toBasetype();
1178 if (tb != typeb)
1179 {
1180 // Look for pointers to functions where the functions are overloaded.
1181 FuncDeclaration *f;
1182
1183 if (hasOverloads &&
1184 typeb->ty == Tpointer && typeb->nextOf()->ty == Tfunction &&
1185 (tb->ty == Tpointer || tb->ty == Tdelegate) && tb->nextOf()->ty == Tfunction)
1186 {
1187 f = var->isFuncDeclaration();
1188 if (f)
1189 {
1190 f = f->overloadExactMatch(tb->nextOf());
1191 if (f)
1192 {
1193 if (tb->ty == Tdelegate && f->needThis() && hasThis(sc))
1194 {
1195 e = new DelegateExp(loc, new ThisExp(loc), f);
1196 e = e->semantic(sc);
1197 }
1198 else if (tb->ty == Tdelegate && f->isNested())
1199 {
1200 e = new DelegateExp(loc, new IntegerExp(0), f);
1201 e = e->semantic(sc);
1202 }
1203 else
1204 {
1205 e = new SymOffExp(loc, f, 0);
1206 e->type = t;
1207 }
1208 f->tookAddressOf = 1;
1209 return e;
1210 }
1211 }
1212 }
1213 e = Expression::castTo(sc, t);
1214 }
1215 else
1216 { e = copy();
1217 e->type = t;
1218 ((SymOffExp *)e)->hasOverloads = 0;
1219 }
1220 return e;
1221 }
1222
1223 Expression *DelegateExp::castTo(Scope *sc, Type *t)
1224 {
1225 #if 0
1226 printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n",
1227 toChars(), type->toChars(), t->toChars());
1228 #endif
1229 static char msg[] = "cannot form delegate due to covariant return type";
1230
1231 Expression *e = this;
1232 Type *tb = t->toBasetype();
1233 Type *typeb = type->toBasetype();
1234 if (tb != typeb)
1235 {
1236 // Look for delegates to functions where the functions are overloaded.
1237 FuncDeclaration *f;
1238
1239 if (typeb->ty == Tdelegate && typeb->nextOf()->ty == Tfunction &&
1240 tb->ty == Tdelegate && tb->nextOf()->ty == Tfunction)
1241 {
1242 if (func)
1243 {
1244 f = func->overloadExactMatch(tb->nextOf());
1245 if (f)
1246 { int offset;
1247 if (f->tintro && f->tintro->nextOf()->isBaseOf(f->type->nextOf(), &offset) && offset)
1248 error("%s", msg);
1249 f->tookAddressOf = 1;
1250 e = new DelegateExp(loc, e1, f);
1251 e->type = t;
1252 return e;
1253 }
1254 if (func->tintro)
1255 error("%s", msg);
1256 }
1257 }
1258 e = Expression::castTo(sc, t);
1259 }
1260 else
1261 { int offset;
1262
1263 func->tookAddressOf = 1;
1264 if (func->tintro && func->tintro->nextOf()->isBaseOf(func->type->nextOf(), &offset) && offset)
1265 error("%s", msg);
1266 e = copy();
1267 e->type = t;
1268 }
1269 return e;
1270 }
1271
1272 Expression *CondExp::castTo(Scope *sc, Type *t)
1273 {
1274 Expression *e = this;
1275
1276 if (type != t)
1277 {
1278 if (1 || e1->op == TOKstring || e2->op == TOKstring)
1279 { e = new CondExp(loc, econd, e1->castTo(sc, t), e2->castTo(sc, t));
1280 e->type = t;
1281 }
1282 else
1283 e = Expression::castTo(sc, t);
1284 }
1285 return e;
1286 }
1287
1288 /* ==================== ====================== */
1289
1290 /****************************************
1291 * Scale addition/subtraction to/from pointer.
1292 */
1293
1294 Expression *BinExp::scaleFactor(Scope *sc)
1295 { d_uns64 stride;
1296 Type *t1b = e1->type->toBasetype();
1297 Type *t2b = e2->type->toBasetype();
1298
1299 if (t1b->ty == Tpointer && t2b->isintegral())
1300 { // Need to adjust operator by the stride
1301 // Replace (ptr + int) with (ptr + (int * stride))
1302 Type *t = Type::tptrdiff_t;
1303
1304 stride = t1b->nextOf()->size(loc);
1305 if (!t->equals(t2b))
1306 e2 = e2->castTo(sc, t);
1307 // LDC: llvm uses typesafe pointer arithmetic
1308 #if !IN_LLVM
1309 e2 = new MulExp(loc, e2, new IntegerExp(0, stride, t));
1310 #endif
1311 e2->type = t;
1312 type = e1->type;
1313 }
1314 else if (t2b->ty == Tpointer && t1b->isintegral())
1315 { // Need to adjust operator by the stride
1316 // Replace (int + ptr) with (ptr + (int * stride))
1317 Type *t = Type::tptrdiff_t;
1318 Expression *e;
1319
1320 stride = t2b->nextOf()->size(loc);
1321 if (!t->equals(t1b))
1322 e = e1->castTo(sc, t);
1323 else
1324 e = e1;
1325 #if !IN_LLVM
1326 e = new MulExp(loc, e, new IntegerExp(0, stride, t));
1327 #endif
1328 e->type = t;
1329 type = e2->type;
1330 e1 = e2;
1331 e2 = e;
1332 }
1333 return this;
1334 }
1335
1336 /**************************************
1337 * Combine types.
1338 * Output:
1339 * *pt merged type, if *pt is not NULL
1340 * *pe1 rewritten e1
1341 * *pe2 rewritten e2
1342 * Returns:
1343 * !=0 success
1344 * 0 failed
1345 */
1346
1347 int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression **pe2)
1348 {
1349 //printf("typeMerge() %s op %s\n", (*pe1)->toChars(), (*pe2)->toChars());
1350 //dump(0);
1351
1352 Expression *e1 = (*pe1)->integralPromotions(sc);
1353 Expression *e2 = (*pe2)->integralPromotions(sc);
1354
1355 Type *t1 = e1->type;
1356 Type *t2 = e2->type;
1357 assert(t1);
1358 Type *t = t1;
1359
1360 //if (t1) printf("\tt1 = %s\n", t1->toChars());
1361 //if (t2) printf("\tt2 = %s\n", t2->toChars());
1362 #ifdef DEBUG
1363 if (!t2) printf("\te2 = '%s'\n", e2->toChars());
1364 #endif
1365 assert(t2);
1366
1367 Type *t1b = t1->toBasetype();
1368 Type *t2b = t2->toBasetype();
1369
1370 TY ty = (TY)Type::impcnvResult[t1b->ty][t2b->ty];
1371 if (ty != Terror)
1372 { TY ty1;
1373 TY ty2;
1374
1375 ty1 = (TY)Type::impcnvType1[t1b->ty][t2b->ty];
1376 ty2 = (TY)Type::impcnvType2[t1b->ty][t2b->ty];
1377
1378 if (t1b->ty == ty1) // if no promotions
1379 {
1380 if (t1 == t2)
1381 {
1382 t = t1;
1383 goto Lret;
1384 }
1385
1386 if (t1b == t2b)
1387 {
1388 t = t1b;
1389 goto Lret;
1390 }
1391 }
1392
1393 t = Type::basic[ty];
1394
1395 t1 = Type::basic[ty1];
1396 t2 = Type::basic[ty2];
1397 e1 = e1->castTo(sc, t1);
1398 e2 = e2->castTo(sc, t2);
1399 //printf("after typeCombine():\n");
1400 //dump(0);
1401 //printf("ty = %d, ty1 = %d, ty2 = %d\n", ty, ty1, ty2);
1402 goto Lret;
1403 }
1404
1405 t1 = t1b;
1406 t2 = t2b;
1407
1408 Lagain:
1409 if (t1 == t2)
1410 {
1411 }
1412 else if (t1->ty == Tpointer && t2->ty == Tpointer)
1413 {
1414 // Bring pointers to compatible type
1415 Type *t1n = t1->nextOf();
1416 Type *t2n = t2->nextOf();
1417
1418 if (t1n == t2n)
1419 ;
1420 else if (t1n->ty == Tvoid) // pointers to void are always compatible
1421 t = t2;
1422 else if (t2n->ty == Tvoid)
1423 ;
1424 else if (t1n->mod != t2n->mod)
1425 {
1426 t1 = t1n->mutableOf()->constOf()->pointerTo();
1427 t2 = t2n->mutableOf()->constOf()->pointerTo();
1428 t = t1;
1429 goto Lagain;
1430 }
1431 else if (t1n->ty == Tclass && t2n->ty == Tclass)
1432 { ClassDeclaration *cd1 = t1n->isClassHandle();
1433 ClassDeclaration *cd2 = t2n->isClassHandle();
1434 int offset;
1435
1436 if (cd1->isBaseOf(cd2, &offset))
1437 {
1438 if (offset)
1439 e2 = e2->castTo(sc, t);
1440 }
1441 else if (cd2->isBaseOf(cd1, &offset))
1442 {
1443 t = t2;
1444 if (offset)
1445 e1 = e1->castTo(sc, t);
1446 }
1447 else
1448 goto Lincompatible;
1449 }
1450 else
1451 goto Lincompatible;
1452 }
1453 else if ((t1->ty == Tsarray || t1->ty == Tarray) &&
1454 e2->op == TOKnull && t2->ty == Tpointer && t2->nextOf()->ty == Tvoid)
1455 { /* (T[n] op void*)
1456 * (T[] op void*)
1457 */
1458 goto Lx1;
1459 }
1460 else if ((t2->ty == Tsarray || t2->ty == Tarray) &&
1461 e1->op == TOKnull && t1->ty == Tpointer && t1->nextOf()->ty == Tvoid)
1462 { /* (void* op T[n])
1463 * (void* op T[])
1464 */
1465 goto Lx2;
1466 }
1467 else if ((t1->ty == Tsarray || t1->ty == Tarray) && t1->implicitConvTo(t2))
1468 {
1469 goto Lt2;
1470 }
1471 else if ((t2->ty == Tsarray || t2->ty == Tarray) && t2->implicitConvTo(t1))
1472 {
1473 goto Lt1;
1474 }
1475 /* If one is mutable and the other invariant, then retry
1476 * with both of them as const
1477 */
1478 else if ((t1->ty == Tsarray || t1->ty == Tarray || t1->ty == Tpointer) &&
1479 (t2->ty == Tsarray || t2->ty == Tarray || t2->ty == Tpointer) &&
1480 t1->nextOf()->mod != t2->nextOf()->mod
1481 )
1482 {
1483 if (t1->ty == Tpointer)
1484 t1 = t1->nextOf()->mutableOf()->constOf()->pointerTo();
1485 else
1486 t1 = t1->nextOf()->mutableOf()->constOf()->arrayOf();
1487
1488 if (t2->ty == Tpointer)
1489 t2 = t2->nextOf()->mutableOf()->constOf()->pointerTo();
1490 else
1491 t2 = t2->nextOf()->mutableOf()->constOf()->arrayOf();
1492 t = t1;
1493 goto Lagain;
1494 }
1495 else if (t1->ty == Tclass || t2->ty == Tclass)
1496 {
1497 while (1)
1498 {
1499 int i1 = e2->implicitConvTo(t1);
1500 int i2 = e1->implicitConvTo(t2);
1501
1502 if (i1 && i2)
1503 {
1504 // We have the case of class vs. void*, so pick class
1505 if (t1->ty == Tpointer)
1506 i1 = 0;
1507 else if (t2->ty == Tpointer)
1508 i2 = 0;
1509 }
1510
1511 if (i2)
1512 {
1513 goto Lt2;
1514 }
1515 else if (i1)
1516 {
1517 goto Lt1;
1518 }
1519 else if (t1->ty == Tclass && t2->ty == Tclass)
1520 { TypeClass *tc1 = (TypeClass *)t1;
1521 TypeClass *tc2 = (TypeClass *)t2;
1522
1523 /* Pick 'tightest' type
1524 */
1525 ClassDeclaration *cd1 = tc1->sym->baseClass;
1526 ClassDeclaration *cd2 = tc2->sym->baseClass;
1527
1528 if (cd1 && cd2)
1529 { t1 = cd1->type;
1530 t2 = cd2->type;
1531 }
1532 else if (cd1)
1533 t1 = cd1->type;
1534 else if (cd2)
1535 t2 = cd2->type;
1536 else
1537 goto Lincompatible;
1538 }
1539 else
1540 goto Lincompatible;
1541 }
1542 }
1543 else if (t1->ty == Tstruct && t2->ty == Tstruct)
1544 {
1545 if (((TypeStruct *)t1)->sym != ((TypeStruct *)t2)->sym)
1546 goto Lincompatible;
1547 }
1548 else if ((e1->op == TOKstring || e1->op == TOKnull) && e1->implicitConvTo(t2))
1549 {
1550 goto Lt2;
1551 }
1552 else if ((e2->op == TOKstring || e2->op == TOKnull) && e2->implicitConvTo(t1))
1553 {
1554 goto Lt1;
1555 }
1556 else if (t1->ty == Tsarray && t2->ty == Tsarray &&
1557 e2->implicitConvTo(t1->nextOf()->arrayOf()))
1558 {
1559 Lx1:
1560 t = t1->nextOf()->arrayOf();
1561 e1 = e1->castTo(sc, t);
1562 e2 = e2->castTo(sc, t);
1563 }
1564 else if (t1->ty == Tsarray && t2->ty == Tsarray &&
1565 e1->implicitConvTo(t2->nextOf()->arrayOf()))
1566 {
1567 Lx2:
1568 t = t2->nextOf()->arrayOf();
1569 e1 = e1->castTo(sc, t);
1570 e2 = e2->castTo(sc, t);
1571 }
1572 else if (t1->isintegral() && t2->isintegral())
1573 {
1574 assert(0);
1575 }
1576 else if (e1->op == TOKslice && t1->ty == Tarray &&
1577 e2->implicitConvTo(t1->nextOf()))
1578 { // T[] op T
1579 e2 = e2->castTo(sc, t1->nextOf());
1580 t = t1->nextOf()->arrayOf();
1581 }
1582 else if (e2->op == TOKslice && t2->ty == Tarray &&
1583 e1->implicitConvTo(t2->nextOf()))
1584 { // T op T[]
1585 e1 = e1->castTo(sc, t2->nextOf());
1586 t = t2->nextOf()->arrayOf();
1587
1588 //printf("test %s\n", e->toChars());
1589 e1 = e1->optimize(WANTvalue);
1590 if (e && e->isCommutative() && e1->isConst())
1591 { /* Swap operands to minimize number of functions generated
1592 */
1593 //printf("swap %s\n", e->toChars());
1594 Expression *tmp = e1;
1595 e1 = e2;
1596 e2 = tmp;
1597 }
1598 }
1599 else
1600 {
1601 Lincompatible:
1602 return 0;
1603 }
1604 Lret:
1605 if (!*pt)
1606 *pt = t;
1607 *pe1 = e1;
1608 *pe2 = e2;
1609 #if 0
1610 printf("-typeMerge() %s op %s\n", e1->toChars(), e2->toChars());
1611 if (e1->type) printf("\tt1 = %s\n", e1->type->toChars());
1612 if (e2->type) printf("\tt2 = %s\n", e2->type->toChars());
1613 printf("\ttype = %s\n", t->toChars());
1614 #endif
1615 //dump(0);
1616 return 1;
1617
1618
1619 Lt1:
1620 e2 = e2->castTo(sc, t1);
1621 t = t1;
1622 goto Lret;
1623
1624 Lt2:
1625 e1 = e1->castTo(sc, t2);
1626 t = t2;
1627 goto Lret;
1628 }
1629
1630 /************************************
1631 * Bring leaves to common type.
1632 */
1633
1634 Expression *BinExp::typeCombine(Scope *sc)
1635 {
1636 Type *t1 = e1->type->toBasetype();
1637 Type *t2 = e2->type->toBasetype();
1638
1639 if (op == TOKmin || op == TOKadd)
1640 {
1641 if (t1 == t2 && (t1->ty == Tstruct || t1->ty == Tclass))
1642 goto Lerror;
1643 }
1644
1645 if (!typeMerge(sc, this, &type, &e1, &e2))
1646 goto Lerror;
1647 return this;
1648
1649 Lerror:
1650 incompatibleTypes();
1651 type = Type::terror;
1652 return this;
1653 }
1654
1655 /***********************************
1656 * Do integral promotions (convertchk).
1657 * Don't convert <array of> to <pointer to>
1658 */
1659
1660 Expression *Expression::integralPromotions(Scope *sc)
1661 {
1662 Expression *e = this;
1663
1664 //printf("integralPromotions %s %s\n", e->toChars(), e->type->toChars());
1665 switch (type->toBasetype()->ty)
1666 {
1667 case Tvoid:
1668 error("void has no value");
1669 break;
1670
1671 case Tint8:
1672 case Tuns8:
1673 case Tint16:
1674 case Tuns16:
1675 case Tbit:
1676 case Tbool:
1677 case Tchar:
1678 case Twchar:
1679 e = e->castTo(sc, Type::tint32);
1680 break;
1681
1682 case Tdchar:
1683 e = e->castTo(sc, Type::tuns32);
1684 break;
1685 }
1686 return e;
1687 }
1688