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);