Mercurial > projects > ldc
diff gen/classes.cpp @ 177:cea8dcfa76df trunk
[svn r193] Fixed: abstract classes implementing interfaces now output proper Interface info arrays. (null vtables).
Did a little renaming of delegate utils.
author | lindquist |
---|---|
date | Wed, 07 May 2008 04:45:51 +0200 |
parents | db9890b3fb64 |
children | 36044016709a |
line wrap: on
line diff
--- a/gen/classes.cpp Wed May 07 00:58:36 2008 +0200 +++ b/gen/classes.cpp Wed May 07 04:45:51 2008 +0200 @@ -610,11 +610,6 @@ infoInits.push_back(c); // offset - // generate target independent offset with constGEP - /*llvm::Value* cidx = DtoConstInt(iri->index); - Logger::cout() << "offset to interface in class type: " << *cd->type->ir.type->get() << '\n'; - size_t ioff = gTargetData->getIndexedOffset(cd->type->ir.type->get(), &cidx, 1); - infoInits.push_back(DtoConstUint(ioff));*/ assert(iri->index >= 0); size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index); infoInits.push_back(DtoConstUint(ioff)); @@ -658,17 +653,19 @@ } } // we always generate interfaceinfos as best we can - /*else + else { - for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + // TODO: this is duplicated code from right above... I'm just too lazy to generalise it right now :/ + // create interface vtable const initalizers + for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) { - ClassDeclaration* id = i->first; + IrInterface* iri = *i; + BaseClass* b = iri->base; + + ClassDeclaration* id = iri->decl; assert(id->type->ty == Tclass); TypeClass* its = (TypeClass*)id->type; - IrInterface* iri = i->second; - BaseClass* b = iri->base; - // generate interface info initializer std::vector<llvm::Constant*> infoInits; @@ -683,12 +680,14 @@ infoInits.push_back(c); // offset - infoInits.push_back(DtoConstInt(0)); + assert(iri->index >= 0); + size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index); + infoInits.push_back(DtoConstUint(ioff)); // create interface info initializer constant iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); } - }*/ + } gIR->classes.pop_back(); gIR->structs.pop_back(); @@ -709,7 +708,8 @@ TypeClass* ts = (TypeClass*)cd->type; if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) { - // interfaces don't have initializers + + // interfaces don't have static initializer/vtable // neither do abstract classes if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { @@ -718,19 +718,30 @@ // initialize interface vtables IrStruct* irstruct = cd->ir.irStruct; - std::vector<llvm::Constant*> infoInits; for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) { IrInterface* iri = *i; iri->vtbl->setInitializer(iri->vtblInit); - infoInits.push_back(iri->infoInit); } - // initialize interface info array - if (!infoInits.empty()) - { - llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits); - irstruct->interfaceInfos->setInitializer(arrInit); - } + } + + // always do interface info array when possible + IrStruct* irstruct = cd->ir.irStruct; + std::vector<llvm::Constant*> infoInits; + for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) + { + IrInterface* iri = *i; + infoInits.push_back(iri->infoInit); + } + // set initializer + if (!infoInits.empty()) + { + llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits); + irstruct->interfaceInfos->setInitializer(arrInit); + } + else + { + assert(irstruct->interfaceInfos == NULL); } // generate classinfo