[svn r355] Get rid of IRState::exps and topexp.

This commit is contained in:
Christian Kamm 2008-07-12 15:43:13 +02:00
parent f0d8b9e153
commit 717d52d4f0
8 changed files with 39 additions and 214 deletions

View file

@ -528,9 +528,7 @@ DSliceValue* DtoCatAssignElement(DValue* array, Expression* exp)
DValue* dptr = new DVarValue(exp->type, ptr, true); DValue* dptr = new DVarValue(exp->type, ptr, true);
gIR->exps.push_back(IRExp(0,exp,dptr));
DValue* e = exp->toElem(gIR); DValue* e = exp->toElem(gIR);
gIR->exps.pop_back();
if (!e->inPlace()) if (!e->inPlace())
DtoAssign(dptr, e); DtoAssign(dptr, e);

View file

@ -72,12 +72,6 @@ DFuncValue::DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt)
cc = (unsigned)-1; cc = (unsigned)-1;
} }
LLValue* DFuncValue::getLVal()
{
assert(0);
return 0;
}
LLValue* DFuncValue::getRVal() LLValue* DFuncValue::getRVal()
{ {
assert(val); assert(val);

View file

@ -42,6 +42,8 @@ struct DValue : Object
virtual LLValue* getLVal() { assert(0); return 0; } virtual LLValue* getLVal() { assert(0); return 0; }
virtual LLValue* getRVal() { assert(0); return 0; } virtual LLValue* getRVal() { assert(0); return 0; }
virtual bool isLVal() { return false; }
virtual DImValue* isIm() { return NULL; } virtual DImValue* isIm() { return NULL; }
virtual DConstValue* isConst() { return NULL; } virtual DConstValue* isConst() { return NULL; }
virtual DNullValue* isNull() { return NULL; } virtual DNullValue* isNull() { return NULL; }
@ -113,6 +115,7 @@ struct DVarValue : DValue
DVarValue(Type* vd, LLValue* lv, LLValue* rv); DVarValue(Type* vd, LLValue* lv, LLValue* rv);
DVarValue(Type* t, LLValue* llvmValue, bool lvalue); DVarValue(Type* t, LLValue* llvmValue, bool lvalue);
virtual bool isLVal() { return val && lval; }
virtual LLValue* getLVal(); virtual LLValue* getLVal();
virtual LLValue* getRVal(); virtual LLValue* getRVal();
@ -134,13 +137,6 @@ struct DThisValue : DVarValue
virtual DThisValue* isThis() { return this; } virtual DThisValue* isThis() { return this; }
}; };
// array length d-value
struct DArrayLenValue : DVarValue
{
DArrayLenValue(Type* t, LLValue* llvmValue) : DVarValue(t, llvmValue, true) {}
virtual DArrayLenValue* isArrayLen() { return this; }
};
// slice d-value // slice d-value
struct DSliceValue : DValue struct DSliceValue : DValue
{ {
@ -165,7 +161,6 @@ struct DFuncValue : DValue
DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt = 0); DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt = 0);
virtual LLValue* getLVal();
virtual LLValue* getRVal(); virtual LLValue* getRVal();
virtual Type* getType() { assert(type); return type; } virtual Type* getType() { assert(type); return type; }
@ -187,6 +182,7 @@ struct DLRValue : DValue
rval = r; rval = r;
} }
virtual bool isLVal() { return lval; }
virtual LLValue* getLVal() { assert(lval); return lval; } virtual LLValue* getLVal() { assert(lval); return lval; }
virtual LLValue* getRVal() { assert(rval); return rval; } virtual LLValue* getRVal() { assert(rval); return rval; }
@ -196,6 +192,13 @@ struct DLRValue : DValue
virtual DLRValue* isLRValue() { return this; } virtual DLRValue* isLRValue() { return this; }
}; };
// array length d-value
struct DArrayLenValue : DLRValue
{
DArrayLenValue(Type* lt, LLValue* l, Type* rt, LLValue* r) : DLRValue(lt, l, rt, r) {}
virtual DArrayLenValue* isArrayLen() { return this; }
};
// complex number immediate d-value (much like slice) // complex number immediate d-value (much like slice)
struct DComplexValue : DValue struct DComplexValue : DValue
{ {

View file

@ -828,9 +828,7 @@ void DtoVariadicArgument(Expression* argexp, LLValue* dst)
Logger::println("DtoVariadicArgument"); Logger::println("DtoVariadicArgument");
LOG_SCOPE; LOG_SCOPE;
DVarValue* vv = new DVarValue(argexp->type, dst, true); DVarValue* vv = new DVarValue(argexp->type, dst, true);
gIR->exps.push_back(IRExp(NULL, argexp, vv));
DtoAssign(vv, argexp->toElem(gIR)); DtoAssign(vv, argexp->toElem(gIR));
gIR->exps.pop_back();
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////

View file

@ -95,11 +95,6 @@ IrStruct* IRState::topstruct()
return structs.back(); return structs.back();
} }
IRExp* IRState::topexp()
{
return exps.empty() ? NULL : &exps.back();
}
IRScope& IRState::scope() IRScope& IRState::scope()
{ {
assert(!scopes.empty()); assert(!scopes.empty());
@ -173,18 +168,3 @@ IRBuilder* IRBuilderHelper::operator->()
assert(b.GetInsertBlock() != NULL); assert(b.GetInsertBlock() != NULL);
return &b; return &b;
} }
//////////////////////////////////////////////////////////////////////////////////////////
IRExp::IRExp()
{
e1 = e2 = NULL;
v = NULL;
}
IRExp::IRExp(Expression* l, Expression* r, DValue* val)
{
e1 = l;
e2 = r;
v = val;
}

View file

@ -59,15 +59,6 @@ struct IRBuilderHelper
IRBuilder* operator->(); IRBuilder* operator->();
}; };
struct IRExp
{
Expression* e1;
Expression* e2;
DValue* v;
IRExp();
IRExp(Expression* l, Expression* r, DValue* val);
};
struct IRAsmStmt struct IRAsmStmt
{ {
std::string code; std::string code;
@ -161,11 +152,6 @@ struct IRState
bool emitMain; bool emitMain;
llvm::Function* mainFunc; llvm::Function* mainFunc;
// expression l/r value handling
typedef std::vector<IRExp> ExpVec;
ExpVec exps;
IRExp* topexp();
// basic block scopes // basic block scopes
std::vector<IRScope> scopes; std::vector<IRScope> scopes;
IRScope& scope(); IRScope& scope();

View file

@ -64,9 +64,7 @@ void ReturnStatement::toIR(IRState* p)
DValue* rvar = new DVarValue(f->type->next, f->decl->ir.irFunc->retArg, true); DValue* rvar = new DVarValue(f->type->next, f->decl->ir.irFunc->retArg, true);
p->exps.push_back(IRExp(NULL,exp,rvar));
DValue* e = exp->toElem(p); DValue* e = exp->toElem(p);
p->exps.pop_back();
if (!e->inPlace()) if (!e->inPlace())
DtoAssign(rvar, e); DtoAssign(rvar, e);

View file

@ -470,24 +470,10 @@ DValue* StringExp::toElem(IRState* p)
if (dtype->ty == Tarray) { if (dtype->ty == Tarray) {
LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false); LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false);
if (!p->topexp() || p->topexp()->e2 != this) {
LLValue* tmpmem = new llvm::AllocaInst(DtoType(dtype),"tempstring",p->topallocapoint()); LLValue* tmpmem = new llvm::AllocaInst(DtoType(dtype),"tempstring",p->topallocapoint());
DtoSetArray(tmpmem, clen, arrptr); DtoSetArray(tmpmem, clen, arrptr);
return new DVarValue(type, tmpmem, true); return new DVarValue(type, tmpmem, true);
} }
else if (p->topexp()->e2 == this) {
DValue* arr = p->topexp()->v;
assert(arr);
if (arr->isSlice()) {
return new DSliceValue(type, clen, arrptr);
}
else {
DtoSetArray(arr->getRVal(), clen, arrptr);
return new DImValue(type, arr->getLVal(), true);
}
}
assert(0);
}
else if (dtype->ty == Tsarray) { else if (dtype->ty == Tsarray) {
const LLType* dstType = getPtrToType(LLArrayType::get(ct, len)); const LLType* dstType = getPtrToType(LLArrayType::get(ct, len));
LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType);
@ -577,14 +563,9 @@ DValue* AssignExp::toElem(IRState* p)
Logger::print("AssignExp::toElem: %s | %s = %s\n", toChars(), e1->type->toChars(), e2->type ? e2->type->toChars() : 0); Logger::print("AssignExp::toElem: %s | %s = %s\n", toChars(), e1->type->toChars(), e2->type ? e2->type->toChars() : 0);
LOG_SCOPE; LOG_SCOPE;
p->exps.push_back(IRExp(e1,e2,NULL));
DValue* l = e1->toElem(p); DValue* l = e1->toElem(p);
p->topexp()->v = l;
DValue* r = e2->toElem(p); DValue* r = e2->toElem(p);
p->exps.pop_back();
Logger::println("performing assignment"); Logger::println("performing assignment");
DImValue* im = r->isIm(); DImValue* im = r->isIm();
@ -592,8 +573,11 @@ DValue* AssignExp::toElem(IRState* p)
Logger::println("assignment not inplace"); Logger::println("assignment not inplace");
if (DArrayLenValue* al = l->isArrayLen()) if (DArrayLenValue* al = l->isArrayLen())
{ {
DSliceValue* slice = DtoResizeDynArray(l->getType(), l, r); DLRValue* arrlenval = l->isLRValue();
DtoAssign(l, slice); assert(arrlenval);
DVarValue arrval(arrlenval->getLType(), arrlenval->getLVal(), true);
DSliceValue* slice = DtoResizeDynArray(arrval.getType(), &arrval, r);
DtoAssign(&arrval, slice);
} }
else else
{ {
@ -672,10 +656,8 @@ DValue* AddAssignExp::toElem(IRState* p)
Logger::print("AddAssignExp::toElem: %s\n", toChars()); Logger::print("AddAssignExp::toElem: %s\n", toChars());
LOG_SCOPE; LOG_SCOPE;
p->exps.push_back(IRExp(e1,e2,NULL));
DValue* l = e1->toElem(p); DValue* l = e1->toElem(p);
DValue* r = e2->toElem(p); DValue* r = e2->toElem(p);
p->exps.pop_back();
Type* t = DtoDType(type); Type* t = DtoDType(type);
@ -692,17 +674,10 @@ DValue* AddAssignExp::toElem(IRState* p)
} }
DtoAssign(l, res); DtoAssign(l, res);
// used as lvalue :/ // might need to return l here if used as an lvalue
if (p->topexp() && p->topexp()->e1 == this) // but when can this ever happen?
{
assert(!l->isLRValue());
return l;
}
else
{
return res; return res;
} }
}
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -1030,31 +1005,13 @@ DValue* CallExp::toElem(IRState* p)
LLFunctionType::param_iterator argiter = llfnty->param_begin(); LLFunctionType::param_iterator argiter = llfnty->param_begin();
int j = 0; int j = 0;
IRExp* topexp = p->topexp();
bool isInPlace = false;
// attrs // attrs
llvm::PAListPtr palist; llvm::PAListPtr palist;
// hidden struct return arguments // hidden struct return arguments
// TODO: use sret param attr // TODO: use sret param attr
if (retinptr) { if (retinptr) {
if (topexp && topexp->e2 == this) {
assert(topexp->v);
LLValue* tlv = topexp->v->getLVal();
assert(isaStruct(tlv->getType()->getContainedType(0)));
llargs[j] = tlv;
isInPlace = true;
/*if (DtoIsPassedByRef(tf->next)) {
isInPlace = true;
}
else
assert(0);*/
}
else {
llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint()); llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint());
}
if (dfn && dfn->func && dfn->func->runTimeHack) { if (dfn && dfn->func && dfn->func->runTimeHack) {
const LLType* rettype = getPtrToType(DtoType(type)); const LLType* rettype = getPtrToType(DtoType(type));
@ -1288,7 +1245,7 @@ DValue* CallExp::toElem(IRState* p)
// param attrs // param attrs
call->setParamAttrs(palist); call->setParamAttrs(palist);
return new DImValue(type, retllval, isInPlace); return new DImValue(type, retllval, false);
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -1302,19 +1259,14 @@ DValue* CastExp::toElem(IRState* p)
DValue* v = DtoCast(u, to); DValue* v = DtoCast(u, to);
if (v->isSlice()) { if (v->isSlice()) {
assert(!gIR->topexp() || gIR->topexp()->e1 != this); // only valid as rvalue!
return v; return v;
} }
else if (DLRValue* lr = u->isLRValue()) else if(u->isLVal())
return new DLRValue(lr->getLType(), lr->getLVal(), to, v->getRVal());
else if (u->isVar() && u->isVar()->lval)
return new DLRValue(e1->type, u->getLVal(), to, v->getRVal());
else if (gIR->topexp() && gIR->topexp()->e1 == this)
return new DLRValue(e1->type, u->getLVal(), to, v->getRVal()); return new DLRValue(e1->type, u->getLVal(), to, v->getRVal());
else
return v; return v;
} }
@ -1365,17 +1317,12 @@ DValue* PtrExp::toElem(IRState* p)
DValue* a = e1->toElem(p); DValue* a = e1->toElem(p);
if (p->topexp() && p->topexp()->e1 == this) {
Logger::println("lval PtrExp");
return new DVarValue(type, a->getRVal(), true);
}
// this should be deterministic but right now lvalue casts don't propagate lvalueness !?! // this should be deterministic but right now lvalue casts don't propagate lvalueness !?!
LLValue* lv = a->getRVal(); LLValue* lv = a->getRVal();
LLValue* v = lv; LLValue* v = lv;
if (DtoCanLoad(v)) if (DtoCanLoad(v))
v = DtoLoad(v); v = DtoLoad(v);
return new DLRValue(e1->type, lv, type, v); return new DLRValue(type, lv, type, v);
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -2000,14 +1947,7 @@ DValue* ArrayLengthExp::toElem(IRState* p)
DValue* u = e1->toElem(p); DValue* u = e1->toElem(p);
Logger::println("e1 = %s", e1->type->toChars()); Logger::println("e1 = %s", e1->type->toChars());
if (p->topexp() && p->topexp()->e1 == this) return new DArrayLenValue(e1->type, u->getLVal(), type, DtoArrayLen(u));
{
return new DArrayLenValue(e1->type, u->getLVal());
}
else
{
return new DImValue(type, DtoArrayLen(u));
}
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -2152,11 +2092,8 @@ DValue* X##AssignExp::toElem(IRState* p) \
{ \ { \
Logger::print("%sAssignExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \ Logger::print("%sAssignExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \
LOG_SCOPE; \ LOG_SCOPE; \
p->exps.push_back(IRExp(e1,e2,NULL)); \
DValue* u = e1->toElem(p); \ DValue* u = e1->toElem(p); \
p->topexp()->v = u; \
DValue* v = e2->toElem(p); \ DValue* v = e2->toElem(p); \
p->exps.pop_back(); \
LLValue* uval = u->getRVal(); \ LLValue* uval = u->getRVal(); \
LLValue* vval = v->getRVal(); \ LLValue* vval = v->getRVal(); \
LLValue* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \ LLValue* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \
@ -2189,11 +2126,8 @@ DValue* ShrAssignExp::toElem(IRState* p)
{ {
Logger::print("ShrAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); Logger::print("ShrAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE; LOG_SCOPE;
p->exps.push_back(IRExp(e1,e2,NULL));
DValue* u = e1->toElem(p); DValue* u = e1->toElem(p);
p->topexp()->v = u;
DValue* v = e2->toElem(p); DValue* v = e2->toElem(p);
p->exps.pop_back();
LLValue* uval = u->getRVal(); LLValue* uval = u->getRVal();
LLValue* vval = v->getRVal(); LLValue* vval = v->getRVal();
LLValue* tmp; LLValue* tmp;
@ -2239,16 +2173,7 @@ DValue* DelegateExp::toElem(IRState* p)
const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty); const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty);
LLValue* lval; LLValue* lval = new llvm::AllocaInst(DtoType(type), "tmpdelegate", p->topallocapoint());
bool inplace = false;
if (p->topexp() && p->topexp()->e2 == this) {
assert(p->topexp()->v);
lval = p->topexp()->v->getLVal();
inplace = true;
}
else {
lval = new llvm::AllocaInst(DtoType(type), "tmpdelegate", p->topallocapoint());
}
DValue* u = e1->toElem(p); DValue* u = e1->toElem(p);
LLValue* uval; LLValue* uval;
@ -2300,7 +2225,7 @@ DValue* DelegateExp::toElem(IRState* p)
castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0)); castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0));
DtoStore(castfptr, fptr); DtoStore(castfptr, fptr);
return new DImValue(type, lval, inplace); return new DImValue(type, lval);
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -2517,18 +2442,8 @@ DValue* FuncExp::toElem(IRState* p)
DtoForceDefineDsymbol(fd); DtoForceDefineDsymbol(fd);
bool temp = false;
LLValue* lval = NULL;
if (p->topexp() && p->topexp()->e2 == this) {
assert(p->topexp()->v);
lval = p->topexp()->v->getLVal();
}
else {
const LLType* dgty = DtoType(type); const LLType* dgty = DtoType(type);
Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; LLValue* lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint());
lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint());
temp = true;
}
LLValue* context = DtoGEPi(lval,0,0); LLValue* context = DtoGEPi(lval,0,0);
const LLPointerType* pty = isaPointer(context->getType()->getContainedType(0)); const LLPointerType* pty = isaPointer(context->getType()->getContainedType(0));
@ -2548,10 +2463,7 @@ DValue* FuncExp::toElem(IRState* p)
LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0)); LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0));
DtoStore(castfptr, fptr); DtoStore(castfptr, fptr);
if (temp)
return new DVarValue(type, lval, true); return new DVarValue(type, lval, true);
else
return new DImValue(type, lval, true);
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -2582,33 +2494,7 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
// dst pointer // dst pointer
LLValue* dstMem = 0; LLValue* dstMem = 0;
// rvalue of assignment
if (p->topexp() && p->topexp()->e2 == this)
{
DValue* topval = p->topexp()->v;
// slice assignment (copy)
if (DSliceValue* s = topval->isSlice())
{
assert(s->ptr->getType()->getContainedType(0) == llStoType->getContainedType(0));
dstMem = DtoBitCast(s->ptr, getPtrToType(llStoType));
sliceInPlace = true;
// FIXME: insert bounds checks
}
// static array assignment
else if (topval->getType()->toBasetype()->ty == Tsarray)
{
dstMem = topval->getLVal();
}
// otherwise we still need to alloca storage
}
// alloca storage if not found already
if (!dstMem)
{
dstMem = new llvm::AllocaInst(llStoType, "arrayliteral", p->topallocapoint()); dstMem = new llvm::AllocaInst(llStoType, "arrayliteral", p->topallocapoint());
}
Logger::cout() << "using dest mem: " << *dstMem << '\n';
// store elements // store elements
for (size_t i=0; i<len; ++i) for (size_t i=0; i<len; ++i)
@ -2618,9 +2504,7 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
// emulate assignment // emulate assignment
DVarValue* vv = new DVarValue(expr->type, elemAddr, true); DVarValue* vv = new DVarValue(expr->type, elemAddr, true);
p->exps.push_back(IRExp(NULL, expr, vv));
DValue* e = expr->toElem(p); DValue* e = expr->toElem(p);
p->exps.pop_back();
DImValue* im = e->isIm(); DImValue* im = e->isIm();
if (!im || !im->inPlace()) { if (!im || !im->inPlace()) {
DtoAssign(vv, e); DtoAssign(vv, e);
@ -2629,7 +2513,7 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
// return storage directly ? // return storage directly ?
if (!dyn || (dyn && sliceInPlace)) if (!dyn || (dyn && sliceInPlace))
return new DImValue(type, dstMem, true); return new DImValue(type, dstMem, false);
// wrap in a slice // wrap in a slice
return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp")); return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp"));
} }
@ -2664,25 +2548,11 @@ DValue* StructLiteralExp::toElem(IRState* p)
Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE; LOG_SCOPE;
LLValue* sptr;
const LLType* llt = DtoType(type); const LLType* llt = DtoType(type);
LLValue* mem = 0; LLValue* mem = 0;
bool isinplace = true;
// already has memory (r-value of assignment) LLValue* sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint());
IRExp* topexp = p->topexp();
if (topexp && topexp->e2 == this && !topexp->v->isSlice())
{
assert(topexp->e2 == this);
sptr = topexp->v->getLVal();
}
// temporary struct literal
else
{
sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint());
isinplace = false;
}
// num elements in literal // num elements in literal
@ -2719,9 +2589,7 @@ DValue* StructLiteralExp::toElem(IRState* p)
LLValue* arrptr = DtoGEPi(sptr,0,j); LLValue* arrptr = DtoGEPi(sptr,0,j);
DValue* darrptr = new DVarValue(vx->type, arrptr, true); DValue* darrptr = new DVarValue(vx->type, arrptr, true);
p->exps.push_back(IRExp(NULL,vx,darrptr));
DValue* ve = vx->toElem(p); DValue* ve = vx->toElem(p);
p->exps.pop_back();
if (!ve->inPlace()) if (!ve->inPlace())
DtoAssign(darrptr, ve); DtoAssign(darrptr, ve);
@ -2729,7 +2597,7 @@ DValue* StructLiteralExp::toElem(IRState* p)
j++; j++;
} }
return new DImValue(type, sptr, isinplace); return new DImValue(type, sptr);
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////