mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-20 14:53:14 +01:00
[svn r307] Fixed: multidimensional new expressions now work. Eg.:
auto ma = new int[][] (3,9);
This commit is contained in:
@@ -477,6 +477,48 @@ DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit)
|
||||
return new DSliceValue(arrayType, arrayLen, newptr);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
DSliceValue* DtoNewMulDimDynArray(Type* arrayType, DValue** dims, size_t ndims, bool defaultInit)
|
||||
{
|
||||
Logger::println("DtoNewMulDimDynArray : %s", arrayType->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
// typeinfo arg
|
||||
LLValue* arrayTypeInfo = DtoTypeInfoOf(arrayType);
|
||||
|
||||
// get runtime function
|
||||
bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
|
||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarraymT" : "_d_newarraymiT" );
|
||||
|
||||
// build dims
|
||||
LLValue* dimsArg = new llvm::AllocaInst(DtoSize_t(), DtoConstUint(ndims), ".newdims", gIR->topallocapoint());
|
||||
for (size_t i=0; i<ndims; ++i)
|
||||
{
|
||||
LLValue* dim = dims[i]->getRVal();
|
||||
DtoStore(dim, DtoGEPi1(dimsArg, i));
|
||||
}
|
||||
|
||||
// call allocator
|
||||
LLConstant* arrayLen = DtoConstSize_t(ndims);
|
||||
LLValue* newptr = gIR->ir->CreateCall3(fn, arrayTypeInfo, arrayLen, dimsArg, ".gc_mem");
|
||||
|
||||
// cast to wanted type
|
||||
const LLType* dstType = DtoType(arrayType)->getContainedType(1);
|
||||
if (newptr->getType() != dstType)
|
||||
newptr = DtoBitCast(newptr, dstType, ".gc_mem");
|
||||
|
||||
Logger::cout() << "final ptr = " << *newptr << '\n';
|
||||
|
||||
#if 0
|
||||
if (defaultInit) {
|
||||
DValue* e = dty->defaultInit()->toElem(gIR);
|
||||
DtoArrayInit(newptr,dim,e->getRVal());
|
||||
}
|
||||
#endif
|
||||
|
||||
return new DSliceValue(arrayType, arrayLen, newptr);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@ void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr);
|
||||
void DtoSetArrayToNull(LLValue* v);
|
||||
|
||||
DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit=true);
|
||||
DSliceValue* DtoNewMulDimDynArray(Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true);
|
||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim);
|
||||
|
||||
DSliceValue* DtoCatAssignElement(DValue* arr, Expression* exp);
|
||||
|
||||
@@ -266,6 +266,20 @@ static void LLVM_D_BuildRuntimeModule()
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
||||
}
|
||||
|
||||
// void* _d_newarraymT(TypeInfo ti, size_t length, size_t* dims)
|
||||
// void* _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims)
|
||||
{
|
||||
std::string fname("_d_newarraymT");
|
||||
std::string fname2("_d_newarraymiT");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(typeInfoTy);
|
||||
types.push_back(sizeTy);
|
||||
types.push_back(rt_ptr(sizeTy));
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
||||
}
|
||||
|
||||
// void* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
|
||||
// void* _d_arraysetlengthiT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
|
||||
{
|
||||
|
||||
19
gen/toir.cpp
19
gen/toir.cpp
@@ -1899,10 +1899,21 @@ DValue* NewExp::toElem(IRState* p)
|
||||
Logger::println("new dynamic array: %s", newtype->toChars());
|
||||
// get dim
|
||||
assert(arguments);
|
||||
assert(arguments->dim == 1);
|
||||
DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
|
||||
// allocate & init
|
||||
return DtoNewDynArray(newtype, sz, true);
|
||||
assert(arguments->dim >= 1);
|
||||
if (arguments->dim == 1)
|
||||
{
|
||||
DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
|
||||
// allocate & init
|
||||
return DtoNewDynArray(newtype, sz, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t ndims = arguments->dim;
|
||||
std::vector<DValue*> dims(ndims);
|
||||
for (size_t i=0; i<ndims; ++i)
|
||||
dims[i] = ((Expression*)arguments->data[i])->toElem(p);
|
||||
return DtoNewMulDimDynArray(newtype, &dims[0], ndims, true);
|
||||
}
|
||||
}
|
||||
// new static array
|
||||
else if (ntype->ty == Tsarray)
|
||||
|
||||
@@ -293,23 +293,19 @@ Loverflow:
|
||||
return null;
|
||||
}
|
||||
|
||||
/+
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
extern (C) Array _d_newarraymT(TypeInfo ti, int ndims, ...)
|
||||
extern (C) void* _d_newarraymT(TypeInfo ti, int ndims, size_t* dims)
|
||||
{
|
||||
Array result;
|
||||
void* result;
|
||||
|
||||
debug(PRINTF) printf("_d_newarraymT(ndims = %d)\n", ndims);
|
||||
if (ndims == 0)
|
||||
result = Array();
|
||||
result = null;
|
||||
else
|
||||
{ va_list q;
|
||||
va_start!(int)(q, ndims);
|
||||
|
||||
void[] foo(TypeInfo ti, size_t* pdim, int ndims)
|
||||
{
|
||||
static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
|
||||
{
|
||||
size_t dim = *pdim;
|
||||
void[] p;
|
||||
@@ -317,7 +313,8 @@ extern (C) Array _d_newarraymT(TypeInfo ti, int ndims, ...)
|
||||
debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
|
||||
if (ndims == 1)
|
||||
{
|
||||
return _d_newarrayT(ti, dim);
|
||||
auto r = _d_newarrayT(ti, dim);
|
||||
return r[0 .. dim];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -330,19 +327,16 @@ extern (C) Array _d_newarraymT(TypeInfo ti, int ndims, ...)
|
||||
return p;
|
||||
}
|
||||
|
||||
size_t* pdim = cast(size_t *)q;
|
||||
void[] arr = foo(ti, pdim, ndims);
|
||||
result = Arra
|
||||
debug(PRINTF) printf("result = %llx\n", result);
|
||||
result = foo(ti, dims, ndims).ptr;
|
||||
debug(PRINTF) printf("result = %p\n", result);
|
||||
|
||||
version (none)
|
||||
{
|
||||
for (int i = 0; i < ndims; i++)
|
||||
{
|
||||
printf("index %d: %d\n", i, va_arg!(int)(q));
|
||||
printf("index %d: %d\n", i, *dims++);
|
||||
}
|
||||
}
|
||||
va_end(q);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -351,19 +345,16 @@ extern (C) Array _d_newarraymT(TypeInfo ti, int ndims, ...)
|
||||
/**
|
||||
*
|
||||
*/
|
||||
extern (C) Array _d_newarraymiT(TypeInfo ti, int ndims, ...)
|
||||
extern (C) void* _d_newarraymiT(TypeInfo ti, int ndims, size_t* dims)
|
||||
{
|
||||
Array result;
|
||||
void* result;
|
||||
|
||||
debug(PRINTF) printf("_d_newarraymiT(ndims = %d)\n", ndims);
|
||||
if (ndims == 0)
|
||||
result = 0;
|
||||
result = null;
|
||||
else
|
||||
{
|
||||
va_list q;
|
||||
va_start!(int)(q, ndims);
|
||||
|
||||
void[] foo(TypeInfo ti, size_t* pdim, int ndims)
|
||||
static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
|
||||
{
|
||||
size_t dim = *pdim;
|
||||
void[] p;
|
||||
@@ -371,7 +362,7 @@ extern (C) Array _d_newarraymiT(TypeInfo ti, int ndims, ...)
|
||||
if (ndims == 1)
|
||||
{
|
||||
auto r = _d_newarrayiT(ti, dim);
|
||||
p = *cast(void[]*)(&r);
|
||||
p = r[0 .. dim];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -384,23 +375,23 @@ extern (C) Array _d_newarraymiT(TypeInfo ti, int ndims, ...)
|
||||
return p;
|
||||
}
|
||||
|
||||
size_t* pdim = cast(size_t *)q;
|
||||
result = cast(ulong)foo(ti, pdim, ndims);
|
||||
debug(PRINTF) printf("result = %llx\n", result);
|
||||
result = foo(ti, dims, ndims).ptr;
|
||||
debug(PRINTF) printf("result = %p\n", result);
|
||||
|
||||
version (none)
|
||||
{
|
||||
for (int i = 0; i < ndims; i++)
|
||||
{
|
||||
printf("index %d: %d\n", i, va_arg!(int)(q));
|
||||
printf("init = %d\n", va_arg!(int)(q));
|
||||
printf("index %d: %d\n", i, *dims++);
|
||||
printf("init = %d\n", *dims++);
|
||||
}
|
||||
}
|
||||
va_end(q);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/+
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
19
tangotests/marray1.d
Normal file
19
tangotests/marray1.d
Normal file
@@ -0,0 +1,19 @@
|
||||
module tangotest.marray1;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[][] arr;
|
||||
int[] a = [1,2];
|
||||
int[] b = [6,7,8,9];
|
||||
arr ~= a;
|
||||
arr ~= b;
|
||||
assert(a.length == 2);
|
||||
assert(b.length == 4);
|
||||
assert(arr.length == 2);
|
||||
assert(arr[0][0] == 1);
|
||||
assert(arr[0][1] == 2);
|
||||
assert(arr[1][0] == 6);
|
||||
assert(arr[1][1] == 7);
|
||||
assert(arr[1][2] == 8);
|
||||
assert(arr[1][3] == 9);
|
||||
}
|
||||
15
tangotests/marray2.d
Normal file
15
tangotests/marray2.d
Normal file
@@ -0,0 +1,15 @@
|
||||
module tangotests.marray2;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[][] ma = new int[][](2,4);
|
||||
assert(ma.length == 2);
|
||||
assert(ma[0].length == 4);
|
||||
assert(ma[1].length == 4);
|
||||
ma[0][3] = 32;
|
||||
ma[1][2] = 123;
|
||||
ma[0][0] = 55;
|
||||
assert(ma[0][3] == 32);
|
||||
assert(ma[1][2] == 123);
|
||||
assert(ma[0][0] == 55);
|
||||
}
|
||||
Reference in New Issue
Block a user