comparison dmd/CastExp.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 832f71e6f96c
comparison
equal deleted inserted replaced
-1:000000000000 0:10317f0c89a5
1 module dmd.CastExp;
2
3 import dmd.Expression;
4 import dmd.TY;
5 import dmd.TypeStruct;
6 import dmd.TypeExp;
7 import dmd.DotIdExp;
8 import dmd.CallExp;
9 import dmd.Global;
10 import dmd.Id;
11 import dmd.Identifier;
12 import dmd.BinExp;
13 import dmd.backend.elem;
14 import dmd.UnaExp;
15 import dmd.VarExp;
16 import dmd.Token;
17 import dmd.VarDeclaration;
18 import dmd.InterState;
19 import dmd.MATCH;
20 import dmd.Type;
21 import dmd.OutBuffer;
22 import dmd.Loc;
23 import dmd.Scope;
24 import dmd.IntRange;
25 import dmd.IRState;
26 import dmd.ArrayTypes;
27 import dmd.HdrGenState;
28 import dmd.MOD;
29 import dmd.TOK;
30 import dmd.WANT;
31 import dmd.ClassDeclaration;
32
33 import dmd.Optimize;
34 import dmd.PREC;
35 import dmd.Cast;
36
37 import dmd.backend.Util;
38 import dmd.expression.Util;
39 import dmd.backend.TYM;
40 import dmd.backend.OPER;
41 import dmd.codegen.Util;
42 import dmd.backend.RTLSYM;
43
44 class CastExp : UnaExp
45 {
46 // Possible to cast to one type while painting to another type
47 Type to; // type to cast to
48 MOD mod; // MODxxxxx
49
50 this(Loc loc, Expression e, Type t)
51 {
52 super(loc, TOK.TOKcast, CastExp.sizeof, e);
53 to = t;
54 this.mod = cast(MOD)~0;
55 }
56
57 this(Loc loc, Expression e, MOD mod)
58 {
59 super(loc, TOK.TOKcast, CastExp.sizeof, e);
60 to = null;
61 this.mod = mod;
62 }
63
64 Expression syntaxCopy()
65 {
66 return to ? new CastExp(loc, e1.syntaxCopy(), to.syntaxCopy())
67 : new CastExp(loc, e1.syntaxCopy(), mod);
68 }
69
70 Expression semantic(Scope sc)
71 {
72 Expression e;
73 BinExp b;
74 UnaExp u;
75
76 version (LOGSEMANTIC) {
77 printf("CastExp.semantic('%s')\n", toChars());
78 }
79
80 //static int x; assert(++x < 10);
81
82 if (type)
83 return this;
84 super.semantic(sc);
85 if (e1.type) // if not a tuple
86 {
87 e1 = resolveProperties(sc, e1);
88
89 if (!to)
90 {
91 /* Handle cast(const) and cast(immutable), etc.
92 */
93 to = e1.type.castMod(mod);
94 }
95 else
96 to = to.semantic(loc, sc);
97
98 if (!to.equals(e1.type))
99 {
100 e = op_overload(sc);
101 if (e)
102 {
103 return e.implicitCastTo(sc, to);
104 }
105 }
106
107 Type t1b = e1.type.toBasetype();
108 Type tob = to.toBasetype();
109 if (tob.ty == TY.Tstruct &&
110 !tob.equals(t1b) &&
111 (cast(TypeStruct)tob).sym.search(Loc(0), Id.call, 0)
112 )
113 {
114 /* Look to replace:
115 * cast(S)t
116 * with:
117 * S(t)
118 */
119
120 // Rewrite as to.call(e1)
121 e = new TypeExp(loc, to);
122 e = new DotIdExp(loc, e, Id.call);
123 e = new CallExp(loc, e, e1);
124 e = e.semantic(sc);
125 return e;
126 }
127 }
128 else if (!to)
129 { error("cannot cast tuple");
130 to = Type.terror;
131 }
132
133 if (global.params.safe && !sc.module_.safe && !sc.intypeof)
134 { // Disallow unsafe casts
135 Type tob = to.toBasetype();
136 Type t1b = e1.type.toBasetype();
137 if (!t1b.isMutable() && tob.isMutable())
138 { // Cast not mutable to mutable
139 Lunsafe:
140 error("cast from %s to %s not allowed in safe mode", e1.type.toChars(), to.toChars());
141 }
142 else if (t1b.isShared() && !tob.isShared())
143 // Cast away shared
144 goto Lunsafe;
145 else if (tob.ty == TY.Tpointer)
146 { if (t1b.ty != TY.Tpointer)
147 goto Lunsafe;
148 Type tobn = tob.nextOf().toBasetype();
149 Type t1bn = t1b.nextOf().toBasetype();
150
151 if (!t1bn.isMutable() && tobn.isMutable())
152 // Cast away pointer to not mutable
153 goto Lunsafe;
154
155 if (t1bn.isShared() && !tobn.isShared())
156 // Cast away pointer to shared
157 goto Lunsafe;
158
159 if (tobn.isTypeBasic() && tobn.size() < t1bn.size()) {
160 // Allow things like casting a long* to an int*
161 ;
162 } else if (tobn.ty != TY.Tvoid) {
163 // Cast to a pointer other than void*
164 goto Lunsafe;
165 }
166 }
167
168 // BUG: Check for casting array types, such as void[] to int*[]
169 }
170
171 e = e1.castTo(sc, to);
172 return e;
173 }
174
175 MATCH implicitConvTo(Type t)
176 {
177 static if (false) {
178 printf("CastExp::implicitConvTo(this=%s, type=%s, t=%s)\n", toChars(), type.toChars(), t.toChars());
179 }
180 MATCH result = type.implicitConvTo(t);
181
182 if (result == MATCHnomatch)
183 {
184 if (t.isintegral() &&
185 e1.type.isintegral() &&
186 e1.implicitConvTo(t) != MATCHnomatch)
187 result = MATCHconvert;
188 else
189 result = Expression.implicitConvTo(t);
190 }
191 return result;
192 }
193
194 IntRange getIntRange()
195 {
196 assert(false);
197 }
198
199 Expression optimize(int result)
200 {
201 //printf("CastExp.optimize(result = %d) %s\n", result, toChars());
202 //printf("from %s to %s\n", type.toChars(), to.toChars());
203 //printf("from %s\n", type.toChars());
204 //printf("e1.type %s\n", e1.type.toChars());
205 //printf("type = %p\n", type);
206 assert(type);
207 TOK op1 = e1.op;
208
209 Expression e1old = e1;
210 e1 = e1.optimize(result);
211 e1 = fromConstInitializer(result, e1);
212
213 if (e1 == e1old &&
214 e1.op == TOK.TOKarrayliteral &&
215 type.toBasetype().ty == TY.Tpointer &&
216 e1.type.toBasetype().ty != TY.Tsarray)
217 {
218 // Casting this will result in the same expression, and
219 // infinite loop because of Expression.implicitCastTo()
220 return this; // no change
221 }
222
223 if ((e1.op == TOK.TOKstring || e1.op == TOK.TOKarrayliteral) &&
224 (type.ty == TY.Tpointer || type.ty == TY.Tarray) &&
225 e1.type.nextOf().size() == type.nextOf().size()
226 )
227 {
228 Expression e = e1.castTo(null, type);
229
230 static if (false) {
231 printf(" returning1 %s\n", e.toChars());
232 }
233 return e;
234 }
235
236 if (e1.op == TOK.TOKstructliteral &&
237 e1.type.implicitConvTo(type) >= MATCH.MATCHconst)
238 {
239 e1.type = type;
240 static if (false) {
241 printf(" returning2 %s\n", e1.toChars());
242 }
243 return e1;
244 }
245
246 /* The first test here is to prevent infinite loops
247 */
248 if (op1 != TOK.TOKarrayliteral && e1.op == TOK.TOKarrayliteral)
249 return e1.castTo(null, to);
250 if (e1.op == TOK.TOKnull &&
251 (type.ty == TY.Tpointer || type.ty == TY.Tclass || type.ty == TY.Tarray))
252 {
253 e1.type = type;
254 static if (false) {
255 printf(" returning3 %s\n", e1.toChars());
256 }
257 return e1;
258 }
259
260 if (result & WANT.WANTflags && type.ty == TY.Tclass && e1.type.ty == TY.Tclass)
261 {
262 // See if we can remove an unnecessary cast
263 ClassDeclaration cdfrom;
264 ClassDeclaration cdto;
265 int offset;
266
267 cdfrom = e1.type.isClassHandle();
268 cdto = type.isClassHandle();
269 if (cdto.isBaseOf(cdfrom, &offset) && offset == 0)
270 {
271 e1.type = type;
272 static if (false) {
273 printf(" returning4 %s\n", e1.toChars());
274 }
275 return e1;
276 }
277 }
278
279 // We can convert 'head const' to mutable
280 if (to.constOf().equals(e1.type.constOf()))
281 // if (to.constConv(e1.type) >= MATCHconst)
282 {
283 e1.type = type;
284 static if (false) {
285 printf(" returning5 %s\n", e1.toChars());
286 }
287 return e1;
288 }
289
290 Expression e;
291
292 if (e1.isConst())
293 {
294 if (e1.op == TOK.TOKsymoff)
295 {
296 if (type.size() == e1.type.size() &&
297 type.toBasetype().ty != TY.Tsarray)
298 {
299 e1.type = type;
300 return e1;
301 }
302 return this;
303 }
304 if (to.toBasetype().ty == TY.Tvoid)
305 e = this;
306 else
307 e = Cast(type, to, e1);
308 }
309 else
310 e = this;
311 static if (false) {
312 printf(" returning6 %s\n", e.toChars());
313 }
314 return e;
315 }
316
317 Expression interpret(InterState* istate)
318 {
319 assert(false);
320 }
321
322 bool checkSideEffect(int flag)
323 {
324 assert(false);
325 }
326
327 void checkEscape()
328 {
329 Type tb = type.toBasetype();
330 if (tb.ty == TY.Tarray && e1.op == TOK.TOKvar && e1.type.toBasetype().ty ==TY.Tsarray)
331 {
332 VarExp ve = cast(VarExp)e1;
333 VarDeclaration v = ve.var.isVarDeclaration();
334 if (v)
335 {
336 if (!v.isDataseg() && !v.isParameter())
337 error("escaping reference to local %s", v.toChars());
338 }
339 }
340 }
341
342 void toCBuffer(OutBuffer buf, HdrGenState* hgs)
343 {
344 buf.writestring("cast(");
345 version (DMDV1) {
346 to.toCBuffer(buf, null, hgs);
347 } else {
348 if (to)
349 to.toCBuffer(buf, null, hgs);
350 else
351 {
352 switch (mod)
353 {
354 case MODundefined:
355 break;
356 case MODconst:
357 buf.writestring(Token.tochars[TOKconst]);
358 break;
359 case MODinvariant:
360 buf.writestring(Token.tochars[TOKimmutable]);
361 break;
362 case MODshared:
363 buf.writestring(Token.tochars[TOKshared]);
364 break;
365 case MODshared | MODconst:
366 buf.writestring(Token.tochars[TOKshared]);
367 buf.writeByte(' ');
368 buf.writestring(Token.tochars[TOKconst]);
369 break;
370 default:
371 assert(0);
372 }
373 }
374 }
375 buf.writeByte(')');
376 expToCBuffer(buf, hgs, e1, precedence[op]);
377 }
378
379 void buildArrayIdent(OutBuffer buf, Expressions arguments)
380 {
381 assert(false);
382 }
383
384 Expression buildArrayLoop(Arguments fparams)
385 {
386 assert(false);
387 }
388
389 static int X(int fty, int tty) {
390 return ((fty) * TY.TMAX + (tty));
391 }
392
393 elem* toElem(IRState* irs)
394 {
395 elem* e;
396 TY fty;
397 TY tty;
398 tym_t ftym;
399 tym_t ttym;
400 OPER eop;
401 Type t;
402 Type tfrom;
403
404 static if (false) {
405 printf("CastExp::toElem()\n");
406 print();
407 printf("\tfrom: %s\n", e1.type.toChars());
408 printf("\tto : %s\n", to.toChars());
409 }
410
411 e = e1.toElem(irs);
412 tfrom = e1.type.toBasetype();
413 t = to.toBasetype(); // skip over typedef's
414 if (t.equals(tfrom))
415 goto Lret;
416
417 fty = tfrom.ty;
418 //printf("fty = %d\n", fty);
419 tty = t.ty;
420
421 if (tty == TY.Tpointer && fty == TY.Tarray
422 ///static if (false) {
423 /// && (t.next.ty == Tvoid || t.next.equals(e1.type.next))
424 ///}
425 )
426 {
427 if (e.Eoper == OPER.OPvar)
428 {
429 // e1 . *(&e1 + 4)
430 e = el_una(OPER.OPaddr, TYM.TYnptr, e);
431 e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, 4));
432 e = el_una(OPER.OPind, t.totym(),e);
433 }
434 else
435 {
436 // e1 . (unsigned)(e1 >> 32)
437 e = el_bin(OPER.OPshr, TYM.TYullong, e, el_long(TYM.TYint, 32));
438 e = el_una(OPER.OP64_32, t.totym(), e);
439 }
440 goto Lret;
441 }
442
443 if (tty == TY.Tpointer && fty == TY.Tsarray
444 ///static if (false) {
445 /// && (t.next.ty == Tvoid || t.next.equals(e1.type.next))
446 ///}
447 )
448 {
449 // e1 . &e1
450 e = el_una(OPER.OPaddr, TYM.TYnptr, e);
451 goto Lret;
452 }
453
454 // Convert from static array to dynamic array
455 if (tty == TY.Tarray && fty == TY.Tsarray)
456 {
457 e = sarray_toDarray(loc, tfrom, t, e);
458 goto Lret;
459 }
460
461 // Convert from dynamic array to dynamic array
462 if (tty == TY.Tarray && fty == TY.Tarray)
463 {
464 uint fsize = cast(uint)tfrom.nextOf().size();
465 uint tsize = cast(uint)t.nextOf().size();
466
467 if (fsize != tsize)
468 {
469 elem* ep = el_params(e, el_long(TYM.TYint, fsize), el_long(TYM.TYint, tsize), null);
470 e = el_bin(OPER.OPcall, type.totym(), el_var(rtlsym[RTLSYM.RTLSYM_ARRAYCAST]), ep);
471 }
472 goto Lret;
473 }
474
475 static if (false) {
476 // Convert from dynamic array string literal to static array
477 if (tty == TY.Tsarray && fty == TY.Tarray && e1.op == TOK.TOKstring)
478 {
479 goto Lret; // treat as a 'paint'
480 }
481 }
482
483 // Casting from base class to derived class requires a runtime check
484 if (fty == TY.Tclass && tty == TY.Tclass)
485 {
486 // Casting from derived class to base class is a no-op
487 ClassDeclaration cdfrom;
488 ClassDeclaration cdto;
489 int offset;
490 int rtl = RTLSYM.RTLSYM_DYNAMIC_CAST;
491
492 cdfrom = tfrom.isClassHandle();
493 cdto = t.isClassHandle();
494 if (cdfrom.isInterfaceDeclaration())
495 {
496 rtl = RTLSYM.RTLSYM_INTERFACE_CAST;
497 if (cdfrom.isCPPinterface())
498 {
499 if (cdto.isCPPinterface())
500 {
501 /* Casting from a C++ interface to a C++ interface
502 * is always a 'paint' operation
503 */
504 goto Lret; // no-op
505 }
506
507 /* Casting from a C++ interface to a class
508 * always results in null because there is no runtime
509 * information available to do it.
510 *
511 * Casting from a C++ interface to a non-C++ interface
512 * always results in null because there's no way one
513 * can be derived from the other.
514 */
515 e = el_bin(OPER.OPcomma, TYM.TYnptr, e, el_long(TYM.TYnptr, 0));
516 goto Lret;
517 }
518 }
519 if (cdto.isBaseOf(cdfrom, &offset) && offset != OFFSET_RUNTIME)
520 {
521 /* The offset from cdfrom=>cdto is known at compile time.
522 */
523
524 //printf("offset = %d\n", offset);
525 if (offset)
526 {
527 /* Rewrite cast as (e ? e + offset : null)
528 */
529 elem* etmp;
530 elem* ex;
531
532 if (e1.op == TOK.TOKthis)
533 {
534 // Assume 'this' is never null, so skip null check
535 e = el_bin(OPER.OPadd, TYM.TYnptr, e, el_long(TYM.TYint, offset));
536 }
537 else
538 {
539 etmp = el_same(&e);
540 ex = el_bin(OPER.OPadd, TYM.TYnptr, etmp, el_long(TYM.TYint, offset));
541 ex = el_bin(OPER.OPcolon, TYM.TYnptr, ex, el_long(TYM.TYnptr, 0));
542 e = el_bin(OPER.OPcond, TYM.TYnptr, e, ex);
543 }
544 }
545 goto Lret; // no-op
546 }
547
548 /* The offset from cdfrom=>cdto can only be determined at runtime.
549 */
550 elem* ep;
551
552 ep = el_param(el_ptr(cdto.toSymbol()), e);
553 e = el_bin(OPER.OPcall, TYM.TYnptr, el_var(rtlsym[rtl]), ep);
554 goto Lret;
555 }
556
557 ftym = e.Ety;
558 ttym = t.totym();
559 if (ftym == ttym)
560 goto Lret;
561
562 switch (tty)
563 {
564 case TY.Tpointer:
565 if (fty == TY.Tdelegate)
566 goto Lpaint;
567 tty = TY.Tuns32;
568 break;
569
570 case TY.Tchar:
571 tty = TY.Tuns8;
572 break;
573 case TY.Twchar:
574 tty = TY.Tuns16;
575 break;
576 case TY.Tdchar:
577 tty = TY.Tuns32;
578 break;
579 case TY.Tvoid:
580 goto Lpaint;
581
582 case TY.Tbool:
583 {
584 // Construct e?true:false
585 elem* eq;
586
587 e = el_una(OPER.OPbool, ttym, e);
588 goto Lret;
589 }
590
591 default:
592 break; ///
593 }
594
595 switch (fty)
596 {
597 case TY.Tpointer: fty = TY.Tuns32; break;
598 case TY.Tchar: fty = TY.Tuns8; break;
599 case TY.Twchar: fty = TY.Tuns16; break;
600 case TY.Tdchar: fty = TY.Tuns32; break;
601 default: break; ///
602 }
603
604 Lagain:
605 switch (X(fty,tty))
606 {
607 static if (false) {
608 case X(TY.Tbit,TY.Tint8):
609 case X(TY.Tbit,TY.Tuns8):
610 goto Lpaint;
611 case X(TY.Tbit,TY.Tint16):
612 case X(TY.Tbit,TY.Tuns16):
613 case X(TY.Tbit,TY.Tint32):
614 case X(TY.Tbit,TY.Tuns32):
615 eop = OPu8_16;
616 goto Leop;
617 case X(TY.Tbit,TY.Tint64):
618 case X(TY.Tbit,TY.Tuns64):
619 case X(TY.Tbit,TY.Tfloat32):
620 case X(TY.Tbit,TY.Tfloat64):
621 case X(TY.Tbit,TY.Tfloat80):
622 case X(TY.Tbit,TY.Tcomplex32):
623 case X(TY.Tbit,TY.Tcomplex64):
624 case X(TY.Tbit,TY.Tcomplex80):
625 e = el_una(OPER.OPu8_16, TYM.TYuint, e);
626 fty = TY.Tuns32;
627 goto Lagain;
628 case X(Tbit,Timaginary32):
629 case X(Tbit,Timaginary64):
630 case X(Tbit,Timaginary80):
631 goto Lzero;
632 }
633 /* ============================= */
634
635 case X(TY.Tbool,TY.Tint8):
636 case X(TY.Tbool,TY.Tuns8):
637 goto Lpaint;
638 case X(TY.Tbool,TY.Tint16):
639 case X(TY.Tbool,TY.Tuns16):
640 case X(TY.Tbool,TY.Tint32):
641 case X(TY.Tbool,TY.Tuns32):
642 eop = OPER.OPu8_16;
643 goto Leop;
644 case X(TY.Tbool,TY.Tint64):
645 case X(TY.Tbool,TY.Tuns64):
646 case X(TY.Tbool,TY.Tfloat32):
647 case X(TY.Tbool,TY.Tfloat64):
648 case X(TY.Tbool,TY.Tfloat80):
649 case X(TY.Tbool,TY.Tcomplex32):
650 case X(TY.Tbool,TY.Tcomplex64):
651 case X(TY.Tbool,TY.Tcomplex80):
652 e = el_una(OPER.OPu8_16, TYM.TYuint, e);
653 fty = TY.Tuns32;
654 goto Lagain;
655 case X(TY.Tbool,TY.Timaginary32):
656 case X(TY.Tbool,TY.Timaginary64):
657 case X(TY.Tbool,TY.Timaginary80):
658 goto Lzero;
659
660 /* ============================= */
661
662 case X(TY.Tint8,TY.Tuns8):
663 goto Lpaint;
664 case X(TY.Tint8,TY.Tint16):
665 case X(TY.Tint8,TY.Tuns16):
666 case X(TY.Tint8,TY.Tint32):
667 case X(TY.Tint8,TY.Tuns32):
668 eop = OPER.OPs8_16;
669 goto Leop;
670 case X(TY.Tint8,TY.Tint64):
671 case X(TY.Tint8,TY.Tuns64):
672 case X(TY.Tint8,TY.Tfloat32):
673 case X(TY.Tint8,TY.Tfloat64):
674 case X(TY.Tint8,TY.Tfloat80):
675 case X(TY.Tint8,TY.Tcomplex32):
676 case X(TY.Tint8,TY.Tcomplex64):
677 case X(TY.Tint8,TY.Tcomplex80):
678 e = el_una(OPER.OPs8_16, TYM.TYint, e);
679 fty = TY.Tint32;
680 goto Lagain;
681 case X(TY.Tint8,TY.Timaginary32):
682 case X(TY.Tint8,TY.Timaginary64):
683 case X(TY.Tint8,TY.Timaginary80):
684 goto Lzero;
685
686 /* ============================= */
687
688 case X(TY.Tuns8,TY.Tint8):
689 goto Lpaint;
690 case X(TY.Tuns8,TY.Tint16):
691 case X(TY.Tuns8,TY.Tuns16):
692 case X(TY.Tuns8,TY.Tint32):
693 case X(TY.Tuns8,TY.Tuns32):
694 eop = OPER.OPu8_16;
695 goto Leop;
696 case X(TY.Tuns8,TY.Tint64):
697 case X(TY.Tuns8,TY.Tuns64):
698 case X(TY.Tuns8,TY.Tfloat32):
699 case X(TY.Tuns8,TY.Tfloat64):
700 case X(TY.Tuns8,TY.Tfloat80):
701 case X(TY.Tuns8,TY.Tcomplex32):
702 case X(TY.Tuns8,TY.Tcomplex64):
703 case X(TY.Tuns8,TY.Tcomplex80):
704 e = el_una(OPER.OPu8_16, TYM.TYuint, e);
705 fty = TY.Tuns32;
706 goto Lagain;
707 case X(TY.Tuns8,TY.Timaginary32):
708 case X(TY.Tuns8,TY.Timaginary64):
709 case X(TY.Tuns8,TY.Timaginary80):
710 goto Lzero;
711
712 /* ============================= */
713
714 case X(TY.Tint16,TY.Tint8):
715 case X(TY.Tint16,TY.Tuns8):
716 eop = OPER.OP16_8;
717 goto Leop;
718 case X(TY.Tint16,TY.Tuns16):
719 goto Lpaint;
720 case X(TY.Tint16,TY.Tint32):
721 case X(TY.Tint16,TY.Tuns32):
722 eop = OPER.OPs16_32;
723 goto Leop;
724 case X(TY.Tint16,TY.Tint64):
725 case X(TY.Tint16,TY.Tuns64):
726 e = el_una(OPER.OPs16_32, TYM.TYint, e);
727 fty = TY.Tint32;
728 goto Lagain;
729 case X(TY.Tint16,TY.Tfloat32):
730 case X(TY.Tint16,TY.Tfloat64):
731 case X(TY.Tint16,TY.Tfloat80):
732 case X(TY.Tint16,TY.Tcomplex32):
733 case X(TY.Tint16,TY.Tcomplex64):
734 case X(TY.Tint16,TY.Tcomplex80):
735 e = el_una(OPER.OPs16_d, TYM.TYdouble, e);
736 fty = TY.Tfloat64;
737 goto Lagain;
738 case X(TY.Tint16,TY.Timaginary32):
739 case X(TY.Tint16,TY.Timaginary64):
740 case X(TY.Tint16,TY.Timaginary80):
741 goto Lzero;
742
743 /* ============================= */
744
745 case X(TY.Tuns16,TY.Tint8):
746 case X(TY.Tuns16,TY.Tuns8):
747 eop = OPER.OP16_8;
748 goto Leop;
749 case X(TY.Tuns16,TY.Tint16):
750 goto Lpaint;
751 case X(TY.Tuns16,TY.Tint32):
752 case X(TY.Tuns16,TY.Tuns32):
753 eop = OPER.OPu16_32;
754 goto Leop;
755 case X(TY.Tuns16,TY.Tint64):
756 case X(TY.Tuns16,TY.Tuns64):
757 case X(TY.Tuns16,TY.Tfloat64):
758 case X(TY.Tuns16,TY.Tfloat32):
759 case X(TY.Tuns16,TY.Tfloat80):
760 case X(TY.Tuns16,TY.Tcomplex32):
761 case X(TY.Tuns16,TY.Tcomplex64):
762 case X(TY.Tuns16,TY.Tcomplex80):
763 e = el_una(OPER.OPu16_32, TYM.TYuint, e);
764 fty = TY.Tuns32;
765 goto Lagain;
766 case X(TY.Tuns16,TY.Timaginary32):
767 case X(TY.Tuns16,TY.Timaginary64):
768 case X(TY.Tuns16,TY.Timaginary80):
769 goto Lzero;
770
771 /* ============================= */
772
773 case X(TY.Tint32,TY.Tint8):
774 case X(TY.Tint32,TY.Tuns8):
775 e = el_una(OPER.OP32_16, TYM.TYshort, e);
776 fty = TY.Tint16;
777 goto Lagain;
778 case X(TY.Tint32,TY.Tint16):
779 case X(TY.Tint32,TY.Tuns16):
780 eop = OPER.OP32_16;
781 goto Leop;
782 case X(TY.Tint32,TY.Tuns32):
783 goto Lpaint;
784 case X(TY.Tint32,TY.Tint64):
785 case X(TY.Tint32,TY.Tuns64):
786 eop = OPER.OPs32_64;
787 goto Leop;
788 case X(TY.Tint32,TY.Tfloat32):
789 case X(TY.Tint32,TY.Tfloat64):
790 case X(TY.Tint32,TY.Tfloat80):
791 case X(TY.Tint32,TY.Tcomplex32):
792 case X(TY.Tint32,TY.Tcomplex64):
793 case X(TY.Tint32,TY.Tcomplex80):
794 e = el_una(OPER.OPs32_d, TYM.TYdouble, e);
795 fty = TY.Tfloat64;
796 goto Lagain;
797 case X(TY.Tint32,TY.Timaginary32):
798 case X(TY.Tint32,TY.Timaginary64):
799 case X(TY.Tint32,TY.Timaginary80):
800 goto Lzero;
801
802 /* ============================= */
803
804 case X(TY.Tuns32,TY.Tint8):
805 case X(TY.Tuns32,TY.Tuns8):
806 e = el_una(OPER.OP32_16, TYM.TYshort, e);
807 fty = TY.Tuns16;
808 goto Lagain;
809 case X(TY.Tuns32,TY.Tint16):
810 case X(TY.Tuns32,TY.Tuns16):
811 eop = OPER.OP32_16;
812 goto Leop;
813 case X(TY.Tuns32,TY.Tint32):
814 goto Lpaint;
815 case X(TY.Tuns32,TY.Tint64):
816 case X(TY.Tuns32,TY.Tuns64):
817 eop = OPER.OPu32_64;
818 goto Leop;
819 case X(TY.Tuns32,TY.Tfloat32):
820 case X(TY.Tuns32,TY.Tfloat64):
821 case X(TY.Tuns32,TY.Tfloat80):
822 case X(TY.Tuns32,TY.Tcomplex32):
823 case X(TY.Tuns32,TY.Tcomplex64):
824 case X(TY.Tuns32,TY.Tcomplex80):
825 e = el_una(OPER.OPu32_d, TYM.TYdouble, e);
826 fty = TY.Tfloat64;
827 goto Lagain;
828 case X(TY.Tuns32,TY.Timaginary32):
829 case X(TY.Tuns32,TY.Timaginary64):
830 case X(TY.Tuns32,TY.Timaginary80):
831 goto Lzero;
832
833 /* ============================= */
834
835 case X(TY.Tint64,TY.Tint8):
836 case X(TY.Tint64,TY.Tuns8):
837 case X(TY.Tint64,TY.Tint16):
838 case X(TY.Tint64,TY.Tuns16):
839 e = el_una(OPER.OP64_32, TYM.TYint, e);
840 fty = TY.Tint32;
841 goto Lagain;
842 case X(TY.Tint64,TY.Tint32):
843 case X(TY.Tint64,TY.Tuns32):
844 eop = OPER.OP64_32;
845 goto Leop;
846 case X(TY.Tint64,TY.Tuns64):
847 goto Lpaint;
848 case X(TY.Tint64,TY.Tfloat32):
849 case X(TY.Tint64,TY.Tfloat64):
850 case X(TY.Tint64,TY.Tfloat80):
851 case X(TY.Tint64,TY.Tcomplex32):
852 case X(TY.Tint64,TY.Tcomplex64):
853 case X(TY.Tint64,TY.Tcomplex80):
854 e = el_una(OPER.OPs64_d, TYM.TYdouble, e);
855 fty = TY.Tfloat64;
856 goto Lagain;
857 case X(TY.Tint64,TY.Timaginary32):
858 case X(TY.Tint64,TY.Timaginary64):
859 case X(TY.Tint64,TY.Timaginary80):
860 goto Lzero;
861
862 /* ============================= */
863
864 case X(TY.Tuns64,TY.Tint8):
865 case X(TY.Tuns64,TY.Tuns8):
866 case X(TY.Tuns64,TY.Tint16):
867 case X(TY.Tuns64,TY.Tuns16):
868 e = el_una(OPER.OP64_32, TYM.TYint, e);
869 fty = TY.Tint32;
870 goto Lagain;
871 case X(TY.Tuns64,TY.Tint32):
872 case X(TY.Tuns64,TY.Tuns32):
873 eop = OPER.OP64_32;
874 goto Leop;
875 case X(TY.Tuns64,TY.Tint64):
876 goto Lpaint;
877 case X(TY.Tuns64,TY.Tfloat32):
878 case X(TY.Tuns64,TY.Tfloat64):
879 case X(TY.Tuns64,TY.Tfloat80):
880 case X(TY.Tuns64,TY.Tcomplex32):
881 case X(TY.Tuns64,TY.Tcomplex64):
882 case X(TY.Tuns64,TY.Tcomplex80):
883 e = el_una(OPER.OPu64_d, TYM.TYdouble, e);
884 fty = TY.Tfloat64;
885 goto Lagain;
886 case X(TY.Tuns64,TY.Timaginary32):
887 case X(TY.Tuns64,TY.Timaginary64):
888 case X(TY.Tuns64,TY.Timaginary80):
889 goto Lzero;
890
891 /* ============================= */
892
893 case X(TY.Tfloat32,TY.Tint8):
894 case X(TY.Tfloat32,TY.Tuns8):
895 case X(TY.Tfloat32,TY.Tint16):
896 case X(TY.Tfloat32,TY.Tuns16):
897 case X(TY.Tfloat32,TY.Tint32):
898 case X(TY.Tfloat32,TY.Tuns32):
899 case X(TY.Tfloat32,TY.Tint64):
900 case X(TY.Tfloat32,TY.Tuns64):
901 case X(TY.Tfloat32,TY.Tfloat80):
902 e = el_una(OPER.OPf_d, TYM.TYdouble, e);
903 fty = TY.Tfloat64;
904 goto Lagain;
905 case X(TY.Tfloat32,TY.Tfloat64):
906 eop = OPER.OPf_d;
907 goto Leop;
908 case X(TY.Tfloat32,TY.Timaginary32):
909 goto Lzero;
910 case X(TY.Tfloat32,TY.Timaginary64):
911 goto Lzero;
912 case X(TY.Tfloat32,TY.Timaginary80):
913 goto Lzero;
914 case X(TY.Tfloat32,TY.Tcomplex32):
915 case X(TY.Tfloat32,TY.Tcomplex64):
916 case X(TY.Tfloat32,TY.Tcomplex80):
917 e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYifloat,0),e);
918 fty = TY.Tcomplex32;
919 goto Lagain;
920
921 /* ============================= */
922
923 case X(TY.Tfloat64,TY.Tint8):
924 case X(TY.Tfloat64,TY.Tuns8):
925 e = el_una(OPER.OPd_s16, TYM.TYshort, e);
926 fty = TY.Tint16;
927 goto Lagain;
928 case X(TY.Tfloat64,TY.Tint16):
929 eop = OPER.OPd_s16;
930 goto Leop;
931 case X(TY.Tfloat64,TY.Tuns16):
932 eop = OPER.OPd_u16;
933 goto Leop;
934 case X(TY.Tfloat64,TY.Tint32):
935 eop = OPER.OPd_s32;
936 goto Leop;
937 case X(TY.Tfloat64,TY.Tuns32):
938 eop = OPER.OPd_u32;
939 goto Leop;
940 case X(TY.Tfloat64,TY.Tint64):
941 eop = OPER.OPd_s64;
942 goto Leop;
943 case X(TY.Tfloat64,TY.Tuns64):
944 eop = OPER.OPd_u64;
945 goto Leop;
946 case X(TY.Tfloat64,TY.Tfloat32):
947 eop = OPER.OPd_f;
948 goto Leop;
949 case X(TY.Tfloat64,TY.Tfloat80):
950 eop = OPER.OPd_ld;
951 goto Leop;
952 case X(TY.Tfloat64,TY.Timaginary32):
953 goto Lzero;
954 case X(TY.Tfloat64,TY.Timaginary64):
955 goto Lzero;
956 case X(TY.Tfloat64,TY.Timaginary80):
957 goto Lzero;
958 case X(TY.Tfloat64,TY.Tcomplex32):
959 case X(TY.Tfloat64,TY.Tcomplex64):
960 case X(TY.Tfloat64,TY.Tcomplex80):
961 e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYidouble,0),e);
962 fty = TY.Tcomplex64;
963 goto Lagain;
964
965 /* ============================= */
966
967 case X(TY.Tfloat80,TY.Tint8):
968 case X(TY.Tfloat80,TY.Tuns8):
969 case X(TY.Tfloat80,TY.Tint16):
970 case X(TY.Tfloat80,TY.Tuns16):
971 case X(TY.Tfloat80,TY.Tint32):
972 case X(TY.Tfloat80,TY.Tuns32):
973 case X(TY.Tfloat80,TY.Tint64):
974 case X(TY.Tfloat80,TY.Tfloat32):
975 e = el_una(OPER.OPld_d, TYM.TYdouble, e);
976 fty = TY.Tfloat64;
977 goto Lagain;
978 case X(TY.Tfloat80,TY.Tuns64):
979 eop = OPER.OPld_u64;
980 goto Leop;
981 case X(TY.Tfloat80,TY.Tfloat64):
982 eop = OPER.OPld_d;
983 goto Leop;
984 case X(TY.Tfloat80,TY.Timaginary32):
985 goto Lzero;
986 case X(TY.Tfloat80,TY.Timaginary64):
987 goto Lzero;
988 case X(TY.Tfloat80,TY.Timaginary80):
989 goto Lzero;
990 case X(TY.Tfloat80,TY.Tcomplex32):
991 case X(TY.Tfloat80,TY.Tcomplex64):
992 case X(TY.Tfloat80,TY.Tcomplex80):
993 e = el_bin(OPER.OPadd,TYM.TYcldouble,e,el_long(TYM.TYildouble,0));
994 fty = TY.Tcomplex80;
995 goto Lagain;
996
997 /* ============================= */
998
999 case X(TY.Timaginary32,TY.Tint8):
1000 case X(TY.Timaginary32,TY.Tuns8):
1001 case X(TY.Timaginary32,TY.Tint16):
1002 case X(TY.Timaginary32,TY.Tuns16):
1003 case X(TY.Timaginary32,TY.Tint32):
1004 case X(TY.Timaginary32,TY.Tuns32):
1005 case X(TY.Timaginary32,TY.Tint64):
1006 case X(TY.Timaginary32,TY.Tuns64):
1007 case X(TY.Timaginary32,TY.Tfloat32):
1008 case X(TY.Timaginary32,TY.Tfloat64):
1009 case X(TY.Timaginary32,TY.Tfloat80):
1010 goto Lzero;
1011 case X(TY.Timaginary32,TY.Timaginary64):
1012 eop = OPER.OPf_d;
1013 goto Leop;
1014 case X(TY.Timaginary32,TY.Timaginary80):
1015 e = el_una(OPER.OPf_d, TYM.TYidouble, e);
1016 fty = TY.Timaginary64;
1017 goto Lagain;
1018 case X(TY.Timaginary32,TY.Tcomplex32):
1019 case X(TY.Timaginary32,TY.Tcomplex64):
1020 case X(TY.Timaginary32,TY.Tcomplex80):
1021 e = el_bin(OPER.OPadd,TYM.TYcfloat,el_long(TYM.TYfloat,0),e);
1022 fty = TY.Tcomplex32;
1023 goto Lagain;
1024
1025 /* ============================= */
1026
1027 case X(TY.Timaginary64,TY.Tint8):
1028 case X(TY.Timaginary64,TY.Tuns8):
1029 case X(TY.Timaginary64,TY.Tint16):
1030 case X(TY.Timaginary64,TY.Tuns16):
1031 case X(TY.Timaginary64,TY.Tint32):
1032 case X(TY.Timaginary64,TY.Tuns32):
1033 case X(TY.Timaginary64,TY.Tint64):
1034 case X(TY.Timaginary64,TY.Tuns64):
1035 case X(TY.Timaginary64,TY.Tfloat32):
1036 case X(TY.Timaginary64,TY.Tfloat64):
1037 case X(TY.Timaginary64,TY.Tfloat80):
1038 goto Lzero;
1039 case X(TY.Timaginary64,TY.Timaginary32):
1040 eop = OPER.OPd_f;
1041 goto Leop;
1042 case X(TY.Timaginary64,TY.Timaginary80):
1043 eop = OPER.OPd_ld;
1044 goto Leop;
1045 case X(TY.Timaginary64,TY.Tcomplex32):
1046 case X(TY.Timaginary64,TY.Tcomplex64):
1047 case X(TY.Timaginary64,TY.Tcomplex80):
1048 e = el_bin(OPER.OPadd, TYM.TYcdouble, el_long(TYM.TYdouble,0), e);
1049 fty = TY.Tcomplex64;
1050 goto Lagain;
1051
1052 /* ============================= */
1053
1054 case X(TY.Timaginary80,TY.Tint8):
1055 case X(TY.Timaginary80,TY.Tuns8):
1056 case X(TY.Timaginary80,TY.Tint16):
1057 case X(TY.Timaginary80,TY.Tuns16):
1058 case X(TY.Timaginary80,TY.Tint32):
1059 case X(TY.Timaginary80,TY.Tuns32):
1060 case X(TY.Timaginary80,TY.Tint64):
1061 case X(TY.Timaginary80,TY.Tuns64):
1062 case X(TY.Timaginary80,TY.Tfloat32):
1063 case X(TY.Timaginary80,TY.Tfloat64):
1064 case X(TY.Timaginary80,TY.Tfloat80):
1065 goto Lzero;
1066 case X(TY.Timaginary80,TY.Timaginary32):
1067 e = el_una(OPER.OPf_d, TYM.TYidouble, e);
1068 fty = TY.Timaginary64;
1069 goto Lagain;
1070 case X(TY.Timaginary80,TY.Timaginary64):
1071 eop = OPER.OPld_d;
1072 goto Leop;
1073 case X(TY.Timaginary80,TY.Tcomplex32):
1074 case X(TY.Timaginary80,TY.Tcomplex64):
1075 case X(TY.Timaginary80,TY.Tcomplex80):
1076 e = el_bin(OPER.OPadd, TYM.TYcldouble, el_long(TYM.TYldouble,0), e);
1077 fty = TY.Tcomplex80;
1078 goto Lagain;
1079
1080 /* ============================= */
1081
1082 case X(TY.Tcomplex32,TY.Tint8):
1083 case X(TY.Tcomplex32,TY.Tuns8):
1084 case X(TY.Tcomplex32,TY.Tint16):
1085 case X(TY.Tcomplex32,TY.Tuns16):
1086 case X(TY.Tcomplex32,TY.Tint32):
1087 case X(TY.Tcomplex32,TY.Tuns32):
1088 case X(TY.Tcomplex32,TY.Tint64):
1089 case X(TY.Tcomplex32,TY.Tuns64):
1090 case X(TY.Tcomplex32,TY.Tfloat32):
1091 case X(TY.Tcomplex32,TY.Tfloat64):
1092 case X(TY.Tcomplex32,TY.Tfloat80):
1093 e = el_una(OPER.OPc_r, TYM.TYfloat, e);
1094 fty = TY.Tfloat32;
1095 goto Lagain;
1096 case X(TY.Tcomplex32,TY.Timaginary32):
1097 case X(TY.Tcomplex32,TY.Timaginary64):
1098 case X(TY.Tcomplex32,TY.Timaginary80):
1099 e = el_una(OPER.OPc_i, TYM.TYifloat, e);
1100 fty = TY.Timaginary32;
1101 goto Lagain;
1102 case X(TY.Tcomplex32,TY.Tcomplex64):
1103 case X(TY.Tcomplex32,TY.Tcomplex80):
1104 e = el_una(OPER.OPf_d, TYM.TYcdouble, e);
1105 fty = TY.Tcomplex64;
1106 goto Lagain;
1107
1108 /* ============================= */
1109
1110 case X(TY.Tcomplex64,TY.Tint8):
1111 case X(TY.Tcomplex64,TY.Tuns8):
1112 case X(TY.Tcomplex64,TY.Tint16):
1113 case X(TY.Tcomplex64,TY.Tuns16):
1114 case X(TY.Tcomplex64,TY.Tint32):
1115 case X(TY.Tcomplex64,TY.Tuns32):
1116 case X(TY.Tcomplex64,TY.Tint64):
1117 case X(TY.Tcomplex64,TY.Tuns64):
1118 case X(TY.Tcomplex64,TY.Tfloat32):
1119 case X(TY.Tcomplex64,TY.Tfloat64):
1120 case X(TY.Tcomplex64,TY.Tfloat80):
1121 e = el_una(OPER.OPc_r, TYM.TYdouble, e);
1122 fty = TY.Tfloat64;
1123 goto Lagain;
1124 case X(TY.Tcomplex64,TY.Timaginary32):
1125 case X(TY.Tcomplex64,TY.Timaginary64):
1126 case X(TY.Tcomplex64,TY.Timaginary80):
1127 e = el_una(OPER.OPc_i, TYM.TYidouble, e);
1128 fty = TY.Timaginary64;
1129 goto Lagain;
1130 case X(TY.Tcomplex64,TY.Tcomplex32):
1131 eop = OPER.OPd_f;
1132 goto Leop;
1133 case X(TY.Tcomplex64,TY.Tcomplex80):
1134 eop = OPER.OPd_ld;
1135 goto Leop;
1136
1137 /* ============================= */
1138
1139 case X(TY.Tcomplex80,TY.Tint8):
1140 case X(TY.Tcomplex80,TY.Tuns8):
1141 case X(TY.Tcomplex80,TY.Tint16):
1142 case X(TY.Tcomplex80,TY.Tuns16):
1143 case X(TY.Tcomplex80,TY.Tint32):
1144 case X(TY.Tcomplex80,TY.Tuns32):
1145 case X(TY.Tcomplex80,TY.Tint64):
1146 case X(TY.Tcomplex80,TY.Tuns64):
1147 case X(TY.Tcomplex80,TY.Tfloat32):
1148 case X(TY.Tcomplex80,TY.Tfloat64):
1149 case X(TY.Tcomplex80,TY.Tfloat80):
1150 e = el_una(OPER.OPc_r, TYM.TYldouble, e);
1151 fty = TY.Tfloat80;
1152 goto Lagain;
1153 case X(TY.Tcomplex80,TY.Timaginary32):
1154 case X(TY.Tcomplex80,TY.Timaginary64):
1155 case X(TY.Tcomplex80,TY.Timaginary80):
1156 e = el_una(OPER.OPc_i, TYM.TYildouble, e);
1157 fty = TY.Timaginary80;
1158 goto Lagain;
1159 case X(TY.Tcomplex80,TY.Tcomplex32):
1160 case X(TY.Tcomplex80,TY.Tcomplex64):
1161 e = el_una(OPER.OPld_d, TYM.TYcdouble, e);
1162 fty = TY.Tcomplex64;
1163 goto Lagain;
1164
1165 /* ============================= */
1166
1167 default:
1168 if (fty == tty)
1169 goto Lpaint;
1170 //dump(0);
1171 //printf("fty = %d, tty = %d\n", fty, tty);
1172 error("e2ir: cannot cast from %s to %s", e1.type.toChars(), t.toChars());
1173 goto Lzero;
1174
1175 Lzero:
1176 e = el_long(ttym, 0);
1177 break;
1178
1179 Lpaint:
1180 e.Ety = ttym;
1181 break;
1182
1183 Leop:
1184 e = el_una(eop, ttym, e);
1185 break;
1186 }
1187 Lret:
1188 // Adjust for any type paints
1189 t = type.toBasetype();
1190 e.Ety = t.totym();
1191
1192 el_setLoc(e,loc);
1193 return e;
1194 }
1195
1196 Identifier opId()
1197 {
1198 return Id.cast_;
1199 }
1200 }
1201