diff --git a/dmd/aggregate.h b/dmd/aggregate.h index a268a6bf..cdb326ee 100644 --- a/dmd/aggregate.h +++ b/dmd/aggregate.h @@ -154,6 +154,8 @@ struct UnionDeclaration : StructDeclaration UnionDeclaration *isUnionDeclaration() { return this; } }; +// warning: two classes with the same base class share the same +// BaseClass instance. struct BaseClass { Type *type; // (before semantic processing) diff --git a/gen/classes.cpp b/gen/classes.cpp index deea99ac..dba377ae 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -66,7 +66,7 @@ static void add_interface(ClassDeclaration* target, BaseClass* b, int newinstanc } // build the interface vtable - b->fillVtbl(target, &b->vtbl, newinstance); + b->fillVtbl(target, &iri->vtblDecls, newinstance); // add the vtable type assert(inter->type->ir.type); @@ -493,8 +493,8 @@ static size_t init_class_initializer(std::vector& inits, ClassDecla lastsize = var->type->size(); } - // if it's a class, and it implements interfaces, add the vtables - IrStruct* irstruct = cd->ir.irStruct; + // if it's a class, and it implements interfaces, add the vtables - as found in the target class! + IrStruct* irstruct = target->ir.irStruct; size_t nvtbls = cd->vtblInterfaces->dim; for(size_t i=0; idecl->toChars()); // build vtable intializer for this interface implementation - Array& arr = iri->base->vtbl; + Array& arr = iri->vtblDecls; size_t narr = arr.dim; if (narr > 0) diff --git a/ir/irstruct.h b/ir/irstruct.h index c4d51bd3..eca25a25 100644 --- a/ir/irstruct.h +++ b/ir/irstruct.h @@ -164,6 +164,7 @@ struct IrInterface : IrBase LLConstant* vtblInit; LLGlobalVariable* vtbl; + Array vtblDecls; // array of FuncDecls that make up the vtbl const LLStructType* infoTy; LLConstant* infoInit;