changeset 136:0e28624814e8 trunk

[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
author lindquist
date Thu, 17 Jan 2008 03:15:12 +0100
parents 176bd52b3cf5
children ce7b81fb957f
files dmd/aggregate.h dmd/declaration.c dmd/declaration.h dmd/dsymbol.c dmd/dsymbol.h dmd/expression.c dmd/func.c dmd/mtype.c dmd/statement.c dmd/struct.c gen/aa.cpp gen/arrays.cpp gen/classes.cpp gen/functions.cpp gen/irstate.cpp gen/irstate.h gen/statements.cpp gen/structs.cpp gen/todebug.cpp gen/toir.cpp gen/tollvm.cpp gen/tollvm.h gen/toobj.cpp gen/typinf.cpp ir/ir.h ir/irforw.h ir/irfunction.cpp ir/irfunction.h ir/irmodule.cpp ir/irmodule.h ir/irstruct.cpp ir/irstruct.h ir/irvar.cpp ir/irvar.h llvmdc.kdevelop.filelist premake.lua tango/lib/compiler/llvmdc/cast.d tango/tango/io/Buffer.d tango/tango/io/Console.d tango/tango/io/DeviceConduit.d
diffstat 40 files changed, 900 insertions(+), 548 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/aggregate.h	Mon Jan 14 23:09:55 2008 +0100
+++ b/dmd/aggregate.h	Thu Jan 17 03:15:12 2008 +0100
@@ -45,7 +45,7 @@
     class ConstantStruct;
     class GlobalVariable;
 }
-struct IRStruct;
+struct IrStruct;
 struct DUnion;
 
 struct AggregateDeclaration : ScopeDsymbol
@@ -110,7 +110,7 @@
     llvm::Constant* llvmConstClass;
     bool llvmHasUnions;
     DUnion* llvmUnion;
-    IRStruct* llvmIRStruct;
+    IrStruct* llvmIrStruct;
     bool llvmClassDeclared;
     bool llvmClassDefined;
 
--- a/dmd/declaration.c	Mon Jan 14 23:09:55 2008 +0100
+++ b/dmd/declaration.c	Thu Jan 17 03:15:12 2008 +0100
@@ -549,12 +549,10 @@
     onstack = 0;
     canassign = 0;
     value = NULL;
-    llvmNestedIndex = -1;
-    llvmFieldIndex = -1;
-    llvmFieldIndexOffset = 0;
-    llvmNeedsStorage = false;
-    llvmConstInit = NULL;
-    llvmIRGlobal = NULL;
+    irGlobal = NULL;
+    irLocal = NULL;
+    irField = NULL;
+    needsStorage = false;
 }
 
 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
@@ -1060,7 +1058,7 @@
 		fdthis->getLevel(loc, fdv);
 	    nestedref = 1;
 	    fdv->nestedFrameRef = 1;
-        fdv->llvmNestedVars.insert(this);
+        fdv->nestedVars.insert(this);
 	    //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
 	}
     }
--- a/dmd/declaration.h	Mon Jan 14 23:09:55 2008 +0100
+++ b/dmd/declaration.h	Thu Jan 17 03:15:12 2008 +0100
@@ -24,8 +24,11 @@
 namespace llvm {
     class Value;
 }
-struct IRFunction;
-struct IRGlobal;
+struct IrFunction;
+struct IrVar;
+struct IrGlobal;
+struct IrLocal;
+struct IrField;
 
 struct Expression;
 struct Statement;
@@ -261,12 +264,13 @@
     VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
 
     // LLVMDC
-    int llvmNestedIndex;
-    int llvmFieldIndex;
-    size_t llvmFieldIndexOffset;
-    bool llvmNeedsStorage;
-    llvm::Constant* llvmConstInit;
-    IRGlobal* llvmIRGlobal;
+    IrGlobal* irGlobal;
+    IrLocal* irLocal;
+    IrField* irField;
+    bool needsStorage;
+
+    IrVar* getIrVar();
+    llvm::Value*& getIrValue();
 };
 
 /**************************************************************/
@@ -609,16 +613,9 @@
     FuncDeclaration *isFuncDeclaration() { return this; }
 
     // llvmdc stuff
-    bool llvmQueued;
-    llvm::Value* llvmThisVar;
-    std::set<VarDeclaration*> llvmNestedVars;
-    llvm::Value* llvmNested;
-    llvm::Value* llvmArguments;
-    llvm::Value* llvmArgPtr;
-    llvm::Constant* llvmDwarfSubProgram;
-    bool llvmRunTimeHack;
-    IRFunction* llvmIRFunc;
-    llvm::Value* llvmRetArg;
+    bool runTimeHack;
+    IrFunction* irFunc;
+    std::set<VarDeclaration*> nestedVars;
 };
 
 struct FuncAliasDeclaration : FuncDeclaration
--- a/dmd/dsymbol.c	Mon Jan 14 23:09:55 2008 +0100
+++ b/dmd/dsymbol.c	Thu Jan 17 03:15:12 2008 +0100
@@ -43,10 +43,12 @@
     this->isym = NULL;
     this->loc = 0;
     this->comment = NULL;
+
     this->llvmInternal = LLVMnone;
     this->llvmInternal1 = NULL;
     this->llvmInternal2 = NULL;
-    this->llvmValue = NULL;
+
+    //this->llvmValue = NULL;
     this->llvmDModule = NULL;
 
     this->llvmResolved = false;
@@ -65,10 +67,12 @@
     this->isym = NULL;
     this->loc = 0;
     this->comment = NULL;
+
     this->llvmInternal = LLVMnone;
     this->llvmInternal1 = NULL;
     this->llvmInternal2 = NULL;
-    this->llvmValue = NULL;
+
+    //this->llvmValue = NULL;
     this->llvmDModule = NULL;
 
     this->llvmResolved = false;
--- a/dmd/dsymbol.h	Mon Jan 14 23:09:55 2008 +0100
+++ b/dmd/dsymbol.h	Thu Jan 17 03:15:12 2008 +0100
@@ -220,7 +220,7 @@
     char* llvmInternal1;
     char* llvmInternal2;
 
-    llvm::Value* llvmValue;
+    //llvm::Value* llvmValue;
     Module* llvmDModule;
 
     bool llvmResolved;
--- a/dmd/expression.c	Mon Jan 14 23:09:55 2008 +0100
+++ b/dmd/expression.c	Thu Jan 17 03:15:12 2008 +0100
@@ -3456,7 +3456,7 @@
     if (v)
     {
     v->checkNestedReference(sc, loc);
-    v->llvmNeedsStorage = true;
+    v->needsStorage = true;
     }
     return this;
 }
@@ -3601,7 +3601,7 @@
     if (v && v->canassign == 0 &&
         (var->isConst() || (global.params.Dversion > 1 && var->isFinal())))
 	error("cannot modify final variable '%s'", var->toChars());
-    v->llvmNeedsStorage = true;
+    v->needsStorage = true;
 
     if (var->isCtorinit())
     {	// It's only modifiable if inside the right constructor
@@ -5887,7 +5887,7 @@
 	    }
         else if (v)
         {
-        v->llvmNeedsStorage = true;
+        v->needsStorage = true;
         }
 	}
 	else if (e1->op == TOKarray)
--- a/dmd/func.c	Mon Jan 14 23:09:55 2008 +0100
+++ b/dmd/func.c	Thu Jan 17 03:15:12 2008 +0100
@@ -73,15 +73,9 @@
     nrvo_can = 1;
     nrvo_var = NULL;
     shidden = NULL;
-    llvmQueued = false;
-    llvmThisVar = NULL;
-    llvmNested = NULL;
-    llvmArguments = NULL;
-    llvmArgPtr = NULL;
-    llvmDwarfSubProgram = NULL;
-    llvmRunTimeHack = false;
-    llvmIRFunc = NULL;
-    llvmRetArg = NULL;
+    // llvmdc
+    runTimeHack = false;
+    irFunc = NULL;
 }
 
 Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
--- a/dmd/mtype.c	Mon Jan 14 23:09:55 2008 +0100
+++ b/dmd/mtype.c	Thu Jan 17 03:15:12 2008 +0100
@@ -1514,7 +1514,7 @@
 
 	nm = name[n->ty == Twchar];
 	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm);
-    fd->llvmRunTimeHack = true;
+    fd->runTimeHack = true;
 	ec = new VarExp(0, fd);
 	e = e->castTo(sc, n->arrayOf());	// convert to dynamic array
 	arguments = new Expressions();
@@ -1532,7 +1532,7 @@
 
 	nm = name[n->ty == Twchar];
 	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm);
-    fd->llvmRunTimeHack = true;
+    fd->runTimeHack = true;
 	ec = new VarExp(0, fd);
 	e = e->castTo(sc, n->arrayOf());	// convert to dynamic array
 	arguments = new Expressions();
@@ -1551,7 +1551,7 @@
 	assert(size);
 	dup = (ident == Id::dup);
 	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), dup ? Id::adDup : Id::adReverse);
-    fd->llvmRunTimeHack = true;
+    fd->runTimeHack = true;
 	ec = new VarExp(0, fd);
 	e = e->castTo(sc, n->arrayOf());	// convert to dynamic array
 	arguments = new Expressions();
@@ -1571,7 +1571,7 @@
 
 	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(),
 		(char*)(n->ty == Tbit ? "_adSortBit" : "_adSort"));
-    fd->llvmRunTimeHack = true;
+    fd->runTimeHack = true;
 	ec = new VarExp(0, fd);
 	e = e->castTo(sc, n->arrayOf());	// convert to dynamic array
 	arguments = new Expressions();
@@ -2273,7 +2273,7 @@
 	Expressions *arguments;
 
 	fd = FuncDeclaration::genCfunc(Type::tsize_t, Id::aaLen);
-    fd->llvmRunTimeHack = true;
+    fd->runTimeHack = true;
 	ec = new VarExp(0, fd);
 	arguments = new Expressions();
 	arguments->push(e);
@@ -2289,7 +2289,7 @@
 
 	assert(size);
 	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaKeys);
-    fd->llvmRunTimeHack = true;
+    fd->runTimeHack = true;
 	ec = new VarExp(0, fd);
 	arguments = new Expressions();
 	arguments->push(e);
@@ -2304,7 +2304,7 @@
 	Expressions *arguments;
 
 	fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaValues);
-    fd->llvmRunTimeHack = true;
+    fd->runTimeHack = true;
 	ec = new VarExp(0, fd);
 	arguments = new Expressions();
 	arguments->push(e);
@@ -2322,7 +2322,7 @@
 	Expressions *arguments;
 
 	fd = FuncDeclaration::genCfunc(Type::tvoid->pointerTo(), Id::aaRehash);
-    fd->llvmRunTimeHack = true;
+    fd->runTimeHack = true;
 	ec = new VarExp(0, fd);
 	arguments = new Expressions();
 	arguments->push(e->addressOf(sc));
--- a/dmd/statement.c	Mon Jan 14 23:09:55 2008 +0100
+++ b/dmd/statement.c	Thu Jan 17 03:15:12 2008 +0100
@@ -1431,7 +1431,7 @@
 		    fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply2");
 		else
 		    fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply");
-        fdapply->llvmRunTimeHack = true;
+        fdapply->runTimeHack = true;
 		ec = new VarExp(0, fdapply);
 		Expressions *exps = new Expressions();
 		exps->push(aggr);
@@ -1473,7 +1473,7 @@
 		int j = sprintf(fdname, "_aApply%s%.*s%d", r, 2, fntab[flag], dim);
 		assert(j < sizeof(fdname));
 		fdapply = FuncDeclaration::genCfunc(Type::tindex, fdname);
-        fdapply->llvmRunTimeHack = true;
+        fdapply->runTimeHack = true;
 
 		ec = new VarExp(0, fdapply);
 		Expressions *exps = new Expressions();
--- a/dmd/struct.c	Mon Jan 14 23:09:55 2008 +0100
+++ b/dmd/struct.c	Thu Jan 17 03:15:12 2008 +0100
@@ -54,7 +54,7 @@
     llvmInProgress = false;
     llvmHasUnions = false;
     llvmUnion = NULL;
-    llvmIRStruct = NULL;
+    llvmIrStruct = NULL;
     llvmClassDeclared = false;
     llvmClassDefined = false;
 }
--- a/gen/aa.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/aa.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -58,8 +58,8 @@
     assert(tid);
     DtoResolveDsymbol(Type::typeinfo);
     DtoForceDeclareDsymbol(tid);
-    assert(tid->llvmValue);
-    return tid->llvmValue;
+    assert(tid->irGlobal->value);
+    return tid->irGlobal->value;
 }
 
 /////////////////////////////////////////////////////////////////////////////////////
--- a/gen/arrays.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/arrays.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -671,13 +671,11 @@
     // pass element typeinfo ?
     if (useti) {
         TypeInfoDeclaration* ti = DtoDType(l->getType())->next->getTypeInfoDeclaration();
-        if (!ti->llvmValue) {
-            DtoForceConstInitDsymbol(ti);
-        }
-        Logger::cout() << "typeinfo decl: " << *ti->llvmValue << '\n';
+        DtoForceConstInitDsymbol(ti);
+        Logger::cout() << "typeinfo decl: " << *ti->getIrValue() << '\n';
 
         pt = fn->getFunctionType()->getParamType(2);
-        args.push_back(DtoBitCast(ti->llvmValue, pt));
+        args.push_back(DtoBitCast(ti->getIrValue(), pt));
     }
 
     return gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp");
--- a/gen/classes.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/classes.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -16,6 +16,8 @@
 #include "gen/runtime.h"
 #include "gen/dvalue.h"
 
+#include "ir/irstruct.h"
+
 //////////////////////////////////////////////////////////////////////////////////////////
 
 static void LLVM_AddBaseClassData(BaseClasses* bcs)
@@ -24,9 +26,8 @@
     for (int j=0; j<bcs->dim; j++)
     {
         BaseClass* bc = (BaseClass*)(bcs->data[j]);
-        assert(bc);
         if (bc->base->isInterfaceDeclaration())
-            continue; // interfaces only has methods
+            continue; // interfaces only have methods
 
         LLVM_AddBaseClassData(&bc->base->baseclasses);
 
@@ -38,14 +39,6 @@
             VarDeclaration* v = (VarDeclaration*)(arr->data[k]);
             v->toObjFile();
         }
-
-        /*for (int k=0; k < bc->base->members->dim; k++) {
-            Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]);
-            if (dsym->isVarDeclaration())
-            {
-                dsym->toObjFile();
-            }
-        }*/
     }
 }
 
@@ -63,11 +56,11 @@
     assert(cd->type->ty == Tclass);
     TypeClass* ts = (TypeClass*)cd->type;
 
-    // make sure the IRStruct is created
-    IRStruct* irstruct = cd->llvmIRStruct;
+    // make sure the IrStruct is created
+    IrStruct* irstruct = cd->llvmIrStruct;
     if (!irstruct) {
-        irstruct = new IRStruct(ts);
-        cd->llvmIRStruct = irstruct;
+        irstruct = new IrStruct(ts);
+        cd->llvmIrStruct = irstruct;
     }
 
     // resolve the base class
@@ -75,7 +68,7 @@
         DtoResolveClass(cd->baseClass);
     }
 
-    // resolve interfaces
+    // resolve interface vtables
     if (cd->vtblInterfaces) {
         for (int i=0; i < cd->vtblInterfaces->dim; i++) {
             BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i];
@@ -111,7 +104,7 @@
         fieldtypes.push_back(ivtblTy);
 
         // add this interface to the map
-        IRInterface* iri = new IRInterface(b, isaStruct(itc->llvmVtblType->get()));
+        IrInterface* iri = new IrInterface(b, isaStruct(itc->llvmVtblType->get()));
         irstruct->interfaces.insert(std::make_pair(id, iri));
     }
 
@@ -140,14 +133,14 @@
         VarDeclaration* fieldinit = NULL;
         size_t fieldpad = 0;
         int idx = 0;
-        for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
+        for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
             // first iteration
             if (lastoffset == (unsigned)-1) {
                 lastoffset = i->first;
                 fieldtype = i->second.type;
                 fieldinit = i->second.var;
                 prevsize = getABITypeSize(fieldtype);
-                i->second.var->llvmFieldIndex = idx;
+                i->second.var->irField->index = idx;
             }
             // colliding offset?
             else if (lastoffset == i->first) {
@@ -157,15 +150,15 @@
                     prevsize = s;
                 }
                 cd->llvmHasUnions = true;
-                i->second.var->llvmFieldIndex = idx;
+                i->second.var->irField->index = idx;
             }
             // intersecting offset?
             else if (i->first < (lastoffset + prevsize)) {
                 size_t s = getABITypeSize(i->second.type);
                 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
                 cd->llvmHasUnions = true;
-                i->second.var->llvmFieldIndex = idx;
-                i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s;
+                i->second.var->irField->index = idx;
+                i->second.var->irField->indexOffset = (i->first - lastoffset) / s;
             }
             // fresh offset
             else {
@@ -185,7 +178,7 @@
                 fieldtype = i->second.type;
                 fieldinit = i->second.var;
                 prevsize = getABITypeSize(fieldtype);
-                i->second.var->llvmFieldIndex = idx;
+                i->second.var->irField->index = idx;
                 fieldpad = 0;
             }
         }
@@ -199,7 +192,7 @@
 
     /*
     // add field types
-    for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
+    for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
         fieldtypes.push_back(i->second.type);
     }
     */
@@ -307,8 +300,8 @@
     assert(cd->type->ty == Tclass);
     TypeClass* ts = (TypeClass*)cd->type;
 
-    assert(cd->llvmIRStruct);
-    IRStruct* irstruct = cd->llvmIRStruct;
+    assert(cd->llvmIrStruct);
+    IrStruct* irstruct = cd->llvmIrStruct;
 
     gIR->structs.push_back(irstruct);
     gIR->classes.push_back(cd);
@@ -318,56 +311,45 @@
         needs_definition = true;
     }
 
-    // interface vtables are emitted by the class implementing them
-    // also, interfaces have no static initializer
-    // also, abstract classes have no vtable
+    llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
+
+    // interfaces have no static initializer
+    // same goes for abstract classes
     if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
         // vtable
         std::string varname("_D");
         varname.append(cd->mangle());
         varname.append("6__vtblZ");
 
-        llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
-
         const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get());
         cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module);
+    }
 
-        // build interface info type
-        std::vector<const llvm::Type*> types;
-        // ClassInfo classinfo
-        ClassDeclaration* cd2 = ClassDeclaration::classinfo;
-        DtoResolveClass(cd2);
-        types.push_back(getPtrToType(cd2->type->llvmType->get()));
-        // void*[] vtbl
-        std::vector<const llvm::Type*> vtbltypes;
-        vtbltypes.push_back(DtoSize_t());
-        const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
-        vtbltypes.push_back(byteptrptrty);
-        types.push_back(llvm::StructType::get(vtbltypes));
-        // int offset
-        types.push_back(llvm::Type::Int32Ty);
-        // create type
-        const llvm::StructType* infoTy = llvm::StructType::get(types);
+    // get interface info type
+    const llvm::StructType* infoTy = DtoInterfaceInfoType();
 
-        // interface info array
-        if (cd->vtblInterfaces->dim > 0) {
-            // symbol name
-            std::string nam = "_D";
-            nam.append(cd->mangle());
-            nam.append("16__interfaceInfosZ");
-            // resolve array type
-            const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim);
-            // declare global
-            irstruct->interfaceInfosTy = arrTy;
-            irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
-        }
+    // interface info array
+    if (cd->vtblInterfaces->dim > 0) {
+        // symbol name
+        std::string nam = "_D";
+        nam.append(cd->mangle());
+        nam.append("16__interfaceInfosZ");
+        // resolve array type
+        const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim);
+        // declare global
+        irstruct->interfaceInfosTy = arrTy;
+        irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
+    }
 
+    // interfaces have no static initializer
+    // same goes for abstract classes
+    if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
         // interface vtables
         unsigned idx = 0;
-        for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
+        for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
         {
             ClassDeclaration* id = i->first;
-            IRInterface* iri = i->second;
+            IrInterface* iri = i->second;
 
             std::string nam("_D");
             nam.append(cd->mangle());
@@ -377,7 +359,6 @@
 
             assert(iri->vtblTy);
             iri->vtbl = new llvm::GlobalVariable(iri->vtblTy, true, _linkage, 0, nam, gIR->module);
-            iri->infoTy = infoTy;
             llvm::Constant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)};
             iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2);
             idx++;
@@ -420,7 +401,7 @@
     Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
     LOG_SCOPE;
 
-    IRStruct* irstruct = cd->llvmIRStruct;
+    IrStruct* irstruct = cd->llvmIrStruct;
     gIR->structs.push_back(irstruct);
     gIR->classes.push_back(cd);
 
@@ -431,12 +412,12 @@
     const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get());
 
     // make sure each offset knows its default initializer
-    for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
+    for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
     {
-        IRStruct::Offset* so = &i->second;
+        IrStruct::Offset* so = &i->second;
         llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
         so->init = finit;
-        so->var->llvmConstInit = finit;
+        so->var->irField->constInit = finit;
     }
 
     // fill out fieldtypes/inits
@@ -465,9 +446,11 @@
     size_t dataoffset = 2;
 
     // next comes interface vtables
-    for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
+    const llvm::StructType* infoTy = DtoInterfaceInfoType();
+    for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
     {
-        IRInterface* iri = i->second;
+        IrInterface* iri = i->second;
+        iri->infoTy = infoTy;
         if (cd->isAbstract())
         {
             fieldinits.push_back(llvm::Constant::getNullValue(iri->vtblTy));
@@ -482,7 +465,7 @@
 
     /*
     // rest
-    for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
+    for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
         Logger::println("adding fieldinit for: %s", i->second.var->toChars());
         fieldinits.push_back(i->second.init);
     }
@@ -493,7 +476,7 @@
     for (size_t i=0; i<nfi; ++i) {
         llvm::Constant* c;
         if (irstruct->defaultFields[i] != NULL) {
-            c = irstruct->defaultFields[i]->llvmConstInit;
+            c = irstruct->defaultFields[i]->irField->constInit;
             assert(c);
         }
         else {
@@ -535,8 +518,8 @@
 
             if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
                 DtoForceDeclareDsymbol(fd);
-                assert(fd->llvmValue);
-                llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
+                assert(fd->irFunc->func);
+                llvm::Constant* c = llvm::cast<llvm::Constant>(fd->irFunc->func);
                 // cast if necessary (overridden method)
                 if (c->getType() != vtbltype->getElementType(k))
                     c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k));
@@ -568,30 +551,34 @@
         // create interface vtable const initalizers
         int idx = 2;
         int idxScale = PTRSIZE;
-        for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
+        for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
         {
             ClassDeclaration* id = i->first;
             assert(id->type->ty == Tclass);
             TypeClass* its = (TypeClass*)id->type;
 
-            IRInterface* iri = i->second;
+            IrInterface* iri = i->second;
             BaseClass* b = iri->base;
 
             const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get());
 
             // generate interface info initializer
             std::vector<llvm::Constant*> infoInits;
+
             // classinfo
             assert(id->llvmClass);
             llvm::Constant* c = id->llvmClass;
             infoInits.push_back(c);
+
             // vtbl
             const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
             c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
             c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c);
             infoInits.push_back(c);
+
             // offset
             infoInits.push_back(DtoConstInt(idx*idxScale));
+
             // create interface info initializer constant
             iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
 
@@ -608,8 +595,9 @@
                 FuncDeclaration* fd = dsym->isFuncDeclaration();
                 assert(fd);
                 DtoForceDeclareDsymbol(fd);
-                assert(fd->llvmValue);
-                llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
+                assert(fd->irFunc->func);
+                llvm::Constant* c = llvm::cast<llvm::Constant>(fd->irFunc->func);
+
                 // we have to bitcast, as the type created in ResolveClass expects a different this type
                 c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k));
                 iinits.push_back(c);
@@ -629,7 +617,39 @@
 
             idx++;
         }
-    } // !abstract
+    }
+    // we always generate interfaceinfos as best we can
+    else
+    {
+        for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
+        {
+            ClassDeclaration* id = i->first;
+            assert(id->type->ty == Tclass);
+            TypeClass* its = (TypeClass*)id->type;
+
+            IrInterface* iri = i->second;
+            BaseClass* b = iri->base;
+
+            // generate interface info initializer
+            std::vector<llvm::Constant*> infoInits;
+
+            // classinfo
+            assert(id->llvmClass);
+            llvm::Constant* c = id->llvmClass;
+            infoInits.push_back(c);
+
+            // vtbl
+            const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
+            c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty));
+            infoInits.push_back(c);
+
+            // offset
+            infoInits.push_back(DtoConstInt(0));
+
+            // create interface info initializer constant
+            iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
+        }
+    }
 
     gIR->classes.pop_back();
     gIR->structs.pop_back();
@@ -658,11 +678,11 @@
             cd->llvmVtbl->setInitializer(cd->llvmConstVtbl);
 
             // initialize interface vtables
-            IRStruct* irstruct = cd->llvmIRStruct;
+            IrStruct* irstruct = cd->llvmIrStruct;
             std::vector<llvm::Constant*> infoInits;
-            for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
+            for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
             {
-                IRInterface* iri = i->second;
+                IrInterface* iri = i->second;
                 iri->vtbl->setInitializer(iri->vtblInit);
                 infoInits.push_back(iri->infoInit);
             }
@@ -711,7 +731,7 @@
         LOG_SCOPE;
         DValue* thisval = newexp->thisexp->toElem(gIR);
         size_t idx = 2;
-        idx += tc->sym->llvmIRStruct->interfaces.size();
+        idx += tc->sym->llvmIrStruct->interfaces.size();
         llvm::Value* dst = thisval->getRVal();
         llvm::Value* src = DtoGEPi(mem,0,idx,"tmp");
         Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
@@ -723,10 +743,10 @@
         Logger::println("Resolving nested context");
         LOG_SCOPE;
         size_t idx = 2;
-        idx += tc->sym->llvmIRStruct->interfaces.size();
-        llvm::Value* nest = gIR->func()->decl->llvmNested;
+        idx += tc->sym->llvmIrStruct->interfaces.size();
+        llvm::Value* nest = gIR->func()->decl->irFunc->nestedVar;
         if (!nest)
-            nest = gIR->func()->decl->llvmThisVar;
+            nest = gIR->func()->decl->irFunc->thisVar;
         assert(nest);
         llvm::Value* gep = DtoGEPi(mem,0,idx,"tmp");
         nest = DtoBitCast(nest, gep->getType()->getContainedType(0));
@@ -792,7 +812,7 @@
 
     assert(ctor);
     DtoForceDeclareDsymbol(ctor);
-    llvm::Function* fn = llvm::cast<llvm::Function>(ctor->llvmValue);
+    llvm::Function* fn = ctor->irFunc->func;
     TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type);
 
     std::vector<llvm::Value*> ctorargs;
@@ -822,8 +842,8 @@
     for (size_t i=0; i<arr->dim; i++)
     {
         FuncDeclaration* fd = (FuncDeclaration*)arr->data[i];
-        assert(fd->llvmValue);
-        new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb());
+        assert(fd->irFunc->func);
+        new llvm::CallInst(fd->irFunc->func, instance, "", gIR->scopebb());
     }
 }
 
@@ -1031,37 +1051,37 @@
 
     unsigned dataoffset = 2 + cd->vtblInterfaces->dim;
 
-    IRStruct* irstruct = cd->llvmIRStruct;
-    for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
+    IrStruct* irstruct = cd->llvmIrStruct;
+    for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
     //for (unsigned i=0; i<cd->fields.dim; ++i) {
         //VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i];
         VarDeclaration* vd = i->second.var;
         assert(vd);
         Type* vdtype = DtoDType(vd->type);
         Logger::println("found %u type %s", vd->offset, vdtype->toChars());
-        assert(vd->llvmFieldIndex >= 0);
+        assert(vd->irField->index >= 0);
         if (os == vd->offset && vdtype == t) {
-            idxs.push_back(vd->llvmFieldIndex + dataoffset);
+            idxs.push_back(vd->irField->index + dataoffset);
             Logger::cout() << "indexing: " << *ptr << '\n';
             ptr = DtoGEP(ptr, idxs, "tmp");
             if (ptr->getType() != llt)
                 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
             Logger::cout() << "indexing: " << *ptr << '\n';
-            if (vd->llvmFieldIndexOffset)
-                ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
+            if (vd->irField->indexOffset)
+                ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
             Logger::cout() << "indexing: " << *ptr << '\n';
             return ptr;
         }
         else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
             TypeStruct* ts = (TypeStruct*)vdtype;
             StructDeclaration* ssd = ts->sym;
-            idxs.push_back(vd->llvmFieldIndex + dataoffset);
-            if (vd->llvmFieldIndexOffset) {
+            idxs.push_back(vd->irField->index + dataoffset);
+            if (vd->irField->indexOffset) {
                 Logger::println("has union field offset");
                 ptr = DtoGEP(ptr, idxs, "tmp");
                 if (ptr->getType() != llt)
                     ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
-                ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
+                ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
                 std::vector<unsigned> tmp;
                 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
             }
@@ -1153,7 +1173,7 @@
     vd->type->getTypeInfo(NULL);
     assert(vd->type->vtinfo);
     DtoForceDeclareDsymbol(vd->type->vtinfo);
-    llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue);
+    llvm::Constant* c = isaConstant(vd->type->vtinfo->getIrValue());
 
     const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get());
     //Logger::cout() << "tiTy = " << *tiTy << '\n';
@@ -1230,8 +1250,8 @@
     else if (cd->dtors.dim == 1) {
         DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
         DtoForceDeclareDsymbol(d);
-        assert(d->llvmValue);
-        return llvm::ConstantExpr::getBitCast(isaConstant(d->llvmValue), getPtrToType(llvm::Type::Int8Ty));
+        assert(d->irFunc->func);
+        return llvm::ConstantExpr::getBitCast(isaConstant(d->irFunc->func), getPtrToType(llvm::Type::Int8Ty));
     }
 
     std::string gname("_D");
@@ -1249,8 +1269,8 @@
     {
         DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i];
         DtoForceDeclareDsymbol(d);
-        assert(d->llvmValue);
-        builder.CreateCall(d->llvmValue, thisptr);
+        assert(d->irFunc->func);
+        builder.CreateCall(d->irFunc->func, thisptr);
     }
     builder.CreateRetVoid();
 
@@ -1380,7 +1400,7 @@
     inits.push_back(c);
 
     // interfaces array
-    IRStruct* irstruct = cd->llvmIRStruct;
+    IrStruct* irstruct = cd->llvmIrStruct;
     if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) {
         c = cinfo->llvmConstInit->getOperand(5);
     }
@@ -1446,7 +1466,7 @@
     // default constructor
     if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) {
         DtoForceDeclareDsymbol(cd->defaultCtor);
-        c = isaConstant(cd->defaultCtor->llvmValue);
+        c = isaConstant(cd->defaultCtor->irFunc->func);
         const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType();
         c = llvm::ConstantExpr::getBitCast(c, toTy);
     }
--- a/gen/functions.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/functions.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -232,7 +232,7 @@
     llvm::Function* func = llvm::dyn_cast<llvm::Function>(fn);
     assert(func);
     assert(func->isIntrinsic());
-    fdecl->llvmValue = func;
+    fdecl->irFunc->func = func;
     return func;
 }
 
@@ -257,7 +257,7 @@
     Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars());
     LOG_SCOPE;
 
-    if (fdecl->llvmRunTimeHack) {
+    if (fdecl->runTimeHack) {
         gIR->declareList.push_back(fdecl);
         TypeFunction* tf = (TypeFunction*)fdecl->type;
         tf->llvmRetInPtr = DtoIsPassedByRef(tf->next);
@@ -309,10 +309,12 @@
         fatal();
     }
 
-    if (fdecl->llvmRunTimeHack) {
+    if (fdecl->runTimeHack) {
         Logger::println("runtime hack func chars: %s", fdecl->toChars());
-        if (!fdecl->llvmValue)
-            fdecl->llvmValue = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars());
+        if (!fdecl->irFunc) {
+            fdecl->irFunc = new IrFunction(fdecl);
+            fdecl->irFunc->func = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars());
+        }
         return;
     }
 
@@ -323,8 +325,8 @@
     else if (fdecl->llvmInternal == LLVMva_start)
         declareOnly = true;
 
-    if (!fdecl->llvmIRFunc) {
-        fdecl->llvmIRFunc = new IRFunction(fdecl);
+    if (!fdecl->irFunc) {
+        fdecl->irFunc = new IrFunction(fdecl);
     }
 
     // mangled name
@@ -351,7 +353,7 @@
         assert(func->getFunctionType() == functype);
 
     // add func to IRFunc
-    fdecl->llvmIRFunc->func = func;
+    fdecl->irFunc->func = func;
 
     // calling convention
     if (!vafunc && fdecl->llvmInternal != LLVMintrinsic)
@@ -372,7 +374,7 @@
         func->setCallingConv(llvm::CallingConv::C);
     }
 
-    fdecl->llvmValue = func;
+    fdecl->irFunc->func = func;
     assert(llvm::isa<llvm::FunctionType>(f->llvmType->get()));
 
     // main
@@ -394,22 +396,22 @@
     int k = 0;
     if (f->llvmRetInPtr) {
         iarg->setName("retval");
-        fdecl->llvmRetArg = iarg;
+        fdecl->irFunc->retArg = iarg;
         ++iarg;
     }
     if (f->llvmUsesThis) {
         iarg->setName("this");
-        fdecl->llvmThisVar = iarg;
-        assert(fdecl->llvmThisVar);
+        fdecl->irFunc->thisVar = iarg;
+        assert(fdecl->irFunc->thisVar);
         ++iarg;
     }
 
     if (f->linkage == LINKd && f->varargs == 1) {
         iarg->setName("_arguments");
-        fdecl->llvmArguments = iarg;
+        fdecl->irFunc->_arguments = iarg;
         ++iarg;
         iarg->setName("_argptr");
-        fdecl->llvmArgPtr = iarg;
+        fdecl->irFunc->_argptr = iarg;
         ++iarg;
     }
 
@@ -420,7 +422,9 @@
         //Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident);
         if (arg && arg->ident != 0) {
             if (arg->vardecl) {
-                arg->vardecl->llvmValue = iarg;
+                assert(!arg->vardecl->irLocal);
+                arg->vardecl->irLocal = new IrLocal(arg->vardecl);
+                arg->vardecl->irLocal->value = iarg;
             }
             iarg->setName(arg->ident->toChars());
         }
@@ -458,14 +462,14 @@
         if (!mo->llvmCompileUnit) {
             mo->llvmCompileUnit = DtoDwarfCompileUnit(mo,false);
         }
-        fd->llvmDwarfSubProgram = DtoDwarfSubProgram(fd, mo->llvmCompileUnit);
+        fd->irFunc->dwarfSubProg = DtoDwarfSubProgram(fd, mo->llvmCompileUnit);
     }
 
     Type* t = DtoDType(fd->type);
     TypeFunction* f = (TypeFunction*)t;
     assert(f->llvmType);
 
-    llvm::Function* func = fd->llvmIRFunc->func;
+    llvm::Function* func = fd->irFunc->func;
     const llvm::FunctionType* functype = func->getFunctionType();
 
     // only members of the current module or template instances maybe be defined
@@ -477,8 +481,8 @@
         if (fd->fbody != 0)
         {
             Logger::println("Doing function body for: %s", fd->toChars());
-            assert(fd->llvmIRFunc);
-            gIR->functions.push_back(fd->llvmIRFunc);
+            assert(fd->irFunc);
+            gIR->functions.push_back(fd->irFunc);
 
             if (fd->isMain())
                 gIR->emitMain = true;
@@ -496,7 +500,8 @@
                 // need result variable? (not nested)
                 if (fd->vresult && !fd->vresult->nestedref) {
                     Logger::println("non-nested vresult value");
-                    fd->vresult->llvmValue = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
+                    fd->vresult->irLocal = new IrLocal(fd->vresult);
+                    fd->vresult->irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
                 }
 
                 // give arguments storage
@@ -505,16 +510,16 @@
                     Argument* arg = Argument::getNth(f->parameters, i);
                     if (arg && arg->vardecl) {
                         VarDeclaration* vd = arg->vardecl;
-                        if (!vd->llvmNeedsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
+                        if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
                             continue;
-                        llvm::Value* a = vd->llvmValue;
+                        llvm::Value* a = vd->irLocal->value;
                         assert(a);
                         std::string s(a->getName());
                         Logger::println("giving argument '%s' storage", s.c_str());
                         s.append("_storage");
                         llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
                         gIR->ir->CreateStore(a,v);
-                        vd->llvmValue = v;
+                        vd->irLocal->value = v;
                     }
                     else {
                         Logger::attention(fd->loc, "some unknown argument: %s", arg ? arg->toChars() : 0);
@@ -527,29 +532,32 @@
                 llvm::Value* parentNested = NULL;
                 if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) {
                     if (!fd->isStatic()) // huh?
-                        parentNested = fd2->llvmNested;
+                        parentNested = fd2->irFunc->nestedVar;
                 }
 
                 // need result variable? (nested)
                 if (fd->vresult && fd->vresult->nestedref) {
                     Logger::println("nested vresult value: %s", fd->vresult->toChars());
-                    fd->llvmNestedVars.insert(fd->vresult);
+                    fd->nestedVars.insert(fd->vresult);
                 }
 
                 // construct nested variables struct
-                if (!fd->llvmNestedVars.empty() || parentNested) {
+                if (!fd->nestedVars.empty() || parentNested) {
                     std::vector<const llvm::Type*> nestTypes;
                     int j = 0;
                     if (parentNested) {
                         nestTypes.push_back(parentNested->getType());
                         j++;
                     }
-                    for (std::set<VarDeclaration*>::iterator i=fd->llvmNestedVars.begin(); i!=fd->llvmNestedVars.end(); ++i) {
+                    for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
                         VarDeclaration* vd = *i;
-                        vd->llvmNestedIndex = j++;
+                        if (!vd->irLocal)
+                            vd->irLocal = new IrLocal(vd);
+                        vd->irLocal->nestedIndex = j++;
                         if (vd->isParameter()) {
-                            assert(vd->llvmValue);
-                            nestTypes.push_back(vd->llvmValue->getType());
+                            
+                            assert(vd->irLocal->value);
+                            nestTypes.push_back(vd->irLocal->value->getType());
                         }
                         else {
                             nestTypes.push_back(DtoType(vd->type));
@@ -557,17 +565,18 @@
                     }
                     const llvm::StructType* nestSType = llvm::StructType::get(nestTypes);
                     Logger::cout() << "nested var struct has type:" << *nestSType << '\n';
-                    fd->llvmNested = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
+                    fd->irFunc->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
                     if (parentNested) {
-                        assert(fd->llvmThisVar);
-                        llvm::Value* ptr = gIR->ir->CreateBitCast(fd->llvmThisVar, parentNested->getType(), "tmp");
-                        gIR->ir->CreateStore(ptr, DtoGEPi(fd->llvmNested, 0,0, "tmp"));
+                        assert(fd->irFunc->thisVar);
+                        llvm::Value* ptr = gIR->ir->CreateBitCast(fd->irFunc->thisVar, parentNested->getType(), "tmp");
+                        gIR->ir->CreateStore(ptr, DtoGEPi(fd->irFunc->nestedVar, 0,0, "tmp"));
                     }
-                    for (std::set<VarDeclaration*>::iterator i=fd->llvmNestedVars.begin(); i!=fd->llvmNestedVars.end(); ++i) {
+                    for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
                         VarDeclaration* vd = *i;
                         if (vd->isParameter()) {
-                            gIR->ir->CreateStore(vd->llvmValue, DtoGEPi(fd->llvmNested, 0, vd->llvmNestedIndex, "tmp"));
-                            vd->llvmValue = fd->llvmNested;
+                            assert(vd->irLocal);
+                            gIR->ir->CreateStore(vd->irLocal->value, DtoGEPi(fd->irFunc->nestedVar, 0, vd->irLocal->nestedIndex, "tmp"));
+                            vd->irLocal->value = fd->irFunc->nestedVar;
                         }
                     }
                 }
@@ -575,9 +584,9 @@
                 // copy _argptr to a memory location
                 if (f->linkage == LINKd && f->varargs == 1)
                 {
-                    llvm::Value* argptrmem = new llvm::AllocaInst(fd->llvmArgPtr->getType(), "_argptrmem", gIR->topallocapoint());
-                    new llvm::StoreInst(fd->llvmArgPtr, argptrmem, gIR->scopebb());
-                    fd->llvmArgPtr = argptrmem;
+                    llvm::Value* argptrmem = new llvm::AllocaInst(fd->irFunc->_argptr->getType(), "_argptrmem", gIR->topallocapoint());
+                    new llvm::StoreInst(fd->irFunc->_argptr, argptrmem, gIR->scopebb());
+                    fd->irFunc->_argptr = argptrmem;
                 }
 
                 // output function body
--- a/gen/irstate.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/irstate.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -40,7 +40,7 @@
     ir.state = this;
 }
 
-IRFunction* IRState::func()
+IrFunction* IRState::func()
 {
     assert(!functions.empty() && "Function stack is empty!");
     return functions.back();
@@ -64,7 +64,7 @@
     return functions.back()->allocapoint;
 }
 
-IRStruct* IRState::topstruct()
+IrStruct* IRState::topstruct()
 {
     assert(!structs.empty() && "Struct vector is empty!");
     return structs.back();
@@ -101,32 +101,6 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-IRStruct::IRStruct(Type* t)
- : recty((t->llvmType != NULL) ? *t->llvmType : llvm::OpaqueType::get())
-{
-    type = t;
-    defined = false;
-    constinited = false;
-    interfaceInfosTy = NULL;
-    interfaceInfos = NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-IRFinally::IRFinally()
-{
-    bb = 0;
-    retbb = 0;
-}
-
-IRFinally::IRFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb)
-{
-    bb = b;
-    retbb = rb;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
 LLVMBuilder* IRBuilderHelper::operator->()
 {
     LLVMBuilder& b = state->scope().builder;
@@ -136,20 +110,6 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-IRFunction::IRFunction(FuncDeclaration* fd)
-{
-    decl = fd;
-    Type* t = DtoDType(fd->type);
-    assert(t->ty == Tfunction);
-    type = (TypeFunction*)t;
-    func = NULL;
-    allocapoint = NULL;
-    finallyretval = NULL;
-    defined = false;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
 IRExp::IRExp()
 {
     e1 = e2 = NULL;
@@ -162,11 +122,3 @@
     e2 = r;
     v = val;
 }
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-IRGlobal::IRGlobal(VarDeclaration* v) :
-    type(llvm::OpaqueType::get())
-{
-    var = v;
-}
--- a/gen/irstate.h	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/irstate.h	Thu Jan 17 03:15:12 2008 +0100
@@ -1,15 +1,16 @@
 #ifndef LLVMDC_GEN_IRSTATE_H
 #define LLVMDC_GEN_IRSTATE_H
 
-#include <stack>
 #include <vector>
-#include <deque>
-#include <map>
 #include <list>
 
 #include "root.h"
 #include "aggregate.h"
 
+#include "ir/irfunction.h"
+#include "ir/irstruct.h"
+#include "ir/irvar.h"
+
 // global ir state for current module
 struct IRState;
 extern IRState* gIR;
@@ -23,13 +24,6 @@
 struct TypeStruct;
 struct BaseClass;
 
-/*
-struct LLVMValue
-{
-    std::vector<llvm::Value*> vals;
-};
-*/
-
 // represents a scope
 struct IRScope
 {
@@ -41,94 +35,6 @@
     IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e);
 };
 
-struct IRInterface : Object
-{
-    BaseClass* base;
-    ClassDeclaration* decl;
-
-    const llvm::StructType* vtblTy;
-    llvm::ConstantStruct* vtblInit;
-    llvm::GlobalVariable* vtbl;
-
-    const llvm::StructType* infoTy;
-    llvm::ConstantStruct* infoInit;
-    llvm::Constant* info;
-
-    IRInterface(BaseClass* b, const llvm::StructType* vt)
-    {
-        base = b;
-        decl = b->base;
-        vtblTy = vt;
-        vtblInit = NULL;
-        vtbl = NULL;
-        infoTy = NULL;
-        infoInit = NULL;
-        info = NULL;
-    }
-};
-
-// represents a struct or class
-struct IRStruct : Object
-{
-    struct Offset
-    {
-        VarDeclaration* var;
-        const llvm::Type* type;
-        llvm::Constant* init;
-
-        Offset(VarDeclaration* v, const llvm::Type* ty)
-        : var(v), type(ty), init(NULL) {}
-    };
-
-    typedef std::multimap<unsigned, Offset> OffsetMap;
-    typedef std::vector<VarDeclaration*> VarDeclVector;
-    typedef std::map<ClassDeclaration*, IRInterface*> InterfaceMap;
-    typedef InterfaceMap::iterator InterfaceIter;
-
-public:
-    IRStruct(Type*);
-
-    Type* type;
-    llvm::PATypeHolder recty;
-    OffsetMap offsets;
-    VarDeclVector defaultFields;
-
-    InterfaceMap interfaces;
-    const llvm::ArrayType* interfaceInfosTy;
-    llvm::GlobalVariable* interfaceInfos;
-
-    bool defined;
-    bool constinited;
-};
-
-// represents a finally block
-struct IRFinally
-{
-    llvm::BasicBlock* bb;
-    llvm::BasicBlock* retbb;
-
-    IRFinally();
-    IRFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb);
-};
-
-// represents a function
-struct IRFunction : Object
-{
-    llvm::Function* func;
-    llvm::Instruction* allocapoint;
-    FuncDeclaration* decl;
-    TypeFunction* type;
-
-    // finally blocks
-    typedef std::vector<IRFinally> FinallyVec;
-    FinallyVec finallys;
-    llvm::Value* finallyretval;
-
-    bool defined;
-
-    IRFunction(FuncDeclaration*);
-};
-
 struct IRBuilderHelper
 {
     IRState* state;
@@ -144,15 +50,6 @@
     IRExp(Expression* l, Expression* r, DValue* val);
 };
 
-// represents a global variable
-struct IRGlobal : Object
-{
-    VarDeclaration* var;
-    llvm::PATypeHolder type;
-
-    IRGlobal(VarDeclaration* v);
-};
-
 // represents the module
 struct IRState
 {
@@ -163,18 +60,18 @@
     llvm::Module* module;
 
     // functions
-    typedef std::vector<IRFunction*> FunctionVector;
+    typedef std::vector<IrFunction*> FunctionVector;
     FunctionVector functions;
-    IRFunction* func();
+    IrFunction* func();
 
     llvm::Function* topfunc();
     TypeFunction* topfunctype();
     llvm::Instruction* topallocapoint();
 
     // structs
-    typedef std::vector<IRStruct*> StructVector;
+    typedef std::vector<IrStruct*> StructVector;
     StructVector structs;
-    IRStruct* topstruct();
+    IrStruct* topstruct();
 
     // classes TODO move into IRClass
     typedef std::vector<ClassDeclaration*> ClassDeclVec;
--- a/gen/statements.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/statements.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -25,6 +25,8 @@
 #include "gen/todebug.h"
 #include "gen/dvalue.h"
 
+#include "ir/irfunction.h"
+
 //////////////////////////////////////////////////////////////////////////////
 
 void CompoundStatement::toIR(IRState* p)
@@ -57,13 +59,13 @@
         if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
             assert(DtoIsPassedByRef(exptype));
 
-            IRFunction* f = p->func();
+            IrFunction* f = p->func();
             assert(f->type->llvmRetInPtr);
-            assert(f->decl->llvmRetArg);
+            assert(f->decl->irFunc->retArg);
 
             if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum);
 
-            DValue* rvar = new DVarValue(f->type->next, f->decl->llvmRetArg, true);
+            DValue* rvar = new DVarValue(f->type->next, f->decl->irFunc->retArg, true);
 
             p->exps.push_back(IRExp(NULL,exp,rvar));
             DValue* e = exp->toElem(p);
@@ -72,7 +74,7 @@
             if (!e->inPlace())
                 DtoAssign(rvar, e);
 
-            IRFunction::FinallyVec& fin = f->finallys;
+            IrFunction::FinallyVec& fin = f->finallys;
             if (fin.empty()) {
                 if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
                 new llvm::ReturnInst(p->scopebb());
@@ -88,7 +90,7 @@
             delete e;
             Logger::cout() << "return value is '" <<*v << "'\n";
 
-            IRFunction::FinallyVec& fin = p->func()->finallys;
+            IrFunction::FinallyVec& fin = p->func()->finallys;
             if (fin.empty()) {
                 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
                 new llvm::ReturnInst(v, p->scopebb());
@@ -105,7 +107,7 @@
     else
     {
         if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
-            IRFunction::FinallyVec& fin = p->func()->finallys;
+            IrFunction::FinallyVec& fin = p->func()->finallys;
             if (fin.empty()) {
                 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
                 new llvm::ReturnInst(p->scopebb());
@@ -425,8 +427,8 @@
 
     // do the try block
     p->scope() = IRScope(trybb,finallybb);
-    gIR->func()->finallys.push_back(IRFinally(finallybb,finallyretbb));
-    IRFinally& fin = p->func()->finallys.back();
+    gIR->func()->finallys.push_back(IrFinally(finallybb,finallyretbb));
+    IrFinally& fin = p->func()->finallys.back();
 
     assert(body);
     body->toIR(p);
@@ -453,7 +455,7 @@
     // terminate finally (return path)
     size_t nfin = p->func()->finallys.size();
     if (nfin > 1) {
-        IRFinally& ofin = p->func()->finallys[nfin-2];
+        IrFinally& ofin = p->func()->finallys[nfin-2];
         p->ir->CreateBr(ofin.retbb);
     }
     // no outer
@@ -793,7 +795,13 @@
     // key
     const llvm::Type* keytype = key ? DtoType(key->type) : DtoSize_t();
     llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint());
-    if (key) key->llvmValue = keyvar;
+    if (key)
+    {
+        //key->llvmValue = keyvar;
+        assert(!key->irLocal);
+        key->irLocal = new IrLocal(key);
+        key->irLocal->value = keyvar;
+    }
     llvm::Value* zerokey = llvm::ConstantInt::get(keytype,0,false);
 
     // value
@@ -801,6 +809,8 @@
     llvm::Value* valvar = NULL;
     if (!value->isRef() && !value->isOut())
         valvar = new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint());
+    assert(!value->irLocal);
+    value->irLocal = new IrLocal(value);
 
     // what to iterate
     DValue* aggrval = aggr->toElem(p);
@@ -896,15 +906,15 @@
     llvm::Constant* zero = llvm::ConstantInt::get(keytype,0,false);
     llvm::Value* loadedKey = p->ir->CreateLoad(keyvar,"tmp");
     if (aggrtype->ty == Tsarray)
-        value->llvmValue = DtoGEP(val,zero,loadedKey,"tmp");
+        value->irLocal->value = DtoGEP(val,zero,loadedKey,"tmp");
     else if (aggrtype->ty == Tarray)
-        value->llvmValue = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb());
+        value->irLocal->value = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb());
 
     if (!value->isRef() && !value->isOut()) {
         DValue* dst = new DVarValue(value->type, valvar, true);
-        DValue* src = new DVarValue(value->type, value->llvmValue, true);
+        DValue* src = new DVarValue(value->type, value->irLocal->value, true);
         DtoAssign(dst, src);
-        value->llvmValue = valvar;
+        value->irLocal->value = valvar;
     }
 
     // emit body
@@ -982,7 +992,7 @@
     assert(body);
 
     DValue* e = exp->toElem(p);
-    wthis->llvmValue = e->getRVal();
+    wthis->irLocal->value = e->getRVal();
     delete e;
 
     body->toIR(p);
--- a/gen/structs.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/structs.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -13,6 +13,8 @@
 #include "gen/logger.h"
 #include "gen/structs.h"
 
+#include "ir/irstruct.h"
+
 //////////////////////////////////////////////////////////////////////////////////////////
 
 const llvm::Type* DtoStructType(Type* t)
@@ -93,7 +95,7 @@
         VarDeclaration* vd = (VarDeclaration*)si->vars.data[i];
         assert(vd);
         llvm::Constant* v = DtoConstInitializer(vd->type, ini);
-        inits.push_back(DUnionIdx(vd->llvmFieldIndex, vd->llvmFieldIndexOffset, v));
+        inits.push_back(DUnionIdx(vd->irField->index, vd->irField->indexOffset, v));
     }
 
     DtoConstInitStruct((StructDeclaration*)si->ad);
@@ -121,26 +123,26 @@
         VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i];
         Type* vdtype = DtoDType(vd->type);
         Logger::println("found %u type %s", vd->offset, vdtype->toChars());
-        assert(vd->llvmFieldIndex >= 0);
+        assert(vd->irField->index >= 0);
         if (os == vd->offset && vdtype == t) {
-            idxs.push_back(vd->llvmFieldIndex);
+            idxs.push_back(vd->irField->index);
             ptr = DtoGEP(ptr, idxs, "tmp");
             if (ptr->getType() != llt)
                 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
-            if (vd->llvmFieldIndexOffset)
-                ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
+            if (vd->irField->indexOffset)
+                ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
             return ptr;
         }
         else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
             TypeStruct* ts = (TypeStruct*)vdtype;
             StructDeclaration* ssd = ts->sym;
-            idxs.push_back(vd->llvmFieldIndex);
-            if (vd->llvmFieldIndexOffset) {
+            idxs.push_back(vd->irField->index);
+            if (vd->irField->indexOffset) {
                 Logger::println("has union field offset");
                 ptr = DtoGEP(ptr, idxs, "tmp");
                 if (ptr->getType() != llt)
                     ptr = DtoBitCast(ptr, llt);
-                ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
+                ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
                 std::vector<unsigned> tmp;
                 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
             }
@@ -176,8 +178,8 @@
 
     TypeStruct* ts = (TypeStruct*)DtoDType(sd->type);
 
-    IRStruct* irstruct = new IRStruct(ts);
-    sd->llvmIRStruct = irstruct;
+    IrStruct* irstruct = new IrStruct(ts);
+    sd->llvmIrStruct = irstruct;
     gIR->structs.push_back(irstruct);
 
     // fields
@@ -233,7 +235,7 @@
         VarDeclaration* fieldinit = NULL;
         size_t fieldpad = 0;
         int idx = 0;
-        for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
+        for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
             // first iteration
             if (lastoffset == (unsigned)-1) {
                 lastoffset = i->first;
@@ -241,7 +243,7 @@
                 fieldtype = i->second.type;
                 fieldinit = i->second.var;
                 prevsize = getABITypeSize(fieldtype);
-                i->second.var->llvmFieldIndex = idx;
+                i->second.var->irField->index = idx;
             }
             // colliding offset?
             else if (lastoffset == i->first) {
@@ -251,15 +253,15 @@
                     prevsize = s;
                 }
                 sd->llvmHasUnions = true;
-                i->second.var->llvmFieldIndex = idx;
+                i->second.var->irField->index = idx;
             }
             // intersecting offset?
             else if (i->first < (lastoffset + prevsize)) {
                 size_t s = getABITypeSize(i->second.type);
                 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
                 sd->llvmHasUnions = true;
-                i->second.var->llvmFieldIndex = idx;
-                i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s;
+                i->second.var->irField->index = idx;
+                i->second.var->irField->indexOffset = (i->first - lastoffset) / s;
             }
             // fresh offset
             else {
@@ -279,7 +281,7 @@
                 fieldtype = i->second.type;
                 fieldinit = i->second.var;
                 prevsize = getABITypeSize(fieldtype);
-                i->second.var->llvmFieldIndex = idx;
+                i->second.var->irField->index = idx;
                 fieldpad = 0;
             }
         }
@@ -349,16 +351,16 @@
     Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars());
     LOG_SCOPE;
 
-    IRStruct* irstruct = sd->llvmIRStruct;
+    IrStruct* irstruct = sd->llvmIrStruct;
     gIR->structs.push_back(irstruct);
 
     // make sure each offset knows its default initializer
-    for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
+    for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
     {
-        IRStruct::Offset* so = &i->second;
+        IrStruct::Offset* so = &i->second;
         llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
         so->init = finit;
-        so->var->llvmConstInit = finit;
+        so->var->irField->constInit = finit;
     }
 
     const llvm::StructType* structtype = isaStruct(sd->type->llvmType->get());
@@ -369,7 +371,7 @@
     for (size_t i=0; i<nfi; ++i) {
         llvm::Constant* c;
         if (irstruct->defaultFields[i] != NULL) {
-            c = irstruct->defaultFields[i]->llvmConstInit;
+            c = irstruct->defaultFields[i]->irField->constInit;
             assert(c);
         }
         else {
@@ -435,12 +437,12 @@
 DUnion::DUnion()
 {
     DUnionField* f = NULL;
-    IRStruct* topstruct = gIR->topstruct();
+    IrStruct* topstruct = gIR->topstruct();
     bool unions = false;
-    for (IRStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i)
+    for (IrStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i)
     {
         unsigned o = i->first;
-        IRStruct::Offset* so = &i->second;
+        IrStruct::Offset* so = &i->second;
         const llvm::Type* ft = so->init->getType();
         size_t sz = getABITypeSize(ft);
         if (f == NULL) { // new field
--- a/gen/todebug.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/todebug.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -164,14 +164,14 @@
 
 void DtoDwarfFuncStart(FuncDeclaration* fd)
 {
-    assert(fd->llvmDwarfSubProgram);
-    gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), dbgToArrTy(fd->llvmDwarfSubProgram));
+    assert(fd->irFunc->dwarfSubProg);
+    gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), dbgToArrTy(fd->irFunc->dwarfSubProg));
 }
 
 void DtoDwarfFuncEnd(FuncDeclaration* fd)
 {
-    assert(fd->llvmDwarfSubProgram);
-    gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), dbgToArrTy(fd->llvmDwarfSubProgram));
+    assert(fd->irFunc->dwarfSubProg);
+    gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), dbgToArrTy(fd->irFunc->dwarfSubProg));
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/toir.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/toir.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -57,12 +57,14 @@
                 DtoAnnotation(toChars());
 
             Logger::println("vdtype = %s", vd->type->toChars());
+
             // referenced by nested delegate?
             if (vd->nestedref) {
                 Logger::println("has nestedref set");
-                vd->llvmValue = p->func()->decl->llvmNested;
-                assert(vd->llvmValue);
-                assert(vd->llvmNestedIndex >= 0);
+                assert(vd->irLocal);
+                vd->irLocal->value = p->func()->decl->irFunc->nestedVar;
+                assert(vd->irLocal->value);
+                assert(vd->irLocal->nestedIndex >= 0);
             }
             // normal stack variable
             else {
@@ -70,14 +72,16 @@
                 const llvm::Type* lltype = DtoType(vd->type);
                 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
                 //allocainst->setAlignment(vd->type->alignsize()); // TODO
-                vd->llvmValue = allocainst;
+                assert(!vd->irLocal);
+                vd->irLocal = new IrLocal(vd);
+                vd->irLocal->value = allocainst;
             }
 
-            Logger::cout() << "llvm value for decl: " << *vd->llvmValue << '\n';
+            Logger::cout() << "llvm value for decl: " << *vd->irLocal->value << '\n';
             DValue* ie = DtoInitializer(vd->init);
         }
 
-        return new DVarValue(vd, vd->llvmValue, true);
+        return new DVarValue(vd, vd->getIrValue(), true);
     }
     // struct declaration
     else if (StructDeclaration* s = declaration->isStructDeclaration())
@@ -149,19 +153,19 @@
         if (vd->ident == Id::_arguments)
         {
             Logger::println("Id::_arguments");
-            if (!vd->llvmValue)
-                vd->llvmValue = p->func()->decl->llvmArguments;
-            assert(vd->llvmValue);
-            return new DVarValue(vd, vd->llvmValue, true);
+            if (!vd->getIrValue())
+                vd->getIrValue() = p->func()->decl->irFunc->_arguments;
+            assert(vd->getIrValue());
+            return new DVarValue(vd, vd->getIrValue(), true);
         }
         // _argptr
         else if (vd->ident == Id::_argptr)
         {
             Logger::println("Id::_argptr");
-            if (!vd->llvmValue)
-                vd->llvmValue = p->func()->decl->llvmArgPtr;
-            assert(vd->llvmValue);
-            return new DVarValue(vd, vd->llvmValue, true);
+            if (!vd->getIrValue())
+                vd->getIrValue() = p->func()->decl->irFunc->_argptr;
+            assert(vd->getIrValue());
+            return new DVarValue(vd, vd->getIrValue(), true);
         }
         // _dollar
         else if (vd->ident == Id::dollar)
@@ -176,13 +180,13 @@
         {
             Logger::println("TypeInfoDeclaration");
             DtoForceDeclareDsymbol(tid);
-            assert(tid->llvmValue);
+            assert(tid->getIrValue());
             const llvm::Type* vartype = DtoType(type);
             llvm::Value* m;
-            if (tid->llvmValue->getType() != getPtrToType(vartype))
-                m = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp");
+            if (tid->getIrValue()->getType() != getPtrToType(vartype))
+                m = p->ir->CreateBitCast(tid->getIrValue(), vartype, "tmp");
             else
-                m = tid->llvmValue;
+                m = tid->getIrValue();
             return new DVarValue(vd, m, true);
         }
         // classinfo
@@ -201,16 +205,16 @@
         // function parameter
         else if (vd->isParameter()) {
             Logger::println("function param");
-            if (!vd->llvmValue) {
+            if (!vd->getIrValue()) {
                 // TODO: determine this properly
                 // this happens when the DMD frontend generates by pointer wrappers for struct opEquals(S) and opCmp(S)
-                vd->llvmValue = &p->func()->func->getArgumentList().back();
+                vd->getIrValue() = &p->func()->func->getArgumentList().back();
             }
-            if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->llvmValue)) {
-                return new DVarValue(vd, vd->llvmValue, true);
+            if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->getIrValue())) {
+                return new DVarValue(vd, vd->getIrValue(), true);
             }
-            else if (llvm::isa<llvm::Argument>(vd->llvmValue)) {
-                return new DImValue(type, vd->llvmValue);
+            else if (llvm::isa<llvm::Argument>(vd->getIrValue())) {
+                return new DImValue(type, vd->getIrValue());
             }
             else assert(0);
         }
@@ -220,11 +224,11 @@
                 vd->toObjFile();
                 DtoConstInitGlobal(vd);
             }
-            if (!vd->llvmValue || vd->llvmValue->getType()->isAbstract()) {
+            if (!vd->getIrValue() || vd->getIrValue()->getType()->isAbstract()) {
                 Logger::println("global variable not resolved :/ %s", vd->toChars());
                 assert(0);
             }
-            return new DVarValue(vd, vd->llvmValue, true);
+            return new DVarValue(vd, vd->getIrValue(), true);
         }
     }
     else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
@@ -233,7 +237,7 @@
         if (fdecl->llvmInternal != LLVMva_arg) {// && fdecl->llvmValue == 0)
             DtoForceDeclareDsymbol(fdecl);
         }
-        return new DFuncValue(fdecl, fdecl->llvmValue);
+        return new DFuncValue(fdecl, fdecl->irFunc->func);
     }
     else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration())
     {
@@ -274,11 +278,11 @@
     else if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
     {
         DtoForceDeclareDsymbol(ti);
-        assert(ti->llvmValue);
+        assert(ti->getIrValue());
         const llvm::Type* vartype = DtoType(type);
-        llvm::Constant* m = isaConstant(ti->llvmValue);
+        llvm::Constant* m = isaConstant(ti->getIrValue());
         assert(m);
-        if (ti->llvmValue->getType() != getPtrToType(vartype))
+        if (ti->getIrValue()->getType() != getPtrToType(vartype))
             m = llvm::ConstantExpr::getBitCast(m, vartype);
         return m;
     }
@@ -974,7 +978,7 @@
             llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint());
         }
 
-        if (dfn && dfn->func && dfn->func->llvmRunTimeHack) {
+        if (dfn && dfn->func && dfn->func->runTimeHack) {
             const llvm::Type* rettype = getPtrToType(DtoType(type));
             if (llargs[j]->getType() != llfnty->getParamType(j)) {
                 Logger::println("llvmRunTimeHack==true - force casting return value param");
@@ -1075,8 +1079,8 @@
                 Expression* argexp = (Expression*)arguments->data[i];
                 TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration();
                 DtoForceDeclareDsymbol(tidecl);
-                assert(tidecl->llvmValue);
-                vtypeinfos.push_back(tidecl->llvmValue);
+                assert(tidecl->getIrValue());
+                vtypeinfos.push_back(tidecl->getIrValue());
                 llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp");
                 p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp"));
             }
@@ -1108,7 +1112,7 @@
                 }
 
                 // this hack is necessary :/
-                if (dfn && dfn->func && dfn->func->llvmRunTimeHack) {
+                if (dfn && dfn->func && dfn->func->runTimeHack) {
                     if (llfnty->getParamType(j) != NULL) {
                         if (llargs[j]->getType() != llfnty->getParamType(j)) {
                             Logger::println("llvmRunTimeHack==true - force casting argument");
@@ -1137,7 +1141,7 @@
     llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb());
     llvm::Value* retllval = (retinptr) ? llargs[0] : call;
 
-    if (retinptr && dfn && dfn->func && dfn->func->llvmRunTimeHack) {
+    if (retinptr && dfn && dfn->func && dfn->func->runTimeHack) {
         const llvm::Type* rettype = getPtrToType(DtoType(type));
         if (retllval->getType() != rettype) {
             Logger::println("llvmRunTimeHack==true - force casting return value");
@@ -1208,12 +1212,12 @@
             vd->toObjFile(); // TODO
         }
 
-        assert(vd->llvmValue);
+        assert(vd->getIrValue());
         Type* t = DtoDType(type);
         Type* tnext = DtoDType(t->next);
         Type* vdtype = DtoDType(vd->type);
 
-        llvm::Value* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->llvmValue;
+        llvm::Value* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->getIrValue();
         llvm::Value* varmem = 0;
 
         if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) {
@@ -1287,9 +1291,8 @@
         //Logger::println("FuncDeclaration");
         FuncDeclaration* fd = fv->func;
         assert(fd);
-        if (fd->llvmValue == 0)
-            DtoForceDeclareDsymbol(fd);
-        return new DFuncValue(fd, fd->llvmValue);
+        DtoForceDeclareDsymbol(fd);
+        return new DFuncValue(fd, fd->irFunc->func);
     }
     else if (DImValue* im = v->isIm()) {
         Logger::println("is immediate");
@@ -1394,7 +1397,7 @@
         // super call
         if (e1->op == TOKsuper) {
             DtoForceDeclareDsymbol(fdecl);
-            funcval = fdecl->llvmValue;
+            funcval = fdecl->irFunc->func;
             assert(funcval);
         }
         // normal virtual call
@@ -1415,7 +1418,7 @@
         // static call
         else {
             DtoForceDeclareDsymbol(fdecl);
-            funcval = fdecl->llvmValue;
+            funcval = fdecl->irFunc->func;
             assert(funcval);
             //assert(funcval->getType() == DtoType(fdecl->type));
         }
@@ -1438,7 +1441,7 @@
 
     if (VarDeclaration* vd = var->isVarDeclaration()) {
         llvm::Value* v;
-        v = p->func()->decl->llvmThisVar;
+        v = p->func()->decl->irFunc->thisVar;
         if (llvm::isa<llvm::AllocaInst>(v))
             v = new llvm::LoadInst(v, "tmp", p->scopebb());
         return new DThisValue(vd, v);
@@ -2187,7 +2190,7 @@
     if (DFuncValue* f = u->isFunc()) {
         //assert(f->vthis);
         //uval = f->vthis;
-        llvm::Value* nestvar = p->func()->decl->llvmNested;
+        llvm::Value* nestvar = p->func()->decl->irFunc->nestedVar;
         if (nestvar)
             uval = nestvar;
         else
@@ -2213,7 +2216,7 @@
     else if (func->toParent()->isInterfaceDeclaration())
         assert(0 && "TODO delegate to interface method");
     else
-        castfptr = func->llvmValue;
+        castfptr = func->irFunc->func;
 
     castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0));
     DtoStore(castfptr, fptr);
@@ -2440,7 +2443,7 @@
 
     llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb());
     const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0));
-    llvm::Value* llvmNested = p->func()->decl->llvmNested;
+    llvm::Value* llvmNested = p->func()->decl->irFunc->nestedVar;
     if (llvmNested == NULL) {
         llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty);
         p->ir->CreateStore(nullcontext, context);
@@ -2452,8 +2455,8 @@
 
     llvm::Value* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb());
 
-    assert(fd->llvmValue);
-    llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb());
+    assert(fd->irFunc->func);
+    llvm::Value* castfptr = new llvm::BitCastInst(fd->irFunc->func,fptr->getType()->getContainedType(0),"tmp",p->scopebb());
     new llvm::StoreInst(castfptr, fptr, p->scopebb());
 
     if (temp)
--- a/gen/tollvm.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/tollvm.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -2,7 +2,6 @@
 
 #include "gen/llvm.h"
 
-#include "mtype.h"
 #include "dsymbol.h"
 #include "aggregate.h"
 #include "declaration.h"
@@ -103,7 +102,7 @@
             // recursive or cyclic declaration
             if (!gIR->structs.empty())
             {
-                IRStruct* found = 0;
+                IrStruct* found = 0;
                 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
                 {
                     if (t == (*i)->type)
@@ -117,7 +116,7 @@
         TypeStruct* ts = (TypeStruct*)t;
         assert(ts->sym);
         DtoResolveDsymbol(ts->sym);
-        return ts->sym->llvmIRStruct->recty.get();//t->llvmType->get();
+        return ts->sym->llvmIrStruct->recty.get();//t->llvmType->get();
     }
 
     case Tclass:    {
@@ -125,7 +124,7 @@
             // recursive or cyclic declaration
             if (!gIR->structs.empty())
             {
-                IRStruct* found = 0;
+                IrStruct* found = 0;
                 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
                 {
                     if (t == (*i)->type)
@@ -140,7 +139,7 @@
         TypeClass* tc = (TypeClass*)t;
         assert(tc->sym);
         DtoResolveDsymbol(tc->sym);
-        return getPtrToType(tc->sym->llvmIRStruct->recty.get());//t->llvmType->get());
+        return getPtrToType(tc->sym->llvmIrStruct->recty.get());//t->llvmType->get());
     }
 
     // functions
@@ -687,7 +686,7 @@
     assert(p->isFuncDeclaration() || p->isClassDeclaration());
     if (FuncDeclaration* fd = p->isFuncDeclaration())
     {
-        llvm::Value* v = fd->llvmNested;
+        llvm::Value* v = fd->irFunc->nestedVar;
         assert(v);
         return v->getType();
     }
@@ -717,9 +716,9 @@
 
         if (fd->toParent2() == func)
         {
-            if (!func->llvmNested)
+            if (!func->irFunc->nestedVar)
                 return NULL;
-            return DtoBitCast(v, func->llvmNested->getType());
+            return DtoBitCast(v, func->irFunc->nestedVar->getType());
         }
 
         v = DtoBitCast(v, get_next_frame_ptr_type(fd));
@@ -733,7 +732,7 @@
         else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration())
         {
             size_t idx = 2;
-            idx += cd->llvmIRStruct->interfaces.size();
+            idx += cd->llvmIrStruct->interfaces.size();
             v = DtoGEPi(v,0,idx,"tmp");
             v = DtoLoad(v);
         }
@@ -747,7 +746,7 @@
     {
         Logger::println("scope is class: %s", cd->toChars());
         /*size_t idx = 2;
-        idx += cd->llvmIRStruct->interfaces.size();
+        idx += cd->llvmIrStruct->interfaces.size();
         v = DtoGEPi(v,0,idx,"tmp");
         Logger::cout() << "gep = " << *v << '\n';
         v = DtoLoad(v);*/
@@ -766,14 +765,14 @@
 {
     Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars());
     LOG_SCOPE;
-    IRFunction* irfunc = gIR->func();
+    IrFunction* irfunc = gIR->func();
 
     // in the right scope already
     if (func == irfunc->decl)
-        return irfunc->decl->llvmNested;
+        return irfunc->decl->irFunc->nestedVar;
 
     // use the 'this' pointer
-    llvm::Value* ptr = irfunc->decl->llvmThisVar;
+    llvm::Value* ptr = irfunc->decl->irFunc->thisVar;
     assert(ptr);
 
     // return the fully resolved frame pointer
@@ -830,7 +829,7 @@
 llvm::Value* DtoNestedVariable(VarDeclaration* vd)
 {
     // log the frame list
-    IRFunction* irfunc = gIR->func();
+    IrFunction* irfunc = gIR->func();
     if (Logger::enabled())
         print_nested_frame_list(vd, irfunc->decl);
 
@@ -841,10 +840,10 @@
     assert(ptr && "nested var, but no context");
 
     // we must cast here to be sure. nested classes just have a void*
-    ptr = DtoBitCast(ptr, func->llvmNested->getType());
+    ptr = DtoBitCast(ptr, func->irFunc->nestedVar->getType());
 
     // index nested var and load (if necessary)
-    llvm::Value* v = DtoGEPi(ptr, 0, vd->llvmNestedIndex, "tmp");
+    llvm::Value* v = DtoGEPi(ptr, 0, vd->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);
@@ -922,9 +921,9 @@
             llvm::Value* tmp = rhs->getRVal();
             FuncDeclaration* fdecl = gIR->func()->decl;
             // respecify the this param
-            if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar))
-                fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint());
-            DtoStore(tmp, fdecl->llvmThisVar);
+            if (!llvm::isa<llvm::AllocaInst>(fdecl->irFunc->thisVar))
+                fdecl->irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint());
+            DtoStore(tmp, fdecl->irFunc->thisVar);
         }
         // regular class ref -> class ref assignment
         else {
@@ -1584,11 +1583,11 @@
 
     if (_init && _init->getType() != _type)
         _type = _init->getType();
-    llvm::cast<llvm::OpaqueType>(vd->llvmIRGlobal->type.get())->refineAbstractTypeTo(_type);
-    _type = vd->llvmIRGlobal->type.get();
+    llvm::cast<llvm::OpaqueType>(vd->irGlobal->type.get())->refineAbstractTypeTo(_type);
+    _type = vd->irGlobal->type.get();
     assert(!_type->isAbstract());
 
-    llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->llvmValue);
+    llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->irGlobal->value);
     if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl))
     {
         gvar->setInitializer(_init);
@@ -1743,3 +1742,29 @@
     // 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()
+{
+    static const llvm::StructType* t = NULL;
+    if (t)
+        return t;
+
+    // build interface info type
+    std::vector<const llvm::Type*> types;
+    // ClassInfo classinfo
+    ClassDeclaration* cd2 = ClassDeclaration::classinfo;
+    DtoResolveClass(cd2);
+    types.push_back(getPtrToType(cd2->type->llvmType->get()));
+    // void*[] vtbl
+    std::vector<const llvm::Type*> vtbltypes;
+    vtbltypes.push_back(DtoSize_t());
+    const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
+    vtbltypes.push_back(byteptrptrty);
+    types.push_back(llvm::StructType::get(vtbltypes));
+    // int offset
+    types.push_back(llvm::Type::Int32Ty);
+    // create type
+    t = llvm::StructType::get(types);
+
+    return t;
+}
--- a/gen/tollvm.h	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/tollvm.h	Thu Jan 17 03:15:12 2008 +0100
@@ -1,51 +1,74 @@
 #ifndef LLVMDC_GEN_TOLLVM_H
 #define LLVMDC_GEN_TOLLVM_H
 
-// D -> LLVM helpers
+#include "gen/llvm.h"
+#include "lexer.h"
+#include "mtype.h"
+#include "attrib.h"
+#include "declaration.h"
 
-struct DValue;
-
+// D->LLVM type handling stuff
 const llvm::Type* DtoType(Type* t);
 bool DtoIsPassedByRef(Type* type);
+
+// resolve typedefs to their real type.
+// TODO should probably be removed in favor of DMD's Type::toBasetype
 Type* DtoDType(Type* t);
 
+// delegate helpers
 const llvm::StructType* DtoDelegateType(Type* t);
 llvm::Value* DtoNullDelegate(llvm::Value* v);
 llvm::Value* DtoDelegateCopy(llvm::Value* dst, llvm::Value* src);
 llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs);
 
+// return linkage types for general cases
 llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc);
+
+// convert DMD calling conv to LLVM
 unsigned DtoCallingConv(LINK l);
 
+// TODO: this one should be removed!!!
 llvm::Value* DtoPointedType(llvm::Value* ptr, llvm::Value* val);
+
+// casts any value to a boolean
 llvm::Value* DtoBoolean(llvm::Value* val);
 
+// some types
 const llvm::Type* DtoSize_t();
+const llvm::StructType* DtoInterfaceInfoType();
 
+// initializer helpers
 llvm::Constant* DtoConstInitializer(Type* type, Initializer* init);
 llvm::Constant* 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();
 
+// getelementptr helpers
 llvm::Value* DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb=NULL);
 llvm::Value* DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb=NULL);
 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, const std::string& var, llvm::BasicBlock* bb=NULL);
 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb=NULL);
 
+// dynamic memory helpers
 llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty);
 llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* len);
 
+// assertion generator
 void DtoAssert(Loc* loc, DValue* msg);
 
+// nested variable/class helpers
 llvm::Value* DtoNestedContext(FuncDeclaration* func);
 llvm::Value* DtoNestedVariable(VarDeclaration* vd);
 
+// annotation generator
 void DtoAnnotation(const char* str);
 
+// to constant helpers
 llvm::ConstantInt* DtoConstSize_t(size_t);
 llvm::ConstantInt* DtoConstUint(unsigned i);
 llvm::ConstantInt* DtoConstInt(int i);
@@ -56,17 +79,18 @@
 llvm::Constant* DtoConstBool(bool);
 llvm::Constant* DtoConstNullPtr(const llvm::Type* t);
 
+// is template instance check
 bool DtoIsTemplateInstance(Dsymbol* s);
 
+// generates lazy static initialization code for a global variable
 void DtoLazyStaticInit(bool istempl, llvm::Value* 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();
--- a/gen/toobj.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/toobj.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -41,6 +41,8 @@
 #include "gen/todebug.h"
 #include "gen/runtime.h"
 
+#include "ir/irvar.h"
+
 //////////////////////////////////////////////////////////////////////////////////////////
 
 // in gen/optimize.cpp
@@ -169,7 +171,7 @@
 
     size_t n = gIR->ctors.size();
     if (n == 1)
-        return llvm::cast<llvm::Function>(gIR->ctors[0]->llvmValue);
+        return gIR->ctors[0]->irFunc->func;
 
     std::string name("_D");
     name.append(gIR->dmodule->mangle());
@@ -184,7 +186,7 @@
     LLVMBuilder builder(bb);
 
     for (size_t i=0; i<n; i++) {
-        llvm::Function* f = llvm::cast<llvm::Function>(gIR->ctors[i]->llvmValue);
+        llvm::Function* f = gIR->ctors[i]->irFunc->func;
         llvm::CallInst* call = builder.CreateCall(f,"");
         call->setCallingConv(llvm::CallingConv::Fast);
     }
@@ -202,7 +204,7 @@
 
     size_t n = gIR->dtors.size();
     if (n == 1)
-        return llvm::cast<llvm::Function>(gIR->dtors[0]->llvmValue);
+        return gIR->dtors[0]->irFunc->func;
 
     std::string name("_D");
     name.append(gIR->dmodule->mangle());
@@ -217,7 +219,7 @@
     LLVMBuilder builder(bb);
 
     for (size_t i=0; i<n; i++) {
-        llvm::Function* f = llvm::cast<llvm::Function>(gIR->dtors[i]->llvmValue);
+        llvm::Function* f = gIR->dtors[i]->irFunc->func;
         llvm::CallInst* call = builder.CreateCall(f,"");
         call->setCallingConv(llvm::CallingConv::Fast);
     }
@@ -235,7 +237,7 @@
 
     size_t n = gIR->unitTests.size();
     if (n == 1)
-        return llvm::cast<llvm::Function>(gIR->unitTests[0]->llvmValue);
+        return gIR->unitTests[0]->irFunc->func;
 
     std::string name("_D");
     name.append(gIR->dmodule->mangle());
@@ -250,7 +252,7 @@
     LLVMBuilder builder(bb);
 
     for (size_t i=0; i<n; i++) {
-        llvm::Function* f = llvm::cast<llvm::Function>(gIR->unitTests[i]->llvmValue);
+        llvm::Function* f = gIR->unitTests[i]->irFunc->func;
         llvm::CallInst* call = builder.CreateCall(f,"");
         call->setCallingConv(llvm::CallingConv::Fast);
     }
@@ -354,7 +356,7 @@
         ClassDeclaration* cd = (ClassDeclaration*)aclasses.data[i];
         if (cd->isInterfaceDeclaration())
         {
-            Logger::println("skipping interface '%s'", cd->toPrettyChars());
+            Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars());
             continue;
         }
         Logger::println("class: %s", cd->toPrettyChars());
@@ -507,7 +509,7 @@
         llvmResolved = true;
         llvmDeclared = true;
 
-        llvmIRGlobal = new IRGlobal(this);
+        irGlobal = new IrGlobal(this);
 
         Logger::println("parent: %s (%s)", parent->toChars(), parent->kind());
 
@@ -529,13 +531,13 @@
         else
             _linkage = DtoLinkage(protection, storage_class);
 
-        const llvm::Type* _type = llvmIRGlobal->type.get();
+        const llvm::Type* _type = irGlobal->type.get();
 
         Logger::println("Creating global variable");
         std::string _name(mangle());
 
         llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module);
-        llvmValue = gvar;
+        irGlobal->value = gvar;
 
         if (static_local)
             DtoConstInitGlobal(this);
@@ -549,9 +551,10 @@
         Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset);
 
         const llvm::Type* _type = DtoType(type);
+        irField = new IrField(this);
 
         // add the field in the IRStruct
-        gIR->topstruct()->offsets.insert(std::make_pair(offset, IRStruct::Offset(this, _type)));
+        gIR->topstruct()->offsets.insert(std::make_pair(offset, IrStruct::Offset(this, _type)));
     }
 
     Logger::println("VarDeclaration::toObjFile is done");
--- a/gen/typinf.cpp	Mon Jan 14 23:09:55 2008 +0100
+++ b/gen/typinf.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -39,6 +39,8 @@
 #include "gen/structs.h"
 #include "gen/classes.h"
 
+#include "ir/irvar.h"
+
 /*******************************************
  * Get a canonicalized form of the TypeInfo for use with the internal
  * runtime library routines. Canonicalized in that static arrays are
@@ -254,7 +256,7 @@
     Logger::println("DtoResolveTypeInfo(%s)", tid->toChars());
     LOG_SCOPE;
 
-    tid->llvmIRGlobal = new IRGlobal(tid);
+    tid->irGlobal = new IrGlobal(tid);
 
     gIR->declareList.push_back(tid);
 }
@@ -280,15 +282,17 @@
             const llvm::Type* t = llvm::OpaqueType::get();
             llvm::GlobalVariable* g = new llvm::GlobalVariable(t, true, llvm::GlobalValue::ExternalLinkage, NULL, mangled, gIR->module);
             assert(g);
-            tid->llvmValue = g;
+            /*if (!tid->irGlobal)
+                tid->irGlobal = new IrGlobal(tid);*/
+            tid->irGlobal->value = g;
             mangled.append("__TYPE");
-            gIR->module->addTypeName(mangled, tid->llvmValue->getType()->getContainedType(0));
-            Logger::println("Got typeinfo var: %s", tid->llvmValue->getName().c_str());
+            gIR->module->addTypeName(mangled, tid->irGlobal->value->getType()->getContainedType(0));
+            Logger::println("Got typeinfo var: %s", tid->irGlobal->value->getName().c_str());
             tid->llvmInitialized = true;
             tid->llvmDefined = true;
         }
-        else if (!tid->llvmValue) {
-            tid->llvmValue = found;
+        else if (!tid->irGlobal->value) {
+            tid->irGlobal->value = found;
             tid->llvmInitialized = true;
             tid->llvmDefined = true;
         }
@@ -352,7 +356,7 @@
     const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
 
     // create the symbol
-    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+    irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
 }
 
 void TypeInfoTypedefDeclaration::llvmDefine()
@@ -385,12 +389,11 @@
 
     sd->basetype->getTypeInfo(NULL);        // generate vtinfo
     assert(sd->basetype->vtinfo);
-    if (!sd->basetype->vtinfo->llvmValue)
-        DtoForceDeclareDsymbol(sd->basetype->vtinfo);
+    DtoForceDeclareDsymbol(sd->basetype->vtinfo);
 
-    assert(sd->basetype->vtinfo->llvmValue);
-    assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->llvmValue));
-    llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->basetype->vtinfo->llvmValue);
+    assert(sd->basetype->vtinfo->irGlobal->value);
+    assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->irGlobal->value));
+    llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->basetype->vtinfo->irGlobal->value);
     castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
     sinits.push_back(castbase);
 
@@ -418,7 +421,7 @@
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+    isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
 }
 
 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
@@ -439,7 +442,7 @@
     const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
 
     // create the symbol
-    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+    irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
 }
 
 void TypeInfoEnumDeclaration::llvmDefine()
@@ -471,11 +474,10 @@
 
     sd->memtype->getTypeInfo(NULL);        // generate vtinfo
     assert(sd->memtype->vtinfo);
-    if (!sd->memtype->vtinfo->llvmValue)
-        DtoForceDeclareDsymbol(sd->memtype->vtinfo);
+    DtoForceDeclareDsymbol(sd->memtype->vtinfo);
 
-    assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->llvmValue));
-    llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->llvmValue);
+    assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->irGlobal->value));
+    llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->irGlobal->value);
     castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
     sinits.push_back(castbase);
 
@@ -504,7 +506,7 @@
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+    isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
 }
 
 void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
@@ -522,7 +524,7 @@
     const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
 
     // create the symbol
-    tid->llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
+    tid->irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
 }
 
 static llvm::Constant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
@@ -543,16 +545,15 @@
     Logger::println("generating base typeinfo");
     basetype->getTypeInfo(NULL);
     assert(basetype->vtinfo);
-    if (!basetype->vtinfo->llvmValue)
-        DtoForceDeclareDsymbol(basetype->vtinfo);
-    assert(llvm::isa<llvm::Constant>(basetype->vtinfo->llvmValue));
-    llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->llvmValue);
+    DtoForceDeclareDsymbol(basetype->vtinfo);
+    assert(llvm::isa<llvm::Constant>(basetype->vtinfo->irGlobal->value));
+    llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->irGlobal->value);
     castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
     sinits.push_back(castbase);
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    isaGlobalVar(tid->llvmValue)->setInitializer(tiInit);
+    isaGlobalVar(tid->irGlobal->value)->setInitializer(tiInit);
 }
 
 /* ========================================================================= */
@@ -628,7 +629,7 @@
     const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
 
     // create the symbol
-    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+    irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
 }
 
 void TypeInfoStaticArrayDeclaration::llvmDefine()
@@ -659,7 +660,7 @@
     // get symbol
     assert(tc->next->vtinfo);
     DtoForceDeclareDsymbol(tc->next->vtinfo);
-    llvm::Constant* castbase = isaConstant(tc->next->vtinfo->llvmValue);
+    llvm::Constant* castbase = isaConstant(tc->next->vtinfo->irGlobal->value);
     castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
     sinits.push_back(castbase);
 
@@ -668,7 +669,7 @@
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+    isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
 }
 
 void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
@@ -691,7 +692,7 @@
     const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
 
     // create the symbol
-    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+    irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
 }
 
 void TypeInfoAssociativeArrayDeclaration::llvmDefine()
@@ -724,7 +725,7 @@
     // get symbol
     assert(tc->next->vtinfo);
     DtoForceDeclareDsymbol(tc->next->vtinfo);
-    llvm::Constant* castbase = isaConstant(tc->next->vtinfo->llvmValue);
+    llvm::Constant* castbase = isaConstant(tc->next->vtinfo->irGlobal->value);
     castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
     sinits.push_back(castbase);
 
@@ -734,13 +735,13 @@
     // get symbol
     assert(tc->index->vtinfo);
     DtoForceDeclareDsymbol(tc->index->vtinfo);
-    castbase = isaConstant(tc->index->vtinfo->llvmValue);
+    castbase = isaConstant(tc->index->vtinfo->irGlobal->value);
     castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(3));
     sinits.push_back(castbase);
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+    isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
 }
 
 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
@@ -824,7 +825,7 @@
     const llvm::StructType* stype = isaStruct(((TypeClass*)base->type)->llvmType->get());
 
     // create the symbol
-    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+    irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
 }
 
 void TypeInfoStructDeclaration::llvmDefine()
@@ -924,8 +925,8 @@
         fd = fdx->overloadExactMatch(tftohash);
         if (fd) {
             DtoForceDeclareDsymbol(fd);
-            assert(fd->llvmValue != 0);
-            llvm::Constant* c = isaConstant(fd->llvmValue);
+            assert(fd->irFunc->func != 0);
+            llvm::Constant* c = isaConstant(fd->irFunc->func);
             assert(c);
             c = llvm::ConstantExpr::getBitCast(c, ptty);
             sinits.push_back(c);
@@ -950,8 +951,8 @@
             fd = fdx->overloadExactMatch(tfeqptr);
             if (fd) {
                 DtoForceDeclareDsymbol(fd);
-                assert(fd->llvmValue != 0);
-                llvm::Constant* c = isaConstant(fd->llvmValue);
+                assert(fd->irFunc->func != 0);
+                llvm::Constant* c = isaConstant(fd->irFunc->func);
                 assert(c);
                 c = llvm::ConstantExpr::getBitCast(c, ptty);
                 sinits.push_back(c);
@@ -978,8 +979,8 @@
         fd = fdx->overloadExactMatch(tftostring);
         if (fd) {
             DtoForceDeclareDsymbol(fd);
-            assert(fd->llvmValue != 0);
-            llvm::Constant* c = isaConstant(fd->llvmValue);
+            assert(fd->irFunc->func != 0);
+            llvm::Constant* c = isaConstant(fd->irFunc->func);
             assert(c);
             c = llvm::ConstantExpr::getBitCast(c, ptty);
             sinits.push_back(c);
@@ -1000,7 +1001,7 @@
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
     llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module);
 
-    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+    isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
 }
 
 void TypeInfoStructDeclaration::toDt(dt_t **pdt)
@@ -1024,7 +1025,7 @@
     const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
 
     // create the symbol
-    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+    irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
 }
 
 void TypeInfoClassDeclaration::llvmDefine()
@@ -1056,7 +1057,7 @@
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+    isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
 }
 
 void TypeInfoClassDeclaration::toDt(dt_t **pdt)
@@ -1080,7 +1081,7 @@
     const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
 
     // create the symbol
-    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+    irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
 }
 
 void TypeInfoInterfaceDeclaration::llvmDefine()
@@ -1112,7 +1113,7 @@
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+    isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
 }
 
 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
@@ -1136,7 +1137,7 @@
     const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
 
     // create the symbol
-    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+    irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
 }
 
 void TypeInfoTupleDeclaration::llvmDefine()
@@ -1175,8 +1176,8 @@
         Argument *arg = (Argument *)tu->arguments->data[i];
         arg->type->getTypeInfo(NULL);
         DtoForceDeclareDsymbol(arg->type->vtinfo);
-        assert(arg->type->vtinfo->llvmValue);
-        llvm::Constant* c = isaConstant(arg->type->vtinfo->llvmValue);
+        assert(arg->type->vtinfo->irGlobal->value);
+        llvm::Constant* c = isaConstant(arg->type->vtinfo->irGlobal->value);
         c = llvm::ConstantExpr::getBitCast(c, tiTy);
         arrInits.push_back(c);
     }
@@ -1191,7 +1192,7 @@
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+    isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
 }
 
 void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/ir.h	Thu Jan 17 03:15:12 2008 +0100
@@ -0,0 +1,14 @@
+// this head contains stuff used by all the IR
+
+#ifndef LLVMDC_IR_IR_H
+#define LLVMDC_IR_IR_H
+
+#include "ir/irforw.h"
+#include "root.h"
+
+struct IrBase : Object
+{
+    virtual ~IrBase() {}
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irforw.h	Thu Jan 17 03:15:12 2008 +0100
@@ -0,0 +1,45 @@
+#ifndef LLVMDC_IR_IRFORW_H
+#define LLVMDC_IR_IRFORW_H
+
+// dmd forward declarations
+struct Module;
+struct Dsymbol;
+struct Declaration;
+struct VarDeclaration;
+struct FuncDeclaration;
+struct AggregateDeclaration;
+struct StructDeclaration;
+struct ClassDeclaration;
+struct InterfaceDeclaration;
+struct Expression;
+struct BaseClass;
+struct Array;
+struct Argument;
+
+struct Type;
+struct TypeStruct;
+struct TypeClass;
+struct TypeEnum;
+struct TypeArray;
+struct TypeFunction;
+
+// llvm forward declarations
+namespace llvm
+{
+    class Value;
+    class GlobalValue;
+    class GlobalVariable;
+    class Function;
+    class Constant;
+    class ConstantStruct;
+    class ConstantArray;
+    class TargetData;
+    class Type;
+    class StructType;
+    class ArrayType;
+    class PointerType;
+    class BasicBlock;
+    class Instruction;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irfunction.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -0,0 +1,44 @@
+#include "gen/tollvm.h"
+#include "ir/irfunction.h"
+
+IrFinally::IrFinally()
+{
+    bb = 0;
+    retbb = 0;
+}
+
+IrFinally::IrFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb)
+{
+    bb = b;
+    retbb = rb;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+IrFunction::IrFunction(FuncDeclaration* fd)
+{
+    decl = fd;
+
+    Type* t = DtoDType(fd->type);
+    assert(t->ty == Tfunction);
+    type = (TypeFunction*)t;
+    func = NULL;
+    allocapoint = NULL;
+    finallyretval = NULL;
+
+    queued = false;
+    defined = false;
+
+    retArg = NULL;
+    thisVar = NULL;
+    nestedVar = NULL;
+    _arguments = NULL;
+    _argptr = NULL;
+    dwarfSubProg = NULL;
+}
+
+IrFunction::~IrFunction()
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irfunction.h	Thu Jan 17 03:15:12 2008 +0100
@@ -0,0 +1,44 @@
+#ifndef LLVMDC_IR_IRFUNCTION_H
+#define LLVMDC_IR_IRFUNCTION_H
+
+#include "ir/ir.h"
+
+#include <vector>
+
+// represents a finally block
+struct IrFinally
+{
+    llvm::BasicBlock* bb;
+    llvm::BasicBlock* retbb;
+
+    IrFinally();
+    IrFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb);
+};
+
+// represents a function
+struct IrFunction : IrBase
+{
+    llvm::Function* func;
+    llvm::Instruction* allocapoint;
+    FuncDeclaration* decl;
+    TypeFunction* type;
+
+    // finally blocks
+    typedef std::vector<IrFinally> FinallyVec;
+    FinallyVec finallys;
+    llvm::Value* finallyretval;
+
+    bool queued;
+    bool defined;
+    llvm::Value* retArg;
+    llvm::Value* thisVar;
+    llvm::Value* nestedVar;
+    llvm::Value* _arguments;
+    llvm::Value* _argptr;
+    llvm::Constant* dwarfSubProg;
+
+    IrFunction(FuncDeclaration* fd);
+    virtual ~IrFunction();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irmodule.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -0,0 +1,10 @@
+#include "ir/irmodule.h"
+
+IrModule::IrModule(Module* module)
+{
+    M = module;
+}
+
+IrModule::~IrModule()
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irmodule.h	Thu Jan 17 03:15:12 2008 +0100
@@ -0,0 +1,16 @@
+#ifndef LLVMDC_IR_IRMODULE_H
+#define LLVMDC_IR_IRMODULE_H
+
+#include "ir/ir.h"
+
+struct Module;
+
+struct IrModule : IrBase
+{
+    IrModule(Module* module);
+    virtual ~IrModule();
+
+    Module* M;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irstruct.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -0,0 +1,38 @@
+#include "gen/llvm.h"
+#include "mtype.h"
+#include "aggregate.h"
+#include "ir/irstruct.h"
+
+IrInterface::IrInterface(BaseClass* b, const llvm::StructType* vt)
+{
+    base = b;
+    decl = b->base;
+    vtblTy = vt;
+    vtblInit = NULL;
+    vtbl = NULL;
+    infoTy = NULL;
+    infoInit = NULL;
+    info = NULL;
+}
+
+IrInterface::~IrInterface()
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+IrStruct::IrStruct(Type* t)
+ : recty((t->llvmType != NULL) ? *t->llvmType : llvm::OpaqueType::get())
+{
+    type = t;
+    defined = false;
+    constinited = false;
+    interfaceInfosTy = NULL;
+    interfaceInfos = NULL;
+}
+
+IrStruct::~IrStruct()
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irstruct.h	Thu Jan 17 03:15:12 2008 +0100
@@ -0,0 +1,65 @@
+#ifndef LLVMDC_IR_IRSTRUCT_H
+#define LLVMDC_IR_IRSTRUCT_H
+
+#include "ir/ir.h"
+
+#include <vector>
+#include <map>
+
+struct IrInterface : IrBase
+{
+    BaseClass* base;
+    ClassDeclaration* decl;
+
+    const llvm::StructType* vtblTy;
+    llvm::ConstantStruct* vtblInit;
+    llvm::GlobalVariable* vtbl;
+
+    const llvm::StructType* infoTy;
+    llvm::ConstantStruct* infoInit;
+    llvm::Constant* info;
+
+    IrInterface(BaseClass* b, const llvm::StructType* vt);
+    ~IrInterface();
+};
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+// represents a struct or class
+struct IrStruct : IrBase
+{
+    struct Offset
+    {
+        VarDeclaration* var;
+        const llvm::Type* type;
+        llvm::Constant* init;
+
+        Offset(VarDeclaration* v, const llvm::Type* ty)
+        : var(v), type(ty), init(NULL) {}
+    };
+
+    typedef std::multimap<unsigned, Offset> OffsetMap;
+    typedef std::vector<VarDeclaration*> VarDeclVector;
+    typedef std::map<ClassDeclaration*, IrInterface*> InterfaceMap;
+    typedef InterfaceMap::iterator InterfaceIter;
+
+public:
+    IrStruct(Type*);
+    virtual ~IrStruct();
+
+    Type* type;
+    llvm::PATypeHolder recty;
+    OffsetMap offsets;
+    VarDeclVector defaultFields;
+
+    InterfaceMap interfaces;
+    const llvm::ArrayType* interfaceInfosTy;
+    llvm::GlobalVariable* interfaceInfos;
+
+    bool defined;
+    bool constinited;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irvar.cpp	Thu Jan 17 03:15:12 2008 +0100
@@ -0,0 +1,63 @@
+#include "llvm/DerivedTypes.h"
+#include "declaration.h"
+#include "ir/irvar.h"
+
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+IrVar* VarDeclaration::getIrVar()
+{
+    assert(irGlobal || irLocal || irField);
+    return irGlobal ? (IrVar*)irGlobal : irLocal ? (IrVar*)irLocal : (IrVar*)irField;
+}
+
+llvm::Value*& VarDeclaration::getIrValue()
+{
+    return getIrVar()->value;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+IrVar::IrVar(VarDeclaration* var)
+{
+    V = var;
+    value = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v),
+    type(llvm::OpaqueType::get())
+{
+    constInit = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+IrLocal::IrLocal(VarDeclaration* v) : IrVar(v)
+{
+    nestedIndex = -1;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+IrField::IrField(VarDeclaration* v) : IrVar(v)
+{
+    index = -1;
+    indexOffset = 0;
+    constInit = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irvar.h	Thu Jan 17 03:15:12 2008 +0100
@@ -0,0 +1,42 @@
+#ifndef LLVMDC_IR_IRVAR_H
+#define LLVMDC_IR_IRVAR_H
+
+#include "ir/ir.h"
+#include "llvm/Type.h"
+
+struct IrVar : IrBase
+{
+    IrVar(VarDeclaration* var);
+
+    VarDeclaration* V;
+    llvm::Value* value;
+};
+
+// represents a global variable
+struct IrGlobal : IrVar
+{
+    IrGlobal(VarDeclaration* v);
+
+    llvm::PATypeHolder type;
+    llvm::Constant* constInit;
+};
+
+// represents a local variable variable
+struct IrLocal : IrVar
+{
+    IrLocal(VarDeclaration* v);
+
+    int nestedIndex;
+};
+
+// represents an aggregate field variable
+struct IrField : IrVar
+{
+    IrField(VarDeclaration* v);
+
+    int index;
+    size_t indexOffset;
+    llvm::Constant* constInit;
+};
+
+#endif
--- a/llvmdc.kdevelop.filelist	Mon Jan 14 23:09:55 2008 +0100
+++ b/llvmdc.kdevelop.filelist	Thu Jan 17 03:15:12 2008 +0100
@@ -120,7 +120,6 @@
 gen/irstate.cpp
 gen/irstate.h
 gen/llvm.h
-gen/llvmd.h
 gen/logger.cpp
 gen/logger.h
 gen/optimizer.cpp
@@ -139,6 +138,19 @@
 gen/toobj.cpp
 gen/typeinf.h
 gen/typinf.cpp
+ir
+ir/forw.h
+ir/ir.h
+ir/irfunction.cpp
+ir/irfunction.h
+ir/irglobal.cpp
+ir/irglobal.h
+ir/irmodule.cpp
+ir/irmodule.h
+ir/irstruct.cpp
+ir/irstruct.h
+ir/irvar.cpp
+ir/irvar.h
 lphobos
 lphobos/build.sh
 lphobos/crc32.d
@@ -263,7 +275,6 @@
 tango/lib/compiler/llvmdc/adi.d
 tango/lib/compiler/llvmdc/arrays.d
 tango/lib/compiler/llvmdc/cast.d
-tango/lib/compiler/llvmdc/contract.d
 tango/lib/compiler/llvmdc/critical.c
 tango/lib/compiler/llvmdc/dmain2.d
 tango/lib/compiler/llvmdc/eh.d
@@ -749,6 +760,8 @@
 tangotests/p.d
 tangotests/q.d
 tangotests/r.d
+tangotests/s.d
+tangotests/t.d
 test
 test/a.d
 test/aa1.d
--- a/premake.lua	Mon Jan 14 23:09:55 2008 +0100
+++ b/premake.lua	Thu Jan 17 03:15:12 2008 +0100
@@ -21,7 +21,7 @@
 package.name = "llvmdc"
 package.kind = "exe"
 package.language = "c++"
-package.files = { matchfiles("dmd/*.c"), matchfiles("gen/*.cpp") }
+package.files = { matchfiles("dmd/*.c"), matchfiles("gen/*.cpp"), matchfiles("ir/*.cpp") }
 package.excludes = { "dmd/idgen.c", "dmd/impcnvgen.c" }
 package.buildoptions = { "-x c++", "`llvm-config --cxxflags`" }
 package.linkoptions = {
--- a/tango/lib/compiler/llvmdc/cast.d	Mon Jan 14 23:09:55 2008 +0100
+++ b/tango/lib/compiler/llvmdc/cast.d	Thu Jan 17 03:15:12 2008 +0100
@@ -27,6 +27,9 @@
 
 extern (C):
 
+debug = PRINTF;
+debug(PRINTF) int printf(char*, ...);
+
 /******************************************
  * Given a pointer:
  *      If it is an Object, return that Object.
@@ -54,6 +57,7 @@
             o = cast(Object)(p - pi.offset);
         }
     }
+    debug(PRINTF) printf("toObject = %p\n", o);
     return o;
 }
 
@@ -75,6 +79,7 @@
         o = cast(Object)(p - pi.offset);
         return _d_dynamic_cast(o, c);
     }
+    debug(PRINTF) printf("_d_interface_cast = %p\n", o);
     return o;
 }
 
@@ -82,7 +87,7 @@
 {   ClassInfo oc;
     size_t offset = 0;
 
-    //printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name);
+    debug(PRINTF) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name.length, c.name.ptr);
 
     if (o)
     {
@@ -96,16 +101,20 @@
             o = null;
     }
     //printf("\tresult = %p\n", o);
+    debug(PRINTF) printf("_d_dynamic_cast = %p\n", o);
     return o;
 }
 
 int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset)
 {   int i;
 
+    debug(PRINTF) printf("_d_isbaseof2(%.*s, %.*s, %ul)\n", oc.name.length, oc.name.ptr, c.name.length, c.name.ptr, offset);
+
     if (oc is c)
         return 1;
     do
     {
+        debug(PRINTF) printf("oc.interfaces.length = %ul\n", oc.interfaces.length);
         if (oc.base is c)
             return 1;
         for (i = 0; i < oc.interfaces.length; i++)
@@ -113,6 +122,7 @@
             ClassInfo ic;
 
             ic = oc.interfaces[i].classinfo;
+            debug(PRINTF) printf("checking %.*s\n", ic.name.length, ic.name.ptr);
             if (ic is c)
             {   offset = cast(size_t)oc.interfaces[i].offset;
                 return 1;
--- a/tango/tango/io/Buffer.d	Mon Jan 14 23:09:55 2008 +0100
+++ b/tango/tango/io/Buffer.d	Thu Jan 17 03:15:12 2008 +0100
@@ -25,6 +25,7 @@
 extern (C)
 {
         protected void * memcpy (void *dst, void *src, uint);
+        private int printf(char*, ...);
 }       
 
 /*******************************************************************************
@@ -163,10 +164,14 @@
 
         this (IConduit conduit)
         {
+                printf("Buffer.this(%p)\n", conduit);
+                assert (conduit !is null);
                 assert (conduit);
 
                 this (conduit.bufferSize);
                 setConduit (conduit);
+
+                assert(this !is null);
         }
 
         /***********************************************************************
@@ -221,7 +226,8 @@
 
         this (uint capacity = 0)
         {
-                setContent (new ubyte[capacity], 0);              
+                setContent (new ubyte[capacity], 0);
+                assert(this !is null);
         }
 
         /***********************************************************************
--- a/tango/tango/io/Console.d	Mon Jan 14 23:09:55 2008 +0100
+++ b/tango/tango/io/Console.d	Thu Jan 17 03:15:12 2008 +0100
@@ -23,6 +23,7 @@
 version (Posix)
          private import tango.stdc.posix.unistd;  // needed for isatty()
 
+private extern(C) int printf(char*, ...);
 
 /*******************************************************************************
 
@@ -69,6 +70,8 @@
 
                 private this (Conduit conduit, bool redirected)
                 {
+                        printf("Console.Input.this(%p, %d)\n", conduit, redirected);
+                        assert (conduit);
                         redirect = redirected;
                         buffer = new Buffer (conduit);
                 }
@@ -596,6 +599,7 @@
 
                         private this (Handle handle)
                         {
+                                printf("Console.Conduit.this(%d)\n", handle);
                                 reopen (handle);
                                 redirected = (isatty(handle) is 0);
                         }
@@ -621,14 +625,13 @@
 
 ******************************************************************************/
 
-extern(C) int printf(char*, ...);
-
 static this ()
 {
         printf("STATIC INIT FOR CONSOLE\n");
-        printf("Cin\n");
+        printf("Cin conduit\n");
         auto conduit = new Console.Conduit (0);
         assert(conduit);
+        printf("Cin input\n");
         Cin  = new Console.Input (conduit, conduit.redirected);
 
         printf("Cout\n");
--- a/tango/tango/io/DeviceConduit.d	Mon Jan 14 23:09:55 2008 +0100
+++ b/tango/tango/io/DeviceConduit.d	Thu Jan 17 03:15:12 2008 +0100
@@ -18,6 +18,8 @@
 
 private import  tango.core.Exception;
 
+private extern(C) int printf(char*, ...);
+
 /*******************************************************************************
 
         Implements a means of reading and writing a file device. Conduits