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 ...

This commit is contained in:
Tomas Lindquist Olsen
2008-09-15 15:48:59 +02:00
parent c9242e3fbe
commit 56fed01c88
2 changed files with 28 additions and 7 deletions

View File

@@ -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);

View File

@@ -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<LLConstant*> vals(elements->dim, NULL);
for (unsigned i=0; i<elements->dim; ++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);
}
//////////////////////////////////////////////////////////////////////////////////////////