diff gen/llvmhelpers.cpp @ 1255:9014d7f0433f

Rewrote runtime struct literal codegen.
author Tomas Lindquist Olsen <tomas.l.olsen gmail com>
date Wed, 22 Apr 2009 03:08:28 +0200
parents 79758fd2f48a
children 0686701178d3
line wrap: on
line diff
--- a/gen/llvmhelpers.cpp	Wed Apr 22 01:18:21 2009 +0200
+++ b/gen/llvmhelpers.cpp	Wed Apr 22 03:08:28 2009 +0200
@@ -1186,6 +1186,78 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
+static LLValue* expand_value_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);
+    if (Logger::enabled())
+        Logger::cout() << "final llvm type requested: " << *dstTy << '\n';
+
+    // get initial value
+    LLValue* val = exp->toElem(gIR)->getRVal();
+    if (DtoIsPassedByRef(exp->type))
+        val = DtoLoad(val);
+
+    Type* expbase = exp->type->toBasetype();
+    Logger::println("expbase: %s", expbase->toChars());
+    Type* t = base->toBasetype();
+
+    LLSmallVector<size_t, 4> dims;
+
+    while(1)
+    {
+        Logger::println("t: %s", t->toChars());
+        if (t->equals(expbase))
+            break;
+        assert(t->ty == Tsarray);
+        TypeSArray* tsa = (TypeSArray*)t;
+        dims.push_back(tsa->dim->toInteger());
+        assert(t->nextOf());
+        t = t->nextOf()->toBasetype();
+    }
+
+    size_t i = dims.size();
+    assert(i);
+
+    std::vector<LLValue*> inits;
+    while (i--)
+    {
+        // start with undefined array
+        const LLArrayType* arrty = LLArrayType::get(val->getType(), dims[i]);
+        LLValue* tmp = llvm::UndefValue::get(arrty);
+        for (size_t j = 0; j < dims[i]; j++)
+        {
+            tmp = gIR->ir->CreateInsertValue(tmp, val, j);
+        }
+        val = tmp;
+    }
+
+    return val;
+}
+
+LLValue* DtoExprValue(Type* type, Expression* e)
+{
+    Type* t1 = e->type->toBasetype();
+    Type* t2 = type->toBasetype();
+
+    // expand static arrays
+    if (t2->ty == Tsarray && !t1->equals(t2))
+    {
+        return expand_value_to_sarray(t2, e);
+    }
+    // or not
+    else
+    {
+        DValue* dv = e->toElem(gIR);
+        LLValue* v = dv->getRVal();
+        if (DtoIsPassedByRef(e->type))
+            v = DtoLoad(v);
+        return v;
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
 void DtoAnnotation(const char* str)
 {
     std::string s("CODE: ");