From d8115713d24a06583d10b3acd36ff16efa8e124b Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Thu, 30 Dec 2010 14:04:24 +0300 Subject: [PATCH] Fixed initialization of multidimensional static arrays. --- gen/arrays.cpp | 41 ++++++++++++++++++++++++++++++++++------- gen/arrays.h | 1 + gen/llvmhelpers.cpp | 18 +++++++++++------- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 0b07b2ea..8e3fe73d 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -87,16 +87,36 @@ void DtoArrayInit(Loc& loc, DValue* array, DValue* value, int op) LOG_SCOPE; #if DMDV2 - Type *elemType = array->type->toBasetype()->nextOf()->toBasetype(); - if (op != -1 && op != TOKblit && arrayNeedsPostblit(elemType)) + + if (op != -1 && op != TOKblit && arrayNeedsPostblit(array->type)) { DtoArraySetAssign(loc, array, value, op); return; } -#endif + + LLValue* ptr = DtoArrayPtr(array); + LLValue* dim; + if (array->type->ty == Tsarray) { + // Calculate length of the static array + LLValue* rv = array->getRVal(); + const LLArrayType* t = isaArray(rv->getType()->getContainedType(0)); + uint64_t c = t->getNumElements(); + while (t = isaArray(t->getContainedType(0))) + c *= t->getNumElements(); + assert(c > 0); + dim = DtoConstSize_t(c); + ptr = DtoBitCast(ptr, DtoType(DtoArrayElementType(array->type)->pointerTo())); + } else { + dim = DtoArrayLen(array); + } + +#else // DMDV1 LLValue* dim = DtoArrayLen(array); LLValue* ptr = DtoArrayPtr(array); + +#endif + LLValue* val; // give slices and complex values storage (and thus an address to pass) @@ -134,7 +154,7 @@ void DtoArrayInit(Loc& loc, DValue* array, DValue* value, int op) } // if not a zero initializer, call the appropriate runtime function! - switch (arrayelemty->ty) + switch (valuety->ty) { case Tbool: val = gIR->ir->CreateZExt(val, LLType::getInt8Ty(gIR->context()), ".bool"); @@ -236,12 +256,19 @@ void DtoArrayInit(Loc& loc, DValue* array, DValue* value, int op) #if DMDV2 +Type *DtoArrayElementType(Type *arrayType) +{ + assert(arrayType->toBasetype()->nextOf()); + Type *t = arrayType->toBasetype()->nextOf()->toBasetype(); + while (t->ty == Tsarray) + t = t->nextOf()->toBasetype(); + return t; +} + // Determine whether t is an array of structs that need a postblit. bool arrayNeedsPostblit(Type *t) { - t = t->toBasetype(); - while (t->ty == Tsarray) - t = t->nextOf()->toBasetype(); + t = DtoArrayElementType(t); if (t->ty == Tstruct) return ((TypeStruct *)t)->sym->postblit != 0; return false; diff --git a/gen/arrays.h b/gen/arrays.h index 66694ca6..e61a7d5d 100644 --- a/gen/arrays.h +++ b/gen/arrays.h @@ -17,6 +17,7 @@ void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src); void DtoArrayInit(Loc& loc, DValue* array, DValue* value, int op); #if DMDV2 +Type *DtoArrayElementType(Type *arrayType); bool arrayNeedsPostblit(Type *t); void DtoArrayAssign(DValue *from, DValue *to, int op); void DtoArraySetAssign(Loc &loc, DValue *array, DValue *value, int op); diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index d1c187f8..c743c1f3 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -411,12 +411,14 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op) else if (t->ty == Tarray) { // lhs is slice if (DSliceValue* s = lhs->isSlice()) { - Type *elemType = t->nextOf()->toBasetype(); - if (elemType->equals(t2)) { - DtoArrayInit(loc, s, rhs, op); + if (t->nextOf()->toBasetype()->equals(t2)) { + DtoArrayInit(loc, lhs, rhs, op); } #if DMDV2 - else if (op != -1 && op != TOKblit && arrayNeedsPostblit(elemType)) { + else if (DtoArrayElementType(t)->equals(t2)) { + DtoArrayInit(loc, s, rhs, op); + } + else if (op != -1 && op != TOKblit && arrayNeedsPostblit(t)) { DtoArrayAssign(s, rhs, op); } #endif @@ -446,13 +448,15 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op) } } else if (t->ty == Tsarray) { - Type *elemType = t->nextOf()->toBasetype(); // T[n] = T - if (elemType->equals(t2)) { + if (t->nextOf()->toBasetype()->equals(t2)) { DtoArrayInit(loc, lhs, rhs, op); } #if DMDV2 - else if (op != -1 && op != TOKblit && arrayNeedsPostblit(elemType)) { + else if (DtoArrayElementType(t)->equals(t2)) { + DtoArrayInit(loc, lhs, rhs, op); + } + else if (op != -1 && op != TOKblit && arrayNeedsPostblit(t)) { DtoArrayAssign(lhs, rhs, op); } #endif