changeset 106:5b5194b25f33 trunk

[svn r110] Fixed typeinfo for classes.
author lindquist
date Mon, 19 Nov 2007 06:01:48 +0100
parents 182b41f56b7f
children 3efbcc81ba45
files dmd/declaration.h gen/classes.cpp gen/tollvm.cpp gen/tollvm.h gen/toobj.cpp gen/typinf.cpp llvmdc.kdevelop.filelist lphobos/build.sh lphobos/internal/objectimpl.d lphobos/typeinfo2/ti_C.d lphobos/typeinfos2.d test/typeinfo12.d
diffstat 12 files changed, 433 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/declaration.h	Mon Nov 19 03:39:46 2007 +0100
+++ b/dmd/declaration.h	Mon Nov 19 06:01:48 2007 +0100
@@ -327,6 +327,10 @@
     virtual void toDt(dt_t **pdt);
 
     virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return this; }
+
+    // LLVMDC
+    virtual void llvmDeclare();
+    virtual void llvmDefine();
 };
 
 struct TypeInfoStructDeclaration : TypeInfoDeclaration
@@ -334,6 +338,10 @@
     TypeInfoStructDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct TypeInfoClassDeclaration : TypeInfoDeclaration
@@ -341,6 +349,10 @@
     TypeInfoClassDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct TypeInfoInterfaceDeclaration : TypeInfoDeclaration
@@ -348,6 +360,10 @@
     TypeInfoInterfaceDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct TypeInfoTypedefDeclaration : TypeInfoDeclaration
@@ -355,6 +371,10 @@
     TypeInfoTypedefDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct TypeInfoPointerDeclaration : TypeInfoDeclaration
@@ -362,6 +382,10 @@
     TypeInfoPointerDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct TypeInfoArrayDeclaration : TypeInfoDeclaration
@@ -369,6 +393,10 @@
     TypeInfoArrayDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct TypeInfoStaticArrayDeclaration : TypeInfoDeclaration
@@ -376,6 +404,10 @@
     TypeInfoStaticArrayDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration
@@ -383,6 +415,10 @@
     TypeInfoAssociativeArrayDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct TypeInfoEnumDeclaration : TypeInfoDeclaration
@@ -390,6 +426,10 @@
     TypeInfoEnumDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct TypeInfoFunctionDeclaration : TypeInfoDeclaration
@@ -397,6 +437,10 @@
     TypeInfoFunctionDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct TypeInfoDelegateDeclaration : TypeInfoDeclaration
@@ -404,6 +448,10 @@
     TypeInfoDelegateDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct TypeInfoTupleDeclaration : TypeInfoDeclaration
@@ -411,6 +459,10 @@
     TypeInfoTupleDeclaration(Type *tinfo);
 
     void toDt(dt_t **pdt);
+
+    // LLVMDC
+    void llvmDeclare();
+    void llvmDefine();
 };
 
 struct ThisDeclaration : VarDeclaration
--- a/gen/classes.cpp	Mon Nov 19 03:39:46 2007 +0100
+++ b/gen/classes.cpp	Mon Nov 19 06:01:48 2007 +0100
@@ -212,6 +212,10 @@
 
     // classinfo
     DtoDeclareClassInfo(cd);
+
+    // typeinfo
+    if (cd->parent->isModule() && cd->getModule() == gIR->dmodule)
+        cd->type->getTypeInfo(NULL);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -530,7 +534,7 @@
         for (size_t i = 0; i < cd2->members->dim; i++)
         {
         Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
-        //printf("sm = %s %s\n", sm->kind(), sm->toChars());
+        //printf("sm = %s %s\n", sm->kind(), sm->toChars());
         if (sm->hasPointers())
             goto L2;
         }
--- a/gen/tollvm.cpp	Mon Nov 19 03:39:46 2007 +0100
+++ b/gen/tollvm.cpp	Mon Nov 19 06:01:48 2007 +0100
@@ -1260,6 +1260,11 @@
     return llvm::dyn_cast<llvm::Argument>(v);
 }
 
+llvm::GlobalVariable* isaGlobalVar(llvm::Value* v)
+{
+    return llvm::dyn_cast<llvm::GlobalVariable>(v);
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 
 bool DtoIsTemplateInstance(Dsymbol* s)
--- a/gen/tollvm.h	Mon Nov 19 03:39:46 2007 +0100
+++ b/gen/tollvm.h	Mon Nov 19 06:01:48 2007 +0100
@@ -90,6 +90,7 @@
 llvm::Constant* isaConstant(llvm::Value* v);
 llvm::ConstantInt* isaConstantInt(llvm::Value* v);
 llvm::Argument* isaArgument(llvm::Value* v);
+llvm::GlobalVariable* isaGlobalVar(llvm::Value* v);
 
 // basic operations
 void DtoAssign(DValue* lhs, DValue* rhs);
--- a/gen/toobj.cpp	Mon Nov 19 03:39:46 2007 +0100
+++ b/gen/toobj.cpp	Mon Nov 19 06:01:48 2007 +0100
@@ -95,6 +95,9 @@
     if (!ClassDeclaration::classinfo->type->llvmType)
         ClassDeclaration::classinfo->type->llvmType = new llvm::PATypeHolder(llvm::OpaqueType::get());
 
+    /*if (!Type::typeinfoclass->type->llvmType)
+        Type::typeinfoclass->type->llvmType = new llvm::PATypeHolder(llvm::OpaqueType::get());*/
+
     // process module members
     for (int k=0; k < members->dim; k++) {
         Dsymbol* dsym = (Dsymbol*)(members->data[k]);
--- a/gen/typinf.cpp	Mon Nov 19 03:39:46 2007 +0100
+++ b/gen/typinf.cpp	Mon Nov 19 06:01:48 2007 +0100
@@ -37,6 +37,7 @@
 #include "gen/tollvm.h"
 #include "gen/arrays.h"
 #include "gen/structs.h"
+#include "gen/classes.h"
 
 /*******************************************
  * Get a canonicalized form of the TypeInfo for use with the internal
@@ -283,6 +284,7 @@
     }
     // custom typedef
     else {
+        tid->llvmDeclare();
         gIR->constInitList.push_back(tid);
     }
 }
@@ -295,10 +297,7 @@
     Logger::println("* DtoConstInitTypeInfo(%s)", tid->toChars());
     LOG_SCOPE;
 
-    tid->toDt(NULL);
-
-    tid->llvmDefined = true;
-    //gIR->defineList.push_back(tid);
+    gIR->defineList.push_back(tid);
 }
 
 void DtoDefineTypeInfo(TypeInfoDeclaration* tid)
@@ -309,21 +308,45 @@
     Logger::println("* DtoDefineTypeInfo(%s)", tid->toChars());
     LOG_SCOPE;
 
-    assert(0);
+    tid->llvmDefine();
 }
 
 /* ========================================================================= */
 
 void TypeInfoDeclaration::toDt(dt_t **pdt)
 {
-    assert(0 && "TypeInfoDeclaration");
+    assert(0 && "TypeInfoDeclaration::toDt");
+}
+
+void TypeInfoDeclaration::llvmDeclare()
+{
+    assert(0 && "TypeInfoDeclaration::llvmDeclare");
+}
+
+void TypeInfoDeclaration::llvmDefine()
+{
+    assert(0 && "TypeInfoDeclaration::llvmDeclare");
 }
 
 /* ========================================================================= */
 
-void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
+void TypeInfoTypedefDeclaration::llvmDeclare()
 {
-    Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars());
+    Logger::println("TypeInfoTypedefDeclaration::llvmDeclare() %s", toChars());
+    LOG_SCOPE;
+
+    ClassDeclaration* base = Type::typeinfotypedef;
+    DtoResolveClass(base);
+
+    const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
+
+    // create the symbol
+    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+}
+
+void TypeInfoTypedefDeclaration::llvmDefine()
+{
+    Logger::println("TypeInfoTypedefDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
     ClassDeclaration* base = Type::typeinfotypedef;
@@ -348,7 +371,7 @@
     sd->basetype->getTypeInfo(NULL);        // generate vtinfo
     assert(sd->basetype->vtinfo);
     if (!sd->basetype->vtinfo->llvmValue)
-        DtoForceConstInitDsymbol(sd->basetype->vtinfo);
+        DtoForceDeclareDsymbol(sd->basetype->vtinfo);
 
     assert(sd->basetype->vtinfo->llvmValue);
     assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->llvmValue));
@@ -380,16 +403,33 @@
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module);
+    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+}
 
-    llvmValue = gvar;
+void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
+{
+    assert(0);
 }
 
 /* ========================================================================= */
 
-void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
+void TypeInfoEnumDeclaration::llvmDeclare()
 {
-    Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars());
+    Logger::println("TypeInfoEnumDeclaration::llvmDeclare() %s", toChars());
+    LOG_SCOPE;
+
+    ClassDeclaration* base = Type::typeinfoenum;
+    DtoResolveClass(base);
+
+    const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
+
+    // create the symbol
+    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+}
+
+void TypeInfoEnumDeclaration::llvmDefine()
+{
+    Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
     ClassDeclaration* base = Type::typeinfoenum;
@@ -413,7 +453,7 @@
     sd->memtype->getTypeInfo(NULL);        // generate vtinfo
     assert(sd->memtype->vtinfo);
     if (!sd->memtype->vtinfo->llvmValue)
-        DtoForceConstInitDsymbol(sd->memtype->vtinfo);
+        DtoForceDeclareDsymbol(sd->memtype->vtinfo);
 
     assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->llvmValue));
     llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->llvmValue);
@@ -445,14 +485,28 @@
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module);
+    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+}
 
-    llvmValue = gvar;
+void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
+{
+    assert(0);
 }
 
 /* ========================================================================= */
 
-static llvm::Constant* LLVM_D_Create_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
+static llvm::Constant* LLVM_D_Declare_TypeInfoBase(TypeInfoDeclaration* tid, ClassDeclaration* cd)
+{
+    ClassDeclaration* base = cd;
+    DtoResolveClass(base);
+
+    const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
+
+    // create the symbol
+    tid->llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
+}
+
+static llvm::Constant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
 {
     ClassDeclaration* base = cd;
     DtoForceConstInitDsymbol(base);
@@ -467,7 +521,7 @@
     basetype->getTypeInfo(NULL);
     assert(basetype->vtinfo);
     if (!basetype->vtinfo->llvmValue)
-        DtoForceConstInitDsymbol(basetype->vtinfo);
+        DtoForceDeclareDsymbol(basetype->vtinfo);
     assert(llvm::isa<llvm::Constant>(basetype->vtinfo->llvmValue));
     llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->llvmValue);
     castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(1));
@@ -475,40 +529,86 @@
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,tid->toChars(),gIR->module);
-
-    tid->llvmValue = gvar;
+    isaGlobalVar(tid->llvmValue)->setInitializer(tiInit);
 }
 
 /* ========================================================================= */
 
-void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
+void TypeInfoPointerDeclaration::llvmDeclare()
 {
-    Logger::println("TypeInfoPointerDeclaration::toDt() %s", toChars());
+    Logger::println("TypeInfoPointerDeclaration::llvmDeclare() %s", toChars());
     LOG_SCOPE;
 
     assert(tinfo->ty == Tpointer);
     TypePointer *tc = (TypePointer *)tinfo;
 
-    LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfopointer);
+    LLVM_D_Declare_TypeInfoBase(this, Type::typeinfopointer);
+}
+
+void TypeInfoPointerDeclaration::llvmDefine()
+{
+    Logger::println("TypeInfoPointerDeclaration::llvmDefine() %s", toChars());
+    LOG_SCOPE;
+
+    assert(tinfo->ty == Tpointer);
+    TypePointer *tc = (TypePointer *)tinfo;
+
+    LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfopointer);
+}
+
+void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
+{
+    assert(0);
 }
 
 /* ========================================================================= */
 
-void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
+void TypeInfoArrayDeclaration::llvmDeclare()
 {
-    Logger::println("TypeInfoArrayDeclaration::toDt() %s", toChars());
+    Logger::println("TypeInfoArrayDeclaration::llvmDeclare() %s", toChars());
     LOG_SCOPE;
 
     assert(tinfo->ty == Tarray);
     TypeDArray *tc = (TypeDArray *)tinfo;
 
-    LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfoarray);
+    LLVM_D_Declare_TypeInfoBase(this, Type::typeinfoarray);
+}
+
+void TypeInfoArrayDeclaration::llvmDefine()
+{
+    Logger::println("TypeInfoArrayDeclaration::llvmDefine() %s", toChars());
+    LOG_SCOPE;
+
+    assert(tinfo->ty == Tarray);
+    TypeDArray *tc = (TypeDArray *)tinfo;
+
+    LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfoarray);
+}
+
+void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
+{
+    assert(0);
 }
 
 /* ========================================================================= */
 
-void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
+void TypeInfoStaticArrayDeclaration::llvmDeclare()
+{
+    Logger::println("TypeInfoStaticArrayDeclaration::toDt() %s", toChars());
+    LOG_SCOPE;
+
+    // init typeinfo class
+    ClassDeclaration* base = Type::typeinfostaticarray;
+    DtoResolveClass(base);
+
+    // get type of typeinfo class
+    const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
+
+    // create the symbol
+    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+}
+
+void TypeInfoStaticArrayDeclaration::llvmDefine()
 {
     Logger::println("TypeInfoStaticArrayDeclaration::toDt() %s", toChars());
     LOG_SCOPE;
@@ -532,7 +632,7 @@
 
     // get symbol
     assert(tc->next->vtinfo);
-    DtoForceConstInitDsymbol(tc->next->vtinfo);
+    DtoForceDeclareDsymbol(tc->next->vtinfo);
     llvm::Constant* castbase = isaConstant(tc->next->vtinfo->llvmValue);
     castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(1));
     sinits.push_back(castbase);
@@ -542,13 +642,26 @@
 
     // create the symbol
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
-    llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module);
+    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+}
 
-    llvmValue = gvar;
+void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
+{
+    assert(0);
 }
 
 /* ========================================================================= */
 
+void TypeInfoAssociativeArrayDeclaration::llvmDeclare()
+{
+    assert(0 && "TypeInfoAssociativeArrayDeclaration");
+}
+
+void TypeInfoAssociativeArrayDeclaration::llvmDefine()
+{
+    assert(0 && "TypeInfoAssociativeArrayDeclaration");
+}
+
 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
 {
     assert(0 && "TypeInfoAssociativeArrayDeclaration");
@@ -572,7 +685,7 @@
 
 /* ========================================================================= */
 
-void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
+void TypeInfoFunctionDeclaration::llvmDeclare()
 {
     Logger::println("TypeInfoFunctionDeclaration::toDt() %s", toChars());
     LOG_SCOPE;
@@ -580,12 +693,28 @@
     assert(tinfo->ty == Tfunction);
     TypeFunction *tc = (TypeFunction *)tinfo;
 
-    LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfofunction);
+    LLVM_D_Declare_TypeInfoBase(this, Type::typeinfofunction);
+}
+
+void TypeInfoFunctionDeclaration::llvmDefine()
+{
+    Logger::println("TypeInfoFunctionDeclaration::toDt() %s", toChars());
+    LOG_SCOPE;
+
+    assert(tinfo->ty == Tfunction);
+    TypeFunction *tc = (TypeFunction *)tinfo;
+
+    LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfofunction);
+}
+
+void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
+{
+    assert(0);
 }
 
 /* ========================================================================= */
 
-void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
+void TypeInfoDelegateDeclaration::llvmDeclare()
 {
     Logger::println("TypeInfoDelegateDeclaration::toDt() %s", toChars());
     LOG_SCOPE;
@@ -593,14 +722,49 @@
     assert(tinfo->ty == Tdelegate);
     TypeDelegate *tc = (TypeDelegate *)tinfo;
 
-    LLVM_D_Create_TypeInfoBase(tc->next->next, this, Type::typeinfodelegate);
+    LLVM_D_Declare_TypeInfoBase(this, Type::typeinfodelegate);
+}
+
+void TypeInfoDelegateDeclaration::llvmDefine()
+{
+    Logger::println("TypeInfoDelegateDeclaration::toDt() %s", toChars());
+    LOG_SCOPE;
+
+    assert(tinfo->ty == Tdelegate);
+    TypeDelegate *tc = (TypeDelegate *)tinfo;
+
+    LLVM_D_Define_TypeInfoBase(tc->next->next, this, Type::typeinfodelegate);
+}
+
+void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
+{
+    assert(0);
 }
 
 /* ========================================================================= */
 
-void TypeInfoStructDeclaration::toDt(dt_t **pdt)
+void TypeInfoStructDeclaration::llvmDeclare()
 {
-    Logger::println("TypeInfoStructDeclaration::toDt() %s", toChars());
+    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);
+
+    const llvm::StructType* stype = isaStruct(((TypeClass*)base->type)->llvmType->get());
+
+    // create the symbol
+    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+}
+
+void TypeInfoStructDeclaration::llvmDefine()
+{
+    Logger::println("TypeInfoStructDeclaration::llvmDefine() %s", toChars());
     LOG_SCOPE;
 
     assert(tinfo->ty == Tstruct);
@@ -764,34 +928,79 @@
     llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
     llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module);
 
-    llvmValue = gvar;
+    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+}
+
+void TypeInfoStructDeclaration::toDt(dt_t **pdt)
+{
+    assert(0);
 }
 
 /* ========================================================================= */
 
+void TypeInfoClassDeclaration::llvmDeclare()
+{
+    Logger::println("TypeInfoClassDeclaration::llvmDeclare() %s", toChars());
+    LOG_SCOPE;
+
+    // init typeinfo class
+    ClassDeclaration* base = Type::typeinfoclass;
+    assert(base);
+    DtoResolveClass(base);
+
+    // get type of typeinfo class
+    const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
+
+    // create the symbol
+    llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
+}
+
+void TypeInfoClassDeclaration::llvmDefine()
+{
+    Logger::println("TypeInfoClassDeclaration::llvmDefine() %s", toChars());
+    LOG_SCOPE;
+
+    // init typeinfo class
+    ClassDeclaration* base = Type::typeinfoclass;
+    assert(base);
+    DtoForceConstInitDsymbol(base);
+
+    // get type of typeinfo class
+    const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
+
+    // initializer vector
+    std::vector<llvm::Constant*> sinits;
+    // first is always the vtable
+    sinits.push_back(base->llvmVtbl);
+
+    // get classinfo
+    assert(tinfo->ty == Tclass);
+    TypeClass *tc = (TypeClass *)tinfo;
+    assert(tc->sym->llvmClass);
+    sinits.push_back(tc->sym->llvmClass);
+
+    // create the symbol
+    llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
+    isaGlobalVar(llvmValue)->setInitializer(tiInit);
+}
+
 void TypeInfoClassDeclaration::toDt(dt_t **pdt)
 {
-    assert(0 && "TypeInfoClassDeclaration");
-
-    /*
-    //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
-    dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
-    dtdword(pdt, 0);                // monitor
-
-    assert(tinfo->ty == Tclass);
-
-    TypeClass *tc = (TypeClass *)tinfo;
-    Symbol *s;
-
-    if (!tc->sym->vclassinfo)
-    tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
-    s = tc->sym->vclassinfo->toSymbol();
-    dtxoff(pdt, s, 0, TYnptr);      // ClassInfo for tinfo
-    */
+    assert(0);
 }
 
 /* ========================================================================= */
 
+void TypeInfoInterfaceDeclaration::llvmDeclare()
+{
+    assert(0 && "TypeInfoTupleDeclaration");
+}
+
+void TypeInfoInterfaceDeclaration::llvmDefine()
+{
+    assert(0 && "TypeInfoTupleDeclaration");
+}
+
 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
 {
     assert(0 && "TypeInfoInterfaceDeclaration");
@@ -815,6 +1024,16 @@
 
 /* ========================================================================= */
 
+void TypeInfoTupleDeclaration::llvmDeclare()
+{
+    assert(0 && "TypeInfoTupleDeclaration");
+}
+
+void TypeInfoTupleDeclaration::llvmDefine()
+{
+    assert(0 && "TypeInfoTupleDeclaration");
+}
+
 void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
 {
     assert(0 && "TypeInfoTupleDeclaration");
--- a/llvmdc.kdevelop.filelist	Mon Nov 19 03:39:46 2007 +0100
+++ b/llvmdc.kdevelop.filelist	Mon Nov 19 06:01:48 2007 +0100
@@ -132,6 +132,7 @@
 gen/tollvm.h
 gen/toobj.cpp
 gen/typeinf.h
+gen/typeinfo12.d
 gen/typinf.cpp
 lphobos
 lphobos/crc32.d
@@ -405,6 +406,7 @@
 test/typeinfo.d
 test/typeinfo10.d
 test/typeinfo11.d
+test/typeinfo12.d
 test/typeinfo2.d
 test/typeinfo3.d
 test/typeinfo4.d
--- a/lphobos/build.sh	Mon Nov 19 03:39:46 2007 +0100
+++ b/lphobos/build.sh	Mon Nov 19 06:01:48 2007 +0100
@@ -20,7 +20,7 @@
 
 
 echo "compiling typeinfo 1"
-rebuild typeinfos1.d -c -oqobj -dc=llvmdc-posix -v || exit 1
+rebuild typeinfos1.d -c -oqobj -dc=llvmdc-posix || exit 1
 llvm-link -f -o=../lib/llvmdcore.bc `ls obj/typeinfo1.*.bc` ../lib/llvmdcore.bc || exit 1
 
 echo "compiling typeinfo 2"
@@ -52,7 +52,7 @@
 llvm-link -f -o=../lib/llvmdcore.bc obj/gclinux.bc obj/gcstub.bc ../lib/llvmdcore.bc || exit 1
 
 echo "compiling phobos"
-rebuild phobos.d -c -oqobj -dc=llvmdc-posix -v || exit 1
+rebuild phobos.d -c -oqobj -dc=llvmdc-posix || exit 1
 llvm-link -f -o=../lib/llvmdcore.bc `ls obj/std.*.bc` ../lib/llvmdcore.bc || exit 1
 
 echo "optimizing"
--- a/lphobos/internal/objectimpl.d	Mon Nov 19 03:39:46 2007 +0100
+++ b/lphobos/internal/objectimpl.d	Mon Nov 19 06:01:48 2007 +0100
@@ -816,8 +816,6 @@
     TypeInfo next;
 }
 
-/+
-
 class TypeInfo_Class : TypeInfo
 {
     char[] toString() { return info.name; }
@@ -881,6 +879,8 @@
     ClassInfo info;
 }
 
+/+
+
 class TypeInfo_Interface : TypeInfo
 {
     char[] toString() { return info.name; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo2/ti_C.d	Mon Nov 19 06:01:48 2007 +0100
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
+ *  Written by Walter Bright
+ *
+ *  This software is provided 'as-is', without any express or implied
+ *  warranty. In no event will the authors be held liable for any damages
+ *  arising from the use of this software.
+ *
+ *  Permission is granted to anyone to use this software for any purpose,
+ *  including commercial applications, and to alter it and redistribute it
+ *  freely, in both source and binary form, subject to the following
+ *  restrictions:
+ *
+ *  o  The origin of this software must not be misrepresented; you must not
+ *     claim that you wrote the original software. If you use this software
+ *     in a product, an acknowledgment in the product documentation would be
+ *     appreciated but is not required.
+ *  o  Altered source versions must be plainly marked as such, and must not
+ *     be misrepresented as being the original software.
+ *  o  This notice may not be removed or altered from any source
+ *     distribution.
+ */
+
+module std.typeinfo.ti_C;
+
+// Object
+
+class TypeInfo_C : TypeInfo
+{
+    hash_t getHash(void *p)
+    {
+	Object o = *cast(Object*)p;
+	assert(o);
+	return o.toHash();
+    }
+
+    int equals(void *p1, void *p2)
+    {
+	Object o1 = *cast(Object*)p1;
+	Object o2 = *cast(Object*)p2;
+
+	return o1 == o2;
+    }
+
+    int compare(void *p1, void *p2)
+    {
+	Object o1 = *cast(Object*)p1;
+	Object o2 = *cast(Object*)p2;
+	int c = 0;
+
+	// Regard null references as always being "less than"
+	if (!(o1 is o2))
+	{
+	    if (o1)
+	    {	if (!o2)
+		    c = 1;
+		else
+		    c = o1.opCmp(o2);
+	    }
+	    else
+		c = -1;
+	}
+	return c;
+    }
+
+    size_t tsize()
+    {
+	return Object.sizeof;
+    }
+
+    uint flags()
+    {
+	return 1;
+    }
+}
+
--- a/lphobos/typeinfos2.d	Mon Nov 19 03:39:46 2007 +0100
+++ b/lphobos/typeinfos2.d	Mon Nov 19 06:01:48 2007 +0100
@@ -7,4 +7,5 @@
 typeinfo2.ti_Aint,
 typeinfo2.ti_Along,
 typeinfo2.ti_Areal,
-typeinfo2.ti_Ashort;
+typeinfo2.ti_Ashort,
+typeinfo2.ti_C;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/typeinfo12.d	Mon Nov 19 06:01:48 2007 +0100
@@ -0,0 +1,9 @@
+module typeinfo12;
+
+class C
+{
+}
+
+void main()
+{
+}