Mercurial > projects > ddmd
comparison dmd/StructLiteralExp.d @ 67:f708f0452e81
some of the backend/codegen stuff implemented
author | korDen |
---|---|
date | Mon, 23 Aug 2010 21:21:05 +0400 |
parents | 4290d870944a |
children | 2e2a5c3f943a |
comparison
equal
deleted
inserted
replaced
66:efb1e5bdf63c | 67:f708f0452e81 |
---|---|
1 module dmd.StructLiteralExp; | 1 module dmd.StructLiteralExp; |
2 | 2 |
3 import dmd.Expression; | 3 import dmd.Expression; |
4 import dmd.MOD; | 4 import dmd.MOD; |
5 import dmd.TypeStruct; | 5 import dmd.TypeStruct; |
6 import dmd.TypeSArray; | |
6 import dmd.expression.Util; | 7 import dmd.expression.Util; |
7 import dmd.ErrorExp; | 8 import dmd.ErrorExp; |
8 import dmd.Dsymbol; | 9 import dmd.Dsymbol; |
9 import dmd.VarDeclaration; | 10 import dmd.VarDeclaration; |
10 import dmd.StructDeclaration; | 11 import dmd.StructDeclaration; |
12 import dmd.FuncDeclaration; | |
13 import dmd.ThisDeclaration; | |
11 import dmd.backend.elem; | 14 import dmd.backend.elem; |
12 import dmd.InterState; | 15 import dmd.InterState; |
13 import dmd.MATCH; | 16 import dmd.MATCH; |
14 import dmd.WANT; | 17 import dmd.WANT; |
15 import dmd.TY; | 18 import dmd.TY; |
25 import dmd.backend.dt_t; | 28 import dmd.backend.dt_t; |
26 import dmd.InlineScanState; | 29 import dmd.InlineScanState; |
27 import dmd.ArrayTypes; | 30 import dmd.ArrayTypes; |
28 import dmd.TOK; | 31 import dmd.TOK; |
29 | 32 |
33 import dmd.codegen.Util; | |
34 import dmd.backend.Util; | |
35 import dmd.backend.RTLSYM; | |
36 import dmd.backend.TYM; | |
37 import dmd.backend.mTY; | |
38 import dmd.backend.OPER; | |
39 | |
30 | 40 |
31 class StructLiteralExp : Expression | 41 class StructLiteralExp : Expression |
32 { | 42 { |
33 StructDeclaration sd; // which aggregate this is for | 43 StructDeclaration sd; // which aggregate this is for |
34 Expressions elements; // parallels sd->fields[] with | 44 Expressions elements; // parallels sd->fields[] with |
156 assert(false); | 166 assert(false); |
157 } | 167 } |
158 | 168 |
159 elem* toElem(IRState* irs) | 169 elem* toElem(IRState* irs) |
160 { | 170 { |
161 assert(false); | 171 elem* e; |
172 size_t dim; | |
173 | |
174 //printf("StructLiteralExp.toElem() %s\n", toChars()); | |
175 | |
176 // struct symbol to initialize with the literal | |
177 Symbol* stmp = sym ? sym : symbol_genauto(sd.type.toCtype()); | |
178 | |
179 e = null; | |
180 | |
181 if (fillHoles) | |
182 { | |
183 /* Initialize all alignment 'holes' to zero. | |
184 * Do before initializing fields, as the hole filling process | |
185 * can spill over into the fields. | |
186 */ | |
187 size_t offset = 0; | |
188 for (size_t i = 0; i < sd.fields.dim; i++) | |
189 { | |
190 Dsymbol s = cast(Dsymbol)sd.fields.data[i]; | |
191 VarDeclaration v = s.isVarDeclaration(); | |
192 assert(v); | |
193 | |
194 e = el_combine(e, fillHole(stmp, &offset, v.offset, sd.structsize)); | |
195 size_t vend = v.offset + cast(uint)v.type.size(); | |
196 if (offset < vend) | |
197 offset = vend; | |
198 } | |
199 e = el_combine(e, fillHole(stmp, &offset, sd.structsize, sd.structsize)); | |
200 } | |
201 | |
202 if (elements) | |
203 { | |
204 dim = elements.dim; | |
205 assert(dim <= sd.fields.dim); | |
206 for (size_t i = 0; i < dim; i++) | |
207 { | |
208 Expression el = cast(Expression)elements.data[i]; | |
209 if (!el) | |
210 continue; | |
211 | |
212 Dsymbol s = cast(Dsymbol)sd.fields.data[i]; | |
213 VarDeclaration v = s.isVarDeclaration(); | |
214 assert(v); | |
215 assert(!v.isThisDeclaration()); | |
216 | |
217 elem* e1; | |
218 if (tybasic(stmp.Stype.Tty) == TYnptr) | |
219 { | |
220 e1 = el_var(stmp); | |
221 e1.EV.sp.Voffset = soffset; | |
222 } | |
223 else | |
224 { | |
225 e1 = el_ptr(stmp); | |
226 if (soffset) | |
227 e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); | |
228 } | |
229 e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); | |
230 elem* ec = e1; // pointer to destination | |
231 | |
232 elem* ep = el.toElem(irs); | |
233 | |
234 Type t1b = v.type.toBasetype(); | |
235 Type t2b = el.type.toBasetype(); | |
236 if (t1b.ty == Tsarray) | |
237 { | |
238 if (t2b.implicitConvTo(t1b)) | |
239 { | |
240 ///version (DMDV2) { | |
241 // Determine if postblit is needed | |
242 int postblit = 0; | |
243 if (needsPostblit(t1b)) | |
244 postblit = 1; | |
245 | |
246 if (postblit) | |
247 { | |
248 /* Generate: | |
249 * _d_arrayctor(ti, From: ep, To: e1) | |
250 */ | |
251 Expression ti = t1b.nextOf().toBasetype().getTypeInfo(null); | |
252 elem* esize = el_long(TYsize_t, (cast(TypeSArray)t1b).dim.toInteger()); | |
253 e1 = el_pair(TYdarray, esize, e1); | |
254 ep = el_pair(TYdarray, el_copytree(esize), array_toPtr(el.type, ep)); | |
255 ep = el_params(e1, ep, ti.toElem(irs), null); | |
256 int rtl = RTLSYM_ARRAYCTOR; | |
257 e1 = el_bin(OPcall, type.totym(), el_var(rtlsym[rtl]), ep); | |
258 } | |
259 else | |
260 ///} | |
261 { | |
262 elem* esize = el_long(TYsize_t, t1b.size()); | |
263 ep = array_toPtr(el.type, ep); | |
264 e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize)); | |
265 } | |
266 } | |
267 else | |
268 { | |
269 elem* edim = el_long(TYsize_t, t1b.size() / t2b.size()); | |
270 e1 = setArray(e1, edim, t2b, ep, irs, TOKconstruct); | |
271 } | |
272 } | |
273 else | |
274 { | |
275 tym_t ty = v.type.totym(); | |
276 e1 = el_una(OPind, ty, e1); | |
277 if (tybasic(ty) == TYstruct) | |
278 e1.Enumbytes = cast(uint)v.type.size(); | |
279 e1 = el_bin(OPeq, ty, e1, ep); | |
280 if (tybasic(ty) == TYstruct) | |
281 { | |
282 e1.Eoper = OPstreq; | |
283 e1.Enumbytes = cast(uint)v.type.size(); | |
284 } | |
285 version (DMDV2) { | |
286 /* Call postblit() on e1 | |
287 */ | |
288 StructDeclaration sd = needsPostblit(v.type); | |
289 if (sd) | |
290 { | |
291 FuncDeclaration fd = sd.postblit; | |
292 ec = el_copytree(ec); | |
293 ec = callfunc(loc, irs, 1, Type.tvoid, ec, sd.type.pointerTo(), fd, fd.type, null, null); | |
294 e1 = el_bin(OPcomma, ec.Ety, e1, ec); | |
295 } | |
296 } | |
297 } | |
298 e = el_combine(e, e1); | |
299 } | |
300 } | |
301 | |
302 version (DMDV2) { | |
303 if (sd.isnested) | |
304 { // Initialize the hidden 'this' pointer | |
305 assert(sd.fields.dim); | |
306 Dsymbol s = cast(Dsymbol)sd.fields.data[sd.fields.dim - 1]; | |
307 ThisDeclaration v = s.isThisDeclaration(); | |
308 assert(v); | |
309 | |
310 elem* e1; | |
311 if (tybasic(stmp.Stype.Tty) == TYnptr) | |
312 { | |
313 e1 = el_var(stmp); | |
314 e1.EV.sp.Voffset = soffset; | |
315 } | |
316 else | |
317 { | |
318 e1 = el_ptr(stmp); | |
319 if (soffset) | |
320 e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); | |
321 } | |
322 e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); | |
323 e1 = setEthis(loc, irs, e1, sd); | |
324 | |
325 e = el_combine(e, e1); | |
326 } | |
327 } | |
328 | |
329 elem* ev = el_var(stmp); | |
330 ev.Enumbytes = sd.structsize; | |
331 e = el_combine(e, ev); | |
332 el_setLoc(e,loc); | |
333 return e; | |
162 } | 334 } |
163 | 335 |
164 bool checkSideEffect(int flag) | 336 bool checkSideEffect(int flag) |
165 { | 337 { |
166 assert(false); | 338 assert(false); |