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 }