Mercurial > projects > ldc
annotate dmd/cast.c @ 474:074e74c1a72b
Removed old moduleinit_backend from lphobos it's useless now.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Mon, 04 Aug 2008 19:38:59 +0200 |
parents | aaade6ded589 |
children | 6aee82889553 |
rev | line source |
---|---|
159 | 1 |
336 | 2 // Copyright (c) 1999-2008 by Digital Mars |
159 | 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 | |
215
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
159
diff
changeset
|
46 warning("%s: implicit conversion of expression (%s) of type %s to %s can cause loss of data", |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
159
diff
changeset
|
47 loc.toChars(), toChars(), type->toChars(), t->toChars()); |
159 | 48 } |
49 return castTo(sc, t); | |
50 } | |
51 | |
52 Expression *e = optimize(WANTflags | WANTvalue); | |
53 if (e != this) | |
54 return e->implicitCastTo(sc, t); | |
55 | |
56 #if 0 | |
57 print(); | |
58 type->print(); | |
59 printf("to:\n"); | |
60 t->print(); | |
61 printf("%p %p type: %s to: %s\n", type->deco, t->deco, type->deco, t->deco); | |
62 //printf("%p %p %p\n", type->next->arrayOf(), type, t); | |
63 fflush(stdout); | |
64 #endif | |
65 if (!t->deco) | |
66 { /* Can happen with: | |
67 * enum E { One } | |
68 * class A | |
69 * { static void fork(EDG dg) { dg(E.One); } | |
70 * alias void delegate(E) EDG; | |
71 * } | |
72 * Should eventually make it work. | |
73 */ | |
74 error("forward reference to type %s", t->toChars()); | |
75 } | |
76 else if (t->reliesOnTident()) | |
77 error("forward reference to type %s", t->reliesOnTident()->toChars()); | |
78 | |
79 error("cannot implicitly convert expression (%s) of type %s to %s", | |
80 toChars(), type->toChars(), t->toChars()); | |
81 return castTo(sc, t); | |
82 } | |
83 | |
84 /******************************************* | |
85 * Return !=0 if we can implicitly convert this to type t. | |
86 * Don't do the actual cast. | |
87 */ | |
88 | |
89 MATCH Expression::implicitConvTo(Type *t) | |
90 { | |
91 #if 0 | |
92 printf("Expression::implicitConvTo(this=%s, type=%s, t=%s)\n", | |
93 toChars(), type->toChars(), t->toChars()); | |
94 #endif | |
95 if (!type) | |
96 { error("%s is not an expression", toChars()); | |
97 type = Type::terror; | |
98 } | |
99 if (t->ty == Tbit && isBit()) | |
100 return MATCHconvert; | |
101 Expression *e = optimize(WANTvalue | WANTflags); | |
102 if (e != this) | |
103 { //printf("optimzed to %s\n", e->toChars()); | |
104 return e->implicitConvTo(t); | |
105 } | |
106 MATCH match = type->implicitConvTo(t); | |
107 if (match) | |
108 return match; | |
109 #if 0 | |
110 Type *tb = t->toBasetype(); | |
111 if (tb->ty == Tdelegate) | |
112 { TypeDelegate *td = (TypeDelegate *)tb; | |
113 TypeFunction *tf = (TypeFunction *)td->next; | |
114 | |
115 if (!tf->varargs && | |
116 !(tf->arguments && tf->arguments->dim) | |
117 ) | |
118 { | |
119 match = type->implicitConvTo(tf->next); | |
120 if (match) | |
121 return match; | |
122 if (tf->next->toBasetype()->ty == Tvoid) | |
123 return MATCHconvert; | |
124 } | |
125 } | |
126 #endif | |
127 return MATCHnomatch; | |
128 } | |
129 | |
130 | |
131 MATCH IntegerExp::implicitConvTo(Type *t) | |
132 { | |
133 #if 0 | |
134 printf("IntegerExp::implicitConvTo(this=%s, type=%s, t=%s)\n", | |
135 toChars(), type->toChars(), t->toChars()); | |
136 #endif | |
137 if (type->equals(t)) | |
138 return MATCHexact; | |
139 | |
140 enum TY ty = type->toBasetype()->ty; | |
141 enum TY toty = t->toBasetype()->ty; | |
142 | |
143 if (type->implicitConvTo(t) == MATCHnomatch && t->ty == Tenum) | |
144 { | |
145 return MATCHnomatch; | |
146 } | |
147 | |
148 switch (ty) | |
149 { | |
150 case Tbit: | |
151 case Tbool: | |
152 value &= 1; | |
153 ty = Tint32; | |
154 break; | |
155 | |
156 case Tint8: | |
157 value = (signed char)value; | |
158 ty = Tint32; | |
159 break; | |
160 | |
161 case Tchar: | |
162 case Tuns8: | |
163 value &= 0xFF; | |
164 ty = Tint32; | |
165 break; | |
166 | |
167 case Tint16: | |
168 value = (short)value; | |
169 ty = Tint32; | |
170 break; | |
171 | |
172 case Tuns16: | |
173 case Twchar: | |
174 value &= 0xFFFF; | |
175 ty = Tint32; | |
176 break; | |
177 | |
178 case Tint32: | |
179 value = (int)value; | |
180 break; | |
181 | |
182 case Tuns32: | |
183 case Tdchar: | |
184 value &= 0xFFFFFFFF; | |
185 ty = Tuns32; | |
186 break; | |
187 | |
188 default: | |
189 break; | |
190 } | |
191 | |
192 // Only allow conversion if no change in value | |
193 switch (toty) | |
194 { | |
195 case Tbit: | |
196 case Tbool: | |
197 if ((value & 1) != value) | |
198 goto Lno; | |
199 goto Lyes; | |
200 | |
201 case Tint8: | |
202 if ((signed char)value != value) | |
203 goto Lno; | |
204 goto Lyes; | |
205 | |
206 case Tchar: | |
207 case Tuns8: | |
208 //printf("value = %llu %llu\n", (integer_t)(unsigned char)value, value); | |
209 if ((unsigned char)value != value) | |
210 goto Lno; | |
211 goto Lyes; | |
212 | |
213 case Tint16: | |
214 if ((short)value != value) | |
215 goto Lno; | |
216 goto Lyes; | |
217 | |
218 case Tuns16: | |
219 if ((unsigned short)value != value) | |
220 goto Lno; | |
221 goto Lyes; | |
222 | |
223 case Tint32: | |
224 if (ty == Tuns32) | |
225 { | |
226 } | |
227 else if ((int)value != value) | |
228 goto Lno; | |
229 goto Lyes; | |
230 | |
231 case Tuns32: | |
232 if (ty == Tint32) | |
233 { | |
234 } | |
235 else if ((unsigned)value != value) | |
236 goto Lno; | |
237 goto Lyes; | |
238 | |
239 case Tdchar: | |
240 if (value > 0x10FFFFUL) | |
241 goto Lno; | |
242 goto Lyes; | |
243 | |
244 case Twchar: | |
245 if ((unsigned short)value != value) | |
246 goto Lno; | |
247 goto Lyes; | |
248 | |
249 case Tfloat32: | |
250 { | |
251 volatile float f; | |
252 if (type->isunsigned()) | |
253 { | |
254 f = (float)value; | |
255 if (f != value) | |
256 goto Lno; | |
257 } | |
258 else | |
259 { | |
260 f = (float)(long long)value; | |
261 if (f != (long long)value) | |
262 goto Lno; | |
263 } | |
264 goto Lyes; | |
265 } | |
266 | |
267 case Tfloat64: | |
268 { | |
269 volatile double f; | |
270 if (type->isunsigned()) | |
271 { | |
272 f = (double)value; | |
273 if (f != value) | |
274 goto Lno; | |
275 } | |
276 else | |
277 { | |
278 f = (double)(long long)value; | |
279 if (f != (long long)value) | |
280 goto Lno; | |
281 } | |
282 goto Lyes; | |
283 } | |
284 | |
285 case Tfloat80: | |
286 { | |
287 volatile long double f; | |
288 if (type->isunsigned()) | |
289 { | |
290 f = (long double)value; | |
291 if (f != value) | |
292 goto Lno; | |
293 } | |
294 else | |
295 { | |
296 f = (long double)(long long)value; | |
297 if (f != (long long)value) | |
298 goto Lno; | |
299 } | |
300 goto Lyes; | |
301 } | |
302 } | |
303 return Expression::implicitConvTo(t); | |
304 | |
305 Lyes: | |
306 //printf("MATCHconvert\n"); | |
307 return MATCHconvert; | |
308 | |
309 Lno: | |
310 //printf("MATCHnomatch\n"); | |
311 return MATCHnomatch; | |
312 } | |
313 | |
314 MATCH NullExp::implicitConvTo(Type *t) | |
315 { | |
316 #if 0 | |
317 printf("NullExp::implicitConvTo(this=%s, type=%s, t=%s)\n", | |
318 toChars(), type->toChars(), t->toChars()); | |
319 #endif | |
320 if (this->type->equals(t)) | |
321 return MATCHexact; | |
322 // NULL implicitly converts to any pointer type or dynamic array | |
323 if (type->ty == Tpointer && type->next->ty == Tvoid) | |
324 { | |
325 if (t->ty == Ttypedef) | |
326 t = ((TypeTypedef *)t)->sym->basetype; | |
327 if (t->ty == Tpointer || t->ty == Tarray || | |
328 t->ty == Taarray || t->ty == Tclass || | |
329 t->ty == Tdelegate) | |
330 return committed ? MATCHconvert : MATCHexact; | |
331 } | |
332 return Expression::implicitConvTo(t); | |
333 } | |
334 | |
335 MATCH StringExp::implicitConvTo(Type *t) | |
336 { MATCH m; | |
337 | |
338 #if 0 | |
339 printf("StringExp::implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n", | |
340 toChars(), committed, type->toChars(), t->toChars()); | |
341 #endif | |
342 if (!committed) | |
343 { | |
344 if (!committed && t->ty == Tpointer && t->next->ty == Tvoid) | |
345 { | |
346 return MATCHnomatch; | |
347 } | |
348 if (type->ty == Tsarray || type->ty == Tarray || type->ty == Tpointer) | |
349 { | |
350 if (type->next->ty == Tchar) | |
351 { | |
352 switch (t->ty) | |
353 { | |
354 case Tsarray: | |
355 if (type->ty == Tsarray && | |
356 ((TypeSArray *)type)->dim->toInteger() != | |
357 ((TypeSArray *)t)->dim->toInteger()) | |
358 return MATCHnomatch; | |
359 goto L1; | |
360 case Tarray: | |
361 goto L1; | |
362 case Tpointer: | |
363 L1: | |
364 if (t->next->ty == Tchar) | |
365 return MATCHexact; | |
366 else if (t->next->ty == Twchar) | |
367 return MATCHexact; | |
368 else if (t->next->ty == Tdchar) | |
369 return MATCHexact; | |
370 break; | |
371 } | |
372 } | |
373 } | |
374 } | |
375 return Expression::implicitConvTo(t); | |
376 #if 0 | |
377 m = (MATCH)type->implicitConvTo(t); | |
378 if (m) | |
379 { | |
380 return m; | |
381 } | |
382 | |
383 return MATCHnomatch; | |
384 #endif | |
385 } | |
386 | |
387 MATCH ArrayLiteralExp::implicitConvTo(Type *t) | |
388 { MATCH result = MATCHexact; | |
389 | |
390 Type *typeb = type->toBasetype(); | |
391 Type *tb = t->toBasetype(); | |
392 if ((tb->ty == Tarray || tb->ty == Tsarray) && | |
393 (typeb->ty == Tarray || typeb->ty == Tsarray)) | |
394 { | |
395 if (tb->ty == Tsarray) | |
396 { TypeSArray *tsa = (TypeSArray *)tb; | |
397 if (elements->dim != tsa->dim->toInteger()) | |
398 result = MATCHnomatch; | |
399 } | |
400 | |
401 for (int i = 0; i < elements->dim; i++) | |
402 { Expression *e = (Expression *)elements->data[i]; | |
403 MATCH m = (MATCH)e->implicitConvTo(tb->next); | |
404 if (m < result) | |
405 result = m; // remember worst match | |
406 if (result == MATCHnomatch) | |
407 break; // no need to check for worse | |
408 } | |
409 return result; | |
410 } | |
411 else | |
412 return Expression::implicitConvTo(t); | |
413 } | |
414 | |
415 MATCH AssocArrayLiteralExp::implicitConvTo(Type *t) | |
416 { MATCH result = MATCHexact; | |
417 | |
418 Type *typeb = type->toBasetype(); | |
419 Type *tb = t->toBasetype(); | |
420 if (tb->ty == Taarray && typeb->ty == Taarray) | |
421 { | |
422 for (size_t i = 0; i < keys->dim; i++) | |
423 { Expression *e = (Expression *)keys->data[i]; | |
424 MATCH m = (MATCH)e->implicitConvTo(((TypeAArray *)tb)->key); | |
425 if (m < result) | |
426 result = m; // remember worst match | |
427 if (result == MATCHnomatch) | |
428 break; // no need to check for worse | |
429 e = (Expression *)values->data[i]; | |
430 m = (MATCH)e->implicitConvTo(tb->next); | |
431 if (m < result) | |
432 result = m; // remember worst match | |
433 if (result == MATCHnomatch) | |
434 break; // no need to check for worse | |
435 } | |
436 return result; | |
437 } | |
438 else | |
439 return Expression::implicitConvTo(t); | |
440 } | |
441 | |
442 MATCH AddrExp::implicitConvTo(Type *t) | |
443 { | |
444 #if 0 | |
445 printf("AddrExp::implicitConvTo(this=%s, type=%s, t=%s)\n", | |
446 toChars(), type->toChars(), t->toChars()); | |
447 #endif | |
448 MATCH result; | |
449 | |
450 result = type->implicitConvTo(t); | |
451 //printf("\tresult = %d\n", result); | |
452 | |
453 if (result == MATCHnomatch) | |
454 { | |
455 // Look for pointers to functions where the functions are overloaded. | |
456 VarExp *ve; | |
457 FuncDeclaration *f; | |
458 | |
459 t = t->toBasetype(); | |
460 if (type->ty == Tpointer && type->next->ty == Tfunction && | |
461 t->ty == Tpointer && t->next->ty == Tfunction && | |
462 e1->op == TOKvar) | |
463 { | |
464 ve = (VarExp *)e1; | |
465 f = ve->var->isFuncDeclaration(); | |
466 if (f && f->overloadExactMatch(t->next)) | |
467 result = MATCHexact; | |
468 } | |
469 } | |
470 //printf("\tresult = %d\n", result); | |
471 return result; | |
472 } | |
473 | |
474 MATCH SymOffExp::implicitConvTo(Type *t) | |
475 { | |
476 #if 0 | |
477 printf("SymOffExp::implicitConvTo(this=%s, type=%s, t=%s)\n", | |
478 toChars(), type->toChars(), t->toChars()); | |
479 #endif | |
480 MATCH result; | |
481 | |
482 result = type->implicitConvTo(t); | |
483 //printf("\tresult = %d\n", result); | |
484 | |
485 if (result == MATCHnomatch) | |
486 { | |
487 // Look for pointers to functions where the functions are overloaded. | |
488 FuncDeclaration *f; | |
489 | |
490 t = t->toBasetype(); | |
491 if (type->ty == Tpointer && type->next->ty == Tfunction && | |
492 t->ty == Tpointer && t->next->ty == Tfunction) | |
493 { | |
494 f = var->isFuncDeclaration(); | |
495 if (f && f->overloadExactMatch(t->next)) | |
496 result = MATCHexact; | |
497 } | |
498 } | |
499 //printf("\tresult = %d\n", result); | |
500 return result; | |
501 } | |
502 | |
503 MATCH DelegateExp::implicitConvTo(Type *t) | |
504 { | |
505 #if 0 | |
506 printf("DelegateExp::implicitConvTo(this=%s, type=%s, t=%s)\n", | |
507 toChars(), type->toChars(), t->toChars()); | |
508 #endif | |
509 MATCH result; | |
510 | |
511 result = type->implicitConvTo(t); | |
512 | |
513 if (result == 0) | |
514 { | |
515 // Look for pointers to functions where the functions are overloaded. | |
516 FuncDeclaration *f; | |
517 | |
518 t = t->toBasetype(); | |
519 if (type->ty == Tdelegate && type->next->ty == Tfunction && | |
520 t->ty == Tdelegate && t->next->ty == Tfunction) | |
521 { | |
522 if (func && func->overloadExactMatch(t->next)) | |
523 result = MATCHexact; | |
524 } | |
525 } | |
526 return result; | |
527 } | |
528 | |
529 MATCH CondExp::implicitConvTo(Type *t) | |
530 { | |
531 MATCH m1; | |
532 MATCH m2; | |
533 | |
534 m1 = e1->implicitConvTo(t); | |
535 m2 = e2->implicitConvTo(t); | |
536 | |
537 // Pick the worst match | |
538 return (m1 < m2) ? m1 : m2; | |
539 } | |
540 | |
541 | |
542 /* ==================== castTo ====================== */ | |
543 | |
544 /************************************** | |
545 * Do an explicit cast. | |
546 */ | |
547 | |
548 Expression *Expression::castTo(Scope *sc, Type *t) | |
549 { | |
550 //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars()); | |
551 #if 0 | |
552 printf("Expression::castTo(this=%s, type=%s, t=%s)\n", | |
553 toChars(), type->toChars(), t->toChars()); | |
554 #endif | |
555 if (type == t) | |
556 return this; | |
557 Expression *e = this; | |
558 Type *tb = t->toBasetype(); | |
559 Type *typeb = type->toBasetype(); | |
560 if (tb != typeb) | |
561 { | |
562 // Do (type *) cast of (type [dim]) | |
563 if (tb->ty == Tpointer && | |
564 typeb->ty == Tsarray | |
565 ) | |
566 { | |
567 //printf("Converting [dim] to *\n"); | |
568 | |
569 if (typeb->size(loc) == 0) | |
570 e = new NullExp(loc); | |
571 else | |
572 e = new AddrExp(loc, e); | |
573 } | |
574 #if 0 | |
575 else if (tb->ty == Tdelegate && type->ty != Tdelegate) | |
576 { | |
577 TypeDelegate *td = (TypeDelegate *)tb; | |
578 TypeFunction *tf = (TypeFunction *)td->nextOf(); | |
579 return toDelegate(sc, tf->nextOf()); | |
580 } | |
581 #endif | |
582 else | |
583 { | |
584 e = new CastExp(loc, e, tb); | |
585 } | |
586 } | |
587 else | |
588 { | |
589 e = e->copy(); // because of COW for assignment to e->type | |
590 } | |
591 assert(e != this); | |
592 e->type = t; | |
593 //printf("Returning: %s\n", e->toChars()); | |
594 return e; | |
595 } | |
596 | |
597 | |
598 Expression *RealExp::castTo(Scope *sc, Type *t) | |
599 { Expression *e = this; | |
600 if (type != t) | |
601 { | |
602 if ((type->isreal() && t->isreal()) || | |
603 (type->isimaginary() && t->isimaginary()) | |
604 ) | |
605 { e = copy(); | |
606 e->type = t; | |
607 } | |
608 else | |
609 e = Expression::castTo(sc, t); | |
610 } | |
611 return e; | |
612 } | |
613 | |
614 | |
615 Expression *ComplexExp::castTo(Scope *sc, Type *t) | |
616 { Expression *e = this; | |
617 if (type != t) | |
618 { | |
619 if (type->iscomplex() && t->iscomplex()) | |
620 { e = copy(); | |
621 e->type = t; | |
622 } | |
623 else | |
624 e = Expression::castTo(sc, t); | |
625 } | |
626 return e; | |
627 } | |
628 | |
629 | |
630 Expression *NullExp::castTo(Scope *sc, Type *t) | |
631 { NullExp *e; | |
632 Type *tb; | |
633 | |
634 //printf("NullExp::castTo(t = %p)\n", t); | |
635 if (type == t) | |
636 { | |
637 committed = 1; | |
638 return this; | |
639 } | |
640 e = (NullExp *)copy(); | |
641 e->committed = 1; | |
642 tb = t->toBasetype(); | |
643 e->type = type->toBasetype(); | |
644 if (tb != e->type) | |
645 { | |
646 // NULL implicitly converts to any pointer type or dynamic array | |
647 if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tvoid && | |
648 (tb->ty == Tpointer || tb->ty == Tarray || tb->ty == Taarray || | |
649 tb->ty == Tdelegate)) | |
650 { | |
651 #if 0 | |
652 if (tb->ty == Tdelegate) | |
653 { TypeDelegate *td = (TypeDelegate *)tb; | |
654 TypeFunction *tf = (TypeFunction *)td->nextOf(); | |
655 | |
656 if (!tf->varargs && | |
657 !(tf->arguments && tf->arguments->dim) | |
658 ) | |
659 { | |
660 return Expression::castTo(sc, t); | |
661 } | |
662 } | |
663 #endif | |
664 } | |
665 else | |
666 { | |
667 return e->Expression::castTo(sc, t); | |
668 } | |
669 } | |
670 e->type = t; | |
671 return e; | |
672 } | |
673 | |
674 Expression *StringExp::castTo(Scope *sc, Type *t) | |
675 { | |
676 /* This follows copy-on-write; any changes to 'this' | |
677 * will result in a copy. | |
678 * The this->string member is considered immutable. | |
679 */ | |
680 StringExp *se; | |
681 Type *tb; | |
682 int copied = 0; | |
683 | |
684 //printf("StringExp::castTo(t = %s), '%s' committed = %d\n", t->toChars(), toChars(), committed); | |
685 | |
686 if (!committed && t->ty == Tpointer && t->nextOf()->ty == Tvoid) | |
687 { | |
688 error("cannot convert string literal to void*"); | |
689 } | |
690 | |
691 se = this; | |
692 if (!committed) | |
693 { se = (StringExp *)copy(); | |
694 se->committed = 1; | |
695 copied = 1; | |
696 } | |
697 | |
698 if (type == t) | |
699 { | |
700 return se; | |
701 } | |
702 | |
703 tb = t->toBasetype(); | |
704 //printf("\ttype = %s\n", type->toChars()); | |
705 if (tb->ty == Tdelegate && type->toBasetype()->ty != Tdelegate) | |
706 return Expression::castTo(sc, t); | |
707 | |
708 Type *typeb = type->toBasetype(); | |
709 if (typeb == tb) | |
710 { | |
711 if (!copied) | |
712 { se = (StringExp *)copy(); | |
713 copied = 1; | |
714 } | |
715 se->type = t; | |
716 return se; | |
717 } | |
718 | |
719 if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer) | |
720 { if (!copied) | |
721 { se = (StringExp *)copy(); | |
722 copied = 1; | |
723 } | |
724 goto Lcast; | |
725 } | |
726 if (typeb->ty != Tsarray && typeb->ty != Tarray && typeb->ty != Tpointer) | |
727 { if (!copied) | |
728 { se = (StringExp *)copy(); | |
729 copied = 1; | |
730 } | |
731 goto Lcast; | |
732 } | |
733 | |
734 if (typeb->nextOf()->size() == tb->nextOf()->size()) | |
735 { | |
736 if (!copied) | |
737 { se = (StringExp *)copy(); | |
738 copied = 1; | |
739 } | |
740 if (tb->ty == Tsarray) | |
741 goto L2; // handle possible change in static array dimension | |
742 se->type = t; | |
743 return se; | |
744 } | |
745 | |
746 if (committed) | |
747 goto Lcast; | |
748 | |
749 #define X(tf,tt) ((tf) * 256 + (tt)) | |
750 { | |
751 OutBuffer buffer; | |
752 size_t newlen = 0; | |
753 int tfty = typeb->nextOf()->toBasetype()->ty; | |
754 int ttty = tb->nextOf()->toBasetype()->ty; | |
755 switch (X(tfty, ttty)) | |
756 { | |
757 case X(Tchar, Tchar): | |
758 case X(Twchar,Twchar): | |
759 case X(Tdchar,Tdchar): | |
760 break; | |
761 | |
762 case X(Tchar, Twchar): | |
763 for (size_t u = 0; u < len;) | |
764 { unsigned c; | |
765 char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c); | |
766 if (p) | |
767 error("%s", p); | |
768 else | |
769 buffer.writeUTF16(c); | |
770 } | |
771 newlen = buffer.offset / 2; | |
772 buffer.writeUTF16(0); | |
773 goto L1; | |
774 | |
775 case X(Tchar, Tdchar): | |
776 for (size_t u = 0; u < len;) | |
777 { unsigned c; | |
778 char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c); | |
779 if (p) | |
780 error("%s", p); | |
781 buffer.write4(c); | |
782 newlen++; | |
783 } | |
784 buffer.write4(0); | |
785 goto L1; | |
786 | |
787 case X(Twchar,Tchar): | |
788 for (size_t u = 0; u < len;) | |
789 { unsigned c; | |
790 char *p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c); | |
791 if (p) | |
792 error("%s", p); | |
793 else | |
794 buffer.writeUTF8(c); | |
795 } | |
796 newlen = buffer.offset; | |
797 buffer.writeUTF8(0); | |
798 goto L1; | |
799 | |
800 case X(Twchar,Tdchar): | |
801 for (size_t u = 0; u < len;) | |
802 { unsigned c; | |
803 char *p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c); | |
804 if (p) | |
805 error("%s", p); | |
806 buffer.write4(c); | |
807 newlen++; | |
808 } | |
809 buffer.write4(0); | |
810 goto L1; | |
811 | |
812 case X(Tdchar,Tchar): | |
813 for (size_t u = 0; u < len; u++) | |
814 { | |
815 unsigned c = ((unsigned *)se->string)[u]; | |
816 if (!utf_isValidDchar(c)) | |
817 error("invalid UCS-32 char \\U%08x", c); | |
818 else | |
819 buffer.writeUTF8(c); | |
820 newlen++; | |
821 } | |
822 newlen = buffer.offset; | |
823 buffer.writeUTF8(0); | |
824 goto L1; | |
825 | |
826 case X(Tdchar,Twchar): | |
827 for (size_t u = 0; u < len; u++) | |
828 { | |
829 unsigned c = ((unsigned *)se->string)[u]; | |
830 if (!utf_isValidDchar(c)) | |
831 error("invalid UCS-32 char \\U%08x", c); | |
832 else | |
833 buffer.writeUTF16(c); | |
834 newlen++; | |
835 } | |
836 newlen = buffer.offset / 2; | |
837 buffer.writeUTF16(0); | |
838 goto L1; | |
839 | |
840 L1: | |
841 if (!copied) | |
842 { se = (StringExp *)copy(); | |
843 copied = 1; | |
844 } | |
845 se->string = buffer.extractData(); | |
846 se->len = newlen; | |
847 se->sz = tb->nextOf()->size(); | |
848 break; | |
849 | |
850 default: | |
851 assert(typeb->nextOf()->size() != tb->nextOf()->size()); | |
852 goto Lcast; | |
853 } | |
854 } | |
855 #undef X | |
856 L2: | |
857 assert(copied); | |
858 | |
859 // See if need to truncate or extend the literal | |
860 if (tb->ty == Tsarray) | |
861 { | |
862 int dim2 = ((TypeSArray *)tb)->dim->toInteger(); | |
863 | |
864 //printf("dim from = %d, to = %d\n", se->len, dim2); | |
865 | |
866 // Changing dimensions | |
867 if (dim2 != se->len) | |
868 { | |
869 // Copy when changing the string literal | |
870 unsigned newsz = se->sz; | |
871 void *s; | |
872 int d; | |
873 | |
874 d = (dim2 < se->len) ? dim2 : se->len; | |
875 s = (unsigned char *)mem.malloc((dim2 + 1) * newsz); | |
876 memcpy(s, se->string, d * newsz); | |
877 // Extend with 0, add terminating 0 | |
878 memset((char *)s + d * newsz, 0, (dim2 + 1 - d) * newsz); | |
879 se->string = s; | |
880 se->len = dim2; | |
881 } | |
882 } | |
883 se->type = t; | |
884 return se; | |
885 | |
886 Lcast: | |
887 Expression *e = new CastExp(loc, se, t); | |
888 e->type = t; // so semantic() won't be run on e | |
889 return e; | |
890 } | |
891 | |
892 Expression *AddrExp::castTo(Scope *sc, Type *t) | |
893 { | |
894 Type *tb; | |
895 | |
896 #if 0 | |
897 printf("AddrExp::castTo(this=%s, type=%s, t=%s)\n", | |
898 toChars(), type->toChars(), t->toChars()); | |
899 #endif | |
900 Expression *e = this; | |
901 | |
902 tb = t->toBasetype(); | |
903 type = type->toBasetype(); | |
904 if (tb != type) | |
905 { | |
906 // Look for pointers to functions where the functions are overloaded. | |
907 VarExp *ve; | |
908 FuncDeclaration *f; | |
909 | |
910 if (type->ty == Tpointer && type->next->ty == Tfunction && | |
911 tb->ty == Tpointer && tb->next->ty == Tfunction && | |
912 e1->op == TOKvar) | |
913 { | |
914 ve = (VarExp *)e1; | |
915 f = ve->var->isFuncDeclaration(); | |
916 if (f) | |
917 { | |
918 f = f->overloadExactMatch(tb->next); | |
919 if (f) | |
920 { | |
921 e = new VarExp(loc, f); | |
922 e->type = f->type; | |
923 e = new AddrExp(loc, e); | |
924 e->type = t; | |
925 return e; | |
926 } | |
927 } | |
928 } | |
929 e = Expression::castTo(sc, t); | |
930 } | |
931 e->type = t; | |
932 return e; | |
933 } | |
934 | |
935 | |
936 Expression *TupleExp::castTo(Scope *sc, Type *t) | |
937 { TupleExp *e = (TupleExp *)copy(); | |
938 e->exps = (Expressions *)exps->copy(); | |
939 for (size_t i = 0; i < e->exps->dim; i++) | |
940 { Expression *ex = (Expression *)e->exps->data[i]; | |
941 ex = ex->castTo(sc, t); | |
942 e->exps->data[i] = (void *)ex; | |
943 } | |
944 return e; | |
945 } | |
946 | |
947 | |
948 Expression *ArrayLiteralExp::castTo(Scope *sc, Type *t) | |
949 { | |
950 #if 0 | |
951 printf("ArrayLiteralExp::castTo(this=%s, type=%s, t=%s)\n", | |
952 toChars(), type->toChars(), t->toChars()); | |
953 #endif | |
954 if (type == t) | |
955 return this; | |
956 ArrayLiteralExp *e = this; | |
957 Type *typeb = type->toBasetype(); | |
958 Type *tb = t->toBasetype(); | |
959 if ((tb->ty == Tarray || tb->ty == Tsarray) && | |
960 (typeb->ty == Tarray || typeb->ty == Tsarray) && | |
961 // Not trying to convert non-void[] to void[] | |
962 !(tb->nextOf()->toBasetype()->ty == Tvoid && typeb->nextOf()->toBasetype()->ty != Tvoid)) | |
963 { | |
964 if (tb->ty == Tsarray) | |
965 { TypeSArray *tsa = (TypeSArray *)tb; | |
966 if (elements->dim != tsa->dim->toInteger()) | |
967 goto L1; | |
968 } | |
969 | |
970 e = (ArrayLiteralExp *)copy(); | |
971 e->elements = (Expressions *)elements->copy(); | |
972 for (int i = 0; i < elements->dim; i++) | |
973 { Expression *ex = (Expression *)elements->data[i]; | |
974 ex = ex->castTo(sc, tb->nextOf()); | |
975 e->elements->data[i] = (void *)ex; | |
976 } | |
977 e->type = t; | |
978 return e; | |
979 } | |
980 if (tb->ty == Tpointer && typeb->ty == Tsarray) | |
981 { | |
982 e = (ArrayLiteralExp *)copy(); | |
983 e->type = typeb->nextOf()->pointerTo(); | |
984 } | |
985 L1: | |
986 return e->Expression::castTo(sc, t); | |
987 } | |
988 | |
989 Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t) | |
990 { | |
991 if (type == t) | |
992 return this; | |
993 AssocArrayLiteralExp *e = this; | |
994 Type *typeb = type->toBasetype(); | |
995 Type *tb = t->toBasetype(); | |
996 if (tb->ty == Taarray && typeb->ty == Taarray && | |
997 tb->nextOf()->toBasetype()->ty != Tvoid) | |
998 { | |
999 e = (AssocArrayLiteralExp *)copy(); | |
1000 e->keys = (Expressions *)keys->copy(); | |
1001 e->values = (Expressions *)values->copy(); | |
1002 assert(keys->dim == values->dim); | |
1003 for (size_t i = 0; i < keys->dim; i++) | |
1004 { Expression *ex = (Expression *)values->data[i]; | |
1005 ex = ex->castTo(sc, tb->nextOf()); | |
1006 e->values->data[i] = (void *)ex; | |
1007 | |
1008 ex = (Expression *)keys->data[i]; | |
1009 ex = ex->castTo(sc, ((TypeAArray *)tb)->index); | |
1010 e->keys->data[i] = (void *)ex; | |
1011 } | |
1012 e->type = t; | |
1013 return e; | |
1014 } | |
1015 L1: | |
1016 return e->Expression::castTo(sc, t); | |
1017 } | |
1018 | |
1019 | |
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 } | |
1153 else if (t2b->ty == Tpointer && t1b->isintegral()) | |
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; | |
1164 #if !IN_LLVM | |
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)); | |
1170 #endif | |
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) | |
336 | 1348 { |
1349 while (1) | |
159 | 1350 { |
336 | 1351 int i1 = e2->implicitConvTo(t1); |
1352 int 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 } | |
159 | 1362 |
336 | 1363 if (i2) |
1364 { | |
1365 goto Lt2; | |
1366 } | |
1367 else if (i1) | |
1368 { | |
1369 goto Lt1; | |
1370 } | |
1371 else if (t1->ty == Tclass && t2->ty == Tclass) | |
1372 { TypeClass *tc1 = (TypeClass *)t1; | |
1373 TypeClass *tc2 = (TypeClass *)t2; | |
1374 | |
1375 /* Pick 'tightest' type | |
1376 */ | |
1377 ClassDeclaration *cd1 = tc1->sym->baseClass; | |
1378 ClassDeclaration *cd2 = tc1->sym->baseClass; | |
1379 | |
1380 if (cd1 && cd2) | |
1381 { t1 = cd1->type; | |
1382 t2 = cd2->type; | |
1383 } | |
1384 else if (cd1) | |
1385 t1 = cd1->type; | |
1386 else if (cd2) | |
1387 t2 = cd2->type; | |
1388 else | |
1389 goto Lincompatible; | |
1390 } | |
1391 else | |
1392 goto Lincompatible; | |
159 | 1393 } |
1394 } | |
1395 else if ((e1->op == TOKstring || e1->op == TOKnull) && e1->implicitConvTo(t2)) | |
1396 { | |
1397 goto Lt2; | |
1398 } | |
1399 //else if (e2->op == TOKstring) { printf("test2\n"); } | |
1400 else if ((e2->op == TOKstring || e2->op == TOKnull) && e2->implicitConvTo(t1)) | |
1401 { | |
1402 goto Lt1; | |
1403 } | |
1404 else if (t1->ty == Tsarray && t2->ty == Tsarray && | |
1405 e2->implicitConvTo(t1->next->arrayOf())) | |
1406 { | |
1407 Lx1: | |
1408 t = t1->next->arrayOf(); | |
1409 e1 = e1->castTo(sc, t); | |
1410 e2 = e2->castTo(sc, t); | |
1411 } | |
1412 else if (t1->ty == Tsarray && t2->ty == Tsarray && | |
1413 e1->implicitConvTo(t2->next->arrayOf())) | |
1414 { | |
1415 Lx2: | |
1416 t = t2->next->arrayOf(); | |
1417 e1 = e1->castTo(sc, t); | |
1418 e2 = e2->castTo(sc, t); | |
1419 } | |
1420 else | |
1421 { | |
1422 Lincompatible: | |
1423 incompatibleTypes(); | |
1424 } | |
1425 Lret: | |
1426 if (!type) | |
1427 type = t; | |
1428 //dump(0); | |
1429 return this; | |
1430 | |
1431 | |
1432 Lt1: | |
1433 e2 = e2->castTo(sc, t1); | |
1434 t = t1; | |
1435 goto Lret; | |
1436 | |
1437 Lt2: | |
1438 e1 = e1->castTo(sc, t2); | |
1439 t = t2; | |
1440 goto Lret; | |
1441 } | |
1442 | |
1443 /*********************************** | |
1444 * Do integral promotions (convertchk). | |
1445 * Don't convert <array of> to <pointer to> | |
1446 */ | |
1447 | |
1448 Expression *Expression::integralPromotions(Scope *sc) | |
1449 { Expression *e; | |
1450 | |
1451 e = this; | |
1452 switch (type->toBasetype()->ty) | |
1453 { | |
1454 case Tvoid: | |
1455 error("void has no value"); | |
1456 break; | |
1457 | |
1458 case Tint8: | |
1459 case Tuns8: | |
1460 case Tint16: | |
1461 case Tuns16: | |
1462 case Tbit: | |
1463 case Tbool: | |
1464 case Tchar: | |
1465 case Twchar: | |
1466 e = e->castTo(sc, Type::tint32); | |
1467 break; | |
1468 | |
1469 case Tdchar: | |
1470 e = e->castTo(sc, Type::tuns32); | |
1471 break; | |
1472 } | |
1473 return e; | |
1474 } | |
1475 |