Mercurial > projects > ldc
diff gen/classes.cpp @ 110:e8da7856a260 trunk
[svn r114] Implemented the ClassInfo.offTi member.
author | lindquist |
---|---|
date | Thu, 22 Nov 2007 21:01:01 +0100 |
parents | 5b5194b25f33 |
children | a7ae554ce4f4 |
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