Fixed classinfo.interfaces for .. interfaces!

This commit is contained in:
Tomas Lindquist Olsen 2009-04-21 20:19:53 +02:00
parent 4567a55f7f
commit 575038bfbd
5 changed files with 54 additions and 13 deletions

View file

@ -58,18 +58,22 @@ void DtoResolveClass(ClassDeclaration* cd)
// 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)
{

View file

@ -424,11 +424,20 @@ LLConstant * IrStruct::getClassInfoInterfaces()
ci = DtoBitCast(ci, classinfo_type);
// vtbl
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");
LLConstant* vtb = itv->second;
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 @@ LLConstant * IrStruct::getClassInfoInterfaces()
}
//////////////////////////////////////////////////////////////////////////////
void IrStruct::initializeInterface()
{
InterfaceDeclaration* base = aggrdecl->isInterfaceDeclaration();
assert(base && "not interface");
// has interface vtbls?
if (!base->vtblInterfaces)
return;
ArrayIter<BaseClass> it(*base->vtblInterfaces);
for (; !it.done(); it.next())
{
// add to the interface list
interfacesWithVtbls.push_back(it.get());
}
}
//////////////////////////////////////////////////////////////////////////////

View file

@ -371,4 +371,3 @@ LLConstant * IrStruct::createStructInitializer(StructInitializer * si)
IF_LOG Logger::cout() << "final struct initializer: " << *c << std::endl;
return c;
}

View file

@ -58,6 +58,11 @@ struct IrStruct : IrBase
LLConstant* createStructInitializer(StructInitializer* si);
//////////////////////////////////////////////////////////////////////////
/// Initialize interface.
void initializeInterface();
//////////////////////////////////////////////////////////////////////////
protected:
/// Static default initializer global.
llvm::GlobalVariable* init;

View file

@ -142,8 +142,13 @@ const llvm::Type* IrTypeClass::buildType()
// 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));