diff gen/arrays.c @ 64:b688ad419f8c trunk

[svn r68] Added support for multi-dimensional static arrays. Several bugfixes to array support.
author lindquist
date Thu, 25 Oct 2007 12:09:13 +0200
parents 2c3cd3596187
children 2b5a2eaa88be
line wrap: on
line diff
--- a/gen/arrays.c	Thu Oct 25 10:05:21 2007 +0200
+++ b/gen/arrays.c	Thu Oct 25 12:09:13 2007 +0200
@@ -143,24 +143,53 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
+typedef const llvm::Type* constLLVMTypeP;
+
+static size_t checkRectArrayInit(const llvm::Type* pt, constLLVMTypeP& finalty)
+{
+    if (llvm::isa<llvm::ArrayType>(pt)) {
+        size_t n = checkRectArrayInit(pt->getContainedType(0), finalty);
+        size_t ne = llvm::cast<llvm::ArrayType>(pt)->getNumElements();
+        if (n) return n * ne;
+        return ne;
+    }
+    finalty = pt;
+    return 0;
+}
+
 void LLVM_DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val)
 {
-    const llvm::Type* t = ptr->getType()->getContainedType(0);
+    const llvm::Type* pt = ptr->getType()->getContainedType(0);
+    const llvm::Type* t = val->getType();
+    const llvm::Type* finalTy;
+    if (size_t arrsz = checkRectArrayInit(pt, finalTy)) {
+        assert(finalTy == t);
+        llvm::Constant* c = llvm::cast_or_null<llvm::Constant>(dim);
+        assert(c);
+        dim = llvm::ConstantExpr::getMul(c, LLVM_DtoConstSize_t(arrsz));
+        ptr = gIR->ir->CreateBitCast(ptr, llvm::PointerType::get(finalTy), "tmp");
+    }
+    else if (llvm::isa<llvm::StructType>(t)) {
+        assert(0);
+    }
+    else {
+        assert(t == pt);
+    }
 
     std::vector<llvm::Value*> args;
     args.push_back(ptr);
     args.push_back(dim);
     args.push_back(val);
-    
+
     const char* funcname = NULL;
-    
+
     if (llvm::isa<llvm::PointerType>(t)) {
         funcname = "_d_array_init_pointer";
-        
+
         const llvm::Type* dstty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty));
         if (args[0]->getType() != dstty)
             args[0] = new llvm::BitCastInst(args[0],dstty,"tmp",gIR->scopebb());
-        
+
         const llvm::Type* valty = llvm::PointerType::get(llvm::Type::Int8Ty);
         if (args[2]->getType() != valty)
             args[2] = new llvm::BitCastInst(args[2],valty,"tmp",gIR->scopebb());
@@ -187,6 +216,7 @@
         funcname = "_d_array_init_double";
     }
     else {
+        Logger::cout() << *ptr->getType() << " = " << *val->getType() << '\n';
         assert(0);
     }
 
@@ -607,3 +637,21 @@
     llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp");
     return b;
 }
+
+//////////////////////////////////////////////////////////////////////////////////////////
+llvm::Constant* LLVM_DtoConstantStaticArray(const llvm::Type* t, llvm::Constant* c)
+{
+    assert(llvm::isa<llvm::ArrayType>(t));
+    const llvm::ArrayType* at = llvm::cast<llvm::ArrayType>(t);
+
+    if (llvm::isa<llvm::ArrayType>(at->getElementType()))
+    {
+        c = LLVM_DtoConstantStaticArray(at->getElementType(), c);
+    }
+    else {
+        assert(at->getElementType() == c->getType());
+    }
+    std::vector<llvm::Constant*> initvals;
+    initvals.resize(at->getNumElements(), c);
+    return llvm::ConstantArray::get(at, initvals);
+}