changeset 110:e8da7856a260 trunk

[svn r114] Implemented the ClassInfo.offTi member.
author lindquist
date Thu, 22 Nov 2007 21:01:01 +0100
parents 5ab8e92611f9
children a7ae554ce4f4
files gen/classes.cpp gen/typinf.cpp llvmdc.kdevelop.filelist test/classinfo3.d
diffstat 4 files changed, 114 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/gen/classes.cpp	Wed Nov 21 04:13:15 2007 +0100
+++ b/gen/classes.cpp	Thu Nov 22 21:01:01 2007 +0100
@@ -414,6 +414,87 @@
     cd->llvmClass = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module);
 }
 
+static llvm::Constant* build_offti_entry(VarDeclaration* vd)
+{
+    std::vector<const llvm::Type*> types;
+    std::vector<llvm::Constant*> inits;
+
+    types.push_back(DtoSize_t());
+
+    size_t offset = vd->offset; // TODO might not be the true offset
+    // dmd only accounts for the vtable, not classinfo or monitor
+    if (global.params.is64bit)
+        offset += 8;
+    else
+        offset += 4;
+    inits.push_back(DtoConstSize_t(offset));
+
+    vd->type->getTypeInfo(NULL);
+    assert(vd->type->vtinfo);
+    DtoForceDeclareDsymbol(vd->type->vtinfo);
+    llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue);
+
+    const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get());
+    Logger::cout() << "tiTy = " << *tiTy << '\n';
+
+    types.push_back(tiTy);
+    inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy));
+
+    const llvm::StructType* sTy = llvm::StructType::get(types);
+    return llvm::ConstantStruct::get(sTy, inits);
+}
+
+static llvm::Constant* build_offti_array(ClassDeclaration* cd, llvm::Constant* init)
+{
+    const llvm::StructType* initTy = isaStruct(init->getType());
+    assert(initTy);
+
+    std::vector<llvm::Constant*> arrayInits;
+    for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass)
+    {
+    if (cd2->members)
+    {
+        for (size_t i = 0; i < cd2->members->dim; i++)
+        {
+        Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
+        if (VarDeclaration* vd = sm->isVarDeclaration())
+        {
+            llvm::Constant* c = build_offti_entry(vd);
+            assert(c);
+            arrayInits.push_back(c);
+        }
+        }
+    }
+    }
+
+    size_t ninits = arrayInits.size();
+    llvm::Constant* size = DtoConstSize_t(ninits);
+    llvm::Constant* ptr;
+
+    if (ninits > 0) {
+        // OffsetTypeInfo type
+        std::vector<const llvm::Type*> elemtypes;
+        elemtypes.push_back(DtoSize_t());
+        const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get());
+        elemtypes.push_back(tiTy);
+        const llvm::StructType* sTy = llvm::StructType::get(elemtypes);
+
+        // array type
+        const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits);
+        llvm::Constant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits);
+
+        std::string name(cd->type->vtinfo->toChars());
+        name.append("__OffsetTypeInfos");
+        llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,llvm::GlobalValue::InternalLinkage,arrInit,name,gIR->module);
+        ptr = llvm::ConstantExpr::getBitCast(gvar, llvm::PointerType::get(sTy));
+    }
+    else {
+        ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1)));
+    }
+
+    return DtoConstSlice(size, ptr);
+}
+
 void DtoDefineClassInfo(ClassDeclaration* cd)
 {
 //     The layout is:
@@ -552,7 +633,7 @@
 
     // offset typeinfo
     // TODO
-    c = cinfo->llvmInitZ->getOperand(10);
+    c = build_offti_array(cd, cinfo->llvmInitZ->getOperand(10));
     inits.push_back(c);
 
     // default constructor
--- a/gen/typinf.cpp	Wed Nov 21 04:13:15 2007 +0100
+++ b/gen/typinf.cpp	Thu Nov 22 21:01:01 2007 +0100
@@ -819,7 +819,7 @@
     // char[] name
     char *name = sd->toPrettyChars();
     sinits.push_back(DtoConstString(name));
-    Logger::println("************** A");
+    //Logger::println("************** A");
     assert(sinits.back()->getType() == stype->getElementType(1));
 
     // void[] init
@@ -881,7 +881,7 @@
     }
 #endif
 
-    Logger::println("************** B");
+    //Logger::println("************** B");
     const llvm::PointerType* ptty = isaPointer(stype->getElementType(3));
 
     s = search_function(sd, Id::tohash);
@@ -909,7 +909,7 @@
     fdx = s ? s->isFuncDeclaration() : NULL;
     for (int i = 0; i < 2; i++)
     {
-        Logger::println("************** C %d", i);
+        //Logger::println("************** C %d", i);
         ptty = isaPointer(stype->getElementType(4+i));
         if (fdx)
         {
@@ -934,7 +934,7 @@
         fdx = s ? s->isFuncDeclaration() : NULL;
     }
 
-    Logger::println("************** D");
+    //Logger::println("************** D");
     ptty = isaPointer(stype->getElementType(6));
     s = search_function(sd, Id::tostring);
     fdx = s ? s->isFuncDeclaration() : NULL;
--- a/llvmdc.kdevelop.filelist	Wed Nov 21 04:13:15 2007 +0100
+++ b/llvmdc.kdevelop.filelist	Thu Nov 22 21:01:01 2007 +0100
@@ -323,7 +323,6 @@
 test/bug71.d
 test/bug72.d
 test/bug73.d
-test/bug74.d
 test/bug8.d
 test/bug9.d
 test/c.d
@@ -337,6 +336,7 @@
 test/classes8.d
 test/classinfo1.d
 test/classinfo2.d
+test/classinfo3.d
 test/comma.d
 test/complex1.d
 test/complex2.d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/classinfo3.d	Thu Nov 22 21:01:01 2007 +0100
@@ -0,0 +1,27 @@
+module classinfo3;
+
+class C
+{
+    int i;
+    float f;
+    long l;
+    int j;
+}
+
+void main()
+{
+    auto c = C.classinfo;
+    assert(c.offTi !is null);
+    assert(c.offTi.length == 4);
+
+    size_t base = 2*size_t.sizeof;
+
+    assert(c.offTi[0].offset == base);
+    assert(c.offTi[0].ti == typeid(int));
+    assert(c.offTi[1].offset == base+4);
+    assert(c.offTi[1].ti == typeid(float));
+    assert(c.offTi[2].offset == base+8);
+    assert(c.offTi[2].ti == typeid(long));
+    assert(c.offTi[3].offset == base+16);
+    assert(c.offTi[3].ti == typeid(int));
+}