mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 06:53:58 +00:00
Fixed some things around
This commit is contained in:
parent
3056570ea9
commit
014db18f2a
3 changed files with 24 additions and 23 deletions
|
@ -6715,16 +6715,17 @@ bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable)
|
||||||
if ((classx->ExprType == EFX_Self) && (ctx.Function && (ctx.Function->Variants[0].Flags & VARF_ReadOnly)))
|
if ((classx->ExprType == EFX_Self) && (ctx.Function && (ctx.Function->Variants[0].Flags & VARF_ReadOnly)))
|
||||||
bWritable = false;
|
bWritable = false;
|
||||||
}
|
}
|
||||||
// [ZZ] plain data "inherits" scope of whatever it was defined in.
|
// [ZZ] implement write barrier between different scopes
|
||||||
if (bWritable) // don't do complex checks on early fail
|
if (bWritable)
|
||||||
{
|
{
|
||||||
int outerflags = 0;
|
int outerflags = 0;
|
||||||
if (ctx.Function)
|
if (ctx.Function)
|
||||||
outerflags = ctx.Function->Variants[0].Flags;
|
outerflags = ctx.Function->Variants[0].Flags;
|
||||||
FScopeBarrier scopeBarrier(outerflags, FScopeBarrier::FlagsFromSide(BarrierSide), membervar->SymbolName.GetChars());
|
FScopeBarrier scopeBarrier(outerflags, FScopeBarrier::FlagsFromSide(BarrierSide), "<unknown>");
|
||||||
if (!scopeBarrier.writable)
|
if (!scopeBarrier.writable)
|
||||||
bWritable = false;
|
bWritable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*writable = bWritable;
|
*writable = bWritable;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -6769,7 +6770,7 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
BarrierSide = scopeBarrier.sidelast;
|
BarrierSide = scopeBarrier.sidelast;
|
||||||
if (classx->ExprType == EFX_StructMember || classx->ExprType == EFX_ClassMember)
|
if (classx->ExprType == EFX_StructMember) // note: only do this for structs now
|
||||||
{
|
{
|
||||||
FxStructMember* pmember = (FxStructMember*)classx;
|
FxStructMember* pmember = (FxStructMember*)classx;
|
||||||
if (BarrierSide == FScopeBarrier::Side_PlainData && pmember)
|
if (BarrierSide == FScopeBarrier::Side_PlainData && pmember)
|
||||||
|
@ -6793,7 +6794,8 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
|
||||||
{
|
{
|
||||||
auto parentfield = static_cast<FxMemberBase *>(classx)->membervar;
|
auto parentfield = static_cast<FxMemberBase *>(classx)->membervar;
|
||||||
// PFields are garbage collected so this will be automatically taken care of later.
|
// PFields are garbage collected so this will be automatically taken care of later.
|
||||||
auto newfield = new PField(NAME_None, membervar->Type, membervar->Flags | parentfield->Flags, membervar->Offset + parentfield->Offset);
|
// [ZZ] call ChangeSideInFlags to ensure that we don't get ui+play
|
||||||
|
auto newfield = new PField(NAME_None, membervar->Type, FScopeBarrier::ChangeSideInFlags(membervar->Flags | parentfield->Flags, BarrierSide), membervar->Offset + parentfield->Offset);
|
||||||
newfield->BitValue = membervar->BitValue;
|
newfield->BitValue = membervar->BitValue;
|
||||||
static_cast<FxMemberBase *>(classx)->membervar = newfield;
|
static_cast<FxMemberBase *>(classx)->membervar = newfield;
|
||||||
classx->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away.
|
classx->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away.
|
||||||
|
@ -8023,15 +8025,16 @@ isresolved:
|
||||||
|
|
||||||
// [ZZ] if self is a struct or a class member, check if it's valid to call this function at all.
|
// [ZZ] if self is a struct or a class member, check if it's valid to call this function at all.
|
||||||
// implement more magic
|
// implement more magic
|
||||||
if (Self->ExprType == EFX_ClassMember || Self->ExprType == EFX_StructMember)
|
|
||||||
{
|
|
||||||
FxStructMember* pmember = (FxStructMember*)Self;
|
|
||||||
int outerflags = 0;
|
int outerflags = 0;
|
||||||
if (ctx.Function)
|
if (ctx.Function)
|
||||||
outerflags = ctx.Function->Variants[0].Flags;
|
outerflags = ctx.Function->Variants[0].Flags;
|
||||||
int innerflags = afd->Variants[0].Flags;
|
int innerflags = afd->Variants[0].Flags;
|
||||||
|
if (Self->ExprType == EFX_StructMember)
|
||||||
|
{
|
||||||
|
FxStructMember* pmember = (FxStructMember*)Self;
|
||||||
if (FScopeBarrier::SideFromFlags(innerflags) == FScopeBarrier::Side_PlainData)
|
if (FScopeBarrier::SideFromFlags(innerflags) == FScopeBarrier::Side_PlainData)
|
||||||
innerflags = FScopeBarrier::ChangeSideInFlags(innerflags, pmember->BarrierSide);
|
innerflags = FScopeBarrier::ChangeSideInFlags(innerflags, pmember->BarrierSide);
|
||||||
|
}
|
||||||
FScopeBarrier scopeBarrier(outerflags, innerflags, MethodName.GetChars());
|
FScopeBarrier scopeBarrier(outerflags, innerflags, MethodName.GetChars());
|
||||||
if (!scopeBarrier.callable)
|
if (!scopeBarrier.callable)
|
||||||
{
|
{
|
||||||
|
@ -8039,7 +8042,6 @@ isresolved:
|
||||||
delete this;
|
delete this;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (staticonly && (afd->Variants[0].Flags & VARF_Method))
|
if (staticonly && (afd->Variants[0].Flags & VARF_Method))
|
||||||
{
|
{
|
||||||
|
|
|
@ -187,7 +187,7 @@ struct FScopeBarrier
|
||||||
sidelast = sideto;
|
sidelast = sideto;
|
||||||
else sideto = sidelast;
|
else sideto = sidelast;
|
||||||
|
|
||||||
if ((sideto == Side_UI) != (sidefrom == Side_UI)) // only ui -> ui is readable
|
if ((sideto == Side_UI) && (sidefrom != Side_UI)) // only ui -> ui is readable
|
||||||
{
|
{
|
||||||
readable = false;
|
readable = false;
|
||||||
readerror.Format("Can't read %s field %s from %s context", StringFromSide(sideto), name, StringFromSide(sidefrom));
|
readerror.Format("Can't read %s field %s from %s context", StringFromSide(sideto), name, StringFromSide(sidefrom));
|
||||||
|
|
|
@ -2397,9 +2397,9 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
if (varflags & VARF_Final)
|
if (varflags & VARF_Final)
|
||||||
sym->Variants[0].Implementation->Final = true;
|
sym->Variants[0].Implementation->Final = true;
|
||||||
// [ZZ] unspecified virtual function inherits old scope. virtual function scope can't be changed.
|
// [ZZ] unspecified virtual function inherits old scope. virtual function scope can't be changed.
|
||||||
if (f->Flags & ZCC_UIFlag) // only direct specification here (varflags can also have owning class scope applied, we don't want that)
|
if (varflags & VARF_UI)
|
||||||
sym->Variants[0].Implementation->ScopeUI = true;
|
sym->Variants[0].Implementation->ScopeUI = true;
|
||||||
if (f->Flags & ZCC_Play) // only direct specification here
|
if (varflags & VARF_Play)
|
||||||
sym->Variants[0].Implementation->ScopePlay = true;
|
sym->Variants[0].Implementation->ScopePlay = true;
|
||||||
if (varflags & VARF_ReadOnly)
|
if (varflags & VARF_ReadOnly)
|
||||||
sym->Variants[0].Implementation->FuncConst = true;
|
sym->Variants[0].Implementation->FuncConst = true;
|
||||||
|
@ -2422,8 +2422,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
Error(f, "Attempt to override final function %s", FName(f->Name).GetChars());
|
Error(f, "Attempt to override final function %s", FName(f->Name).GetChars());
|
||||||
}
|
}
|
||||||
// you can't change ui/play/clearscope for a virtual method.
|
// you can't change ui/play/clearscope for a virtual method.
|
||||||
if ((oldfunc->ScopePlay != sym->Variants[0].Implementation->ScopePlay) ||
|
if (f->Flags & (ZCC_UIFlag|ZCC_Play|ZCC_ClearScope))
|
||||||
(oldfunc->ScopeUI != sym->Variants[0].Implementation->ScopeUI))
|
|
||||||
{
|
{
|
||||||
Error(f, "Attempt to change scope for virtual function %s", FName(f->Name).GetChars());
|
Error(f, "Attempt to change scope for virtual function %s", FName(f->Name).GetChars());
|
||||||
}
|
}
|
||||||
|
@ -2432,7 +2431,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
{
|
{
|
||||||
Error(f, "Attempt to change const qualifier for virtual function %s", FName(f->Name).GetChars());
|
Error(f, "Attempt to change const qualifier for virtual function %s", FName(f->Name).GetChars());
|
||||||
}
|
}
|
||||||
// inherit scope of original function
|
// inherit scope of original function if override not specified
|
||||||
if (sym->Variants[0].Implementation->ScopeUI = oldfunc->ScopeUI)
|
if (sym->Variants[0].Implementation->ScopeUI = oldfunc->ScopeUI)
|
||||||
sym->Variants[0].Flags = (sym->Variants[0].Flags&~(VARF_Play)) | VARF_UI;
|
sym->Variants[0].Flags = (sym->Variants[0].Flags&~(VARF_Play)) | VARF_UI;
|
||||||
else if (sym->Variants[0].Implementation->ScopePlay = oldfunc->ScopePlay)
|
else if (sym->Variants[0].Implementation->ScopePlay = oldfunc->ScopePlay)
|
||||||
|
|
Loading…
Reference in a new issue