Mercurial > projects > ldc
annotate dmd/constfold.c @ 1650:40bd4a0d4870
Update to work with LLVM 2.7.
Removed use of dyn_cast, llvm no compiles
without exceptions and rtti by
default. We do need exceptions for the libconfig stuff, but rtti isn't
necessary (anymore).
Debug info needs to be rewritten, as in LLVM 2.7 the format has
completely changed. To have something to look at while rewriting, the
old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means
that you have to define this to compile at the moment.
Updated tango 0.99.9 patch to include updated EH runtime code, which is
needed for LLVM 2.7 as well.
author | Tomas Lindquist Olsen |
---|---|
date | Wed, 19 May 2010 12:42:32 +0200 |
parents | fb2e6707ad17 |
children |
rev | line source |
---|---|
336 | 1 |
2 // Compiler implementation of the D programming language | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
3 // Copyright (c) 1999-2009 by Digital Mars |
336 | 4 // All Rights Reserved |
5 // written by Walter Bright | |
6 // http://www.digitalmars.com | |
7 // License for redistribution is by either the Artistic License | |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | |
9 // See the included readme.txt for details. | |
10 | |
11 #include <stdio.h> | |
12 #include <stdlib.h> | |
13 #include <assert.h> | |
14 #include <math.h> | |
15 | |
16 #if __DMC__ | |
17 #include <complex.h> | |
18 #endif | |
19 | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
20 #include "rmem.h" |
336 | 21 #include "root.h" |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
22 #include "port.h" |
336 | 23 |
24 #include "mtype.h" | |
25 #include "expression.h" | |
26 #include "aggregate.h" | |
27 #include "declaration.h" | |
28 | |
29 #ifdef IN_GCC | |
30 #include "d-gcc-real.h" | |
31 | |
32 /* %% fix? */ | |
33 extern "C" bool real_isnan (const real_t *); | |
34 #endif | |
35 | |
36 static real_t zero; // work around DMC bug for now | |
37 | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
38 #if __FreeBSD__ |
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
39 #define fmodl fmod // hack for now, fix later |
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
40 #endif |
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
41 |
336 | 42 #define LOG 0 |
43 | |
44 Expression *expType(Type *type, Expression *e) | |
45 { | |
46 if (type != e->type) | |
47 { | |
48 e = e->copy(); | |
49 e->type = type; | |
50 } | |
51 return e; | |
52 } | |
53 | |
54 /* ================================== isConst() ============================== */ | |
55 | |
56 int Expression::isConst() | |
57 { | |
58 //printf("Expression::isConst(): %s\n", toChars()); | |
59 return 0; | |
60 } | |
61 | |
62 int IntegerExp::isConst() | |
63 { | |
64 return 1; | |
65 } | |
66 | |
67 int RealExp::isConst() | |
68 { | |
69 return 1; | |
70 } | |
71 | |
72 int ComplexExp::isConst() | |
73 { | |
74 return 1; | |
75 } | |
76 | |
1587 | 77 int NullExp::isConst() |
78 { | |
79 return 1; | |
80 } | |
81 | |
336 | 82 int SymOffExp::isConst() |
83 { | |
84 return 2; | |
85 } | |
86 | |
87 /* =============================== constFold() ============================== */ | |
88 | |
89 /* The constFold() functions were redundant with the optimize() ones, | |
90 * and so have been folded in with them. | |
91 */ | |
92 | |
93 /* ========================================================================== */ | |
94 | |
95 Expression *Neg(Type *type, Expression *e1) | |
96 { Expression *e; | |
97 Loc loc = e1->loc; | |
98 | |
99 if (e1->type->isreal()) | |
100 { | |
101 e = new RealExp(loc, -e1->toReal(), type); | |
102 } | |
103 else if (e1->type->isimaginary()) | |
104 { | |
105 e = new RealExp(loc, -e1->toImaginary(), type); | |
106 } | |
107 else if (e1->type->iscomplex()) | |
108 { | |
109 e = new ComplexExp(loc, -e1->toComplex(), type); | |
110 } | |
111 else | |
112 e = new IntegerExp(loc, -e1->toInteger(), type); | |
113 return e; | |
114 } | |
115 | |
116 Expression *Com(Type *type, Expression *e1) | |
117 { Expression *e; | |
118 Loc loc = e1->loc; | |
119 | |
120 e = new IntegerExp(loc, ~e1->toInteger(), type); | |
121 return e; | |
122 } | |
123 | |
124 Expression *Not(Type *type, Expression *e1) | |
125 { Expression *e; | |
126 Loc loc = e1->loc; | |
127 | |
128 e = new IntegerExp(loc, e1->isBool(0), type); | |
129 return e; | |
130 } | |
131 | |
132 Expression *Bool(Type *type, Expression *e1) | |
133 { Expression *e; | |
134 Loc loc = e1->loc; | |
135 | |
136 e = new IntegerExp(loc, e1->isBool(1), type); | |
137 return e; | |
138 } | |
139 | |
140 Expression *Add(Type *type, Expression *e1, Expression *e2) | |
141 { Expression *e; | |
142 Loc loc = e1->loc; | |
143 | |
144 #if LOG | |
145 printf("Add(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); | |
146 #endif | |
147 if (type->isreal()) | |
148 { | |
149 e = new RealExp(loc, e1->toReal() + e2->toReal(), type); | |
150 } | |
151 else if (type->isimaginary()) | |
152 { | |
153 e = new RealExp(loc, e1->toImaginary() + e2->toImaginary(), type); | |
154 } | |
155 else if (type->iscomplex()) | |
156 { | |
157 // This rigamarole is necessary so that -0.0 doesn't get | |
158 // converted to +0.0 by doing an extraneous add with +0.0 | |
159 complex_t c1; | |
160 real_t r1; | |
161 real_t i1; | |
162 | |
163 complex_t c2; | |
164 real_t r2; | |
165 real_t i2; | |
166 | |
167 complex_t v; | |
168 int x; | |
169 | |
170 if (e1->type->isreal()) | |
171 { r1 = e1->toReal(); | |
172 x = 0; | |
173 } | |
174 else if (e1->type->isimaginary()) | |
175 { i1 = e1->toImaginary(); | |
176 x = 3; | |
177 } | |
178 else | |
179 { c1 = e1->toComplex(); | |
180 x = 6; | |
181 } | |
182 | |
183 if (e2->type->isreal()) | |
184 { r2 = e2->toReal(); | |
185 } | |
186 else if (e2->type->isimaginary()) | |
187 { i2 = e2->toImaginary(); | |
188 x += 1; | |
189 } | |
190 else | |
191 { c2 = e2->toComplex(); | |
192 x += 2; | |
193 } | |
194 | |
195 switch (x) | |
196 { | |
197 #if __DMC__ | |
198 case 0+0: v = (complex_t) (r1 + r2); break; | |
199 case 0+1: v = r1 + i2 * I; break; | |
200 case 0+2: v = r1 + c2; break; | |
201 case 3+0: v = i1 * I + r2; break; | |
202 case 3+1: v = (complex_t) ((i1 + i2) * I); break; | |
203 case 3+2: v = i1 * I + c2; break; | |
204 case 6+0: v = c1 + r2; break; | |
205 case 6+1: v = c1 + i2 * I; break; | |
206 case 6+2: v = c1 + c2; break; | |
207 #else | |
208 case 0+0: v = complex_t(r1 + r2, 0); break; | |
209 case 0+1: v = complex_t(r1, i2); break; | |
210 case 0+2: v = complex_t(r1 + creall(c2), cimagl(c2)); break; | |
211 case 3+0: v = complex_t(r2, i1); break; | |
212 case 3+1: v = complex_t(0, i1 + i2); break; | |
213 case 3+2: v = complex_t(creall(c2), i1 + cimagl(c2)); break; | |
214 case 6+0: v = complex_t(creall(c1) + r2, cimagl(c2)); break; | |
215 case 6+1: v = complex_t(creall(c1), cimagl(c1) + i2); break; | |
216 case 6+2: v = c1 + c2; break; | |
217 #endif | |
218 default: assert(0); | |
219 } | |
220 e = new ComplexExp(loc, v, type); | |
221 } | |
222 else if (e1->op == TOKsymoff) | |
223 { | |
224 SymOffExp *soe = (SymOffExp *)e1; | |
225 e = new SymOffExp(loc, soe->var, soe->offset + e2->toInteger()); | |
226 e->type = type; | |
227 } | |
228 else if (e2->op == TOKsymoff) | |
229 { | |
230 SymOffExp *soe = (SymOffExp *)e2; | |
231 e = new SymOffExp(loc, soe->var, soe->offset + e1->toInteger()); | |
232 e->type = type; | |
233 } | |
234 else | |
235 e = new IntegerExp(loc, e1->toInteger() + e2->toInteger(), type); | |
236 return e; | |
237 } | |
238 | |
239 | |
240 Expression *Min(Type *type, Expression *e1, Expression *e2) | |
241 { Expression *e; | |
242 Loc loc = e1->loc; | |
243 | |
244 if (type->isreal()) | |
245 { | |
246 e = new RealExp(loc, e1->toReal() - e2->toReal(), type); | |
247 } | |
248 else if (type->isimaginary()) | |
249 { | |
250 e = new RealExp(loc, e1->toImaginary() - e2->toImaginary(), type); | |
251 } | |
252 else if (type->iscomplex()) | |
253 { | |
254 // This rigamarole is necessary so that -0.0 doesn't get | |
255 // converted to +0.0 by doing an extraneous add with +0.0 | |
256 complex_t c1; | |
257 real_t r1; | |
258 real_t i1; | |
259 | |
260 complex_t c2; | |
261 real_t r2; | |
262 real_t i2; | |
263 | |
264 complex_t v; | |
265 int x; | |
266 | |
267 if (e1->type->isreal()) | |
268 { r1 = e1->toReal(); | |
269 x = 0; | |
270 } | |
271 else if (e1->type->isimaginary()) | |
272 { i1 = e1->toImaginary(); | |
273 x = 3; | |
274 } | |
275 else | |
276 { c1 = e1->toComplex(); | |
277 x = 6; | |
278 } | |
279 | |
280 if (e2->type->isreal()) | |
281 { r2 = e2->toReal(); | |
282 } | |
283 else if (e2->type->isimaginary()) | |
284 { i2 = e2->toImaginary(); | |
285 x += 1; | |
286 } | |
287 else | |
288 { c2 = e2->toComplex(); | |
289 x += 2; | |
290 } | |
291 | |
292 switch (x) | |
293 { | |
294 #if __DMC__ | |
295 case 0+0: v = (complex_t) (r1 - r2); break; | |
296 case 0+1: v = r1 - i2 * I; break; | |
297 case 0+2: v = r1 - c2; break; | |
298 case 3+0: v = i1 * I - r2; break; | |
299 case 3+1: v = (complex_t) ((i1 - i2) * I); break; | |
300 case 3+2: v = i1 * I - c2; break; | |
301 case 6+0: v = c1 - r2; break; | |
302 case 6+1: v = c1 - i2 * I; break; | |
303 case 6+2: v = c1 - c2; break; | |
304 #else | |
305 case 0+0: v = complex_t(r1 - r2, 0); break; | |
306 case 0+1: v = complex_t(r1, -i2); break; | |
307 case 0+2: v = complex_t(r1 - creall(c2), -cimagl(c2)); break; | |
308 case 3+0: v = complex_t(-r2, i1); break; | |
309 case 3+1: v = complex_t(0, i1 - i2); break; | |
310 case 3+2: v = complex_t(-creall(c2), i1 - cimagl(c2)); break; | |
311 case 6+0: v = complex_t(creall(c1) - r2, cimagl(c1)); break; | |
312 case 6+1: v = complex_t(creall(c1), cimagl(c1) - i2); break; | |
313 case 6+2: v = c1 - c2; break; | |
314 #endif | |
315 default: assert(0); | |
316 } | |
317 e = new ComplexExp(loc, v, type); | |
318 } | |
319 else if (e1->op == TOKsymoff) | |
320 { | |
321 SymOffExp *soe = (SymOffExp *)e1; | |
322 e = new SymOffExp(loc, soe->var, soe->offset - e2->toInteger()); | |
323 e->type = type; | |
324 } | |
325 else | |
326 { | |
327 e = new IntegerExp(loc, e1->toInteger() - e2->toInteger(), type); | |
328 } | |
329 return e; | |
330 } | |
331 | |
332 Expression *Mul(Type *type, Expression *e1, Expression *e2) | |
333 { Expression *e; | |
334 Loc loc = e1->loc; | |
335 | |
336 if (type->isfloating()) | |
337 { complex_t c; | |
338 #ifdef IN_GCC | |
339 real_t r; | |
340 #else | |
341 d_float80 r; | |
342 #endif | |
343 | |
344 if (e1->type->isreal()) | |
345 { | |
346 #if __DMC__ | |
347 c = e1->toReal() * e2->toComplex(); | |
348 #else | |
349 r = e1->toReal(); | |
350 c = e2->toComplex(); | |
351 c = complex_t(r * creall(c), r * cimagl(c)); | |
352 #endif | |
353 } | |
354 else if (e1->type->isimaginary()) | |
355 { | |
356 #if __DMC__ | |
357 c = e1->toImaginary() * I * e2->toComplex(); | |
358 #else | |
359 r = e1->toImaginary(); | |
360 c = e2->toComplex(); | |
361 c = complex_t(-r * cimagl(c), r * creall(c)); | |
362 #endif | |
363 } | |
364 else if (e2->type->isreal()) | |
365 { | |
366 #if __DMC__ | |
367 c = e2->toReal() * e1->toComplex(); | |
368 #else | |
369 r = e2->toReal(); | |
370 c = e1->toComplex(); | |
371 c = complex_t(r * creall(c), r * cimagl(c)); | |
372 #endif | |
373 } | |
374 else if (e2->type->isimaginary()) | |
375 { | |
376 #if __DMC__ | |
377 c = e1->toComplex() * e2->toImaginary() * I; | |
378 #else | |
379 r = e2->toImaginary(); | |
380 c = e1->toComplex(); | |
381 c = complex_t(-r * cimagl(c), r * creall(c)); | |
382 #endif | |
383 } | |
384 else | |
385 c = e1->toComplex() * e2->toComplex(); | |
386 | |
387 if (type->isreal()) | |
388 e = new RealExp(loc, creall(c), type); | |
389 else if (type->isimaginary()) | |
390 e = new RealExp(loc, cimagl(c), type); | |
391 else if (type->iscomplex()) | |
392 e = new ComplexExp(loc, c, type); | |
393 else | |
394 assert(0); | |
395 } | |
396 else | |
397 { | |
398 e = new IntegerExp(loc, e1->toInteger() * e2->toInteger(), type); | |
399 } | |
400 return e; | |
401 } | |
402 | |
403 Expression *Div(Type *type, Expression *e1, Expression *e2) | |
404 { Expression *e; | |
405 Loc loc = e1->loc; | |
406 | |
407 if (type->isfloating()) | |
408 { complex_t c; | |
409 #ifdef IN_GCC | |
410 real_t r; | |
411 #else | |
412 d_float80 r; | |
413 #endif | |
414 | |
415 //e1->type->print(); | |
416 //e2->type->print(); | |
417 if (e2->type->isreal()) | |
418 { | |
419 if (e1->type->isreal()) | |
420 { | |
421 e = new RealExp(loc, e1->toReal() / e2->toReal(), type); | |
422 return e; | |
423 } | |
424 #if __DMC__ | |
425 //r = e2->toReal(); | |
426 //c = e1->toComplex(); | |
427 //printf("(%Lg + %Lgi) / %Lg\n", creall(c), cimagl(c), r); | |
428 | |
429 c = e1->toComplex() / e2->toReal(); | |
430 #else | |
431 r = e2->toReal(); | |
432 c = e1->toComplex(); | |
433 c = complex_t(creall(c) / r, cimagl(c) / r); | |
434 #endif | |
435 } | |
436 else if (e2->type->isimaginary()) | |
437 { | |
438 #if __DMC__ | |
439 //r = e2->toImaginary(); | |
440 //c = e1->toComplex(); | |
441 //printf("(%Lg + %Lgi) / %Lgi\n", creall(c), cimagl(c), r); | |
442 | |
443 c = e1->toComplex() / (e2->toImaginary() * I); | |
444 #else | |
445 r = e2->toImaginary(); | |
446 c = e1->toComplex(); | |
447 c = complex_t(cimagl(c) / r, -creall(c) / r); | |
448 #endif | |
449 } | |
450 else | |
451 { | |
452 c = e1->toComplex() / e2->toComplex(); | |
453 } | |
454 | |
455 if (type->isreal()) | |
456 e = new RealExp(loc, creall(c), type); | |
457 else if (type->isimaginary()) | |
458 e = new RealExp(loc, cimagl(c), type); | |
459 else if (type->iscomplex()) | |
460 e = new ComplexExp(loc, c, type); | |
461 else | |
462 assert(0); | |
463 } | |
464 else | |
465 { sinteger_t n1; | |
466 sinteger_t n2; | |
467 sinteger_t n; | |
468 | |
469 n1 = e1->toInteger(); | |
470 n2 = e2->toInteger(); | |
471 if (n2 == 0) | |
472 { e2->error("divide by 0"); | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
473 e2 = new IntegerExp(loc, 1, e2->type); |
336 | 474 n2 = 1; |
475 } | |
476 if (e1->type->isunsigned() || e2->type->isunsigned()) | |
477 n = ((d_uns64) n1) / ((d_uns64) n2); | |
478 else | |
479 n = n1 / n2; | |
480 e = new IntegerExp(loc, n, type); | |
481 } | |
482 return e; | |
483 } | |
484 | |
485 Expression *Mod(Type *type, Expression *e1, Expression *e2) | |
486 { Expression *e; | |
487 Loc loc = e1->loc; | |
488 | |
489 if (type->isfloating()) | |
490 { | |
491 complex_t c; | |
492 | |
493 if (e2->type->isreal()) | |
494 { real_t r2 = e2->toReal(); | |
495 | |
496 #ifdef __DMC__ | |
497 c = fmodl(e1->toReal(), r2) + fmodl(e1->toImaginary(), r2) * I; | |
498 #elif defined(IN_GCC) | |
499 c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2); | |
735
eee9efe5b51f
Attempt at getting LLVM to provide a proper target data layout. Should assert now if things are borked.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
734
diff
changeset
|
500 #elif (defined(__FreeBSD__) && __FreeBSD_version < 800000) || defined(__arm__) || defined(__thumb__) |
734
6dcab994ddc3
Fold in mandel's patch for ARM from #106
Christian Kamm <kamm incasoftware de>
parents:
717
diff
changeset
|
501 // freebsd is kinda messed up. the STABLE branch doesn't support C99's fmodl !?! |
6dcab994ddc3
Fold in mandel's patch for ARM from #106
Christian Kamm <kamm incasoftware de>
parents:
717
diff
changeset
|
502 // arm also doesn't like fmodl |
6dcab994ddc3
Fold in mandel's patch for ARM from #106
Christian Kamm <kamm incasoftware de>
parents:
717
diff
changeset
|
503 c = complex_t(fmod(e1->toReal(), r2), fmod(e1->toImaginary(), r2)); |
336 | 504 #else |
505 c = complex_t(fmodl(e1->toReal(), r2), fmodl(e1->toImaginary(), r2)); | |
506 #endif | |
507 } | |
508 else if (e2->type->isimaginary()) | |
509 { real_t i2 = e2->toImaginary(); | |
510 | |
511 #ifdef __DMC__ | |
512 c = fmodl(e1->toReal(), i2) + fmodl(e1->toImaginary(), i2) * I; | |
513 #elif defined(IN_GCC) | |
514 c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2); | |
735
eee9efe5b51f
Attempt at getting LLVM to provide a proper target data layout. Should assert now if things are borked.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
734
diff
changeset
|
515 #elif (defined(__FreeBSD__) && __FreeBSD_version < 800000) || defined(__arm__) || defined(__thumb__) |
637
29dc68c949b0
Applied the FreeBSD patch from Ralith, closes ticket #95 , slightly changed but basically the same. Thanx Ralith :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
336
diff
changeset
|
516 // freebsd is kinda messed up. the STABLE branch doesn't support C99's fmodl !?! |
734
6dcab994ddc3
Fold in mandel's patch for ARM from #106
Christian Kamm <kamm incasoftware de>
parents:
717
diff
changeset
|
517 // arm also doesn't like fmodl |
6dcab994ddc3
Fold in mandel's patch for ARM from #106
Christian Kamm <kamm incasoftware de>
parents:
717
diff
changeset
|
518 c = complex_t(fmod(e1->toReal(), i2), fmod(e1->toImaginary(), i2)); |
336 | 519 #else |
520 c = complex_t(fmodl(e1->toReal(), i2), fmodl(e1->toImaginary(), i2)); | |
521 #endif | |
522 } | |
523 else | |
524 assert(0); | |
525 | |
526 if (type->isreal()) | |
527 e = new RealExp(loc, creall(c), type); | |
528 else if (type->isimaginary()) | |
529 e = new RealExp(loc, cimagl(c), type); | |
530 else if (type->iscomplex()) | |
531 e = new ComplexExp(loc, c, type); | |
532 else | |
533 assert(0); | |
534 } | |
535 else | |
536 { sinteger_t n1; | |
537 sinteger_t n2; | |
538 sinteger_t n; | |
539 | |
540 n1 = e1->toInteger(); | |
541 n2 = e2->toInteger(); | |
542 if (n2 == 0) | |
543 { e2->error("divide by 0"); | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
544 e2 = new IntegerExp(loc, 1, e2->type); |
336 | 545 n2 = 1; |
546 } | |
547 if (e1->type->isunsigned() || e2->type->isunsigned()) | |
548 n = ((d_uns64) n1) % ((d_uns64) n2); | |
549 else | |
550 n = n1 % n2; | |
551 e = new IntegerExp(loc, n, type); | |
552 } | |
553 return e; | |
554 } | |
555 | |
556 Expression *Shl(Type *type, Expression *e1, Expression *e2) | |
557 { Expression *e; | |
558 Loc loc = e1->loc; | |
559 | |
560 e = new IntegerExp(loc, e1->toInteger() << e2->toInteger(), type); | |
561 return e; | |
562 } | |
563 | |
564 Expression *Shr(Type *type, Expression *e1, Expression *e2) | |
565 { Expression *e; | |
566 Loc loc = e1->loc; | |
567 unsigned count; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
568 dinteger_t value; |
336 | 569 |
570 value = e1->toInteger(); | |
571 count = e2->toInteger(); | |
572 switch (e1->type->toBasetype()->ty) | |
573 { | |
574 case Tint8: | |
575 value = (d_int8)(value) >> count; | |
576 break; | |
577 | |
578 case Tuns8: | |
579 value = (d_uns8)(value) >> count; | |
580 break; | |
581 | |
582 case Tint16: | |
583 value = (d_int16)(value) >> count; | |
584 break; | |
585 | |
586 case Tuns16: | |
587 value = (d_uns16)(value) >> count; | |
588 break; | |
589 | |
590 case Tint32: | |
591 value = (d_int32)(value) >> count; | |
592 break; | |
593 | |
594 case Tuns32: | |
595 value = (d_uns32)(value) >> count; | |
596 break; | |
597 | |
598 case Tint64: | |
599 value = (d_int64)(value) >> count; | |
600 break; | |
601 | |
602 case Tuns64: | |
603 value = (d_uns64)(value) >> count; | |
604 break; | |
605 | |
606 default: | |
607 assert(0); | |
608 } | |
609 e = new IntegerExp(loc, value, type); | |
610 return e; | |
611 } | |
612 | |
613 Expression *Ushr(Type *type, Expression *e1, Expression *e2) | |
614 { Expression *e; | |
615 Loc loc = e1->loc; | |
616 unsigned count; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
617 dinteger_t value; |
336 | 618 |
619 value = e1->toInteger(); | |
620 count = e2->toInteger(); | |
621 switch (e1->type->toBasetype()->ty) | |
622 { | |
623 case Tint8: | |
624 case Tuns8: | |
625 assert(0); // no way to trigger this | |
626 value = (value & 0xFF) >> count; | |
627 break; | |
628 | |
629 case Tint16: | |
630 case Tuns16: | |
631 assert(0); // no way to trigger this | |
632 value = (value & 0xFFFF) >> count; | |
633 break; | |
634 | |
635 case Tint32: | |
636 case Tuns32: | |
637 value = (value & 0xFFFFFFFF) >> count; | |
638 break; | |
639 | |
640 case Tint64: | |
641 case Tuns64: | |
642 value = (d_uns64)(value) >> count; | |
643 break; | |
644 | |
645 default: | |
646 assert(0); | |
647 } | |
648 e = new IntegerExp(loc, value, type); | |
649 return e; | |
650 } | |
651 | |
652 Expression *And(Type *type, Expression *e1, Expression *e2) | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
653 { |
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
654 Expression *e; |
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
655 e = new IntegerExp(e1->loc, e1->toInteger() & e2->toInteger(), type); |
336 | 656 return e; |
657 } | |
658 | |
659 Expression *Or(Type *type, Expression *e1, Expression *e2) | |
660 { Expression *e; | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
661 e = new IntegerExp(e1->loc, e1->toInteger() | e2->toInteger(), type); |
336 | 662 return e; |
663 } | |
664 | |
665 Expression *Xor(Type *type, Expression *e1, Expression *e2) | |
666 { Expression *e; | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
667 e = new IntegerExp(e1->loc, e1->toInteger() ^ e2->toInteger(), type); |
336 | 668 return e; |
669 } | |
670 | |
671 /* Also returns EXP_CANT_INTERPRET if cannot be computed. | |
672 */ | |
673 Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2) | |
674 { Expression *e; | |
675 Loc loc = e1->loc; | |
676 int cmp; | |
677 real_t r1; | |
678 real_t r2; | |
679 | |
680 //printf("Equal(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); | |
681 | |
682 assert(op == TOKequal || op == TOKnotequal); | |
683 | |
684 if (e1->op == TOKnull) | |
685 { | |
686 if (e2->op == TOKnull) | |
687 cmp = 1; | |
688 else if (e2->op == TOKstring) | |
689 { StringExp *es2 = (StringExp *)e2; | |
690 cmp = (0 == es2->len); | |
691 } | |
692 else if (e2->op == TOKarrayliteral) | |
693 { ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; | |
694 cmp = !es2->elements || (0 == es2->elements->dim); | |
695 } | |
696 else | |
697 return EXP_CANT_INTERPRET; | |
698 } | |
699 else if (e2->op == TOKnull) | |
700 { | |
701 if (e1->op == TOKstring) | |
702 { StringExp *es1 = (StringExp *)e1; | |
703 cmp = (0 == es1->len); | |
704 } | |
705 else if (e1->op == TOKarrayliteral) | |
706 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; | |
707 cmp = !es1->elements || (0 == es1->elements->dim); | |
708 } | |
709 else | |
710 return EXP_CANT_INTERPRET; | |
711 } | |
712 else if (e1->op == TOKstring && e2->op == TOKstring) | |
713 { StringExp *es1 = (StringExp *)e1; | |
714 StringExp *es2 = (StringExp *)e2; | |
715 | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
716 if (es1->sz != es2->sz) |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
717 { |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
718 assert(global.errors); |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
719 return EXP_CANT_INTERPRET; |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
720 } |
336 | 721 if (es1->len == es2->len && |
722 memcmp(es1->string, es2->string, es1->sz * es1->len) == 0) | |
723 cmp = 1; | |
724 else | |
725 cmp = 0; | |
726 } | |
727 else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral) | |
728 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; | |
729 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; | |
730 | |
731 if ((!es1->elements || !es1->elements->dim) && | |
732 (!es2->elements || !es2->elements->dim)) | |
733 cmp = 1; // both arrays are empty | |
734 else if (!es1->elements || !es2->elements) | |
735 cmp = 0; | |
736 else if (es1->elements->dim != es2->elements->dim) | |
737 cmp = 0; | |
738 else | |
739 { | |
740 for (size_t i = 0; i < es1->elements->dim; i++) | |
741 { Expression *ee1 = (Expression *)es1->elements->data[i]; | |
742 Expression *ee2 = (Expression *)es2->elements->data[i]; | |
743 | |
744 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); | |
745 if (v == EXP_CANT_INTERPRET) | |
746 return EXP_CANT_INTERPRET; | |
747 cmp = v->toInteger(); | |
748 if (cmp == 0) | |
749 break; | |
750 } | |
751 } | |
752 } | |
753 else if (e1->op == TOKarrayliteral && e2->op == TOKstring) | |
754 { // Swap operands and use common code | |
755 Expression *e = e1; | |
756 e1 = e2; | |
757 e2 = e; | |
758 goto Lsa; | |
759 } | |
760 else if (e1->op == TOKstring && e2->op == TOKarrayliteral) | |
761 { | |
762 Lsa: | |
763 StringExp *es1 = (StringExp *)e1; | |
764 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; | |
765 size_t dim1 = es1->len; | |
766 size_t dim2 = es2->elements ? es2->elements->dim : 0; | |
767 if (dim1 != dim2) | |
768 cmp = 0; | |
769 else | |
770 { | |
771 for (size_t i = 0; i < dim1; i++) | |
772 { | |
773 uinteger_t c = es1->charAt(i); | |
774 Expression *ee2 = (Expression *)es2->elements->data[i]; | |
775 if (ee2->isConst() != 1) | |
776 return EXP_CANT_INTERPRET; | |
777 cmp = (c == ee2->toInteger()); | |
778 if (cmp == 0) | |
779 break; | |
780 } | |
781 } | |
782 } | |
783 else if (e1->op == TOKstructliteral && e2->op == TOKstructliteral) | |
784 { StructLiteralExp *es1 = (StructLiteralExp *)e1; | |
785 StructLiteralExp *es2 = (StructLiteralExp *)e2; | |
786 | |
787 if (es1->sd != es2->sd) | |
788 cmp = 0; | |
789 else if ((!es1->elements || !es1->elements->dim) && | |
790 (!es2->elements || !es2->elements->dim)) | |
791 cmp = 1; // both arrays are empty | |
792 else if (!es1->elements || !es2->elements) | |
793 cmp = 0; | |
794 else if (es1->elements->dim != es2->elements->dim) | |
795 cmp = 0; | |
796 else | |
797 { | |
798 cmp = 1; | |
799 for (size_t i = 0; i < es1->elements->dim; i++) | |
800 { Expression *ee1 = (Expression *)es1->elements->data[i]; | |
801 Expression *ee2 = (Expression *)es2->elements->data[i]; | |
802 | |
803 if (ee1 == ee2) | |
804 continue; | |
805 if (!ee1 || !ee2) | |
806 { cmp = 0; | |
807 break; | |
808 } | |
809 Expression *v = Equal(TOKequal, Type::tint32, ee1, ee2); | |
810 if (v == EXP_CANT_INTERPRET) | |
811 return EXP_CANT_INTERPRET; | |
812 cmp = v->toInteger(); | |
813 if (cmp == 0) | |
814 break; | |
815 } | |
816 } | |
817 } | |
818 #if 0 // Should handle this | |
819 else if (e1->op == TOKarrayliteral && e2->op == TOKstring) | |
820 { | |
821 } | |
822 #endif | |
823 else if (e1->isConst() != 1 || e2->isConst() != 1) | |
824 return EXP_CANT_INTERPRET; | |
825 else if (e1->type->isreal()) | |
826 { | |
827 r1 = e1->toReal(); | |
828 r2 = e2->toReal(); | |
829 goto L1; | |
830 } | |
831 else if (e1->type->isimaginary()) | |
832 { | |
833 r1 = e1->toImaginary(); | |
834 r2 = e2->toImaginary(); | |
835 L1: | |
836 #if __DMC__ | |
837 cmp = (r1 == r2); | |
838 #else | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
839 if (Port::isNan(r1) || Port::isNan(r2)) // if unordered |
336 | 840 { |
841 cmp = 0; | |
842 } | |
843 else | |
844 { | |
845 cmp = (r1 == r2); | |
846 } | |
847 #endif | |
848 } | |
849 else if (e1->type->iscomplex()) | |
850 { | |
851 cmp = e1->toComplex() == e2->toComplex(); | |
852 } | |
1587 | 853 else if (e1->type->isintegral() || e1->type->toBasetype()->ty == Tpointer) |
336 | 854 { |
855 cmp = (e1->toInteger() == e2->toInteger()); | |
856 } | |
857 else | |
858 return EXP_CANT_INTERPRET; | |
859 if (op == TOKnotequal) | |
860 cmp ^= 1; | |
861 e = new IntegerExp(loc, cmp, type); | |
862 return e; | |
863 } | |
864 | |
865 Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2) | |
1621
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
866 { |
336 | 867 Loc loc = e1->loc; |
868 int cmp; | |
869 | |
1587 | 870 if (e1->op == TOKnull) |
336 | 871 { |
1587 | 872 cmp = (e2->op == TOKnull); |
873 } | |
874 else if (e2->op == TOKnull) | |
875 { | |
876 cmp = 0; | |
336 | 877 } |
878 else if (e1->op == TOKsymoff && e2->op == TOKsymoff) | |
879 { | |
880 SymOffExp *es1 = (SymOffExp *)e1; | |
881 SymOffExp *es2 = (SymOffExp *)e2; | |
882 | |
883 cmp = (es1->var == es2->var && es1->offset == es2->offset); | |
884 } | |
885 else if (e1->isConst() == 1 && e2->isConst() == 1) | |
886 return Equal((op == TOKidentity) ? TOKequal : TOKnotequal, | |
887 type, e1, e2); | |
888 else | |
889 assert(0); | |
890 if (op == TOKnotidentity) | |
891 cmp ^= 1; | |
892 return new IntegerExp(loc, cmp, type); | |
893 } | |
894 | |
895 | |
896 Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2) | |
897 { Expression *e; | |
898 Loc loc = e1->loc; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
899 dinteger_t n; |
336 | 900 real_t r1; |
901 real_t r2; | |
902 | |
903 if (e1->type->isreal()) | |
904 { | |
905 r1 = e1->toReal(); | |
906 r2 = e2->toReal(); | |
907 goto L1; | |
908 } | |
909 else if (e1->type->isimaginary()) | |
910 { | |
911 r1 = e1->toImaginary(); | |
912 r2 = e2->toImaginary(); | |
913 L1: | |
914 #if __DMC__ | |
915 // DMC is the only compiler I know of that handles NAN arguments | |
916 // correctly in comparisons. | |
917 switch (op) | |
918 { | |
919 case TOKlt: n = r1 < r2; break; | |
920 case TOKle: n = r1 <= r2; break; | |
921 case TOKgt: n = r1 > r2; break; | |
922 case TOKge: n = r1 >= r2; break; | |
923 | |
924 case TOKleg: n = r1 <>= r2; break; | |
925 case TOKlg: n = r1 <> r2; break; | |
926 case TOKunord: n = r1 !<>= r2; break; | |
927 case TOKue: n = r1 !<> r2; break; | |
928 case TOKug: n = r1 !<= r2; break; | |
929 case TOKuge: n = r1 !< r2; break; | |
930 case TOKul: n = r1 !>= r2; break; | |
931 case TOKule: n = r1 !> r2; break; | |
932 | |
933 default: | |
934 assert(0); | |
935 } | |
936 #else | |
937 // Don't rely on compiler, handle NAN arguments separately | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
938 if (Port::isNan(r1) || Port::isNan(r2)) // if unordered |
336 | 939 { |
940 switch (op) | |
941 { | |
942 case TOKlt: n = 0; break; | |
943 case TOKle: n = 0; break; | |
944 case TOKgt: n = 0; break; | |
945 case TOKge: n = 0; break; | |
946 | |
947 case TOKleg: n = 0; break; | |
948 case TOKlg: n = 0; break; | |
949 case TOKunord: n = 1; break; | |
950 case TOKue: n = 1; break; | |
951 case TOKug: n = 1; break; | |
952 case TOKuge: n = 1; break; | |
953 case TOKul: n = 1; break; | |
954 case TOKule: n = 1; break; | |
955 | |
956 default: | |
957 assert(0); | |
958 } | |
959 } | |
960 else | |
961 { | |
962 switch (op) | |
963 { | |
964 case TOKlt: n = r1 < r2; break; | |
965 case TOKle: n = r1 <= r2; break; | |
966 case TOKgt: n = r1 > r2; break; | |
967 case TOKge: n = r1 >= r2; break; | |
968 | |
969 case TOKleg: n = 1; break; | |
970 case TOKlg: n = r1 != r2; break; | |
971 case TOKunord: n = 0; break; | |
972 case TOKue: n = r1 == r2; break; | |
973 case TOKug: n = r1 > r2; break; | |
974 case TOKuge: n = r1 >= r2; break; | |
975 case TOKul: n = r1 < r2; break; | |
976 case TOKule: n = r1 <= r2; break; | |
977 | |
978 default: | |
979 assert(0); | |
980 } | |
981 } | |
982 #endif | |
983 } | |
984 else if (e1->type->iscomplex()) | |
985 { | |
986 assert(0); | |
987 } | |
988 else | |
989 { sinteger_t n1; | |
990 sinteger_t n2; | |
991 | |
992 n1 = e1->toInteger(); | |
993 n2 = e2->toInteger(); | |
994 if (e1->type->isunsigned() || e2->type->isunsigned()) | |
995 { | |
996 switch (op) | |
997 { | |
998 case TOKlt: n = ((d_uns64) n1) < ((d_uns64) n2); break; | |
999 case TOKle: n = ((d_uns64) n1) <= ((d_uns64) n2); break; | |
1000 case TOKgt: n = ((d_uns64) n1) > ((d_uns64) n2); break; | |
1001 case TOKge: n = ((d_uns64) n1) >= ((d_uns64) n2); break; | |
1002 | |
1003 case TOKleg: n = 1; break; | |
1004 case TOKlg: n = ((d_uns64) n1) != ((d_uns64) n2); break; | |
1005 case TOKunord: n = 0; break; | |
1006 case TOKue: n = ((d_uns64) n1) == ((d_uns64) n2); break; | |
1007 case TOKug: n = ((d_uns64) n1) > ((d_uns64) n2); break; | |
1008 case TOKuge: n = ((d_uns64) n1) >= ((d_uns64) n2); break; | |
1009 case TOKul: n = ((d_uns64) n1) < ((d_uns64) n2); break; | |
1010 case TOKule: n = ((d_uns64) n1) <= ((d_uns64) n2); break; | |
1011 | |
1012 default: | |
1013 assert(0); | |
1014 } | |
1015 } | |
1016 else | |
1017 { | |
1018 switch (op) | |
1019 { | |
1020 case TOKlt: n = n1 < n2; break; | |
1021 case TOKle: n = n1 <= n2; break; | |
1022 case TOKgt: n = n1 > n2; break; | |
1023 case TOKge: n = n1 >= n2; break; | |
1024 | |
1025 case TOKleg: n = 1; break; | |
1026 case TOKlg: n = n1 != n2; break; | |
1027 case TOKunord: n = 0; break; | |
1028 case TOKue: n = n1 == n2; break; | |
1029 case TOKug: n = n1 > n2; break; | |
1030 case TOKuge: n = n1 >= n2; break; | |
1031 case TOKul: n = n1 < n2; break; | |
1032 case TOKule: n = n1 <= n2; break; | |
1033 | |
1034 default: | |
1035 assert(0); | |
1036 } | |
1037 } | |
1038 } | |
1039 e = new IntegerExp(loc, n, type); | |
1040 return e; | |
1041 } | |
1042 | |
1043 /* Also returns EXP_CANT_INTERPRET if cannot be computed. | |
1044 * to: type to cast to | |
1045 * type: type to paint the result | |
1046 */ | |
1047 | |
1048 Expression *Cast(Type *type, Type *to, Expression *e1) | |
1049 { Expression *e = EXP_CANT_INTERPRET; | |
1050 Loc loc = e1->loc; | |
1051 | |
1052 //printf("Cast(type = %s, to = %s, e1 = %s)\n", type->toChars(), to->toChars(), e1->toChars()); | |
1053 //printf("e1->type = %s\n", e1->type->toChars()); | |
1054 if (type->equals(e1->type) && to->equals(type)) | |
1055 return e1; | |
1056 | |
1333
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1057 Type *tb = to->toBasetype(); |
1621
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1058 Type *typeb = type->toBasetype(); |
1333
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1059 |
1587 | 1060 /* Allow casting from one string type to another |
1061 */ | |
1333
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1062 if (e1->op == TOKstring) |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1063 { |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1064 if (tb->ty == Tarray && typeb->ty == Tarray && |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1065 tb->nextOf()->size() == typeb->nextOf()->size()) |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1066 { |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1067 return expType(to, e1); |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1068 } |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1069 } |
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1070 |
1621
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1071 if (e1->op == TOKarrayliteral && typeb == tb) |
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1072 { |
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1073 return e1; |
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1074 } |
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1075 |
336 | 1076 if (e1->isConst() != 1) |
1621
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1077 { |
336 | 1078 return EXP_CANT_INTERPRET; |
1621
fb2e6707ad17
Merge DMD r314+r315: bugzilla 2029 Typesafe variadic functions don't...
Leandro Lucarella <llucax@gmail.com>
parents:
1587
diff
changeset
|
1079 } |
336 | 1080 |
1081 if (tb->ty == Tbool) | |
1082 e = new IntegerExp(loc, e1->toInteger() != 0, type); | |
1083 else if (type->isintegral()) | |
1084 { | |
1085 if (e1->type->isfloating()) | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
1086 { dinteger_t result; |
336 | 1087 real_t r = e1->toReal(); |
1088 | |
1587 | 1089 switch (type->toBasetype()->ty) |
336 | 1090 { |
1091 case Tint8: result = (d_int8)r; break; | |
1092 case Tchar: | |
1093 case Tuns8: result = (d_uns8)r; break; | |
1094 case Tint16: result = (d_int16)r; break; | |
1095 case Twchar: | |
1096 case Tuns16: result = (d_uns16)r; break; | |
1097 case Tint32: result = (d_int32)r; break; | |
1098 case Tdchar: | |
1099 case Tuns32: result = (d_uns32)r; break; | |
1100 case Tint64: result = (d_int64)r; break; | |
1101 case Tuns64: result = (d_uns64)r; break; | |
1102 default: | |
1103 assert(0); | |
1104 } | |
1105 | |
1106 e = new IntegerExp(loc, result, type); | |
1107 } | |
1108 else if (type->isunsigned()) | |
1109 e = new IntegerExp(loc, e1->toUInteger(), type); | |
1110 else | |
1111 e = new IntegerExp(loc, e1->toInteger(), type); | |
1112 } | |
1113 else if (tb->isreal()) | |
1114 { real_t value = e1->toReal(); | |
1115 | |
1116 e = new RealExp(loc, value, type); | |
1117 } | |
1118 else if (tb->isimaginary()) | |
1119 { real_t value = e1->toImaginary(); | |
1120 | |
1121 e = new RealExp(loc, value, type); | |
1122 } | |
1123 else if (tb->iscomplex()) | |
1124 { complex_t value = e1->toComplex(); | |
1125 | |
1126 e = new ComplexExp(loc, value, type); | |
1127 } | |
1128 else if (tb->isscalar()) | |
1129 e = new IntegerExp(loc, e1->toInteger(), type); | |
1130 else if (tb->ty == Tvoid) | |
1131 e = EXP_CANT_INTERPRET; | |
1132 else if (tb->ty == Tstruct && e1->op == TOKint64) | |
1133 { // Struct = 0; | |
1134 StructDeclaration *sd = tb->toDsymbol(NULL)->isStructDeclaration(); | |
1135 assert(sd); | |
1136 Expressions *elements = new Expressions; | |
1137 for (size_t i = 0; i < sd->fields.dim; i++) | |
1138 { Dsymbol *s = (Dsymbol *)sd->fields.data[i]; | |
1139 VarDeclaration *v = s->isVarDeclaration(); | |
1140 assert(v); | |
1141 | |
1142 Expression *exp = new IntegerExp(0); | |
1143 exp = Cast(v->type, v->type, exp); | |
1144 if (exp == EXP_CANT_INTERPRET) | |
1145 return exp; | |
1146 elements->push(exp); | |
1147 } | |
1148 e = new StructLiteralExp(loc, sd, elements); | |
1149 e->type = type; | |
1150 } | |
1151 else | |
1152 { | |
1153 error(loc, "cannot cast %s to %s", e1->type->toChars(), type->toChars()); | |
1333
6bae1c30480f
Backport D2 CTFE cast behavior to allow cast(char[])char[n] to succeed.
Christian Kamm <kamm incasoftware de>
parents:
1195
diff
changeset
|
1154 e = new IntegerExp(loc, 0, Type::tint32); |
336 | 1155 } |
1156 return e; | |
1157 } | |
1158 | |
1159 | |
1160 Expression *ArrayLength(Type *type, Expression *e1) | |
1161 { Expression *e; | |
1162 Loc loc = e1->loc; | |
1163 | |
1164 if (e1->op == TOKstring) | |
1165 { StringExp *es1 = (StringExp *)e1; | |
1166 | |
1167 e = new IntegerExp(loc, es1->len, type); | |
1168 } | |
1169 else if (e1->op == TOKarrayliteral) | |
1170 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; | |
1171 size_t dim; | |
1172 | |
1173 dim = ale->elements ? ale->elements->dim : 0; | |
1174 e = new IntegerExp(loc, dim, type); | |
1175 } | |
1176 else if (e1->op == TOKassocarrayliteral) | |
1177 { AssocArrayLiteralExp *ale = (AssocArrayLiteralExp *)e1; | |
1178 size_t dim = ale->keys->dim; | |
1179 | |
1180 e = new IntegerExp(loc, dim, type); | |
1181 } | |
1182 else | |
1183 e = EXP_CANT_INTERPRET; | |
1184 return e; | |
1185 } | |
1186 | |
1187 /* Also return EXP_CANT_INTERPRET if this fails | |
1188 */ | |
1189 Expression *Index(Type *type, Expression *e1, Expression *e2) | |
1190 { Expression *e = EXP_CANT_INTERPRET; | |
1191 Loc loc = e1->loc; | |
1192 | |
1193 //printf("Index(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); | |
1194 assert(e1->type); | |
1195 if (e1->op == TOKstring && e2->op == TOKint64) | |
1196 { StringExp *es1 = (StringExp *)e1; | |
1197 uinteger_t i = e2->toInteger(); | |
1198 | |
1199 if (i >= es1->len) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
1200 e1->error("string index %ju is out of bounds [0 .. %zu]", i, es1->len); |
336 | 1201 else |
1202 { unsigned value = es1->charAt(i); | |
1203 e = new IntegerExp(loc, value, type); | |
1204 } | |
1205 } | |
1206 else if (e1->type->toBasetype()->ty == Tsarray && e2->op == TOKint64) | |
1207 { TypeSArray *tsa = (TypeSArray *)e1->type->toBasetype(); | |
1208 uinteger_t length = tsa->dim->toInteger(); | |
1209 uinteger_t i = e2->toInteger(); | |
1210 | |
1211 if (i >= length) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
1212 { e2->error("array index %ju is out of bounds %s[0 .. %ju]", i, e1->toChars(), length); |
336 | 1213 } |
1214 else if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2)) | |
1215 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; | |
1216 e = (Expression *)ale->elements->data[i]; | |
1217 e->type = type; | |
1218 } | |
1219 } | |
1220 else if (e1->type->toBasetype()->ty == Tarray && e2->op == TOKint64) | |
1221 { | |
1222 uinteger_t i = e2->toInteger(); | |
1223 | |
1224 if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2)) | |
1225 { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; | |
1226 if (i >= ale->elements->dim) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
1227 { e2->error("array index %ju is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim); |
336 | 1228 } |
1229 else | |
1230 { e = (Expression *)ale->elements->data[i]; | |
1231 e->type = type; | |
1232 } | |
1233 } | |
1234 } | |
1235 else if (e1->op == TOKassocarrayliteral && !e1->checkSideEffect(2)) | |
1236 { | |
1237 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e1; | |
1238 /* Search the keys backwards, in case there are duplicate keys | |
1239 */ | |
1240 for (size_t i = ae->keys->dim; i;) | |
1241 { | |
1242 i--; | |
1243 Expression *ekey = (Expression *)ae->keys->data[i]; | |
1244 Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2); | |
1245 if (ex == EXP_CANT_INTERPRET) | |
1246 return ex; | |
1247 if (ex->isBool(TRUE)) | |
1248 { e = (Expression *)ae->values->data[i]; | |
1249 e->type = type; | |
1250 break; | |
1251 } | |
1252 } | |
1253 } | |
1254 return e; | |
1255 } | |
1256 | |
1257 /* Also return EXP_CANT_INTERPRET if this fails | |
1258 */ | |
1259 Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr) | |
1260 { Expression *e = EXP_CANT_INTERPRET; | |
1261 Loc loc = e1->loc; | |
1262 | |
1263 #if LOG | |
1264 printf("Slice()\n"); | |
1265 if (lwr) | |
1266 { printf("\te1 = %s\n", e1->toChars()); | |
1267 printf("\tlwr = %s\n", lwr->toChars()); | |
1268 printf("\tupr = %s\n", upr->toChars()); | |
1269 } | |
1270 #endif | |
1271 if (e1->op == TOKstring && lwr->op == TOKint64 && upr->op == TOKint64) | |
1272 { StringExp *es1 = (StringExp *)e1; | |
1273 uinteger_t ilwr = lwr->toInteger(); | |
1274 uinteger_t iupr = upr->toInteger(); | |
1275 | |
1276 if (iupr > es1->len || ilwr > iupr) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
1277 e1->error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr); |
336 | 1278 else |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
1279 { dinteger_t value; |
336 | 1280 void *s; |
1281 size_t len = iupr - ilwr; | |
1282 int sz = es1->sz; | |
1283 StringExp *es; | |
1284 | |
1285 s = mem.malloc((len + 1) * sz); | |
1286 memcpy((unsigned char *)s, (unsigned char *)es1->string + ilwr * sz, len * sz); | |
1287 memset((unsigned char *)s + len * sz, 0, sz); | |
1288 | |
1289 es = new StringExp(loc, s, len, es1->postfix); | |
1290 es->sz = sz; | |
1291 es->committed = 1; | |
1292 es->type = type; | |
1293 e = es; | |
1294 } | |
1295 } | |
1296 else if (e1->op == TOKarrayliteral && | |
1297 lwr->op == TOKint64 && upr->op == TOKint64 && | |
1298 !e1->checkSideEffect(2)) | |
1299 { ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; | |
1300 uinteger_t ilwr = lwr->toInteger(); | |
1301 uinteger_t iupr = upr->toInteger(); | |
1302 | |
1303 if (iupr > es1->elements->dim || ilwr > iupr) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
735
diff
changeset
|
1304 e1->error("array slice [%ju .. %ju] is out of bounds", ilwr, iupr); |
336 | 1305 else |
1306 { | |
1307 Expressions *elements = new Expressions(); | |
1308 elements->setDim(iupr - ilwr); | |
1309 memcpy(elements->data, | |
1310 es1->elements->data + ilwr, | |
1311 (iupr - ilwr) * sizeof(es1->elements->data[0])); | |
1312 e = new ArrayLiteralExp(e1->loc, elements); | |
1313 e->type = type; | |
1314 } | |
1315 } | |
1316 return e; | |
1317 } | |
1318 | |
1319 /* Also return EXP_CANT_INTERPRET if this fails | |
1320 */ | |
1321 Expression *Cat(Type *type, Expression *e1, Expression *e2) | |
1322 { Expression *e = EXP_CANT_INTERPRET; | |
1323 Loc loc = e1->loc; | |
1324 Type *t; | |
717
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1325 Type *t1 = e1->type->toBasetype(); |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1326 Type *t2 = e2->type->toBasetype(); |
336 | 1327 |
1328 //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
1329 //printf("\tt1 = %s, t2 = %s\n", t1->toChars(), t2->toChars()); |
336 | 1330 |
1331 if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral)) | |
1332 { e = e2; | |
1333 goto L2; | |
1334 } | |
1335 else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull) | |
1336 { e = e1; | |
1337 L2: | |
1338 Type *tn = e->type->toBasetype(); | |
1339 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) | |
1340 { | |
1341 // Create a StringExp | |
1342 void *s; | |
1343 StringExp *es; | |
1344 size_t len = 1; | |
1345 int sz = tn->size(); | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
1346 dinteger_t v = e->toInteger(); |
336 | 1347 |
1348 s = mem.malloc((len + 1) * sz); | |
1349 memcpy((unsigned char *)s, &v, sz); | |
1350 | |
1351 // Add terminating 0 | |
1352 memset((unsigned char *)s + len * sz, 0, sz); | |
1353 | |
1354 es = new StringExp(loc, s, len); | |
1355 es->sz = sz; | |
1356 es->committed = 1; | |
1357 e = es; | |
1358 } | |
1359 else | |
1360 { // Create an ArrayLiteralExp | |
1361 Expressions *elements = new Expressions(); | |
1362 elements->push(e); | |
1363 e = new ArrayLiteralExp(e->loc, elements); | |
1364 } | |
1365 e->type = type; | |
1366 return e; | |
1367 } | |
1368 else if (e1->op == TOKstring && e2->op == TOKstring) | |
1369 { | |
1370 // Concatenate the strings | |
1371 void *s; | |
1372 StringExp *es1 = (StringExp *)e1; | |
1373 StringExp *es2 = (StringExp *)e2; | |
1374 StringExp *es; | |
1375 Type *t; | |
1376 size_t len = es1->len + es2->len; | |
1377 int sz = es1->sz; | |
1378 | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1379 if (sz != es2->sz) |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1380 { |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1381 /* Can happen with: |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1382 * auto s = "foo"d ~ "bar"c; |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1383 */ |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1384 assert(global.errors); |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1385 return e; |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
637
diff
changeset
|
1386 } |
336 | 1387 s = mem.malloc((len + 1) * sz); |
1388 memcpy(s, es1->string, es1->len * sz); | |
1389 memcpy((unsigned char *)s + es1->len * sz, es2->string, es2->len * sz); | |
1390 | |
1391 // Add terminating 0 | |
1392 memset((unsigned char *)s + len * sz, 0, sz); | |
1393 | |
1394 es = new StringExp(loc, s, len); | |
1395 es->sz = sz; | |
1396 es->committed = es1->committed | es2->committed; | |
1397 if (es1->committed) | |
1398 t = es1->type; | |
1399 else | |
1400 t = es2->type; | |
1401 es->type = type; | |
1402 e = es; | |
1403 } | |
1404 else if (e1->op == TOKstring && e2->op == TOKint64) | |
1405 { | |
1406 // Concatenate the strings | |
1407 void *s; | |
1408 StringExp *es1 = (StringExp *)e1; | |
1409 StringExp *es; | |
1410 Type *t; | |
1411 size_t len = es1->len + 1; | |
1412 int sz = es1->sz; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
1413 dinteger_t v = e2->toInteger(); |
336 | 1414 |
1415 s = mem.malloc((len + 1) * sz); | |
1416 memcpy(s, es1->string, es1->len * sz); | |
1417 memcpy((unsigned char *)s + es1->len * sz, &v, sz); | |
1418 | |
1419 // Add terminating 0 | |
1420 memset((unsigned char *)s + len * sz, 0, sz); | |
1421 | |
1422 es = new StringExp(loc, s, len); | |
1423 es->sz = sz; | |
1424 es->committed = es1->committed; | |
1425 t = es1->type; | |
1426 es->type = type; | |
1427 e = es; | |
1428 } | |
1429 else if (e1->op == TOKint64 && e2->op == TOKstring) | |
1430 { | |
1431 // Concatenate the strings | |
1432 void *s; | |
1433 StringExp *es2 = (StringExp *)e2; | |
1434 StringExp *es; | |
1435 Type *t; | |
1436 size_t len = 1 + es2->len; | |
1437 int sz = es2->sz; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1103
diff
changeset
|
1438 dinteger_t v = e1->toInteger(); |
336 | 1439 |
1440 s = mem.malloc((len + 1) * sz); | |
1441 memcpy((unsigned char *)s, &v, sz); | |
1442 memcpy((unsigned char *)s + sz, es2->string, es2->len * sz); | |
1443 | |
1444 // Add terminating 0 | |
1445 memset((unsigned char *)s + len * sz, 0, sz); | |
1446 | |
1447 es = new StringExp(loc, s, len); | |
1448 es->sz = sz; | |
1449 es->committed = es2->committed; | |
1450 t = es2->type; | |
1451 es->type = type; | |
1452 e = es; | |
1453 } | |
1454 else if (e1->op == TOKarrayliteral && e2->op == TOKarrayliteral && | |
1455 e1->type->equals(e2->type)) | |
1456 { | |
1457 // Concatenate the arrays | |
1458 ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1; | |
1459 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; | |
1460 | |
1461 es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy()); | |
1462 es1->elements->insert(es1->elements->dim, es2->elements); | |
1463 e = es1; | |
1464 | |
1465 if (type->toBasetype()->ty == Tsarray) | |
1466 { | |
1467 e->type = new TypeSArray(e1->type->toBasetype()->next, new IntegerExp(0, es1->elements->dim, Type::tindex)); | |
1468 e->type = e->type->semantic(loc, NULL); | |
1469 } | |
1470 else | |
1471 e->type = type; | |
1472 } | |
717
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1473 else if (e1->op == TOKarrayliteral && e2->op == TOKnull && |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1474 t1->nextOf()->equals(t2->nextOf())) |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1475 { |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1476 e = e1; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1477 goto L3; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1478 } |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1479 else if (e1->op == TOKnull && e2->op == TOKarrayliteral && |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1480 t1->nextOf()->equals(t2->nextOf())) |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1481 { |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1482 e = e2; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1483 L3: |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1484 // Concatenate the array with null |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1485 ArrayLiteralExp *es = (ArrayLiteralExp *)e; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1486 |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1487 es = new ArrayLiteralExp(es->loc, (Expressions *)es->elements->copy()); |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1488 e = es; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1489 |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1490 if (type->toBasetype()->ty == Tsarray) |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1491 { |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1492 e->type = new TypeSArray(t1->nextOf(), new IntegerExp(loc, es->elements->dim, Type::tindex)); |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1493 e->type = e->type->semantic(loc, NULL); |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1494 } |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1495 else |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1496 e->type = type; |
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
1497 } |
336 | 1498 else if ((e1->op == TOKarrayliteral || e1->op == TOKnull) && |
1499 e1->type->toBasetype()->nextOf()->equals(e2->type)) | |
1500 { | |
1501 ArrayLiteralExp *es1; | |
1502 if (e1->op == TOKarrayliteral) | |
1503 { es1 = (ArrayLiteralExp *)e1; | |
1504 es1 = new ArrayLiteralExp(es1->loc, (Expressions *)es1->elements->copy()); | |
1505 es1->elements->push(e2); | |
1506 } | |
1507 else | |
1508 { | |
1509 es1 = new ArrayLiteralExp(e1->loc, e2); | |
1510 } | |
1511 e = es1; | |
1512 | |
1513 if (type->toBasetype()->ty == Tsarray) | |
1514 { | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
1515 e->type = new TypeSArray(e2->type, new IntegerExp(loc, es1->elements->dim, Type::tindex)); |
336 | 1516 e->type = e->type->semantic(loc, NULL); |
1517 } | |
1518 else | |
1519 e->type = type; | |
1520 } | |
1521 else if (e2->op == TOKarrayliteral && | |
1522 e2->type->toBasetype()->nextOf()->equals(e1->type)) | |
1523 { | |
1524 ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2; | |
1525 | |
1526 es2 = new ArrayLiteralExp(es2->loc, (Expressions *)es2->elements->copy()); | |
1527 es2->elements->shift(e1); | |
1528 e = es2; | |
1529 | |
1530 if (type->toBasetype()->ty == Tsarray) | |
1531 { | |
1367
8026319762be
Merged DMD 1.045 !!!
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents:
1333
diff
changeset
|
1532 e->type = new TypeSArray(e1->type, new IntegerExp(loc, es2->elements->dim, Type::tindex)); |
336 | 1533 e->type = e->type->semantic(loc, NULL); |
1534 } | |
1535 else | |
1536 e->type = type; | |
1537 } | |
1538 else if (e1->op == TOKnull && e2->op == TOKstring) | |
1539 { | |
1540 t = e1->type; | |
1541 e = e2; | |
1542 goto L1; | |
1543 } | |
1544 else if (e1->op == TOKstring && e2->op == TOKnull) | |
1545 { e = e1; | |
1546 t = e2->type; | |
1547 L1: | |
1548 Type *tb = t->toBasetype(); | |
1549 if (tb->ty == Tarray && tb->nextOf()->equals(e->type)) | |
1550 { Expressions *expressions = new Expressions(); | |
1551 expressions->push(e); | |
1552 e = new ArrayLiteralExp(loc, expressions); | |
1553 e->type = t; | |
1554 } | |
1555 if (!e->type->equals(type)) | |
1556 { StringExp *se = (StringExp *)e->copy(); | |
1557 e = se->castTo(NULL, type); | |
1558 } | |
1559 } | |
1560 return e; | |
1561 } | |
1562 | |
1563 Expression *Ptr(Type *type, Expression *e1) | |
1564 { | |
1565 //printf("Ptr(e1 = %s)\n", e1->toChars()); | |
1566 if (e1->op == TOKadd) | |
1567 { AddExp *ae = (AddExp *)e1; | |
1568 if (ae->e1->op == TOKaddress && ae->e2->op == TOKint64) | |
1569 { AddrExp *ade = (AddrExp *)ae->e1; | |
1570 if (ade->e1->op == TOKstructliteral) | |
1571 { StructLiteralExp *se = (StructLiteralExp *)ade->e1; | |
1572 unsigned offset = ae->e2->toInteger(); | |
1573 Expression *e = se->getField(type, offset); | |
1574 if (!e) | |
1575 e = EXP_CANT_INTERPRET; | |
1576 return e; | |
1577 } | |
1578 } | |
1579 } | |
1580 return EXP_CANT_INTERPRET; | |
1581 } | |
1582 |