Mercurial > projects > ddmd
diff 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 |
line wrap: on
line diff
--- a/dmd/StructLiteralExp.d Mon Aug 23 20:38:30 2010 +0400 +++ b/dmd/StructLiteralExp.d Mon Aug 23 21:21:05 2010 +0400 @@ -3,11 +3,14 @@ import dmd.Expression; import dmd.MOD; import dmd.TypeStruct; +import dmd.TypeSArray; import dmd.expression.Util; import dmd.ErrorExp; import dmd.Dsymbol; import dmd.VarDeclaration; import dmd.StructDeclaration; +import dmd.FuncDeclaration; +import dmd.ThisDeclaration; import dmd.backend.elem; import dmd.InterState; import dmd.MATCH; @@ -27,6 +30,13 @@ import dmd.ArrayTypes; import dmd.TOK; +import dmd.codegen.Util; +import dmd.backend.Util; +import dmd.backend.RTLSYM; +import dmd.backend.TYM; +import dmd.backend.mTY; +import dmd.backend.OPER; + class StructLiteralExp : Expression { @@ -158,7 +168,169 @@ elem* toElem(IRState* irs) { - assert(false); + elem* e; + size_t dim; + + //printf("StructLiteralExp.toElem() %s\n", toChars()); + + // struct symbol to initialize with the literal + Symbol* stmp = sym ? sym : symbol_genauto(sd.type.toCtype()); + + e = null; + + if (fillHoles) + { + /* Initialize all alignment 'holes' to zero. + * Do before initializing fields, as the hole filling process + * can spill over into the fields. + */ + size_t offset = 0; + for (size_t i = 0; i < sd.fields.dim; i++) + { + Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + VarDeclaration v = s.isVarDeclaration(); + assert(v); + + e = el_combine(e, fillHole(stmp, &offset, v.offset, sd.structsize)); + size_t vend = v.offset + cast(uint)v.type.size(); + if (offset < vend) + offset = vend; + } + e = el_combine(e, fillHole(stmp, &offset, sd.structsize, sd.structsize)); + } + + if (elements) + { + dim = elements.dim; + assert(dim <= sd.fields.dim); + for (size_t i = 0; i < dim; i++) + { + Expression el = cast(Expression)elements.data[i]; + if (!el) + continue; + + Dsymbol s = cast(Dsymbol)sd.fields.data[i]; + VarDeclaration v = s.isVarDeclaration(); + assert(v); + assert(!v.isThisDeclaration()); + + elem* e1; + if (tybasic(stmp.Stype.Tty) == TYnptr) + { + e1 = el_var(stmp); + e1.EV.sp.Voffset = soffset; + } + else + { + e1 = el_ptr(stmp); + if (soffset) + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); + } + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); + elem* ec = e1; // pointer to destination + + elem* ep = el.toElem(irs); + + Type t1b = v.type.toBasetype(); + Type t2b = el.type.toBasetype(); + if (t1b.ty == Tsarray) + { + if (t2b.implicitConvTo(t1b)) + { + ///version (DMDV2) { + // Determine if postblit is needed + int postblit = 0; + if (needsPostblit(t1b)) + postblit = 1; + + if (postblit) + { + /* Generate: + * _d_arrayctor(ti, From: ep, To: e1) + */ + Expression ti = t1b.nextOf().toBasetype().getTypeInfo(null); + elem* esize = el_long(TYsize_t, (cast(TypeSArray)t1b).dim.toInteger()); + e1 = el_pair(TYdarray, esize, e1); + ep = el_pair(TYdarray, el_copytree(esize), array_toPtr(el.type, ep)); + ep = el_params(e1, ep, ti.toElem(irs), null); + int rtl = RTLSYM_ARRAYCTOR; + e1 = el_bin(OPcall, type.totym(), el_var(rtlsym[rtl]), ep); + } + else + ///} + { + elem* esize = el_long(TYsize_t, t1b.size()); + ep = array_toPtr(el.type, ep); + e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize)); + } + } + else + { + elem* edim = el_long(TYsize_t, t1b.size() / t2b.size()); + e1 = setArray(e1, edim, t2b, ep, irs, TOKconstruct); + } + } + else + { + tym_t ty = v.type.totym(); + e1 = el_una(OPind, ty, e1); + if (tybasic(ty) == TYstruct) + e1.Enumbytes = cast(uint)v.type.size(); + e1 = el_bin(OPeq, ty, e1, ep); + if (tybasic(ty) == TYstruct) + { + e1.Eoper = OPstreq; + e1.Enumbytes = cast(uint)v.type.size(); + } +version (DMDV2) { + /* Call postblit() on e1 + */ + StructDeclaration sd = needsPostblit(v.type); + if (sd) + { + FuncDeclaration fd = sd.postblit; + ec = el_copytree(ec); + ec = callfunc(loc, irs, 1, Type.tvoid, ec, sd.type.pointerTo(), fd, fd.type, null, null); + e1 = el_bin(OPcomma, ec.Ety, e1, ec); + } +} + } + e = el_combine(e, e1); + } + } + +version (DMDV2) { + if (sd.isnested) + { // Initialize the hidden 'this' pointer + assert(sd.fields.dim); + Dsymbol s = cast(Dsymbol)sd.fields.data[sd.fields.dim - 1]; + ThisDeclaration v = s.isThisDeclaration(); + assert(v); + + elem* e1; + if (tybasic(stmp.Stype.Tty) == TYnptr) + { + e1 = el_var(stmp); + e1.EV.sp.Voffset = soffset; + } + else + { + e1 = el_ptr(stmp); + if (soffset) + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset)); + } + e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset)); + e1 = setEthis(loc, irs, e1, sd); + + e = el_combine(e, e1); + } +} + + elem* ev = el_var(stmp); + ev.Enumbytes = sd.structsize; + e = el_combine(e, ev); + el_setLoc(e,loc); + return e; } bool checkSideEffect(int flag)