# HG changeset patch # User lindquist # Date 1195761661 -3600 # Node ID e8da7856a2607fa6ece2ea48188004f8a179dc07 # Parent 5ab8e92611f9d0e4852223ac2c393b9ec0b991da [svn r114] Implemented the ClassInfo.offTi member. diff -r 5ab8e92611f9 -r e8da7856a260 gen/classes.cpp --- 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 types; + std::vector 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 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 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 diff -r 5ab8e92611f9 -r e8da7856a260 gen/typinf.cpp --- 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; diff -r 5ab8e92611f9 -r e8da7856a260 llvmdc.kdevelop.filelist --- 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 diff -r 5ab8e92611f9 -r e8da7856a260 test/classinfo3.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)); +}