Mercurial > projects > ldc
changeset 502:837af2a63564
Fixed problems constant multidimensional static array initializers.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Wed, 13 Aug 2008 15:43:13 +0200 |
parents | ba7f06832d1c |
children | 7148a3f2b44b |
files | gen/llvmhelpers.cpp gen/llvmhelpers.h |
diffstat | 2 files changed, 75 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/gen/llvmhelpers.cpp Tue Aug 12 00:56:09 2008 +0200 +++ b/gen/llvmhelpers.cpp Wed Aug 13 15:43:13 2008 +0200 @@ -961,6 +961,9 @@ llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->ir.irGlobal->value); if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl)) { + Logger::println("setting initializer"); + Logger::cout() << "global: " << *gvar << '\n'; + Logger::cout() << "init: " << *_init << '\n'; gvar->setInitializer(_init); // do debug info if (global.params.symdebug) @@ -1258,22 +1261,7 @@ if (!init) { Logger::println("const default initializer for %s", type->toChars()); - - if(type->ty == Tsarray) - { - Logger::println("type is a static array, building constant array initializer"); - TypeSArray* arrtype = (TypeSArray*)type; - Type* elemtype = type->next; - - integer_t arraydim; - arraydim = arrtype->dim->toInteger(); - - std::vector<LLConstant*> inits(arraydim, elemtype->defaultInit()->toConstElem(gIR)); - const LLArrayType* arrty = LLArrayType::get(DtoType(elemtype),arraydim); - _init = LLConstantArray::get(arrty, inits); - } - else - _init = type->defaultInit()->toConstElem(gIR); + _init = DtoDefaultInit(type); } else if (ExpInitializer* ex = init->isExpInitializer()) { @@ -1396,6 +1384,74 @@ return 0; } +////////////////////////////////////////////////////////////////////////////////////////// + +static LLConstant* expand_to_sarray(Type *base, Expression* exp) +{ + Logger::println("building type %s from expression (%s) of type %s", base->toChars(), exp->toChars(), exp->type->toChars()); + const LLType* dstTy = DtoType(base); + Logger::cout() << "final llvm type requested: " << *dstTy << '\n'; + + LLConstant* val = exp->toConstElem(gIR); + + Type* expbase = exp->type->toBasetype(); + Type* t = base; + + LLSmallVector<size_t, 4> dims; + + while(1) + { + if (t->equals(expbase)) + break; + assert(t->ty == Tsarray); + TypeSArray* tsa = (TypeSArray*)t; + dims.push_back(tsa->dim->toInteger()); + assert(t->next); + t = t->next->toBasetype(); + } + + size_t i = dims.size(); + assert(i); + + std::vector<LLConstant*> inits; + while (i--) + { + const LLArrayType* arrty = LLArrayType::get(val->getType(), dims[i]); + inits.clear(); + inits.insert(inits.end(), dims[i], val); + val = LLConstantArray::get(arrty, inits); + } + + return val; +} + +LLConstant* DtoDefaultInit(Type* type) +{ + Expression* exp = type->defaultInit(); + + Type* expbase = exp->type->toBasetype(); + Type* base = type->toBasetype(); + + // if not the same basetypes, we won't get the same llvm types either + if (!expbase->equals(base)) + { + if (base->ty == Tsarray) + { + Logger::println("type is a static array, building constant array initializer from single value"); + return expand_to_sarray(base, exp); + } + else + { + error("cannot yet convert default initializer %s from type %s to %s", exp->toChars(), exp->type->toChars(), type->toChars()); + fatal(); + } + assert(0); + + } + + return exp->toConstElem(gIR); +} + //////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/llvmhelpers.h Tue Aug 12 00:56:09 2008 +0200 +++ b/gen/llvmhelpers.h Wed Aug 13 15:43:13 2008 +0200 @@ -105,6 +105,9 @@ /// Converts any value to a boolean (llvm i1) LLValue* DtoBoolean(Loc& loc, DValue* dval); +/// get the default initializer of the type +LLConstant* DtoDefaultInit(Type* t); + //////////////////////////////////////////// // gen/tocall.cpp stuff below ////////////////////////////////////////////