mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-02-21 19:10:50 +00:00
- Implement return type covariance for ZScript virtual functions
# Conflicts: # src/dobjtype.h # wadsrc_extra/static/filter/harmony/zscript.txt
This commit is contained in:
parent
efe5f349e5
commit
6fa409825b
5 changed files with 13 additions and 8 deletions
|
@ -59,6 +59,7 @@
|
||||||
// TYPES -------------------------------------------------------------------
|
// TYPES -------------------------------------------------------------------
|
||||||
|
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||||
|
bool AreCompatiblePointerTypes(PType* dest, PType* source, bool forcompare = false);
|
||||||
|
|
||||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||||
|
|
||||||
|
@ -778,7 +779,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;
|
auto proto = variant->Proto;
|
||||||
for (unsigned i = 0; i < Virtuals.Size(); i++)
|
for (unsigned i = 0; i < Virtuals.Size(); i++)
|
||||||
|
@ -806,7 +807,10 @@ int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction
|
||||||
|
|
||||||
for (unsigned a = 0; a < proto->ReturnTypes.Size(); a++)
|
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;
|
fail = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
void WriteAllFields(FSerializer &ar, const void *addr) const;
|
void WriteAllFields(FSerializer &ar, const void *addr) const;
|
||||||
bool ReadAllFields(FSerializer &ar, void *addr) const;
|
bool ReadAllFields(FSerializer &ar, void *addr) const;
|
||||||
void InitializeDefaults();
|
void InitializeDefaults();
|
||||||
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;
|
PSymbol *FindSymbol(FName symname, bool searchparents) const;
|
||||||
PField *AddField(FName name, PType *type, uint32_t flags);
|
PField *AddField(FName name, PType *type, uint32_t flags);
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ static const FLOP FxFlops[] =
|
||||||
{ NAME_Round, FLOP_ROUND, [](double v) { return round(v); } },
|
{ 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);
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -288,7 +288,7 @@ static 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())
|
if (dest->isPointer() && source->isPointer())
|
||||||
{
|
{
|
||||||
|
|
|
@ -3013,6 +3013,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
sym->Variants[0].Implementation->VarFlags = sym->Variants[0].Flags;
|
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;
|
PClass *clstype = forclass? static_cast<PClassType *>(c->Type())->Descriptor : nullptr;
|
||||||
if (varflags & VARF_Virtual)
|
if (varflags & VARF_Virtual)
|
||||||
{
|
{
|
||||||
|
@ -3026,7 +3027,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;
|
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.
|
// specifying 'override' is necessary to prevent one of the biggest problem spots with virtual inheritance: Mismatching argument types.
|
||||||
if (varflags & VARF_Override)
|
if (varflags & VARF_Override)
|
||||||
{
|
{
|
||||||
|
@ -3106,7 +3107,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
}
|
}
|
||||||
else if (forclass)
|
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)
|
if (vindex != -1)
|
||||||
{
|
{
|
||||||
Error(f, "Function %s attempts to override parent function without 'override' qualifier", FName(f->Name).GetChars());
|
Error(f, "Function %s attempts to override parent function without 'override' qualifier", FName(f->Name).GetChars());
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version "4.3"
|
version "4.4"
|
||||||
#include "zscript/base.zs"
|
#include "zscript/base.zs"
|
||||||
#include "zscript/sounddata.zs"
|
#include "zscript/sounddata.zs"
|
||||||
#include "zscript/mapdata.zs"
|
#include "zscript/mapdata.zs"
|
||||||
|
|
Loading…
Reference in a new issue