diff --git a/gen/aa.cpp b/gen/aa.cpp index f98d5440b1..db335c975a 100644 --- a/gen/aa.cpp +++ b/gen/aa.cpp @@ -14,41 +14,6 @@ #include "gen/dvalue.h" #include "ir/irmodule.h" -// makes sure the key value lives in memory so it can be passed to the runtime functions without problems -// returns the pointer -static LLValue* to_pkey(Loc& loc, DValue* key) -{ - Type* keytype = key->getType(); - bool needmem = !DtoIsPassedByRef(keytype); - LLValue* pkey; - if (key->isIm()) { - pkey = key->getRVal(); - } - else if (DVarValue* var = key->isVar()) { - pkey = key->getLVal(); - needmem = false; - } - else if (key->isConst()) { - needmem = true; - pkey = key->getRVal(); - } - else { - LLValue* tmp = DtoAlloca(keytype, "aatmpkeystorage"); - DVarValue var(keytype, tmp); - DtoAssign(loc, &var, key); - return tmp; - } - - // give memory - if (needmem) { - LLValue* tmp = DtoAlloca(keytype, "aatmpkeystorage"); - DtoStore(pkey, tmp); - pkey = tmp; - } - - return pkey; -} - // returns the keytype typeinfo static LLValue* to_keyti(DValue* key) { @@ -79,7 +44,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) keyti = DtoBitCast(keyti, funcTy->getParamType(1)); // pkey param - LLValue* pkey = to_pkey(loc, key); + LLValue* pkey = makeLValue(loc, key); pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2)); // call runtime @@ -164,7 +129,7 @@ DValue* DtoAAIn(Loc& loc, Type* type, DValue* aa, DValue* key) keyti = DtoBitCast(keyti, funcTy->getParamType(1)); // pkey param - LLValue* pkey = to_pkey(loc, key); + LLValue* pkey = makeLValue(loc, key); pkey = DtoBitCast(pkey, funcTy->getParamType(2)); // call runtime @@ -206,7 +171,7 @@ void DtoAARemove(Loc& loc, DValue* aa, DValue* key) keyti = DtoBitCast(keyti, funcTy->getParamType(1)); // pkey param - LLValue* pkey = to_pkey(loc, key); + LLValue* pkey = makeLValue(loc, key); pkey = DtoBitCast(pkey, funcTy->getParamType(2)); // build arg vector diff --git a/gen/arrays.cpp b/gen/arrays.cpp index c8355d7207..c4652b7bc1 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -532,23 +532,14 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim) } ////////////////////////////////////////////////////////////////////////////////////////// -void DtoCatAssignElement(Type* arrayType, DValue* array, Expression* exp) +void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* exp) { Logger::println("DtoCatAssignElement"); LOG_SCOPE; assert(array); - DValue *expVal = exp->toElem(gIR); - LLValue *valueToAppend; - if (expVal->isLVal()) - valueToAppend = expVal->getLVal(); - else { - valueToAppend = DtoAlloca(expVal->getType(), ".appendingElementOnStack"); - DVarValue lval(expVal->getType(), valueToAppend); - Loc loc; - DtoAssign(loc, &lval, expVal); - } + LLValue *valueToAppend = makeLValue(loc, exp->toElem(gIR)); LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcT"); LLSmallVector args; diff --git a/gen/arrays.h b/gen/arrays.h index c7ec1dfb55..a597bca8eb 100644 --- a/gen/arrays.h +++ b/gen/arrays.h @@ -24,7 +24,7 @@ DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool default DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true); DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim); -void DtoCatAssignElement(Type* type, DValue* arr, Expression* exp); +void DtoCatAssignElement(Loc& loc, Type* type, DValue* arr, Expression* exp); DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp); DSliceValue* DtoCatArrays(Type* type, Expression* e1, Expression* e2); DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2); diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 3fc07c44d6..bbdde852d7 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1572,3 +1572,36 @@ Type * stripModifiers( Type * type ) } ////////////////////////////////////////////////////////////////////////////////////////// + +LLValue* makeLValue(Loc& loc, DValue* value) +{ + Type* valueType = value->getType(); + bool needsMemory; + LLValue* valuePointer; + if (value->isIm()) { + valuePointer = value->getRVal(); + needsMemory = !DtoIsPassedByRef(valueType); + } + else if (DVarValue* var = value->isVar()) { + valuePointer = value->getLVal(); + needsMemory = false; + } + else if (value->isConst()) { + valuePointer = value->getRVal(); + needsMemory = true; + } + else { + valuePointer = DtoAlloca(valueType, ".makelvaluetmp"); + DVarValue var(valueType, valuePointer); + DtoAssign(loc, &var, value); + needsMemory = false; + } + + if (needsMemory) { + LLValue* tmp = DtoAlloca(valueType, ".makelvaluetmp"); + DtoStore(valuePointer, tmp); + valuePointer = tmp; + } + + return valuePointer; +} diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index e783edf0a8..817c3752df 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -146,6 +146,11 @@ IrModule* getIrModule(Module* M); /// Returns the offset rounded up to the closest safely aligned offset. size_t realignOffset(size_t offset, Type* type); +/// Returns the llvm::Value of the passed DValue, making sure that it is an +/// lvalue (has a memory address), so it can be passed to the D runtime +/// functions without problems. +LLValue* makeLValue(Loc& loc, DValue* value); + //////////////////////////////////////////// // gen/tocall.cpp stuff below //////////////////////////////////////////// diff --git a/gen/toir.cpp b/gen/toir.cpp index 694a874bd3..cf5472396c 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2234,7 +2234,7 @@ DValue* CatAssignExp::toElem(IRState* p) Type* e2type = e2->type->toBasetype(); if (e2type == elemtype) { - DtoCatAssignElement(e1type, l, e2); + DtoCatAssignElement(loc, e1type, l, e2); } else if (e1type == e2type) { DSliceValue* slice = DtoCatAssignArray(l,e2);