Fixed initialization of multidimensional static arrays.

This commit is contained in:
Alexey Prokhin 2010-12-30 14:04:24 +03:00
parent 8d7ff66019
commit d8115713d2
3 changed files with 46 additions and 14 deletions

View file

@ -87,16 +87,36 @@ void DtoArrayInit(Loc& loc, DValue* array, DValue* value, int op)
LOG_SCOPE; LOG_SCOPE;
#if DMDV2 #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); DtoArraySetAssign(loc, array, value, op);
return; 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* dim = DtoArrayLen(array);
LLValue* ptr = DtoArrayPtr(array); LLValue* ptr = DtoArrayPtr(array);
#endif
LLValue* val; LLValue* val;
// give slices and complex values storage (and thus an address to pass) // 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! // if not a zero initializer, call the appropriate runtime function!
switch (arrayelemty->ty) switch (valuety->ty)
{ {
case Tbool: case Tbool:
val = gIR->ir->CreateZExt(val, LLType::getInt8Ty(gIR->context()), ".bool"); 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 #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. // Determine whether t is an array of structs that need a postblit.
bool arrayNeedsPostblit(Type *t) bool arrayNeedsPostblit(Type *t)
{ {
t = t->toBasetype(); t = DtoArrayElementType(t);
while (t->ty == Tsarray)
t = t->nextOf()->toBasetype();
if (t->ty == Tstruct) if (t->ty == Tstruct)
return ((TypeStruct *)t)->sym->postblit != 0; return ((TypeStruct *)t)->sym->postblit != 0;
return false; return false;

View file

@ -17,6 +17,7 @@ void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src);
void DtoArrayInit(Loc& loc, DValue* array, DValue* value, int op); void DtoArrayInit(Loc& loc, DValue* array, DValue* value, int op);
#if DMDV2 #if DMDV2
Type *DtoArrayElementType(Type *arrayType);
bool arrayNeedsPostblit(Type *t); bool arrayNeedsPostblit(Type *t);
void DtoArrayAssign(DValue *from, DValue *to, int op); void DtoArrayAssign(DValue *from, DValue *to, int op);
void DtoArraySetAssign(Loc &loc, DValue *array, DValue *value, int op); void DtoArraySetAssign(Loc &loc, DValue *array, DValue *value, int op);

View file

@ -411,12 +411,14 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op)
else if (t->ty == Tarray) { else if (t->ty == Tarray) {
// lhs is slice // lhs is slice
if (DSliceValue* s = lhs->isSlice()) { if (DSliceValue* s = lhs->isSlice()) {
Type *elemType = t->nextOf()->toBasetype(); if (t->nextOf()->toBasetype()->equals(t2)) {
if (elemType->equals(t2)) { DtoArrayInit(loc, lhs, rhs, op);
DtoArrayInit(loc, s, rhs, op);
} }
#if DMDV2 #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); DtoArrayAssign(s, rhs, op);
} }
#endif #endif
@ -446,13 +448,15 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op)
} }
} }
else if (t->ty == Tsarray) { else if (t->ty == Tsarray) {
Type *elemType = t->nextOf()->toBasetype();
// T[n] = T // T[n] = T
if (elemType->equals(t2)) { if (t->nextOf()->toBasetype()->equals(t2)) {
DtoArrayInit(loc, lhs, rhs, op); DtoArrayInit(loc, lhs, rhs, op);
} }
#if DMDV2 #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); DtoArrayAssign(lhs, rhs, op);
} }
#endif #endif