root/trunk/rebuild/cast.c

Revision 921, 37.2 kB (checked in by Gregor, 3 months ago)

rebuild/*: Removed some needless error messages.

Line 
1 // Copyright (c) 1999-2008 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 of type %s) => %s\n", toChars(), type->toChars(), t->toChars());
34
35     MATCH match = implicitConvTo(t);
36     if (match)
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 #if V2
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)\n",
342     toChars(), type->toChars(), t->toChars());
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 V2
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         /* I don't think this can ever happen -
567          * it should have been
568          * converted to a SymOffExp.
569          */
570         assert(0);
571         VarExp *ve = (VarExp *)e1;
572         FuncDeclaration *f = ve->var->isFuncDeclaration();
573         if (f && f->overloadExactMatch(t->nextOf()))
574         result = MATCHexact;
575     }
576     }
577     //printf("\tresult = %d\n", result);
578     return result;
579 }
580
581 MATCH SymOffExp::implicitConvTo(Type *t)
582 {
583 #if 0
584     printf("SymOffExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
585     toChars(), type->toChars(), t->toChars());
586 #endif
587     MATCH result;
588
589     result = type->implicitConvTo(t);
590     //printf("\tresult = %d\n", result);
591
592     if (result == MATCHnomatch)
593     {
594     // Look for pointers to functions where the functions are overloaded.
595     FuncDeclaration *f;
596
597     t = t->toBasetype();
598     if (type->ty == Tpointer && type->nextOf()->ty == Tfunction &&
599         (t->ty == Tpointer || t->ty == Tdelegate) && t->nextOf()->ty == Tfunction)
600     {
601         f = var->isFuncDeclaration();
602         if (f)
603         {   f = f->overloadExactMatch(t->nextOf());
604         if (f)
605         {   if ((t->ty == Tdelegate && (f->needThis() || f->isNested())) ||
606             (t->ty == Tpointer && !(f->needThis() || f->isNested())))
607             {
608             result = MATCHexact;
609             }
610         }
611         }
612     }
613     }
614     //printf("\tresult = %d\n", result);
615     return result;
616 }
617
618 MATCH DelegateExp::implicitConvTo(Type *t)
619 {
620 #if 0
621     printf("DelegateExp::implicitConvTo(this=%s, type=%s, t=%s)\n",
622     toChars(), type->toChars(), t->toChars());
623 #endif
624     MATCH result;
625
626     result = type->implicitConvTo(t);
627
628     if (result == MATCHnomatch)
629     {
630     // Look for pointers to functions where the functions are overloaded.
631     FuncDeclaration *f;
632
633     t = t->toBasetype();
634     if (type->ty == Tdelegate && type->nextOf()->ty == Tfunction &&
635         t->ty == Tdelegate && t->nextOf()->ty == Tfunction)
636     {
637         if (func && func->overloadExactMatch(t->nextOf()))
638         result = MATCHexact;
639     }
640     }
641     return result;
642 }
643
644 MATCH CondExp::implicitConvTo(Type *t)
645 {
646     MATCH m1;
647     MATCH m2;
648
649     m1 = e1->implicitConvTo(t);
650     m2 = e2->implicitConvTo(t);
651
652     // Pick the worst match
653     return (m1 < m2) ? m1 : m2;
654 }
655
656
657 /* ==================== castTo ====================== */
658
659 /**************************************
660  * Do an explicit cast.
661  */
662
663 Expression *Expression::castTo(Scope *sc, Type *t)
664 {
665     //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars());
666 #if 0
667     printf("Expression::castTo(this=%s, type=%s, t=%s)\n",
668     toChars(), type->toChars(), t->toChars());
669 #endif
670     if (type == t)
671     return this;
672     Expression *e = this;
673     Type *tb = t->toBasetype();
674     Type *typeb = type->toBasetype();
675     if (tb != typeb)
676     {
677     // Do (type *) cast of (type [dim])