diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 2546432499..20503f81ac 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -956,6 +956,9 @@ void DtoConstInitGlobal(VarDeclaration* vd) llvm::GlobalVariable* gvar = llvm::cast(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) @@ -1253,22 +1256,7 @@ LLConstant* DtoConstInitializer(Type* type, Initializer* init) 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 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()) { @@ -1391,6 +1379,74 @@ DValue* DtoInitializer(LLValue* target, Initializer* init) 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 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 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); +} + ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 7d2794f35b..4e13f35225 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -105,6 +105,9 @@ void findDefaultTarget(); /// 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 //////////////////////////////////////////// diff --git a/tests/mini/bug26.d b/tests/mini/compile_bug26.d similarity index 100% rename from tests/mini/bug26.d rename to tests/mini/compile_bug26.d diff --git a/tests/mini/imports_1of2.d b/tests/mini/imports_1of2.d deleted file mode 100644 index 87455e545b..0000000000 --- a/tests/mini/imports_1of2.d +++ /dev/null @@ -1,11 +0,0 @@ -module imports_1of2; - -import imports_2of2; - -void main() -{ - assert(func() == 42); - S s; - s.l = 32; - assert(s.l == 32); -} diff --git a/tests/mini/imports_2of2.d b/tests/mini/imports_2of2.d deleted file mode 100644 index d2e3946752..0000000000 --- a/tests/mini/imports_2of2.d +++ /dev/null @@ -1,11 +0,0 @@ -module imports_2of2; - -int func() -{ - return 42; -} - -struct S -{ - long l; -} diff --git a/tests/mini/bug57.d b/tests/mini/phobos/bug57.d similarity index 100% rename from tests/mini/bug57.d rename to tests/mini/phobos/bug57.d diff --git a/tests/mini/bug58.d b/tests/mini/phobos/bug58.d similarity index 100% rename from tests/mini/bug58.d rename to tests/mini/phobos/bug58.d diff --git a/tests/mini/bug66.d b/tests/mini/phobos/bug66.d similarity index 100% rename from tests/mini/bug66.d rename to tests/mini/phobos/bug66.d diff --git a/tests/mini/bug71.d b/tests/mini/phobos/bug71.d similarity index 100% rename from tests/mini/bug71.d rename to tests/mini/phobos/bug71.d diff --git a/tests/mini/bug79.d b/tests/mini/phobos/bug79.d similarity index 100% rename from tests/mini/bug79.d rename to tests/mini/phobos/bug79.d diff --git a/tests/mini/imports2.d b/tests/mini/phobos/imports2.d similarity index 100% rename from tests/mini/imports2.d rename to tests/mini/phobos/imports2.d diff --git a/tests/mini/stdiotest.d b/tests/mini/phobos/stdiotest.d similarity index 100% rename from tests/mini/stdiotest.d rename to tests/mini/phobos/stdiotest.d diff --git a/tests/mini/stdiotest2.d b/tests/mini/phobos/stdiotest2.d similarity index 100% rename from tests/mini/stdiotest2.d rename to tests/mini/phobos/stdiotest2.d diff --git a/tests/mini/strings2.d b/tests/mini/phobos/strings2.d similarity index 100% rename from tests/mini/strings2.d rename to tests/mini/phobos/strings2.d