- Implement return type covariance for ZScript virtual functions

This commit is contained in:
Player701 2019-11-09 19:22:47 +03:00 committed by Christoph Oelckers
parent a8d966c6a2
commit 3a526c9e5a
6 changed files with 14 additions and 9 deletions

View file

@ -51,6 +51,7 @@
// TYPES -------------------------------------------------------------------
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
bool AreCompatiblePointerTypes(PType* dest, PType* source, bool forcompare = false);
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
@ -665,7 +666,7 @@ PClass *PClass::FindClassTentative(FName name)
//
//==========================================================================
int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc)
int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType)
{
auto proto = variant->Proto;
for (unsigned i = 0; i < Virtuals.Size(); i++)
@ -693,7 +694,10 @@ int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction
for (unsigned a = 0; a < proto->ReturnTypes.Size(); a++)
{
if (proto->ReturnTypes[a] != vproto->ReturnTypes[a])
PType* expected = vproto->ReturnTypes[a];
PType* actual = proto->ReturnTypes[a];
if (expected != actual && (exactReturnType || !AreCompatiblePointerTypes(expected, actual)))
{
fail = true;
break;

View file

@ -43,7 +43,7 @@ public:
void InitializeSpecials(void* addr, void* defaults, TArray<FTypeAndOffset> PClass::* Inits);
void WriteAllFields(FSerializer &ar, const void *addr) const;
bool ReadAllFields(FSerializer &ar, void *addr) const;
int FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc);
int FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType);
PSymbol *FindSymbol(FName symname, bool searchparents) const;
PField *AddField(FName name, PType *type, uint32_t flags);
void InitializeDefaults();

View file

@ -81,7 +81,7 @@ static const FLOP FxFlops[] =
{ NAME_Round, FLOP_ROUND, [](double v) { return round(v); } },
};
static bool AreCompatiblePointerTypes(PType* dest, PType* source, bool forcompare = false);
bool AreCompatiblePointerTypes(PType* dest, PType* source, bool forcompare = false);
//==========================================================================
//
@ -271,7 +271,7 @@ PFunction *FindBuiltinFunction(FName funcname)
//
//==========================================================================
static bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare)
bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare)
{
if (dest->isPointer() && source->isPointer())
{

View file

@ -2366,6 +2366,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
sym->Variants[0].Implementation->VarFlags = sym->Variants[0].Flags;
}
bool exactReturnType = mVersion < MakeVersion(4, 4);
PClass *clstype = forclass? static_cast<PClassType *>(c->Type())->Descriptor : nullptr;
if (varflags & VARF_Virtual)
{
@ -2379,7 +2380,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
{
auto parentfunc = clstype->ParentClass? dyn_cast<PFunction>(clstype->ParentClass->VMType->Symbols.FindSymbol(sym->SymbolName, true)) : nullptr;
int vindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], parentfunc);
int vindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], parentfunc, exactReturnType);
// specifying 'override' is necessary to prevent one of the biggest problem spots with virtual inheritance: Mismatching argument types.
if (varflags & VARF_Override)
{
@ -2459,7 +2460,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
}
else if (forclass)
{
int vindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], nullptr);
int vindex = clstype->FindVirtualIndex(sym->SymbolName, &sym->Variants[0], nullptr, exactReturnType);
if (vindex != -1)
{
Error(f, "Function %s attempts to override parent function without 'override' qualifier", FName(f->Name).GetChars());

View file

@ -1,4 +1,4 @@
version "4.3"
version "4.4"
#include "zscript/base.zs"
#include "zscript/sounddata.zs"
#include "zscript/mapdata.zs"

View file

@ -1,2 +1,2 @@
version "4.2"
version "4.4"
#include "zscript/harm_sbar.zs"