root/branches/dmdfe/cast.c

Revision 740, 29.4 kB (checked in by Gregor, 1 year ago)

MERGE: DMD 1.019

Line 
1 // Copyright (c) 1999-2006 by Digital Mars
2 // All Rights Reserved
3 // written by Walter Bright
4 // http://www.digitalmars.com
5 // License for redistribution is by either the Artistic License
6 // in artistic.txt, or the GNU General Public License in gnu.txt.
7 // See the included readme.txt for details.
8
9 #include <stdio.h>
10 #include <assert.h>
11
12 #if _WIN32 || IN_GCC || IN_DMDFE
13 #include "mem.h"
14 #else
15 #include "../root/mem.h"
16 #endif
17
18 #include "expression.h"
19 #include "mtype.h"
20 #include "utf.h"
21 #include "declaration.h"
22 #include "aggregate.h"
23
24 /* ==================== implicitCast ====================== */
25
26 /**************************************
27  * Do an implicit cast.
28  * Issue error if it can't be done.
29  */
30
31 Expression *Expression::implicitCastTo(Scope *sc, Type *t)
32 {
33     //printf("implicitCastTo(%s) => %s\n", type->toChars(), t->toChars());
34     if (implicitConvTo(t))
35     {
36     if (global.params.warnings &&
37         Type::impcnvWarn[type->toBasetype()->ty][t->toBasetype()->ty] &&
38         op != TOKint64)
39     {
40         Expression *e = optimize(WANTflags | WANTvalue);
41
42         if (e->op == TOKint64)
43         return e->implicitCastTo(sc, t);
44
45         fprintf(stdmsg, "warning - ");
46         error("implicit conversion of expression (%s) of type %s to %s can cause loss of data",
47         toChars(), type->toChars(), t->toChars());
48     }
49     return castTo(sc, t);
50     }
51
52     Expression *e = optimize(WANTflags | WANTvalue);
53     if (e != this)
54     return e->implicitCastTo(sc, t);
55
56 #if 0
57 print();
58 type->print();
59 printf("to:\n");
60 t->print();
61 printf("%p %p type: %s to: %s\n", type->deco, t->deco, type->deco, t->deco);
62 //printf("%p %p %p\n", type->next->arrayOf(), type, t);
63 fflush(stdout);
64 #endif
65     if (!t->deco)
66     {   /* Can happen with:
67      *    enum E { One }
68      *    class A
69      *    { static void fork(EDG dg) { dg(E.One); }
70      *  alias void delegate(E) EDG;
71      *    }
72      * Should eventually make it work.
73      */
74     error("forward reference to type %s", t->toChars());
75     }
76     else if (t->reliesOnTident())
77     error("forward reference to type %s", t->reliesOnTident()->toChars());
78
79     error("cannot implicitly convert expression (%s) of type %s to %s",
80     toChars(), type->toChars(), t->toChars());
81     return castTo(sc, t);
82 }
83
84 /*******************************************
85  * Return !=0 if we can implicitly convert this to type t.
86  * Don't do the actual cast.
87  */
88
89 MATCH Expression::implicitConvTo(Type *t)
90 {
91 #if 0
92     printf("Expression::implicitConvTo(this=%s, type=%s, t=%s)\n",
93     toChars(), type->toChars(), t->toChars());
94 #endif
95     if (!type)
96     {   error("%s is not an expression", toChars());
97     type = Type::terror;
98     }
99     if (t->ty == Tbit && isBit())
100     return MATCHconvert;
101     Expression *e = optimize(WANTvalue | WANTflags);
102     if (e != this)
103     {   //printf("optimzed to %s\n", e->toChars());
104     return e->implicitConvTo(t);
105     }
106     MATCH match = type->implicitConvTo(t);
107     if (match)
108     return match;
109 #if 0
110     Type *tb = t->toBasetype();
111     if (tb->ty == Tdelegate)
112     {   TypeDelegate *td = (TypeDelegate *)tb;
113     TypeFunction *tf = (TypeFunction *)td->next;
114
115     if (!tf->varargs &&
116         !(tf->arguments && tf->arguments->dim)
117        )
118     {
119         match = type->implicitConvTo(tf->next);
120         if (match)
121         return match;
122         if (tf->next->toBasetype()->ty == Tvoid)
123         return MATCHconvert;
124     }
125     }
126 #endif
127     return MATCHnomatch;
128 }
129
130
131 MATCH IntegerExp::implicitConvTo(Type *t)
132 {
133 #if 0
134     printf("IntegerExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
135     toChars(), type->toChars(), t->toChars());
136 #endif
137     if (type->equals(t))
138     return MATCHexact;
139
140     enum TY ty = type->toBasetype()->ty;
141     enum TY toty = t->toBasetype()->ty;
142
143     if (type->implicitConvTo(t) == MATCHnomatch && t->ty == Tenum)
144     {
145     return MATCHnomatch;
146     }
147
148     switch (ty)
149     {
150     case Tbit:
151     case Tbool:
152         value &= 1;
153         ty = Tint32;
154         break;
155
156     case Tint8:
157         value = (signed char)value;
158         ty = Tint32;
159         break;
160
161     case Tchar:
162     case Tuns8:
163         value &= 0xFF;
164         ty = Tint32;
165         break;
166
167     case Tint16:
168         value = (short)value;
169         ty = Tint32;
170         break;
171
172     case Tuns16:
173     case Twchar:
174         value &= 0xFFFF;
175         ty = Tint32;
176         break;
177
178     case Tint32:
179         value = (int)value;
180         break;
181
182     case Tuns32:
183     case Tdchar:
184         value &= 0xFFFFFFFF;
185         ty = Tuns32;
186         break;
187
188     default:
189         break;
190     }
191
192     // Only allow conversion if no change in value
193     switch (toty)
194     {
195     case Tbit:
196     case Tbool:
197         if ((value & 1) != value)
198         goto Lno;
199         goto Lyes;
200
201     case Tint8:
202         if ((signed char)value != value)
203         goto Lno;
204         goto Lyes;
205
206     case Tchar:
207     case Tuns8:
208         //printf("value = %llu %llu\n", (integer_t)(unsigned char)value, value);
209         if ((unsigned char)value != value)
210         goto Lno;
211         goto Lyes;
212
213     case Tint16:
214         if ((short)value != value)
215         goto Lno;
216         goto Lyes;
217
218     case Tuns16:
219         if ((unsigned short)value != value)
220         goto Lno;
221         goto Lyes;
222
223     case Tint32:
224         if (ty == Tuns32)
225         {
226         }
227         else if ((int)value != value)
228         goto Lno;
229         goto Lyes;
230
231     case Tuns32:
232         if (ty == Tint32)
233         {
234         }
235         else if ((unsigned)value != value)
236         goto Lno;
237         goto Lyes;
238
239     case Tdchar:
240         if (value > 0x10FFFFUL)
241         goto Lno;
242         goto Lyes;
243
244     case Twchar:
245         if ((unsigned short)value != value)
246         goto Lno;
247         goto Lyes;
248
249     case Tfloat32:
250     {
251         volatile float f;
252         if (type->isunsigned())
253         {
254         f = (float)value;
255         if (f != value)
256             goto Lno;
257         }
258         else
259         {
260         f = (float)(long long)value;
261         if (f != (long long)value)
262             goto Lno;
263         }
264         goto Lyes;
265     }
266
267     case Tfloat64:
268     {
269         volatile double f;
270         if (type->isunsigned())
271         {
272         f = (double)value;
273         if (f != value)
274             goto Lno;
275         }
276         else
277         {
278         f = (double)(long long)value;
279         if (f != (long long)value)
280             goto Lno;
281         }
282         goto Lyes;
283     }
284
285     case Tfloat80:
286     {
287         volatile long double f;
288         if (type->isunsigned())
289         {
290         f = (long double)value;
291         if (f != value)
292             goto Lno;
293         }
294         else
295         {
296         f = (long double)(long long)value;
297         if (f != (long long)value)
298             goto Lno;
299         }
300         goto Lyes;
301     }
302     }
303     return Expression::implicitConvTo(t);
304
305 Lyes:
306     //printf("MATCHconvert\n");
307     return MATCHconvert;
308
309 Lno:
310     //printf("MATCHnomatch\n");
311     return MATCHnomatch;
312 }
313
314 MATCH NullExp::implicitConvTo(Type *t)
315 {
316 #if 0
317     printf("NullExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
318     toChars(), type->toChars(), t->toChars());
319 #endif
320     if (this->type->equals(t))
321     return MATCHexact;
322     // NULL implicitly converts to any pointer type or dynamic array
323     if (type->ty == Tpointer && type->next->ty == Tvoid)
324     {
325     if (t->ty == Ttypedef)
326         t = ((TypeTypedef *)t)->sym->basetype;
327     if (t->ty == Tpointer || t->ty == Tarray ||
328         t->ty == Taarray  || t->ty == Tclass ||
329         t->ty == Tdelegate)
330         return committed ? MATCHconvert : MATCHexact;
331     }
332     return Expression::implicitConvTo(t);
333 }
334
335 MATCH StringExp::implicitConvTo(Type *t)
336 {   MATCH m;
337
338 #if 0
339     printf("StringExp::implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n",
340     toChars(), committed, type->toChars(), t->toChars());
341 #endif
342     if (!committed)
343     {
344     if (!committed && t->ty == Tpointer && t->next->ty == Tvoid)
345     {
346     return MATCHnomatch;
347     }
348     if (type->ty == Tsarray || type->ty == Tarray || type->ty == Tpointer)
349     {
350     if (type->next->ty == Tchar)
351     {
352         switch (t->ty)
353         {
354         case Tsarray:
355             if (type->ty == Tsarray &&
356             ((TypeSArray *)type)->dim->toInteger() !=
357             ((TypeSArray *)t)->dim->toInteger())
358             return MATCHnomatch;
359             goto L1;
360         case Tarray:
361             goto L1;
362         case Tpointer:
363         L1:
364             if (t->next->ty == Tchar)
365             return MATCHexact;
366             else if (t->next->ty == Twchar)
367             return MATCHexact;
368             else if (t->next->ty == Tdchar)
369             return MATCHexact;
370             break;
371         }
372     }
373     }
374     }
375     return Expression::implicitConvTo(t);
376 #if 0
377     m = (MATCH)type->implicitConvTo(t);
378     if (m)
379     {
380     return m;
381     }
382
383     return MATCHnomatch;
384 #endif
385 }
386
387 MATCH ArrayLiteralExp::implicitConvTo(Type *t)
388 {   MATCH result = MATCHexact;
389
390     Type *typeb = type->toBasetype();
391     Type *tb = t->toBasetype();
392     if ((tb->ty == Tarray || tb->ty == Tsarray) &&
393     (typeb->ty == Tarray || typeb->ty == Tsarray))
394     {
395     if (tb->ty == Tsarray)
396     {   TypeSArray *tsa = (TypeSArray *)tb;
397         if (elements->dim != tsa->dim->toInteger())
398         result = MATCHnomatch;
399     }
400
401     for (int i = 0; i < elements->dim; i++)
402     {   Expression *e = (Expression *)elements->data[i];
403         MATCH m = (MATCH)e->implicitConvTo(tb->next);
404         if (m < result)
405         result = m;         // remember worst match
406         if (result == MATCHnomatch)
407         break;              // no need to check for worse
408     }
409     return result;
410     }
411     else
412     return Expression::implicitConvTo(t);
413 }
414
415 MATCH AssocArrayLiteralExp::implicitConvTo(Type *t)
416 {   MATCH result = MATCHexact;
417
418     Type *typeb = type->toBasetype();
419     Type *tb = t->toBasetype();
420     if (tb->ty == Taarray && typeb->ty == Taarray)
421     {
422     for (size_t i = 0; i < keys->dim; i++)
423     {   Expression *e = (Expression *)keys->data[i];
424         MATCH m = (MATCH)e->implicitConvTo(((TypeAArray *)tb)->key);
425         if (m < result)
426         result = m;         // remember worst match
427         if (result == MATCHnomatch)
428         break;              // no need to check for worse
429         e = (Expression *)values->data[i];
430         m = (MATCH)e->implicitConvTo(tb->next);
431         if (m < result)
432         result = m;         // remember worst match
433         if (result == MATCHnomatch)
434         break;              // no need to check for worse
435     }
436     return result;
437     }
438     else
439     return Expression::implicitConvTo(t);
440 }
441
442 MATCH AddrExp::implicitConvTo(Type *t)
443 {
444 #if 0
445     printf("AddrExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
446     toChars(), type->toChars(), t->toChars());
447 #endif
448     MATCH result;
449
450     result = type->implicitConvTo(t);
451     //printf("\tresult = %d\n", result);
452
453     if (result == MATCHnomatch)
454     {
455     // Look for pointers to functions where the functions are overloaded.
456     VarExp *ve;
457     FuncDeclaration *f;
458
459     t = t->toBasetype();
460     if (type->ty == Tpointer && type->next->ty == Tfunction &&
461         t->ty == Tpointer && t->next->ty == Tfunction &&
462         e1->op == TOKvar)
463     {
464         ve = (VarExp *)e1;
465         f = ve->var->isFuncDeclaration();
466         if (f && f->overloadExactMatch(t->next))
467         result = MATCHexact;
468     }
469     }
470     //printf("\tresult = %d\n", result);
471     return result;
472 }
473
474 MATCH SymOffExp::implicitConvTo(Type *t)
475 {
476 #if 0
477     printf("SymOffExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
478     toChars(), type->toChars(), t->toChars());
479 #endif
480     MATCH result;
481
482     result = type->implicitConvTo(t);
483     //printf("\tresult = %d\n", result);
484
485     if (result == MATCHnomatch)
486     {
487     // Look for pointers to functions where the functions are overloaded.
488     FuncDeclaration *f;
489
490     t = t->toBasetype();
491     if (type->ty == Tpointer && type->next->ty == Tfunction &&
492         t->ty == Tpointer && t->next->ty == Tfunction)
493     {
494         f = var->isFuncDeclaration();
495         if (f && f->overloadExactMatch(t->next))
496         result = MATCHexact;
497     }
498     }
499     //printf("\tresult = %d\n", result);
500     return result;
501 }
502
503 MATCH DelegateExp::implicitConvTo(Type *t)
504 {
505 #if 0
506     printf("DelegateExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
507     toChars(), type->toChars(), t->toChars());
508 #endif
509     MATCH result;
510
511     result = type->implicitConvTo(t);
512
513     if (result == 0)
514     {
515     // Look for pointers to functions where the functions are overloaded.
516     FuncDeclaration *f;
517
518     t = t->toBasetype();
519     if (type->ty == Tdelegate && type->next->ty == Tfunction &&
520         t->ty == Tdelegate && t->next->ty == Tfunction)
521     {
522         if (func && func->overloadExactMatch(t->next))
523         result = MATCHexact;
524     }
525     }
526     return result;
527 }
528
529 MATCH CondExp::implicitConvTo(Type *t)
530 {
531     MATCH m1;
532     MATCH m2;
533
534     m1 = e1->implicitConvTo(t);
535     m2 = e2->implicitConvTo(t);
536
537     // Pick the worst match
538     return (m1 < m2) ? m1 : m2;
539 }
540
541
542 /* ==================== castTo ====================== */
543
544 /**************************************
545  * Do an explicit cast.
546  */
547
548 Expression *Expression::castTo(Scope *sc, Type *t)
549 {   Expression *e;
550     Type *tb;
551
552     //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars());
553 #if 0
554     printf("Expression::castTo(this=%s, type=%s, t=%s)\n",
555     toChars(), type->toChars(), t->toChars());
556 #endif
557     e = this;
558     tb = t->toBasetype();
559     type = type->toBasetype();
560     if (tb != type)
561     {
562     if (tb->ty == Tbit && isBit())
563         ;
564
565     // Do (type *) cast of (type [dim])
566     else if (tb->ty == Tpointer &&
567         type->ty == Tsarray
568        )
569     {
570         //printf("Converting [dim] to *\n");
571
572         if (type->size(loc) == 0)
573         e = new NullExp(loc);
574         else
575         e = new AddrExp(loc, e);
576     }
577 #if 0
578     else if (tb->ty == Tdelegate && type->ty != Tdelegate)
579     {
580         TypeDelegate *td = (TypeDelegate *)tb;
581         TypeFunction *tf = (TypeFunction *)td->next;
582         return toDelegate(sc, tf->next);
583     }
584 #endif
585     else
586     {
587         e = new CastExp(loc, e, tb);
588     }
589     }
590     e->type = t;
591     //printf("Returning: %s\n", e->toChars());
592     return e;
593 }
594
595
596 Expression *RealExp::castTo(Scope *sc, Type *t)
597 {
598     if (type->isreal() && t->isreal())
599     type = t;
600     else if (type->isimaginary() && t->isimaginary())
601     type = t;
602     else
603     return Expression::castTo(sc, t);
604     return this;
605 }
606
607
608 Expression *ComplexExp::castTo(Scope *sc, Type *t)
609 {
610     if (type->iscomplex() && t->iscomplex())
611     type = t;
612     else
613     return Expression::castTo(sc, t);
614     return this;
615 }
616
617
618 Expression *NullExp::castTo(Scope *sc, Type *t)
619 {   Expression *e;
620     Type *tb;
621
622     //printf("NullExp::castTo(t = %p)\n", t);
623     committed = 1;
624     e = this;
625     tb = t->toBasetype();
626     type = type->toBasetype();
627     if (tb != type)
628     {
629     // NULL implicitly converts to any pointer type or dynamic array
630     if (type->ty == Tpointer && type->next->ty == Tvoid &&
631         (tb->ty == Tpointer || tb->ty == Tarray || tb->ty == Taarray ||
632          tb->ty == Tdelegate))
633     {
634 #if 0
635         if (tb->ty == Tdelegate)
636         {   TypeDelegate *td = (TypeDelegate *)tb;
637         TypeFunction *tf = (TypeFunction *)td->next;
638
639         if (!tf->varargs &&
640             !(tf->arguments && tf->arguments->dim)
641            )
642         {
643             return Expression::castTo(sc, t);
644         }
645         }
646 #endif
647     }
648     else
649     {
650         return Expression::castTo(sc, t);
651         //e = new CastExp(loc, e, tb);
652     }
653     }
654     e->type = t;
655     return e;
656 }
657
658 Expression *StringExp::castTo(Scope *sc, Type *t)
659 {
660     StringExp *se;
661     Type *tb;
662     int unique;
663
664     //printf("StringExp::castTo(t = %s), '%s' committed = %d\n", t->toChars(), toChars(), committed);
665
666     if (!committed && t->ty == Tpointer && t->next->ty == Tvoid)
667     {
668     error("cannot convert string literal to void*");
669     }
670
671     tb = t->toBasetype();
672     //printf("\ttype = %s\n", type->toChars());
673     if (tb->ty == Tdelegate && type->toBasetype()->ty != Tdelegate)
674     return Expression::castTo(sc, t);
675
676     se = this;
677     unique = 0;
678     if (!committed)
679     {
680     // Copy when committing the type
681     void *s;
682
683     s = (unsigned char *)mem.malloc((len + 1) * sz);
684     memcpy(s, string, (len + 1) * sz);
685     se = new StringExp(loc, s, len);
686     se->type = type;
687     se->sz = sz;
688     se->committed = 0;
689     unique = 1;     // this is the only instance
690     }
691     se->type = type->toBasetype();
692     if (tb == se->