changeset 137:ce7b81fb957f trunk

[svn r141] fixed more problems with classinfo moved more IR state out of the AST classes
author lindquist
date Fri, 18 Jan 2008 16:42:16 +0100
parents 0e28624814e8
children aeddd4d533b3
files dmd/aggregate.h dmd/struct.c gen/classes.cpp gen/functions.cpp gen/statements.cpp gen/structs.cpp gen/toir.cpp gen/tollvm.cpp gen/toobj.cpp gen/typinf.cpp ir/irstruct.cpp ir/irstruct.h llvmdc.kdevelop llvmdc.kdevelop.filelist tango/lib/compiler/llvmdc/cast.d tango/lib/compiler/llvmdc/lifetime.d tango/tango/io/Buffer.d tangotests/l.d
diffstat 18 files changed, 310 insertions(+), 266 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/aggregate.h	Thu Jan 17 03:15:12 2008 +0100
+++ b/dmd/aggregate.h	Fri Jan 18 16:42:16 2008 +0100
@@ -101,20 +101,10 @@
     Symbol *sinit;
     Symbol *toInitializer();
 
-    bool llvmInProgress;
-    llvm::GlobalVariable* llvmVtbl;
-    llvm::ConstantStruct* llvmConstVtbl;
-    llvm::GlobalVariable* llvmInit;
-    llvm::Constant* llvmConstInit;
-    llvm::GlobalVariable* llvmClass;
-    llvm::Constant* llvmConstClass;
-    bool llvmHasUnions;
-    DUnion* llvmUnion;
-    IrStruct* llvmIrStruct;
-    bool llvmClassDeclared;
-    bool llvmClassDefined;
+    AggregateDeclaration *isAggregateDeclaration() { return this; }
 
-    AggregateDeclaration *isAggregateDeclaration() { return this; }
+    // llvmdc
+    IrStruct* irStruct;
 };
 
 struct AnonymousAggregateDeclaration : AggregateDeclaration
--- a/dmd/struct.c	Thu Jan 17 03:15:12 2008 +0100
+++ b/dmd/struct.c	Fri Jan 18 16:42:16 2008 +0100
@@ -45,18 +45,7 @@
     sinit = NULL;
     scope = NULL;
 
-    llvmVtbl = NULL;
-    llvmConstVtbl = NULL;
-    llvmInit = NULL;
-    llvmConstInit = NULL;
-    llvmClass = NULL;
-    llvmConstClass = NULL;
-    llvmInProgress = false;
-    llvmHasUnions = false;
-    llvmUnion = NULL;
-    llvmIrStruct = NULL;
-    llvmClassDeclared = false;
-    llvmClassDefined = false;
+    irStruct = NULL;
 }
 
 enum PROT AggregateDeclaration::prot()
--- a/gen/classes.cpp	Thu Jan 17 03:15:12 2008 +0100
+++ b/gen/classes.cpp	Fri Jan 18 16:42:16 2008 +0100
@@ -20,21 +20,54 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
+static void LLVM_AddBaseClassInterfaces(ClassDeclaration* target, BaseClasses* bcs)
+{
+    // add base class data members first
+    for (int j=0; j<bcs->dim; j++)
+    {
+        BaseClass* bc = (BaseClass*)(bcs->data[j]);
+
+        // resolve interfaces while we're at it
+        if (bc->base->isInterfaceDeclaration())
+        {
+            Logger::println("adding interface '%s'", bc->base->toPrettyChars());
+            IrInterface* iri = new IrInterface(bc, NULL);
+            target->irStruct->interfaces.insert(std::make_pair(bc->base, iri));
+            if (!target->isAbstract()) {
+                // Fill in vtbl[]
+                bc->fillVtbl(target, &bc->vtbl, 0);
+            }
+            DtoResolveClass(bc->base);
+        }
+
+        // base *classes* might add more interfaces?
+        LLVM_AddBaseClassInterfaces(target, &bc->base->baseclasses);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
 static void LLVM_AddBaseClassData(BaseClasses* bcs)
 {
     // add base class data members first
     for (int j=0; j<bcs->dim; j++)
     {
         BaseClass* bc = (BaseClass*)(bcs->data[j]);
+
+        // interfaces never add data fields
         if (bc->base->isInterfaceDeclaration())
-            continue; // interfaces only have methods
+            continue;
 
+        // recursively add baseclass data
         LLVM_AddBaseClassData(&bc->base->baseclasses);
 
+        Array* arr = &bc->base->fields;
+        if (arr->dim == 0)
+            continue;
+
         Logger::println("Adding base class members of %s", bc->base->toChars());
         LOG_SCOPE;
 
-        Array* arr = &bc->base->fields;
         for (int k=0; k < arr->dim; k++) {
             VarDeclaration* v = (VarDeclaration*)(arr->data[k]);
             v->toObjFile();
@@ -57,10 +90,10 @@
     TypeClass* ts = (TypeClass*)cd->type;
 
     // make sure the IrStruct is created
-    IrStruct* irstruct = cd->llvmIrStruct;
+    IrStruct* irstruct = cd->irStruct;
     if (!irstruct) {
         irstruct = new IrStruct(ts);
-        cd->llvmIrStruct = irstruct;
+        cd->irStruct = irstruct;
     }
 
     // resolve the base class
@@ -69,15 +102,18 @@
     }
 
     // resolve interface vtables
-    if (cd->vtblInterfaces) {
+    /*if (cd->vtblInterfaces) {
+        Logger::println("Vtbl interfaces for '%s'", cd->toPrettyChars());
+        LOG_SCOPE;
         for (int i=0; i < cd->vtblInterfaces->dim; i++) {
             BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i];
             ClassDeclaration *id = b->base;
+            Logger::println("Vtbl interface: '%s'", id->toPrettyChars());
             DtoResolveClass(id);
             // Fill in vtbl[]
             b->fillVtbl(cd, &b->vtbl, 1);
         }
-    }
+    }*/
 
     gIR->structs.push_back(irstruct);
     gIR->classes.push_back(cd);
@@ -92,23 +128,7 @@
     // add monitor
     fieldtypes.push_back(getPtrToType(llvm::Type::Int8Ty));
 
-    // add interface vtables
-    if (cd->vtblInterfaces)
-    for (size_t i = 0; i < cd->vtblInterfaces->dim; i++)
-    {
-        BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i];
-        ClassDeclaration *id = b->base;
-        assert(id->type->ty == Tclass);
-        TypeClass* itc = (TypeClass*)id->type;
-        const llvm::Type* ivtblTy = getPtrToType(itc->llvmVtblType->get());
-        fieldtypes.push_back(ivtblTy);
-
-        // add this interface to the map
-        IrInterface* iri = new IrInterface(b, isaStruct(itc->llvmVtblType->get()));
-        irstruct->interfaces.insert(std::make_pair(id, iri));
-    }
-
-    // base classes first
+    // add base class data fields first
     LLVM_AddBaseClassData(&cd->baseclasses);
 
     // then add own members
@@ -149,14 +169,14 @@
                     fieldpad += s - prevsize;
                     prevsize = s;
                 }
-                cd->llvmHasUnions = true;
+                cd->irStruct->hasUnions = true;
                 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;
+                cd->irStruct->hasUnions = true;
                 i->second.var->irField->index = idx;
                 i->second.var->irField->indexOffset = (i->first - lastoffset) / s;
             }
@@ -190,21 +210,44 @@
         }
     }
 
-    /*
-    // add field types
-    for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
-        fieldtypes.push_back(i->second.type);
+    // populate interface map
+    {
+        Logger::println("Adding interfaces to '%s'", cd->toPrettyChars());
+        LOG_SCOPE;
+        LLVM_AddBaseClassInterfaces(cd, &cd->baseclasses);
+        Logger::println("%d interfaces added", cd->irStruct->interfaces.size());
     }
-    */
+
+    // add interface vtables at the end
+    int interIdx = (int)fieldtypes.size();
+    for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
+    {
+        ClassDeclaration* id = i->first;
+        IrInterface* iri = i->second;
 
+        // set vtbl type
+        TypeClass* itc = (TypeClass*)id->type;
+        const llvm::Type* ivtblTy = getPtrToType(itc->llvmVtblType->get());
+        fieldtypes.push_back(ivtblTy);
+
+        // fix the interface vtable type
+        iri->vtblTy = isaStruct(itc->llvmVtblType->get());
+
+        // set index
+        iri->index = interIdx++;
+    }
+    Logger::println("%d interface vtables added", cd->irStruct->interfaces.size());
+
+    // create type
     const llvm::StructType* structtype = llvm::StructType::get(fieldtypes);
+
     // refine abstract types for stuff like: class C {C next;}
     assert(irstruct->recty != 0);
-
     llvm::PATypeHolder& spa = irstruct->recty;
     llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype);
     structtype = isaStruct(spa.get());
 
+    // make it official
     if (!ts->llvmType)
         ts->llvmType = new llvm::PATypeHolder(structtype);
     else
@@ -214,22 +257,8 @@
     // name the type
     gIR->module->addTypeName(cd->mangle(), ts->llvmType->get());
 
-    // build interface info type
-    std::vector<const llvm::Type*> infoTypes;
-    // ClassInfo classinfo
-    ClassDeclaration* cinfod = ClassDeclaration::classinfo;
-    DtoResolveClass(cinfod);
-    infoTypes.push_back(getPtrToType(cinfod->type->llvmType->get()));
-    // void*[] vtbl
-    std::vector<const llvm::Type*> infoVtbltypes;
-    infoVtbltypes.push_back(DtoSize_t());
-    const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
-    infoVtbltypes.push_back(byteptrptrty);
-    infoTypes.push_back(llvm::StructType::get(infoVtbltypes));
-    // int offset
-    infoTypes.push_back(llvm::Type::Int32Ty);
-    // create type
-    const llvm::StructType* infoTy = llvm::StructType::get(infoTypes);
+    // get interface info type
+    const llvm::StructType* infoTy = DtoInterfaceInfoType();
 
     // create vtable type
     llvm::GlobalVariable* svtblVar = 0;
@@ -256,9 +285,8 @@
             if (cd->isInterfaceDeclaration()) {
                 cinfoty = infoTy;
             }
-            else if (cd != cinfod) {
-                DtoResolveClass(cinfod);
-                cinfoty = cinfod->type->llvmType->get();
+            else if (cd != ClassDeclaration::classinfo) {
+                cinfoty = ClassDeclaration::classinfo->type->llvmType->get();
             }
             else {
                 // this is the ClassInfo class, the type is this type
@@ -300,8 +328,8 @@
     assert(cd->type->ty == Tclass);
     TypeClass* ts = (TypeClass*)cd->type;
 
-    assert(cd->llvmIrStruct);
-    IrStruct* irstruct = cd->llvmIrStruct;
+    assert(cd->irStruct);
+    IrStruct* irstruct = cd->irStruct;
 
     gIR->structs.push_back(irstruct);
     gIR->classes.push_back(cd);
@@ -322,20 +350,20 @@
         varname.append("6__vtblZ");
 
         const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get());
-        cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module);
+        cd->irStruct->vtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module);
     }
 
     // get interface info type
     const llvm::StructType* infoTy = DtoInterfaceInfoType();
 
     // interface info array
-    if (cd->vtblInterfaces->dim > 0) {
+    if (!cd->irStruct->interfaces.empty()) {
         // 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);
+        const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->irStruct->interfaces.size());
         // declare global
         irstruct->interfaceInfosTy = arrTy;
         irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
@@ -370,7 +398,7 @@
         initname.append("6__initZ");
 
         llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module);
-        cd->llvmInit = initvar;
+        cd->irStruct->init = initvar;
     }
 
     gIR->classes.pop_back();
@@ -401,7 +429,7 @@
     Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
     LOG_SCOPE;
 
-    IrStruct* irstruct = cd->llvmIrStruct;
+    IrStruct* irstruct = cd->irStruct;
     gIR->structs.push_back(irstruct);
     gIR->classes.push_back(cd);
 
@@ -436,16 +464,31 @@
     }
     else
     {
-        assert(cd->llvmVtbl != 0);
-        fieldinits.push_back(cd->llvmVtbl);
+        assert(cd->irStruct->vtbl != 0);
+        fieldinits.push_back(cd->irStruct->vtbl);
     }
 
     // then comes monitor
     fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
 
-    size_t dataoffset = 2;
+    // go through the field inits and build the default initializer
+    size_t nfi = irstruct->defaultFields.size();
+    for (size_t i=0; i<nfi; ++i) {
+        llvm::Constant* c;
+        if (irstruct->defaultFields[i]) {
+            c = irstruct->defaultFields[i]->irField->constInit;
+            assert(c);
+        }
+        else {
+            const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2));
+            assert(arrty);
+            std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
+            c = llvm::ConstantArray::get(arrty, vals);
+        }
+        fieldinits.push_back(c);
+    }
 
-    // next comes interface vtables
+    // last comes interface vtables
     const llvm::StructType* infoTy = DtoInterfaceInfoType();
     for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
     {
@@ -453,48 +496,27 @@
         iri->infoTy = infoTy;
         if (cd->isAbstract())
         {
-            fieldinits.push_back(llvm::Constant::getNullValue(iri->vtblTy));
+            fieldinits.push_back(llvm::Constant::getNullValue(structtype->getElementType(iri->index)));
         }
         else
         {
             assert(iri->vtbl);
             fieldinits.push_back(iri->vtbl);
-            ++dataoffset;
         }
     }
 
-    /*
-    // rest
-    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);
-    }
-    */
-
-    // go through the field inits and build the default initializer
-    size_t nfi = irstruct->defaultFields.size();
-    for (size_t i=0; i<nfi; ++i) {
-        llvm::Constant* c;
-        if (irstruct->defaultFields[i] != NULL) {
-            c = irstruct->defaultFields[i]->irField->constInit;
-            assert(c);
-        }
-        else {
-            const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+dataoffset));
-            std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
-            c = llvm::ConstantArray::get(arrty, vals);
-        }
-        fieldinits.push_back(c);
-    }
-
     // generate initializer
 #if 0
-    Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n';
-
+    //Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n';
+    assert(fieldinits.size() == structtype->getNumElements());
     for(size_t i=0; i<structtype->getNumElements(); ++i) {
         Logger::cout() << "s#" << i << " = " << *structtype->getElementType(i) << '\n';
+        Logger::cout() << "i#" << i << " = " << *fieldinits[i] << '\n';
+        assert(fieldinits[i]->getType() == structtype->getElementType(i));
     }
+#endif
 
+#if 0
     for(size_t i=0; i<fieldinits.size(); ++i) {
         Logger::cout() << "i#" << i << " = " << *fieldinits[i]->getType() << '\n';
     }
@@ -502,10 +524,11 @@
 
     llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits);
     assert(_init);
-    cd->llvmConstInit = _init;
+    cd->irStruct->constInit = _init;
 
     // abstract classes have no static vtable
-    if (!cd->isAbstract())
+    // neither do interfaces (on their own, the implementing class supplies the vtable)
+    if (!cd->isInterfaceDeclaration() && !cd->isAbstract())
     {
         // generate vtable initializer
         std::vector<llvm::Constant*> sinits;
@@ -526,8 +549,8 @@
                 sinits.push_back(c);
             }
             else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) {
-                assert(cd->llvmClass);
-                llvm::Constant* c = cd->llvmClass;
+                assert(cd->irStruct->classInfo);
+                llvm::Constant* c = cd->irStruct->classInfo;
                 sinits.push_back(c);
             }
             else
@@ -546,11 +569,9 @@
 #endif
 
         llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits);
-        cd->llvmConstVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit);
+        cd->irStruct->constVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit);
 
         // create interface vtable const initalizers
-        int idx = 2;
-        int idxScale = PTRSIZE;
         for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
         {
             ClassDeclaration* id = i->first;
@@ -566,8 +587,8 @@
             std::vector<llvm::Constant*> infoInits;
 
             // classinfo
-            assert(id->llvmClass);
-            llvm::Constant* c = id->llvmClass;
+            assert(id->irStruct->classInfo);
+            llvm::Constant* c = id->irStruct->classInfo;
             infoInits.push_back(c);
 
             // vtbl
@@ -577,7 +598,14 @@
             infoInits.push_back(c);
 
             // offset
-            infoInits.push_back(DtoConstInt(idx*idxScale));
+            // generate target independent offset with constGEP
+            /*llvm::Value* cidx = DtoConstInt(iri->index);
+            Logger::cout() << "offset to interface in class type: " << *cd->type->llvmType->get() << '\n';
+            size_t ioff = gTargetData->getIndexedOffset(cd->type->llvmType->get(), &cidx, 1);
+            infoInits.push_back(DtoConstUint(ioff));*/
+            assert(iri->index >= 0);
+            size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->llvmType->get()))->getElementOffset(iri->index);
+            infoInits.push_back(DtoConstUint(ioff));
 
             // create interface info initializer constant
             iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
@@ -592,6 +620,7 @@
             {
                 Logger::println("interface vtbl const init nr. %d", k);
                 Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k];
+                assert(dsym);
                 FuncDeclaration* fd = dsym->isFuncDeclaration();
                 assert(fd);
                 DtoForceDeclareDsymbol(fd);
@@ -603,7 +632,7 @@
                 iinits.push_back(c);
             }
 
-    #if 1
+    #if 0
             for (size_t x=0; x< iinits.size(); ++x)
             {
                 Logger::cout() << "field[" << x << "] = " << *ivtbl_ty->getElementType(x) << "\n\n";
@@ -614,12 +643,10 @@
 
             llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits);
             iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit);
-
-            idx++;
         }
     }
     // we always generate interfaceinfos as best we can
-    else
+    /*else
     {
         for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
         {
@@ -634,8 +661,8 @@
             std::vector<llvm::Constant*> infoInits;
 
             // classinfo
-            assert(id->llvmClass);
-            llvm::Constant* c = id->llvmClass;
+            assert(id->irStruct->classInfo);
+            llvm::Constant* c = id->irStruct->classInfo;
             infoInits.push_back(c);
 
             // vtbl
@@ -649,7 +676,7 @@
             // 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();
@@ -674,11 +701,11 @@
         // neither do abstract classes
         if (!cd->isInterfaceDeclaration() && !cd->isAbstract())
         {
-            cd->llvmInit->setInitializer(cd->llvmConstInit);
-            cd->llvmVtbl->setInitializer(cd->llvmConstVtbl);
+            cd->irStruct->init->setInitializer(cd->irStruct->constInit);
+            cd->irStruct->vtbl->setInitializer(cd->irStruct->constVtbl);
 
             // initialize interface vtables
-            IrStruct* irstruct = cd->llvmIrStruct;
+            IrStruct* irstruct = cd->irStruct;
             std::vector<llvm::Constant*> infoInits;
             for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
             {
@@ -716,7 +743,7 @@
     {
         llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass");
         std::vector<llvm::Value*> args;
-        args.push_back(tc->sym->llvmClass);
+        args.push_back(tc->sym->irStruct->classInfo);
         mem = gIR->ir->CreateCall(fn, args.begin(), args.end(), "newclass_gc_alloc");
         mem = DtoBitCast(mem, DtoType(tc), "newclass_gc");
     }
@@ -731,7 +758,7 @@
         LOG_SCOPE;
         DValue* thisval = newexp->thisexp->toElem(gIR);
         size_t idx = 2;
-        idx += tc->sym->llvmIrStruct->interfaces.size();
+        idx += tc->sym->irStruct->interfaces.size();
         llvm::Value* dst = thisval->getRVal();
         llvm::Value* src = DtoGEPi(mem,0,idx,"tmp");
         Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
@@ -743,7 +770,7 @@
         Logger::println("Resolving nested context");
         LOG_SCOPE;
         size_t idx = 2;
-        idx += tc->sym->llvmIrStruct->interfaces.size();
+        idx += tc->sym->irStruct->interfaces.size();
         llvm::Value* nest = gIR->func()->decl->irFunc->nestedVar;
         if (!nest)
             nest = gIR->func()->decl->irFunc->thisVar;
@@ -769,8 +796,8 @@
     uint64_t n = getABITypeSize(tc->llvmType->get()) - presz;
 
     // set vtable field seperately, this might give better optimization
-    assert(tc->sym->llvmVtbl);
-    DtoStore(tc->sym->llvmVtbl, DtoGEPi(dst,0,0,"vtbl"));
+    assert(tc->sym->irStruct->vtbl);
+    DtoStore(tc->sym->irStruct->vtbl, DtoGEPi(dst,0,0,"vtbl"));
 
     // monitor always defaults to zero
     llvm::Value* tmp = DtoGEPi(dst,0,1,"monitor");
@@ -781,15 +808,15 @@
         return;
 
     // copy the rest from the static initializer
-    assert(tc->sym->llvmInit);
-    assert(dst->getType() == tc->sym->llvmInit->getType());
+    assert(tc->sym->irStruct->init);
+    assert(dst->getType() == tc->sym->irStruct->init->getType());
 
     const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty);
 
     llvm::Value* dstarr = DtoGEPi(dst,0,2,"tmp");
     dstarr = DtoBitCast(dstarr, arrty);
 
-    llvm::Value* srcarr = DtoGEPi(tc->sym->llvmInit,0,2,"tmp");
+    llvm::Value* srcarr = DtoGEPi(tc->sym->irStruct->init,0,2,"tmp");
     srcarr = DtoBitCast(srcarr, arrty);
 
     llvm::Function* fn = LLVM_DeclareMemCpy32();
@@ -912,8 +939,8 @@
     // ClassInfo c
     TypeClass* to = (TypeClass*)DtoDType(_to);
     DtoForceDeclareDsymbol(to->sym);
-    assert(to->sym->llvmClass);
-    tmp = to->sym->llvmClass;
+    assert(to->sym->irStruct->classInfo);
+    tmp = to->sym->irStruct->classInfo;
     // unfortunately this is needed as the implementation of object differs somehow from the declaration
     // this could happen in user code as well :/
     tmp = DtoBitCast(tmp, funcTy->getParamType(1));
@@ -978,8 +1005,8 @@
     // ClassInfo c
     TypeClass* to = (TypeClass*)DtoDType(_to);
     DtoForceDeclareDsymbol(to->sym);
-    assert(to->sym->llvmClass);
-    tmp = to->sym->llvmClass;
+    assert(to->sym->irStruct->classInfo);
+    tmp = to->sym->irStruct->classInfo;
     // unfortunately this is needed as the implementation of object differs somehow from the declaration
     // this could happen in user code as well :/
     tmp = DtoBitCast(tmp, funcTy->getParamType(1));
@@ -1045,13 +1072,13 @@
     const llvm::Type* llt = getPtrToType(DtoType(t));
     const llvm::Type* st = DtoType(cd->type);
     if (ptr->getType() != st) {
-        assert(cd->llvmHasUnions);
+        assert(cd->irStruct->hasUnions);
         ptr = gIR->ir->CreateBitCast(ptr, st, "tmp");
     }
 
-    unsigned dataoffset = 2 + cd->vtblInterfaces->dim;
+    unsigned dataoffset = 2;
 
-    IrStruct* irstruct = cd->llvmIrStruct;
+    IrStruct* irstruct = cd->irStruct;
     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];
@@ -1134,8 +1161,8 @@
 
 void DtoDeclareClassInfo(ClassDeclaration* cd)
 {
-    if (cd->llvmClassDeclared) return;
-    cd->llvmClassDeclared = true;
+    if (cd->irStruct->classDeclared) return;
+    cd->irStruct->classDeclared = true;
 
     Logger::println("DtoDeclareClassInfo(%s)", cd->toChars());
     LOG_SCOPE;
@@ -1152,7 +1179,7 @@
 
     const llvm::Type* st = cinfo->type->llvmType->get();
 
-    cd->llvmClass = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module);
+    cd->irStruct->classInfo = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module);
 }
 
 static llvm::Constant* build_offti_entry(VarDeclaration* vd)
@@ -1325,21 +1352,21 @@
 //         void *defaultConstructor;
 //        }
 
-    if (cd->llvmClassDefined) return;
-    cd->llvmClassDefined = true;
+    if (cd->irStruct->classDefined) return;
+    cd->irStruct->classDefined = true;
 
     Logger::println("DtoDefineClassInfo(%s)", cd->toChars());
     LOG_SCOPE;
 
     assert(cd->type->ty == Tclass);
-    assert(cd->llvmClass);
+    assert(cd->irStruct->classInfo);
 
     TypeClass* cdty = (TypeClass*)cd->type;
     if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
-        assert(cd->llvmInit);
-        assert(cd->llvmConstInit);
-        assert(cd->llvmVtbl);
-        assert(cd->llvmConstVtbl);
+        assert(cd->irStruct->init);
+        assert(cd->irStruct->constInit);
+        assert(cd->irStruct->vtbl);
+        assert(cd->irStruct->constVtbl);
     }
 
     // holds the list of initializers for llvm
@@ -1347,28 +1374,28 @@
 
     ClassDeclaration* cinfo = ClassDeclaration::classinfo;
     DtoForceConstInitDsymbol(cinfo);
-    assert(cinfo->llvmConstInit);
+    assert(cinfo->irStruct->constInit);
 
     llvm::Constant* c;
 
     // own vtable
-    c = cinfo->llvmConstInit->getOperand(0);
+    c = cinfo->irStruct->constInit->getOperand(0);
     assert(c);
     inits.push_back(c);
 
     // monitor
-    c = cinfo->llvmConstInit->getOperand(1);
+    c = cinfo->irStruct->constInit->getOperand(1);
     inits.push_back(c);
 
     // byte[] init
     const llvm::Type* byteptrty = getPtrToType(llvm::Type::Int8Ty);
     if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
-        c = cinfo->llvmConstInit->getOperand(2);
+        c = cinfo->irStruct->constInit->getOperand(2);
     }
     else {
-        c = llvm::ConstantExpr::getBitCast(cd->llvmInit, byteptrty);
-        assert(!cd->llvmConstInit->getType()->isAbstract());
-        size_t initsz = getABITypeSize(cd->llvmConstInit->getType());
+        c = llvm::ConstantExpr::getBitCast(cd->irStruct->init, byteptrty);
+        assert(!cd->irStruct->constInit->getType()->isAbstract());
+        size_t initsz = getABITypeSize(cd->irStruct->constInit->getType());
         c = DtoConstSlice(DtoConstSize_t(initsz), c);
     }
     inits.push_back(c);
@@ -1387,25 +1414,25 @@
 
     // vtbl array
     if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
-        c = cinfo->llvmConstInit->getOperand(4);
+        c = cinfo->irStruct->constInit->getOperand(4);
     }
     else {
         const llvm::Type* byteptrptrty = getPtrToType(byteptrty);
-        assert(!cd->llvmVtbl->getType()->isAbstract());
-        c = llvm::ConstantExpr::getBitCast(cd->llvmVtbl, byteptrptrty);
-        assert(!cd->llvmConstVtbl->getType()->isAbstract());
-        size_t vtblsz = cd->llvmConstVtbl->getType()->getNumElements();
+        assert(!cd->irStruct->vtbl->getType()->isAbstract());
+        c = llvm::ConstantExpr::getBitCast(cd->irStruct->vtbl, byteptrptrty);
+        assert(!cd->irStruct->constVtbl->getType()->isAbstract());
+        size_t vtblsz = cd->irStruct->constVtbl->getType()->getNumElements();
         c = DtoConstSlice(DtoConstSize_t(vtblsz), c);
     }
     inits.push_back(c);
 
     // interfaces array
-    IrStruct* irstruct = cd->llvmIrStruct;
+    IrStruct* irstruct = cd->irStruct;
     if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) {
-        c = cinfo->llvmConstInit->getOperand(5);
+        c = cinfo->irStruct->constInit->getOperand(5);
     }
     else {
-        const llvm::Type* t = cinfo->llvmConstInit->getOperand(5)->getType()->getContainedType(1);
+        const llvm::Type* t = cinfo->irStruct->constInit->getOperand(5)->getType()->getContainedType(1);
         c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t);
         size_t iisz = irstruct->interfaceInfosTy->getNumElements();
         c = DtoConstSlice(DtoConstSize_t(iisz), c);
@@ -1415,19 +1442,19 @@
     // base classinfo
     if (cd->baseClass && !cd->isInterfaceDeclaration() && !cd->isAbstract()) {
         DtoDeclareClassInfo(cd->baseClass);
-        c = cd->baseClass->llvmClass;
+        c = cd->baseClass->irStruct->classInfo;
         assert(c);
         inits.push_back(c);
     }
     else {
         // null
-        c = cinfo->llvmConstInit->getOperand(6);
+        c = cinfo->irStruct->constInit->getOperand(6);
         inits.push_back(c);
     }
 
     // destructor
     if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
-        c = cinfo->llvmConstInit->getOperand(7);
+        c = cinfo->irStruct->constInit->getOperand(7);
     }
     else {
         c = build_class_dtor(cd);
@@ -1436,12 +1463,12 @@
 
     // invariant
     // TODO
-    c = cinfo->llvmConstInit->getOperand(8);
+    c = cinfo->irStruct->constInit->getOperand(8);
     inits.push_back(c);
 
     // uint flags
     if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
-        c = cinfo->llvmConstInit->getOperand(9);
+        c = cinfo->irStruct->constInit->getOperand(9);
     }
     else {
         uint flags = build_classinfo_flags(cd);
@@ -1451,15 +1478,15 @@
 
     // allocator
     // TODO
-    c = cinfo->llvmConstInit->getOperand(10);
+    c = cinfo->irStruct->constInit->getOperand(10);
     inits.push_back(c);
 
     // offset typeinfo
     if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
-        c = cinfo->llvmConstInit->getOperand(11);
+        c = cinfo->irStruct->constInit->getOperand(11);
     }
     else {
-        c = build_offti_array(cd, cinfo->llvmConstInit->getOperand(11));
+        c = build_offti_array(cd, cinfo->irStruct->constInit->getOperand(11));
     }
     inits.push_back(c);
 
@@ -1467,11 +1494,11 @@
     if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) {
         DtoForceDeclareDsymbol(cd->defaultCtor);
         c = isaConstant(cd->defaultCtor->irFunc->func);
-        const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType();
+        const llvm::Type* toTy = cinfo->irStruct->constInit->getOperand(12)->getType();
         c = llvm::ConstantExpr::getBitCast(c, toTy);
     }
     else {
-        c = cinfo->llvmConstInit->getOperand(12);
+        c = cinfo->irStruct->constInit->getOperand(12);
     }
     inits.push_back(c);
 
@@ -1482,10 +1509,10 @@
     }*/
 
     // build the initializer
-    const llvm::StructType* st = isaStruct(cinfo->llvmConstInit->getType());
+    const llvm::StructType* st = isaStruct(cinfo->irStruct->constInit->getType());
     llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits);
     //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n';
 
-    cd->llvmConstClass = finalinit;
-    cd->llvmClass->setInitializer(finalinit);
+    cd->irStruct->constClassInfo = finalinit;
+    cd->irStruct->classInfo->setInitializer(finalinit);
 }
--- a/gen/functions.cpp	Thu Jan 17 03:15:12 2008 +0100
+++ b/gen/functions.cpp	Fri Jan 18 16:42:16 2008 +0100
@@ -74,10 +74,10 @@
         ClassDeclaration* ti = Type::typeinfo;
         ti->toObjFile();
         DtoForceConstInitDsymbol(ti);
-        assert(ti->llvmConstInit);
+        assert(ti->irStruct->constInit);
         std::vector<const llvm::Type*> types;
         types.push_back(DtoSize_t());
-        types.push_back(getPtrToType(getPtrToType(ti->llvmConstInit->getType())));
+        types.push_back(getPtrToType(getPtrToType(ti->irStruct->constInit->getType())));
         const llvm::Type* t1 = llvm::StructType::get(types);
         paramvec.push_back(getPtrToType(t1));
         paramvec.push_back(getPtrToType(llvm::Type::Int8Ty));
--- a/gen/statements.cpp	Thu Jan 17 03:15:12 2008 +0100
+++ b/gen/statements.cpp	Fri Jan 18 16:42:16 2008 +0100
@@ -130,13 +130,12 @@
     Logger::println("ExpStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
-    if (global.params.llvmAnnotate)
-        DtoAnnotation(exp->toChars());
-
     if (global.params.symdebug)
         DtoDwarfStopPoint(loc.linnum);
 
-    if (exp != 0) {
+    if (exp) {
+        if (global.params.llvmAnnotate)
+            DtoAnnotation(exp->toChars());
         elem* e = exp->toElem(p);
         delete e;
     }
--- a/gen/structs.cpp	Thu Jan 17 03:15:12 2008 +0100
+++ b/gen/structs.cpp	Fri Jan 18 16:42:16 2008 +0100
@@ -99,7 +99,7 @@
     }
 
     DtoConstInitStruct((StructDeclaration*)si->ad);
-    return si->ad->llvmUnion->getConst(inits);
+    return si->ad->irStruct->dunion->getConst(inits);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -115,7 +115,7 @@
     const llvm::Type* llt = getPtrToType(DtoType(t));
     const llvm::Type* st = getPtrToType(DtoType(sd->type));
     if (ptr->getType() != st) {
-        assert(sd->llvmHasUnions);
+        assert(sd->irStruct->hasUnions);
         ptr = gIR->ir->CreateBitCast(ptr, st, "tmp");
     }
 
@@ -179,7 +179,7 @@
     TypeStruct* ts = (TypeStruct*)DtoDType(sd->type);
 
     IrStruct* irstruct = new IrStruct(ts);
-    sd->llvmIrStruct = irstruct;
+    sd->irStruct = irstruct;
     gIR->structs.push_back(irstruct);
 
     // fields
@@ -252,14 +252,14 @@
                     fieldpad += s - prevsize;
                     prevsize = s;
                 }
-                sd->llvmHasUnions = true;
+                sd->irStruct->hasUnions = true;
                 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;
+                sd->irStruct->hasUnions = true;
                 i->second.var->irField->index = idx;
                 i->second.var->irField->indexOffset = (i->first - lastoffset) / s;
             }
@@ -334,7 +334,7 @@
 
     llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
     llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module);
-    sd->llvmInit = initvar;
+    sd->irStruct->init = initvar;
 
     gIR->constInitList.push_back(sd);
     if (sd->getModule() == gIR->dmodule)
@@ -351,7 +351,7 @@
     Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars());
     LOG_SCOPE;
 
-    IrStruct* irstruct = sd->llvmIrStruct;
+    IrStruct* irstruct = sd->irStruct;
     gIR->structs.push_back(irstruct);
 
     // make sure each offset knows its default initializer
@@ -383,7 +383,7 @@
     }
 
     // generate the union mapper
-    sd->llvmUnion = new DUnion; // uses gIR->topstruct()
+    sd->irStruct->dunion = new DUnion; // uses gIR->topstruct()
 
     // always generate the constant initalizer
     if (!sd->zeroInit) {
@@ -399,11 +399,11 @@
         }
         Logger::cout() << "Initializer printed" << '\n';
         #endif
-        sd->llvmConstInit = llvm::ConstantStruct::get(structtype,fieldinits_ll);
+        sd->irStruct->constInit = llvm::ConstantStruct::get(structtype,fieldinits_ll);
     }
     else {
         Logger::println("Zero initialized");
-        sd->llvmConstInit = llvm::ConstantAggregateZero::get(structtype);
+        sd->irStruct->constInit = llvm::ConstantAggregateZero::get(structtype);
     }
 
     gIR->structs.pop_back();
@@ -425,7 +425,7 @@
 
     assert(sd->type->ty == Tstruct);
     TypeStruct* ts = (TypeStruct*)sd->type;
-    sd->llvmInit->setInitializer(sd->llvmConstInit);
+    sd->irStruct->init->setInitializer(sd->irStruct->constInit);
 
     sd->llvmDModule = gIR->dmodule;
 }
--- a/gen/toir.cpp	Thu Jan 17 03:15:12 2008 +0100
+++ b/gen/toir.cpp	Fri Jan 18 16:42:16 2008 +0100
@@ -194,8 +194,8 @@
         {
             Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
             DtoDeclareClassInfo(cid->cd);
-            assert(cid->cd->llvmClass);
-            return new DVarValue(vd, cid->cd->llvmClass, true);
+            assert(cid->cd->irStruct->classInfo);
+            return new DVarValue(vd, cid->cd->irStruct->classInfo, true);
         }
         // nested variable
         else if (vd->nestedref) {
@@ -247,8 +247,8 @@
         assert(sdecltype->ty == Tstruct);
         TypeStruct* ts = (TypeStruct*)sdecltype;
         assert(ts->sym);
-        assert(ts->sym->llvmInit);
-        return new DVarValue(type, ts->sym->llvmInit, true);
+        assert(ts->sym->irStruct->init);
+        return new DVarValue(type, ts->sym->irStruct->init, true);
     }
     else
     {
@@ -272,8 +272,8 @@
         assert(sdecltype->ty == Tstruct);
         TypeStruct* ts = (TypeStruct*)sdecltype;
         DtoForceConstInitDsymbol(ts->sym);
-        assert(ts->sym->llvmConstInit);
-        return ts->sym->llvmConstInit;
+        assert(ts->sym->irStruct->constInit);
+        return ts->sym->irStruct->constInit;
     }
     else if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
     {
@@ -1068,8 +1068,8 @@
             }
 
             // build type info array
-            assert(Type::typeinfo->llvmConstInit);
-            const llvm::Type* typeinfotype = getPtrToType(Type::typeinfo->llvmConstInit->getType());
+            assert(Type::typeinfo->irStruct->constInit);
+            const llvm::Type* typeinfotype = getPtrToType(Type::typeinfo->irStruct->constInit->getType());
             Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n';
             const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
 
@@ -1907,7 +1907,7 @@
         }
         else {
             assert(ts->sym);
-            DtoStructCopy(emem,ts->sym->llvmInit);
+            DtoStructCopy(emem,ts->sym->irStruct->init);
         }
     }
 
@@ -2585,7 +2585,7 @@
     unsigned n = elements->dim;
 
     // unions might have different types for each literal
-    if (sd->llvmHasUnions) {
+    if (sd->irStruct->hasUnions) {
         // build the type of the literal
         std::vector<const llvm::Type*> tys;
         for (unsigned i=0; i<n; ++i) {
--- a/gen/tollvm.cpp	Thu Jan 17 03:15:12 2008 +0100
+++ b/gen/tollvm.cpp	Fri Jan 18 16:42:16 2008 +0100
@@ -116,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->irStruct->recty.get();//t->llvmType->get();
     }
 
     case Tclass:    {
@@ -139,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->irStruct->recty.get());//t->llvmType->get());
     }
 
     // functions
@@ -523,8 +523,8 @@
             TypeStruct* ts = (TypeStruct*)t;
             assert(ts);
             assert(ts->sym);
-            assert(ts->sym->llvmConstInit);
-            _init = ts->sym->llvmConstInit;
+            assert(ts->sym->irStruct->constInit);
+            _init = ts->sym->irStruct->constInit;
         }
         else if (t->ty == Tclass)
         {
@@ -732,7 +732,7 @@
         else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration())
         {
             size_t idx = 2;
-            idx += cd->llvmIrStruct->interfaces.size();
+            idx += cd->irStruct->interfaces.size();
             v = DtoGEPi(v,0,idx,"tmp");
             v = DtoLoad(v);
         }
@@ -1562,8 +1562,8 @@
             llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init);
             assert(t->ty == Tstruct);
             TypeStruct* ts = (TypeStruct*)t;
-            assert(ts->sym->llvmConstInit);
-            _init = ts->sym->llvmConstInit;
+            assert(ts->sym->irStruct->constInit);
+            _init = ts->sym->irStruct->constInit;
         }
         // array single value init
         else if (isaArray(_type))
--- a/gen/toobj.cpp	Thu Jan 17 03:15:12 2008 +0100
+++ b/gen/toobj.cpp	Fri Jan 18 16:42:16 2008 +0100
@@ -293,7 +293,7 @@
     llvm::Constant* c = 0;
 
     // vtable
-    c = moduleinfo->llvmVtbl;
+    c = moduleinfo->irStruct->vtbl;
     initVec.push_back(c);
 
     // monitor
@@ -335,7 +335,7 @@
         c = DtoConstSlice(DtoConstSize_t(importInits.size()), c);
     }
     else
-        c = moduleinfo->llvmConstInit->getOperand(3);
+        c = moduleinfo->irStruct->constInit->getOperand(3);
     initVec.push_back(c);
 
     // localClasses[]
@@ -360,8 +360,8 @@
             continue;
         }
         Logger::println("class: %s", cd->toPrettyChars());
-        assert(cd->llvmClass);
-        classInits.push_back(cd->llvmClass);
+        assert(cd->irStruct->classInfo);
+        classInits.push_back(cd->irStruct->classInfo);
     }
     // has class array?
     if (!classInits.empty())
@@ -376,7 +376,7 @@
         c = DtoConstSlice(DtoConstSize_t(classInits.size()), c);
     }
     else
-        c = moduleinfo->llvmConstInit->getOperand(4);
+        c = moduleinfo->irStruct->constInit->getOperand(4);
     initVec.push_back(c);
 
     // flags
@@ -387,25 +387,25 @@
 
     // ctor
     llvm::Function* fctor = build_module_ctor();
-    c = fctor ? fctor : moduleinfo->llvmConstInit->getOperand(6);
+    c = fctor ? fctor : moduleinfo->irStruct->constInit->getOperand(6);
     initVec.push_back(c);
 
     // dtor
     llvm::Function* fdtor = build_module_dtor();
-    c = fdtor ? fdtor : moduleinfo->llvmConstInit->getOperand(7);
+    c = fdtor ? fdtor : moduleinfo->irStruct->constInit->getOperand(7);
     initVec.push_back(c);
 
     // unitTest
     llvm::Function* unittest = build_module_unittest();
-    c = unittest ? unittest : moduleinfo->llvmConstInit->getOperand(8);
+    c = unittest ? unittest : moduleinfo->irStruct->constInit->getOperand(8);
     initVec.push_back(c);
 
     // xgetMembers
-    c = moduleinfo->llvmConstInit->getOperand(9);
+    c = moduleinfo->irStruct->constInit->getOperand(9);
     initVec.push_back(c);
 
     // ictor
-    c = moduleinfo->llvmConstInit->getOperand(10);
+    c = moduleinfo->irStruct->constInit->getOperand(10);
     initVec.push_back(c);
 
     /*Logger::println("MODULE INFO INITIALIZERS");
--- a/gen/typinf.cpp	Thu Jan 17 03:15:12 2008 +0100
+++ b/gen/typinf.cpp	Fri Jan 18 16:42:16 2008 +0100
@@ -372,7 +372,7 @@
 
     // vtbl
     std::vector<llvm::Constant*> sinits;
-    sinits.push_back(base->llvmVtbl);
+    sinits.push_back(base->irStruct->vtbl);
 
     // monitor
     sinits.push_back(getNullPtr(getPtrToType(llvm::Type::Int8Ty)));
@@ -457,7 +457,7 @@
 
     // vtbl
     std::vector<llvm::Constant*> sinits;
-    sinits.push_back(base->llvmVtbl);
+    sinits.push_back(base->irStruct->vtbl);
 
     // monitor
     sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
@@ -536,7 +536,7 @@
 
     // vtbl
     std::vector<llvm::Constant*> sinits;
-    sinits.push_back(base->llvmVtbl);
+    sinits.push_back(base->irStruct->vtbl);
 
     // monitor
     sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
@@ -647,7 +647,7 @@
     // initializer vector
     std::vector<llvm::Constant*> sinits;
     // first is always the vtable
-    sinits.push_back(base->llvmVtbl);
+    sinits.push_back(base->irStruct->vtbl);
 
     // monitor
     sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
@@ -710,7 +710,7 @@
     // initializer vector
     std::vector<llvm::Constant*> sinits;
     // first is always the vtable
-    sinits.push_back(base->llvmVtbl);
+    sinits.push_back(base->irStruct->vtbl);
 
     // monitor
     sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
@@ -845,7 +845,7 @@
 
     // vtbl
     std::vector<llvm::Constant*> sinits;
-    sinits.push_back(base->llvmVtbl);
+    sinits.push_back(base->irStruct->vtbl);
 
     // monitor
     sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
@@ -865,7 +865,7 @@
     else
     {
         size_t cisize = getTypeStoreSize(tc->llvmType->get());
-        llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(sd->llvmInit, initpt);
+        llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(sd->irStruct->init, initpt);
         sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
     }
 
@@ -1044,7 +1044,7 @@
     // initializer vector
     std::vector<llvm::Constant*> sinits;
     // first is always the vtable
-    sinits.push_back(base->llvmVtbl);
+    sinits.push_back(base->irStruct->vtbl);
 
     // monitor
     sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
@@ -1052,8 +1052,8 @@
     // get classinfo
     assert(tinfo->ty == Tclass);
     TypeClass *tc = (TypeClass *)tinfo;
-    assert(tc->sym->llvmClass);
-    sinits.push_back(tc->sym->llvmClass);
+    assert(tc->sym->irStruct->classInfo);
+    sinits.push_back(tc->sym->irStruct->classInfo);
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
@@ -1100,7 +1100,7 @@
     // initializer vector
     std::vector<llvm::Constant*> sinits;
     // first is always the vtable
-    sinits.push_back(base->llvmVtbl);
+    sinits.push_back(base->irStruct->vtbl);
 
     // monitor
     sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
@@ -1108,8 +1108,8 @@
     // get classinfo
     assert(tinfo->ty == Tclass);
     TypeClass *tc = (TypeClass *)tinfo;
-    assert(tc->sym->llvmClass);
-    sinits.push_back(tc->sym->llvmClass);
+    assert(tc->sym->irStruct->classInfo);
+    sinits.push_back(tc->sym->irStruct->classInfo);
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
@@ -1156,7 +1156,7 @@
     // initializer vector
     std::vector<llvm::Constant*> sinits;
     // first is always the vtable
-    sinits.push_back(base->llvmVtbl);
+    sinits.push_back(base->irStruct->vtbl);
 
     // monitor
     sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
--- a/ir/irstruct.cpp	Thu Jan 17 03:15:12 2008 +0100
+++ b/ir/irstruct.cpp	Fri Jan 18 16:42:16 2008 +0100
@@ -13,6 +13,8 @@
     infoTy = NULL;
     infoInit = NULL;
     info = NULL;
+
+    index = -1;
 }
 
 IrInterface::~IrInterface()
@@ -31,6 +33,18 @@
     constinited = false;
     interfaceInfosTy = NULL;
     interfaceInfos = NULL;
+
+    vtbl = NULL;
+    constVtbl = NULL;
+    init = NULL;
+    constInit = NULL;
+    classInfo = NULL;
+    constClassInfo = NULL;
+    hasUnions = false;
+    dunion = NULL;
+
+    classDeclared = false;
+    classDefined = false;
 }
 
 IrStruct::~IrStruct()
--- a/ir/irstruct.h	Thu Jan 17 03:15:12 2008 +0100
+++ b/ir/irstruct.h	Fri Jan 18 16:42:16 2008 +0100
@@ -19,6 +19,8 @@
     llvm::ConstantStruct* infoInit;
     llvm::Constant* info;
 
+    int index;
+
     IrInterface(BaseClass* b, const llvm::StructType* vt);
     ~IrInterface();
 };
@@ -60,6 +62,17 @@
 
     bool defined;
     bool constinited;
+
+    llvm::GlobalVariable* vtbl;
+    llvm::ConstantStruct* constVtbl;
+    llvm::GlobalVariable* init;
+    llvm::Constant* constInit;
+    llvm::GlobalVariable* classInfo;
+    llvm::Constant* constClassInfo;
+    bool hasUnions;
+    DUnion* dunion;
+    bool classDeclared;
+    bool classDefined;
 };
 
 #endif
--- a/llvmdc.kdevelop	Thu Jan 17 03:15:12 2008 +0100
+++ b/llvmdc.kdevelop	Fri Jan 18 16:42:16 2008 +0100
@@ -602,6 +602,9 @@
         <default/>
       </environments>
     </make>
+    <general>
+      <activedir>ir</activedir>
+    </general>
   </kdevcustomproject>
   <cppsupportpart>
     <filetemplates>
--- a/llvmdc.kdevelop.filelist	Thu Jan 17 03:15:12 2008 +0100
+++ b/llvmdc.kdevelop.filelist	Fri Jan 18 16:42:16 2008 +0100
@@ -139,12 +139,9 @@
 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
--- a/tango/lib/compiler/llvmdc/cast.d	Thu Jan 17 03:15:12 2008 +0100
+++ b/tango/lib/compiler/llvmdc/cast.d	Fri Jan 18 16:42:16 2008 +0100
@@ -40,20 +40,24 @@
 
 Object _d_toObject(void* p)
 {   Object o;
-
+    debug(PRINTF) printf("toObject(%p)\n", p);
     if (p)
     {
         o = cast(Object)p;
+        debug(PRINTF) printf("o = %p\n", o);
+        debug(PRINTF) printf("o.vtbl = %p\n", *cast(void**)p);
         ClassInfo oc = o.classinfo;
+        debug(PRINTF) printf("oc = %p\n", oc);
         Interface *pi = **cast(Interface ***)p;
+        debug(PRINTF) printf("pi = %p\n", pi);
 
         /* Interface.offset lines up with ClassInfo.name.ptr,
          * so we rely on pointers never being less than 64K,
-         * and Objects never being greater.
+         * and interface vtable offsets never being greater.
          */
         if (pi.offset < 0x10000)
         {
-            //printf("\tpi.offset = %d\n", pi.offset);
+            debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset);
             o = cast(Object)(p - pi.offset);
         }
     }
@@ -70,12 +74,12 @@
 Object _d_interface_cast(void* p, ClassInfo c)
 {   Object o;
 
-    //printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name);
+    debug(PRINTF) printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name.length, c.name.ptr);
     if (p)
     {
         Interface *pi = **cast(Interface ***)p;
 
-        //printf("\tpi.offset = %d\n", pi.offset);
+        debug(PRINTF) printf("\tpi.offset = %d\n", pi.offset);
         o = cast(Object)(p - pi.offset);
         return _d_dynamic_cast(o, c);
     }
@@ -94,7 +98,7 @@
         oc = o.classinfo;
         if (_d_isbaseof2(oc, c, offset))
         {
-            //printf("\toffset = %d\n", offset);
+            debug(PRINTF) printf("\toffset = %d\n", offset);
             o = cast(Object)(cast(void*)o + offset);
         }
         else
--- a/tango/lib/compiler/llvmdc/lifetime.d	Thu Jan 17 03:15:12 2008 +0100
+++ b/tango/lib/compiler/llvmdc/lifetime.d	Fri Jan 18 16:42:16 2008 +0100
@@ -27,7 +27,7 @@
 module lifetime;
 
 //debug=PRINTF;
-debug=PRINTF2;
+//debug=PRINTF2;
 
 private
 {
@@ -89,7 +89,7 @@
 {
     void* p;
 
-    debug(PRINTF) printf("_d_newclass(ci = %p, %s)\n", ci, cast(char *)ci.name.ptr);
+    debug(PRINTF2) printf("_d_newclass(ci = %p, %s)\n", ci, cast(char *)ci.name.ptr);
     /+
     if (ci.flags & 1) // if COM object
     {   /* COM objects are not garbage collected, they are reference counted
@@ -109,18 +109,18 @@
         debug(PRINTF2) printf(" p = %p\n", p);
     }
 
-    debug(PRINTF)
+    debug(PRINTF2)
     {
         printf("p = %p\n", p);
-        printf("ci = %p, ci.init = %p, len = %d\n", ci, ci.init, ci.init.length);
-        printf("vptr = %p\n", *cast(void**) ci.init);
-        printf("vtbl[0] = %p\n", (*cast(void***) ci.init)[0]);
-        printf("vtbl[1] = %p\n", (*cast(void***) ci.init)[1]);
-        printf("init[0] = %x\n", (cast(uint*) ci.init)[0]);
-        printf("init[1] = %x\n", (cast(uint*) ci.init)[1]);
-        printf("init[2] = %x\n", (cast(uint*) ci.init)[2]);
-        printf("init[3] = %x\n", (cast(uint*) ci.init)[3]);
-        printf("init[4] = %x\n", (cast(uint*) ci.init)[4]);
+        printf("ci = %p, ci.init = %p, len = %d\n", ci, ci.init.ptr, ci.init.length);
+        printf("vptr = %p\n", *cast(void**) ci.init.ptr);
+        printf("vtbl[0] = %p\n", (*cast(void***) ci.init.ptr)[0]);
+        printf("vtbl[1] = %p\n", (*cast(void***) ci.init.ptr)[1]);
+        printf("init[0] = %p\n", (cast(uint**) ci.init.ptr)[0]);
+        printf("init[1] = %p\n", (cast(uint**) ci.init.ptr)[1]);
+        printf("init[2] = %p\n", (cast(uint**) ci.init.ptr)[2]);
+        printf("init[3] = %p\n", (cast(uint**) ci.init.ptr)[3]);
+        printf("init[4] = %p\n", (cast(uint**) ci.init.ptr)[4]);
     }
 
     // initialize it
--- a/tango/tango/io/Buffer.d	Thu Jan 17 03:15:12 2008 +0100
+++ b/tango/tango/io/Buffer.d	Fri Jan 18 16:42:16 2008 +0100
@@ -165,9 +165,13 @@
         this (IConduit conduit)
         {
                 printf("Buffer.this(%p)\n", conduit);
+                printf("assert (conduit !is null);\n");
                 assert (conduit !is null);
+                printf("assert (conduit);\n", conduit);
                 assert (conduit);
 
+                printf("this (conduit.bufferSize(%p));\n", conduit);
+                printf("cast(Object)conduit = %p\n", cast(Object)conduit);
                 this (conduit.bufferSize);
                 setConduit (conduit);
 
@@ -226,6 +230,7 @@
 
         this (uint capacity = 0)
         {
+                printf("Buffer.this(%p, %u)\n", this, capacity);
                 setContent (new ubyte[capacity], 0);
                 assert(this !is null);
         }
--- a/tangotests/l.d	Thu Jan 17 03:15:12 2008 +0100
+++ b/tangotests/l.d	Fri Jan 18 16:42:16 2008 +0100
@@ -4,6 +4,9 @@
 {
     printf("enter\n");
     assert(Cout !is null);
+    printf("newline\n");
+    Cout.newline;
+    printf("hi message\n");
     Cout("Hi, says LLVMDC + Tango").newline;
     printf("exit\n");
 }