From 56fed01c88666e4baddbf3d054d1bf4a97f81aa0 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Mon, 15 Sep 2008 15:48:59 +0200 Subject: [PATCH] Fixed ArrayLiteralExp::toConstElem for dynamic arrays, tango-user library should now be possible to build. It seems to be related to DMD bug 2356, which must have been introduced recently, as we already handled this fine for ArrayInitializers, just not ArrayLiterals... Kinda annoying to have to do this work due to DMD bugs ... --- gen/arrays.cpp | 2 +- gen/toir.cpp | 33 +++++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/gen/arrays.cpp b/gen/arrays.cpp index dc7d6f66..d6c9bc23 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -347,7 +347,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) else assert(arrinittype->ty == Tarray); - LLGlobalVariable* gvar = new LLGlobalVariable(arrty,true,LLGlobalValue::InternalLinkage,constarr,"constarray",gIR->module); + LLGlobalVariable* gvar = new LLGlobalVariable(arrty,true,LLGlobalValue::InternalLinkage,constarr,".constarray",gIR->module); LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); return DtoConstSlice(DtoConstSize_t(tdim),gep); diff --git a/gen/toir.cpp b/gen/toir.cpp index 71e202fd..89a3454e 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2210,12 +2210,21 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p) Logger::print("ArrayLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - const LLType* t = DtoType(type); - Logger::cout() << "array literal has llvm type: " << *t << '\n'; - assert(isaArray(t)); - const LLArrayType* arrtype = isaArray(t); + // extract D types + Type* bt = type->toBasetype(); + Type* elemt = bt->next; - assert(arrtype->getNumElements() == elements->dim); + // build llvm array type + const LLArrayType* arrtype = LLArrayType::get(DtoType(elemt), elements->dim); + + // dynamic arrays can occur here as well ... + bool dyn = (bt->ty == Tsarray); + if (!dyn) + assert(arrtype->getNumElements() == elements->dim); + else + assert(bt->ty == Tarray); + + // build the initializer std::vector vals(elements->dim, NULL); for (unsigned i=0; idim; ++i) { @@ -2223,7 +2232,19 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p) vals[i] = expr->toConstElem(p); } - return llvm::ConstantArray::get(arrtype, vals); + // build the constant array initializer + LLConstant* initval = llvm::ConstantArray::get(arrtype, vals); + + // if static array, we're done + if (!dyn) + return initval; + + // for dynamic arrays we need to put the initializer in a global, and build a constant dynamic array reference with the .ptr field pointing into this global + LLConstant* globalstore = new LLGlobalVariable(arrtype, true, LLGlobalValue::InternalLinkage, initval, ".dynarrayStorage", p->module); + LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; + LLConstant* globalstorePtr = llvm::ConstantExpr::getGetElementPtr(globalstore, idxs, 2); + + return DtoConstSlice(DtoConstSize_t(elements->dim), globalstorePtr); } //////////////////////////////////////////////////////////////////////////////////////////