# HG changeset patch # User lindquist # Date 1210111273 -7200 # Node ID c44e6a711885ea56509cea7c6bcc7ec88c4d1c25 # Parent 16e676ae5ab42510d173e6f3becb2c769a141db0 [svn r191] Fixed: array literals did not support all type/storage combinations. Fixed: with expression had broke somewhere along the way. diff -r 16e676ae5ab4 -r c44e6a711885 gen/statements.cpp --- a/gen/statements.cpp Tue May 06 18:36:46 2008 +0200 +++ b/gen/statements.cpp Wed May 07 00:01:13 2008 +0200 @@ -1053,8 +1053,9 @@ assert(body); DValue* e = exp->toElem(p); + assert(!wthis->ir.isSet()); + wthis->ir.irLocal = new IrLocal(wthis); wthis->ir.irLocal->value = e->getRVal(); - delete e; body->toIR(p); } diff -r 16e676ae5ab4 -r c44e6a711885 gen/toir.cpp --- a/gen/toir.cpp Tue May 06 18:36:46 2008 +0200 +++ b/gen/toir.cpp Wed May 07 00:01:13 2008 +0200 @@ -2550,66 +2550,76 @@ Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - Type* ty = DtoDType(type); - const llvm::Type* t = DtoType(ty); - Logger::cout() << "array literal has llvm type: " << *t << '\n'; - - llvm::Value* mem = 0; - bool inplace_slice = false; - - if (!p->topexp() || p->topexp()->e2 != this) { - assert(DtoDType(type)->ty == Tsarray); - mem = new llvm::AllocaInst(t,"arrayliteral",p->topallocapoint()); - } - else if (p->topexp()->e2 == this) { - DValue* tlv = p->topexp()->v; - if (DSliceValue* sv = tlv->isSlice()) { - assert(sv->len == 0); - mem = sv->ptr; - inplace_slice = true; + // D types + Type* arrayType = type->toBasetype(); + Type* elemType = arrayType->nextOf()->toBasetype(); + + // is dynamic ? + bool dyn = (arrayType->ty == Tarray); + // length + size_t len = elements->dim; + // store into slice? + bool sliceInPlace = false; + + // llvm target type + const llvm::Type* llType = DtoType(arrayType); + Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; + + // llvm storage type + const llvm::Type* llStoType = llvm::ArrayType::get(DtoType(elemType), len); + Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; + + // dst pointer + llvm::Value* dstMem = 0; + + // rvalue of assignment + if (p->topexp() && p->topexp()->e2 == this) + { + DValue* topval = p->topexp()->v; + // slice assignment (copy) + if (DSliceValue* s = topval->isSlice()) + { + dstMem = s->ptr; + sliceInPlace = true; + assert(s->len == NULL); } - else { - mem = p->topexp()->v->getLVal(); - } - assert(mem); - if (!isaPointer(mem->getType()) || - !isaArray(mem->getType()->getContainedType(0))) + // static array assignment + else if (topval->getType()->toBasetype()->ty == Tsarray) { - assert(!inplace_slice); - assert(ty->ty == Tarray); - // we need to give this array literal storage - const llvm::ArrayType* arrty = llvm::ArrayType::get(DtoType(ty->next), elements->dim); - mem = new llvm::AllocaInst(arrty, "arrayliteral", p->topallocapoint()); + dstMem = topval->getLVal(); } + // otherwise we still need to alloca storage } - else - assert(0); - - Logger::cout() << "array literal mem: " << *mem << '\n'; - - for (unsigned i=0; idim; ++i) + + // alloca storage if not found already + if (!dstMem) + { + dstMem = new llvm::AllocaInst(llStoType, "arrayliteral", p->topallocapoint()); + } + Logger::cout() << "using dest mem: " << *dstMem << '\n'; + + // store elements + for (size_t i=0; idata[i]; - llvm::Value* elemAddr = DtoGEPi(mem,0,i,"tmp",p->scopebb()); + llvm::Value* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb()); + + // emulate assignment DVarValue* vv = new DVarValue(expr->type, elemAddr, true); p->exps.push_back(IRExp(NULL, expr, vv)); DValue* e = expr->toElem(p); p->exps.pop_back(); - DImValue* im = e->isIm(); if (!im || !im->inPlace()) { DtoAssign(vv, e); } } - if (ty->ty == Tsarray || (ty->ty == Tarray && inplace_slice)) - return new DImValue(type, mem, true); - else if (ty->ty == Tarray) - return new DSliceValue(type, DtoConstSize_t(elements->dim), DtoGEPi(mem,0,0,"tmp")); - else { - assert(0); - return 0; - } + // return storage directly ? + if (!dyn || (dyn && sliceInPlace)) + return new DImValue(type, dstMem, true); + // wrap in a slice + return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp")); } ////////////////////////////////////////////////////////////////////////////////////////// diff -r 16e676ae5ab4 -r c44e6a711885 ir/irsymbol.cpp --- a/ir/irsymbol.cpp Tue May 06 18:36:46 2008 +0200 +++ b/ir/irsymbol.cpp Wed May 07 00:01:13 2008 +0200 @@ -51,6 +51,11 @@ irField = NULL; } +bool IrDsymbol::isSet() +{ + return (irStruct || irFunc || irGlobal || irLocal || irField); +} + IrVar* IrDsymbol::getIrVar() { assert(irGlobal || irLocal || irField); diff -r 16e676ae5ab4 -r c44e6a711885 ir/irsymbol.h --- a/ir/irsymbol.h Tue May 06 18:36:46 2008 +0200 +++ b/ir/irsymbol.h Wed May 07 00:01:13 2008 +0200 @@ -47,6 +47,8 @@ IrField* irField; IrVar* getIrVar(); llvm::Value*& getIrValue(); + + bool isSet(); }; #endif diff -r 16e676ae5ab4 -r c44e6a711885 test/arrays.d --- a/test/arrays.d Tue May 06 18:36:46 2008 +0200 +++ b/test/arrays.d Wed May 07 00:01:13 2008 +0200 @@ -1,3 +1,5 @@ +extern(C) int printf(char*, ...); + void integer() { auto arr = new int[16]; diff -r 16e676ae5ab4 -r c44e6a711885 test/arrays13.d --- a/test/arrays13.d Tue May 06 18:36:46 2008 +0200 +++ b/test/arrays13.d Wed May 07 00:01:13 2008 +0200 @@ -1,8 +1,10 @@ module arrays13; +extern(C) int printf(char*, ...); + void main() { - string a = "hello"; + char[] a = "hello"; assert(a > "hel"); assert(a >= "hel"); diff -r 16e676ae5ab4 -r c44e6a711885 test/arrays4.d --- a/test/arrays4.d Tue May 06 18:36:46 2008 +0200 +++ b/test/arrays4.d Wed May 07 00:01:13 2008 +0200 @@ -1,5 +1,5 @@ module arrays4; -import std.stdio; + void main() { int[] arr; @@ -10,5 +10,4 @@ assert(arr.length == 2); assert(arr[0] == 3); assert(arr[1] == 5); - writefln(arr); } diff -r 16e676ae5ab4 -r c44e6a711885 test/arrays7.d --- a/test/arrays7.d Tue May 06 18:36:46 2008 +0200 +++ b/test/arrays7.d Wed May 07 00:01:13 2008 +0200 @@ -1,5 +1,7 @@ module arrays7; +extern(C) int printf(char*, ...); + pragma(LLVM_internal, "notypeinfo") struct S { diff -r 16e676ae5ab4 -r c44e6a711885 test/arrays8.d --- a/test/arrays8.d Tue May 06 18:36:46 2008 +0200 +++ b/test/arrays8.d Wed May 07 00:01:13 2008 +0200 @@ -1,5 +1,7 @@ module arrays8; +extern(C) int printf(char*, ...); + void main() { char[] a = "hello "; diff -r 16e676ae5ab4 -r c44e6a711885 test/with1.d --- a/test/with1.d Tue May 06 18:36:46 2008 +0200 +++ b/test/with1.d Wed May 07 00:01:13 2008 +0200 @@ -10,6 +10,8 @@ with(s) { i = 0; - f = 3.4; + f = 3.5; } + assert(s.i == 0); + assert(s.f == 3.5); }