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