mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-02 08:01:11 +03:00
Apply patch from klickverbot. This is his 'proper fix' patch for bug #395.
This commit is contained in:
parent
902bc06fb1
commit
b38845e88e
6 changed files with 45 additions and 51 deletions
41
gen/aa.cpp
41
gen/aa.cpp
|
@ -14,41 +14,6 @@
|
||||||
#include "gen/dvalue.h"
|
#include "gen/dvalue.h"
|
||||||
#include "ir/irmodule.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
|
// returns the keytype typeinfo
|
||||||
static LLValue* to_keyti(DValue* key)
|
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));
|
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
|
||||||
|
|
||||||
// pkey param
|
// pkey param
|
||||||
LLValue* pkey = to_pkey(loc, key);
|
LLValue* pkey = makeLValue(loc, key);
|
||||||
pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2));
|
pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2));
|
||||||
|
|
||||||
// call runtime
|
// call runtime
|
||||||
|
@ -164,7 +129,7 @@ DValue* DtoAAIn(Loc& loc, Type* type, DValue* aa, DValue* key)
|
||||||
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
|
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
|
||||||
|
|
||||||
// pkey param
|
// pkey param
|
||||||
LLValue* pkey = to_pkey(loc, key);
|
LLValue* pkey = makeLValue(loc, key);
|
||||||
pkey = DtoBitCast(pkey, funcTy->getParamType(2));
|
pkey = DtoBitCast(pkey, funcTy->getParamType(2));
|
||||||
|
|
||||||
// call runtime
|
// call runtime
|
||||||
|
@ -206,7 +171,7 @@ void DtoAARemove(Loc& loc, DValue* aa, DValue* key)
|
||||||
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
|
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
|
||||||
|
|
||||||
// pkey param
|
// pkey param
|
||||||
LLValue* pkey = to_pkey(loc, key);
|
LLValue* pkey = makeLValue(loc, key);
|
||||||
pkey = DtoBitCast(pkey, funcTy->getParamType(2));
|
pkey = DtoBitCast(pkey, funcTy->getParamType(2));
|
||||||
|
|
||||||
// build arg vector
|
// build arg vector
|
||||||
|
|
|
@ -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");
|
Logger::println("DtoCatAssignElement");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
assert(array);
|
assert(array);
|
||||||
|
|
||||||
DValue *expVal = exp->toElem(gIR);
|
LLValue *valueToAppend = makeLValue(loc, 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcT");
|
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcT");
|
||||||
LLSmallVector<LLValue*,3> args;
|
LLSmallVector<LLValue*,3> args;
|
||||||
|
|
|
@ -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* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true);
|
||||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim);
|
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* DtoCatAssignArray(DValue* arr, Expression* exp);
|
||||||
DSliceValue* DtoCatArrays(Type* type, Expression* e1, Expression* e2);
|
DSliceValue* DtoCatArrays(Type* type, Expression* e1, Expression* e2);
|
||||||
DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2);
|
DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -146,6 +146,11 @@ IrModule* getIrModule(Module* M);
|
||||||
/// Returns the offset rounded up to the closest safely aligned offset.
|
/// Returns the offset rounded up to the closest safely aligned offset.
|
||||||
size_t realignOffset(size_t offset, Type* type);
|
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
|
// gen/tocall.cpp stuff below
|
||||||
////////////////////////////////////////////
|
////////////////////////////////////////////
|
||||||
|
|
|
@ -2234,7 +2234,7 @@ DValue* CatAssignExp::toElem(IRState* p)
|
||||||
Type* e2type = e2->type->toBasetype();
|
Type* e2type = e2->type->toBasetype();
|
||||||
|
|
||||||
if (e2type == elemtype) {
|
if (e2type == elemtype) {
|
||||||
DtoCatAssignElement(e1type, l, e2);
|
DtoCatAssignElement(loc, e1type, l, e2);
|
||||||
}
|
}
|
||||||
else if (e1type == e2type) {
|
else if (e1type == e2type) {
|
||||||
DSliceValue* slice = DtoCatAssignArray(l,e2);
|
DSliceValue* slice = DtoCatAssignArray(l,e2);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue