Mercurial > projects > ldc
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); +}