# HG changeset patch # User Tomas Lindquist Olsen # Date 1240337993 -7200 # Node ID 752bed475b757d24d918e03fc6e395d852cbeec8 # Parent 7c1b55db4ff34565fdc3714ccfc6ee20a5d2dd95 Fixed classinfo.interfaces for .. interfaces! diff -r 7c1b55db4ff3 -r 752bed475b75 gen/classes.cpp --- a/gen/classes.cpp Tue Apr 21 19:32:22 2009 +0200 +++ b/gen/classes.cpp Tue Apr 21 20:19:53 2009 +0200 @@ -58,18 +58,22 @@ // emit the ClassZ symbol LLGlobalVariable* ClassZ = irstruct->getClassInfoSymbol(); + // emit the interfaceInfosZ symbol if necessary + if (cd->vtblInterfaces && cd->vtblInterfaces->dim > 0) + irstruct->getInterfaceArraySymbol(); // initializer is applied when it's built + // interface only emit typeinfo and classinfo - if (!cd->isInterfaceDeclaration()) + if (cd->isInterfaceDeclaration()) + { + irstruct->initializeInterface(); + } + else { // emit the initZ symbol LLGlobalVariable* initZ = irstruct->getInitSymbol(); // emit the vtblZ symbol LLGlobalVariable* vtblZ = irstruct->getVtblSymbol(); - // emit the interfaceInfosZ symbol if necessary - if (cd->vtblInterfaces && cd->vtblInterfaces->dim > 0) - irstruct->getInterfaceArraySymbol(); // initializer is applied when it's built - // perform definition if (needs_def) { diff -r 7c1b55db4ff3 -r 752bed475b75 ir/irclass.cpp --- a/ir/irclass.cpp Tue Apr 21 19:32:22 2009 +0200 +++ b/ir/irclass.cpp Tue Apr 21 20:19:53 2009 +0200 @@ -424,11 +424,20 @@ ci = DtoBitCast(ci, classinfo_type); // vtbl - ClassGlobalMap::iterator itv = interfaceVtblMap.find(it->base); - assert(itv != interfaceVtblMap.end() && "interface vtbl not found"); - LLConstant* vtb = itv->second; - vtb = DtoBitCast(vtb, voidptrptr_type); - vtb = DtoConstSlice(DtoConstSize_t(itc->getVtblSize()), vtb); + LLConstant* vtb; + // interface get a null + if (cd->isInterfaceDeclaration()) + { + vtb = DtoConstSlice(DtoConstSize_t(0), getNullValue(voidptrptr_type)); + } + else + { + ClassGlobalMap::iterator itv = interfaceVtblMap.find(it->base); + assert(itv != interfaceVtblMap.end() && "interface vtbl not found"); + vtb = itv->second; + vtb = DtoBitCast(vtb, voidptrptr_type); + vtb = DtoConstSlice(DtoConstSize_t(itc->getVtblSize()), vtb); + } // offset LLConstant* off = DtoConstSize_t(it->offset); @@ -473,3 +482,22 @@ } ////////////////////////////////////////////////////////////////////////////// + +void IrStruct::initializeInterface() +{ + InterfaceDeclaration* base = aggrdecl->isInterfaceDeclaration(); + assert(base && "not interface"); + + // has interface vtbls? + if (!base->vtblInterfaces) + return; + + ArrayIter it(*base->vtblInterfaces); + for (; !it.done(); it.next()) + { + // add to the interface list + interfacesWithVtbls.push_back(it.get()); + } +} + +////////////////////////////////////////////////////////////////////////////// diff -r 7c1b55db4ff3 -r 752bed475b75 ir/irstruct.cpp --- a/ir/irstruct.cpp Tue Apr 21 19:32:22 2009 +0200 +++ b/ir/irstruct.cpp Tue Apr 21 20:19:53 2009 +0200 @@ -371,4 +371,3 @@ IF_LOG Logger::cout() << "final struct initializer: " << *c << std::endl; return c; } - diff -r 7c1b55db4ff3 -r 752bed475b75 ir/irstruct.h --- a/ir/irstruct.h Tue Apr 21 19:32:22 2009 +0200 +++ b/ir/irstruct.h Tue Apr 21 20:19:53 2009 +0200 @@ -58,6 +58,11 @@ LLConstant* createStructInitializer(StructInitializer* si); ////////////////////////////////////////////////////////////////////////// + + /// Initialize interface. + void initializeInterface(); + + ////////////////////////////////////////////////////////////////////////// protected: /// Static default initializer global. llvm::GlobalVariable* init; diff -r 7c1b55db4ff3 -r 752bed475b75 ir/irtypeclass.cpp --- a/ir/irtypeclass.cpp Tue Apr 21 19:32:22 2009 +0200 +++ b/ir/irtypeclass.cpp Tue Apr 21 20:19:53 2009 +0200 @@ -142,8 +142,13 @@ // add vtbl defaultTypes.push_back(llvm::PointerType::get(vtbl_pa.get(), 0)); - // interface are just a vtable - if (!cd->isInterfaceDeclaration()) + // interfaces are just a vtable + if (cd->isInterfaceDeclaration()) + { + num_interface_vtbls = cd->vtblInterfaces ? cd->vtblInterfaces->dim : 0; + } + // classes have monitor and fields + else { // add monitor defaultTypes.push_back(llvm::PointerType::get(llvm::Type::Int8Ty, 0));