# HG changeset patch # User lindquist # Date 1201099699 -3600 # Node ID a123dca8349b8bc28ee3cc55cd708b2414ce323d # Parent 8f43f5c43c951e9ec651c86d6e05460da55ffdf1 [svn r146] fixed some potential problems with mismatch in order of interfaces in class data layout diff -r 8f43f5c43c95 -r a123dca8349b gen/classes.cpp --- a/gen/classes.cpp Wed Jan 23 12:58:51 2008 +0100 +++ b/gen/classes.cpp Wed Jan 23 15:48:19 2008 +0100 @@ -27,21 +27,30 @@ { BaseClass* bc = (BaseClass*)(bcs->data[j]); + // base *classes* might add more interfaces? + DtoResolveClass(bc->base); + LLVM_AddBaseClassInterfaces(target, &bc->base->baseclasses); + // resolve interfaces while we're at it if (bc->base->isInterfaceDeclaration()) { - Logger::println("adding interface '%s'", bc->base->toPrettyChars()); - IrInterface* iri = new IrInterface(bc, NULL); - target->irStruct->interfaces.insert(std::make_pair(bc->base, iri)); - if (!target->isAbstract()) { + // don't add twice + if (target->irStruct->interfaceMap.find(bc->base) == target->irStruct->interfaceMap.end()) + { + Logger::println("adding interface '%s'", bc->base->toPrettyChars()); + IrInterface* iri = new IrInterface(bc, NULL); + + // add to map + target->irStruct->interfaceMap.insert(std::make_pair(bc->base, iri)); + // add to ordered list + target->irStruct->interfaceVec.push_back(iri); + // Fill in vtbl[] - bc->fillVtbl(target, &bc->vtbl, 0); + if (!target->isAbstract()) { + bc->fillVtbl(target, &bc->vtbl, 0); + } } - DtoResolveClass(bc->base); } - - // base *classes* might add more interfaces? - LLVM_AddBaseClassInterfaces(target, &bc->base->baseclasses); } } @@ -215,15 +224,16 @@ Logger::println("Adding interfaces to '%s'", cd->toPrettyChars()); LOG_SCOPE; LLVM_AddBaseClassInterfaces(cd, &cd->baseclasses); - Logger::println("%d interfaces added", cd->irStruct->interfaces.size()); + Logger::println("%d interfaces added", cd->irStruct->interfaceVec.size()); + assert(cd->irStruct->interfaceVec.size() == cd->irStruct->interfaceMap.size()); } // add interface vtables at the end int interIdx = (int)fieldtypes.size(); - for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) { - ClassDeclaration* id = i->first; - IrInterface* iri = i->second; + IrInterface* iri = *i; + ClassDeclaration* id = iri->decl; // set vtbl type TypeClass* itc = (TypeClass*)id->type; @@ -236,7 +246,8 @@ // set index iri->index = interIdx++; } - Logger::println("%d interface vtables added", cd->irStruct->interfaces.size()); + Logger::println("%d interface vtables added", cd->irStruct->interfaceVec.size()); + assert(cd->irStruct->interfaceVec.size() == cd->irStruct->interfaceMap.size()); // create type const llvm::StructType* structtype = llvm::StructType::get(fieldtypes); @@ -357,13 +368,13 @@ const llvm::StructType* infoTy = DtoInterfaceInfoType(); // interface info array - if (!cd->irStruct->interfaces.empty()) { + if (!cd->irStruct->interfaceVec.empty()) { // symbol name std::string nam = "_D"; nam.append(cd->mangle()); nam.append("16__interfaceInfosZ"); // resolve array type - const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->irStruct->interfaces.size()); + const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->irStruct->interfaceVec.size()); // declare global irstruct->interfaceInfosTy = arrTy; irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module); @@ -374,10 +385,10 @@ if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { // interface vtables unsigned idx = 0; - for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) { - ClassDeclaration* id = i->first; - IrInterface* iri = i->second; + IrInterface* iri = *i; + ClassDeclaration* id = iri->decl; std::string nam("_D"); nam.append(cd->mangle()); @@ -490,10 +501,11 @@ // last comes interface vtables const llvm::StructType* infoTy = DtoInterfaceInfoType(); - for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) { - IrInterface* iri = i->second; + IrInterface* iri = *i; iri->infoTy = infoTy; + if (cd->isAbstract()) { fieldinits.push_back(llvm::Constant::getNullValue(structtype->getElementType(iri->index))); @@ -572,15 +584,15 @@ cd->irStruct->constVtbl = llvm::cast(cvtblInit); // create interface vtable const initalizers - for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + 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; - const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get()); // generate interface info initializer @@ -707,9 +719,9 @@ // initialize interface vtables IrStruct* irstruct = cd->irStruct; std::vector infoInits; - for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) { - IrInterface* iri = i->second; + IrInterface* iri = *i; iri->vtbl->setInitializer(iri->vtblInit); infoInits.push_back(iri->infoInit); } @@ -758,7 +770,7 @@ LOG_SCOPE; DValue* thisval = newexp->thisexp->toElem(gIR); size_t idx = 2; - idx += tc->sym->irStruct->interfaces.size(); + //idx += tc->sym->irStruct->interfaces.size(); llvm::Value* dst = thisval->getRVal(); llvm::Value* src = DtoGEPi(mem,0,idx,"tmp"); Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; @@ -770,7 +782,7 @@ Logger::println("Resolving nested context"); LOG_SCOPE; size_t idx = 2; - idx += tc->sym->irStruct->interfaces.size(); + //idx += tc->sym->irStruct->interfaces.size(); llvm::Value* nest = gIR->func()->decl->irFunc->nestedVar; if (!nest) nest = gIR->func()->decl->irFunc->thisVar; @@ -1064,7 +1076,7 @@ // vtable is 0, monitor is 1 r += 2; // interface offset further - r += vtblInterfaces->dim; + //r += vtblInterfaces->dim; // the final index was not pushed result.push_back(r); } diff -r 8f43f5c43c95 -r a123dca8349b gen/tollvm.cpp --- a/gen/tollvm.cpp Wed Jan 23 12:58:51 2008 +0100 +++ b/gen/tollvm.cpp Wed Jan 23 15:48:19 2008 +0100 @@ -732,7 +732,7 @@ else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration()) { size_t idx = 2; - idx += cd->irStruct->interfaces.size(); + //idx += cd->irStruct->interfaceVec.size(); v = DtoGEPi(v,0,idx,"tmp"); v = DtoLoad(v); } diff -r 8f43f5c43c95 -r a123dca8349b ir/irstruct.h --- a/ir/irstruct.h Wed Jan 23 12:58:51 2008 +0100 +++ b/ir/irstruct.h Wed Jan 23 15:48:19 2008 +0100 @@ -42,18 +42,12 @@ : var(v), type(ty), init(NULL) {} }; - struct InterCmp - { - bool operator()(ClassDeclaration* lhs, ClassDeclaration* rhs) const - { - return strcmp(lhs->toPrettyChars(), rhs->toPrettyChars()) < 0; - } - }; - typedef std::multimap OffsetMap; typedef std::vector VarDeclVector; - typedef std::map InterfaceMap; - typedef InterfaceMap::iterator InterfaceIter; + typedef std::map InterfaceMap; + typedef InterfaceMap::iterator InterfaceMapIter; + typedef std::vector InterfaceVector; + typedef InterfaceVector::iterator InterfaceVectorIter; public: IrStruct(Type*); @@ -64,7 +58,8 @@ OffsetMap offsets; VarDeclVector defaultFields; - InterfaceMap interfaces; + InterfaceMap interfaceMap; + InterfaceVector interfaceVec; const llvm::ArrayType* interfaceInfosTy; llvm::GlobalVariable* interfaceInfos;