root/branches/tango/rebuild/cast.c

Revision 796, 31.1 kB (checked in by Gregor, 1 year ago)

MERGE: trunk r795

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