mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-04-07 18:42:36 +00:00
make const actually work, and add unsafe(const)
for old behavior
This commit is contained in:
parent
236c9b4224
commit
7e86116ab1
9 changed files with 25 additions and 16 deletions
|
@ -177,6 +177,7 @@ std2:
|
|||
/* Other keywords from UnrealScript */
|
||||
'abstract' { RET(TK_Abstract); }
|
||||
'foreach' { RET(ParseVersion >= MakeVersion(4, 10, 0)? TK_ForEach : TK_Identifier); }
|
||||
'unsafe' { RET(ParseVersion >= MakeVersion(4, 15, 0)? TK_Unsafe : TK_Identifier); }
|
||||
'true' { RET(TK_True); }
|
||||
'false' { RET(TK_False); }
|
||||
'none' { RET(TK_None); }
|
||||
|
|
|
@ -80,6 +80,7 @@ xx(TK_Color, "'color'")
|
|||
xx(TK_Goto, "'goto'")
|
||||
xx(TK_Abstract, "'abstract'")
|
||||
xx(TK_ForEach, "'foreach'")
|
||||
xx(TK_Unsafe, "'unsafe'")
|
||||
xx(TK_True, "'true'")
|
||||
xx(TK_False, "'false'")
|
||||
xx(TK_None, "'none'")
|
||||
|
|
|
@ -6701,7 +6701,7 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
|
|||
}
|
||||
FxExpression *self = new FxSelf(ScriptPosition);
|
||||
self = self->Resolve(ctx);
|
||||
newex = ResolveMember(ctx, ctx.Function->Variants[0].SelfClass, self, ctx.Function->Variants[0].SelfClass);
|
||||
newex = ResolveMember(ctx, ctx.Function->Variants[0].SelfClass, self, ctx.Function->Variants[0].SelfClass, ctx.Function->Variants[0].Flags & VARF_SafeConst);
|
||||
ABORT(newex);
|
||||
goto foundit;
|
||||
}
|
||||
|
@ -6863,7 +6863,7 @@ foundit:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PContainerType *classctx, FxExpression *&object, PContainerType *objtype)
|
||||
FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PContainerType *classctx, FxExpression *&object, PContainerType *objtype, bool isConst)
|
||||
{
|
||||
PSymbol *sym;
|
||||
PSymbolTable *symtbl;
|
||||
|
@ -6956,7 +6956,7 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PContainerType *
|
|||
}
|
||||
}
|
||||
|
||||
auto x = isclass ? new FxClassMember(object, vsym, ScriptPosition) : new FxStructMember(object, vsym, ScriptPosition);
|
||||
auto x = isclass ? new FxClassMember(object, vsym, ScriptPosition, isConst) : new FxStructMember(object, vsym, ScriptPosition, isConst);
|
||||
object = nullptr;
|
||||
return x->Resolve(ctx);
|
||||
}
|
||||
|
@ -7611,8 +7611,8 @@ FxMemberBase::FxMemberBase(EFxType type, PField *f, const FScriptPosition &p)
|
|||
}
|
||||
|
||||
|
||||
FxStructMember::FxStructMember(FxExpression *x, PField* mem, const FScriptPosition &pos)
|
||||
: FxMemberBase(EFX_StructMember, mem, pos)
|
||||
FxStructMember::FxStructMember(FxExpression *x, PField* mem, const FScriptPosition &pos, bool isConst)
|
||||
: FxMemberBase(EFX_StructMember, mem, pos), IsConst(isConst)
|
||||
{
|
||||
classx = x;
|
||||
}
|
||||
|
@ -7662,7 +7662,7 @@ bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable)
|
|||
bWritable = false;
|
||||
}
|
||||
|
||||
*writable = bWritable;
|
||||
*writable = bWritable && !IsConst;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -7873,8 +7873,8 @@ ExpEmit FxStructMember::Emit(VMFunctionBuilder *build)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FxClassMember::FxClassMember(FxExpression *x, PField* mem, const FScriptPosition &pos)
|
||||
: FxStructMember(x, mem, pos)
|
||||
FxClassMember::FxClassMember(FxExpression *x, PField* mem, const FScriptPosition &pos, bool isConst)
|
||||
: FxStructMember(x, mem, pos, isConst)
|
||||
{
|
||||
ExprType = EFX_ClassMember;
|
||||
}
|
||||
|
|
|
@ -396,7 +396,7 @@ public:
|
|||
|
||||
FxIdentifier(FName i, const FScriptPosition &p);
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
FxExpression *ResolveMember(FCompileContext&, PContainerType*, FxExpression*&, PContainerType*);
|
||||
FxExpression *ResolveMember(FCompileContext&, PContainerType*, FxExpression*&, PContainerType*, bool isConst = false);
|
||||
};
|
||||
|
||||
|
||||
|
@ -1475,8 +1475,9 @@ class FxStructMember : public FxMemberBase
|
|||
{
|
||||
public:
|
||||
FxExpression *classx;
|
||||
bool IsConst;
|
||||
|
||||
FxStructMember(FxExpression*, PField*, const FScriptPosition&);
|
||||
FxStructMember(FxExpression*, PField*, const FScriptPosition&, bool isConst = false);
|
||||
~FxStructMember();
|
||||
FxExpression *Resolve(FCompileContext&);
|
||||
bool RequestAddress(FCompileContext &ctx, bool *writable);
|
||||
|
@ -1494,7 +1495,7 @@ class FxClassMember : public FxStructMember
|
|||
{
|
||||
public:
|
||||
|
||||
FxClassMember(FxExpression*, PField*, const FScriptPosition&);
|
||||
FxClassMember(FxExpression*, PField*, const FScriptPosition&, bool isConst = false);
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -37,6 +37,7 @@ enum
|
|||
VARF_VirtualScope = (1<<22), // [ZZ] virtualscope: object should use the scope of the particular class it's being used with (methods only)
|
||||
VARF_ClearScope = (1<<23), // [ZZ] clearscope: this method ignores the member access chain that leads to it and is always plain data.
|
||||
VARF_Abstract = (1<<24), // [Player701] Function does not have a body and must be overridden in subclasses
|
||||
VARF_SafeConst = (1<<25), // [Jay] properly-working const function/unsafe clearscope field
|
||||
};
|
||||
|
||||
// Basic information shared by all types ------------------------------------
|
||||
|
|
|
@ -1316,8 +1316,9 @@ decl_flag(X) ::= PLAY(T). { X.Int = ZCC_Play; X.SourceLoc = T.SourceLoc; }
|
|||
decl_flag(X) ::= CLEARSCOPE(T). { X.Int = ZCC_ClearScope; X.SourceLoc = T.SourceLoc; }
|
||||
decl_flag(X) ::= VIRTUALSCOPE(T). { X.Int = ZCC_VirtualScope; X.SourceLoc = T.SourceLoc; }
|
||||
|
||||
func_const(X) ::= . { X.Int = 0; X.SourceLoc = stat->sc->GetMessageLine(); }
|
||||
func_const(X) ::= CONST(T). { X.Int = ZCC_FuncConst; X.SourceLoc = T.SourceLoc; }
|
||||
func_const(X) ::= . { X.Int = 0; X.SourceLoc = stat->sc->GetMessageLine(); }
|
||||
func_const(X) ::= CONST(T). { X.Int = ZCC_FuncConst; X.SourceLoc = T.SourceLoc; }
|
||||
func_const(X) ::= UNSAFE(T) LPAREN CONST RPAREN. { X.Int = ZCC_FuncConstUnsafe; X.SourceLoc = T.SourceLoc; }
|
||||
|
||||
opt_func_body(X) ::= SEMICOLON. { X = NULL; }
|
||||
opt_func_body(X) ::= function_body(X).
|
||||
|
|
|
@ -1475,8 +1475,8 @@ bool ZCCCompiler::CompileFields(PContainerType *type, TArray<ZCC_VarDeclarator *
|
|||
|
||||
// For structs only allow 'deprecated', for classes exclude function qualifiers.
|
||||
int notallowed = forstruct?
|
||||
ZCC_Latent | ZCC_Final | ZCC_Action | ZCC_Static | ZCC_FuncConst | ZCC_Abstract | ZCC_Virtual | ZCC_Override | ZCC_Meta | ZCC_Extension | ZCC_VirtualScope | ZCC_ClearScope :
|
||||
ZCC_Latent | ZCC_Final | ZCC_Action | ZCC_Static | ZCC_FuncConst | ZCC_Abstract | ZCC_Virtual | ZCC_Override | ZCC_Extension | ZCC_VirtualScope | ZCC_ClearScope;
|
||||
ZCC_Latent | ZCC_Final | ZCC_Action | ZCC_Static | ZCC_FuncConst | ZCC_FuncConstUnsafe | ZCC_Abstract | ZCC_Virtual | ZCC_Override | ZCC_Meta | ZCC_Extension | ZCC_VirtualScope | ZCC_ClearScope :
|
||||
ZCC_Latent | ZCC_Final | ZCC_Action | ZCC_Static | ZCC_FuncConst | ZCC_FuncConstUnsafe | ZCC_Abstract | ZCC_Virtual | ZCC_Override | ZCC_Extension | ZCC_VirtualScope | ZCC_ClearScope;
|
||||
|
||||
// Some internal fields need to be set to clearscope.
|
||||
if (fileSystem.GetFileContainer(Lump) == 0) notallowed &= ~ZCC_ClearScope;
|
||||
|
@ -2446,7 +2446,9 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
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 (f->Flags & ZCC_FuncConst) varflags |= (mVersion >= MakeVersion(4, 15, 0) ? VARF_ReadOnly | VARF_SafeConst : VARF_ReadOnly); // FuncConst method is internally marked as VARF_ReadOnly
|
||||
if (f->Flags & ZCC_FuncConstUnsafe) varflags |= VARF_ReadOnly;
|
||||
|
||||
if (mVersion >= MakeVersion(2, 4, 0))
|
||||
{
|
||||
if (c->Type()->ScopeFlags & Scope_UI)
|
||||
|
|
|
@ -251,6 +251,7 @@ static void InitTokenMap()
|
|||
TOKENDEF (TK_Do, ZCC_DO);
|
||||
TOKENDEF (TK_For, ZCC_FOR);
|
||||
TOKENDEF (TK_ForEach, ZCC_FOREACH);
|
||||
TOKENDEF (TK_Unsafe, ZCC_UNSAFE);
|
||||
TOKENDEF (TK_While, ZCC_WHILE);
|
||||
TOKENDEF (TK_Until, ZCC_UNTIL);
|
||||
TOKENDEF (TK_If, ZCC_IF);
|
||||
|
|
|
@ -65,6 +65,7 @@ enum
|
|||
ZCC_Version = 1 << 21,
|
||||
ZCC_Internal = 1 << 22,
|
||||
ZCC_Sealed = 1 << 23,
|
||||
ZCC_FuncConstUnsafe = 1 << 24,
|
||||
};
|
||||
|
||||
// Function parameter modifiers
|
||||
|
|
Loading…
Reference in a new issue