changeset 1148:3d1b16dabd25

Eliminated the need for resolve, declare, const-init and define lists to drive code generation.
author Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
date Fri, 27 Mar 2009 21:50:32 +0100
parents dbe4af57b240
children 5ebe8224988b
files dmd/declaration.h gen/arrays.cpp gen/classes.cpp gen/declarations.cpp gen/functions.cpp gen/irstate.h gen/llvmhelpers.cpp gen/llvmhelpers.h gen/structs.cpp gen/toir.cpp gen/toobj.cpp gen/typinf.cpp ir/ir.h ir/irlandingpad.cpp
diffstat 14 files changed, 198 insertions(+), 402 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/declaration.h	Fri Mar 27 17:54:27 2009 +0100
+++ b/dmd/declaration.h	Fri Mar 27 21:50:32 2009 +0100
@@ -288,7 +288,7 @@
 
 #if IN_LLVM
     /// Codegen traversal
-    void codegen(Ir* ir);
+    virtual void codegen(Ir* ir);
 
     // LDC
     AnonDeclaration* anonDecl;
@@ -368,7 +368,6 @@
 #if IN_LLVM
     /// Codegen traversal
     void codegen(Ir* ir);
-    virtual void llvmDeclare();
     virtual void llvmDefine();
 #endif
 };
@@ -382,7 +381,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -396,7 +394,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -410,7 +407,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -424,7 +420,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -438,7 +433,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -452,7 +446,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -466,7 +459,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -480,7 +472,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -494,7 +485,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -508,7 +498,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -522,7 +511,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -536,7 +524,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -551,7 +538,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
@@ -565,7 +551,6 @@
 #endif
 
 #if IN_LLVM
-    void llvmDeclare();
     void llvmDefine();
 #endif
 };
--- a/gen/arrays.cpp	Fri Mar 27 17:54:27 2009 +0100
+++ b/gen/arrays.cpp	Fri Mar 27 21:50:32 2009 +0100
@@ -676,7 +676,7 @@
         Type* t = l->getType();
         LLValue* tival = DtoTypeInfoOf(t);
         // DtoTypeInfoOf only does declare, not enough in this case :/
-        DtoForceConstInitDsymbol(t->vtinfo);
+        t->vtinfo->codegen(Type::sir);
 
         if (Logger::enabled())
             Logger::cout() << "typeinfo decl: " << *tival << '\n';
--- a/gen/classes.cpp	Fri Mar 27 17:54:27 2009 +0100
+++ b/gen/classes.cpp	Fri Mar 27 21:50:32 2009 +0100
@@ -124,6 +124,10 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
+static void DtoDeclareInterface(InterfaceDeclaration* cd);
+static void DtoConstInitInterface(InterfaceDeclaration* cd);
+static void DtoDefineInterface(InterfaceDeclaration* cd);
+
 static void DtoResolveInterface(InterfaceDeclaration* cd)
 {
     if (cd->ir.resolved) return;
@@ -156,7 +160,7 @@
             assert(id);
 
             DtoResolveInterface(id);
-    
+
             // add to interfaceInfos
             IrInterface* iri = new IrInterface(bc);
             irstruct->interfaceVec.push_back(iri);
@@ -170,7 +174,7 @@
     ts->ir.type = new LLPATypeHolder(getPtrToType(t));
 
     // request declaration
-    gIR->declareList.push_back(cd);
+    DtoDeclareInterface(cd);
 
     // handle members
     // like "nested" interfaces
@@ -193,14 +197,16 @@
         return;
     }
 
+    // make sure the base classes are processed first
+    if (cd->baseClass)
+        cd->baseClass->codegen(Type::sir);
+
     if (cd->ir.resolved) return;
     cd->ir.resolved = true;
 
     Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
     LOG_SCOPE;
 
-    //printf("resolve class: %s\n", cd->toPrettyChars());
-
     // get the TypeClass
     assert(cd->type->ty == Tclass);
     TypeClass* ts = (TypeClass*)cd->type;
@@ -221,10 +227,21 @@
         return;
     }
 
-    // resolve the base class
-    if (cd->baseClass) {
-        DtoResolveClass(cd->baseClass);
-    }
+    // create the symbols we're going to need
+    // avoids chicken egg problems
+    llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(cd);
+
+    // there is always a vtbl symbol
+    std::string varname("_D");
+    varname.append(cd->mangle());
+    varname.append("6__vtblZ");
+    irstruct->vtbl = new llvm::GlobalVariable(irstruct->vtblInitTy.get(), true, _linkage, NULL, varname, gIR->module);
+
+    // ... and initZ
+    std::string initname("_D");
+    initname.append(cd->mangle());
+    initname.append("6__initZ");
+    irstruct->init = new llvm::GlobalVariable(irstruct->initOpaque.get(), true, _linkage, NULL, initname, gIR->module);
 
     // push state
     gIR->structs.push_back(irstruct);
@@ -252,6 +269,7 @@
     llvm::PATypeHolder* spa = ts->ir.type;
     llvm::cast<llvm::OpaqueType>(spa->get())->refineAbstractTypeTo(structtype);
     structtype = isaStruct(spa->get());
+    assert(structtype);
 
     // name the type
     gIR->module->addTypeName(cd->mangle(), ts->ir.type->get());
@@ -269,13 +287,15 @@
     gIR->structs.pop_back();
 
     // queue declare
-    gIR->declareList.push_back(cd);
+    DtoDeclareClass(cd);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
 static void DtoDeclareInterface(InterfaceDeclaration* cd)
 {
+    DtoResolveInterface(cd);
+
     if (cd->ir.declared) return;
     cd->ir.declared = true;
 
@@ -321,12 +341,12 @@
     DtoDeclareClassInfo(cd);
 
     // request const init
-    gIR->constInitList.push_back(cd);
+    DtoConstInitInterface(cd);
 
     // emit typeinfo and request definition
     if (mustDefineSymbol(cd))
     {
-        gIR->defineList.push_back(cd);
+        DtoDefineInterface(cd);
         DtoTypeInfoOf(cd->type, false);
     }
 }
@@ -343,6 +363,8 @@
         return;
     }
 
+    DtoResolveClass(cd);
+
     if (cd->ir.declared) return;
     cd->ir.declared = true;
 
@@ -366,12 +388,6 @@
 
     llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(cd);
 
-    // create vtbl symbol
-    std::string varname("_D");
-    varname.append(cd->mangle());
-    varname.append("6__vtblZ");
-    irstruct->vtbl = new llvm::GlobalVariable(irstruct->vtblInitTy.get(), true, _linkage, 0, varname, gIR->module);
-
     // get interface info type
     const llvm::StructType* infoTy = DtoInterfaceInfoType();
 
@@ -410,23 +426,14 @@
         idx++;
     }
 
-    // initZ init
-    std::string initname("_D");
-    initname.append(cd->mangle());
-    initname.append("6__initZ");
-
-    // initZ global
-    llvm::GlobalVariable* initvar = new llvm::GlobalVariable(irstruct->initOpaque.get(), true, _linkage, NULL, initname, gIR->module);
-    irstruct->init = initvar;
-
     gIR->structs.pop_back();
 
     // request const init
-    gIR->constInitList.push_back(cd);
+    DtoConstInitClass(cd);
 
     // define ? (set initializers)
     if (needs_definition)
-        gIR->defineList.push_back(cd);
+        DtoDefineClass(cd);
 
     // classinfo
     DtoDeclareClassInfo(cd);
@@ -544,6 +551,8 @@
 // build the vtable initializer for class cd
 static void init_class_vtbl_initializer(ClassDeclaration* cd)
 {
+    cd->codegen(Type::sir);
+
     // generate vtable initializer
     std::vector<LLConstant*> sinits(cd->vtbl.dim, NULL);
 
@@ -551,6 +560,8 @@
 
     assert(cd->vtbl.dim > 1);
 
+    DtoDeclareClassInfo(cd);
+
     // first entry always classinfo
     assert(irstruct->classInfo);
     sinits[0] = DtoBitCast(irstruct->classInfo, DtoType(ClassDeclaration::classinfo->type));
@@ -575,7 +586,9 @@
         }
         else
         {
-            DtoForceDeclareDsymbol(fd);
+            fd->codegen(Type::sir);
+            Logger::println("F = %s", fd->toPrettyChars());
+            assert(fd->ir.irFunc);
             assert(fd->ir.irFunc->func);
             sinits[k] = fd->ir.irFunc->func;
         }
@@ -645,7 +658,7 @@
                     inits[j] = getNullPtr(getVoidPtrType());
                 else
                 {
-                    DtoForceDeclareDsymbol(fd);
+                    fd->codegen(Type::sir);
 
                     assert(fd->ir.irFunc->func);
                     inits[j] = fd->ir.irFunc->func;
@@ -662,7 +675,7 @@
         // build the interface info for ClassInfo
         // generate interface info initializer
 
-        DtoForceDeclareDsymbol(iri->decl);
+        iri->decl->codegen(Type::sir);
 
         // classinfo
         IrStruct* iris = iri->decl->ir.irStruct;
@@ -698,6 +711,8 @@
 
 static void DtoConstInitInterface(InterfaceDeclaration* cd)
 {
+    DtoDeclareInterface(cd);
+
     if (cd->ir.initialized) return;
     cd->ir.initialized = true;
 
@@ -717,18 +732,14 @@
         return;
     }
 
+    DtoDeclareClass(cd);
+
     if (cd->ir.initialized) return;
     cd->ir.initialized = true;
 
     Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
     LOG_SCOPE;
 
-    assert(!cd->isInterfaceDeclaration());
-
-    // make sure the baseclass is const initialized
-    if (cd->baseClass)
-        DtoForceConstInitDsymbol(cd->baseClass);
-
     // get IrStruct
     IrStruct* irstruct = cd->ir.irStruct;
     gIR->structs.push_back(irstruct);
@@ -811,6 +822,8 @@
 
 static void DtoDefineInterface(InterfaceDeclaration* cd)
 {
+    DtoConstInitInterface(cd);
+
     if (cd->ir.defined) return;
     cd->ir.defined = true;
 
@@ -839,6 +852,8 @@
         return;
     }
 
+    DtoConstInitClass(cd);
+
     if (cd->ir.defined) return;
     cd->ir.defined = true;
 
@@ -898,7 +913,7 @@
 DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp)
 {
     // resolve type
-    DtoForceDeclareDsymbol(tc->sym);
+    tc->sym->codegen(Type::sir);
 
     // allocate
     LLValue* mem;
@@ -909,7 +924,7 @@
     // custom allocator
     else if (newexp->allocator)
     {
-        DtoForceDeclareDsymbol(newexp->allocator);
+        newexp->allocator->codegen(Type::sir);
         DFuncValue dfn(newexp->allocator, newexp->allocator->ir.irFunc->func);
         DValue* res = DtoCallFunction(newexp->loc, NULL, &dfn, newexp->newargs);
         mem = DtoBitCast(res->getRVal(), DtoType(tc), ".newclass_custom");
@@ -959,7 +974,7 @@
     {
         Logger::println("Calling constructor");
         assert(newexp->arguments != NULL);
-        DtoForceDeclareDsymbol(newexp->member);
+        newexp->member->codegen(Type::sir);
         DFuncValue dfn(newexp->member, newexp->member->ir.irFunc->func, mem);
         return DtoCallFunction(newexp->loc, tc, &dfn, newexp->arguments);
     }
@@ -972,7 +987,7 @@
 
 void DtoInitClass(TypeClass* tc, LLValue* dst)
 {
-    DtoForceConstInitDsymbol(tc->sym);
+    tc->sym->codegen(Type::sir);
 
     size_t presz = 2*getTypePaddedSize(DtoSize_t());
     uint64_t n = getTypePaddedSize(tc->ir.type->get()) - presz;
@@ -1122,8 +1137,8 @@
     // call:
     // Object _d_dynamic_cast(Object o, ClassInfo c)
 
-    DtoForceDeclareDsymbol(ClassDeclaration::object);
-    DtoForceDeclareDsymbol(ClassDeclaration::classinfo);
+    ClassDeclaration::object->codegen(Type::sir);
+    ClassDeclaration::classinfo->codegen(Type::sir);
 
     llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast");
     const llvm::FunctionType* funcTy = func->getFunctionType();
@@ -1137,7 +1152,7 @@
 
     // ClassInfo c
     TypeClass* to = (TypeClass*)_to->toBasetype();
-    DtoForceDeclareDsymbol(to->sym);
+    to->sym->codegen(Type::sir);
     assert(to->sym->ir.irStruct->classInfo);
     LLValue* cinfo = to->sym->ir.irStruct->classInfo;
     // unfortunately this is needed as the implementation of object differs somehow from the declaration
@@ -1187,8 +1202,8 @@
     // call:
     // Object _d_interface_cast(void* p, ClassInfo c)
 
-    DtoForceDeclareDsymbol(ClassDeclaration::object);
-    DtoForceDeclareDsymbol(ClassDeclaration::classinfo);
+    ClassDeclaration::object->codegen(Type::sir);
+    ClassDeclaration::classinfo->codegen(Type::sir);
 
     llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_interface_cast");
     const llvm::FunctionType* funcTy = func->getFunctionType();
@@ -1201,7 +1216,7 @@
 
     // ClassInfo c
     TypeClass* to = (TypeClass*)_to->toBasetype();
-    DtoForceDeclareDsymbol(to->sym);
+    to->sym->codegen(Type::sir);
     assert(to->sym->ir.irStruct->classInfo);
     LLValue* cinfo = to->sym->ir.irStruct->classInfo;
     // unfortunately this is needed as the implementation of object differs somehow from the declaration
@@ -1404,7 +1419,7 @@
     if (!dtor)
         return getNullPtr(getVoidPtrType());
 
-    DtoForceDeclareDsymbol(dtor);
+    dtor->codegen(Type::sir);
     return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::Int8Ty));
 }
 
@@ -1480,7 +1495,7 @@
     std::vector<LLConstant*> inits;
 
     ClassDeclaration* cinfo = ClassDeclaration::classinfo;
-    DtoForceConstInitDsymbol(cinfo);
+    cinfo->codegen(Type::sir);
 
     LLConstant* c;
 
@@ -1575,7 +1590,7 @@
     const LLType* invTy = DtoType(invVar->type);
     if (cd->inv)
     {
-        DtoForceDeclareDsymbol(cd->inv);
+        cd->inv->codegen(Type::sir);
         c = cd->inv->ir.irFunc->func;
         c = DtoBitCast(c, invTy);
     }
@@ -1595,7 +1610,7 @@
     // deallocator
     if (cd->aggDelete)
     {
-        DtoForceDeclareDsymbol(cd->aggDelete);
+        cd->aggDelete->codegen(Type::sir);
         c = cd->aggDelete->ir.irFunc->func;
         c = DtoBitCast(c, voidPtr);
     }
@@ -1625,7 +1640,7 @@
     // default constructor
     if (cd->defaultCtor)
     {
-        DtoForceDeclareDsymbol(cd->defaultCtor);
+        cd->defaultCtor->codegen(Type::sir);
         c = isaConstant(cd->defaultCtor->ir.irFunc->func);
         c = DtoBitCast(c, voidPtr);
     }
--- a/gen/declarations.cpp	Fri Mar 27 17:54:27 2009 +0100
+++ b/gen/declarations.cpp	Fri Mar 27 21:50:32 2009 +0100
@@ -135,7 +135,7 @@
         if (nakedUse)
             gIR->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType()));
 
-        gIR->constInitList.push_back(this);
+        DtoConstInitGlobal(this);
     }
     else
     {
--- a/gen/functions.cpp	Fri Mar 27 17:54:27 2009 +0100
+++ b/gen/functions.cpp	Fri Mar 27 21:50:32 2009 +0100
@@ -26,6 +26,12 @@
 
 const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, bool ismain)
 {
+    // already built ?
+    if (type->ir.type != NULL) {
+        //assert(f->fty != NULL);
+        return llvm::cast<llvm::FunctionType>(type->ir.type->get());
+    }
+
     if (Logger::enabled())
         Logger::println("DtoFunctionType(%s)", type->toChars());
     LOG_SCOPE
@@ -33,12 +39,6 @@
     assert(type->ty == Tfunction);
     TypeFunction* f = (TypeFunction*)type;
 
-    // already built ?
-    if (type->ir.type != NULL) {
-        //assert(f->fty != NULL);
-        return llvm::cast<llvm::FunctionType>(type->ir.type->get());
-    }
-
     if (f->linkage != LINKintrinsic) {
         // Tell the ABI we're resolving a new function type
         gABI->newFunctionType(f);
@@ -241,14 +241,14 @@
 
 const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
 {
+    // type has already been resolved
+    if (fdecl->type->ir.type != 0)
+        return llvm::cast<llvm::FunctionType>(fdecl->type->ir.type->get());
+
     // handle for C vararg intrinsics
     if (fdecl->isVaIntrinsic())
         return DtoVaFunctionType(fdecl);
 
-    // type has already been resolved
-    if (fdecl->type->ir.type != 0)
-        return llvm::cast<llvm::FunctionType>(fdecl->type->ir.type->get());
-
     Type *dthis=0, *dnest=0;
 
     if (fdecl->needThis()) {
@@ -299,6 +299,7 @@
 void DtoResolveFunction(FuncDeclaration* fdecl)
 {
     if (!global.params.useUnitTests && fdecl->isUnitTestDeclaration()) {
+        Logger::println("Ignoring unittest %s", fdecl->toPrettyChars());
         return; // ignore declaration completely
     }
 
@@ -306,15 +307,12 @@
     if (fdecl->getModule() != gIR->dmodule)
     {
         if (fdecl->prot() == PROTprivate)
+        {
+            Logger::println("Ignoring private imported function %s", fdecl->toPrettyChars());
             return;
+        }
     }
 
-    if (fdecl->ir.resolved) return;
-    fdecl->ir.resolved = true;
-
-    Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars());
-    LOG_SCOPE;
-
     //printf("resolve function: %s\n", fdecl->toPrettyChars());
 
     if (fdecl->parent)
@@ -325,6 +323,7 @@
         {
             Logger::println("magic va_arg found");
             fdecl->llvmInternal = LLVMva_arg;
+            fdecl->ir.resolved = true;
             fdecl->ir.declared = true;
             fdecl->ir.initialized = true;
             fdecl->ir.defined = true;
@@ -347,9 +346,18 @@
 
     DtoFunctionType(fdecl);
 
+    if (fdecl->ir.resolved) return;
+    fdecl->ir.resolved = true;
+
+    Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars());
+    LOG_SCOPE;
+
     // queue declaration
     if (!fdecl->isAbstract())
-        gIR->declareList.push_back(fdecl);
+    {
+        Logger::println("Ignoring declaration of abstract function %s", fdecl->toPrettyChars());
+        DtoDeclareFunction(fdecl);
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -569,12 +577,9 @@
         gIR->unitTests.push_back(fdecl);
 
     if (!declareOnly)
-        gIR->defineList.push_back(fdecl);
+        Type::sir->addFunctionBody(fdecl->ir.irFunc);
     else
         assert(func->getLinkage() != llvm::GlobalValue::InternalLinkage);
-
-    if (Logger::enabled())
-        Logger::cout() << "func decl: " << *func << '\n';
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/irstate.h	Fri Mar 27 17:54:27 2009 +0100
+++ b/gen/irstate.h	Fri Mar 27 21:50:32 2009 +0100
@@ -153,16 +153,6 @@
     // debug info helper
     llvm::DIFactory difactory;
 
-    typedef std::list<Dsymbol*> DsymbolList;
-    // dsymbols that need to be resolved
-    DsymbolList resolveList;
-    // dsymbols that need to be declared
-    DsymbolList declareList;
-    // dsymbols that need constant initializers constructed
-    DsymbolList constInitList;
-    // dsymbols that need definitions
-    DsymbolList defineList;
-
     // static ctors/dtors/unittests
     typedef std::vector<FuncDeclaration*> FuncDeclVector;
     FuncDeclVector ctors;
--- a/gen/llvmhelpers.cpp	Fri Mar 27 17:54:27 2009 +0100
+++ b/gen/llvmhelpers.cpp	Fri Mar 27 21:50:32 2009 +0100
@@ -866,6 +866,8 @@
 
 void DtoDeclareDsymbol(Dsymbol* dsym)
 {
+    DtoResolveDsymbol(dsym);
+
     if (StructDeclaration* sd = dsym->isStructDeclaration()) {
         DtoDeclareStruct(sd);
     }
@@ -888,6 +890,8 @@
 
 void DtoConstInitDsymbol(Dsymbol* dsym)
 {
+    DtoDeclareDsymbol(dsym);
+
     if (StructDeclaration* sd = dsym->isStructDeclaration()) {
         DtoConstInitStruct(sd);
     }
@@ -910,6 +914,8 @@
 
 void DtoDefineDsymbol(Dsymbol* dsym)
 {
+    DtoConstInitDsymbol(dsym);
+
     if (StructDeclaration* sd = dsym->isStructDeclaration()) {
         DtoDefineStruct(sd);
     }
@@ -917,7 +923,7 @@
         DtoDefineClass(cd);
     }
     else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
-        DtoDefineFunction(fd);
+        Type::sir->addFunctionBody(fd->ir.irFunc);
     }
     else if (TypeInfoDeclaration* fd = dsym->isTypeInfoDeclaration()) {
         DtoDefineTypeInfo(fd);
@@ -932,6 +938,8 @@
 
 void DtoConstInitGlobal(VarDeclaration* vd)
 {
+    vd->codegen(Type::sir);
+
     if (vd->ir.initialized) return;
     vd->ir.initialized = gIR->dmodule;
 
@@ -977,42 +985,6 @@
     }
 }
 
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoForceDeclareDsymbol(Dsymbol* dsym)
-{
-    if (dsym->ir.declared) return;
-    Logger::println("DtoForceDeclareDsymbol(%s)", dsym->toPrettyChars());
-    LOG_SCOPE;
-    DtoResolveDsymbol(dsym);
-    DtoDeclareDsymbol(dsym);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoForceConstInitDsymbol(Dsymbol* dsym)
-{
-    if (dsym->ir.initialized) return;
-    Logger::println("DtoForceConstInitDsymbol(%s)", dsym->toPrettyChars());
-    LOG_SCOPE;
-    DtoResolveDsymbol(dsym);
-    DtoDeclareDsymbol(dsym);
-    DtoConstInitDsymbol(dsym);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-void DtoForceDefineDsymbol(Dsymbol* dsym)
-{
-    if (dsym->ir.defined) return;
-    Logger::println("DtoForceDefineDsymbol(%s)", dsym->toPrettyChars());
-    LOG_SCOPE;
-    DtoResolveDsymbol(dsym);
-    DtoDeclareDsymbol(dsym);
-    DtoConstInitDsymbol(dsym);
-    DtoDefineDsymbol(dsym);
-}
-
 /****************************************************************************************/
 /*////////////////////////////////////////////////////////////////////////////////////////
 //      DECLARATION EXP HELPER
@@ -1106,13 +1078,13 @@
     else if (StructDeclaration* s = declaration->isStructDeclaration())
     {
         Logger::println("StructDeclaration");
-        DtoForceConstInitDsymbol(s);
+        s->codegen(Type::sir);
     }
     // function declaration
     else if (FuncDeclaration* f = declaration->isFuncDeclaration())
     {
         Logger::println("FuncDeclaration");
-        DtoForceDeclareDsymbol(f);
+        f->codegen(Type::sir);
     }
     // alias declaration
     else if (AliasDeclaration* a = declaration->isAliasDeclaration())
@@ -1130,7 +1102,7 @@
     else if (ClassDeclaration* e = declaration->isClassDeclaration())
     {
         Logger::println("ClassDeclaration");
-        DtoForceConstInitDsymbol(e);
+        e->codegen(Type::sir);
     }
     // typedef
     else if (TypedefDeclaration* tdef = declaration->isTypedefDeclaration())
@@ -1392,8 +1364,9 @@
     type->getTypeInfo(NULL);
     TypeInfoDeclaration* tidecl = type->vtinfo;
     assert(tidecl);
-    DtoForceDeclareDsymbol(tidecl);
+    tidecl->codegen(Type::sir);
     assert(tidecl->ir.irGlobal != NULL);
+    assert(tidecl->ir.irGlobal->value != NULL);
     LLConstant* c = isaConstant(tidecl->ir.irGlobal->value);
     assert(c != NULL);
     if (base)
--- a/gen/llvmhelpers.h	Fri Mar 27 17:54:27 2009 +0100
+++ b/gen/llvmhelpers.h	Fri Mar 27 21:50:32 2009 +0100
@@ -94,9 +94,6 @@
 void DtoDefineDsymbol(Dsymbol* dsym);
 void DtoConstInitDsymbol(Dsymbol* dsym);
 void DtoConstInitGlobal(VarDeclaration* vd);
-void DtoForceDeclareDsymbol(Dsymbol* dsym);
-void DtoForceConstInitDsymbol(Dsymbol* dsym);
-void DtoForceDefineDsymbol(Dsymbol* dsym);
 
 // declaration inside a declarationexp
 DValue* DtoDeclarationExp(Dsymbol* declaration);
--- a/gen/structs.cpp	Fri Mar 27 17:54:27 2009 +0100
+++ b/gen/structs.cpp	Fri Mar 27 21:50:32 2009 +0100
@@ -97,7 +97,7 @@
     TypeStruct* ts = (TypeStruct*)si->ad->type;
 
     // force constant initialization of the symbol
-    DtoForceConstInitDsymbol(si->ad);
+    si->ad->codegen(Type::sir);;
 
     // get formal type
     const llvm::StructType* structtype = isaStruct(ts->ir.type->get());
@@ -517,6 +517,15 @@
     // create the type
     ts->ir.type = new LLPATypeHolder(llvm::OpaqueType::get());
 
+    // create symbols we're going to need
+    // avoids chicken egg problems
+    std::string initname("_D");
+    initname.append(sd->mangle());
+    initname.append("6__initZ");
+
+    llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(sd);
+    sd->ir.irStruct->init = new llvm::GlobalVariable(sd->ir.irStruct->initOpaque.get(), true, _linkage, NULL, initname, gIR->module);
+
     // handle forward declaration structs (opaques)
     // didn't even know D had those ...
     if (sd->sizeok != 1)
@@ -579,13 +588,15 @@
 
     gIR->structs.pop_back();
 
-    gIR->declareList.push_back(sd);
+    DtoDeclareStruct(sd);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
 void DtoDeclareStruct(StructDeclaration* sd)
 {
+    DtoResolveStruct(sd);
+
     if (sd->ir.declared) return;
     sd->ir.declared = true;
 
@@ -594,23 +605,17 @@
 
     TypeStruct* ts = (TypeStruct*)sd->type->toBasetype();
 
-    std::string initname("_D");
-    initname.append(sd->mangle());
-    initname.append("6__initZ");
-
-    llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(sd);
-    llvm::GlobalVariable* initvar = new llvm::GlobalVariable(sd->ir.irStruct->initOpaque.get(), true, _linkage, NULL, initname, gIR->module);
-    sd->ir.irStruct->init = initvar;
-
-    gIR->constInitList.push_back(sd);
+    DtoConstInitStruct(sd);
     if (mustDefineSymbol(sd))
-        gIR->defineList.push_back(sd);
+        DtoDefineStruct(sd);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
 void DtoConstInitStruct(StructDeclaration* sd)
 {
+    DtoDeclareStruct(sd);
+
     if (sd->ir.initialized) return;
     sd->ir.initialized = true;
 
@@ -651,6 +656,8 @@
 
 void DtoDefineStruct(StructDeclaration* sd)
 {
+    DtoConstInitStruct(sd);
+
     if (sd->ir.defined) return;
     sd->ir.defined = true;
 
--- a/gen/toir.cpp	Fri Mar 27 17:54:27 2009 +0100
+++ b/gen/toir.cpp	Fri Mar 27 21:50:32 2009 +0100
@@ -95,7 +95,7 @@
         else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
         {
             Logger::println("TypeInfoDeclaration");
-            DtoForceDeclareDsymbol(tid);
+            tid->codegen(Type::sir);
             assert(tid->ir.getIrValue());
             const LLType* vartype = DtoType(type);
             LLValue* m = tid->ir.getIrValue();
@@ -107,7 +107,7 @@
         else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration())
         {
             Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
-            DtoForceDeclareDsymbol(cid->cd);
+            cid->cd->codegen(Type::sir);;
             assert(cid->cd->ir.irStruct->classInfo);
             return new DVarValue(type, vd, cid->cd->ir.irStruct->classInfo);
         }
@@ -175,7 +175,7 @@
         Logger::println("FuncDeclaration");
         LLValue* func = 0;
         if (fdecl->llvmInternal != LLVMva_arg) {
-            DtoForceDeclareDsymbol(fdecl);
+            fdecl->codegen(Type::sir);
             func = fdecl->ir.irFunc->func;
         }
         return new DFuncValue(fdecl, func);
@@ -188,7 +188,7 @@
         assert(sdecltype->ty == Tstruct);
         TypeStruct* ts = (TypeStruct*)sdecltype;
         assert(ts->sym);
-        DtoForceConstInitDsymbol(ts->sym);
+        ts->sym->codegen(Type::sir);
         assert(ts->sym->ir.irStruct->init);
         return new DVarValue(type, ts->sym->ir.irStruct->init);
     }
@@ -214,7 +214,7 @@
         Logger::print("Sym: type=%s\n", sdecltype->toChars());
         assert(sdecltype->ty == Tstruct);
         TypeStruct* ts = (TypeStruct*)sdecltype;
-        DtoForceConstInitDsymbol(ts->sym);
+        ts->sym->codegen(Type::sir);
         assert(ts->sym->ir.irStruct->constInit);
         return ts->sym->ir.irStruct->constInit;
     }
@@ -922,7 +922,7 @@
         //Logger::println("FuncDeclaration");
         FuncDeclaration* fd = fv->func;
         assert(fd);
-        DtoForceDeclareDsymbol(fd);
+        fd->codegen(Type::sir);
         return new DFuncValue(fd, fd->ir.irFunc->func);
     }
     else if (DImValue* im = v->isIm()) {
@@ -976,7 +976,7 @@
         // static function
         else if (FuncDeclaration* fd = vexp->var->isFuncDeclaration())
         {
-            DtoForceDeclareDsymbol(fd);
+            fd->codegen(Type::sir);
             IrFunction* irfunc = fd->ir.irFunc;
             return irfunc->func;
         }
@@ -1125,7 +1125,7 @@
         // look up function
         //
         if (!vtbllookup) {
-            DtoForceDeclareDsymbol(fdecl);
+            fdecl->codegen(Type::sir);
             funcval = fdecl->ir.irFunc->func;
             assert(funcval);
         }
@@ -1634,7 +1634,7 @@
         }
         else {
             assert(ts->sym);
-            DtoForceConstInitDsymbol(ts->sym);
+            ts->sym->codegen(Type::sir);
             DtoAggrCopy(mem,ts->sym->ir.irStruct->init);
         }
         return new DImValue(type, mem);
@@ -2027,7 +2027,7 @@
         assert(0 && "TODO delegate to interface method");
     else
     {
-        DtoForceDeclareDsymbol(func);
+        func->codegen(Type::sir);
         castfptr = func->ir.irFunc->func;
     }
 
@@ -2252,7 +2252,7 @@
     if (fd->isNested()) Logger::println("nested");
     Logger::println("kind = %s\n", fd->kind());
 
-    DtoForceDefineDsymbol(fd);
+    fd->codegen(Type::sir);
     assert(fd->ir.irFunc->func);
 
     if(fd->tok == TOKdelegate) {
@@ -2289,7 +2289,7 @@
     assert(fd);
     assert(fd->tok == TOKfunction);
 
-    DtoForceDefineDsymbol(fd);
+    fd->codegen(Type::sir);
     assert(fd->ir.irFunc->func);
 
     return fd->ir.irFunc->func;
--- a/gen/toobj.cpp	Fri Mar 27 17:54:27 2009 +0100
+++ b/gen/toobj.cpp	Fri Mar 27 21:50:32 2009 +0100
@@ -145,6 +145,9 @@
     // generate ModuleInfo
     genmoduleinfo();
 
+    // emit function bodies
+    sir->emitFunctionBodies();
+
     // emit usedArray
     if (!ir.usedArray.empty())
     {
@@ -599,7 +602,7 @@
         fatal();
     }
 
-    DtoForceConstInitDsymbol(moduleinfo);
+    moduleinfo->codegen(Type::sir);
 
     // check for patch
     if (moduleinfo->fields.dim != 9)
--- a/gen/typinf.cpp	Fri Mar 27 17:54:27 2009 +0100
+++ b/gen/typinf.cpp	Fri Mar 27 21:50:32 2009 +0100
@@ -271,6 +271,15 @@
 //                             MAGIC   PLACE
 //////////////////////////////////////////////////////////////////////////////
 
+void DtoResolveTypeInfo(TypeInfoDeclaration* tid);
+void DtoDeclareTypeInfo(TypeInfoDeclaration* tid);
+void DtoConstInitTypeInfo(TypeInfoDeclaration* tid);
+
+void TypeInfoDeclaration::codegen(Ir*)
+{
+    DtoResolveTypeInfo(this);
+}
+
 void DtoResolveTypeInfo(TypeInfoDeclaration* tid)
 {
     if (tid->ir.resolved) return;
@@ -279,57 +288,46 @@
     Logger::println("DtoResolveTypeInfo(%s)", tid->toChars());
     LOG_SCOPE;
 
-    tid->ir.irGlobal = new IrGlobal(tid);
+    IrGlobal* irg = new IrGlobal(tid);
+    irg->value = new llvm::GlobalVariable(irg->type.get(), true,
+        TYPEINFO_LINKAGE_TYPE, NULL, tid->mangle(), gIR->module);
 
-    gIR->declareList.push_back(tid);
-}
+    tid->ir.irGlobal = irg;
 
-void TypeInfoDeclaration::codegen(Ir*)
-{
-    DtoResolveTypeInfo(this);
+    DtoDeclareTypeInfo(tid);
 }
 
 void DtoDeclareTypeInfo(TypeInfoDeclaration* tid)
 {
+    DtoResolveTypeInfo(tid);
+
     if (tid->ir.declared) return;
     tid->ir.declared = true;
 
     Logger::println("DtoDeclareTypeInfo(%s)", tid->toChars());
     LOG_SCOPE;
 
+    IrGlobal* irg = tid->ir.irGlobal;
+
     std::string mangled(tid->mangle());
 
     Logger::println("type = '%s'", tid->tinfo->toChars());
     Logger::println("typeinfo mangle: %s", mangled.c_str());
 
+    assert(irg->value != NULL);
+
     // this is a declaration of a builtin __initZ var
     if (tid->tinfo->builtinTypeInfo()) {
-        LLValue* found = gIR->module->getNamedGlobal(mangled);
-        if (!found)
-        {
-            const LLType* t = LLOpaqueType::get();
-            llvm::GlobalVariable* g = new llvm::GlobalVariable(t, true, llvm::GlobalValue::ExternalLinkage, NULL, mangled, gIR->module);
-            assert(g);
-            /*if (!tid->ir.irGlobal)
-                tid->ir.irGlobal = new IrGlobal(tid);*/
-            tid->ir.irGlobal->value = g;
-            mangled.append("__TYPE");
-            gIR->module->addTypeName(mangled, tid->ir.irGlobal->value->getType()->getContainedType(0));
-            Logger::println("Got typeinfo var: %s", tid->ir.irGlobal->value->getName().c_str());
-            tid->ir.initialized = true;
-            tid->ir.defined = true;
-        }
-        else if (!tid->ir.irGlobal->value) {
-            tid->ir.irGlobal->value = found;
-            tid->ir.initialized = true;
-            tid->ir.defined = true;
-        }
+        // fixup the global
+        const llvm::Type* rty = Type::typeinfo->type->ir.type->get();
+        llvm::cast<llvm::OpaqueType>(irg->type.get())->refineAbstractTypeTo(rty);
+        LLGlobalVariable* g = isaGlobalVar(irg->value);
+        g->setLinkage(llvm::GlobalValue::ExternalLinkage);
+        return;
     }
+
     // custom typedef
-    else {
-        tid->llvmDeclare();
-        gIR->constInitList.push_back(tid);
-    }
+    DtoConstInitTypeInfo(tid);
 }
 
 void DtoConstInitTypeInfo(TypeInfoDeclaration* tid)
@@ -340,7 +338,7 @@
     Logger::println("DtoConstInitTypeInfo(%s)", tid->toChars());
     LOG_SCOPE;
 
-    gIR->defineList.push_back(tid);
+    tid->llvmDefine();
 }
 
 void DtoDefineTypeInfo(TypeInfoDeclaration* tid)
@@ -356,11 +354,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoDeclaration::llvmDeclare()
-{
-    assert(0 && "TypeInfoDeclaration::llvmDeclare");
-}
-
 void TypeInfoDeclaration::llvmDefine()
 {
     assert(0 && "TypeInfoDeclaration::llvmDeclare");
@@ -368,27 +361,13 @@
 
 /* ========================================================================= */
 
-void TypeInfoTypedefDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoTypedefDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    ClassDeclaration* base = Type::typeinfotypedef;
-    DtoResolveClass(base);
-
-    const LLStructType* stype = isaStruct(base->type->ir.type->get());
-
-    // create the symbol
-    ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module);
-}
-
 void TypeInfoTypedefDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoTypedefDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
     ClassDeclaration* base = Type::typeinfotypedef;
-    DtoForceConstInitDsymbol(base);
+    base->codegen(Type::sir);
 
     // vtbl
     std::vector<LLConstant*> sinits;
@@ -439,25 +418,13 @@
 
 /* ========================================================================= */
 
-void TypeInfoEnumDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoEnumDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    ClassDeclaration* base = Type::typeinfoenum;
-    DtoResolveClass(base);
-
-    // create the symbol
-    ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module);
-}
-
 void TypeInfoEnumDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
     ClassDeclaration* base = Type::typeinfoenum;
-    DtoForceConstInitDsymbol(base);
+    base->codegen(Type::sir);
 
     // vtbl
     std::vector<LLConstant*> sinits;
@@ -512,19 +479,10 @@
 
 /* ========================================================================= */
 
-static void LLVM_D_Declare_TypeInfoBase(TypeInfoDeclaration* tid, ClassDeclaration* cd)
-{
-    ClassDeclaration* base = cd;
-    DtoResolveClass(base);
-
-    // create the symbol
-    tid->ir.irGlobal->value = new llvm::GlobalVariable(tid->ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, tid->toChars(), gIR->module);
-}
-
 static void LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
 {
     ClassDeclaration* base = cd;
-    DtoForceConstInitDsymbol(base);
+    base->codegen(Type::sir);
 
     // vtbl
     std::vector<LLConstant*> sinits;
@@ -549,17 +507,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoPointerDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoPointerDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    assert(tinfo->ty == Tpointer);
-    TypePointer *tc = (TypePointer *)tinfo;
-
-    LLVM_D_Declare_TypeInfoBase(this, Type::typeinfopointer);
-}
-
 void TypeInfoPointerDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoPointerDeclaration::llvmDefine() %s", toChars());
@@ -573,17 +520,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoArrayDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoArrayDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    assert(tinfo->ty == Tarray);
-    TypeDArray *tc = (TypeDArray *)tinfo;
-
-    LLVM_D_Declare_TypeInfoBase(this, Type::typeinfoarray);
-}
-
 void TypeInfoArrayDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoArrayDeclaration::llvmDefine() %s", toChars());
@@ -597,19 +533,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoStaticArrayDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoStaticArrayDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    // init typeinfo class
-    ClassDeclaration* base = Type::typeinfostaticarray;
-    DtoResolveClass(base);
-
-    // create the symbol
-    ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module);
-}
-
 void TypeInfoStaticArrayDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoStaticArrayDeclaration::llvmDefine() %s", toChars());
@@ -617,7 +540,7 @@
 
     // init typeinfo class
     ClassDeclaration* base = Type::typeinfostaticarray;
-    DtoForceConstInitDsymbol(base);
+    base->codegen(Type::sir);
 
     // get type of typeinfo class
     const LLStructType* stype = isaStruct(base->type->ir.type->get());
@@ -652,19 +575,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoAssociativeArrayDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoAssociativeArrayDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    // init typeinfo class
-    ClassDeclaration* base = Type::typeinfoassociativearray;
-    DtoResolveClass(base);
-
-    // create the symbol
-    ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module);
-}
-
 void TypeInfoAssociativeArrayDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoAssociativeArrayDeclaration::llvmDefine() %s", toChars());
@@ -672,7 +582,7 @@
 
     // init typeinfo class
     ClassDeclaration* base = Type::typeinfoassociativearray;
-    DtoForceConstInitDsymbol(base);
+    base->codegen(Type::sir);
 
     // initializer vector
     std::vector<LLConstant*> sinits;
@@ -706,17 +616,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoFunctionDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoFunctionDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    assert(tinfo->ty == Tfunction);
-    TypeFunction *tc = (TypeFunction *)tinfo;
-
-    LLVM_D_Declare_TypeInfoBase(this, Type::typeinfofunction);
-}
-
 void TypeInfoFunctionDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoFunctionDeclaration::llvmDefine() %s", toChars());
@@ -730,17 +629,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoDelegateDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoDelegateDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    assert(tinfo->ty == Tdelegate);
-    TypeDelegate *tc = (TypeDelegate *)tinfo;
-
-    LLVM_D_Declare_TypeInfoBase(this, Type::typeinfodelegate);
-}
-
 void TypeInfoDelegateDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoDelegateDeclaration::llvmDefine() %s", toChars());
@@ -754,23 +642,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoStructDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoStructDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    assert(tinfo->ty == Tstruct);
-    TypeStruct *tc = (TypeStruct *)tinfo;
-    StructDeclaration *sd = tc->sym;
-    DtoResolveDsymbol(sd);
-
-    ClassDeclaration* base = Type::typeinfostruct;
-    DtoResolveClass(base);
-
-    // create the symbol
-    ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module);
-}
-
 void TypeInfoStructDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoStructDeclaration::llvmDefine() %s", toChars());
@@ -779,10 +650,10 @@
     assert(tinfo->ty == Tstruct);
     TypeStruct *tc = (TypeStruct *)tinfo;
     StructDeclaration *sd = tc->sym;
-    DtoForceConstInitDsymbol(sd);
+    sd->codegen(Type::sir);
 
     ClassDeclaration* base = Type::typeinfostruct;
-    DtoForceConstInitDsymbol(base);
+    base->codegen(Type::sir);
 
     const LLStructType* stype = isaStruct(base->type->ir.type->get());
 
@@ -870,7 +741,7 @@
     {
         fd = fdx->overloadExactMatch(tftohash);
         if (fd) {
-            DtoForceDeclareDsymbol(fd);
+            fd->codegen(Type::sir);
             assert(fd->ir.irFunc->func != 0);
             LLConstant* c = isaConstant(fd->ir.irFunc->func);
             assert(c);
@@ -896,7 +767,7 @@
         {
             fd = fdx->overloadExactMatch(tfeqptr);
             if (fd) {
-                DtoForceDeclareDsymbol(fd);
+                fd->codegen(Type::sir);
                 assert(fd->ir.irFunc->func != 0);
                 LLConstant* c = isaConstant(fd->ir.irFunc->func);
                 assert(c);
@@ -924,7 +795,7 @@
     {
         fd = fdx->overloadExactMatch(tftostring);
         if (fd) {
-            DtoForceDeclareDsymbol(fd);
+            fd->codegen(Type::sir);
             assert(fd->ir.irFunc->func != 0);
             LLConstant* c = isaConstant(fd->ir.irFunc->func);
             assert(c);
@@ -968,20 +839,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoClassDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoClassDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    // init typeinfo class
-    ClassDeclaration* base = Type::typeinfoclass;
-    assert(base);
-    DtoResolveClass(base);
-
-    // create the symbol
-    ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module);
-}
-
 void TypeInfoClassDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoClassDeclaration::llvmDefine() %s", toChars());
@@ -990,7 +847,7 @@
     // init typeinfo class
     ClassDeclaration* base = Type::typeinfoclass;
     assert(base);
-    DtoForceConstInitDsymbol(base);
+    base->codegen(Type::sir);
 
     // initializer vector
     std::vector<LLConstant*> sinits;
@@ -1003,7 +860,7 @@
     // get classinfo
     assert(tinfo->ty == Tclass);
     TypeClass *tc = (TypeClass *)tinfo;
-    DtoForceDeclareDsymbol(tc->sym);
+    tc->sym->codegen(Type::sir);;
     assert(tc->sym->ir.irStruct->classInfo);
     sinits.push_back(tc->sym->ir.irStruct->classInfo);
 
@@ -1019,20 +876,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoInterfaceDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoInterfaceDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    // init typeinfo class
-    ClassDeclaration* base = Type::typeinfointerface;
-    assert(base);
-    DtoResolveClass(base);
-
-    // create the symbol
-    ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module);
-}
-
 void TypeInfoInterfaceDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoInterfaceDeclaration::llvmDefine() %s", toChars());
@@ -1041,7 +884,7 @@
     // init typeinfo class
     ClassDeclaration* base = Type::typeinfointerface;
     assert(base);
-    DtoForceConstInitDsymbol(base);
+    base->codegen(Type::sir);
 
     // get type of typeinfo class
     const LLStructType* stype = isaStruct(base->type->ir.type->get());
@@ -1072,20 +915,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoTupleDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoTupleDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    // init typeinfo class
-    ClassDeclaration* base = Type::typeinfotypelist;
-    assert(base);
-    DtoResolveClass(base);
-
-    // create the symbol
-    ir.irGlobal->value = new llvm::GlobalVariable(ir.irGlobal->type.get(), true, TYPEINFO_LINKAGE_TYPE, NULL, toChars(), gIR->module);
-}
-
 void TypeInfoTupleDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoTupleDeclaration::llvmDefine() %s", toChars());
@@ -1094,7 +923,7 @@
     // init typeinfo class
     ClassDeclaration* base = Type::typeinfotypelist;
     assert(base);
-    DtoForceConstInitDsymbol(base);
+    base->codegen(Type::sir);
 
     // get type of typeinfo class
     const LLStructType* stype = isaStruct(base->type->ir.type->get());
@@ -1156,14 +985,6 @@
 
 #if DMDV2
 
-void TypeInfoConstDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoConstDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    LLVM_D_Declare_TypeInfoBase(this, Type::typeinfoconst);
-}
-
 void TypeInfoConstDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoConstDeclaration::llvmDefine() %s", toChars());
@@ -1177,14 +998,6 @@
 
 /* ========================================================================= */
 
-void TypeInfoInvariantDeclaration::llvmDeclare()
-{
-    Logger::println("TypeInfoInvariantDeclaration::llvmDeclare() %s", toChars());
-    LOG_SCOPE;
-
-    LLVM_D_Declare_TypeInfoBase(this, Type::typeinfoinvariant);
-}
-
 void TypeInfoInvariantDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoInvariantDeclaration::llvmDefine() %s", toChars());
--- a/ir/ir.h	Fri Mar 27 17:54:27 2009 +0100
+++ b/ir/ir.h	Fri Mar 27 21:50:32 2009 +0100
@@ -3,10 +3,13 @@
 #ifndef LDC_IR_IR_H
 #define LDC_IR_IR_H
 
+#include <deque>
+
 #include "ir/irforw.h"
 #include "root.h"
 
 struct IRState;
+struct IrFunction;
 
 struct IrBase : Object
 {
@@ -15,13 +18,18 @@
 
 struct Ir
 {
-    Ir() : irs(NULL) {}
+    Ir();
 
     void setState(IRState* p)   { irs = p; }
     IRState* getState()         { return irs; }
 
+    void addFunctionBody(IrFunction* f);
+    void emitFunctionBodies();
+
 private:
     IRState* irs;
+
+    std::deque<IrFunction*> functionbodies;
 };
 
 #endif
--- a/ir/irlandingpad.cpp	Fri Mar 27 17:54:27 2009 +0100
+++ b/ir/irlandingpad.cpp	Fri Mar 27 21:50:32 2009 +0100
@@ -49,7 +49,7 @@
     assert(catchstmt->type);
     catchType = catchstmt->type->toBasetype()->isClassHandle();
     assert(catchType);
-    DtoForceDeclareDsymbol(catchType);
+    catchType->codegen(Type::sir);
 }
 
 IRLandingPadInfo::IRLandingPadInfo(Statement* finallystmt)