Mercurial > projects > ddmd
annotate dmd/StructLiteralExp.d @ 191:52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
Also changed Array allocation policy:
Now doesn't reallocate but malloc's, followed by a memcpy (no free).
(this fixes a crash while compiling druntime. Same bug in dmd)
author | korDen@korDen-pc |
---|---|
date | Sun, 25 Mar 2012 03:11:12 +0400 |
parents | b0d41ff5e0df |
children |
rev | line source |
---|---|
72 | 1 module dmd.StructLiteralExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
123 | 5 import dmd.GlobalExpressions; |
72 | 6 import dmd.MOD; |
7 import dmd.TypeStruct; | |
8 import dmd.TypeSArray; | |
9 import dmd.expression.Util; | |
10 import dmd.ErrorExp; | |
123 | 11 import dmd.Array; |
72 | 12 import dmd.Dsymbol; |
13 import dmd.VarDeclaration; | |
14 import dmd.StructDeclaration; | |
15 import dmd.FuncDeclaration; | |
16 import dmd.ThisDeclaration; | |
17 import dmd.backend.elem; | |
18 import dmd.InterState; | |
19 import dmd.MATCH; | |
20 import dmd.WANT; | |
21 import dmd.TY; | |
22 import dmd.Type; | |
23 import dmd.OutBuffer; | |
24 import dmd.Loc; | |
25 import dmd.Scope; | |
109 | 26 import dmd.Initializer; |
72 | 27 import dmd.InlineCostState; |
28 import dmd.IRState; | |
29 import dmd.InlineDoState; | |
30 import dmd.backend.Symbol; | |
31 import dmd.HdrGenState; | |
32 import dmd.backend.dt_t; | |
33 import dmd.InlineScanState; | |
79 | 34 import dmd.ArrayLiteralExp; |
72 | 35 import dmd.ArrayTypes; |
36 import dmd.TOK; | |
37 | |
38 import dmd.codegen.Util; | |
39 import dmd.backend.Util; | |
40 import dmd.backend.RTLSYM; | |
41 import dmd.backend.TYM; | |
42 import dmd.backend.mTY; | |
43 import dmd.backend.OPER; | |
44 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
45 import dmd.DDMDExtensions; |
72 | 46 |
0 | 47 class StructLiteralExp : Expression |
48 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
49 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
50 |
72 | 51 StructDeclaration sd; // which aggregate this is for |
79 | 52 Expressions elements; // parallels sd.fields[] with |
72 | 53 // NULL entries for fields to skip |
54 | |
55 Symbol* sym; // back end symbol to initialize with literal | |
56 size_t soffset; // offset from start of s | |
0 | 57 int fillHoles; // fill alignment 'holes' with zero |
58 | |
59 this(Loc loc, StructDeclaration sd, Expressions elements) | |
60 { | |
178 | 61 register(); |
72 | 62 super(loc, TOKstructliteral, StructLiteralExp.sizeof); |
63 this.sd = sd; | |
64 this.elements = elements; | |
65 this.sym = null; | |
66 this.soffset = 0; | |
67 this.fillHoles = 1; | |
0 | 68 } |
69 | |
72 | 70 override Expression syntaxCopy() |
0 | 71 { |
123 | 72 return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements)); |
0 | 73 } |
74 | |
72 | 75 override Expression semantic(Scope sc) |
0 | 76 { |
72 | 77 Expression e; |
78 int nfields = sd.fields.dim - sd.isnested; | |
79 | |
80 version (LOGSEMANTIC) { | |
81 printf("StructLiteralExp.semantic('%s')\n", toChars()); | |
82 } | |
83 if (type) | |
84 return this; | |
85 | |
86 // Run semantic() on each element | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
87 foreach(size_t i, Expression e; elements) |
72 | 88 { |
89 if (!e) | |
90 continue; | |
91 e = e.semantic(sc); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
92 elements[i] = e; |
72 | 93 } |
94 expandTuples(elements); | |
95 size_t offset = 0; | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
96 foreach(size_t i, Expression e; elements) |
72 | 97 { |
98 if (!e) | |
99 continue; | |
100 | |
101 if (!e.type) | |
102 error("%s has no value", e.toChars()); | |
103 e = resolveProperties(sc, e); | |
104 if (i >= nfields) | |
105 { | |
106 error("more initializers than fields of %s", sd.toChars()); | |
107 return new ErrorExp(); | |
108 } | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
109 auto s = sd.fields[i]; |
72 | 110 VarDeclaration v = s.isVarDeclaration(); |
111 assert(v); | |
112 if (v.offset < offset) | |
113 error("overlapping initialization for %s", v.toChars()); | |
114 offset = v.offset + cast(uint)v.type.size(); | |
115 | |
116 Type telem = v.type; | |
117 while (!e.implicitConvTo(telem) && telem.toBasetype().ty == Tsarray) | |
118 { | |
119 /* Static array initialization, as in: | |
120 * T[3][5] = e; | |
121 */ | |
122 telem = telem.toBasetype().nextOf(); | |
123 } | |
124 | |
125 e = e.implicitCastTo(sc, telem); | |
126 | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
127 elements[i] = e; |
72 | 128 } |
129 | |
130 /* Fill out remainder of elements[] with default initializers for fields[] | |
131 */ | |
132 for (size_t i = elements.dim; i < nfields; i++) | |
133 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
134 VarDeclaration v = sd.fields[i]; |
72 | 135 assert(v); |
136 assert(!v.isThisDeclaration()); | |
137 | |
138 if (v.offset < offset) | |
139 { | |
140 e = null; | |
141 sd.hasUnions = 1; | |
142 } | |
143 else | |
144 { | |
145 if (v.init) | |
146 { | |
147 e = v.init.toExpression(); | |
148 if (!e) | |
109 | 149 { |
72 | 150 error("cannot make expression out of initializer for %s", v.toChars()); |
109 | 151 e = new ErrorExp(); |
152 } | |
153 else if (v.scope_) | |
154 { | |
155 // Do deferred semantic anaylsis | |
156 Initializer i2 = v.init.syntaxCopy(); | |
157 i2 = i2.semantic(v.scope_, v.type); | |
158 e = i2.toExpression(); | |
159 v.scope_ = null; | |
160 } | |
72 | 161 } |
162 else | |
163 { | |
135 | 164 e = v.type.defaultInitLiteral(loc); |
72 | 165 } |
166 offset = v.offset + cast(uint)v.type.size(); | |
167 } | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
168 elements.push(e); |
72 | 169 } |
170 | |
171 type = sd.type; | |
63 | 172 return this; |
0 | 173 } |
174 | |
109 | 175 /************************************** |
176 * Gets expression at offset of type. | |
177 * Returns null if not found. | |
178 */ | |
0 | 179 Expression getField(Type type, uint offset) |
180 { | |
79 | 181 //printf("StructLiteralExp.getField(this = %s, type = %s, offset = %u)\n", |
182 // /*toChars()*/"", type.toChars(), offset); | |
183 Expression e = null; | |
184 int i = getFieldIndex(type, offset); | |
185 | |
186 if (i != -1) | |
187 { | |
188 //printf("\ti = %d\n", i); | |
189 assert(i < elements.dim); | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
85
diff
changeset
|
190 e = elements[i]; |
79 | 191 if (e) |
192 { | |
193 //writef("e = %s, e.type = %s\n", e.toChars(), e.type.toChars()); | |
194 | |
195 /* If type is a static array, and e is an initializer for that array, | |
196 * then the field initializer should be an array literal of e. | |
197 */ | |
198 if (e.type != type && type.ty == Tsarray) | |
199 { | |
200 TypeSArray tsa = cast(TypeSArray)type; | |
201 size_t length = cast(size_t) tsa.dim.toInteger(); | |
202 Expressions z = new Expressions; | |
203 z.setDim(length); | |
204 for (int q = 0; q < length; ++q) | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
85
diff
changeset
|
205 z[q] = e.copy(); |
79 | 206 e = new ArrayLiteralExp(loc, z); |
207 e.type = type; | |
208 } | |
209 else | |
210 { | |
211 e = e.copy(); | |
212 e.type = type; | |
213 } | |
214 } | |
215 } | |
216 return e; | |
0 | 217 } |
218 | |
219 int getFieldIndex(Type type, uint offset) | |
220 { | |
79 | 221 /* Find which field offset is by looking at the field offsets |
222 */ | |
223 if (elements.dim) | |
224 { | |
85
8e69d041a99d
Previous commit didn't compile. Fixed.
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
225 foreach (size_t i, VarDeclaration v; sd.fields) |
79 | 226 { |
227 assert(v); | |
228 | |
229 if (offset == v.offset && type.size() == v.type.size()) | |
230 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
85
diff
changeset
|
231 auto e = elements[i]; |
79 | 232 if (e) |
233 { | |
234 return i; | |
235 } | |
236 break; | |
237 } | |
238 } | |
239 } | |
240 return -1; | |
0 | 241 } |
242 | |
72 | 243 override elem* toElem(IRState* irs) |
0 | 244 { |
72 | 245 elem* e; |
246 size_t dim; | |
247 | |
248 //printf("StructLiteralExp.toElem() %s\n", toChars()); | |
249 | |
250 // struct symbol to initialize with the literal | |
251 Symbol* stmp = sym ? sym : symbol_genauto(sd.type.toCtype()); | |
252 | |
253 e = null; | |
254 | |
255 if (fillHoles) | |
256 { | |
257 /* Initialize all alignment 'holes' to zero. | |
258 * Do before initializing fields, as the hole filling process | |
259 * can spill over into the fields. | |
260 */ | |
261 size_t offset = 0; | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
262 foreach (VarDeclaration v; sd.fields) |
72 | 263 { |
264 assert(v); | |
265 | |
266 e = el_combine(e, fillHole(stmp, &offset, v.offset, sd.structsize)); | |
267 size_t vend = v.offset + cast(uint)v.type.size(); | |
268 if (offset < vend) | |
269 offset = vend; | |
270 } | |
271 e = el_combine(e, fillHole(stmp, &offset, sd.structsize, sd.structsize)); | |
272 } | |
273 | |
274 if (elements) | |
275 { | |
276 dim = elements.dim; | |
277 assert(dim <= sd.fields.dim); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
278 foreach (size_t i, Expression el; elements) |
72 | 279 { |
280 if (!el) | |
281 continue; | |
282 | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
283 VarDeclaration v = sd.fields[i]; |
72 | 284 assert(v); |
285 assert(!v.isThisDeclaration()); | |
286 | |
287 elem* e1; | |
288 if (tybasic(stmp.Stype.Tty) == TYnptr) | |
289 { | |
290 e1 = el_var(stmp); | |
291 e1.EV.sp.Voffset = soffset; | |
292 } | |
293 else | |
294 { | |
295 e1 = el_ptr(stmp); | |
296 if (soffset) | |
297 e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); | |
298 } | |
299 e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); | |
300 elem* ec = e1; // pointer to destination | |
301 | |
302 elem* ep = el.toElem(irs); | |
303 | |
304 Type t1b = v.type.toBasetype(); | |
305 Type t2b = el.type.toBasetype(); | |
306 if (t1b.ty == Tsarray) | |
307 { | |
308 if (t2b.implicitConvTo(t1b)) | |
309 { | |
310 ///version (DMDV2) { | |
311 // Determine if postblit is needed | |
312 int postblit = 0; | |
313 if (needsPostblit(t1b)) | |
314 postblit = 1; | |
315 | |
316 if (postblit) | |
317 { | |
318 /* Generate: | |
319 * _d_arrayctor(ti, From: ep, To: e1) | |
320 */ | |
321 Expression ti = t1b.nextOf().toBasetype().getTypeInfo(null); | |
322 elem* esize = el_long(TYsize_t, (cast(TypeSArray)t1b).dim.toInteger()); | |
323 e1 = el_pair(TYdarray, esize, e1); | |
324 ep = el_pair(TYdarray, el_copytree(esize), array_toPtr(el.type, ep)); | |
325 ep = el_params(e1, ep, ti.toElem(irs), null); | |
326 int rtl = RTLSYM_ARRAYCTOR; | |
327 e1 = el_bin(OPcall, type.totym(), el_var(rtlsym[rtl]), ep); | |
328 } | |
329 else | |
330 ///} | |
331 { | |
332 elem* esize = el_long(TYsize_t, t1b.size()); | |
333 ep = array_toPtr(el.type, ep); | |
334 e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize)); | |
335 } | |
336 } | |
337 else | |
338 { | |
339 elem* edim = el_long(TYsize_t, t1b.size() / t2b.size()); | |
340 e1 = setArray(e1, edim, t2b, ep, irs, TOKconstruct); | |
341 } | |
342 } | |
343 else | |
344 { | |
345 tym_t ty = v.type.totym(); | |
346 e1 = el_una(OPind, ty, e1); | |
347 if (tybasic(ty) == TYstruct) | |
348 e1.Enumbytes = cast(uint)v.type.size(); | |
349 e1 = el_bin(OPeq, ty, e1, ep); | |
350 if (tybasic(ty) == TYstruct) | |
351 { | |
352 e1.Eoper = OPstreq; | |
353 e1.Enumbytes = cast(uint)v.type.size(); | |
354 } | |
355 version (DMDV2) { | |
356 /* Call postblit() on e1 | |
357 */ | |
358 StructDeclaration sd = needsPostblit(v.type); | |
359 if (sd) | |
360 { | |
361 FuncDeclaration fd = sd.postblit; | |
362 ec = el_copytree(ec); | |
363 ec = callfunc(loc, irs, 1, Type.tvoid, ec, sd.type.pointerTo(), fd, fd.type, null, null); | |
364 e1 = el_bin(OPcomma, ec.Ety, e1, ec); | |
365 } | |
366 } | |
367 } | |
368 e = el_combine(e, e1); | |
369 } | |
370 } | |
371 | |
79 | 372 version (DMDV2) |
373 { | |
72 | 374 if (sd.isnested) |
375 { // Initialize the hidden 'this' pointer | |
376 assert(sd.fields.dim); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
377 auto s = sd.fields[sd.fields.dim - 1]; |
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
378 auto v = s.isThisDeclaration(); |
72 | 379 assert(v); |
380 | |
381 elem* e1; | |
382 if (tybasic(stmp.Stype.Tty) == TYnptr) | |
383 { | |
384 e1 = el_var(stmp); | |
385 e1.EV.sp.Voffset = soffset; | |
386 } | |
387 else | |
388 { | |
389 e1 = el_ptr(stmp); | |
390 if (soffset) | |
391 e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); | |
392 } | |
393 e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); | |
394 e1 = setEthis(loc, irs, e1, sd); | |
395 | |
396 e = el_combine(e, e1); | |
397 } | |
398 } | |
399 | |
400 elem* ev = el_var(stmp); | |
401 ev.Enumbytes = sd.structsize; | |
402 e = el_combine(e, ev); | |
403 el_setLoc(e,loc); | |
67 | 404 return e; |
0 | 405 } |
406 | |
72 | 407 override bool checkSideEffect(int flag) |
0 | 408 { |
79 | 409 bool f = 0; |
410 | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
85
diff
changeset
|
411 foreach (e; elements) |
79 | 412 { |
413 if (!e) | |
414 continue; | |
415 | |
416 f |= e.checkSideEffect(2); | |
417 } | |
418 if (flag == 0 && f == 0) | |
419 Expression.checkSideEffect(0); | |
420 return f; | |
0 | 421 } |
422 | |
72 | 423 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 424 { |
79 | 425 buf.writestring(sd.toChars()); |
426 buf.writeByte('('); | |
427 argsToCBuffer(buf, elements, hgs); | |
428 buf.writeByte(')'); | |
0 | 429 } |
430 | |
72 | 431 override void toMangleBuffer(OutBuffer buf) |
0 | 432 { |
79 | 433 size_t dim = elements ? elements.dim : 0; |
434 buf.printf("S%u", dim); | |
435 for (size_t i = 0; i < dim; i++) | |
436 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
85
diff
changeset
|
437 auto e = elements[i]; |
79 | 438 if (e) |
439 e.toMangleBuffer(buf); | |
440 else | |
441 buf.writeByte('v'); // 'v' for void | |
442 } | |
0 | 443 } |
444 | |
72 | 445 override void scanForNestedRef(Scope sc) |
0 | 446 { |
447 assert(false); | |
448 } | |
449 | |
72 | 450 override Expression optimize(int result) |
0 | 451 { |
72 | 452 if (elements) |
453 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
454 foreach (size_t i, Expression e; elements) |
72 | 455 { |
456 if (!e) | |
457 continue; | |
458 e = e.optimize(WANTvalue | (result & WANTinterpret)); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
459 elements[i] = e; |
72 | 460 } |
461 } | |
56 | 462 return this; |
0 | 463 } |
464 | |
72 | 465 override Expression interpret(InterState istate) |
0 | 466 { |
123 | 467 Expressions expsx = null; |
468 | |
469 version (LOG) { | |
470 printf("StructLiteralExp.interpret() %.*s\n", toChars()); | |
471 } | |
472 /* We don't know how to deal with overlapping fields | |
473 */ | |
474 if (sd.hasUnions) | |
475 { | |
476 error("Unions with overlapping fields are not yet supported in CTFE"); | |
477 return EXP_CANT_INTERPRET; | |
478 } | |
479 | |
480 if (elements) | |
481 { | |
482 foreach (size_t i, Expression e; elements) | |
483 { | |
484 if (!e) | |
485 continue; | |
486 | |
487 Expression ex = e.interpret(istate); | |
488 if (ex is EXP_CANT_INTERPRET) | |
489 { | |
490 delete expsx; | |
491 return EXP_CANT_INTERPRET; | |
492 } | |
493 | |
494 /* If any changes, do Copy On Write | |
495 */ | |
496 if (ex != e) | |
497 { | |
498 if (!expsx) | |
499 { | |
500 expsx = new Expressions(); | |
501 expsx.setDim(elements.dim); | |
502 for (size_t j = 0; j < elements.dim; j++) | |
503 { | |
504 expsx[j] = elements[j]; | |
505 } | |
506 } | |
507 expsx[i] = ex; | |
508 } | |
509 } | |
510 } | |
511 if (elements && expsx) | |
512 { | |
513 expandTuples(expsx); | |
514 if (expsx.dim != elements.dim) | |
515 { | |
516 delete expsx; | |
517 return EXP_CANT_INTERPRET; | |
518 } | |
519 StructLiteralExp se = new StructLiteralExp(loc, sd, expsx); | |
520 se.type = type; | |
521 return se; | |
522 } | |
523 return this; | |
0 | 524 } |
525 | |
72 | 526 override dt_t** toDt(dt_t** pdt) |
0 | 527 { |
147
9a2a1ae6c8e5
fix test runnable\structlit.d
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
135
diff
changeset
|
528 scope dts = new Array; |
123 | 529 dt_t *dt; |
530 dt_t *d; | |
531 uint offset; | |
532 | |
533 //printf("StructLiteralExp.toDt() %s)\n", toChars()); | |
534 dts.setDim(sd.fields.dim); | |
535 dts.zero(); | |
536 assert(elements.dim <= sd.fields.dim); | |
537 | |
538 foreach (uint i, Expression e; elements) | |
539 { | |
540 if (!e) | |
541 continue; | |
542 | |
543 dt = null; | |
544 e.toDt(&dt); | |
545 dts.data[i] = dt; | |
546 } | |
547 | |
548 offset = 0; | |
549 foreach (uint j, VarDeclaration v; sd.fields) | |
550 { | |
551 d = cast(dt_t*)dts.data[j]; | |
552 if (!d) | |
553 { // An instance specific initializer was not provided. | |
554 // Look to see if there's a default initializer from the | |
555 // struct definition | |
556 if (v.init) | |
557 { | |
558 d = v.init.toDt(); | |
559 } | |
560 else if (v.offset >= offset) | |
561 { | |
562 uint k; | |
563 uint offset2 = v.offset + cast(uint)v.type.size(); | |
564 // Make sure this field (v) does not overlap any explicitly | |
565 // initialized field. | |
566 for (k = j + 1; 1; k++) | |
567 { | |
568 if (k == dts.dim) // didn't find any overlap | |
569 { | |
570 v.type.toDt(&d); | |
571 break; | |
572 } | |
573 VarDeclaration v2 = sd.fields[k]; | |
574 | |
575 if (v2.offset < offset2 && dts.data[k]) | |
576 break; // overlap | |
577 } | |
578 } | |
579 } | |
580 if (d) | |
581 { | |
582 if (v.offset < offset) | |
583 error("duplicate union initialization for %s", v.toChars()); | |
584 else | |
585 { | |
586 uint sz = dt_size(d); | |
587 uint vsz = cast(uint)v.type.size(); | |
588 uint voffset = v.offset; | |
589 assert(sz <= vsz); | |
590 | |
591 uint dim = 1; | |
592 for (Type vt = v.type.toBasetype(); vt.ty == Tsarray; vt = vt.nextOf().toBasetype()) | |
593 { | |
594 TypeSArray tsa = cast(TypeSArray)vt; | |
595 dim *= tsa.dim.toInteger(); | |
596 } | |
597 | |
598 for (size_t i = 0; i < dim; i++) | |
599 { | |
600 if (offset < voffset) | |
601 pdt = dtnzeros(pdt, voffset - offset); | |
602 if (!d) | |
603 { | |
604 if (v.init) | |
605 d = v.init.toDt(); | |
606 else | |
607 v.type.toDt(&d); | |
608 } | |
609 pdt = dtcat(pdt, d); | |
610 d = null; | |
611 offset = voffset + sz; | |
612 voffset += vsz / dim; | |
613 if (sz == vsz) | |
614 break; | |
615 } | |
616 } | |
617 } | |
618 } | |
619 | |
620 if (offset < sd.structsize) | |
621 pdt = dtnzeros(pdt, sd.structsize - offset); | |
622 | |
623 return pdt; | |
0 | 624 } |
625 | |
79 | 626 version(DMDV2) |
627 { | |
191
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
628 override bool isLvalue() |
0 | 629 { |
191
52188e7e3fb5
Fixed deprecated features, now compiles with DMD2.058
korDen@korDen-pc
parents:
187
diff
changeset
|
630 return true; |
0 | 631 } |
79 | 632 } |
0 | 633 |
72 | 634 override Expression toLvalue(Scope sc, Expression e) |
0 | 635 { |
79 | 636 return this; |
0 | 637 } |
638 | |
79 | 639 version(DMDV2) |
640 { | |
72 | 641 override bool canThrow() |
0 | 642 { |
64 | 643 return arrayExpressionCanThrow(elements); |
0 | 644 } |
79 | 645 } |
0 | 646 |
72 | 647 override MATCH implicitConvTo(Type t) |
0 | 648 { |
72 | 649 static if (false) { |
650 printf("StructLiteralExp.implicitConvTo(this=%.*s, type=%.*s, t=%.*s)\n", | |
651 toChars(), type.toChars(), t.toChars()); | |
652 } | |
653 MATCH m = Expression.implicitConvTo(t); | |
654 if (m != MATCHnomatch) | |
655 return m; | |
656 if (type.ty == t.ty && type.ty == Tstruct && (cast(TypeStruct)type).sym == (cast(TypeStruct)t).sym) | |
657 { | |
658 m = MATCHconst; | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
659 foreach(e; elements) |
72 | 660 { |
661 Type te = e.type; | |
662 if (t.mod == 0) | |
663 te = te.mutableOf(); | |
664 else | |
665 { | |
135 | 666 assert(t.mod == MODimmutable); |
72 | 667 te = te.invariantOf(); |
668 } | |
669 MATCH m2 = e.implicitConvTo(te); | |
670 //printf("\t%s => %s, match = %d\n", e.toChars(), te.toChars(), m2); | |
671 if (m2 < m) | |
672 m = m2; | |
673 } | |
674 } | |
64 | 675 return m; |
0 | 676 } |
677 | |
72 | 678 override int inlineCost(InlineCostState* ics) |
0 | 679 { |
680 assert(false); | |
681 } | |
682 | |
72 | 683 override Expression doInline(InlineDoState ids) |
0 | 684 { |
685 assert(false); | |
686 } | |
687 | |
72 | 688 override Expression inlineScan(InlineScanState* iss) |
0 | 689 { |
690 assert(false); | |
691 } | |
692 } | |
693 |