159
|
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)
|
|
550 {
|
|
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
|
|
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)
|
|
562 {
|
|
563 // Do (type *) cast of (type [dim])
|
|
564 if (tb->ty == Tpointer &&
|
|
565 typeb->ty == Tsarray
|
|
566 )
|
|
567 {
|
|
568 //printf("Converting [dim] to *\n");
|
|
569
|
|
570 if (typeb->size(loc) == 0)
|
|
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;
|
|
579 TypeFunction *tf = (TypeFunction *)td->nextOf();
|
|
580 return toDelegate(sc, tf->nextOf());
|
|
581 }
|
|
582 #endif
|
|
583 else
|
|
584 {
|
|
585 e = new CastExp(loc, e, tb);
|
|
586 }
|
|
587 }
|
|
588 else
|
|
589 {
|
|
590 e = e->copy(); // because of COW for assignment to e->type
|
|
591 }
|
|
592 assert(e != this);
|
|
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)
|
|
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;
|
|
613 }
|
|
614
|
|
615
|
|
616 Expression *ComplexExp::castTo(Scope *sc, Type *t)
|
|
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;
|
|
628 }
|
|
629
|
|
630
|
|
631 Expression *NullExp::castTo(Scope *sc, Type *t)
|
|
632 { NullExp *e;
|
|
633 Type *tb;
|
|
634
|
|
635 //printf("NullExp::castTo(t = %p)\n", t);
|
|
636 if (type == t)
|
|
637 {
|
|
638 committed = 1;
|
|
639 return this;
|
|
640 }
|
|
641 e = (NullExp *)copy();
|
|
642 e->committed = 1;
|
|
643 tb = t->toBasetype();
|
|
644 e->type = type->toBasetype();
|
|
645 if (tb != e->type)
|
|
646 {
|
|
647 // NULL implicitly converts to any pointer type or dynamic array
|
|
648 if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tvoid &&
|
|
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;
|
|
655 TypeFunction *tf = (TypeFunction *)td->nextOf();
|
|
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 {
|
|
668 return e->Expression::castTo(sc, t);
|
|
669 }
|
|
670 }
|
|
671 e->type = t;
|
|
672 return e;
|
|
673 }
|
|
674
|
|
675 Expression *StringExp::castTo(Scope *sc, Type *t)
|
|
676 {
|
|
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 */
|
|
681 StringExp *se;
|
|
682 Type *tb;
|
|
683 int copied = 0;
|
|
684
|
|
685 //printf("StringExp::castTo(t = %s), '%s' committed = %d\n", t->toChars(), toChars(), committed);
|
|
686
|
|
687 if (!committed && t->ty == Tpointer && t->nextOf()->ty == Tvoid)
|
|
688 {
|
|
689 error("cannot convert string literal to void*");
|
|
690 }
|
|
691
|
|
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
|
|
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
|
|
709 Type *typeb = type->toBasetype();
|
|
710 if (typeb == tb)
|
|
711 {
|
|
712 if (!copied)
|
|
713 { se = (StringExp *)copy();
|
|
714 copied = 1;
|
|
715 }
|
|
716 se->type = t;
|
|
717 return se;
|
|
718 }
|
|
719
|
|
720 if (tb->ty != Tsarray && tb->ty != Tarray && tb->ty != Tpointer)
|
|
721 { if (!copied)
|
|
722 { se = (StringExp *)copy();
|
|
723 copied = 1;
|
|
724 }
|
|
725 goto Lcast;
|
|
726 }
|
|
727 if (typeb->ty != Tsarray && typeb->ty != Tarray && typeb->ty != Tpointer)
|
|
728 { if (!copied)
|
|
729 { se = (StringExp *)copy();
|
|
730 copied = 1;
|
|
731 }
|
|
732 goto Lcast;
|
|
733 }
|
|
734
|
|
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 }
|
|
746
|
|
747 if (committed)
|
|
748 goto Lcast;
|
|
749
|
|
750 #define X(tf,tt) ((tf) * 256 + (tt))
|
|
751 {
|
|
752 OutBuffer buffer;
|
|
753 size_t newlen = 0;
|
|
754 int tfty = typeb->nextOf()->toBasetype()->ty;
|
|
755 int ttty = tb->nextOf()->toBasetype()->ty;
|
|
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):
|
|
764 for (size_t u = 0; u < len;)
|
|
765 { unsigned c;
|
|
766 char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c);
|
|
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):
|
|
777 for (size_t u = 0; u < len;)
|
|
778 { unsigned c;
|
|
779 char *p = utf_decodeChar((unsigned char *)se->string, len, &u, &c);
|
|
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):
|
|
789 for (size_t u = 0; u < len;)
|
|
790 { unsigned c;
|
|
791 char *p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c);
|
|
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):
|
|
802 for (size_t u = 0; u < len;)
|
|
803 { unsigned c;
|
|
804 char *p = utf_decodeWchar((unsigned short *)se->string, len, &u, &c);
|
|
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):
|
|
814 for (size_t u = 0; u < len; u++)
|
|
815 {
|
|
816 unsigned c = ((unsigned *)se->string)[u];
|
|
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):
|
|
828 for (size_t u = 0; u < len; u++)
|
|
829 {
|
|
830 unsigned c = ((unsigned *)se->string)[u];
|
|
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:
|
|
842 if (!copied)
|
|
843 { se = (StringExp *)copy();
|
|
844 copied = 1;
|
|
845 }
|
|
846 se->string = buffer.extractData();
|
|
847 se->len = newlen;
|
|
848 se->sz = tb->nextOf()->size();
|
|
849 break;
|
|
850
|
|
851 default:
|
|
852 assert(typeb->nextOf()->size() != tb->nextOf()->size());
|
|
853 goto Lcast;
|
|
854 }
|
|
855 }
|
|
856 #undef X
|
|
857 L2:
|
|
858 assert(copied);
|
|
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 {
|
|
870 // Copy when changing the string literal
|
|
871 unsigned newsz = se->sz;
|
|
872 void *s;
|
|
873 int d;
|
|
874
|
|
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;
|
|
882 }
|
|
883 }
|
|
884 se->type = t;
|
|
885 return se;
|
|
886
|
|
887 Lcast:
|
|
888 Expression *e = new CastExp(loc, se, t);
|
|
889 e->type = t; // so semantic() won't be run on e
|
|
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)
|
|
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;
|
|
944 }
|
|
945 return e;
|
|
946 }
|
|
947
|
|
948
|
|
949 Expression *ArrayLiteralExp::castTo(Scope *sc, Type *t)
|
|
950 {
|
|
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;
|
|
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) &&
|
|
962 // Not trying to convert non-void[] to void[]
|
|
963 !(tb->nextOf()->toBasetype()->ty == Tvoid && typeb->nextOf()->toBasetype()->ty != Tvoid))
|
|
964 {
|
|
965 if (tb->ty == Tsarray)
|
|
966 { TypeSArray *tsa = (TypeSArray *)tb;
|
|
967 if (elements->dim != tsa->dim->toInteger())
|
|
968 goto L1;
|
|
969 }
|
|
970
|
|
971 e = (ArrayLiteralExp *)copy();
|
|
972 e->elements = (Expressions *)elements->copy();
|
|
973 for (int i = 0; i < elements->dim; i++)
|
|
974 { Expression *ex = (Expression *)elements->data[i];
|
|
975 ex = ex->castTo(sc, tb->nextOf());
|
|
976 e->elements->data[i] = (void *)ex;
|
|
977 }
|
|
978 e->type = t;
|
|
979 return e;
|
|
980 }
|
|
981 if (tb->ty == Tpointer && typeb->ty == Tsarray)
|
|
982 {
|
|
983 e = (ArrayLiteralExp *)copy();
|
|
984 e->type = typeb->nextOf()->pointerTo();
|
|
985 }
|
|
986 L1:
|
|
987 return e->Expression::castTo(sc, t);
|
|
988 }
|
|
989
|
|
990 Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t)
|
|
991 {
|
|
992 if (type == t)
|
|
993 return this;
|
|
994 AssocArrayLiteralExp *e = this;
|
|
995 Type *typeb = type->toBasetype();
|
|
996 Type *tb = t->toBasetype();
|
|
997 if (tb->ty == Taarray && typeb->ty == Taarray &&
|
|
998 tb->nextOf()->toBasetype()->ty != Tvoid)
|
|
999 {
|
|
1000 e = (AssocArrayLiteralExp *)copy();
|
|
1001 e->keys = (Expressions *)keys->copy();
|
|
1002 e->values = (Expressions *)values->copy();
|
|
1003 assert(keys->dim == values->dim);
|
|
1004 for (size_t i = 0; i < keys->dim; i++)
|
|
1005 { Expression *ex = (Expression *)values->data[i];
|
|
1006 ex = ex->castTo(sc, tb->nextOf());
|
|
1007 e->values->data[i] = (void *)ex;
|
|
1008
|
|
1009 ex = (Expression *)keys->data[i];
|
|
1010 ex = ex->castTo(sc, ((TypeAArray *)tb)->index);
|
|
1011 e->keys->data[i] = (void *)ex;
|
|
1012 }
|
|
1013 e->type = t;
|
|
1014 return e;
|
|
1015 }
|
|
1016 L1:
|
|
1017 return e->Expression::castTo(sc, t);
|
|
1018 }
|
|
1019
|
|
1020
|
|
1021 Expression *SymOffExp::castTo(Scope *sc, Type *t)
|
|
1022 {
|
|
1023 Type *tb;
|
|
1024
|
|
1025 #if 0
|
|
1026 printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n",
|
|
1027 toChars(), type->toChars(), t->toChars());
|
|
1028 #endif
|
|
1029 Expression *e = this;
|
|
1030
|
|
1031 tb = t->toBasetype();
|
|
1032 type = type->toBasetype();
|
|
1033 if (tb != type)
|
|
1034 {
|
|
1035 // Look for pointers to functions where the functions are overloaded.
|
|
1036 FuncDeclaration *f;
|
|
1037
|
|
1038 if (type->ty == Tpointer && type->next->ty == Tfunction &&
|
|
1039 tb->ty == Tpointer && tb->next->ty == Tfunction)
|
|
1040 {
|
|
1041 f = var->isFuncDeclaration();
|
|
1042 if (f)
|
|
1043 {
|
|
1044 f = f->overloadExactMatch(tb->next);
|
|
1045 if (f)
|
|
1046 {
|
|
1047 e = new SymOffExp(loc, f, 0);
|
|
1048 e->type = t;
|
|
1049 return e;
|
|
1050 }
|
|
1051 }
|
|
1052 }
|
|
1053 e = Expression::castTo(sc, t);
|
|
1054 }
|
|
1055 e->type = t;
|
|
1056 return e;
|
|
1057 }
|
|
1058
|
|
1059 Expression *DelegateExp::castTo(Scope *sc, Type *t)
|
|
1060 {
|
|
1061 Type *tb;
|
|
1062 #if 0
|
|
1063 printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n",
|
|
1064 toChars(), type->toChars(), t->toChars());
|
|
1065 #endif
|
|
1066 Expression *e = this;
|
|
1067 static char msg[] = "cannot form delegate due to covariant return type";
|
|
1068
|
|
1069 tb = t->toBasetype();
|
|
1070 type = type->toBasetype();
|
|
1071 if (tb != type)
|
|
1072 {
|
|
1073 // Look for delegates to functions where the functions are overloaded.
|
|
1074 FuncDeclaration *f;
|
|
1075
|
|
1076 if (type->ty == Tdelegate && type->next->ty == Tfunction &&
|
|
1077 tb->ty == Tdelegate && tb->next->ty == Tfunction)
|
|
1078 {
|
|
1079 if (func)
|
|
1080 {
|
|
1081 f = func->overloadExactMatch(tb->next);
|
|
1082 if (f)
|
|
1083 { int offset;
|
|
1084 if (f->tintro && f->tintro->next->isBaseOf(f->type->next, &offset) && offset)
|
|
1085 error("%s", msg);
|
|
1086 e = new DelegateExp(loc, e1, f);
|
|
1087 e->type = t;
|
|
1088 return e;
|
|
1089 }
|
|
1090 if (func->tintro)
|
|
1091 error("%s", msg);
|
|
1092 }
|
|
1093 }
|
|
1094 e = Expression::castTo(sc, t);
|
|
1095 }
|
|
1096 else
|
|
1097 { int offset;
|
|
1098
|
|
1099 if (func->tintro && func->tintro->next->isBaseOf(func->type->next, &offset) && offset)
|
|
1100 error("%s", msg);
|
|
1101 }
|
|
1102 e->type = t;
|
|
1103 return e;
|
|
1104 }
|
|
1105
|
|
1106 Expression *CondExp::castTo(Scope *sc, Type *t)
|
|
1107 {
|
|
1108 Expression *e = this;
|
|
1109
|
|
1110 if (type != t)
|
|
1111 {
|
|
1112 if (1 || e1->op == TOKstring || e2->op == TOKstring)
|
|
1113 { e = new CondExp(loc, econd, e1->castTo(sc, t), e2->castTo(sc, t));
|
|
1114 e->type = t;
|
|
1115 }
|
|
1116 else
|
|
1117 e = Expression::castTo(sc, t);
|
|
1118 }
|
|
1119 return e;
|
|
1120 }
|
|
1121
|
|
1122 /* ==================== ====================== */
|
|
1123
|
|
1124 /****************************************
|
|
1125 * Scale addition/subtraction to/from pointer.
|
|
1126 */
|
|
1127
|
|
1128 Expression *BinExp::scaleFactor(Scope *sc)
|
|
1129 { d_uns64 stride;
|
|
1130 Type *t1b = e1->type->toBasetype();
|
|
1131 Type *t2b = e2->type->toBasetype();
|
|
1132
|
|
1133 if (t1b->ty == Tpointer && t2b->isintegral())
|
|
1134 { // Need to adjust operator by the stride
|
|
1135 // Replace (ptr + int) with (ptr + (int * stride))
|
|
1136 Type *t = Type::tptrdiff_t;
|
|
1137
|
|
1138 stride = t1b->next->size();
|
|
1139 if (!t->equals(t2b))
|
|
1140 e2 = e2->castTo(sc, t);
|
|
1141 // LLVMDC: llvm uses typesafe pointer arithmetic
|
|
1142 #if !IN_LLVM
|
|
1143 if (t1b->next->isbit())
|
|
1144 // BUG: should add runtime check for misaligned offsets
|
|
1145 // This perhaps should be done by rewriting as &p[i]
|
|
1146 // and letting back end do it.
|
|
1147 e2 = new UshrExp(loc, e2, new IntegerExp(0, 3, t));
|
|
1148 else
|
|
1149 e2 = new MulExp(loc, e2, new IntegerExp(0, stride, t));
|
|
1150 #endif
|
|
1151 e2->type = t;
|
|
1152 type = e1->type;
|
|
1153 }
|
|
1154 else if (t2b->ty == Tpointer && t1b->isintegral())
|
|
1155 { // Need to adjust operator by the stride
|
|
1156 // Replace (int + ptr) with (ptr + (int * stride))
|
|
1157 Type *t = Type::tptrdiff_t;
|
|
1158 Expression *e;
|
|
1159
|
|
1160 stride = t2b->next->size();
|
|
1161 if (!t->equals(t1b))
|
|
1162 e = e1->castTo(sc, t);
|
|
1163 else
|
|
1164 e = e1;
|
|
1165 #if !IN_LLVM
|
|
1166 if (t2b->next->isbit())
|
|
1167 // BUG: should add runtime check for misaligned offsets
|
|
1168 e = new UshrExp(loc, e, new IntegerExp(0, 3, t));
|
|
1169 else
|
|
1170 e = new MulExp(loc, e, new IntegerExp(0, stride, t));
|
|
1171 #endif
|
|
1172 e->type = t;
|
|
1173 type = e2->type;
|
|
1174 e1 = e2;
|
|
1175 e2 = e;
|
|
1176 }
|
|
1177 return this;
|
|
1178 }
|
|
1179
|
|
1180 /************************************
|
|
1181 * Bring leaves to common type.
|
|
1182 */
|
|
1183
|
|
1184 Expression *BinExp::typeCombine(Scope *sc)
|
|
1185 {
|
|
1186 Type *t1;
|
|
1187 Type *t2;
|
|
1188 Type *t;
|
|
1189 TY ty;
|
|
1190
|
|
1191 //printf("BinExp::typeCombine()\n");
|
|
1192 //dump(0);
|
|
1193
|
|
1194 e1 = e1->integralPromotions(sc);
|
|
1195 e2 = e2->integralPromotions(sc);
|
|
1196
|
|
1197 // BUG: do toBasetype()
|
|
1198 t1 = e1->type;
|
|
1199 t2 = e2->type;
|
|
1200 assert(t1);
|
|
1201
|
|
1202 //if (t1) printf("\tt1 = %s\n", t1->toChars());
|
|
1203 //if (t2) printf("\tt2 = %s\n", t2->toChars());
|
|
1204 #ifdef DEBUG
|
|
1205 if (!t2) printf("\te2 = '%s'\n", e2->toChars());
|
|
1206 #endif
|
|
1207 assert(t2);
|
|
1208
|
|
1209 Type *t1b = t1->toBasetype();
|
|
1210 Type *t2b = t2->toBasetype();
|
|
1211
|
|
1212 ty = (TY)Type::impcnvResult[t1b->ty][t2b->ty];
|
|
1213 if (ty != Terror)
|
|
1214 { TY ty1;
|
|
1215 TY ty2;
|
|
1216
|
|
1217 ty1 = (TY)Type::impcnvType1[t1b->ty][t2b->ty];
|
|
1218 ty2 = (TY)Type::impcnvType2[t1b->ty][t2b->ty];
|
|
1219
|
|
1220 if (t1b->ty == ty1) // if no promotions
|
|
1221 {
|
|
1222 if (t1 == t2)
|
|
1223 {
|
|
1224 if (!type)
|
|
1225 type = t1;
|
|
1226 return this;
|
|
1227 }
|
|
1228
|
|
1229 if (t1b == t2b)
|
|
1230 {
|
|
1231 if (!type)
|
|
1232 type = t1b;
|
|
1233 return this;
|
|
1234 }
|
|
1235 }
|
|
1236
|
|
1237 if (!type)
|
|
1238 type = Type::basic[ty];
|
|
1239
|
|
1240 t1 = Type::basic[ty1];
|
|
1241 t2 = Type::basic[ty2];
|
|
1242 e1 = e1->castTo(sc, t1);
|
|
1243 e2 = e2->castTo(sc, t2);
|
|
1244 #if 0
|
|
1245 if (type != Type::basic[ty])
|
|
1246 { t = type;
|
|
1247 type = Type::basic[ty];
|
|
1248 return castTo(sc, t);
|
|
1249 }
|
|
1250 #endif
|
|
1251 //printf("after typeCombine():\n");
|
|
1252 //dump(0);
|
|
1253 //printf("ty = %d, ty1 = %d, ty2 = %d\n", ty, ty1, ty2);
|
|
1254 return this;
|
|
1255 }
|
|
1256
|
|
1257 t = t1;
|
|
1258 if (t1 == t2)
|
|
1259 {
|
|
1260 if ((t1->ty == Tstruct || t1->ty == Tclass) &&
|
|
1261 (op == TOKmin || op == TOKadd))
|
|
1262 goto Lincompatible;
|
|
1263 }
|
|
1264 else if (t1->isintegral() && t2->isintegral())
|
|
1265 {
|
|
1266 printf("t1 = %s, t2 = %s\n", t1->toChars(), t2->toChars());
|
|
1267 int sz1 = t1->size();
|
|
1268 int sz2 = t2->size();
|
|
1269 int sign1 = t1->isunsigned() == 0;
|
|
1270 int sign2 = t2->isunsigned() == 0;
|
|
1271
|
|
1272 if (sign1 == sign2)
|
|
1273 {
|
|
1274 if (sz1 < sz2)
|
|
1275 goto Lt2;
|
|
1276 else
|
|
1277 goto Lt1;
|
|
1278 }
|
|
1279 if (!sign1)
|
|
1280 {
|
|
1281 if (sz1 >= sz2)
|
|
1282 goto Lt1;
|
|
1283 else
|
|
1284 goto Lt2;
|
|
1285 }
|
|
1286 else
|
|
1287 {
|
|
1288 if (sz2 >= sz1)
|
|
1289 goto Lt2;
|
|
1290 else
|
|
1291 goto Lt1;
|
|
1292 }
|
|
1293 }
|
|
1294 else if (t1->ty == Tpointer && t2->ty == Tpointer)
|
|
1295 {
|
|
1296 // Bring pointers to compatible type
|
|
1297 Type *t1n = t1->next;
|
|
1298 Type *t2n = t2->next;
|
|
1299
|
|
1300 //t1->print();
|
|
1301 //t2->print();
|
|
1302 //if (t1n == t2n) *(char *)0 = 0;
|
|
1303 assert(t1n != t2n);
|
|
1304 if (t1n->ty == Tvoid) // pointers to void are always compatible
|
|
1305 t = t2;
|
|
1306 else if (t2n->ty == Tvoid)
|
|
1307 ;
|
|
1308 else if (t1n->ty == Tclass && t2n->ty == Tclass)
|
|
1309 { ClassDeclaration *cd1 = t1n->isClassHandle();
|
|
1310 ClassDeclaration *cd2 = t2n->isClassHandle();
|
|
1311 int offset;
|
|
1312
|
|
1313 if (cd1->isBaseOf(cd2, &offset))
|
|
1314 {
|
|
1315 if (offset)
|
|
1316 e2 = e2->castTo(sc, t);
|
|
1317 }
|
|
1318 else if (cd2->isBaseOf(cd1, &offset))
|
|
1319 {
|
|
1320 t = t2;
|
|
1321 if (offset)
|
|
1322 e1 = e1->castTo(sc, t);
|
|
1323 }
|
|
1324 else
|
|
1325 goto Lincompatible;
|
|
1326 }
|
|
1327 else
|
|
1328 goto Lincompatible;
|
|
1329 }
|
|
1330 else if ((t1->ty == Tsarray || t1->ty == Tarray) &&
|
|
1331 e2->op == TOKnull && t2->ty == Tpointer && t2->next->ty == Tvoid)
|
|
1332 {
|
|
1333 goto Lx1;
|
|
1334 }
|
|
1335 else if ((t2->ty == Tsarray || t2->ty == Tarray) &&
|
|
1336 e1->op == TOKnull && t1->ty == Tpointer && t1->next->ty == Tvoid)
|
|
1337 {
|
|
1338 goto Lx2;
|
|
1339 }
|
|
1340 else if ((t1->ty == Tsarray || t1->ty == Tarray) && t1->implicitConvTo(t2))
|
|
1341 {
|
|
1342 goto Lt2;
|
|
1343 }
|
|
1344 else if ((t2->ty == Tsarray || t2->ty == Tarray) && t2->implicitConvTo(t1))
|
|
1345 {
|
|
1346 goto Lt1;
|
|
1347 }
|
|
1348 else if (t1->ty == Tclass || t2->ty == Tclass)
|
|
1349 { int i1;
|
|
1350 int i2;
|
|
1351
|
|
1352 i1 = e2->implicitConvTo(t1);
|
|
1353 i2 = e1->implicitConvTo(t2);
|
|
1354
|
|
1355 if (i1 && i2)
|
|
1356 {
|
|
1357 // We have the case of class vs. void*, so pick class
|
|
1358 if (t1->ty == Tpointer)
|
|
1359 i1 = 0;
|
|
1360 else if (t2->ty == Tpointer)
|
|
1361 i2 = 0;
|
|
1362 }
|
|
1363
|
|
1364 if (i2)
|
|
1365 {
|
|
1366 goto Lt2;
|
|
1367 }
|
|
1368 else if (i1)
|
|
1369 {
|
|
1370 goto Lt1;
|
|
1371 }
|
|
1372 else
|
|
1373 goto Lincompatible;
|
|
1374 }
|
|
1375 else if ((e1->op == TOKstring || e1->op == TOKnull) && e1->implicitConvTo(t2))
|
|
1376 {
|
|
1377 goto Lt2;
|
|
1378 }
|
|
1379 //else if (e2->op == TOKstring) { printf("test2\n"); }
|
|
1380 else if ((e2->op == TOKstring || e2->op == TOKnull) && e2->implicitConvTo(t1))
|
|
1381 {
|
|
1382 goto Lt1;
|
|
1383 }
|
|
1384 else if (t1->ty == Tsarray && t2->ty == Tsarray &&
|
|
1385 e2->implicitConvTo(t1->next->arrayOf()))
|
|
1386 {
|
|
1387 Lx1:
|
|
1388 t = t1->next->arrayOf();
|
|
1389 e1 = e1->castTo(sc, t);
|
|
1390 e2 = e2->castTo(sc, t);
|
|
1391 }
|
|
1392 else if (t1->ty == Tsarray && t2->ty == Tsarray &&
|
|
1393 e1->implicitConvTo(t2->next->arrayOf()))
|
|
1394 {
|
|
1395 Lx2:
|
|
1396 t = t2->next->arrayOf();
|
|
1397 e1 = e1->castTo(sc, t);
|
|
1398 e2 = e2->castTo(sc, t);
|
|
1399 }
|
|
1400 else
|
|
1401 {
|
|
1402 Lincompatible:
|
|
1403 incompatibleTypes();
|
|
1404 }
|
|
1405 Lret:
|
|
1406 if (!type)
|
|
1407 type = t;
|
|
1408 //dump(0);
|
|
1409 return this;
|
|
1410
|
|
1411
|
|
1412 Lt1:
|
|
1413 e2 = e2->castTo(sc, t1);
|
|
1414 t = t1;
|
|
1415 goto Lret;
|
|
1416
|
|
1417 Lt2:
|
|
1418 e1 = e1->castTo(sc, t2);
|
|
1419 t = t2;
|
|
1420 goto Lret;
|
|
1421 }
|
|
1422
|
|
1423 /***********************************
|
|
1424 * Do integral promotions (convertchk).
|
|
1425 * Don't convert <array of> to <pointer to>
|
|
1426 */
|
|
1427
|
|
1428 Expression *Expression::integralPromotions(Scope *sc)
|
|
1429 { Expression *e;
|
|
1430
|
|
1431 e = this;
|
|
1432 switch (type->toBasetype()->ty)
|
|
1433 {
|
|
1434 case Tvoid:
|
|
1435 error("void has no value");
|
|
1436 break;
|
|
1437
|
|
1438 case Tint8:
|
|
1439 case Tuns8:
|
|
1440 case Tint16:
|
|
1441 case Tuns16:
|
|
1442 case Tbit:
|
|
1443 case Tbool:
|
|
1444 case Tchar:
|
|
1445 case Twchar:
|
|
1446 e = e->castTo(sc, Type::tint32);
|
|
1447 break;
|
|
1448
|
|
1449 case Tdchar:
|
|
1450 e = e->castTo(sc, Type::tuns32);
|
|
1451 break;
|
|
1452 }
|
|
1453 return e;
|
|
1454 }
|
|
1455
|