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