- Implemented ZScript abstract functions
This commit is contained in:
parent
628d23a688
commit
761dea8640
9 changed files with 82 additions and 22 deletions
|
|
@ -2042,7 +2042,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
} while (t != f->Type);
|
||||
}
|
||||
|
||||
int notallowed = ZCC_Latent | ZCC_Meta | ZCC_ReadOnly | ZCC_Abstract | ZCC_Internal;
|
||||
int notallowed = ZCC_Latent | ZCC_Meta | ZCC_ReadOnly | ZCC_Internal;
|
||||
|
||||
if (f->Flags & notallowed)
|
||||
{
|
||||
|
|
@ -2088,6 +2088,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
if (f->Flags & ZCC_Deprecated) varflags |= VARF_Deprecated;
|
||||
if (f->Flags & ZCC_Virtual) varflags |= VARF_Virtual;
|
||||
if (f->Flags & ZCC_Override) varflags |= VARF_Override;
|
||||
if (f->Flags & ZCC_Abstract) varflags |= VARF_Abstract;
|
||||
if (f->Flags & ZCC_VarArg) varflags |= VARF_VarArg;
|
||||
if (f->Flags & ZCC_FuncConst) varflags |= VARF_ReadOnly; // FuncConst method is internally marked as VARF_ReadOnly
|
||||
if (mVersion >= MakeVersion(2, 4, 0))
|
||||
|
|
@ -2131,7 +2132,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
|
||||
if (varflags & VARF_Override) varflags &= ~VARF_Virtual; // allow 'virtual override'.
|
||||
// Only one of these flags may be used.
|
||||
static int exclude[] = { ZCC_Virtual, ZCC_Override, ZCC_Action, ZCC_Static };
|
||||
static int exclude[] = { ZCC_Abstract, ZCC_Virtual, ZCC_Override, ZCC_Action, ZCC_Static };
|
||||
int excludeflags = 0;
|
||||
int fc = 0;
|
||||
for (size_t i = 0; i < countof(exclude); i++)
|
||||
|
|
@ -2147,7 +2148,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
Error(f, "Invalid combination of qualifiers %s on function %s", FlagsToString(excludeflags).GetChars(), FName(f->Name).GetChars());
|
||||
varflags |= VARF_Method;
|
||||
}
|
||||
if (varflags & VARF_Override) varflags |= VARF_Virtual; // Now that the flags are checked, make all override functions virtual as well.
|
||||
if (varflags & (VARF_Override | VARF_Abstract)) varflags |= VARF_Virtual; // Now that the flags are checked, make all override and abstract functions virtual as well.
|
||||
|
||||
// [ZZ] this doesn't make sense either.
|
||||
if ((varflags&(VARF_ReadOnly | VARF_Method)) == VARF_ReadOnly) // non-method const function
|
||||
|
|
@ -2180,6 +2181,12 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
|
||||
if (f->Flags & ZCC_Native)
|
||||
{
|
||||
if (varflags & VARF_Abstract)
|
||||
{
|
||||
Error(f, "Native functions cannot be abstract");
|
||||
return;
|
||||
}
|
||||
|
||||
varflags |= VARF_Native;
|
||||
afd = FindFunction(c->Type(), FName(f->Name).GetChars());
|
||||
if (afd == nullptr)
|
||||
|
|
@ -2371,19 +2378,20 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
|
||||
if (!(f->Flags & ZCC_Native))
|
||||
{
|
||||
if (f->Body == nullptr)
|
||||
if (f->Body != nullptr && (varflags & VARF_Abstract))
|
||||
{
|
||||
Error(f, "Abstract function %s cannot have a body", FName(f->Name).GetChars());
|
||||
return;
|
||||
}
|
||||
|
||||
if (f->Body == nullptr && !(varflags & VARF_Abstract))
|
||||
{
|
||||
Error(f, "Empty function %s", FName(f->Name).GetChars());
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto code = ConvertAST(c->Type(), f->Body);
|
||||
if (code != nullptr)
|
||||
{
|
||||
newfunc = FunctionBuildList.AddFunction(OutNamespace, mVersion, sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false, -1, 0, Lump);
|
||||
}
|
||||
}
|
||||
|
||||
FxExpression* code = f->Body != nullptr ? ConvertAST(c->Type(), f->Body) : nullptr;
|
||||
newfunc = FunctionBuildList.AddFunction(OutNamespace, mVersion, sym, code, FStringf("%s.%s", c->Type()->TypeName.GetChars(), FName(f->Name).GetChars()), false, -1, 0, Lump);
|
||||
}
|
||||
if (sym->Variants[0].Implementation != nullptr && hasdefault) // do not copy empty default lists, they only waste space and processing time.
|
||||
{
|
||||
|
|
@ -2408,6 +2416,12 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
|
||||
if (forclass)
|
||||
{
|
||||
if ((varflags & VARF_Abstract) && !clstype->bAbstract)
|
||||
{
|
||||
Error(f, "Abstract functions can only be defined in abstract classes");
|
||||
return;
|
||||
}
|
||||
|
||||
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, exactReturnType);
|
||||
|
|
@ -2526,6 +2540,18 @@ void ZCCCompiler::InitFunctions()
|
|||
{
|
||||
CompileFunction(c, f, true);
|
||||
}
|
||||
|
||||
// [Player701] Make sure all abstract functions are overridden
|
||||
if (!c->ClassType()->bAbstract)
|
||||
{
|
||||
for (auto v : c->ClassType()->Virtuals)
|
||||
{
|
||||
if (v->VarFlags & VARF_Abstract)
|
||||
{
|
||||
Error(c->cls, "Non-abstract class %s must override abstract function %s", c->Type()->TypeName.GetChars(), v->PrintableName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue