mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 09:00:33 +03:00
Fixed classinfo.interfaces for .. interfaces!
This commit is contained in:
parent
4567a55f7f
commit
575038bfbd
5 changed files with 54 additions and 13 deletions
|
@ -58,18 +58,22 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||||
// emit the ClassZ symbol
|
// emit the ClassZ symbol
|
||||||
LLGlobalVariable* ClassZ = irstruct->getClassInfoSymbol();
|
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
|
// interface only emit typeinfo and classinfo
|
||||||
if (!cd->isInterfaceDeclaration())
|
if (cd->isInterfaceDeclaration())
|
||||||
|
{
|
||||||
|
irstruct->initializeInterface();
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// emit the initZ symbol
|
// emit the initZ symbol
|
||||||
LLGlobalVariable* initZ = irstruct->getInitSymbol();
|
LLGlobalVariable* initZ = irstruct->getInitSymbol();
|
||||||
// emit the vtblZ symbol
|
// emit the vtblZ symbol
|
||||||
LLGlobalVariable* vtblZ = irstruct->getVtblSymbol();
|
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
|
// perform definition
|
||||||
if (needs_def)
|
if (needs_def)
|
||||||
{
|
{
|
||||||
|
|
|
@ -424,11 +424,20 @@ LLConstant * IrStruct::getClassInfoInterfaces()
|
||||||
ci = DtoBitCast(ci, classinfo_type);
|
ci = DtoBitCast(ci, classinfo_type);
|
||||||
|
|
||||||
// vtbl
|
// vtbl
|
||||||
ClassGlobalMap::iterator itv = interfaceVtblMap.find(it->base);
|
LLConstant* vtb;
|
||||||
assert(itv != interfaceVtblMap.end() && "interface vtbl not found");
|
// interface get a null
|
||||||
LLConstant* vtb = itv->second;
|
if (cd->isInterfaceDeclaration())
|
||||||
vtb = DtoBitCast(vtb, voidptrptr_type);
|
{
|
||||||
vtb = DtoConstSlice(DtoConstSize_t(itc->getVtblSize()), vtb);
|
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
|
// offset
|
||||||
LLConstant* off = DtoConstSize_t(it->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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -371,4 +371,3 @@ LLConstant * IrStruct::createStructInitializer(StructInitializer * si)
|
||||||
IF_LOG Logger::cout() << "final struct initializer: " << *c << std::endl;
|
IF_LOG Logger::cout() << "final struct initializer: " << *c << std::endl;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,11 @@ struct IrStruct : IrBase
|
||||||
LLConstant* createStructInitializer(StructInitializer* si);
|
LLConstant* createStructInitializer(StructInitializer* si);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/// Initialize interface.
|
||||||
|
void initializeInterface();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
protected:
|
protected:
|
||||||
/// Static default initializer global.
|
/// Static default initializer global.
|
||||||
llvm::GlobalVariable* init;
|
llvm::GlobalVariable* init;
|
||||||
|
|
|
@ -142,8 +142,13 @@ const llvm::Type* IrTypeClass::buildType()
|
||||||
// add vtbl
|
// add vtbl
|
||||||
defaultTypes.push_back(llvm::PointerType::get(vtbl_pa.get(), 0));
|
defaultTypes.push_back(llvm::PointerType::get(vtbl_pa.get(), 0));
|
||||||
|
|
||||||
// interface are just a vtable
|
// interfaces are just a vtable
|
||||||
if (!cd->isInterfaceDeclaration())
|
if (cd->isInterfaceDeclaration())
|
||||||
|
{
|
||||||
|
num_interface_vtbls = cd->vtblInterfaces ? cd->vtblInterfaces->dim : 0;
|
||||||
|
}
|
||||||
|
// classes have monitor and fields
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// add monitor
|
// add monitor
|
||||||
defaultTypes.push_back(llvm::PointerType::get(llvm::Type::Int8Ty, 0));
|
defaultTypes.push_back(llvm::PointerType::get(llvm::Type::Int8Ty, 0));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue