changeset 602:48f079b4fe0f

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 ...
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Mon, 15 Sep 2008 15:48:59 +0200
parents 03a5e609eef3
children 10bc9eb9e262
files gen/arrays.cpp gen/toir.cpp
diffstat 2 files changed, 29 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/gen/arrays.cpp	Mon Sep 15 15:17:41 2008 +0200
+++ b/gen/arrays.cpp	Mon Sep 15 15:48:59 2008 +0200
@@ -347,7 +347,7 @@
     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);
--- a/gen/toir.cpp	Mon Sep 15 15:17:41 2008 +0200
+++ b/gen/toir.cpp	Mon Sep 15 15:48:59 2008 +0200
@@ -2210,12 +2210,21 @@
     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);
-
-    assert(arrtype->getNumElements() == elements->dim);
+    // extract D types
+    Type* bt = type->toBasetype();
+    Type* elemt = bt->next;
+
+    // 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 @@
         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);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////