Build vtable type lazily

This commit is contained in:
Martin 2016-11-05 00:30:25 +01:00
parent 7ebcae7b6b
commit e1394fad5f
5 changed files with 23 additions and 20 deletions

View file

@ -390,6 +390,7 @@ LLValue *DtoVirtualFunctionPointer(DValue *inst, FuncDeclaration *fdecl,
LLValue *funcval = vthis;
// get the vtbl for objects
stripModifiers(inst->type->toBasetype())->ctype->isClass()->getVtblType(true);
funcval = DtoGEPi(funcval, 0, 0);
// load vtbl ptr
funcval = DtoLoad(funcval);

View file

@ -2664,6 +2664,7 @@ public:
LLValue *val = DtoRVal(ex);
// Get and load vtbl pointer.
stripModifiers(t)->ctype->isClass()->getVtblType(true);
llvm::Value *vtbl = DtoLoad(DtoGEPi(val, 0, 0));
// TypeInfo ptr is first vtbl entry.

View file

@ -49,7 +49,7 @@ LLGlobalVariable *IrAggr::getVtblSymbol() {
// create the vtblZ symbol
auto initname = getMangledVTableSymbolName(aggrdecl);
LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtbl();
LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtblType(false);
vtbl =
getOrCreateGlobal(aggrdecl->loc, gIR->module, vtblTy, true,
@ -224,7 +224,7 @@ LLConstant *IrAggr::getVtblInit() {
}
// build the constant struct
LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtbl();
LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtblType(true);
#ifndef NDEBUG
size_t nc = constants.size();
@ -241,10 +241,6 @@ LLConstant *IrAggr::getVtblInit() {
#endif
constVtbl = LLConstantStruct::get(isaStruct(vtblTy), constants);
assert(constVtbl->getType() ==
stripModifiers(type)->ctype->isClass()->getVtbl() &&
"vtbl initializer type mismatch");
return constVtbl;
}

View file

@ -117,19 +117,6 @@ IrTypeClass *IrTypeClass::get(ClassDeclaration *cd) {
isaStruct(t->type)->setBody(builder.defaultTypes(), t->packed);
t->varGEPIndices = builder.varGEPIndices();
// set vtbl type body
FuncDeclarations vtbl;
vtbl.reserve(cd->vtbl.dim);
if (!cd->isCPPclass())
vtbl.push(nullptr);
for (size_t i = cd->vtblOffset(); i < cd->vtbl.dim; ++i) {
FuncDeclaration *fd = cd->vtbl[i]->isFuncDeclaration();
assert(fd);
vtbl.push(fd);
}
Type* first = cd->isCPPclass() ? nullptr : Type::typeinfoclass->type;
t->vtbl_type->setBody(t->buildVtblType(first, &vtbl));
IF_LOG Logger::cout() << "class type: " << *t->type << std::endl;
return t;
@ -194,6 +181,24 @@ llvm::Type *IrTypeClass::getLLType() { return llvm::PointerType::get(type, 0); }
llvm::Type *IrTypeClass::getMemoryLLType() { return type; }
llvm::StructType *IrTypeClass::getVtblType(bool notOpaque) {
if (notOpaque && vtbl_type->isOpaque()) {
FuncDeclarations vtbl;
vtbl.reserve(cd->vtbl.dim);
if (!cd->isCPPclass())
vtbl.push(nullptr);
for (size_t i = cd->vtblOffset(); i < cd->vtbl.dim; ++i) {
FuncDeclaration *fd = cd->vtbl[i]->isFuncDeclaration();
assert(fd);
vtbl.push(fd);
}
Type* first = cd->isCPPclass() ? nullptr : Type::typeinfoclass->type;
vtbl_type->setBody(buildVtblType(first, &vtbl));
}
return vtbl_type;
}
size_t IrTypeClass::getInterfaceIndex(ClassDeclaration *inter) {
auto it = interfaceMap.find(inter);
if (it == interfaceMap.end()) {

View file

@ -37,7 +37,7 @@ public:
llvm::Type *getMemoryLLType();
/// Returns the vtable type for this class.
llvm::Type *getVtbl() { return vtbl_type; }
llvm::StructType *getVtblType(bool notOpaque);
/// Get index to interface implementation.
/// Returns the index of a specific interface implementation in this