changeset 244:a95056b3c996 trunk

[svn r261] Fixed debug info for integer and floating local variables, can now be inspected in GDB. Did a lot of smaller cleans up here and there. Replaced more llvm::Foo with LLFoo for common stuff. Split up tollvm.cpp.
author lindquist
date Mon, 09 Jun 2008 09:37:08 +0200
parents 4d006f7b2ada
children d61ce72c39ab
files gen/aa.cpp gen/arrays.cpp gen/arrays.h gen/binops.cpp gen/classes.cpp gen/complex.cpp gen/complex.h gen/functions.cpp gen/linker.cpp gen/linker.h gen/llvm.h gen/llvmhelpers.cpp gen/llvmhelpers.h gen/runtime.cpp gen/statements.cpp gen/structs.cpp gen/structs.h gen/todebug.cpp gen/todebug.h gen/toir.cpp gen/tollvm.cpp gen/tollvm.h gen/toobj.cpp gen/typinf.cpp ir/irstruct.h llvmdc.kdevelop.filelist
diffstat 26 files changed, 2027 insertions(+), 1989 deletions(-) [+]
line wrap: on
line diff
--- a/gen/aa.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/aa.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -7,6 +7,7 @@
 #include "gen/aa.h"
 #include "gen/runtime.h"
 #include "gen/tollvm.h"
+#include "gen/llvmhelpers.h"
 #include "gen/logger.h"
 #include "gen/irstate.h"
 #include "gen/dvalue.h"
--- a/gen/arrays.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/arrays.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -8,6 +8,7 @@
 
 #include "gen/irstate.h"
 #include "gen/tollvm.h"
+#include "gen/llvmhelpers.h"
 #include "gen/arrays.h"
 #include "gen/runtime.h"
 #include "gen/logger.h"
@@ -15,23 +16,23 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-const llvm::StructType* DtoArrayType(Type* arrayTy)
+const LLStructType* DtoArrayType(Type* arrayTy)
 {
     assert(arrayTy->next);
     const LLType* elemty = DtoType(arrayTy->next);
-    if (elemty == llvm::Type::VoidTy)
-        elemty = llvm::Type::Int8Ty;
-    return llvm::StructType::get(DtoSize_t(), getPtrToType(elemty), 0);
+    if (elemty == LLType::VoidTy)
+        elemty = LLType::Int8Ty;
+    return LLStructType::get(DtoSize_t(), getPtrToType(elemty), 0);
 }
 
-const llvm::StructType* DtoArrayType(const LLType* t)
+const LLStructType* DtoArrayType(const LLType* t)
 {
-    return llvm::StructType::get(DtoSize_t(), getPtrToType(t), 0);
+    return LLStructType::get(DtoSize_t(), getPtrToType(t), 0);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-const llvm::ArrayType* DtoStaticArrayType(Type* t)
+const LLArrayType* DtoStaticArrayType(Type* t)
 {
     if (t->ir.type)
         return isaArray(t->ir.type->get());
@@ -43,10 +44,10 @@
 
     TypeSArray* tsa = (TypeSArray*)t;
     assert(tsa->dim->type->isintegral());
-    const llvm::ArrayType* arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
+    const LLArrayType* arrty = LLArrayType::get(at,tsa->dim->toUInteger());
 
     assert(!tsa->ir.type);
-    tsa->ir.type = new llvm::PATypeHolder(arrty);
+    tsa->ir.type = new LLPATypeHolder(arrty);
     return arrty;
 }
 
@@ -57,14 +58,14 @@
     Logger::println("DtoSetArrayToNull");
     LOG_SCOPE;
 
-    LLValue* len = DtoGEPi(v,0,0,"tmp",gIR->scopebb());
+    LLValue* len = DtoGEPi(v,0,0);
     LLValue* zerolen = llvm::ConstantInt::get(len->getType()->getContainedType(0), 0, false);
-    new llvm::StoreInst(zerolen, len, gIR->scopebb());
+    DtoStore(zerolen, len);
 
-    LLValue* ptr = DtoGEPi(v,0,1,"tmp",gIR->scopebb());
-    const llvm::PointerType* pty = isaPointer(ptr->getType()->getContainedType(0));
+    LLValue* ptr = DtoGEPi(v,0,1);
+    const LLPointerType* pty = isaPointer(ptr->getType()->getContainedType(0));
     LLValue* nullptr = llvm::ConstantPointerNull::get(pty);
-    new llvm::StoreInst(nullptr, ptr, gIR->scopebb());
+    DtoStore(nullptr, ptr);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -77,20 +78,20 @@
     assert(gIR);
     if (dst->getType() == src->getType())
     {
-        LLValue* ptr = DtoGEPi(src,0,0,"tmp",gIR->scopebb());
-        LLValue* val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb());
-        ptr = DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
-        new llvm::StoreInst(val, ptr, gIR->scopebb());
+        LLValue* ptr = DtoGEPi(src,0,0);
+        LLValue* val = DtoLoad(ptr);
+        ptr = DtoGEPi(dst,0,0);
+        DtoStore(val, ptr);
 
-        ptr = DtoGEPi(src,0,1,"tmp",gIR->scopebb());
-        val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb());
-        ptr = DtoGEPi(dst,0,1,"tmp",gIR->scopebb());
-        new llvm::StoreInst(val, ptr, gIR->scopebb());
+        ptr = DtoGEPi(src,0,1);
+        val = DtoLoad(ptr);
+        ptr = DtoGEPi(dst,0,1);
+        DtoStore(val, ptr);
     }
     else
     {
         Logger::cout() << "array assignment type dont match: " << *dst->getType() << "\n\n" << *src->getType() << '\n';
-        const llvm::ArrayType* arrty = isaArray(src->getType()->getContainedType(0));
+        const LLArrayType* arrty = isaArray(src->getType()->getContainedType(0));
         if (!arrty)
         {
             Logger::cout() << "invalid: " << *src << '\n';
@@ -98,13 +99,13 @@
         }
         const LLType* dstty = getPtrToType(arrty->getElementType());
 
-        LLValue* dstlen = DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
+        LLValue* dstlen = DtoGEPi(dst,0,0);
         LLValue* srclen = DtoConstSize_t(arrty->getNumElements());
-        new llvm::StoreInst(srclen, dstlen, gIR->scopebb());
+        DtoStore(srclen, dstlen);
 
-        LLValue* dstptr = DtoGEPi(dst,0,1,"tmp",gIR->scopebb());
+        LLValue* dstptr = DtoGEPi(dst,0,1);
         LLValue* srcptr = DtoBitCast(src, dstty);
-        new llvm::StoreInst(srcptr, dstptr, gIR->scopebb());
+        DtoStore(srcptr, dstptr);
     }
 }
 
@@ -115,19 +116,19 @@
     Logger::println("DtoArrayInit");
     LOG_SCOPE;
 
-    const llvm::PointerType* ptrty = isaPointer(l->getType());
+    const LLPointerType* ptrty = isaPointer(l->getType());
     const LLType* t = ptrty->getContainedType(0);
-    const llvm::ArrayType* arrty = isaArray(t);
+    const LLArrayType* arrty = isaArray(t);
     if (arrty)
     {
-        LLValue* ptr = DtoGEPi(l,0,0,"tmp",gIR->scopebb());
-        LLValue* dim = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
+        LLValue* ptr = DtoGEPi(l,0,0);
+        LLValue* dim = DtoConstSize_t(arrty->getNumElements());
         DtoArrayInit(ptr, dim, r);
     }
     else if (isaStruct(t))
     {
-        LLValue* dim = DtoLoad(DtoGEPi(l, 0,0, "tmp"));
-        LLValue* ptr = DtoLoad(DtoGEPi(l, 0,1, "tmp"));
+        LLValue* dim = DtoLoad(DtoGEPi(l, 0,0));
+        LLValue* ptr = DtoLoad(DtoGEPi(l, 0,1));
         DtoArrayInit(ptr, dim, r);
     }
     else
@@ -140,7 +141,7 @@
 
 static size_t checkRectArrayInit(const LLType* pt, constLLVMTypeP& finalty)
 {
-    if (const llvm::ArrayType* arrty = isaArray(pt)) {
+    if (const LLArrayType* arrty = isaArray(pt)) {
         size_t n = checkRectArrayInit(arrty->getElementType(), finalty);
         size_t ne = arrty->getNumElements();
         if (n) return n * ne;
@@ -180,7 +181,7 @@
             return;
         }
         else {
-            ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(llvm::Type::Int8Ty), "tmp");
+            ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(LLType::Int8Ty), "tmp");
         }
     }
     else {
@@ -203,33 +204,33 @@
     else if (isaPointer(t)) {
         funcname = "_d_array_init_pointer";
 
-        const LLType* dstty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
+        const LLType* dstty = getPtrToType(getPtrToType(LLType::Int8Ty));
         if (args[0]->getType() != dstty)
             args[0] = DtoBitCast(args[0],dstty);
 
-        const LLType* valty = getPtrToType(llvm::Type::Int8Ty);
+        const LLType* valty = getPtrToType(LLType::Int8Ty);
         if (args[2]->getType() != valty)
             args[2] = DtoBitCast(args[2],valty);
     }
-    else if (t == llvm::Type::Int1Ty) {
+    else if (t == LLType::Int1Ty) {
         funcname = "_d_array_init_i1";
     }
-    else if (t == llvm::Type::Int8Ty) {
+    else if (t == LLType::Int8Ty) {
         funcname = "_d_array_init_i8";
     }
-    else if (t == llvm::Type::Int16Ty) {
+    else if (t == LLType::Int16Ty) {
         funcname = "_d_array_init_i16";
     }
-    else if (t == llvm::Type::Int32Ty) {
+    else if (t == LLType::Int32Ty) {
         funcname = "_d_array_init_i32";
     }
-    else if (t == llvm::Type::Int64Ty) {
+    else if (t == LLType::Int64Ty) {
         funcname = "_d_array_init_i64";
     }
-    else if (t == llvm::Type::FloatTy) {
+    else if (t == LLType::FloatTy) {
         funcname = "_d_array_init_float";
     }
-    else if (t == llvm::Type::DoubleTy) {
+    else if (t == LLType::DoubleTy) {
         funcname = "_d_array_init_double";
     }
     else {
@@ -237,7 +238,7 @@
         assert(0);
     }
 
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
+    LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
     assert(fn);
     Logger::cout() << "calling array init function: " << *fn <<'\n';
     llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb());
@@ -248,25 +249,9 @@
 
 void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr)
 {
-    Logger::println("DtoSetArray");
-    LOG_SCOPE;
-
-    Logger::cout() << "arr = " << *arr << '\n';
-    Logger::cout() << "dim = " << *dim << '\n';
-    Logger::cout() << "ptr = " << *ptr << '\n';
-
-    const llvm::StructType* st = isaStruct(arr->getType()->getContainedType(0));
-
-    LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-    LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
-
-    LLValue* arrdim = DtoGEP(arr,zero,zero,"tmp",gIR->scopebb());
-    Logger::cout() << "arrdim = " << *arrdim << '\n';
-    new llvm::StoreInst(dim, arrdim, gIR->scopebb());
-
-    LLValue* arrptr = DtoGEP(arr,zero,one,"tmp",gIR->scopebb());
-    Logger::cout() << "arrptr = " << *arrptr << '\n';
-    new llvm::StoreInst(ptr, arrptr, gIR->scopebb());
+    Logger::println("SetArray");
+    DtoStore(dim, DtoGEPi(arr,0,0));
+    DtoStore(ptr, DtoGEPi(arr,0,1));
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -326,7 +311,7 @@
                 LLConstant* cc = idx->toConstElem(gIR);
                 Logger::println("value gotten");
                 assert(cc != NULL);
-                llvm::ConstantInt* ci = llvm::dyn_cast<llvm::ConstantInt>(cc);
+                LLConstantInt* ci = llvm::dyn_cast<LLConstantInt>(cc);
                 assert(ci != NULL);
                 uint64_t k = ci->getZExtValue();
                 if (i == k)
@@ -356,15 +341,15 @@
     }
 
     Logger::println("building constant array");
-    const llvm::ArrayType* arrty = llvm::ArrayType::get(elemty,tdim);
-    LLConstant* constarr = llvm::ConstantArray::get(arrty, inits);
+    const LLArrayType* arrty = LLArrayType::get(elemty,tdim);
+    LLConstant* constarr = LLConstantArray::get(arrty, inits);
 
     if (arrinittype->ty == Tsarray)
         return constarr;
     else
         assert(arrinittype->ty == Tarray);
 
-    llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrty,true,llvm::GlobalValue::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);
@@ -390,7 +375,7 @@
         }
     }
     else if (isaArray(t)) {
-        ret = DtoGEPi(e->ptr, 0, 0, "tmp", gIR->scopebb());
+        ret = DtoGEPi(e->ptr, 0, 0);
 
         size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0));
         llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false);
@@ -401,14 +386,14 @@
         sz = llvm::ConstantExpr::getMul(elemsz, nelems);
     }
     else if (isaStruct(t)) {
-        ret = DtoGEPi(e->ptr, 0, 1, "tmp", gIR->scopebb());
-        ret = new llvm::LoadInst(ret, "tmp", gIR->scopebb());
+        ret = DtoGEPi(e->ptr, 0, 1);
+        ret = DtoLoad(ret);
 
         size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0));
         llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false);
 
-        LLValue* len = DtoGEPi(e->ptr, 0, 0, "tmp", gIR->scopebb());
-        len = new llvm::LoadInst(len, "tmp", gIR->scopebb());
+        LLValue* len = DtoGEPi(e->ptr, 0, 0);
+        len = DtoLoad(len);
         sz = llvm::BinaryOperator::createMul(len,elemsz,"tmp",gIR->scopebb());
     }
     else {
@@ -420,63 +405,32 @@
 void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src)
 {
     Logger::println("ArrayCopySlices");
-    const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
-
-    LLValue* sz1;
-    LLValue* dstarr = DtoBitCast(get_slice_ptr(dst,sz1),arrty);
-
-    LLValue* sz2;
-    LLValue* srcarr = DtoBitCast(get_slice_ptr(src,sz2),arrty);
 
-    llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
-    LLSmallVector<LLValue*, 4> llargs(4);
-    llargs[0] = dstarr;
-    llargs[1] = srcarr;
-    llargs[2] = sz1;
-    llargs[3] = DtoConstInt(0);
+    LLValue *sz1,*sz2;
+    LLValue* dstarr = get_slice_ptr(dst,sz1);
+    LLValue* srcarr = get_slice_ptr(src,sz2);
 
-    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
+    DtoMemCpy(dstarr, srcarr, sz1);
 }
 
 void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src)
 {
     Logger::println("ArrayCopyToSlice");
-    const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
 
     LLValue* sz1;
-    LLValue* dstarr = DtoBitCast(get_slice_ptr(dst,sz1),arrty);
-    LLValue* srcarr = DtoBitCast(DtoArrayPtr(src),arrty);
+    LLValue* dstarr = get_slice_ptr(dst,sz1);
+    LLValue* srcarr = DtoArrayPtr(src);
 
-    llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
-    LLSmallVector<LLValue*, 4> llargs(4);
-    llargs[0] = dstarr;
-    llargs[1] = srcarr;
-    llargs[2] = sz1;
-    llargs[3] = DtoConstInt(0);
-
-    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
+    DtoMemCpy(dstarr, srcarr, sz1);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 void DtoStaticArrayCopy(LLValue* dst, LLValue* src)
 {
-    Logger::cout() << "static array copy: " << *dst << " from " << *src << '\n';
-    assert(dst->getType() == src->getType());
-    size_t arrsz = getABITypeSize(dst->getType()->getContainedType(0));
-    LLValue* n = llvm::ConstantInt::get(DtoSize_t(), arrsz, false);
-
-    const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
-    LLValue* dstarr = DtoBitCast(dst,arrty);
-    LLValue* srcarr = DtoBitCast(src,arrty);
+    Logger::println("StaticArrayCopy");
 
-    llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
-    LLSmallVector<LLValue*,4> llargs(4);
-    llargs[0] = dstarr;
-    llargs[1] = srcarr;
-    llargs[2] = n;
-    llargs[3] = DtoConstInt(0);
-
-    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
+    size_t n = getABITypeSize(dst->getType()->getContainedType(0));
+    DtoMemCpy(dst, src, DtoConstSize_t(n));
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -501,7 +455,7 @@
 
     // get runtime function
     bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" );
+    LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" );
 
     // call allocator
     LLValue* newptr = gIR->ir->CreateCall2(fn, arrayTypeInfo, arrayLen, ".gc_mem");
@@ -538,7 +492,7 @@
     bool zeroInit = arrayType->toBasetype()->next->isZeroInit();
 
     // call runtime
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT" );
+    LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT" );
 
     LLSmallVector<LLValue*,4> args;
     args.push_back(DtoTypeInfoOf(arrayType));
@@ -725,7 +679,7 @@
 static LLValue* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti)
 {
     Logger::println("comparing arrays");
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, func);
+    LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, func);
     assert(fn);
 
     LLValue* lmem;
@@ -888,7 +842,7 @@
     args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false));
     args.push_back(llvm::ConstantInt::get(DtoSize_t(), nsz, false));
 
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
+    LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
     return llvm::CallInst::Create(fn, args.begin(), args.end(), "tmp", gIR->scopebb());
 }
 
@@ -898,12 +852,12 @@
     llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
 
     if (r == NULL) {
-        LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp");
+        LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0),"tmp");
         LLValue* rl = llvm::Constant::getNullValue(ll->getType());//DtoConstSize_t(0);
         LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
 
-        LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp");
-        const llvm::PointerType* pty = isaPointer(lp->getType());
+        LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1),"tmp");
+        const LLPointerType* pty = isaPointer(lp->getType());
         LLValue* rp = llvm::ConstantPointerNull::get(pty);
         LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
 
@@ -913,12 +867,12 @@
     else {
         assert(l->getType() == r->getType());
 
-        LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp");
-        LLValue* rl = gIR->ir->CreateLoad(DtoGEPi(r, 0,0, "tmp"),"tmp");
+        LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0),"tmp");
+        LLValue* rl = gIR->ir->CreateLoad(DtoGEPi(r, 0,0),"tmp");
         LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
 
-        LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp");
-        LLValue* rp = gIR->ir->CreateLoad(DtoGEPi(r, 0,1, "tmp"),"tmp");
+        LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1),"tmp");
+        LLValue* rp = gIR->ir->CreateLoad(DtoGEPi(r, 0,1),"tmp");
         LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
 
         LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp");
@@ -929,7 +883,7 @@
 //////////////////////////////////////////////////////////////////////////////////////////
 LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c)
 {
-    const llvm::ArrayType* at = isaArray(t);
+    const LLArrayType* at = isaArray(t);
     assert(at);
 
     if (isaArray(at->getElementType()))
@@ -956,19 +910,19 @@
             if (s->len) {
                 return s->len;
             }
-            const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
+            const LLArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
             if (arrTy)
                 return DtoConstSize_t(arrTy->getNumElements());
             else
-                return DtoLoad(DtoGEPi(s->ptr, 0,0, "tmp"));
+                return DtoLoad(DtoGEPi(s->ptr, 0,0));
         }
-        return DtoLoad(DtoGEPi(v->getRVal(), 0,0, "tmp"));
+        return DtoLoad(DtoGEPi(v->getRVal(), 0,0));
     }
     else if (t->ty == Tsarray) {
         assert(!v->isSlice());
         LLValue* rv = v->getRVal();
         Logger::cout() << "casting: " << *rv << '\n';
-        const llvm::ArrayType* t = isaArray(rv->getType()->getContainedType(0));
+        const LLArrayType* t = isaArray(rv->getType()->getContainedType(0));
         return DtoConstSize_t(t->getNumElements());
     }
     assert(0);
@@ -987,16 +941,16 @@
             if (s->len) return s->ptr;
             const LLType* t = s->ptr->getType()->getContainedType(0);
             Logger::cout() << "ptr of full slice: " << *s->ptr << '\n';
-            const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
+            const LLArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
             if (arrTy)
-                return DtoGEPi(s->ptr, 0,0, "tmp");
+                return DtoGEPi(s->ptr, 0,0);
             else
-                return DtoLoad(DtoGEPi(s->ptr, 0,1, "tmp"));
+                return DtoLoad(DtoGEPi(s->ptr, 0,1));
         }
-        return DtoLoad(DtoGEPi(v->getRVal(), 0,1, "tmp"));
+        return DtoLoad(DtoGEPi(v->getRVal(), 0,1));
     }
     else if (t->ty == Tsarray) {
-        return DtoGEPi(v->getRVal(), 0,0, "tmp");
+        return DtoGEPi(v->getRVal(), 0,0);
     }
     assert(0);
     return 0;
@@ -1028,13 +982,13 @@
     else if (totype->ty == Tarray) {
         Logger::cout() << "to array" << '\n';
         const LLType* ptrty = DtoType(totype->next);
-        if (ptrty == llvm::Type::VoidTy)
-            ptrty = llvm::Type::Int8Ty;
+        if (ptrty == LLType::VoidTy)
+            ptrty = LLType::Int8Ty;
         ptrty = getPtrToType(ptrty);
 
         const LLType* ety = DtoType(fromtype->next);
-        if (ety == llvm::Type::VoidTy)
-            ety = llvm::Type::Int8Ty;
+        if (ety == LLType::VoidTy)
+            ety = LLType::Int8Ty;
 
         if (DSliceValue* usl = u->isSlice()) {
             Logger::println("from slice");
@@ -1050,20 +1004,20 @@
             if (fromtype->ty == Tsarray) {
                 Logger::cout() << "uvalTy = " << *uval->getType() << '\n';
                 assert(isaPointer(uval->getType()));
-                const llvm::ArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
+                const LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
                 rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
                 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
                 rval = DtoBitCast(uval, ptrty);
             }
             else {
-                LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-                LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
-                rval2 = DtoGEP(uval,zero,zero,"tmp",gIR->scopebb());
-                rval2 = new llvm::LoadInst(rval2, "tmp", gIR->scopebb());
+                LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
+                LLValue* one = llvm::ConstantInt::get(LLType::Int32Ty, 1, false);
+                rval2 = DtoGEP(uval,zero,zero);
+                rval2 = DtoLoad(rval2);
                 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
 
-                rval = DtoGEP(uval,zero,one,"tmp",gIR->scopebb());
-                rval = new llvm::LoadInst(rval, "tmp", gIR->scopebb());
+                rval = DtoGEP(uval,zero,one);
+                rval = DtoLoad(rval);
                 //Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n';
                 rval = DtoBitCast(rval, ptrty);
             }
--- a/gen/arrays.h	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/arrays.h	Mon Jun 09 09:37:08 2008 +0200
@@ -9,7 +9,7 @@
 
 LLConstant* DtoConstArrayInitializer(ArrayInitializer* si);
 LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr);
-LLConstant* DtoConstStaticArray(const llvm::Type* t, LLConstant* c);
+LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c);
 
 void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src);
 void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src);
@@ -35,7 +35,7 @@
 
 LLValue* DtoDynArrayIs(TOK op, LLValue* l, LLValue* r);
 
-LLValue* DtoArrayCastLength(LLValue* len, const llvm::Type* elemty, const llvm::Type* newelemty);
+LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* newelemty);
 
 LLValue* DtoArrayLen(DValue* v);
 LLValue* DtoArrayPtr(DValue* v);
--- a/gen/binops.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/binops.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -35,7 +35,7 @@
 DValue* DtoBinDiv(DValue* lhs, DValue* rhs)
 {
     Type* t = lhs->getType();
-    llvm::Value *l, *r;
+    LLValue *l, *r;
     l = lhs->getRVal();
     r = rhs->getRVal();
     LLValue* res;
@@ -53,7 +53,7 @@
 DValue* DtoBinRem(DValue* lhs, DValue* rhs)
 {
     Type* t = lhs->getType();
-    llvm::Value *l, *r;
+    LLValue *l, *r;
     l = lhs->getRVal();
     r = rhs->getRVal();
     LLValue* res;
--- a/gen/classes.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/classes.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -8,6 +8,7 @@
 
 #include "gen/irstate.h"
 #include "gen/tollvm.h"
+#include "gen/llvmhelpers.h"
 #include "gen/arrays.h"
 #include "gen/logger.h"
 #include "gen/classes.h"
@@ -199,7 +200,7 @@
                 fieldtypes.push_back(fieldtype);
                 irstruct->defaultFields.push_back(fieldinit);
                 if (fieldpad) {
-                    fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad));
+                    fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad));
                     irstruct->defaultFields.push_back(NULL);
                     idx++;
                 }
@@ -218,7 +219,7 @@
         fieldtypes.push_back(fieldtype);
         irstruct->defaultFields.push_back(fieldinit);
         if (fieldpad) {
-            fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad));
+            fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad));
             irstruct->defaultFields.push_back(NULL);
         }
     }
@@ -498,7 +499,7 @@
     }
 
     // then comes monitor
-    fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
+    fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
 
     // go through the field inits and build the default initializer
     size_t nfi = irstruct->defaultFields.size();
@@ -511,7 +512,7 @@
         else {
             const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2));
             assert(arrty);
-            std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
+            std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(LLType::Int8Ty, 0, false));
             c = llvm::ConstantArray::get(arrty, vals);
         }
         fieldinits.push_back(c);
@@ -628,7 +629,7 @@
             infoInits.push_back(c);
 
             // vtbl
-            const LLType* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
+            const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::Int8Ty));
             c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
             c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c);
             infoInits.push_back(c);
@@ -706,7 +707,7 @@
             infoInits.push_back(c);
 
             // vtbl
-            const LLType* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
+            const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::Int8Ty));
             c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty));
             infoInits.push_back(c);
 
@@ -865,23 +866,10 @@
     assert(tc->sym->ir.irStruct->init);
     assert(dst->getType() == tc->sym->ir.irStruct->init->getType());
 
-    const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
-
     LLValue* dstarr = DtoGEPi(dst,0,2,"tmp");
-    dstarr = DtoBitCast(dstarr, arrty);
-
     LLValue* srcarr = DtoGEPi(tc->sym->ir.irStruct->init,0,2,"tmp");
-    srcarr = DtoBitCast(srcarr, arrty);
 
-    llvm::Function* fn = LLVM_DeclareMemCpy32();
-    std::vector<LLValue*> llargs;
-    llargs.resize(4);
-    llargs[0] = dstarr;
-    llargs[1] = srcarr;
-    llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
-    llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-
-    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
+    DtoMemCpy(dstarr, srcarr, DtoConstSize_t(n));
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -1343,16 +1331,16 @@
     std::vector<const LLType*> paramTypes;
     paramTypes.push_back(getPtrToType(cd->type->ir.type->get()));
 
-    const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false);
+    const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::VoidTy, paramTypes, false);
 
     if (cd->dtors.dim == 0) {
-        return llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty));
+        return llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty));
     }
     else if (cd->dtors.dim == 1) {
         DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
         DtoForceDeclareDsymbol(d);
         assert(d->ir.irFunc->func);
-        return llvm::ConstantExpr::getBitCast(isaConstant(d->ir.irFunc->func), getPtrToType(llvm::Type::Int8Ty));
+        return llvm::ConstantExpr::getBitCast(isaConstant(d->ir.irFunc->func), getPtrToType(LLType::Int8Ty));
     }
 
     std::string gname("_D");
@@ -1375,7 +1363,7 @@
     }
     builder.CreateRetVoid();
 
-    return llvm::ConstantExpr::getBitCast(func, getPtrToType(llvm::Type::Int8Ty));
+    return llvm::ConstantExpr::getBitCast(func, getPtrToType(LLType::Int8Ty));
 }
 
 static uint build_classinfo_flags(ClassDeclaration* cd)
@@ -1462,7 +1450,7 @@
     inits.push_back(c);
 
     // byte[] init
-    const LLType* byteptrty = getPtrToType(llvm::Type::Int8Ty);
+    const LLType* byteptrty = getPtrToType(LLType::Int8Ty);
     if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
         c = cinfo->ir.irStruct->constInit->getOperand(2);
     }
--- a/gen/complex.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/complex.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -5,6 +5,7 @@
 
 #include "gen/complex.h"
 #include "gen/tollvm.h"
+#include "gen/llvmhelpers.h"
 #include "gen/irstate.h"
 #include "gen/dvalue.h"
 
@@ -307,3 +308,56 @@
     LLValue* b2 = new llvm::FCmpInst(cmpop, b, d, "tmp", gIR->scopebb());
     return gIR->ir->CreateAnd(b1,b2,"tmp");
 }
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+DValue* DtoCastComplex(DValue* val, Type* _to)
+{
+    Type* to = DtoDType(_to);
+    Type* vty = val->getType();
+    if (to->iscomplex()) {
+        if (vty->size() == to->size())
+            return val;
+
+        llvm::Value *re, *im;
+        DtoGetComplexParts(val, re, im);
+        const LLType* toty = DtoComplexBaseType(to);
+
+        if (to->size() < vty->size()) {
+            re = gIR->ir->CreateFPTrunc(re, toty, "tmp");
+            im = gIR->ir->CreateFPTrunc(im, toty, "tmp");
+        }
+        else if (to->size() > vty->size()) {
+            re = gIR->ir->CreateFPExt(re, toty, "tmp");
+            im = gIR->ir->CreateFPExt(im, toty, "tmp");
+        }
+        else {
+            return val;
+        }
+
+        if (val->isComplex())
+            return new DComplexValue(_to, re, im);
+
+        // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions.
+        // so we need to give it storage, or fix the system that handles this stuff (DLRValue)
+        LLValue* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint());
+        DtoComplexSet(mem, re, im);
+        return new DLRValue(val->getType(), val->getRVal(), _to, mem);
+    }
+    else if (to->isimaginary()) {
+        if (val->isComplex())
+            return new DImValue(to, val->isComplex()->im);
+        LLValue* v = val->getRVal();
+        DImValue* im = new DImValue(to, DtoLoad(DtoGEPi(v,0,1,"tmp")));
+        return DtoCastFloat(im, to);
+    }
+    else if (to->isfloating()) {
+        if (val->isComplex())
+            return new DImValue(to, val->isComplex()->re);
+        LLValue* v = val->getRVal();
+        DImValue* re = new DImValue(to, DtoLoad(DtoGEPi(v,0,0,"tmp")));
+        return DtoCastFloat(re, to);
+    }
+    else
+    assert(0);
+}
\ No newline at end of file
--- a/gen/complex.h	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/complex.h	Mon Jun 09 09:37:08 2008 +0200
@@ -26,4 +26,6 @@
 
 LLValue* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs);
 
+DValue* DtoCastComplex(DValue* val, Type* to);
+
 #endif // LLVMDC_GEN_COMPLEX_H
--- a/gen/functions.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/functions.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -10,6 +10,7 @@
 
 #include "gen/irstate.h"
 #include "gen/tollvm.h"
+#include "gen/llvmhelpers.h"
 #include "gen/runtime.h"
 #include "gen/arrays.h"
 #include "gen/logger.h"
@@ -49,7 +50,7 @@
 
     if (ismain)
     {
-        rettype = llvm::Type::Int32Ty;
+        rettype = LLType::Int32Ty;
         actualRettype = rettype;
         if (Argument::dim(f->parameters) == 0)
         {
@@ -63,7 +64,7 @@
         Type* rtfin = DtoDType(rt);
         if (DtoIsReturnedInArg(rt)) {
             rettype = getPtrToType(DtoType(rt));
-            actualRettype = llvm::Type::VoidTy;
+            actualRettype = LLType::VoidTy;
             f->llvmRetInPtr = retinptr = true;
         }
         else {
@@ -92,7 +93,7 @@
         types.push_back(getPtrToType(getPtrToType(ti->ir.irStruct->constInit->getType())));
         const LLType* t1 = llvm::StructType::get(types);
         paramvec.push_back(getPtrToType(t1));
-        paramvec.push_back(getPtrToType(llvm::Type::Int8Ty));
+        paramvec.push_back(getPtrToType(LLType::Int8Ty));
     }
     else if (arrayVararg)
     {
@@ -172,7 +173,7 @@
     TypeFunction* f = (TypeFunction*)fdecl->type;
     assert(f != 0);
 
-    const llvm::PointerType* i8pty = getPtrToType(llvm::Type::Int8Ty);
+    const llvm::PointerType* i8pty = getPtrToType(LLType::Int8Ty);
     std::vector<const LLType*> args;
 
     if (fdecl->llvmInternal == LLVMva_start) {
@@ -187,7 +188,7 @@
     else
     assert(0);
 
-    const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::VoidTy, args, false);
+    const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::VoidTy, args, false);
 
     f->ir.type = new llvm::PATypeHolder(fty);
 
@@ -205,7 +206,7 @@
     // unittest has null type, just build it manually
     /*if (fdecl->isUnitTestDeclaration()) {
         std::vector<const LLType*> args;
-        return llvm::FunctionType::get(llvm::Type::VoidTy, args, false);
+        return llvm::FunctionType::get(LLType::VoidTy, args, false);
     }*/
 
     // type has already been resolved
@@ -228,7 +229,7 @@
         }
     }
     else if (fdecl->isNested()) {
-        thisty = getPtrToType(llvm::Type::Int8Ty);
+        thisty = getPtrToType(LLType::Int8Ty);
     }
 
     const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, fdecl->isMain());
@@ -549,194 +550,195 @@
     const llvm::FunctionType* functype = func->getFunctionType();
 
     // only members of the current module or template instances maybe be defined
-    if (fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent))
-    {
-        fd->ir.DModule = gIR->dmodule;
+    if (!(fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent)))
+        return;
 
-        // function definition
-        if (fd->fbody != 0)
-        {
-            Logger::println("Doing function body for: %s", fd->toChars());
-            assert(fd->ir.irFunc);
-            gIR->functions.push_back(fd->ir.irFunc);
-
-            if (fd->isMain())
-                gIR->emitMain = true;
-
-            std::string entryname("entry_");
-            entryname.append(fd->toPrettyChars());
+    // set module owner
+    fd->ir.DModule = gIR->dmodule;
 
-            llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(entryname,func);
-            llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endentry",func);
-
-            //assert(gIR->scopes.empty());
-            gIR->scopes.push_back(IRScope(beginbb, endbb));
+    // is there a body?
+    if (fd->fbody == NULL)
+        return;
 
-                // create alloca point
-                llvm::Instruction* allocaPoint = new llvm::AllocaInst(llvm::Type::Int32Ty, "alloca point", beginbb);
-                gIR->func()->allocapoint = allocaPoint;
-
-                // need result variable? (not nested)
-                if (fd->vresult && !fd->vresult->nestedref) {
-                    Logger::println("non-nested vresult value");
-                    fd->vresult->ir.irLocal = new IrLocal(fd->vresult);
-                    fd->vresult->ir.irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
-                }
+    Logger::println("Doing function body for: %s", fd->toChars());
+    assert(fd->ir.irFunc);
+    gIR->functions.push_back(fd->ir.irFunc);
 
-                // give arguments storage
-                if (fd->parameters)
-                {
-                    size_t n = fd->parameters->dim;
-                    for (int i=0; i < n; ++i)
-                    {
-                        Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i];
-                        VarDeclaration* vd = argsym->isVarDeclaration();
-                        assert(vd);
+    if (fd->isMain())
+        gIR->emitMain = true;
 
-                        if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
-                            continue;
-
-                        LLValue* a = vd->ir.irLocal->value;
-                        assert(a);
-                        std::string s(a->getName());
-                        Logger::println("giving argument '%s' storage", s.c_str());
-                        s.append("_storage");
+    std::string entryname("entry_");
+    entryname.append(fd->toPrettyChars());
 
-                        LLValue* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
-                        gIR->ir->CreateStore(a,v);
-                        vd->ir.irLocal->value = v;
-                    }
-                }
-
-                // debug info
-                if (global.params.symdebug) DtoDwarfFuncStart(fd);
+    llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(entryname,func);
+    llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endentry",func);
 
-                LLValue* parentNested = NULL;
-                if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) {
-                    if (!fd->isStatic()) // huh?
-                        parentNested = fd2->ir.irFunc->nestedVar;
-                }
+    //assert(gIR->scopes.empty());
+    gIR->scopes.push_back(IRScope(beginbb, endbb));
 
-                // need result variable? (nested)
-                if (fd->vresult && fd->vresult->nestedref) {
-                    Logger::println("nested vresult value: %s", fd->vresult->toChars());
-                    fd->nestedVars.insert(fd->vresult);
-                }
+    // create alloca point
+    llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::Int32Ty, "alloca point", beginbb);
+    gIR->func()->allocapoint = allocaPoint;
 
-                // construct nested variables struct
-                if (!fd->nestedVars.empty() || parentNested) {
-                    std::vector<const LLType*> nestTypes;
-                    int j = 0;
-                    if (parentNested) {
-                        nestTypes.push_back(parentNested->getType());
-                        j++;
-                    }
-                    for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
-                        VarDeclaration* vd = *i;
-                        Logger::println("referenced nested variable %s", vd->toChars());
-                        if (!vd->ir.irLocal)
-                            vd->ir.irLocal = new IrLocal(vd);
-                        vd->ir.irLocal->nestedIndex = j++;
-                        if (vd->isParameter()) {
-                            if (!vd->ir.irLocal->value) {
-                                assert(vd == fd->vthis);
-                                vd->ir.irLocal->value = fd->ir.irFunc->thisVar;
-                            }
-                            assert(vd->ir.irLocal->value);
-                            nestTypes.push_back(vd->ir.irLocal->value->getType());
-                        }
-                        else {
-                            nestTypes.push_back(DtoType(vd->type));
-                        }
-                    }
-                    const llvm::StructType* nestSType = llvm::StructType::get(nestTypes);
-                    Logger::cout() << "nested var struct has type:" << *nestSType << '\n';
-                    fd->ir.irFunc->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
-                    if (parentNested) {
-                        assert(fd->ir.irFunc->thisVar);
-                        LLValue* ptr = gIR->ir->CreateBitCast(fd->ir.irFunc->thisVar, parentNested->getType(), "tmp");
-                        gIR->ir->CreateStore(ptr, DtoGEPi(fd->ir.irFunc->nestedVar, 0,0, "tmp"));
-                    }
-                    for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
-                        VarDeclaration* vd = *i;
-                        if (vd->isParameter()) {
-                            assert(vd->ir.irLocal);
-                            gIR->ir->CreateStore(vd->ir.irLocal->value, DtoGEPi(fd->ir.irFunc->nestedVar, 0, vd->ir.irLocal->nestedIndex, "tmp"));
-                            vd->ir.irLocal->value = fd->ir.irFunc->nestedVar;
-                        }
-                    }
-                }
-
-                // copy _argptr to a memory location
-                if (f->linkage == LINKd && f->varargs == 1)
-                {
-                    LLValue* argptrmem = new llvm::AllocaInst(fd->ir.irFunc->_argptr->getType(), "_argptrmem", gIR->topallocapoint());
-                    new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb());
-                    fd->ir.irFunc->_argptr = argptrmem;
-                }
-
-                // output function body
-                fd->fbody->toIR(gIR);
+    // need result variable? (not nested)
+    if (fd->vresult && !fd->vresult->nestedref) {
+        Logger::println("non-nested vresult value");
+        fd->vresult->ir.irLocal = new IrLocal(fd->vresult);
+        fd->vresult->ir.irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
+    }
 
-                // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement
-                // in automatically, so we do it here.
-                if (!fd->isMain()) {
-                    if (!gIR->scopereturned()) {
-                        // pass the previous block into this block
-                        if (global.params.symdebug) DtoDwarfFuncEnd(fd);
-                        if (func->getReturnType() == llvm::Type::VoidTy) {
-                            llvm::ReturnInst::Create(gIR->scopebb());
-                        }
-                        else {
-                            llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb());
-                        }
-                    }
-                }
-
-                // erase alloca point
-                allocaPoint->eraseFromParent();
-                allocaPoint = 0;
-                gIR->func()->allocapoint = 0;
-
-            gIR->scopes.pop_back();
-
-            // get rid of the endentry block, it's never used
-            assert(!func->getBasicBlockList().empty());
-            func->getBasicBlockList().pop_back();
+    // give arguments storage
+    if (fd->parameters)
+    {
+        size_t n = fd->parameters->dim;
+        for (int i=0; i < n; ++i)
+        {
+            Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i];
+            VarDeclaration* vd = argsym->isVarDeclaration();
+            assert(vd);
 
-            // if the last block is empty now, it must be unreachable or it's a bug somewhere else
-            // would be nice to figure out how to assert that this is correct
-            llvm::BasicBlock* lastbb = &func->getBasicBlockList().back();
-            if (lastbb->empty()) {
-                if (lastbb->getNumUses() == 0)
-                    lastbb->eraseFromParent();
-                else {
-                    new llvm::UnreachableInst(lastbb);
-                    /*if (func->getReturnType() == llvm::Type::VoidTy) {
-                        llvm::ReturnInst::Create(lastbb);
-                    }
-                    else {
-                        llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), lastbb);
-                    }*/
-                }
-            }
+            if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
+                continue;
 
-            // if the last block is not terminated we return a null value or void
-            // for some unknown reason this is needed when a void main() has a inline asm block ...
-            // this should be harmless for well formed code!
-            lastbb = &func->getBasicBlockList().back();
-            if (!lastbb->getTerminator())
-            {
-                Logger::println("adding missing return statement");
-                if (func->getReturnType() == llvm::Type::VoidTy)
-                    llvm::ReturnInst::Create(lastbb);
-                else
-                    llvm::ReturnInst::Create(llvm::Constant::getNullValue(func->getReturnType()), lastbb);
-            }
+            LLValue* a = vd->ir.irLocal->value;
+            assert(a);
+            std::string s(a->getName());
+            Logger::println("giving argument '%s' storage", s.c_str());
+            s.append("_storage");
 
-            gIR->functions.pop_back();
+            LLValue* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
+            gIR->ir->CreateStore(a,v);
+            vd->ir.irLocal->value = v;
         }
     }
+
+    // debug info
+    if (global.params.symdebug) DtoDwarfFuncStart(fd);
+
+    LLValue* parentNested = NULL;
+    if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) {
+        if (!fd->isStatic()) // huh?
+            parentNested = fd2->ir.irFunc->nestedVar;
+    }
+
+    // need result variable? (nested)
+    if (fd->vresult && fd->vresult->nestedref) {
+        Logger::println("nested vresult value: %s", fd->vresult->toChars());
+        fd->nestedVars.insert(fd->vresult);
+    }
+
+    // construct nested variables struct
+    if (!fd->nestedVars.empty() || parentNested) {
+        std::vector<const LLType*> nestTypes;
+        int j = 0;
+        if (parentNested) {
+            nestTypes.push_back(parentNested->getType());
+            j++;
+        }
+        for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
+            VarDeclaration* vd = *i;
+            Logger::println("referenced nested variable %s", vd->toChars());
+            if (!vd->ir.irLocal)
+                vd->ir.irLocal = new IrLocal(vd);
+            vd->ir.irLocal->nestedIndex = j++;
+            if (vd->isParameter()) {
+                if (!vd->ir.irLocal->value) {
+                    assert(vd == fd->vthis);
+                    vd->ir.irLocal->value = fd->ir.irFunc->thisVar;
+                }
+                assert(vd->ir.irLocal->value);
+                nestTypes.push_back(vd->ir.irLocal->value->getType());
+            }
+            else {
+                nestTypes.push_back(DtoType(vd->type));
+            }
+        }
+        const llvm::StructType* nestSType = llvm::StructType::get(nestTypes);
+        Logger::cout() << "nested var struct has type:" << *nestSType << '\n';
+        fd->ir.irFunc->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
+        if (parentNested) {
+            assert(fd->ir.irFunc->thisVar);
+            LLValue* ptr = gIR->ir->CreateBitCast(fd->ir.irFunc->thisVar, parentNested->getType(), "tmp");
+            gIR->ir->CreateStore(ptr, DtoGEPi(fd->ir.irFunc->nestedVar, 0,0, "tmp"));
+        }
+        for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
+            VarDeclaration* vd = *i;
+            if (vd->isParameter()) {
+                assert(vd->ir.irLocal);
+                gIR->ir->CreateStore(vd->ir.irLocal->value, DtoGEPi(fd->ir.irFunc->nestedVar, 0, vd->ir.irLocal->nestedIndex, "tmp"));
+                vd->ir.irLocal->value = fd->ir.irFunc->nestedVar;
+            }
+        }
+    }
+
+    // copy _argptr to a memory location
+    if (f->linkage == LINKd && f->varargs == 1)
+    {
+        LLValue* argptrmem = new llvm::AllocaInst(fd->ir.irFunc->_argptr->getType(), "_argptrmem", gIR->topallocapoint());
+        new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb());
+        fd->ir.irFunc->_argptr = argptrmem;
+    }
+
+    // output function body
+    fd->fbody->toIR(gIR);
+
+    // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement
+    // in automatically, so we do it here.
+    if (!fd->isMain()) {
+        if (!gIR->scopereturned()) {
+            // pass the previous block into this block
+            if (global.params.symdebug) DtoDwarfFuncEnd(fd);
+            if (func->getReturnType() == LLType::VoidTy) {
+                llvm::ReturnInst::Create(gIR->scopebb());
+            }
+            else {
+                llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb());
+            }
+        }
+    }
+
+    // erase alloca point
+    allocaPoint->eraseFromParent();
+    allocaPoint = 0;
+    gIR->func()->allocapoint = 0;
+
+    gIR->scopes.pop_back();
+
+    // get rid of the endentry block, it's never used
+    assert(!func->getBasicBlockList().empty());
+    func->getBasicBlockList().pop_back();
+
+    // if the last block is empty now, it must be unreachable or it's a bug somewhere else
+    // would be nice to figure out how to assert that this is correct
+    llvm::BasicBlock* lastbb = &func->getBasicBlockList().back();
+    if (lastbb->empty()) {
+        if (lastbb->getNumUses() == 0)
+            lastbb->eraseFromParent();
+        else {
+            new llvm::UnreachableInst(lastbb);
+            /*if (func->getReturnType() == LLType::VoidTy) {
+                llvm::ReturnInst::Create(lastbb);
+            }
+            else {
+                llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), lastbb);
+            }*/
+        }
+    }
+
+    // if the last block is not terminated we return a null value or void
+    // for some unknown reason this is needed when a void main() has a inline asm block ...
+    // this should be harmless for well formed code!
+    lastbb = &func->getBasicBlockList().back();
+    if (!lastbb->getTerminator())
+    {
+        Logger::println("adding missing return statement");
+        if (func->getReturnType() == LLType::VoidTy)
+            llvm::ReturnInst::Create(lastbb);
+        else
+            llvm::ReturnInst::Create(llvm::Constant::getNullValue(func->getReturnType()), lastbb);
+    }
+
+    gIR->functions.pop_back();
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen/linker.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -0,0 +1,25 @@
+#include "gen/llvm.h"
+#include "llvm/Linker.h"
+
+#include "root.h"
+#include "mars.h"
+
+typedef std::vector<llvm::Module*> Module_vector;
+
+void linkModules(llvm::Module* dst, const Module_vector& MV)
+{
+    if (MV.empty())
+        return;
+
+    llvm::Linker linker("llvmdc", dst);
+
+    std::string err;
+    for (Module_vector::const_iterator i=MV.begin(); i!=MV.end(); ++i)
+    {
+        if (!linker.LinkInModule(*i, &err))
+        {
+            error("%s", err.c_str());
+            fatal();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen/linker.h	Mon Jun 09 09:37:08 2008 +0200
@@ -0,0 +1,11 @@
+#ifndef LLVMDC_GEN_LINKER_H
+#define LLVMDC_GEN_LINKER_H
+
+/**
+ * Links the modules given in MV in to dst.
+ * @param dst Destination module.
+ * @param MV Vector of modules to link in to destination.
+ */
+void linkModules(llvm::Module* dst, const std::vector<llvm::Module*>& MV);
+
+#endif // LLVMDC_GEN_LINKER_H
--- a/gen/llvm.h	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/llvm.h	Mon Jun 09 09:37:08 2008 +0200
@@ -18,10 +18,27 @@
 
 #define GET_INTRINSIC_DECL(_X) (llvm::Intrinsic::getDeclaration(gIR->module, llvm::Intrinsic:: _X ))
 
-// shortcuts for the _very_ common llvm types
+// shortcuts for the common llvm types
+
 typedef llvm::Type LLType;
+typedef llvm::FunctionType LLFunctionType;
+typedef llvm::PointerType LLPointerType;
+typedef llvm::StructType LLStructType;
+typedef llvm::ArrayType LLArrayType;
+typedef llvm::IntegerType LLIntegerType;
+typedef llvm::OpaqueType LLOpaqueType;
+
 typedef llvm::Value LLValue;
+typedef llvm::GlobalValue LLGlobalValue;
+typedef llvm::GlobalVariable LLGlobalVariable;
+typedef llvm::Function LLFunction;
+
 typedef llvm::Constant LLConstant;
+typedef llvm::ConstantStruct LLConstantStruct;
+typedef llvm::ConstantArray LLConstantArray;
+typedef llvm::ConstantInt LLConstantInt;
+
+typedef llvm::PATypeHolder LLPATypeHolder;
 
 #define LLSmallVector llvm::SmallVector
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen/llvmhelpers.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -0,0 +1,1090 @@
+#include "gen/llvm.h"
+
+#include "mars.h"
+#include "init.h"
+
+#include "gen/tollvm.h"
+#include "gen/llvmhelpers.h"
+#include "gen/irstate.h"
+#include "gen/runtime.h"
+#include "gen/logger.h"
+#include "gen/arrays.h"
+#include "gen/dvalue.h"
+#include "gen/complex.h"
+#include "gen/classes.h"
+#include "gen/functions.h"
+#include "gen/typeinf.h"
+
+/****************************************************************************************/
+/*////////////////////////////////////////////////////////////////////////////////////////
+// DYNAMIC MEMORY HELPERS
+////////////////////////////////////////////////////////////////////////////////////////*/
+
+LLValue* DtoNew(Type* newtype)
+{
+    // get runtime function
+    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT");
+    // get type info
+    LLConstant* ti = DtoTypeInfoOf(newtype);
+    assert(isaPointer(ti));
+    // call runtime allocator
+    LLValue* mem = gIR->ir->CreateCall(fn, ti, ".gc_mem");
+    // cast
+    return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem");
+}
+
+void DtoDeleteMemory(LLValue* ptr)
+{
+    // get runtime function
+    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delmemory");
+    // build args
+    LLSmallVector<LLValue*,1> arg;
+    arg.push_back(DtoBitCast(ptr, getVoidPtrType(), ".tmp"));
+    // call
+    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
+}
+
+void DtoDeleteClass(LLValue* inst)
+{
+    // get runtime function
+    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delclass");
+    // build args
+    LLSmallVector<LLValue*,1> arg;
+    arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
+    // call
+    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
+}
+
+void DtoDeleteInterface(LLValue* inst)
+{
+    // get runtime function
+    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delinterface");
+    // build args
+    LLSmallVector<LLValue*,1> arg;
+    arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
+    // call
+    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
+}
+
+void DtoDeleteArray(DValue* arr)
+{
+    // get runtime function
+    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delarray");
+    // build args
+    LLSmallVector<LLValue*,2> arg;
+    arg.push_back(DtoArrayLen(arr));
+    arg.push_back(DtoBitCast(DtoArrayPtr(arr), getVoidPtrType(), ".tmp"));
+    // call
+    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
+}
+
+/****************************************************************************************/
+/*////////////////////////////////////////////////////////////////////////////////////////
+// ASSERT HELPER
+////////////////////////////////////////////////////////////////////////////////////////*/
+
+void DtoAssert(Loc* loc, DValue* msg)
+{
+    std::vector<LLValue*> args;
+    LLConstant* c;
+
+    // func
+    const char* fname = msg ? "_d_assert_msg" : "_d_assert";
+    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname);
+
+    // param attrs
+    llvm::PAListPtr palist;
+    int idx = 1;
+
+    c = DtoConstString(loc->filename);
+
+    // msg param
+    if (msg)
+    {
+        if (DSliceValue* s = msg->isSlice())
+        {
+            llvm::AllocaInst* alloc = gIR->func()->msgArg;
+            if (!alloc)
+            {
+                alloc = new llvm::AllocaInst(c->getType(), ".assertmsg", gIR->topallocapoint());
+                DtoSetArray(alloc, DtoArrayLen(s), DtoArrayPtr(s));
+                gIR->func()->msgArg = alloc;
+            }
+            args.push_back(alloc);
+        }
+        else
+        {
+            args.push_back(msg->getRVal());
+        }
+        palist = palist.addAttr(idx++, llvm::ParamAttr::ByVal);
+    }
+
+    // file param
+    llvm::AllocaInst* alloc = gIR->func()->srcfileArg;
+    if (!alloc)
+    {
+        alloc = new llvm::AllocaInst(c->getType(), ".srcfile", gIR->topallocapoint());
+        gIR->func()->srcfileArg = alloc;
+    }
+    LLValue* ptr = DtoGEPi(alloc, 0,0, "tmp");
+    DtoStore(c->getOperand(0), ptr);
+    ptr = DtoGEPi(alloc, 0,1, "tmp");
+    DtoStore(c->getOperand(1), ptr);
+
+    args.push_back(alloc);
+    palist = palist.addAttr(idx++, llvm::ParamAttr::ByVal);
+
+
+    // line param
+    c = DtoConstUint(loc->linnum);
+    args.push_back(c);
+
+    // call
+    llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb());
+    call->setParamAttrs(palist);
+}
+
+/****************************************************************************************/
+/*////////////////////////////////////////////////////////////////////////////////////////
+// NESTED VARIABLE HELPERS
+////////////////////////////////////////////////////////////////////////////////////////*/
+
+static const LLType* get_next_frame_ptr_type(Dsymbol* sc)
+{
+    assert(sc->isFuncDeclaration() || sc->isClassDeclaration());
+    Dsymbol* p = sc->toParent2();
+    if (!p->isFuncDeclaration() && !p->isClassDeclaration())
+        Logger::println("unexpected parent symbol found while resolving frame pointer - '%s' kind: '%s'", p->toChars(), p->kind());
+    assert(p->isFuncDeclaration() || p->isClassDeclaration());
+    if (FuncDeclaration* fd = p->isFuncDeclaration())
+    {
+        LLValue* v = fd->ir.irFunc->nestedVar;
+        assert(v);
+        return v->getType();
+    }
+    else if (ClassDeclaration* cd = p->isClassDeclaration())
+    {
+        return DtoType(cd->type);
+    }
+    else
+    {
+        Logger::println("symbol: '%s' kind: '%s'", sc->toChars(), sc->kind());
+        assert(0);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+static LLValue* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, LLValue* v)
+{
+    LOG_SCOPE;
+    if (sc == func)
+    {
+        return v;
+    }
+    else if (FuncDeclaration* fd = sc->isFuncDeclaration())
+    {
+        Logger::println("scope is function: %s", fd->toChars());
+
+        if (fd->toParent2() == func)
+        {
+            if (!func->ir.irFunc->nestedVar)
+                return NULL;
+            return DtoBitCast(v, func->ir.irFunc->nestedVar->getType());
+        }
+
+        v = DtoBitCast(v, get_next_frame_ptr_type(fd));
+        Logger::cout() << "v = " << *v << '\n';
+
+        if (fd->toParent2()->isFuncDeclaration())
+        {
+            v = DtoGEPi(v, 0,0, "tmp");
+            v = DtoLoad(v);
+        }
+        else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration())
+        {
+            size_t idx = 2;
+            //idx += cd->ir.irStruct->interfaceVec.size();
+            v = DtoGEPi(v,0,idx,"tmp");
+            v = DtoLoad(v);
+        }
+        else
+        {
+            assert(0);
+        }
+        return get_frame_ptr_impl(func, fd->toParent2(), v);
+    }
+    else if (ClassDeclaration* cd = sc->isClassDeclaration())
+    {
+        Logger::println("scope is class: %s", cd->toChars());
+        /*size_t idx = 2;
+        idx += cd->llvmIrStruct->interfaces.size();
+        v = DtoGEPi(v,0,idx,"tmp");
+        Logger::cout() << "gep = " << *v << '\n';
+        v = DtoLoad(v);*/
+        return get_frame_ptr_impl(func, cd->toParent2(), v);
+    }
+    else
+    {
+        Logger::println("symbol: '%s'", sc->toPrettyChars());
+        assert(0);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+static LLValue* get_frame_ptr(FuncDeclaration* func)
+{
+    Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars());
+    LOG_SCOPE;
+    IrFunction* irfunc = gIR->func();
+
+    // in the right scope already
+    if (func == irfunc->decl)
+        return irfunc->decl->ir.irFunc->nestedVar;
+
+    // use the 'this' pointer
+    LLValue* ptr = irfunc->decl->ir.irFunc->thisVar;
+    assert(ptr);
+
+    // return the fully resolved frame pointer
+    ptr = get_frame_ptr_impl(func, irfunc->decl, ptr);
+    if (ptr) Logger::cout() << "Found context!" << *ptr;
+    else Logger::cout() << "NULL context!\n";
+
+    return ptr;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+LLValue* DtoNestedContext(FuncDeclaration* func)
+{
+    // resolve frame ptr
+    LLValue* ptr = get_frame_ptr(func);
+    Logger::cout() << "Nested context ptr = ";
+    if (ptr) Logger::cout() << *ptr;
+    else Logger::cout() << "NULL";
+    Logger::cout() << '\n';
+    return ptr;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+static void print_frame_worker(VarDeclaration* vd, Dsymbol* par)
+{
+    if (vd->toParent2() == par)
+    {
+        Logger::println("found: '%s' kind: '%s'", par->toChars(), par->kind());
+        return;
+    }
+
+    Logger::println("diving into: '%s' kind: '%s'", par->toChars(), par->kind());
+    LOG_SCOPE;
+    print_frame_worker(vd, par->toParent2());
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+static void print_nested_frame_list(VarDeclaration* vd, Dsymbol* par)
+{
+    Logger::println("Frame pointer list for nested var: '%s'", vd->toPrettyChars());
+    LOG_SCOPE;
+    if (vd->toParent2() != par)
+        print_frame_worker(vd, par);
+    else
+        Logger::println("Found at level 0");
+    Logger::println("Done");
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+LLValue* DtoNestedVariable(VarDeclaration* vd)
+{
+    // log the frame list
+    IrFunction* irfunc = gIR->func();
+    if (Logger::enabled())
+        print_nested_frame_list(vd, irfunc->decl);
+
+    // resolve frame ptr
+    FuncDeclaration* func = vd->toParent2()->isFuncDeclaration();
+    assert(func);
+    LLValue* ptr = DtoNestedContext(func);
+    assert(ptr && "nested var, but no context");
+
+    // we must cast here to be sure. nested classes just have a void*
+    ptr = DtoBitCast(ptr, func->ir.irFunc->nestedVar->getType());
+
+    // index nested var and load (if necessary)
+    LLValue* v = DtoGEPi(ptr, 0, vd->ir.irLocal->nestedIndex, "tmp");
+    // references must be loaded, for normal variables this IS already the variable storage!!!
+    if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)))
+        v = DtoLoad(v);
+
+    // log and return
+    Logger::cout() << "Nested var ptr = " << *v << '\n';
+    return v;
+}
+
+/****************************************************************************************/
+/*////////////////////////////////////////////////////////////////////////////////////////
+// ASSIGNMENT HELPER (store this in that)
+////////////////////////////////////////////////////////////////////////////////////////*/
+
+void DtoAssign(DValue* lhs, DValue* rhs)
+{
+    Logger::cout() << "DtoAssign(...);\n";
+    LOG_SCOPE;
+
+    Type* t = DtoDType(lhs->getType());
+    Type* t2 = DtoDType(rhs->getType());
+
+    if (t->ty == Tstruct) {
+        if (t2 != t) {
+            // TODO: fix this, use 'rhs' for something
+            DtoAggrZeroInit(lhs->getLVal());
+        }
+        else if (!rhs->inPlace()) {
+            DtoAggrCopy(lhs->getLVal(), rhs->getRVal());
+        }
+    }
+    else if (t->ty == Tarray) {
+        // lhs is slice
+        if (DSliceValue* s = lhs->isSlice()) {
+            if (DSliceValue* s2 = rhs->isSlice()) {
+                DtoArrayCopySlices(s, s2);
+            }
+            else if (t->next == t2) {
+                if (s->len)
+                    DtoArrayInit(s->ptr, s->len, rhs->getRVal());
+                else
+                    DtoArrayInit(s->ptr, rhs->getRVal());
+            }
+            else {
+                DtoArrayCopyToSlice(s, rhs);
+            }
+        }
+        // rhs is slice
+        else if (DSliceValue* s = rhs->isSlice()) {
+            assert(s->getType()->toBasetype() == lhs->getType()->toBasetype());
+            DtoSetArray(lhs->getLVal(),DtoArrayLen(s),DtoArrayPtr(s));
+        }
+        // null
+        else if (rhs->isNull()) {
+            DtoSetArrayToNull(lhs->getLVal());
+        }
+        // reference assignment
+        else {
+            DtoArrayAssign(lhs->getLVal(), rhs->getRVal());
+        }
+    }
+    else if (t->ty == Tsarray) {
+        if (DtoType(lhs->getType()) == DtoType(rhs->getType())) {
+            DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal());
+        }
+        else {
+            DtoArrayInit(lhs->getLVal(), rhs->getRVal());
+        }
+    }
+    else if (t->ty == Tdelegate) {
+        if (rhs->isNull())
+            DtoAggrZeroInit(lhs->getLVal());
+        else if (!rhs->inPlace()) {
+            LLValue* l = lhs->getLVal();
+            LLValue* r = rhs->getRVal();
+            Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
+            DtoAggrCopy(l, r);
+        }
+    }
+    else if (t->ty == Tclass) {
+        assert(t2->ty == Tclass);
+        // assignment to this in constructor special case
+        if (lhs->isThis()) {
+            LLValue* tmp = rhs->getRVal();
+            FuncDeclaration* fdecl = gIR->func()->decl;
+            // respecify the this param
+            if (!llvm::isa<llvm::AllocaInst>(fdecl->ir.irFunc->thisVar))
+                fdecl->ir.irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint());
+            DtoStore(tmp, fdecl->ir.irFunc->thisVar);
+        }
+        // regular class ref -> class ref assignment
+        else {
+            DtoStore(rhs->getRVal(), lhs->getLVal());
+        }
+    }
+    else if (t->iscomplex()) {
+        assert(!lhs->isComplex());
+
+        LLValue* dst;
+        if (DLRValue* lr = lhs->isLRValue()) {
+            dst = lr->getLVal();
+            rhs = DtoCastComplex(rhs, lr->getLType());
+        }
+        else {
+            dst = lhs->getRVal();
+        }
+
+        if (DComplexValue* cx = rhs->isComplex())
+            DtoComplexSet(dst, cx->re, cx->im);
+        else
+            DtoComplexAssign(dst, rhs->getRVal());
+    }
+    else {
+        LLValue* l = lhs->getLVal();
+        LLValue* r = rhs->getRVal();
+        Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
+        const LLType* lit = l->getType()->getContainedType(0);
+        if (r->getType() != lit) {
+            // handle lvalue cast assignments
+            if (DLRValue* lr = lhs->isLRValue()) {
+                Logger::println("lvalue cast!");
+                r = DtoCast(rhs, lr->getLType())->getRVal();
+            }
+            else {
+                r = DtoCast(rhs, lhs->getType())->getRVal();
+            }
+            Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n';
+            assert(r->getType() == l->getType()->getContainedType(0));
+        }
+        gIR->ir->CreateStore(r, l);
+    }
+}
+
+/****************************************************************************************/
+/*////////////////////////////////////////////////////////////////////////////////////////
+//      CASTING HELPERS
+////////////////////////////////////////////////////////////////////////////////////////*/
+
+DValue* DtoCastInt(DValue* val, Type* _to)
+{
+    const LLType* tolltype = DtoType(_to);
+
+    Type* to = DtoDType(_to);
+    Type* from = DtoDType(val->getType());
+    assert(from->isintegral());
+
+    size_t fromsz = from->size();
+    size_t tosz = to->size();
+
+    LLValue* rval = val->getRVal();
+    if (rval->getType() == tolltype) {
+        return new DImValue(_to, rval);
+    }
+
+    if (to->isintegral()) {
+        if (fromsz < tosz) {
+            Logger::cout() << "cast to: " << *tolltype << '\n';
+            if (from->isunsigned() || from->ty == Tbool) {
+                rval = new llvm::ZExtInst(rval, tolltype, "tmp", gIR->scopebb());
+            } else {
+                rval = new llvm::SExtInst(rval, tolltype, "tmp", gIR->scopebb());
+            }
+        }
+        else if (fromsz > tosz) {
+            rval = new llvm::TruncInst(rval, tolltype, "tmp", gIR->scopebb());
+        }
+        else {
+            rval = DtoBitCast(rval, tolltype);
+        }
+    }
+    else if (to->isfloating()) {
+        if (from->isunsigned()) {
+            rval = new llvm::UIToFPInst(rval, tolltype, "tmp", gIR->scopebb());
+        }
+        else {
+            rval = new llvm::SIToFPInst(rval, tolltype, "tmp", gIR->scopebb());
+        }
+    }
+    else if (to->ty == Tpointer) {
+        Logger::cout() << "cast pointer: " << *tolltype << '\n';
+        rval = gIR->ir->CreateIntToPtr(rval, tolltype, "tmp");
+    }
+    else {
+        assert(0 && "bad int cast");
+    }
+
+    return new DImValue(_to, rval);
+}
+
+DValue* DtoCastPtr(DValue* val, Type* to)
+{
+    const LLType* tolltype = DtoType(to);
+
+    Type* totype = DtoDType(to);
+    Type* fromtype = DtoDType(val->getType());
+    assert(fromtype->ty == Tpointer || fromtype->ty == Tfunction);
+
+    LLValue* rval;
+
+    if (totype->ty == Tpointer || totype->ty == Tclass) {
+        LLValue* src = val->getRVal();
+        Logger::cout() << "src: " << *src << "to type: " << *tolltype << '\n';
+        rval = DtoBitCast(src, tolltype);
+    }
+    else if (totype->isintegral()) {
+        rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
+    }
+    else {
+        Logger::println("invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars());
+        assert(0);
+    }
+
+    return new DImValue(to, rval);
+}
+
+DValue* DtoCastFloat(DValue* val, Type* to)
+{
+    if (val->getType() == to)
+        return val;
+
+    const LLType* tolltype = DtoType(to);
+
+    Type* totype = DtoDType(to);
+    Type* fromtype = DtoDType(val->getType());
+    assert(fromtype->isfloating());
+
+    size_t fromsz = fromtype->size();
+    size_t tosz = totype->size();
+
+    LLValue* rval;
+
+    if (totype->iscomplex()) {
+        assert(0);
+        //return new DImValue(to, DtoComplex(to, val));
+    }
+    else if (totype->isfloating()) {
+        if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) {
+            rval = val->getRVal();
+        }
+        else if (fromsz < tosz) {
+            rval = new llvm::FPExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
+        }
+        else if (fromsz > tosz) {
+            rval = new llvm::FPTruncInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
+        }
+        else {
+            assert(0 && "bad float cast");
+        }
+    }
+    else if (totype->isintegral()) {
+        if (totype->isunsigned()) {
+            rval = new llvm::FPToUIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
+        }
+        else {
+            rval = new llvm::FPToSIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
+        }
+    }
+    else {
+        assert(0 && "bad float cast");
+    }
+
+    return new DImValue(to, rval);
+}
+
+DValue* DtoCast(DValue* val, Type* to)
+{
+    Type* fromtype = DtoDType(val->getType());
+    Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars());
+    if (fromtype->isintegral()) {
+        return DtoCastInt(val, to);
+    }
+    else if (fromtype->iscomplex()) {
+        return DtoCastComplex(val, to);
+    }
+    else if (fromtype->isfloating()) {
+        return DtoCastFloat(val, to);
+    }
+    else if (fromtype->ty == Tclass) {
+        return DtoCastClass(val, to);
+    }
+    else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) {
+        return DtoCastArray(val, to);
+    }
+    else if (fromtype->ty == Tpointer || fromtype->ty == Tfunction) {
+        return DtoCastPtr(val, to);
+    }
+    else {
+        assert(0);
+    }
+}
+
+/****************************************************************************************/
+/*////////////////////////////////////////////////////////////////////////////////////////
+//      TEMPLATE HELPERS
+////////////////////////////////////////////////////////////////////////////////////////*/
+
+bool DtoIsTemplateInstance(Dsymbol* s)
+{
+    if (!s) return false;
+    if (s->isTemplateInstance() && !s->isTemplateMixin())
+        return true;
+    else if (s->parent)
+        return DtoIsTemplateInstance(s->parent);
+    return false;
+}
+
+/****************************************************************************************/
+/*////////////////////////////////////////////////////////////////////////////////////////
+//      LAZY STATIC INIT HELPER
+////////////////////////////////////////////////////////////////////////////////////////*/
+
+void DtoLazyStaticInit(bool istempl, LLValue* gvar, Initializer* init, Type* t)
+{
+    // create a flag to make sure initialization only happens once
+    llvm::GlobalValue::LinkageTypes gflaglink = istempl ? llvm::GlobalValue::WeakLinkage : llvm::GlobalValue::InternalLinkage;
+    std::string gflagname(gvar->getName());
+    gflagname.append("__initflag");
+    llvm::GlobalVariable* gflag = new llvm::GlobalVariable(LLType::Int1Ty,false,gflaglink,DtoConstBool(false),gflagname,gIR->module);
+
+    // check flag and do init if not already done
+    llvm::BasicBlock* oldend = gIR->scopeend();
+    llvm::BasicBlock* initbb = llvm::BasicBlock::Create("ifnotinit",gIR->topfunc(),oldend);
+    llvm::BasicBlock* endinitbb = llvm::BasicBlock::Create("ifnotinitend",gIR->topfunc(),oldend);
+    LLValue* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false));
+    gIR->ir->CreateCondBr(cond, initbb, endinitbb);
+    gIR->scope() = IRScope(initbb,endinitbb);
+    DValue* ie = DtoInitializer(init);
+    if (!ie->inPlace()) {
+        DValue* dst = new DVarValue(t, gvar, true);
+        DtoAssign(dst, ie);
+    }
+    gIR->ir->CreateStore(DtoConstBool(true), gflag);
+    gIR->ir->CreateBr(endinitbb);
+    gIR->scope() = IRScope(endinitbb,oldend);
+}
+
+/****************************************************************************************/
+/*////////////////////////////////////////////////////////////////////////////////////////
+//      PROCESSING QUEUE HELPERS
+////////////////////////////////////////////////////////////////////////////////////////*/
+
+void DtoResolveDsymbol(Dsymbol* dsym)
+{
+    if (StructDeclaration* sd = dsym->isStructDeclaration()) {
+        DtoResolveStruct(sd);
+    }
+    else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
+        DtoResolveClass(cd);
+    }
+    else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
+        DtoResolveFunction(fd);
+    }
+    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
+        DtoResolveTypeInfo(fd);
+    }
+    else {
+    error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
+    assert(0 && "unsupported dsymbol for DtoResolveDsymbol");
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoDeclareDsymbol(Dsymbol* dsym)
+{
+    if (StructDeclaration* sd = dsym->isStructDeclaration()) {
+        DtoDeclareStruct(sd);
+    }
+    else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
+        DtoDeclareClass(cd);
+    }
+    else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
+        DtoDeclareFunction(fd);
+    }
+    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
+        DtoDeclareTypeInfo(fd);
+    }
+    else {
+    error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
+    assert(0 && "unsupported dsymbol for DtoDeclareDsymbol");
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoConstInitDsymbol(Dsymbol* dsym)
+{
+    if (StructDeclaration* sd = dsym->isStructDeclaration()) {
+        DtoConstInitStruct(sd);
+    }
+    else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
+        DtoConstInitClass(cd);
+    }
+    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
+        DtoConstInitTypeInfo(fd);
+    }
+    else if (VarDeclaration* vd = dsym->isVarDeclaration()) {
+        DtoConstInitGlobal(vd);
+    }
+    else {
+    error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
+    assert(0 && "unsupported dsymbol for DtoConstInitDsymbol");
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoDefineDsymbol(Dsymbol* dsym)
+{
+    if (StructDeclaration* sd = dsym->isStructDeclaration()) {
+        DtoDefineStruct(sd);
+    }
+    else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
+        DtoDefineClass(cd);
+    }
+    else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
+        DtoDefineFunc(fd);
+    }
+    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
+        DtoDefineTypeInfo(fd);
+    }
+    else {
+    error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
+    assert(0 && "unsupported dsymbol for DtoDefineDsymbol");
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoConstInitGlobal(VarDeclaration* vd)
+{
+    if (vd->ir.initialized) return;
+    vd->ir.initialized = gIR->dmodule;
+
+    Logger::println("* DtoConstInitGlobal(%s)", vd->toChars());
+    LOG_SCOPE;
+
+    bool emitRTstaticInit = false;
+
+    LLConstant* _init = 0;
+    if (vd->parent && vd->parent->isFuncDeclaration() && vd->init && vd->init->isExpInitializer()) {
+        _init = DtoConstInitializer(vd->type, NULL);
+        emitRTstaticInit = true;
+    }
+    else {
+        _init = DtoConstInitializer(vd->type, vd->init);
+    }
+
+    const LLType* _type = DtoType(vd->type);
+    Type* t = DtoDType(vd->type);
+
+    //Logger::cout() << "initializer: " << *_init << '\n';
+    if (_type != _init->getType()) {
+        Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n";
+        // zero initalizer
+        if (_init->isNullValue())
+            _init = llvm::Constant::getNullValue(_type);
+        // pointer to global constant (struct.init)
+        else if (llvm::isa<llvm::GlobalVariable>(_init))
+        {
+            assert(_init->getType()->getContainedType(0) == _type);
+            llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init);
+            assert(t->ty == Tstruct);
+            TypeStruct* ts = (TypeStruct*)t;
+            assert(ts->sym->ir.irStruct->constInit);
+            _init = ts->sym->ir.irStruct->constInit;
+        }
+        // array single value init
+        else if (isaArray(_type))
+        {
+            _init = DtoConstStaticArray(_type, _init);
+        }
+        else {
+            Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
+            //assert(0);
+        }
+    }
+
+    bool istempl = false;
+    if ((vd->storage_class & STCcomdat) || (vd->parent && DtoIsTemplateInstance(vd->parent))) {
+        istempl = true;
+    }
+
+    if (_init && _init->getType() != _type)
+        _type = _init->getType();
+    llvm::cast<LLOpaqueType>(vd->ir.irGlobal->type.get())->refineAbstractTypeTo(_type);
+    _type = vd->ir.irGlobal->type.get();
+    //_type->dump();
+    assert(!_type->isAbstract());
+
+    llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->ir.irGlobal->value);
+    if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl))
+    {
+        gvar->setInitializer(_init);
+    }
+
+    if (emitRTstaticInit)
+        DtoLazyStaticInit(istempl, gvar, vd->init, t);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoEmptyResolveList()
+{
+    //Logger::println("DtoEmptyResolveList()");
+    Dsymbol* dsym;
+    while (!gIR->resolveList.empty()) {
+        dsym = gIR->resolveList.front();
+        gIR->resolveList.pop_front();
+        DtoResolveDsymbol(dsym);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoEmptyDeclareList()
+{
+    //Logger::println("DtoEmptyDeclareList()");
+    Dsymbol* dsym;
+    while (!gIR->declareList.empty()) {
+        dsym = gIR->declareList.front();
+        gIR->declareList.pop_front();
+        DtoDeclareDsymbol(dsym);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoEmptyConstInitList()
+{
+    //Logger::println("DtoEmptyConstInitList()");
+    Dsymbol* dsym;
+    while (!gIR->constInitList.empty()) {
+        dsym = gIR->constInitList.front();
+        gIR->constInitList.pop_front();
+        DtoConstInitDsymbol(dsym);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoEmptyDefineList()
+{
+    //Logger::println("DtoEmptyDefineList()");
+    Dsymbol* dsym;
+    while (!gIR->defineList.empty()) {
+        dsym = gIR->defineList.front();
+        gIR->defineList.pop_front();
+        DtoDefineDsymbol(dsym);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void DtoEmptyAllLists()
+{
+    for(;;)
+    {
+        Dsymbol* dsym;
+        if (!gIR->resolveList.empty()) {
+            dsym = gIR->resolveList.front();
+            gIR->resolveList.pop_front();
+            DtoResolveDsymbol(dsym);
+        }
+        else if (!gIR->declareList.empty()) {
+            dsym = gIR->declareList.front();
+            gIR->declareList.pop_front();
+            DtoDeclareDsymbol(dsym);
+        }
+        else if (!gIR->constInitList.empty()) {
+            dsym = gIR->constInitList.front();
+            gIR->constInitList.pop_front();
+            DtoConstInitDsymbol(dsym);
+        }
+        else if (!gIR->defineList.empty()) {
+            dsym = gIR->defineList.front();
+            gIR->defineList.pop_front();
+            DtoDefineDsymbol(dsym);
+        }
+        else {
+            break;
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoForceDeclareDsymbol(Dsymbol* dsym)
+{
+    if (dsym->ir.declared) return;
+    Logger::println("DtoForceDeclareDsymbol(%s)", dsym->toPrettyChars());
+    LOG_SCOPE;
+    DtoResolveDsymbol(dsym);
+
+    DtoEmptyResolveList();
+
+    DtoDeclareDsymbol(dsym);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoForceConstInitDsymbol(Dsymbol* dsym)
+{
+    if (dsym->ir.initialized) return;
+    Logger::println("DtoForceConstInitDsymbol(%s)", dsym->toPrettyChars());
+    LOG_SCOPE;
+    DtoResolveDsymbol(dsym);
+
+    DtoEmptyResolveList();
+    DtoEmptyDeclareList();
+
+    DtoConstInitDsymbol(dsym);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoForceDefineDsymbol(Dsymbol* dsym)
+{
+    if (dsym->ir.defined) return;
+    Logger::println("DtoForceDefineDsymbol(%s)", dsym->toPrettyChars());
+    LOG_SCOPE;
+    DtoResolveDsymbol(dsym);
+
+    DtoEmptyResolveList();
+    DtoEmptyDeclareList();
+    DtoEmptyConstInitList();
+
+    DtoDefineDsymbol(dsym);
+}
+
+/****************************************************************************************/
+/*////////////////////////////////////////////////////////////////////////////////////////
+//      INITIALIZER HELPERS
+////////////////////////////////////////////////////////////////////////////////////////*/
+
+LLConstant* DtoConstInitializer(Type* type, Initializer* init)
+{
+    LLConstant* _init = 0; // may return zero
+    if (!init)
+    {
+        Logger::println("const default initializer for %s", type->toChars());
+        _init = type->defaultInit()->toConstElem(gIR);
+    }
+    else if (ExpInitializer* ex = init->isExpInitializer())
+    {
+        Logger::println("const expression initializer");
+        _init = ex->exp->toConstElem(gIR);
+    }
+    else if (StructInitializer* si = init->isStructInitializer())
+    {
+        Logger::println("const struct initializer");
+        _init = DtoConstStructInitializer(si);
+    }
+    else if (ArrayInitializer* ai = init->isArrayInitializer())
+    {
+        Logger::println("const array initializer");
+        _init = DtoConstArrayInitializer(ai);
+    }
+    else if (init->isVoidInitializer())
+    {
+        Logger::println("const void initializer");
+        const LLType* ty = DtoType(type);
+        _init = llvm::Constant::getNullValue(ty);
+    }
+    else {
+        Logger::println("unsupported const initializer: %s", init->toChars());
+    }
+    return _init;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+LLConstant* DtoConstFieldInitializer(Type* t, Initializer* init)
+{
+    Logger::println("DtoConstFieldInitializer");
+    LOG_SCOPE;
+
+    const LLType* _type = DtoType(t);
+
+    LLConstant* _init = DtoConstInitializer(t, init);
+    assert(_init);
+    if (_type != _init->getType())
+    {
+        Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n';
+        if (t->ty == Tsarray)
+        {
+            const LLArrayType* arrty = isaArray(_type);
+            uint64_t n = arrty->getNumElements();
+            std::vector<LLConstant*> vals(n,_init);
+            _init = llvm::ConstantArray::get(arrty, vals);
+        }
+        else if (t->ty == Tarray)
+        {
+            assert(isaStruct(_type));
+            _init = llvm::ConstantAggregateZero::get(_type);
+        }
+        else if (t->ty == Tstruct)
+        {
+            const LLStructType* structty = isaStruct(_type);
+            TypeStruct* ts = (TypeStruct*)t;
+            assert(ts);
+            assert(ts->sym);
+            assert(ts->sym->ir.irStruct->constInit);
+            _init = ts->sym->ir.irStruct->constInit;
+        }
+        else if (t->ty == Tclass)
+        {
+            _init = llvm::Constant::getNullValue(_type);
+        }
+        else {
+            Logger::println("failed for type %s", t->toChars());
+            assert(0);
+        }
+    }
+
+    return _init;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+DValue* DtoInitializer(Initializer* init)
+{
+    if (ExpInitializer* ex = init->isExpInitializer())
+    {
+        Logger::println("expression initializer");
+        assert(ex->exp);
+        return ex->exp->toElem(gIR);
+    }
+    else if (init->isVoidInitializer())
+    {
+        // do nothing
+    }
+    else {
+        Logger::println("unsupported initializer: %s", init->toChars());
+        assert(0);
+    }
+    return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoAnnotation(const char* str)
+{
+    std::string s("CODE: ");
+    s.append(str);
+    char* p = &s[0];
+    while (*p)
+    {
+        if (*p == '"')
+            *p = '\'';
+        ++p;
+    }
+    // create a noop with the code as the result name!
+    gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str());
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+LLConstant* DtoTypeInfoOf(Type* type, bool base)
+{
+    const LLType* typeinfotype = DtoType(Type::typeinfo->type);
+    if (!type->vtinfo)
+        type->getTypeInfo(NULL);
+    TypeInfoDeclaration* tidecl = type->vtinfo;
+    DtoForceDeclareDsymbol(tidecl);
+    assert(tidecl->ir.irGlobal != NULL);
+    LLConstant* c = isaConstant(tidecl->ir.irGlobal->value);
+    assert(c != NULL);
+    if (base)
+        return llvm::ConstantExpr::getBitCast(c, typeinfotype);
+    return c;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen/llvmhelpers.h	Mon Jun 09 09:37:08 2008 +0200
@@ -0,0 +1,65 @@
+#ifndef LLVMDC_GEN_LLVMHELPERS_H
+#define LLVMDC_GEN_LLVMHELPERS_H
+
+// dynamic memory helpers
+LLValue* DtoNew(Type* newtype);
+void DtoDeleteMemory(LLValue* ptr);
+void DtoDeleteClass(LLValue* inst);
+void DtoDeleteInterface(LLValue* inst);
+void DtoDeleteArray(DValue* arr);
+
+// assertion generator
+void DtoAssert(Loc* loc, DValue* msg);
+
+// nested variable/class helpers
+LLValue* DtoNestedContext(FuncDeclaration* func);
+LLValue* DtoNestedVariable(VarDeclaration* vd);
+
+// basic operations
+void DtoAssign(DValue* lhs, DValue* rhs);
+
+// casts
+DValue* DtoCastInt(DValue* val, Type* to);
+DValue* DtoCastPtr(DValue* val, Type* to);
+DValue* DtoCastFloat(DValue* val, Type* to);
+DValue* DtoCast(DValue* val, Type* to);
+
+// is template instance check
+bool DtoIsTemplateInstance(Dsymbol* s);
+
+// generates lazy static initialization code for a global variable
+void DtoLazyStaticInit(bool istempl, LLValue* gvar, Initializer* init, Type* t);
+
+// these are all basically drivers for the codegeneration called by the main loop
+void DtoResolveDsymbol(Dsymbol* dsym);
+void DtoDeclareDsymbol(Dsymbol* dsym);
+void DtoDefineDsymbol(Dsymbol* dsym);
+void DtoConstInitDsymbol(Dsymbol* dsym);
+void DtoConstInitGlobal(VarDeclaration* vd);
+void DtoEmptyResolveList();
+void DtoEmptyDeclareList();
+void DtoEmptyConstInitList();
+void DtoEmptyAllLists();
+void DtoForceDeclareDsymbol(Dsymbol* dsym);
+void DtoForceConstInitDsymbol(Dsymbol* dsym);
+void DtoForceDefineDsymbol(Dsymbol* dsym);
+
+// initializer helpers
+LLConstant* DtoConstInitializer(Type* type, Initializer* init);
+LLConstant* DtoConstFieldInitializer(Type* type, Initializer* init);
+DValue* DtoInitializer(Initializer* init);
+
+// annotation generator
+void DtoAnnotation(const char* str);
+
+// getting typeinfo of type, base=true casts to object.TypeInfo
+LLConstant* DtoTypeInfoOf(Type* ty, bool base=true);
+
+// binary operations
+DValue* DtoBinAdd(DValue* lhs, DValue* rhs);
+DValue* DtoBinSub(DValue* lhs, DValue* rhs);
+DValue* DtoBinMul(DValue* lhs, DValue* rhs);
+DValue* DtoBinDiv(DValue* lhs, DValue* rhs);
+DValue* DtoBinRem(DValue* lhs, DValue* rhs);
+
+#endif
--- a/gen/runtime.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/runtime.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -158,12 +158,12 @@
 static const LLType* rt_dg1()
 {
     std::vector<const LLType*> types;
-    types.push_back(rt_ptr(llvm::Type::Int8Ty));
-    types.push_back(rt_ptr(llvm::Type::Int8Ty));
-    const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::Int32Ty, types, false);
+    types.push_back(rt_ptr(LLType::Int8Ty));
+    types.push_back(rt_ptr(LLType::Int8Ty));
+    const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::Int32Ty, types, false);
 
     std::vector<const LLType*> t;
-    t.push_back(rt_ptr(llvm::Type::Int8Ty));
+    t.push_back(rt_ptr(LLType::Int8Ty));
     t.push_back(rt_ptr(fty));
     return rt_ptr(llvm::StructType::get(t));
 }
@@ -171,13 +171,13 @@
 static const LLType* rt_dg2()
 {
     std::vector<const LLType*> types;
-    types.push_back(rt_ptr(llvm::Type::Int8Ty));
-    types.push_back(rt_ptr(llvm::Type::Int8Ty));
-    types.push_back(rt_ptr(llvm::Type::Int8Ty));
-    const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::Int32Ty, types, false);
+    types.push_back(rt_ptr(LLType::Int8Ty));
+    types.push_back(rt_ptr(LLType::Int8Ty));
+    types.push_back(rt_ptr(LLType::Int8Ty));
+    const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::Int32Ty, types, false);
 
     std::vector<const LLType*> t;
-    t.push_back(rt_ptr(llvm::Type::Int8Ty));
+    t.push_back(rt_ptr(LLType::Int8Ty));
     t.push_back(rt_ptr(fty));
     return rt_ptr(llvm::StructType::get(t));
 }
@@ -186,14 +186,14 @@
 {
     M = new llvm::Module("llvmdc internal runtime");
 
-    const LLType* voidTy = llvm::Type::VoidTy;
-    const LLType* boolTy = llvm::Type::Int1Ty;
-    const LLType* byteTy = llvm::Type::Int8Ty;
-    const LLType* shortTy = llvm::Type::Int16Ty;
-    const LLType* intTy = llvm::Type::Int32Ty;
-    const LLType* longTy = llvm::Type::Int64Ty;
-    const LLType* floatTy = llvm::Type::FloatTy;
-    const LLType* doubleTy = llvm::Type::DoubleTy;
+    const LLType* voidTy = LLType::VoidTy;
+    const LLType* boolTy = LLType::Int1Ty;
+    const LLType* byteTy = LLType::Int8Ty;
+    const LLType* shortTy = LLType::Int16Ty;
+    const LLType* intTy = LLType::Int32Ty;
+    const LLType* longTy = LLType::Int64Ty;
+    const LLType* floatTy = LLType::FloatTy;
+    const LLType* doubleTy = LLType::DoubleTy;
     const LLType* sizeTy = DtoSize_t();
     const LLType* voidPtrTy = rt_ptr(byteTy);
     const LLType* stringTy = rt_array(byteTy);
--- a/gen/statements.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/statements.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -20,6 +20,7 @@
 #include "gen/irstate.h"
 #include "gen/logger.h"
 #include "gen/tollvm.h"
+#include "gen/llvmhelpers.h"
 #include "gen/runtime.h"
 #include "gen/arrays.h"
 #include "gen/todebug.h"
@@ -74,7 +75,7 @@
 
     if (exp)
     {
-        if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
+        if (p->topfunc()->getReturnType() == LLType::VoidTy) {
             IrFunction* f = p->func();
             assert(f->type->llvmRetInPtr);
             assert(f->decl->ir.irFunc->retArg);
@@ -128,7 +129,7 @@
     }
     else
     {
-        assert(p->topfunc()->getReturnType() == llvm::Type::VoidTy);
+        assert(p->topfunc()->getReturnType() == LLType::VoidTy);
         emit_finallyblocks(p, enclosingtryfinally, NULL);
 
         if (gIR->func()->inVolatile) {
@@ -187,7 +188,7 @@
     llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endif", gIR->topfunc(), oldend);
     llvm::BasicBlock* elsebb = elsebody ? llvm::BasicBlock::Create("else", gIR->topfunc(), endbb) : endbb;
 
-    if (cond_val->getType() != llvm::Type::Int1Ty) {
+    if (cond_val->getType() != LLType::Int1Ty) {
         Logger::cout() << "if conditional: " << *cond_val << '\n';
         cond_val = DtoBoolean(cond_val);
     }
@@ -892,10 +893,10 @@
         else {
             Logger::println("foreach over dynamic array");
             val = aggrval->getRVal();
-            niters = DtoGEPi(val,0,0,"tmp",p->scopebb());
-            niters = p->ir->CreateLoad(niters, "numiterations");
-            val = DtoGEPi(val,0,1,"tmp",p->scopebb());
-            val = p->ir->CreateLoad(val, "collection");
+            niters = DtoGEPi(val,0,0);
+            niters = DtoLoad(niters, "numiterations");
+            val = DtoGEPi(val,0,1);
+            val = DtoLoad(val, "collection");
         }
     }
     else
@@ -935,7 +936,7 @@
     p->scope() = IRScope(condbb,bodybb);
 
     LLValue* done = 0;
-    LLValue* load = new llvm::LoadInst(keyvar, "tmp", p->scopebb());
+    LLValue* load = DtoLoad(keyvar);
     if (op == TOKforeach) {
         done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, niters, "tmp", p->scopebb());
     }
--- a/gen/structs.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/structs.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -9,6 +9,7 @@
 
 #include "gen/irstate.h"
 #include "gen/tollvm.h"
+#include "gen/llvmhelpers.h"
 #include "gen/arrays.h"
 #include "gen/logger.h"
 #include "gen/structs.h"
@@ -16,66 +17,6 @@
 #include "ir/irstruct.h"
 
 //////////////////////////////////////////////////////////////////////////////////////////
-
-const LLType* DtoStructType(Type* t)
-{
-    assert(0);
-    std::vector<const LLType*> types;
-    return llvm::StructType::get(types);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-LLValue* DtoStructZeroInit(LLValue* v)
-{
-    assert(gIR);
-    uint64_t n = getTypeStoreSize(v->getType()->getContainedType(0));
-    //LLType* sarrty = getPtrToType(llvm::ArrayType::get(llvm::Type::Int8Ty, n));
-    const LLType* sarrty = getPtrToType(llvm::Type::Int8Ty);
-
-    LLValue* sarr = DtoBitCast(v, sarrty);
-
-    llvm::Function* fn = LLVM_DeclareMemSet32();
-    assert(fn);
-    std::vector<LLValue*> llargs;
-    llargs.resize(4);
-    llargs[0] = sarr;
-    llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
-    llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
-    llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-
-    LLValue* ret = llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
-
-    return ret;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-LLValue* DtoStructCopy(LLValue* dst, LLValue* src)
-{
-    Logger::cout() << "dst = " << *dst << " src = " << *src << '\n';
-    assert(dst->getType() == src->getType());
-    assert(gIR);
-
-    uint64_t n = getTypeStoreSize(dst->getType()->getContainedType(0));
-    //LLType* sarrty = getPtrToType(llvm::ArrayType::get(llvm::Type::Int8Ty, n));
-    const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
-
-    LLValue* dstarr = DtoBitCast(dst,arrty);
-    LLValue* srcarr = DtoBitCast(src,arrty);
-
-    llvm::Function* fn = LLVM_DeclareMemCpy32();
-    std::vector<LLValue*> llargs;
-    llargs.resize(4);
-    llargs[0] = dstarr;
-    llargs[1] = srcarr;
-    llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
-    llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-
-    return llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
 LLConstant* DtoConstStructInitializer(StructInitializer* si)
 {
     Logger::println("DtoConstStructInitializer: %s", si->toChars());
@@ -227,7 +168,7 @@
     if (irstruct->offsets.empty())
     {
         Logger::println("has no fields");
-        fieldtypes.push_back(llvm::Type::Int8Ty);
+        fieldtypes.push_back(LLType::Int8Ty);
         structtype = llvm::StructType::get(fieldtypes);
     }
     else
@@ -273,7 +214,7 @@
                 fieldtypes.push_back(fieldtype);
                 irstruct->defaultFields.push_back(fieldinit);
                 if (fieldpad) {
-                    fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad));
+                    fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad));
                     irstruct->defaultFields.push_back(NULL);
                     idx++;
                 }
@@ -292,7 +233,7 @@
         fieldtypes.push_back(fieldtype);
         irstruct->defaultFields.push_back(fieldinit);
         if (fieldpad) {
-            fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad));
+            fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad));
             irstruct->defaultFields.push_back(NULL);
         }
 
@@ -380,7 +321,7 @@
         }
         else {
             const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i));
-            std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
+            std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(LLType::Int8Ty, 0, false));
             c = llvm::ConstantArray::get(arrty, vals);
         }
         fieldinits_ll.push_back(c);
@@ -392,6 +333,7 @@
     // always generate the constant initalizer
     if (!sd->zeroInit) {
         Logger::println("Not zero initialized");
+    #if 0
         //assert(tk == gIR->gIR->topstruct()().size());
         #ifndef LLVMD_NO_LOGGER
         Logger::cout() << "struct type: " << *structtype << '\n';
@@ -403,6 +345,7 @@
         }
         Logger::cout() << "Initializer printed" << '\n';
         #endif
+    #endif
         sd->ir.irStruct->constInit = llvm::ConstantStruct::get(structtype,fieldinits_ll);
     }
     else {
@@ -498,8 +441,8 @@
 static void push_nulls(size_t nbytes, std::vector<LLConstant*>& out)
 {
     assert(nbytes > 0);
-    std::vector<LLConstant*> i(nbytes, llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
-    out.push_back(llvm::ConstantArray::get(llvm::ArrayType::get(llvm::Type::Int8Ty, nbytes), i));
+    std::vector<LLConstant*> i(nbytes, llvm::ConstantInt::get(LLType::Int8Ty, 0, false));
+    out.push_back(llvm::ConstantArray::get(llvm::ArrayType::get(LLType::Int8Ty, nbytes), i));
 }
 
 LLConstant* DUnion::getConst(std::vector<DUnionIdx>& in)
--- a/gen/structs.h	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/structs.h	Mon Jun 09 09:37:08 2008 +0200
@@ -3,11 +3,6 @@
 
 struct StructInitializer;
 
-const LLType* DtoStructType(Type* t);
-
-LLValue* DtoStructZeroInit(LLValue* v);
-LLValue* DtoStructCopy(LLValue* dst, LLValue* src);
-
 LLConstant* DtoConstStructInitializer(StructInitializer* si);
 
 /**
--- a/gen/todebug.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/todebug.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -22,17 +22,15 @@
 
 static const llvm::PointerType* dbgArrTy()
 {
-    std::vector<const LLType*> t;
-    return ptrTy(llvm::StructType::get(t));
+    return ptrTy(llvm::StructType::get(NULL,NULL));
 }
 
 static LLConstant* dbgToArrTy(LLConstant* c)
 {
-    Logger::cout() << "casting: " << *c << '\n';
     return llvm::ConstantExpr::getBitCast(c, dbgArrTy());
 }
 
-#define Ty(X) llvm::Type::X
+#define Ty(X) LLType::X
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -48,7 +46,7 @@
         uint    ;; Tag of descriptors grouped by the anchor
     }
     */
-    std::vector<const LLType*> elems(2, Ty(Int32Ty));
+
     const llvm::StructType* t = isaStruct(gIR->module->getTypeByName("llvm.dbg.anchor.type"));
 
     /*
@@ -154,7 +152,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit)
+LLGlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit)
 {
     std::vector<LLConstant*> vals;
     vals.push_back(llvm::ConstantExpr::getAdd(
@@ -203,3 +201,111 @@
     args.push_back(dbgToArrTy(DtoDwarfCompileUnit(fd->getModule())));
     gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end());
 }
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+const llvm::StructType* GetDwarfBasicTypeType() {
+    return isaStruct(gIR->module->getTypeByName("llvm.dbg.basictype.type"));
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+LLGlobalVariable* DtoDwarfBasicType(Type* type, llvm::GlobalVariable* compileUnit)
+{
+    const LLType* T = DtoType(type);
+
+    std::vector<LLConstant*> vals;
+    // tag
+    vals.push_back(llvm::ConstantExpr::getAdd(
+        DtoConstUint(DW_TAG_base_type),
+        DtoConstUint(llvm::LLVMDebugVersion)));
+    // context
+    vals.push_back(dbgToArrTy(compileUnit));
+    // name
+    vals.push_back(DtoConstStringPtr(type->toChars(), "llvm.metadata"));
+    // compile unit where defined
+    vals.push_back(getNullPtr(dbgArrTy()));
+    // line number where defined
+    vals.push_back(DtoConstInt(0));
+    // size in bits
+    vals.push_back(LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false));
+    // alignment in bits
+    vals.push_back(LLConstantInt::get(LLType::Int64Ty, getABITypeAlign(T)*8, false));
+    // offset in bits
+    vals.push_back(LLConstantInt::get(LLType::Int64Ty, 0, false));
+    // FIXME: dont know what this is
+    vals.push_back(DtoConstUint(0));
+    // dwarf type
+    unsigned id;
+    if (type->isintegral())
+    {
+        if (type->isunsigned())
+            id = llvm::dwarf::DW_ATE_unsigned;
+        else
+            id = llvm::dwarf::DW_ATE_signed;
+    }
+    else if (type->isfloating())
+    {
+        id = llvm::dwarf::DW_ATE_float;
+    }
+    else
+    {
+        assert(0 && "unsupported basictype for debug info");
+    }
+    vals.push_back(DtoConstUint(id));
+
+    LLConstant* c = llvm::ConstantStruct::get(GetDwarfBasicTypeType(), vals);
+    LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, LLGlobalValue::InternalLinkage, c, "llvm.dbg.basictype", gIR->module);
+    gv->setSection("llvm.metadata");
+    return gv;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+const llvm::StructType* GetDwarfVariableType() {
+    return isaStruct(gIR->module->getTypeByName("llvm.dbg.variable.type"));
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+LLGlobalVariable* DtoDwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr)
+{
+    unsigned tag;
+    if (vd->isParameter())
+        tag = DW_TAG_arg_variable;
+    else if (vd->isCodeseg())
+        assert(0 && "a static variable");
+    else
+        tag = DW_TAG_auto_variable;
+
+    std::vector<LLConstant*> vals;
+    // tag
+    vals.push_back(llvm::ConstantExpr::getAdd(
+        DtoConstUint(tag),
+        DtoConstUint(llvm::LLVMDebugVersion)));
+    // context
+    vals.push_back(dbgToArrTy(gIR->func()->dwarfSubProg));
+    // name
+    vals.push_back(DtoConstStringPtr(vd->toChars(), "llvm.metadata"));
+    // compile unit where defined
+    vals.push_back(dbgToArrTy(DtoDwarfCompileUnit(vd->getModule())));
+    // line number where defined
+    vals.push_back(DtoConstUint(vd->loc.linnum));
+    // type descriptor
+    vals.push_back(dbgToArrTy(typeDescr));
+
+    LLConstant* c = llvm::ConstantStruct::get(GetDwarfVariableType(), vals);
+    LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, LLGlobalValue::InternalLinkage, c, "llvm.dbg.variable", gIR->module);
+    gv->setSection("llvm.metadata");
+    return gv;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+void DtoDwarfDeclare(LLValue* var, LLGlobalVariable* varDescr)
+{
+    LLSmallVector<LLValue*,2> args;
+    args.push_back(DtoBitCast(var, dbgArrTy()));
+    args.push_back(dbgToArrTy(varDescr));
+    gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.declare"), args.begin(), args.end());
+}
--- a/gen/todebug.h	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/todebug.h	Mon Jun 09 09:37:08 2008 +0200
@@ -15,6 +15,13 @@
 
 void DtoDwarfStopPoint(unsigned ln);
 
+const llvm::StructType* GetDwarfBasicTypeType();
+LLGlobalVariable* DtoDwarfBasicType(Type* type, llvm::GlobalVariable* compileUnit);
+
+const llvm::StructType* GetDwarfVariableType();
+LLGlobalVariable* DtoDwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr);
+void DtoDwarfDeclare(LLValue* var, LLGlobalVariable* varDescr);
+
 #endif // LLVMDC_GEN_TODEBUG_H
 
 
--- a/gen/toir.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/toir.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -24,6 +24,7 @@
 #include "gen/irstate.h"
 #include "gen/logger.h"
 #include "gen/tollvm.h"
+#include "gen/llvmhelpers.h"
 #include "gen/runtime.h"
 #include "gen/arrays.h"
 #include "gen/structs.h"
@@ -33,6 +34,7 @@
 #include "gen/dvalue.h"
 #include "gen/aa.h"
 #include "gen/functions.h"
+#include "gen/todebug.h"
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
@@ -75,6 +77,14 @@
                 assert(!vd->ir.irLocal);
                 vd->ir.irLocal = new IrLocal(vd);
                 vd->ir.irLocal->value = allocainst;
+
+                if (global.params.symdebug && (vd->type->isintegral() || vd->type->isfloating()))
+                {
+                    LLGlobalVariable* cu = DtoDwarfCompileUnit(vd->getModule());
+                    LLGlobalVariable* bt = DtoDwarfBasicType(vd->type, cu);
+                    LLGlobalVariable* vdesc = DtoDwarfVariable(vd, bt);
+                    DtoDwarfDeclare(allocainst, vdesc);
+                }
             }
 
             Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n';
@@ -315,7 +325,7 @@
         LLConstant* i = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)value,false);
         return llvm::ConstantExpr::getIntToPtr(i, t);
     }
-    assert(llvm::isa<llvm::IntegerType>(t));
+    assert(llvm::isa<LLIntegerType>(t));
     LLConstant* c = llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned());
     assert(c);
     Logger::cout() << "value = " << *c << '\n';
@@ -410,10 +420,10 @@
     Type* cty = DtoDType(dtype->next);
 
     const LLType* ct = DtoType(cty);
-    if (ct == llvm::Type::VoidTy)
-        ct = llvm::Type::Int8Ty;
+    if (ct == LLType::VoidTy)
+        ct = LLType::Int8Ty;
     //printf("ct = %s\n", type->next->toChars());
-    const llvm::ArrayType* at = llvm::ArrayType::get(ct,len+1);
+    const LLArrayType* at = LLArrayType::get(ct,len+1);
 
     LLConstant* _init;
     if (cty->size() == 1) {
@@ -446,7 +456,7 @@
     Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n';
     llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".stringliteral",gIR->module);
 
-    llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
+    llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
     LLConstant* idxs[2] = { zero, zero };
     LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
 
@@ -471,7 +481,7 @@
         assert(0);
     }
     else if (dtype->ty == Tsarray) {
-        const LLType* dstType = getPtrToType(llvm::ArrayType::get(ct, len));
+        const LLType* dstType = getPtrToType(LLArrayType::get(ct, len));
         LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType);
         return new DVarValue(type, emem, true);
     }
@@ -497,7 +507,7 @@
     size_t endlen = nullterm ? len+1 : len;
 
     const LLType* ct = DtoType(cty);
-    const llvm::ArrayType* at = llvm::ArrayType::get(ct,endlen);
+    const LLArrayType* at = LLArrayType::get(ct,endlen);
 
     LLConstant* _init;
     if (cty->size() == 1) {
@@ -536,7 +546,7 @@
     llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
     llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".stringliteral",gIR->module);
 
-    llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
+    llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
     LLConstant* idxs[2] = { zero, zero };
     LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
 
@@ -880,8 +890,6 @@
     Type* e1type = DtoDType(e1->type);
 
     bool delegateCall = false;
-    LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false);
-    LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty,1,false);
     LINK dlink = LINKd;
 
     // hidden struct return parameter handling
@@ -952,7 +960,7 @@
             DValue* expv = exp->toElem(p);
             if (expv->getType()->toBasetype()->ty != Tint32)
                 expv = DtoCast(expv, Type::tint32);
-            LLValue* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb());
+            LLValue* alloc = new llvm::AllocaInst(LLType::Int8Ty, expv->getRVal(), "alloca", p->scopebb());
             // done
             return new DImValue(type, alloc);
         }
@@ -972,32 +980,32 @@
     assert(funcval != 0);
     std::vector<LLValue*> llargs(n, 0);
 
-    const llvm::FunctionType* llfnty = 0;
+    const LLFunctionType* llfnty = 0;
 
     // TODO: review the stuff below, using the llvm type to choose seem like a bad idea. the D type should be used.
     //
     // normal function call
-    if (llvm::isa<llvm::FunctionType>(funcval->getType())) {
-        llfnty = llvm::cast<llvm::FunctionType>(funcval->getType());
+    if (llvm::isa<LLFunctionType>(funcval->getType())) {
+        llfnty = llvm::cast<LLFunctionType>(funcval->getType());
     }
     // pointer to something
     else if (isaPointer(funcval->getType())) {
         // pointer to function pointer - I think this not really supposed to happen, but does :/
         // seems like sometimes we get a func* other times a func**
         if (isaPointer(funcval->getType()->getContainedType(0))) {
-            funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
+            funcval = DtoLoad(funcval);
         }
         // function pointer
-        if (llvm::isa<llvm::FunctionType>(funcval->getType()->getContainedType(0))) {
+        if (llvm::isa<LLFunctionType>(funcval->getType()->getContainedType(0))) {
             //Logger::cout() << "function pointer type:\n" << *funcval << '\n';
-            llfnty = llvm::cast<llvm::FunctionType>(funcval->getType()->getContainedType(0));
+            llfnty = llvm::cast<LLFunctionType>(funcval->getType()->getContainedType(0));
         }
         // struct pointer - delegate
         else if (isaStruct(funcval->getType()->getContainedType(0))) {
-            funcval = DtoGEP(funcval,zero,one,"tmp",p->scopebb());
-            funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
+            funcval = DtoGEPi(funcval,0,1);
+            funcval = DtoLoad(funcval);
             const LLType* ty = funcval->getType()->getContainedType(0);
-            llfnty = llvm::cast<llvm::FunctionType>(ty);
+            llfnty = llvm::cast<LLFunctionType>(ty);
         }
         // unknown
         else {
@@ -1011,7 +1019,7 @@
     //Logger::cout() << "Function LLVM type: " << *llfnty << '\n';
 
     // argument handling
-    llvm::FunctionType::param_iterator argiter = llfnty->param_begin();
+    LLFunctionType::param_iterator argiter = llfnty->param_begin();
     int j = 0;
 
     IRExp* topexp = p->topexp();
@@ -1069,8 +1077,8 @@
     // delegate context arguments
     else if (delegateCall) {
         Logger::println("Delegate Call");
-        LLValue* contextptr = DtoGEP(fn->getRVal(),zero,zero,"tmp",p->scopebb());
-        llargs[j] = new llvm::LoadInst(contextptr,"tmp",p->scopebb());
+        LLValue* contextptr = DtoGEPi(fn->getRVal(),0,0);
+        llargs[j] = DtoLoad(contextptr);
         ++j;
         ++argiter;
     }
@@ -1079,8 +1087,8 @@
         Logger::println("Nested Call");
         LLValue* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration());
         if (!contextptr)
-            contextptr = llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty));
-        llargs[j] = DtoBitCast(contextptr, getPtrToType(llvm::Type::Int8Ty));
+            contextptr = llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty));
+        llargs[j] = DtoBitCast(contextptr, getPtrToType(LLType::Int8Ty));
         ++j;
         ++argiter;
     }
@@ -1094,7 +1102,7 @@
             Argument* fnarg = Argument::getNth(tf->parameters, i);
             Expression* exp = (Expression*)arguments->data[i];
             DValue* expelem = exp->toElem(p);
-            llargs[j] = DtoBitCast(expelem->getLVal(), getPtrToType(llvm::Type::Int8Ty));
+            llargs[j] = DtoBitCast(expelem->getLVal(), getPtrToType(LLType::Int8Ty));
         }
     }
     // d variadic function
@@ -1117,7 +1125,7 @@
             Expression* argexp = (Expression*)arguments->data[i];
             vtypes.push_back(DtoType(argexp->type));
         }
-        const llvm::StructType* vtype = llvm::StructType::get(vtypes);
+        const LLStructType* vtype = LLStructType::get(vtypes);
         Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n';
         LLValue* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint());
 
@@ -1133,7 +1141,7 @@
         // build type info array
         assert(Type::typeinfo->ir.irStruct->constInit);
         const LLType* typeinfotype = DtoType(Type::typeinfo->type);
-        const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
+        const LLArrayType* typeinfoarraytype = LLArrayType::get(typeinfotype,vtype->getNumElements());
 
         llvm::GlobalVariable* typeinfomem =
             new llvm::GlobalVariable(typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage", gIR->module);
@@ -1162,7 +1170,7 @@
         // specify arguments
         llargs[j] = typeinfoarrayparam;;
         j++;
-        llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp");
+        llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(LLType::Int8Ty), "tmp");
         j++;
 
         // pass non variadic args
@@ -1228,7 +1236,7 @@
 
     // void returns cannot not be named
     const char* varname = "";
-    if (llfnty->getReturnType() != llvm::Type::VoidTy)
+    if (llfnty->getReturnType() != LLType::VoidTy)
         varname = "tmp";
 
     //Logger::cout() << "Calling: " << *funcval << '\n';
@@ -1425,13 +1433,13 @@
             assert(fdecl->vtblIndex > 0);
             assert(e1type->ty == Tclass);
 
-            LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-            LLValue* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false);
+            LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
+            LLValue* vtblidx = llvm::ConstantInt::get(LLType::Int32Ty, (size_t)fdecl->vtblIndex, false);
             //Logger::cout() << "vthis: " << *vthis << '\n';
-            funcval = DtoGEP(vthis, zero, zero, "tmp", p->scopebb());
-            funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
-            funcval = DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb());
-            funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
+            funcval = DtoGEP(vthis, zero, zero);
+            funcval = DtoLoad(funcval);
+            funcval = DtoGEP(funcval, zero, vtblidx, toChars());
+            funcval = DtoLoad(funcval);
         #if OPAQUE_VTBLS
             funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
             Logger::cout() << "funcval casted: " << *funcval << '\n';
@@ -1465,10 +1473,10 @@
         LLValue* v;
         v = p->func()->decl->ir.irFunc->thisVar;
         if (llvm::isa<llvm::AllocaInst>(v))
-            v = new llvm::LoadInst(v, "tmp", p->scopebb());
+            v = DtoLoad(v);
         const LLType* t = DtoType(type);
         if (v->getType() != t)
-            v = DtoBitCast(v, t, "tmp");
+            v = DtoBitCast(v, t);
         return new DThisValue(vd, v);
     }
 
@@ -1491,20 +1499,20 @@
     DValue* r = e2->toElem(p);
     p->arrays.pop_back();
 
-    LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-    LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
+    LLValue* zero = DtoConstUint(0);
+    LLValue* one = DtoConstUint(1);
 
     LLValue* arrptr = 0;
     if (e1type->ty == Tpointer) {
-        arrptr = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb());
+        arrptr = DtoGEP1(l->getRVal(),r->getRVal());
     }
     else if (e1type->ty == Tsarray) {
-        arrptr = DtoGEP(l->getRVal(), zero, r->getRVal(),"tmp",p->scopebb());
+        arrptr = DtoGEP(l->getRVal(), zero, r->getRVal());
     }
     else if (e1type->ty == Tarray) {
-        arrptr = DtoGEP(l->getRVal(),zero,one,"tmp",p->scopebb());
-        arrptr = new llvm::LoadInst(arrptr,"tmp",p->scopebb());
-        arrptr = llvm::GetElementPtrInst::Create(arrptr,r->getRVal(),"tmp",p->scopebb());
+        arrptr = DtoGEP(l->getRVal(),zero,one);
+        arrptr = DtoLoad(arrptr);
+        arrptr = DtoGEP1(arrptr,r->getRVal());
     }
     else if (e1type->ty == Taarray) {
         return DtoAAIndex(type, l, r);
@@ -1530,8 +1538,8 @@
     LLValue* vmem = v->getRVal();
     assert(vmem);
 
-    LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-    LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
+    LLValue* zero = DtoConstUint(0);
+    LLValue* one = DtoConstUint(1);
 
     LLValue* emem = 0;
     LLValue* earg = 0;
@@ -1552,32 +1560,32 @@
                 emem = v->getRVal();
             }
             else if (e1type->ty == Tarray) {
-                LLValue* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb());
-                emem = new llvm::LoadInst(tmp,"tmp",p->scopebb());
+                LLValue* tmp = DtoGEP(vmem,zero,one);
+                emem = DtoLoad(tmp);
             }
             else if (e1type->ty == Tsarray) {
-                emem = DtoGEP(vmem,zero,zero,"tmp",p->scopebb());
+                emem = DtoGEP(vmem,zero,zero);
             }
             else
             assert(emem);
 
             llvm::ConstantInt* c = llvm::cast<llvm::ConstantInt>(cv->c);
             if (!(lwr_is_zero = c->isZero())) {
-                emem = llvm::GetElementPtrInst::Create(emem,cv->c,"tmp",p->scopebb());
+                emem = DtoGEP1(emem,cv->c);
             }
         }
         else
         {
             if (e1type->ty == Tarray) {
-                LLValue* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb());
-                tmp = new llvm::LoadInst(tmp,"tmp",p->scopebb());
-                emem = llvm::GetElementPtrInst::Create(tmp,lo->getRVal(),"tmp",p->scopebb());
+                LLValue* tmp = DtoGEP(vmem,zero,one);
+                tmp = DtoLoad(tmp);
+                emem = DtoGEP1(tmp,lo->getRVal());
             }
             else if (e1type->ty == Tsarray) {
-                emem = DtoGEP(vmem,zero,lo->getRVal(),"tmp",p->scopebb());
+                emem = DtoGEP(vmem,zero,lo->getRVal());
             }
             else if (e1type->ty == Tpointer) {
-                emem = llvm::GetElementPtrInst::Create(v->getRVal(),lo->getRVal(),"tmp",p->scopebb());
+                emem = DtoGEP1(v->getRVal(),lo->getRVal());
             }
             else {
                 Logger::println("type = %s", e1type->toChars());
@@ -1915,11 +1923,11 @@
         // init
         TypeStruct* ts = (TypeStruct*)ntype;
         if (ts->isZeroInit()) {
-            DtoStructZeroInit(mem);
+            DtoAggrZeroInit(mem);
         }
         else {
             assert(ts->sym);
-            DtoStructCopy(mem,ts->sym->ir.irStruct->init);
+            DtoAggrCopy(mem,ts->sym->ir.irStruct->init);
         }
         return new DImValue(type, mem, false);
     }
@@ -2071,7 +2079,7 @@
 
     LLValue* b = DtoBoolean(u->getRVal());
 
-    LLConstant* zero = llvm::ConstantInt::get(llvm::Type::Int1Ty, 0, true);
+    LLConstant* zero = llvm::ConstantInt::get(LLType::Int1Ty, 0, true);
     b = p->ir->CreateICmpEQ(b,zero);
 
     return new DImValue(type, b);
@@ -2087,7 +2095,7 @@
     // allocate a temporary for the final result. failed to come up with a better way :/
     LLValue* resval = 0;
     llvm::BasicBlock* entryblock = &p->topfunc()->front();
-    resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"andandtmp",p->topallocapoint());
+    resval = new llvm::AllocaInst(LLType::Int1Ty,"andandtmp",p->topallocapoint());
 
     DValue* u = e1->toElem(p);
 
@@ -2096,7 +2104,7 @@
     llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend);
 
     LLValue* ubool = DtoBoolean(u->getRVal());
-    new llvm::StoreInst(ubool,resval,p->scopebb());
+    DtoStore(ubool,resval);
     llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb());
 
     p->scope() = IRScope(andand, andandend);
@@ -2104,12 +2112,12 @@
 
     LLValue* vbool = DtoBoolean(v->getRVal());
     LLValue* uandvbool = llvm::BinaryOperator::create(llvm::BinaryOperator::And, ubool, vbool,"tmp",p->scopebb());
-    new llvm::StoreInst(uandvbool,resval,p->scopebb());
+    DtoStore(uandvbool,resval);
     llvm::BranchInst::Create(andandend,p->scopebb());
 
     p->scope() = IRScope(andandend, oldend);
 
-    resval = new llvm::LoadInst(resval,"tmp",p->scopebb());
+    resval = DtoLoad(resval);
     return new DImValue(type, resval);
 }
 
@@ -2123,7 +2131,7 @@
     // allocate a temporary for the final result. failed to come up with a better way :/
     LLValue* resval = 0;
     llvm::BasicBlock* entryblock = &p->topfunc()->front();
-    resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"orortmp",p->topallocapoint());
+    resval = new llvm::AllocaInst(LLType::Int1Ty,"orortmp",p->topallocapoint());
 
     DValue* u = e1->toElem(p);
 
@@ -2132,14 +2140,14 @@
     llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend);
 
     LLValue* ubool = DtoBoolean(u->getRVal());
-    new llvm::StoreInst(ubool,resval,p->scopebb());
+    DtoStore(ubool,resval);
     llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb());
 
     p->scope() = IRScope(oror, ororend);
     DValue* v = e2->toElem(p);
 
     LLValue* vbool = DtoBoolean(v->getRVal());
-    new llvm::StoreInst(vbool,resval,p->scopebb());
+    DtoStore(vbool,resval);
     llvm::BranchInst::Create(ororend,p->scopebb());
 
     p->scope() = IRScope(ororend, oldend);
@@ -2173,7 +2181,7 @@
     LLValue* uval = u->getRVal(); \
     LLValue* vval = v->getRVal(); \
     LLValue* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \
-    new llvm::StoreInst(DtoPointedType(u->getLVal(), tmp), u->getLVal(), p->scopebb()); \
+    DtoStore(DtoPointedType(u->getLVal(), tmp), u->getLVal()); \
     return u; \
 }
 
@@ -2205,7 +2213,7 @@
     Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
-    const llvm::PointerType* int8ptrty = getPtrToType(llvm::Type::Int8Ty);
+    const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty);
 
     LLValue* lval;
     bool inplace = false;
@@ -2245,11 +2253,11 @@
 
     Logger::cout() << "context = " << *uval << '\n';
 
-    LLValue* context = DtoGEPi(lval,0,0,"tmp");
+    LLValue* context = DtoGEPi(lval,0,0);
     LLValue* castcontext = DtoBitCast(uval, int8ptrty);
     DtoStore(castcontext, context);
 
-    LLValue* fptr = DtoGEPi(lval,0,1,"tmp");
+    LLValue* fptr = DtoGEPi(lval,0,1);
 
     Logger::println("func: '%s'", func->toPrettyChars());
 
@@ -2318,7 +2326,7 @@
             if (v->isNull())
                 r = llvm::ConstantPointerNull::get(isaPointer(l->getType()));
             else
-                r = DtoBitCast(r, l->getType(), "tmp");
+                r = DtoBitCast(r, l->getType());
         }
         llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
         eval = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb());
@@ -2528,23 +2536,23 @@
         temp = true;
     }
 
-    LLValue* context = DtoGEPi(lval,0,0,"tmp",p->scopebb());
-    const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0));
+    LLValue* context = DtoGEPi(lval,0,0);
+    const LLPointerType* pty = isaPointer(context->getType()->getContainedType(0));
     LLValue* llvmNested = p->func()->decl->ir.irFunc->nestedVar;
     if (llvmNested == NULL) {
         LLValue* nullcontext = llvm::ConstantPointerNull::get(pty);
-        p->ir->CreateStore(nullcontext, context);
+        DtoStore(nullcontext, context);
     }
     else {
-        LLValue* nestedcontext = p->ir->CreateBitCast(llvmNested, pty, "tmp");
-        p->ir->CreateStore(nestedcontext, context);
+        LLValue* nestedcontext = DtoBitCast(llvmNested, pty);
+        DtoStore(nestedcontext, context);
     }
 
     LLValue* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb());
 
     assert(fd->ir.irFunc->func);
-    LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func,fptr->getType()->getContainedType(0));
-    new llvm::StoreInst(castfptr, fptr, p->scopebb());
+    LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0));
+    DtoStore(castfptr, fptr);
 
     if (temp)
         return new DVarValue(type, lval, true);
@@ -2575,7 +2583,7 @@
     Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n";
 
     // llvm storage type
-    const LLType* llStoType = llvm::ArrayType::get(DtoType(elemType), len);
+    const LLType* llStoType = LLArrayType::get(DtoType(elemType), len);
     Logger::cout() << "llvm storage type: '" << *llStoType << "'\n";
 
     // dst pointer
@@ -2641,7 +2649,7 @@
     const LLType* t = DtoType(type);
     Logger::cout() << "array literal has llvm type: " << *t << '\n';
     assert(isaArray(t));
-    const llvm::ArrayType* arrtype = isaArray(t);
+    const LLArrayType* arrtype = isaArray(t);
 
     assert(arrtype->getNumElements() == elements->dim);
     std::vector<LLConstant*> vals(elements->dim, NULL);
@@ -2692,7 +2700,7 @@
             if (!vx) continue;
             tys.push_back(DtoType(vx->type));
         }
-        const llvm::StructType* t = llvm::StructType::get(tys);
+        const LLStructType* t = LLStructType::get(tys);
         if (t != llt) {
             if (getABITypeSize(t) != getABITypeSize(llt)) {
                 Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n';
@@ -2711,7 +2719,7 @@
         if (!vx) continue;
 
         Logger::cout() << "getting index " << j << " of " << *sptr << '\n';
-        LLValue* arrptr = DtoGEPi(sptr,0,j,"tmp",p->scopebb());
+        LLValue* arrptr = DtoGEPi(sptr,0,j);
         DValue* darrptr = new DVarValue(vx->type, arrptr, true);
 
         p->exps.push_back(IRExp(NULL,vx,darrptr));
@@ -2745,7 +2753,7 @@
 
     assert(DtoDType(type)->ty == Tstruct);
     const LLType* t = DtoType(type);
-    const llvm::StructType* st = isaStruct(t);
+    const LLStructType* st = isaStruct(t);
     return llvm::ConstantStruct::get(st,vals);
 }
 
--- a/gen/tollvm.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/tollvm.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -18,6 +18,7 @@
 #include "gen/classes.h"
 #include "gen/typeinf.h"
 #include "gen/complex.h"
+#include "gen/llvmhelpers.h"
 
 bool DtoIsPassedByRef(Type* type)
 {
@@ -52,18 +53,18 @@
     case Tint8:
     case Tuns8:
     case Tchar:
-        return (const LLType*)llvm::Type::Int8Ty;
+        return (const LLType*)LLType::Int8Ty;
     case Tint16:
     case Tuns16:
     case Twchar:
-        return (const LLType*)llvm::Type::Int16Ty;
+        return (const LLType*)LLType::Int16Ty;
     case Tint32:
     case Tuns32:
     case Tdchar:
-        return (const LLType*)llvm::Type::Int32Ty;
+        return (const LLType*)LLType::Int32Ty;
     case Tint64:
     case Tuns64:
-        return (const LLType*)llvm::Type::Int64Ty;
+        return (const LLType*)LLType::Int64Ty;
 
     case Tbool:
         return (const LLType*)llvm::ConstantInt::getTrue()->getType();
@@ -71,13 +72,13 @@
     // floats
     case Tfloat32:
     case Timaginary32:
-        return llvm::Type::FloatTy;
+        return LLType::FloatTy;
     case Tfloat64:
     case Timaginary64:
-        return llvm::Type::DoubleTy;
+        return LLType::DoubleTy;
     case Tfloat80:
     case Timaginary80:
-        return (global.params.useFP80) ? llvm::Type::X86_FP80Ty : llvm::Type::DoubleTy;
+        return (global.params.useFP80) ? LLType::X86_FP80Ty : LLType::DoubleTy;
 
     // complex
     case Tcomplex32:
@@ -89,7 +90,7 @@
     case Tpointer: {
         assert(t->next);
         if (t->next->ty == Tvoid)
-            return (const LLType*)getPtrToType(llvm::Type::Int8Ty);
+            return (const LLType*)getPtrToType(LLType::Int8Ty);
         else
             return (const LLType*)getPtrToType(DtoType(t->next));
     }
@@ -102,25 +103,10 @@
 
     // void
     case Tvoid:
-        return llvm::Type::VoidTy;
+        return LLType::VoidTy;
 
     // aggregates
     case Tstruct:    {
-        if (!t->ir.type || *t->ir.type == NULL) {
-            // recursive or cyclic declaration
-            if (!gIR->structs.empty())
-            {
-                IrStruct* found = 0;
-                for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
-                {
-                    if (t == (*i)->type)
-                    {
-                        return (*i)->recty.get();
-                    }
-                }
-            }
-        }
-
         TypeStruct* ts = (TypeStruct*)t;
         assert(ts->sym);
         DtoResolveDsymbol(ts->sym);
@@ -128,22 +114,6 @@
     }
 
     case Tclass:    {
-        /*if (!t].type || *gIR->irType[t->ir.type == NULL) {
-            // recursive or cyclic declaration
-            if (!gIR->structs.empty())
-            {
-                IrStruct* found = 0;
-                for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
-                {
-                    if (t == (*i)->type)
-                    {
-                        return getPtrToType((*i)->recty.get());
-                    }
-                }
-            }
-            Logger::println("no type found");
-        }*/
-
         TypeClass* tc = (TypeClass*)t;
         assert(tc->sym);
         DtoResolveDsymbol(tc->sym);
@@ -186,10 +156,7 @@
     case Taarray:
     {
         TypeAArray* taa = (TypeAArray*)t;
-        std::vector<const LLType*> types;
-        types.push_back(DtoType(taa->key));
-        types.push_back(DtoType(taa->next));
-        return getPtrToType(llvm::StructType::get(types));
+        return getPtrToType(LLStructType::get(DtoType(taa->key), DtoType(taa->next), 0));
     }
 
     default:
@@ -201,112 +168,12 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-const llvm::StructType* DtoDelegateType(Type* t)
+const LLStructType* DtoDelegateType(Type* t)
 {
-    const LLType* i8ptr = getPtrToType(llvm::Type::Int8Ty);
+    const LLType* i8ptr = getVoidPtrType();
     const LLType* func = DtoFunctionType(t->next, i8ptr);
     const LLType* funcptr = getPtrToType(func);
-
-    std::vector<const LLType*> types;
-    types.push_back(i8ptr);
-    types.push_back(funcptr);
-    return llvm::StructType::get(types);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-/*
-static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false)
-{
-    assert(bits == 32 || bits == 64);
-    const LLType* int8ty =    (const LLType*)llvm::Type::Int8Ty;
-    const LLType* int32ty =   (const LLType*)llvm::Type::Int32Ty;
-    const LLType* int64ty =   (const LLType*)llvm::Type::Int64Ty;
-    const LLType* int8ptrty = (const LLType*)getPtrToType(llvm::Type::Int8Ty);
-    const LLType* voidty =    (const LLType*)llvm::Type::VoidTy;
-
-    assert(gIR);
-    assert(gIR->module);
-
-    // parameter types
-    std::vector<const LLType*> pvec;
-    pvec.push_back(int8ptrty);
-    pvec.push_back(set?int8ty:int8ptrty);
-    pvec.push_back(bits==32?int32ty:int64ty);
-    pvec.push_back(int32ty);
-    llvm::FunctionType* functype = llvm::FunctionType::get(voidty, pvec, false);
-    return llvm::cast<llvm::Function>(gIR->module->getOrInsertFunction(name, functype));
-}
-*/
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-// llvm.memset.i32
-llvm::Function* LLVM_DeclareMemSet32()
-{
-    return GET_INTRINSIC_DECL(memset_i32);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-llvm::Function* LLVM_DeclareMemSet64()
-{
-    return GET_INTRINSIC_DECL(memset_i64);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-// llvm.memcpy.i32
-llvm::Function* LLVM_DeclareMemCpy32()
-{
-    return GET_INTRINSIC_DECL(memcpy_i32);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-// llvm.memcpy.i64
-llvm::Function* LLVM_DeclareMemCpy64()
-{
-    return GET_INTRINSIC_DECL(memcpy_i64);
-}
-
-void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device)
-{
-    llvm::Function* fn = GET_INTRINSIC_DECL(memory_barrier);
-    assert(fn != NULL);
-
-    LLSmallVector<LLValue*, 5> llargs;
-    llargs.push_back(DtoConstBool(ll));
-    llargs.push_back(DtoConstBool(ls));
-    llargs.push_back(DtoConstBool(sl));
-    llargs.push_back(DtoConstBool(ss));
-    llargs.push_back(DtoConstBool(device));
-
-    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoDelegateToNull(LLValue* v)
-{
-    LLSmallVector<LLValue*, 4> args;
-    args.push_back(DtoBitCast(v, getVoidPtrType()));
-    args.push_back(llvm::Constant::getNullValue(llvm::Type::Int8Ty));
-    args.push_back(DtoConstInt(global.params.is64bit ? 16 : 8));
-    args.push_back(DtoConstInt(0));
-    gIR->ir->CreateCall(GET_INTRINSIC_DECL(memset_i32), args.begin(), args.end(), "");
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoDelegateCopy(LLValue* dst, LLValue* src)
-{
-    LLSmallVector<LLValue*, 4> args;
-    args.push_back(DtoBitCast(dst,getVoidPtrType()));
-    args.push_back(DtoBitCast(src,getVoidPtrType()));
-    args.push_back(DtoConstInt(global.params.is64bit ? 16 : 8));
-    args.push_back(DtoConstInt(0));
-    gIR->ir->CreateCall(GET_INTRINSIC_DECL(memcpy_i32), args.begin(), args.end(), "");
+    return LLStructType::get(i8ptr, funcptr, 0);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -318,20 +185,20 @@
     llvm::Value *b1, *b2;
     if (rhs == NULL)
     {
-        LLValue* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp");
+        LLValue* l = DtoLoad(DtoGEPi(lhs,0,0));
         LLValue* r = llvm::Constant::getNullValue(l->getType());
         b1 = gIR->ir->CreateICmp(pred,l,r,"tmp");
-        l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp");
+        l = DtoLoad(DtoGEPi(lhs,0,1));
         r = llvm::Constant::getNullValue(l->getType());
         b2 = gIR->ir->CreateICmp(pred,l,r,"tmp");
     }
     else
     {
-        LLValue* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp");
-        LLValue* r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,0,"tmp"),"tmp");
+        LLValue* l = DtoLoad(DtoGEPi(lhs,0,0));
+        LLValue* r = DtoLoad(DtoGEPi(rhs,0,0));
         b1 = gIR->ir->CreateICmp(pred,l,r,"tmp");
-        l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp");
-        r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,1,"tmp"),"tmp");
+        l = DtoLoad(DtoGEPi(lhs,0,1));
+        r = DtoLoad(DtoGEPi(rhs,0,1));
         b2 = gIR->ir->CreateICmp(pred,l,r,"tmp");
     }
     LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp");
@@ -342,7 +209,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-llvm::GlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
+LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym)
 {
     // global variable
     if (VarDeclaration* vd = sym->isVarDeclaration())
@@ -384,11 +251,6 @@
 
     // default to external linkage
     return llvm::GlobalValue::ExternalLinkage;
-
-// llvm linkage types
-/*      ExternalLinkage = 0, LinkOnceLinkage, WeakLinkage, AppendingLinkage,
-  InternalLinkage, DLLImportLinkage, DLLExportLinkage, ExternalWeakLinkage,
-  GhostLinkage */
 }
 
 llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym)
@@ -437,8 +299,8 @@
     {
         // val is integer
         assert(valTy->isInteger());
-        const llvm::IntegerType* pt = llvm::cast<const llvm::IntegerType>(ptrTy);
-        const llvm::IntegerType* vt = llvm::cast<const llvm::IntegerType>(valTy);
+        const LLIntegerType* pt = llvm::cast<const LLIntegerType>(ptrTy);
+        const LLIntegerType* vt = llvm::cast<const LLIntegerType>(valTy);
         if (pt->getBitWidth() < vt->getBitWidth()) {
             return new llvm::TruncInst(val, pt, "tmp", gIR->scopebb());
         }
@@ -461,7 +323,7 @@
     const LLType* t = val->getType();
     if (t->isInteger())
     {
-        if (t == llvm::Type::Int1Ty)
+        if (t == LLType::Int1Ty)
             return val;
         else {
             LLValue* zero = llvm::ConstantInt::get(t, 0, false);
@@ -484,116 +346,18 @@
 
 const LLType* DtoSize_t()
 {
-    if (global.params.is64bit)
-    return llvm::Type::Int64Ty;
-    else
-    return llvm::Type::Int32Ty;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-LLConstant* DtoConstInitializer(Type* type, Initializer* init)
-{
-    LLConstant* _init = 0; // may return zero
-    if (!init)
-    {
-        Logger::println("const default initializer for %s", type->toChars());
-        _init = type->defaultInit()->toConstElem(gIR);
-    }
-    else if (ExpInitializer* ex = init->isExpInitializer())
-    {
-        Logger::println("const expression initializer");
-        _init = ex->exp->toConstElem(gIR);
-    }
-    else if (StructInitializer* si = init->isStructInitializer())
-    {
-        Logger::println("const struct initializer");
-        _init = DtoConstStructInitializer(si);
-    }
-    else if (ArrayInitializer* ai = init->isArrayInitializer())
-    {
-        Logger::println("const array initializer");
-        _init = DtoConstArrayInitializer(ai);
-    }
-    else if (init->isVoidInitializer())
-    {
-        Logger::println("const void initializer");
-        const LLType* ty = DtoType(type);
-        _init = llvm::Constant::getNullValue(ty);
-    }
-    else {
-        Logger::println("unsupported const initializer: %s", init->toChars());
-    }
-    return _init;
+    // the type of size_t does not change once set
+    static const LLType* t = NULL;
+    if (t == NULL)
+        t = (global.params.is64bit) ? LLType::Int64Ty : LLType::Int32Ty;
+    return t;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-LLConstant* DtoConstFieldInitializer(Type* t, Initializer* init)
+LLValue* DtoGEP1(LLValue* ptr, LLValue* i0, const char* var, llvm::BasicBlock* bb)
 {
-    Logger::println("DtoConstFieldInitializer");
-    LOG_SCOPE;
-
-    const LLType* _type = DtoType(t);
-
-    LLConstant* _init = DtoConstInitializer(t, init);
-    assert(_init);
-    if (_type != _init->getType())
-    {
-        Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n';
-        if (t->ty == Tsarray)
-        {
-            const llvm::ArrayType* arrty = isaArray(_type);
-            uint64_t n = arrty->getNumElements();
-            std::vector<LLConstant*> vals(n,_init);
-            _init = llvm::ConstantArray::get(arrty, vals);
-        }
-        else if (t->ty == Tarray)
-        {
-            assert(isaStruct(_type));
-            _init = llvm::ConstantAggregateZero::get(_type);
-        }
-        else if (t->ty == Tstruct)
-        {
-            const llvm::StructType* structty = isaStruct(_type);
-            TypeStruct* ts = (TypeStruct*)t;
-            assert(ts);
-            assert(ts->sym);
-            assert(ts->sym->ir.irStruct->constInit);
-            _init = ts->sym->ir.irStruct->constInit;
-        }
-        else if (t->ty == Tclass)
-        {
-            _init = llvm::Constant::getNullValue(_type);
-        }
-        else {
-            Logger::println("failed for type %s", t->toChars());
-            assert(0);
-        }
-    }
-
-    return _init;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-DValue* DtoInitializer(Initializer* init)
-{
-    if (ExpInitializer* ex = init->isExpInitializer())
-    {
-        Logger::println("expression initializer");
-        assert(ex->exp);
-        return ex->exp->toElem(gIR);
-    }
-    else if (init->isVoidInitializer())
-    {
-        // do nothing
-    }
-    else {
-        Logger::println("unsupported initializer: %s", init->toChars());
-        assert(0);
-    }
-    return 0;
+    return llvm::GetElementPtrInst::Create(ptr, i0, var?var:"tmp", bb?bb:gIR->scopebb());
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -603,7 +367,7 @@
     LLSmallVector<LLValue*,2> v(2);
     v[0] = i0;
     v[1] = i1;
-    return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb());
+    return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var?var:"tmp", bb?bb:gIR->scopebb());
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -617,14 +381,14 @@
     for (DStructIndexVector::const_iterator i=src.begin(); i!=src.end(); ++i)
         dst[j++] = DtoConstUint(*i);
 
-    return llvm::GetElementPtrInst::Create(ptr, dst.begin(), dst.end(), var, bb?bb:gIR->scopebb());
+    return llvm::GetElementPtrInst::Create(ptr, dst.begin(), dst.end(), var?var:"tmp", bb?bb:gIR->scopebb());
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-LLValue* DtoGEPi(LLValue* ptr, unsigned i, const char* var, llvm::BasicBlock* bb)
+LLValue* DtoGEPi1(LLValue* ptr, unsigned i, const char* var, llvm::BasicBlock* bb)
 {
-    return llvm::GetElementPtrInst::Create(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb?bb:gIR->scopebb());
+    return llvm::GetElementPtrInst::Create(ptr, DtoConstUint(i), var?var:"tmp", bb?bb:gIR->scopebb());
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -634,634 +398,71 @@
     LLSmallVector<LLValue*,2> v(2);
     v[0] = DtoConstUint(i0);
     v[1] = DtoConstUint(i1);
-    return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb());
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-LLValue* DtoNew(Type* newtype)
-{
-    // get runtime function
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT");
-    // get type info
-    LLConstant* ti = DtoTypeInfoOf(newtype);
-    assert(isaPointer(ti));
-    // call runtime allocator
-    LLValue* mem = gIR->ir->CreateCall(fn, ti, ".gc_mem");
-    // cast
-    return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem");
-}
-
-void DtoDeleteMemory(LLValue* ptr)
-{
-    // get runtime function
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delmemory");
-    // build args
-    LLSmallVector<LLValue*,1> arg;
-    arg.push_back(DtoBitCast(ptr, getVoidPtrType(), ".tmp"));
-    // call
-    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
-}
-
-void DtoDeleteClass(LLValue* inst)
-{
-    // get runtime function
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delclass");
-    // build args
-    LLSmallVector<LLValue*,1> arg;
-    arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
-    // call
-    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
-}
-
-void DtoDeleteInterface(LLValue* inst)
-{
-    // get runtime function
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delinterface");
-    // build args
-    LLSmallVector<LLValue*,1> arg;
-    arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp"));
-    // call
-    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
-}
-
-void DtoDeleteArray(DValue* arr)
-{
-    // get runtime function
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delarray");
-    // build args
-    LLSmallVector<LLValue*,2> arg;
-    arg.push_back(DtoArrayLen(arr));
-    arg.push_back(DtoBitCast(DtoArrayPtr(arr), getVoidPtrType(), ".tmp"));
-    // call
-    llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb());
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoAssert(Loc* loc, DValue* msg)
-{
-    std::vector<LLValue*> args;
-    LLConstant* c;
-
-    // func
-    const char* fname = msg ? "_d_assert_msg" : "_d_assert";
-    llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname);
-
-    // param attrs
-    llvm::PAListPtr palist;
-    int idx = 1;
-
-    c = DtoConstString(loc->filename);
-
-    // msg param
-    if (msg)
-    {
-        if (DSliceValue* s = msg->isSlice())
-        {
-            llvm::AllocaInst* alloc = gIR->func()->msgArg;
-            if (!alloc)
-            {
-                alloc = new llvm::AllocaInst(c->getType(), ".assertmsg", gIR->topallocapoint());
-                DtoSetArray(alloc, DtoArrayLen(s), DtoArrayPtr(s));
-                gIR->func()->msgArg = alloc;
-            }
-            args.push_back(alloc);
-        }
-        else
-        {
-            args.push_back(msg->getRVal());
-        }
-        palist = palist.addAttr(idx++, llvm::ParamAttr::ByVal);
-    }
-
-    // file param
-    llvm::AllocaInst* alloc = gIR->func()->srcfileArg;
-    if (!alloc)
-    {
-        alloc = new llvm::AllocaInst(c->getType(), ".srcfile", gIR->topallocapoint());
-        gIR->func()->srcfileArg = alloc;
-    }
-    LLValue* ptr = DtoGEPi(alloc, 0,0, "tmp");
-    DtoStore(c->getOperand(0), ptr);
-    ptr = DtoGEPi(alloc, 0,1, "tmp");
-    DtoStore(c->getOperand(1), ptr);
-
-    args.push_back(alloc);
-    palist = palist.addAttr(idx++, llvm::ParamAttr::ByVal);
-
-
-    // line param
-    c = DtoConstUint(loc->linnum);
-    args.push_back(c);
-
-    // call
-    llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb());
-    call->setParamAttrs(palist);
+    return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var?var:"tmp", bb?bb:gIR->scopebb());
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-static const LLType* get_next_frame_ptr_type(Dsymbol* sc)
-{
-    assert(sc->isFuncDeclaration() || sc->isClassDeclaration());
-    Dsymbol* p = sc->toParent2();
-    if (!p->isFuncDeclaration() && !p->isClassDeclaration())
-        Logger::println("unexpected parent symbol found while resolving frame pointer - '%s' kind: '%s'", p->toChars(), p->kind());
-    assert(p->isFuncDeclaration() || p->isClassDeclaration());
-    if (FuncDeclaration* fd = p->isFuncDeclaration())
-    {
-        LLValue* v = fd->ir.irFunc->nestedVar;
-        assert(v);
-        return v->getType();
-    }
-    else if (ClassDeclaration* cd = p->isClassDeclaration())
-    {
-        return DtoType(cd->type);
-    }
-    else
-    {
-        Logger::println("symbol: '%s' kind: '%s'", sc->toChars(), sc->kind());
-        assert(0);
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-static LLValue* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, LLValue* v)
-{
-    LOG_SCOPE;
-    if (sc == func)
-    {
-        return v;
-    }
-    else if (FuncDeclaration* fd = sc->isFuncDeclaration())
-    {
-        Logger::println("scope is function: %s", fd->toChars());
-
-        if (fd->toParent2() == func)
-        {
-            if (!func->ir.irFunc->nestedVar)
-                return NULL;
-            return DtoBitCast(v, func->ir.irFunc->nestedVar->getType());
-        }
-
-        v = DtoBitCast(v, get_next_frame_ptr_type(fd));
-        Logger::cout() << "v = " << *v << '\n';
-
-        if (fd->toParent2()->isFuncDeclaration())
-        {
-            v = DtoGEPi(v, 0,0, "tmp");
-            v = DtoLoad(v);
-        }
-        else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration())
-        {
-            size_t idx = 2;
-            //idx += cd->ir.irStruct->interfaceVec.size();
-            v = DtoGEPi(v,0,idx,"tmp");
-            v = DtoLoad(v);
-        }
-        else
-        {
-            assert(0);
-        }
-        return get_frame_ptr_impl(func, fd->toParent2(), v);
-    }
-    else if (ClassDeclaration* cd = sc->isClassDeclaration())
-    {
-        Logger::println("scope is class: %s", cd->toChars());
-        /*size_t idx = 2;
-        idx += cd->llvmIrStruct->interfaces.size();
-        v = DtoGEPi(v,0,idx,"tmp");
-        Logger::cout() << "gep = " << *v << '\n';
-        v = DtoLoad(v);*/
-        return get_frame_ptr_impl(func, cd->toParent2(), v);
-    }
-    else
-    {
-        Logger::println("symbol: '%s'", sc->toPrettyChars());
-        assert(0);
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-static LLValue* get_frame_ptr(FuncDeclaration* func)
+void DtoMemSetZero(LLValue* dst, LLValue* nbytes)
 {
-    Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars());
-    LOG_SCOPE;
-    IrFunction* irfunc = gIR->func();
-
-    // in the right scope already
-    if (func == irfunc->decl)
-        return irfunc->decl->ir.irFunc->nestedVar;
-
-    // use the 'this' pointer
-    LLValue* ptr = irfunc->decl->ir.irFunc->thisVar;
-    assert(ptr);
-
-    // return the fully resolved frame pointer
-    ptr = get_frame_ptr_impl(func, irfunc->decl, ptr);
-    if (ptr) Logger::cout() << "Found context!" << *ptr;
-    else Logger::cout() << "NULL context!\n";
-
-    return ptr;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-LLValue* DtoNestedContext(FuncDeclaration* func)
-{
-    // resolve frame ptr
-    LLValue* ptr = get_frame_ptr(func);
-    Logger::cout() << "Nested context ptr = ";
-    if (ptr) Logger::cout() << *ptr;
-    else Logger::cout() << "NULL";
-    Logger::cout() << '\n';
-    return ptr;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-static void print_frame_worker(VarDeclaration* vd, Dsymbol* par)
-{
-    if (vd->toParent2() == par)
-    {
-        Logger::println("found: '%s' kind: '%s'", par->toChars(), par->kind());
-        return;
-    }
+    dst = DtoBitCast(dst,getVoidPtrType());
 
-    Logger::println("diving into: '%s' kind: '%s'", par->toChars(), par->kind());
-    LOG_SCOPE;
-    print_frame_worker(vd, par->toParent2());
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-static void print_nested_frame_list(VarDeclaration* vd, Dsymbol* par)
-{
-    Logger::println("Frame pointer list for nested var: '%s'", vd->toPrettyChars());
-    LOG_SCOPE;
-    if (vd->toParent2() != par)
-        print_frame_worker(vd, par);
+    llvm::Function* fn;
+    if (global.params.is64bit)
+        fn = GET_INTRINSIC_DECL(memset_i64);
     else
-        Logger::println("Found at level 0");
-    Logger::println("Done");
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
+        fn = GET_INTRINSIC_DECL(memset_i32);
 
-LLValue* DtoNestedVariable(VarDeclaration* vd)
-{
-    // log the frame list
-    IrFunction* irfunc = gIR->func();
-    if (Logger::enabled())
-        print_nested_frame_list(vd, irfunc->decl);
-
-    // resolve frame ptr
-    FuncDeclaration* func = vd->toParent2()->isFuncDeclaration();
-    assert(func);
-    LLValue* ptr = DtoNestedContext(func);
-    assert(ptr && "nested var, but no context");
-
-    // we must cast here to be sure. nested classes just have a void*
-    ptr = DtoBitCast(ptr, func->ir.irFunc->nestedVar->getType());
-
-    // index nested var and load (if necessary)
-    LLValue* v = DtoGEPi(ptr, 0, vd->ir.irLocal->nestedIndex, "tmp");
-    // references must be loaded, for normal variables this IS already the variable storage!!!
-    if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)))
-        v = DtoLoad(v);
-
-    // log and return
-    Logger::cout() << "Nested var ptr = " << *v << '\n';
-    return v;
+    gIR->ir->CreateCall4(fn, dst, DtoConstUbyte(0), nbytes, DtoConstUint(0), "");
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-void DtoAssign(DValue* lhs, DValue* rhs)
+void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes)
 {
-    Logger::cout() << "DtoAssign(...);\n";
-    LOG_SCOPE;
-
-    Type* t = DtoDType(lhs->getType());
-    Type* t2 = DtoDType(rhs->getType());
+    dst = DtoBitCast(dst,getVoidPtrType());
+    src = DtoBitCast(src,getVoidPtrType());
 
-    if (t->ty == Tstruct) {
-        if (t2 != t) {
-            // TODO: fix this, use 'rhs' for something
-            DtoStructZeroInit(lhs->getLVal());
-        }
-        else if (!rhs->inPlace()) {
-            DtoStructCopy(lhs->getLVal(),rhs->getRVal());
-        }
-    }
-    else if (t->ty == Tarray) {
-        // lhs is slice
-        if (DSliceValue* s = lhs->isSlice()) {
-            if (DSliceValue* s2 = rhs->isSlice()) {
-                DtoArrayCopySlices(s, s2);
-            }
-            else if (t->next == t2) {
-                if (s->len)
-                    DtoArrayInit(s->ptr, s->len, rhs->getRVal());
-                else
-                    DtoArrayInit(s->ptr, rhs->getRVal());
-            }
-            else {
-                DtoArrayCopyToSlice(s, rhs);
-            }
-        }
-        // rhs is slice
-        else if (DSliceValue* s = rhs->isSlice()) {
-            assert(s->getType()->toBasetype() == lhs->getType()->toBasetype());
-            DtoSetArray(lhs->getLVal(),DtoArrayLen(s),DtoArrayPtr(s));
-        }
-        // null
-        else if (rhs->isNull()) {
-            DtoSetArrayToNull(lhs->getLVal());
-        }
-        // reference assignment
-        else {
-            DtoArrayAssign(lhs->getLVal(), rhs->getRVal());
-        }
-    }
-    else if (t->ty == Tsarray) {
-        if (DtoType(lhs->getType()) == DtoType(rhs->getType())) {
-            DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal());
-        }
-        else {
-            DtoArrayInit(lhs->getLVal(), rhs->getRVal());
-        }
-    }
-    else if (t->ty == Tdelegate) {
-        if (rhs->isNull())
-            DtoDelegateToNull(lhs->getLVal());
-        else if (!rhs->inPlace()) {
-            LLValue* l = lhs->getLVal();
-            LLValue* r = rhs->getRVal();
-            Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
-            DtoDelegateCopy(l, r);
-        }
-    }
-    else if (t->ty == Tclass) {
-        assert(t2->ty == Tclass);
-        // assignment to this in constructor special case
-        if (lhs->isThis()) {
-            LLValue* tmp = rhs->getRVal();
-            FuncDeclaration* fdecl = gIR->func()->decl;
-            // respecify the this param
-            if (!llvm::isa<llvm::AllocaInst>(fdecl->ir.irFunc->thisVar))
-                fdecl->ir.irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint());
-            DtoStore(tmp, fdecl->ir.irFunc->thisVar);
-        }
-        // regular class ref -> class ref assignment
-        else {
-            DtoStore(rhs->getRVal(), lhs->getLVal());
-        }
-    }
-    else if (t->iscomplex()) {
-        assert(!lhs->isComplex());
+    llvm::Function* fn;
+    if (global.params.is64bit)
+        fn = GET_INTRINSIC_DECL(memcpy_i64);
+    else
+        fn = GET_INTRINSIC_DECL(memcpy_i32);
 
-        LLValue* dst;
-        if (DLRValue* lr = lhs->isLRValue()) {
-            dst = lr->getLVal();
-            rhs = DtoCastComplex(rhs, lr->getLType());
-        }
-        else {
-            dst = lhs->getRVal();
-        }
+    gIR->ir->CreateCall4(fn, dst, src, nbytes, DtoConstUint(0), "");
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
 
-        if (DComplexValue* cx = rhs->isComplex())
-            DtoComplexSet(dst, cx->re, cx->im);
-        else
-            DtoComplexAssign(dst, rhs->getRVal());
-    }
-    else {
-        LLValue* l = lhs->getLVal();
-        LLValue* r = rhs->getRVal();
-        Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
-        const LLType* lit = l->getType()->getContainedType(0);
-        if (r->getType() != lit) {
-            // handle lvalue cast assignments
-            if (DLRValue* lr = lhs->isLRValue()) {
-                Logger::println("lvalue cast!");
-                r = DtoCast(rhs, lr->getLType())->getRVal();
-            }
-            else {
-                r = DtoCast(rhs, lhs->getType())->getRVal();
-            }
-            Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n';
-            assert(r->getType() == l->getType()->getContainedType(0));
-        }
-        gIR->ir->CreateStore(r, l);
-    }
+void DtoAggrZeroInit(LLValue* v)
+{
+    uint64_t n = getTypeStoreSize(v->getType()->getContainedType(0));
+    DtoMemSetZero(v, DtoConstSize_t(n));
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
-DValue* DtoCastInt(DValue* val, Type* _to)
+
+void DtoAggrCopy(LLValue* dst, LLValue* src)
 {
-    const LLType* tolltype = DtoType(_to);
-
-    Type* to = DtoDType(_to);
-    Type* from = DtoDType(val->getType());
-    assert(from->isintegral());
-
-    size_t fromsz = from->size();
-    size_t tosz = to->size();
-
-    LLValue* rval = val->getRVal();
-    if (rval->getType() == tolltype) {
-        return new DImValue(_to, rval);
-    }
-
-    if (to->isintegral()) {
-        if (fromsz < tosz) {
-            Logger::cout() << "cast to: " << *tolltype << '\n';
-            if (from->isunsigned() || from->ty == Tbool) {
-                rval = new llvm::ZExtInst(rval, tolltype, "tmp", gIR->scopebb());
-            } else {
-                rval = new llvm::SExtInst(rval, tolltype, "tmp", gIR->scopebb());
-            }
-        }
-        else if (fromsz > tosz) {
-            rval = new llvm::TruncInst(rval, tolltype, "tmp", gIR->scopebb());
-        }
-        else {
-            rval = DtoBitCast(rval, tolltype);
-        }
-    }
-    else if (to->isfloating()) {
-        if (from->isunsigned()) {
-            rval = new llvm::UIToFPInst(rval, tolltype, "tmp", gIR->scopebb());
-        }
-        else {
-            rval = new llvm::SIToFPInst(rval, tolltype, "tmp", gIR->scopebb());
-        }
-    }
-    else if (to->ty == Tpointer) {
-        Logger::cout() << "cast pointer: " << *tolltype << '\n';
-        rval = gIR->ir->CreateIntToPtr(rval, tolltype, "tmp");
-    }
-    else {
-        assert(0 && "bad int cast");
-    }
-
-    return new DImValue(_to, rval);
-}
-
-DValue* DtoCastPtr(DValue* val, Type* to)
-{
-    const LLType* tolltype = DtoType(to);
-
-    Type* totype = DtoDType(to);
-    Type* fromtype = DtoDType(val->getType());
-    assert(fromtype->ty == Tpointer || fromtype->ty == Tfunction);
-
-    LLValue* rval;
-
-    if (totype->ty == Tpointer || totype->ty == Tclass) {
-        LLValue* src = val->getRVal();
-        Logger::cout() << "src: " << *src << "to type: " << *tolltype << '\n';
-        rval = DtoBitCast(src, tolltype);
-    }
-    else if (totype->isintegral()) {
-        rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
-    }
-    else {
-        Logger::println("invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars());
-        assert(0);
-    }
-
-    return new DImValue(to, rval);
+    uint64_t n = getTypeStoreSize(dst->getType()->getContainedType(0));
+    DtoMemCpy(dst, src, DtoConstSize_t(n));
 }
 
-DValue* DtoCastFloat(DValue* val, Type* to)
-{
-    if (val->getType() == to)
-        return val;
-
-    const LLType* tolltype = DtoType(to);
-
-    Type* totype = DtoDType(to);
-    Type* fromtype = DtoDType(val->getType());
-    assert(fromtype->isfloating());
-
-    size_t fromsz = fromtype->size();
-    size_t tosz = totype->size();
-
-    LLValue* rval;
+//////////////////////////////////////////////////////////////////////////////////////////
 
-    if (totype->iscomplex()) {
-        assert(0);
-        //return new DImValue(to, DtoComplex(to, val));
-    }
-    else if (totype->isfloating()) {
-        if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) {
-            rval = val->getRVal();
-        }
-        else if (fromsz < tosz) {
-            rval = new llvm::FPExtInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
-        }
-        else if (fromsz > tosz) {
-            rval = new llvm::FPTruncInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
-        }
-        else {
-            assert(0 && "bad float cast");
-        }
-    }
-    else if (totype->isintegral()) {
-        if (totype->isunsigned()) {
-            rval = new llvm::FPToUIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
-        }
-        else {
-            rval = new llvm::FPToSIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
-        }
-    }
-    else {
-        assert(0 && "bad float cast");
-    }
-
-    return new DImValue(to, rval);
-}
-
-DValue* DtoCastComplex(DValue* val, Type* _to)
+void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device)
 {
-    Type* to = DtoDType(_to);
-    Type* vty = val->getType();
-    if (to->iscomplex()) {
-        if (vty->size() == to->size())
-            return val;
-
-        llvm::Value *re, *im;
-        DtoGetComplexParts(val, re, im);
-        const LLType* toty = DtoComplexBaseType(to);
+    llvm::Function* fn = GET_INTRINSIC_DECL(memory_barrier);
+    assert(fn != NULL);
 
-        if (to->size() < vty->size()) {
-            re = gIR->ir->CreateFPTrunc(re, toty, "tmp");
-            im = gIR->ir->CreateFPTrunc(im, toty, "tmp");
-        }
-        else if (to->size() > vty->size()) {
-            re = gIR->ir->CreateFPExt(re, toty, "tmp");
-            im = gIR->ir->CreateFPExt(im, toty, "tmp");
-        }
-        else {
-            return val;
-        }
-
-        if (val->isComplex())
-            return new DComplexValue(_to, re, im);
+    LLSmallVector<LLValue*, 5> llargs;
+    llargs.push_back(DtoConstBool(ll));
+    llargs.push_back(DtoConstBool(ls));
+    llargs.push_back(DtoConstBool(sl));
+    llargs.push_back(DtoConstBool(ss));
+    llargs.push_back(DtoConstBool(device));
 
-        // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions.
-        // so we need to give it storage, or fix the system that handles this stuff (DLRValue)
-        LLValue* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint());
-        DtoComplexSet(mem, re, im);
-        return new DLRValue(val->getType(), val->getRVal(), _to, mem);
-    }
-    else if (to->isimaginary()) {
-        if (val->isComplex())
-            return new DImValue(to, val->isComplex()->im);
-        LLValue* v = val->getRVal();
-        DImValue* im = new DImValue(to, DtoLoad(DtoGEPi(v,0,1,"tmp")));
-        return DtoCastFloat(im, to);
-    }
-    else if (to->isfloating()) {
-        if (val->isComplex())
-            return new DImValue(to, val->isComplex()->re);
-        LLValue* v = val->getRVal();
-        DImValue* re = new DImValue(to, DtoLoad(DtoGEPi(v,0,0,"tmp")));
-        return DtoCastFloat(re, to);
-    }
-    else
-    assert(0);
-}
-
-DValue* DtoCast(DValue* val, Type* to)
-{
-    Type* fromtype = DtoDType(val->getType());
-    Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars());
-    if (fromtype->isintegral()) {
-        return DtoCastInt(val, to);
-    }
-    else if (fromtype->iscomplex()) {
-        return DtoCastComplex(val, to);
-    }
-    else if (fromtype->isfloating()) {
-        return DtoCastFloat(val, to);
-    }
-    else if (fromtype->ty == Tclass) {
-        return DtoCastClass(val, to);
-    }
-    else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) {
-        return DtoCastArray(val, to);
-    }
-    else if (fromtype->ty == Tpointer || fromtype->ty == Tfunction) {
-        return DtoCastPtr(val, to);
-    }
-    else {
-        assert(0);
-    }
+    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -1272,15 +473,19 @@
 }
 llvm::ConstantInt* DtoConstUint(unsigned i)
 {
-    return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false);
+    return llvm::ConstantInt::get(LLType::Int32Ty, i, false);
 }
 llvm::ConstantInt* DtoConstInt(int i)
 {
-    return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, true);
+    return llvm::ConstantInt::get(LLType::Int32Ty, i, true);
 }
 LLConstant* DtoConstBool(bool b)
 {
-    return llvm::ConstantInt::get(llvm::Type::Int1Ty, b, false);
+    return llvm::ConstantInt::get(LLType::Int1Ty, b, false);
+}
+llvm::ConstantInt* DtoConstUbyte(unsigned char i)
+{
+    return llvm::ConstantInt::get(LLType::Int8Ty, i, false);
 }
 
 llvm::ConstantFP* DtoConstFP(Type* t, long double value)
@@ -1292,7 +497,6 @@
         return llvm::ConstantFP::get(llvm::APFloat(double(value)));
 }
 
-
 //////////////////////////////////////////////////////////////////////////////////////////
 
 LLConstant* DtoConstString(const char* str)
@@ -1320,61 +524,6 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-void DtoMemSetZero(LLValue* dst, LLValue* nbytes)
-{
-    const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
-    llvm::Value *dstarr;
-    if (dst->getType() == arrty)
-    {
-        dstarr = dst;
-    }
-    else
-    {
-        dstarr = DtoBitCast(dst,arrty);
-    }
-
-    llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemSet64() : LLVM_DeclareMemSet32();
-    std::vector<LLValue*> llargs;
-    llargs.resize(4);
-    llargs[0] = dstarr;
-    llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
-    llargs[2] = nbytes;
-    llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-
-    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes)
-{
-    const LLType* arrty = getVoidPtrType();
-
-    LLValue* dstarr;
-    if (dst->getType() == arrty)
-        dstarr = dst;
-    else
-        dstarr = DtoBitCast(dst, arrty, "tmp");
-
-    LLValue* srcarr;
-    if (src->getType() == arrty)
-        srcarr = src;
-    else
-        srcarr = DtoBitCast(src, arrty, "tmp");
-
-    llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
-    std::vector<LLValue*> llargs;
-    llargs.resize(4);
-    llargs[0] = dstarr;
-    llargs[1] = srcarr;
-    llargs[2] = nbytes;
-    llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-
-    llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
 LLValue* DtoLoad(LLValue* src, const char* name)
 {
     LLValue* ld = gIR->ir->CreateLoad(src, name ? name : "tmp");
@@ -1407,34 +556,34 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-const llvm::PointerType* isaPointer(LLValue* v)
+const LLPointerType* isaPointer(LLValue* v)
 {
-    return llvm::dyn_cast<llvm::PointerType>(v->getType());
+    return llvm::dyn_cast<LLPointerType>(v->getType());
 }
 
-const llvm::PointerType* isaPointer(const LLType* t)
+const LLPointerType* isaPointer(const LLType* t)
 {
-    return llvm::dyn_cast<llvm::PointerType>(t);
+    return llvm::dyn_cast<LLPointerType>(t);
 }
 
-const llvm::ArrayType* isaArray(LLValue* v)
+const LLArrayType* isaArray(LLValue* v)
 {
-    return llvm::dyn_cast<llvm::ArrayType>(v->getType());
+    return llvm::dyn_cast<LLArrayType>(v->getType());
 }
 
-const llvm::ArrayType* isaArray(const LLType* t)
+const LLArrayType* isaArray(const LLType* t)
 {
-    return llvm::dyn_cast<llvm::ArrayType>(t);
+    return llvm::dyn_cast<LLArrayType>(t);
 }
 
-const llvm::StructType* isaStruct(LLValue* v)
+const LLStructType* isaStruct(LLValue* v)
 {
-    return llvm::dyn_cast<llvm::StructType>(v->getType());
+    return llvm::dyn_cast<LLStructType>(v->getType());
 }
 
-const llvm::StructType* isaStruct(const LLType* t)
+const LLStructType* isaStruct(const LLType* t)
 {
-    return llvm::dyn_cast<llvm::StructType>(t);
+    return llvm::dyn_cast<LLStructType>(t);
 }
 
 LLConstant* isaConstant(LLValue* v)
@@ -1459,19 +608,19 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-const llvm::PointerType* getPtrToType(const LLType* t)
+const LLPointerType* getPtrToType(const LLType* t)
 {
-    return llvm::PointerType::get(t, 0);
+    return LLPointerType::get(t, 0);
 }
 
-const llvm::PointerType* getVoidPtrType()
+const LLPointerType* getVoidPtrType()
 {
-    return getPtrToType(llvm::Type::Int8Ty);
+    return getPtrToType(LLType::Int8Ty);
 }
 
 llvm::ConstantPointerNull* getNullPtr(const LLType* t)
 {
-    const llvm::PointerType* pt = llvm::cast<llvm::PointerType>(t);
+    const LLPointerType* pt = llvm::cast<LLPointerType>(t);
     return llvm::ConstantPointerNull::get(pt);
 }
 
@@ -1492,355 +641,19 @@
     return gTargetData->getABITypeSize(t);
 }
 
-//////////////////////////////////////////////////////////////////////////////////////////
-
-bool DtoIsTemplateInstance(Dsymbol* s)
-{
-    if (!s) return false;
-    if (s->isTemplateInstance() && !s->isTemplateMixin())
-        return true;
-    else if (s->parent)
-        return DtoIsTemplateInstance(s->parent);
-    return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoLazyStaticInit(bool istempl, LLValue* gvar, Initializer* init, Type* t)
+unsigned char getABITypeAlign(const LLType* t)
 {
-    // create a flag to make sure initialization only happens once
-    llvm::GlobalValue::LinkageTypes gflaglink = istempl ? llvm::GlobalValue::WeakLinkage : llvm::GlobalValue::InternalLinkage;
-    std::string gflagname(gvar->getName());
-    gflagname.append("__initflag");
-    llvm::GlobalVariable* gflag = new llvm::GlobalVariable(llvm::Type::Int1Ty,false,gflaglink,DtoConstBool(false),gflagname,gIR->module);
-
-    // check flag and do init if not already done
-    llvm::BasicBlock* oldend = gIR->scopeend();
-    llvm::BasicBlock* initbb = llvm::BasicBlock::Create("ifnotinit",gIR->topfunc(),oldend);
-    llvm::BasicBlock* endinitbb = llvm::BasicBlock::Create("ifnotinitend",gIR->topfunc(),oldend);
-    LLValue* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false));
-    gIR->ir->CreateCondBr(cond, initbb, endinitbb);
-    gIR->scope() = IRScope(initbb,endinitbb);
-    DValue* ie = DtoInitializer(init);
-    if (!ie->inPlace()) {
-        DValue* dst = new DVarValue(t, gvar, true);
-        DtoAssign(dst, ie);
-    }
-    gIR->ir->CreateStore(DtoConstBool(true), gflag);
-    gIR->ir->CreateBr(endinitbb);
-    gIR->scope() = IRScope(endinitbb,oldend);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoResolveDsymbol(Dsymbol* dsym)
-{
-    if (StructDeclaration* sd = dsym->isStructDeclaration()) {
-        DtoResolveStruct(sd);
-    }
-    else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
-        DtoResolveClass(cd);
-    }
-    else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
-        DtoResolveFunction(fd);
-    }
-    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
-        DtoResolveTypeInfo(fd);
-    }
-    else {
-    error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
-    assert(0 && "unsupported dsymbol for DtoResolveDsymbol");
-    }
+    return gTargetData->getABITypeAlignment(t);
 }
 
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoDeclareDsymbol(Dsymbol* dsym)
-{
-    if (StructDeclaration* sd = dsym->isStructDeclaration()) {
-        DtoDeclareStruct(sd);
-    }
-    else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
-        DtoDeclareClass(cd);
-    }
-    else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
-        DtoDeclareFunction(fd);
-    }
-    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
-        DtoDeclareTypeInfo(fd);
-    }
-    else {
-    error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
-    assert(0 && "unsupported dsymbol for DtoDeclareDsymbol");
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoConstInitDsymbol(Dsymbol* dsym)
+unsigned char getPrefTypeAlign(const LLType* t)
 {
-    if (StructDeclaration* sd = dsym->isStructDeclaration()) {
-        DtoConstInitStruct(sd);
-    }
-    else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
-        DtoConstInitClass(cd);
-    }
-    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
-        DtoConstInitTypeInfo(fd);
-    }
-    else if (VarDeclaration* vd = dsym->isVarDeclaration()) {
-        DtoConstInitGlobal(vd);
-    }
-    else {
-    error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
-    assert(0 && "unsupported dsymbol for DtoConstInitDsymbol");
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoDefineDsymbol(Dsymbol* dsym)
-{
-    if (StructDeclaration* sd = dsym->isStructDeclaration()) {
-        DtoDefineStruct(sd);
-    }
-    else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
-        DtoDefineClass(cd);
-    }
-    else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
-        DtoDefineFunc(fd);
-    }
-    else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
-        DtoDefineTypeInfo(fd);
-    }
-    else {
-    error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
-    assert(0 && "unsupported dsymbol for DtoDefineDsymbol");
-    }
+    return gTargetData->getPrefTypeAlignment(t);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-void DtoConstInitGlobal(VarDeclaration* vd)
-{
-    if (vd->ir.initialized) return;
-    vd->ir.initialized = gIR->dmodule;
-
-    Logger::println("* DtoConstInitGlobal(%s)", vd->toChars());
-    LOG_SCOPE;
-
-    bool emitRTstaticInit = false;
-
-    LLConstant* _init = 0;
-    if (vd->parent && vd->parent->isFuncDeclaration() && vd->init && vd->init->isExpInitializer()) {
-        _init = DtoConstInitializer(vd->type, NULL);
-        emitRTstaticInit = true;
-    }
-    else {
-        _init = DtoConstInitializer(vd->type, vd->init);
-    }
-
-    const LLType* _type = DtoType(vd->type);
-    Type* t = DtoDType(vd->type);
-
-    //Logger::cout() << "initializer: " << *_init << '\n';
-    if (_type != _init->getType()) {
-        Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n";
-        // zero initalizer
-        if (_init->isNullValue())
-            _init = llvm::Constant::getNullValue(_type);
-        // pointer to global constant (struct.init)
-        else if (llvm::isa<llvm::GlobalVariable>(_init))
-        {
-            assert(_init->getType()->getContainedType(0) == _type);
-            llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init);
-            assert(t->ty == Tstruct);
-            TypeStruct* ts = (TypeStruct*)t;
-            assert(ts->sym->ir.irStruct->constInit);
-            _init = ts->sym->ir.irStruct->constInit;
-        }
-        // array single value init
-        else if (isaArray(_type))
-        {
-            _init = DtoConstStaticArray(_type, _init);
-        }
-        else {
-            Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
-            //assert(0);
-        }
-    }
-
-    bool istempl = false;
-    if ((vd->storage_class & STCcomdat) || (vd->parent && DtoIsTemplateInstance(vd->parent))) {
-        istempl = true;
-    }
-
-    if (_init && _init->getType() != _type)
-        _type = _init->getType();
-    llvm::cast<llvm::OpaqueType>(vd->ir.irGlobal->type.get())->refineAbstractTypeTo(_type);
-    _type = vd->ir.irGlobal->type.get();
-    //_type->dump();
-    assert(!_type->isAbstract());
-
-    llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->ir.irGlobal->value);
-    if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl))
-    {
-        gvar->setInitializer(_init);
-    }
-
-    if (emitRTstaticInit)
-        DtoLazyStaticInit(istempl, gvar, vd->init, t);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoEmptyResolveList()
-{
-    //Logger::println("DtoEmptyResolveList()");
-    Dsymbol* dsym;
-    while (!gIR->resolveList.empty()) {
-        dsym = gIR->resolveList.front();
-        gIR->resolveList.pop_front();
-        DtoResolveDsymbol(dsym);
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoEmptyDeclareList()
-{
-    //Logger::println("DtoEmptyDeclareList()");
-    Dsymbol* dsym;
-    while (!gIR->declareList.empty()) {
-        dsym = gIR->declareList.front();
-        gIR->declareList.pop_front();
-        DtoDeclareDsymbol(dsym);
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoEmptyConstInitList()
-{
-    //Logger::println("DtoEmptyConstInitList()");
-    Dsymbol* dsym;
-    while (!gIR->constInitList.empty()) {
-        dsym = gIR->constInitList.front();
-        gIR->constInitList.pop_front();
-        DtoConstInitDsymbol(dsym);
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoEmptyDefineList()
-{
-    //Logger::println("DtoEmptyDefineList()");
-    Dsymbol* dsym;
-    while (!gIR->defineList.empty()) {
-        dsym = gIR->defineList.front();
-        gIR->defineList.pop_front();
-        DtoDefineDsymbol(dsym);
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-void DtoEmptyAllLists()
-{
-    for(;;)
-    {
-        Dsymbol* dsym;
-        if (!gIR->resolveList.empty()) {
-            dsym = gIR->resolveList.front();
-            gIR->resolveList.pop_front();
-            DtoResolveDsymbol(dsym);
-        }
-        else if (!gIR->declareList.empty()) {
-            dsym = gIR->declareList.front();
-            gIR->declareList.pop_front();
-            DtoDeclareDsymbol(dsym);
-        }
-        else if (!gIR->constInitList.empty()) {
-            dsym = gIR->constInitList.front();
-            gIR->constInitList.pop_front();
-            DtoConstInitDsymbol(dsym);
-        }
-        else if (!gIR->defineList.empty()) {
-            dsym = gIR->defineList.front();
-            gIR->defineList.pop_front();
-            DtoDefineDsymbol(dsym);
-        }
-        else {
-            break;
-        }
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoForceDeclareDsymbol(Dsymbol* dsym)
-{
-    if (dsym->ir.declared) return;
-    Logger::println("DtoForceDeclareDsymbol(%s)", dsym->toPrettyChars());
-    LOG_SCOPE;
-    DtoResolveDsymbol(dsym);
-
-    DtoEmptyResolveList();
-
-    DtoDeclareDsymbol(dsym);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoForceConstInitDsymbol(Dsymbol* dsym)
-{
-    if (dsym->ir.initialized) return;
-    Logger::println("DtoForceConstInitDsymbol(%s)", dsym->toPrettyChars());
-    LOG_SCOPE;
-    DtoResolveDsymbol(dsym);
-
-    DtoEmptyResolveList();
-    DtoEmptyDeclareList();
-
-    DtoConstInitDsymbol(dsym);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoForceDefineDsymbol(Dsymbol* dsym)
-{
-    if (dsym->ir.defined) return;
-    Logger::println("DtoForceDefineDsymbol(%s)", dsym->toPrettyChars());
-    LOG_SCOPE;
-    DtoResolveDsymbol(dsym);
-
-    DtoEmptyResolveList();
-    DtoEmptyDeclareList();
-    DtoEmptyConstInitList();
-
-    DtoDefineDsymbol(dsym);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoAnnotation(const char* str)
-{
-    std::string s("CODE: ");
-    s.append(str);
-    char* p = &s[0];
-    while (*p)
-    {
-        if (*p == '"')
-            *p = '\'';
-        ++p;
-    }
-    // create a noop with the code as the result name!
-    gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str());
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-const llvm::StructType* DtoInterfaceInfoType()
+const LLStructType* DtoInterfaceInfoType()
 {
     if (gIR->interfaceInfoType)
         return gIR->interfaceInfoType;
@@ -1854,34 +667,17 @@
     // void*[] vtbl
     std::vector<const LLType*> vtbltypes;
     vtbltypes.push_back(DtoSize_t());
-    const LLType* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
+    const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::Int8Ty));
     vtbltypes.push_back(byteptrptrty);
-    types.push_back(llvm::StructType::get(vtbltypes));
+    types.push_back(LLStructType::get(vtbltypes));
     // int offset
-    types.push_back(llvm::Type::Int32Ty);
+    types.push_back(LLType::Int32Ty);
     // create type
-    gIR->interfaceInfoType = llvm::StructType::get(types);
+    gIR->interfaceInfoType = LLStructType::get(types);
 
     return gIR->interfaceInfoType;
 }
 
-//////////////////////////////////////////////////////////////////////////////////////////
-
-LLConstant* DtoTypeInfoOf(Type* type, bool base)
-{
-    const LLType* typeinfotype = DtoType(Type::typeinfo->type);
-    if (!type->vtinfo)
-        type->getTypeInfo(NULL);
-    TypeInfoDeclaration* tidecl = type->vtinfo;
-    DtoForceDeclareDsymbol(tidecl);
-    assert(tidecl->ir.irGlobal != NULL);
-    LLConstant* c = isaConstant(tidecl->ir.irGlobal->value);
-    assert(c != NULL);
-    if (base)
-        return llvm::ConstantExpr::getBitCast(c, typeinfotype);
-    return c;
-}
-
 
 
 
@@ -1891,5 +687,3 @@
 
 
 
-
-
--- a/gen/tollvm.h	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/tollvm.h	Mon Jun 09 09:37:08 2008 +0200
@@ -19,15 +19,13 @@
 Type* DtoDType(Type* t);
 
 // delegate helpers
-const llvm::StructType* DtoDelegateType(Type* t);
-void DtoDelegateToNull(LLValue* v);
-void DtoDelegateCopy(LLValue* dst, LLValue* src);
+const LLStructType* DtoDelegateType(Type* t);
 LLValue* DtoDelegateCompare(TOK op, LLValue* lhs, LLValue* rhs);
 
 // return linkage type for symbol using the current ir state for context
-llvm::GlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym);
-llvm::GlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym);
-llvm::GlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym);
+LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym);
+LLGlobalValue::LinkageTypes DtoInternalLinkage(Dsymbol* sym);
+LLGlobalValue::LinkageTypes DtoExternalLinkage(Dsymbol* sym);
 
 // convert DMD calling conv to LLVM
 unsigned DtoCallingConv(LINK l);
@@ -40,122 +38,94 @@
 
 // some types
 const LLType* DtoSize_t();
-const llvm::StructType* DtoInterfaceInfoType();
-
-// getting typeinfo of type, base=true casts to object.TypeInfo
-LLConstant* DtoTypeInfoOf(Type* ty, bool base=true);
-
-// initializer helpers
-LLConstant* DtoConstInitializer(Type* type, Initializer* init);
-LLConstant* DtoConstFieldInitializer(Type* type, Initializer* init);
-DValue* DtoInitializer(Initializer* init);
-
-// declaration of memset/cpy intrinsics
-llvm::Function* LLVM_DeclareMemSet32();
-llvm::Function* LLVM_DeclareMemSet64();
-llvm::Function* LLVM_DeclareMemCpy32();
-llvm::Function* LLVM_DeclareMemCpy64();
+const LLStructType* DtoInterfaceInfoType();
 
 // getelementptr helpers
-LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var, llvm::BasicBlock* bb=NULL);
-LLValue* DtoGEPi(LLValue* ptr, const DStructIndexVector& src, const char* var, llvm::BasicBlock* bb=NULL);
-LLValue* DtoGEPi(LLValue* ptr, unsigned i0, const char* var, llvm::BasicBlock* bb=NULL);
-LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const char* var, llvm::BasicBlock* bb=NULL);
-
-// dynamic memory helpers
-LLValue* DtoNew(Type* newtype);
-void DtoDeleteMemory(LLValue* ptr);
-void DtoDeleteClass(LLValue* inst);
-void DtoDeleteInterface(LLValue* inst);
-void DtoDeleteArray(DValue* arr);
-
-// assertion generator
-void DtoAssert(Loc* loc, DValue* msg);
-
-// nested variable/class helpers
-LLValue* DtoNestedContext(FuncDeclaration* func);
-LLValue* DtoNestedVariable(VarDeclaration* vd);
-
-// annotation generator
-void DtoAnnotation(const char* str);
+LLValue* DtoGEP1(LLValue* ptr, LLValue* i0, const char* var=NULL, llvm::BasicBlock* bb=NULL);
+LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const char* var=NULL, llvm::BasicBlock* bb=NULL);
+LLValue* DtoGEPi(LLValue* ptr, const DStructIndexVector& src, const char* var=NULL, llvm::BasicBlock* bb=NULL);
+LLValue* DtoGEPi1(LLValue* ptr, unsigned i0, const char* var=NULL, llvm::BasicBlock* bb=NULL);
+LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const char* var=NULL, llvm::BasicBlock* bb=NULL);
 
 // to constant helpers
-llvm::ConstantInt* DtoConstSize_t(size_t);
-llvm::ConstantInt* DtoConstUint(unsigned i);
-llvm::ConstantInt* DtoConstInt(int i);
+LLConstantInt* DtoConstSize_t(size_t);
+LLConstantInt* DtoConstUint(unsigned i);
+LLConstantInt* DtoConstInt(int i);
+LLConstantInt* DtoConstUbyte(unsigned char i);
 llvm::ConstantFP* DtoConstFP(Type* t, long double value);
 
 LLConstant* DtoConstString(const char*);
 LLConstant* DtoConstStringPtr(const char* str, const char* section = 0);
 LLConstant* DtoConstBool(bool);
 
-// is template instance check
-bool DtoIsTemplateInstance(Dsymbol* s);
-
-// generates lazy static initialization code for a global variable
-void DtoLazyStaticInit(bool istempl, LLValue* gvar, Initializer* init, Type* t);
-
-// these are all basically drivers for the codegeneration called by the main loop
-void DtoResolveDsymbol(Dsymbol* dsym);
-void DtoDeclareDsymbol(Dsymbol* dsym);
-void DtoDefineDsymbol(Dsymbol* dsym);
-void DtoConstInitDsymbol(Dsymbol* dsym);
-void DtoConstInitGlobal(VarDeclaration* vd);
-void DtoEmptyResolveList();
-void DtoEmptyDeclareList();
-void DtoEmptyConstInitList();
-void DtoEmptyAllLists();
-void DtoForceDeclareDsymbol(Dsymbol* dsym);
-void DtoForceConstInitDsymbol(Dsymbol* dsym);
-void DtoForceDefineDsymbol(Dsymbol* dsym);
-
 // llvm wrappers
-void DtoMemSetZero(LLValue* dst, LLValue* nbytes);
-void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes);
-void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device=false);
 bool DtoCanLoad(LLValue* ptr);
 LLValue* DtoLoad(LLValue* src, const char* name=0);
 void DtoStore(LLValue* src, LLValue* dst);
 LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name=0);
 
 // llvm::dyn_cast wrappers
-const llvm::PointerType* isaPointer(LLValue* v);
-const llvm::PointerType* isaPointer(const LLType* t);
-const llvm::ArrayType* isaArray(LLValue* v);
-const llvm::ArrayType* isaArray(const LLType* t);
-const llvm::StructType* isaStruct(LLValue* v);
-const llvm::StructType* isaStruct(const LLType* t);
+const LLPointerType* isaPointer(LLValue* v);
+const LLPointerType* isaPointer(const LLType* t);
+const LLArrayType* isaArray(LLValue* v);
+const LLArrayType* isaArray(const LLType* t);
+const LLStructType* isaStruct(LLValue* v);
+const LLStructType* isaStruct(const LLType* t);
 LLConstant* isaConstant(LLValue* v);
-llvm::ConstantInt* isaConstantInt(LLValue* v);
+LLConstantInt* isaConstantInt(LLValue* v);
 llvm::Argument* isaArgument(LLValue* v);
-llvm::GlobalVariable* isaGlobalVar(LLValue* v);
+LLGlobalVariable* isaGlobalVar(LLValue* v);
 
 // llvm::T::get(...) wrappers
-const llvm::PointerType* getPtrToType(const LLType* t);
-const llvm::PointerType* getVoidPtrType();
+const LLPointerType* getPtrToType(const LLType* t);
+const LLPointerType* getVoidPtrType();
 llvm::ConstantPointerNull* getNullPtr(const LLType* t);
 
 // type sizes
 size_t getTypeBitSize(const LLType* t);
 size_t getTypeStoreSize(const LLType* t);
 size_t getABITypeSize(const LLType* t);
+// type alignments
+unsigned char getABITypeAlign(const LLType* t);
+unsigned char getPrefTypeAlign(const LLType* t);
 
-// basic operations
-void DtoAssign(DValue* lhs, DValue* rhs);
+/**
+ * Generates a call to llvm.memset.i32 (or i64 depending on architecture).
+ * @param dst Destination memory.
+ * @param nbytes Number of bytes to overwrite.
+ */
+void DtoMemSetZero(LLValue* dst, LLValue* nbytes);
+
+/**
+ * Generates a call to llvm.memcpy.i32 (or i64 depending on architecture).
+ * @param dst Destination memory.
+ * @param src Source memory.
+ * @param nbytes Number of bytes to copy.
+ */
+void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes);
 
-// casts
-DValue* DtoCastInt(DValue* val, Type* to);
-DValue* DtoCastPtr(DValue* val, Type* to);
-DValue* DtoCastFloat(DValue* val, Type* to);
-DValue* DtoCastComplex(DValue* val, Type* to);
-DValue* DtoCast(DValue* val, Type* to);
+/**
+ * The same as DtoMemSetZero but figures out the size itself by "dereferencing" the v pointer once.
+ * @param v Destination memory.
+ */
+void DtoAggrZeroInit(LLValue* v);
 
-// binary operations
-DValue* DtoBinAdd(DValue* lhs, DValue* rhs);
-DValue* DtoBinSub(DValue* lhs, DValue* rhs);
-DValue* DtoBinMul(DValue* lhs, DValue* rhs);
-DValue* DtoBinDiv(DValue* lhs, DValue* rhs);
-DValue* DtoBinRem(DValue* lhs, DValue* rhs);
+/**
+ * The same as DtoMemCpy but figures out the size itself by "dereferencing" dst the pointer once.
+ * @param dst Destination memory.
+ * @param src Source memory.
+ */
+void DtoAggrCopy(LLValue* dst, LLValue* src);
+
+/**
+ * Generates a call to llvm.memory.barrier
+ * @param ll load-load
+ * @param ls load-store
+ * @param sl store-load
+ * @param ss store-store
+ * @param device special device flag
+ */
+void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device=false);
 
 #include "enums.h"
 
--- a/gen/toobj.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/toobj.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -35,6 +35,7 @@
 #include "gen/irstate.h"
 #include "gen/logger.h"
 #include "gen/tollvm.h"
+#include "gen/llvmhelpers.h"
 #include "gen/arrays.h"
 #include "gen/structs.h"
 #include "gen/classes.h"
@@ -203,7 +204,7 @@
     name.append("6__ctorZ");
 
     std::vector<const LLType*> argsTy;
-    const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false);
+    const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::VoidTy,argsTy,false);
     assert(gIR->module->getFunction(name) == NULL);
     llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
     fn->setCallingConv(llvm::CallingConv::Fast);
@@ -237,7 +238,7 @@
     name.append("6__dtorZ");
 
     std::vector<const LLType*> argsTy;
-    const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false);
+    const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::VoidTy,argsTy,false);
     assert(gIR->module->getFunction(name) == NULL);
     llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
     fn->setCallingConv(llvm::CallingConv::Fast);
@@ -271,7 +272,7 @@
     name.append("10__unittestZ");
 
     std::vector<const LLType*> argsTy;
-    const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false);
+    const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::VoidTy,argsTy,false);
     assert(gIR->module->getFunction(name) == NULL);
     llvm::Function* fn = llvm::Function::Create(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
     fn->setCallingConv(llvm::CallingConv::Fast);
@@ -325,7 +326,7 @@
     initVec.push_back(c);
 
     // monitor
-    c = getNullPtr(getPtrToType(llvm::Type::Int8Ty));
+    c = getNullPtr(getPtrToType(LLType::Int8Ty));
     initVec.push_back(c);
 
     // name
@@ -463,9 +464,9 @@
     gvar->setInitializer(constMI);
 
     // declare the appending array
-    const llvm::ArrayType* appendArrTy = llvm::ArrayType::get(getPtrToType(llvm::Type::Int8Ty), 1);
+    const llvm::ArrayType* appendArrTy = llvm::ArrayType::get(getPtrToType(LLType::Int8Ty), 1);
     std::vector<LLConstant*> appendInits;
-    appendInits.push_back(llvm::ConstantExpr::getBitCast(gvar, getPtrToType(llvm::Type::Int8Ty)));
+    appendInits.push_back(llvm::ConstantExpr::getBitCast(gvar, getPtrToType(LLType::Int8Ty)));
     LLConstant* appendInit = llvm::ConstantArray::get(appendArrTy, appendInits);
     std::string appendName("_d_moduleinfo_array");
     llvm::GlobalVariable* appendVar = new llvm::GlobalVariable(appendArrTy, true, llvm::GlobalValue::AppendingLinkage, appendInit, appendName, gIR->module);
--- a/gen/typinf.cpp	Mon Jun 09 03:02:14 2008 +0200
+++ b/gen/typinf.cpp	Mon Jun 09 09:37:08 2008 +0200
@@ -35,6 +35,7 @@
 #include "gen/logger.h"
 #include "gen/runtime.h"
 #include "gen/tollvm.h"
+#include "gen/llvmhelpers.h"
 #include "gen/arrays.h"
 #include "gen/structs.h"
 #include "gen/classes.h"
@@ -279,7 +280,7 @@
         LLValue* found = gIR->module->getNamedGlobal(mangled);
         if (!found)
         {
-            const LLType* t = llvm::OpaqueType::get();
+            const LLType* t = LLOpaqueType::get();
             llvm::GlobalVariable* g = new llvm::GlobalVariable(t, true, llvm::GlobalValue::ExternalLinkage, NULL, mangled, gIR->module);
             assert(g);
             /*if (!tid->ir.irGlobal)
@@ -353,7 +354,7 @@
     ClassDeclaration* base = Type::typeinfotypedef;
     DtoResolveClass(base);
 
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // create the symbol
     this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
@@ -367,7 +368,7 @@
     ClassDeclaration* base = Type::typeinfotypedef;
     DtoForceConstInitDsymbol(base);
 
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
     Logger::cout() << "got stype: " << *stype << '\n';
 
     // vtbl
@@ -375,14 +376,14 @@
     sinits.push_back(base->ir.irStruct->vtbl);
 
     // monitor
-    sinits.push_back(getNullPtr(getPtrToType(llvm::Type::Int8Ty)));
+    sinits.push_back(getNullPtr(getPtrToType(LLType::Int8Ty)));
 
     assert(tinfo->ty == Ttypedef);
     TypeTypedef *tc = (TypeTypedef *)tinfo;
     TypedefDeclaration *sd = tc->sym;
 
     // TypeInfo base
-    //const llvm::PointerType* basept = isaPointer(initZ->getOperand(1)->getType());
+    //const LLPointerType* basept = isaPointer(initZ->getOperand(1)->getType());
     //sinits.push_back(llvm::ConstantPointerNull::get(basept));
     Logger::println("generating base typeinfo");
     //sd->basetype = sd->basetype->merge();
@@ -403,7 +404,7 @@
     assert(sinits.back()->getType() == stype->getElementType(3));
 
     // void[] init
-    const llvm::PointerType* initpt = getPtrToType(llvm::Type::Int8Ty);
+    const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
     if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type
     {
         sinits.push_back(DtoConstSlice(DtoConstSize_t(0), getNullPtr(initpt)));
@@ -439,7 +440,7 @@
     ClassDeclaration* base = Type::typeinfoenum;
     DtoResolveClass(base);
 
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // create the symbol
     this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
@@ -453,21 +454,21 @@
     ClassDeclaration* base = Type::typeinfoenum;
     DtoForceConstInitDsymbol(base);
 
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // vtbl
     std::vector<LLConstant*> sinits;
     sinits.push_back(base->ir.irStruct->vtbl);
 
     // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
+    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
 
     assert(tinfo->ty == Tenum);
     TypeEnum *tc = (TypeEnum *)tinfo;
     EnumDeclaration *sd = tc->sym;
 
     // TypeInfo base
-    //const llvm::PointerType* basept = isaPointer(initZ->getOperand(1)->getType());
+    //const LLPointerType* basept = isaPointer(initZ->getOperand(1)->getType());
     //sinits.push_back(llvm::ConstantPointerNull::get(basept));
     Logger::println("generating base typeinfo");
     //sd->basetype = sd->basetype->merge();
@@ -487,7 +488,7 @@
     assert(sinits.back()->getType() == stype->getElementType(3));
 
     // void[] init
-    const llvm::PointerType* initpt = getPtrToType(llvm::Type::Int8Ty);
+    const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
     if (tinfo->isZeroInit() || !sd->defaultval) // 0 initializer, or the same as the base type
     {
         sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
@@ -521,7 +522,7 @@
     ClassDeclaration* base = cd;
     DtoResolveClass(base);
 
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // create the symbol
     tid->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
@@ -532,14 +533,14 @@
     ClassDeclaration* base = cd;
     DtoForceConstInitDsymbol(base);
 
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // vtbl
     std::vector<LLConstant*> sinits;
     sinits.push_back(base->ir.irStruct->vtbl);
 
     // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
+    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
 
     // TypeInfo base
     Logger::println("generating base typeinfo");
@@ -626,7 +627,7 @@
     DtoResolveClass(base);
 
     // get type of typeinfo class
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // create the symbol
     this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
@@ -642,7 +643,7 @@
     DtoForceConstInitDsymbol(base);
 
     // get type of typeinfo class
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // initializer vector
     std::vector<LLConstant*> sinits;
@@ -650,7 +651,7 @@
     sinits.push_back(base->ir.irStruct->vtbl);
 
     // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
+    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
 
     // value typeinfo
     assert(tinfo->ty == Tsarray);
@@ -689,7 +690,7 @@
     DtoResolveClass(base);
 
     // get type of typeinfo class
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // create the symbol
     this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
@@ -705,7 +706,7 @@
     DtoForceConstInitDsymbol(base);
 
     // get type of typeinfo class
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // initializer vector
     std::vector<LLConstant*> sinits;
@@ -713,7 +714,7 @@
     sinits.push_back(base->ir.irStruct->vtbl);
 
     // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
+    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
 
     // get type
     assert(tinfo->ty == Taarray);
@@ -822,7 +823,7 @@
     ClassDeclaration* base = Type::typeinfostruct;
     DtoResolveClass(base);
 
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // create the symbol
     this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
@@ -841,14 +842,14 @@
     ClassDeclaration* base = Type::typeinfostruct;
     DtoForceConstInitDsymbol(base);
 
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // vtbl
     std::vector<LLConstant*> sinits;
     sinits.push_back(base->ir.irStruct->vtbl);
 
     // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
+    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
 
     // char[] name
     char *name = sd->toPrettyChars();
@@ -857,7 +858,7 @@
     assert(sinits.back()->getType() == stype->getElementType(2));
 
     // void[] init
-    const llvm::PointerType* initpt = getPtrToType(llvm::Type::Int8Ty);
+    const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
 #if 0
     // the implementation of TypeInfo_Struct uses this to determine size. :/
     if (sd->zeroInit) // 0 initializer, or the same as the base type
@@ -918,7 +919,7 @@
 #endif
 
     //Logger::println("************** B");
-    const llvm::PointerType* ptty = isaPointer(stype->getElementType(4));
+    const LLPointerType* ptty = isaPointer(stype->getElementType(4));
     assert(ptty);
 
     s = search_function(sd, Id::tohash);
@@ -1025,7 +1026,7 @@
     DtoResolveClass(base);
 
     // get type of typeinfo class
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // create the symbol
     this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
@@ -1042,7 +1043,7 @@
     DtoForceConstInitDsymbol(base);
 
     // get type of typeinfo class
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // initializer vector
     std::vector<LLConstant*> sinits;
@@ -1050,7 +1051,7 @@
     sinits.push_back(base->ir.irStruct->vtbl);
 
     // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
+    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
 
     // get classinfo
     assert(tinfo->ty == Tclass);
@@ -1082,7 +1083,7 @@
     DtoResolveClass(base);
 
     // get type of typeinfo class
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // create the symbol
     this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
@@ -1099,7 +1100,7 @@
     DtoForceConstInitDsymbol(base);
 
     // get type of typeinfo class
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // initializer vector
     std::vector<LLConstant*> sinits;
@@ -1107,7 +1108,7 @@
     sinits.push_back(base->ir.irStruct->vtbl);
 
     // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
+    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
 
     // get classinfo
     assert(tinfo->ty == Tclass);
@@ -1138,7 +1139,7 @@
     DtoResolveClass(base);
 
     // get type of typeinfo class
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // create the symbol
     this->ir.irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
@@ -1155,7 +1156,7 @@
     DtoForceConstInitDsymbol(base);
 
     // get type of typeinfo class
-    const llvm::StructType* stype = isaStruct(base->type->ir.type->get());
+    const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
     // initializer vector
     std::vector<LLConstant*> sinits;
@@ -1163,7 +1164,7 @@
     sinits.push_back(base->ir.irStruct->vtbl);
 
     // monitor
-    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
+    sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
 
     // create elements array
     assert(tinfo->ty == Ttuple);
@@ -1187,7 +1188,7 @@
     }
 
     // build array type
-    const llvm::ArrayType* arrTy = llvm::ArrayType::get(tiTy, dim);
+    const LLArrayType* arrTy = LLArrayType::get(tiTy, dim);
     LLConstant* arrC = llvm::ConstantArray::get(arrTy, arrInits);
 
     // build the slice
--- a/ir/irstruct.h	Mon Jun 09 03:02:14 2008 +0200
+++ b/ir/irstruct.h	Mon Jun 09 09:37:08 2008 +0200
@@ -44,10 +44,10 @@
     struct Offset
     {
         VarDeclaration* var;
-        const llvm::Type* type;
+        const LLType* type;
         llvm::Constant* init;
 
-        Offset(VarDeclaration* v, const llvm::Type* ty)
+        Offset(VarDeclaration* v, const LLType* ty)
         : var(v), type(ty), init(NULL) {}
     };
 
--- a/llvmdc.kdevelop.filelist	Mon Jun 09 03:02:14 2008 +0200
+++ b/llvmdc.kdevelop.filelist	Mon Jun 09 09:37:08 2008 +0200
@@ -116,6 +116,8 @@
 gen/enums.h
 gen/functions.cpp
 gen/functions.h
+gen/intrinsics.cpp
+gen/intrinsics.h
 gen/irstate.cpp
 gen/irstate.h
 gen/linker.h
@@ -762,6 +764,7 @@
 tangotests/c.d
 tangotests/classes1.d
 tangotests/constructors.d
+tangotests/debug1.d
 tangotests/e.d
 tangotests/f.d
 tangotests/files1.d