Mercurial > projects > ddmd
comparison dmd/StructInitializer.d @ 67:f708f0452e81
some of the backend/codegen stuff implemented
author | korDen |
---|---|
date | Mon, 23 Aug 2010 21:21:05 +0400 |
parents | 51605de93870 |
children | 2e2a5c3f943a |
comparison
equal
deleted
inserted
replaced
66:efb1e5bdf63c | 67:f708f0452e81 |
---|---|
1 module dmd.StructInitializer; | 1 module dmd.StructInitializer; |
2 | 2 |
3 import dmd.Initializer; | 3 import dmd.Initializer; |
4 import dmd.TOK; | 4 import dmd.TOK; |
5 import dmd.TypeSArray; | |
5 import dmd.FuncLiteralDeclaration; | 6 import dmd.FuncLiteralDeclaration; |
6 import dmd.TypeFunction; | 7 import dmd.TypeFunction; |
7 import dmd.StructDeclaration; | 8 import dmd.StructDeclaration; |
8 import dmd.StructLiteralExp; | 9 import dmd.StructLiteralExp; |
9 import dmd.ArrayTypes; | 10 import dmd.ArrayTypes; |
25 import dmd.ExpInitializer; | 26 import dmd.ExpInitializer; |
26 import dmd.FuncExp; | 27 import dmd.FuncExp; |
27 import dmd.LINK; | 28 import dmd.LINK; |
28 | 29 |
29 import dmd.backend.dt_t; | 30 import dmd.backend.dt_t; |
31 import dmd.backend.Util; | |
30 | 32 |
31 class StructInitializer : Initializer | 33 class StructInitializer : Initializer |
32 { | 34 { |
33 Identifiers field; // of Identifier *'s | 35 Identifiers field; // of Identifier *'s |
34 Initializers value; // parallel array of Initializer *'s | 36 Initializers value; // parallel array of Initializer *'s |
217 assert(false); | 219 assert(false); |
218 } | 220 } |
219 | 221 |
220 dt_t* toDt() | 222 dt_t* toDt() |
221 { | 223 { |
222 assert(false); | 224 scope Array dts = new Array(); |
225 uint i; | |
226 uint j; | |
227 dt_t* dt; | |
228 dt_t* d; | |
229 dt_t** pdtend; | |
230 uint offset; | |
231 | |
232 //printf("StructInitializer.toDt('%s')\n", toChars()); | |
233 dts.setDim(ad.fields.dim); | |
234 dts.zero(); | |
235 | |
236 for (i = 0; i < vars.dim; i++) | |
237 { | |
238 VarDeclaration v = cast(VarDeclaration)vars.data[i]; | |
239 Initializer val = cast(Initializer)value.data[i]; | |
240 | |
241 //printf("vars[%d] = %s\n", i, v.toChars()); | |
242 | |
243 for (j = 0; 1; j++) | |
244 { | |
245 assert(j < dts.dim); | |
246 //printf(" adfield[%d] = %s\n", j, ((VarDeclaration *)ad.fields.data[j]).toChars()); | |
247 if (cast(VarDeclaration)ad.fields.data[j] == v) | |
248 { | |
249 if (dts.data[j]) | |
250 error(loc, "field %s of %s already initialized", v.toChars(), ad.toChars()); | |
251 dts.data[j] = cast(void*)val.toDt(); | |
252 break; | |
253 } | |
254 } | |
255 } | |
256 | |
257 dt = null; | |
258 pdtend = &dt; | |
259 offset = 0; | |
260 for (j = 0; j < dts.dim; j++) | |
261 { | |
262 VarDeclaration v = cast(VarDeclaration)ad.fields.data[j]; | |
263 | |
264 d = cast(dt_t*)dts.data[j]; | |
265 if (!d) | |
266 { | |
267 // An instance specific initializer was not provided. | |
268 // Look to see if there's a default initializer from the | |
269 // struct definition | |
270 if (v.init) | |
271 { | |
272 d = v.init.toDt(); | |
273 } | |
274 else if (v.offset >= offset) | |
275 { | |
276 uint k; | |
277 uint offset2 = v.offset + cast(uint)v.type.size(); | |
278 // Make sure this field does not overlap any explicitly | |
279 // initialized field. | |
280 for (k = j + 1; 1; k++) | |
281 { | |
282 if (k == dts.dim) // didn't find any overlap | |
283 { | |
284 v.type.toDt(&d); | |
285 break; | |
286 } | |
287 VarDeclaration v2 = cast(VarDeclaration)ad.fields.data[k]; | |
288 | |
289 if (v2.offset < offset2 && dts.data[k]) | |
290 break; // overlap | |
291 } | |
292 } | |
293 } | |
294 if (d) | |
295 { | |
296 if (v.offset < offset) | |
297 error(loc, "duplicate union initialization for %s", v.toChars()); | |
298 else | |
299 { | |
300 uint sz = dt_size(d); | |
301 uint vsz = cast(uint)v.type.size(); | |
302 uint voffset = v.offset; | |
303 | |
304 uint dim = 1; | |
305 for (Type vt = v.type.toBasetype(); | |
306 vt.ty == Tsarray; | |
307 vt = vt.nextOf().toBasetype()) | |
308 { | |
309 TypeSArray tsa = cast(TypeSArray)vt; | |
310 dim *= tsa.dim.toInteger(); | |
311 } | |
312 assert(sz == vsz || sz * dim <= vsz); | |
313 | |
314 for (size_t k = 0; k < dim; k++) | |
315 { | |
316 if (offset < voffset) | |
317 pdtend = dtnzeros(pdtend, voffset - offset); | |
318 if (!d) | |
319 { | |
320 if (v.init) | |
321 d = v.init.toDt(); | |
322 else | |
323 v.type.toDt(&d); | |
324 } | |
325 pdtend = dtcat(pdtend, d); | |
326 d = null; | |
327 offset = voffset + sz; | |
328 voffset += vsz / dim; | |
329 if (sz == vsz) | |
330 break; | |
331 } | |
332 } | |
333 } | |
334 } | |
335 | |
336 if (offset < ad.structsize) | |
337 dtnzeros(pdtend, ad.structsize - offset); | |
338 | |
339 return dt; | |
223 } | 340 } |
224 | 341 |
225 StructInitializer isStructInitializer() { return this; } | 342 StructInitializer isStructInitializer() { return this; } |
226 } | 343 } |