mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2025-02-22 19:21:28 +00:00
- fixed identifier resolution in FxIdentifier for action functions with a different invoker than self.
- fixed creation of direct function invocations on a state line. In order to receive the implicit arguments this needs to be wrapped into a compound statement so that the local variable getter works.
This commit is contained in:
parent
fe74a14431
commit
a603af805c
3 changed files with 27 additions and 11 deletions
|
@ -2495,6 +2495,10 @@ unsigned PFunction::AddVariant(PPrototype *proto, TArray<DWORD> &argflags, TArra
|
||||||
variant.SelfClass = dyn_cast<PClass>(selftypeptr->PointedType);
|
variant.SelfClass = dyn_cast<PClass>(selftypeptr->PointedType);
|
||||||
assert(variant.SelfClass != nullptr);
|
assert(variant.SelfClass != nullptr);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
variant.SelfClass = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return Variants.Push(variant);
|
return Variants.Push(variant);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5096,14 +5096,11 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
|
||||||
// Ugh, the horror. Constants need to be taken from the owning class, but members from the self class to catch invalid accesses here...
|
// Ugh, the horror. Constants need to be taken from the owning class, but members from the self class to catch invalid accesses here...
|
||||||
// see if the current class (if valid) defines something with this name.
|
// see if the current class (if valid) defines something with this name.
|
||||||
PSymbolTable *symtbl;
|
PSymbolTable *symtbl;
|
||||||
if ((sym = ctx.FindInClass(Identifier, symtbl)) != nullptr)
|
|
||||||
|
// first check fields in self
|
||||||
|
if ((sym = ctx.FindInSelfClass(Identifier, symtbl)) != nullptr)
|
||||||
{
|
{
|
||||||
if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst)))
|
if (sym->IsKindOf(RUNTIME_CLASS(PField)))
|
||||||
{
|
|
||||||
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as class constant\n", Identifier.GetChars());
|
|
||||||
newex = FxConstant::MakeConstant(sym, ScriptPosition);
|
|
||||||
}
|
|
||||||
else if (sym->IsKindOf(RUNTIME_CLASS(PField)))
|
|
||||||
{
|
{
|
||||||
if (!ctx.Function)
|
if (!ctx.Function)
|
||||||
{
|
{
|
||||||
|
@ -5161,6 +5158,18 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
|
||||||
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as member variable, index %d\n", Identifier.GetChars(), vsym->Offset);
|
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as member variable, index %d\n", Identifier.GetChars(), vsym->Offset);
|
||||||
newex = new FxClassMember((new FxSelf(ScriptPosition))->Resolve(ctx), vsym, ScriptPosition);
|
newex = new FxClassMember((new FxSelf(ScriptPosition))->Resolve(ctx), vsym, ScriptPosition);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now constants in the owning class.
|
||||||
|
if (newex == nullptr && (sym = ctx.FindInClass(Identifier, symtbl)) != nullptr)
|
||||||
|
{
|
||||||
|
if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst)))
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as class constant\n", Identifier.GetChars());
|
||||||
|
newex = FxConstant::MakeConstant(sym, ScriptPosition);
|
||||||
|
delete this;
|
||||||
|
return newex->Resolve(ctx);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (sym->IsKindOf(RUNTIME_CLASS(PFunction)))
|
if (sym->IsKindOf(RUNTIME_CLASS(PFunction)))
|
||||||
|
@ -5177,7 +5186,7 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// now check the global identifiers.
|
// now check the global identifiers.
|
||||||
else if ((sym = ctx.FindGlobal(Identifier)) != nullptr)
|
if (newex == nullptr && (sym = ctx.FindGlobal(Identifier)) != nullptr)
|
||||||
{
|
{
|
||||||
if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst)))
|
if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst)))
|
||||||
{
|
{
|
||||||
|
@ -5197,12 +5206,13 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// and line specials
|
// and line specials
|
||||||
else if ((num = P_FindLineSpecial(Identifier, nullptr, nullptr)))
|
if (newex == nullptr && (num = P_FindLineSpecial(Identifier, nullptr, nullptr)))
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as line special %d\n", Identifier.GetChars(), num);
|
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as line special %d\n", Identifier.GetChars(), num);
|
||||||
newex = new FxConstant(num, ScriptPosition);
|
newex = new FxConstant(num, ScriptPosition);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (newex == nullptr)
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "Unknown identifier '%s'", Identifier.GetChars());
|
ScriptPosition.Message(MSG_ERROR, "Unknown identifier '%s'", Identifier.GetChars());
|
||||||
delete this;
|
delete this;
|
||||||
|
|
|
@ -2577,7 +2577,9 @@ FxExpression *ZCCCompiler::ConvertAST(PClass *cls, ZCC_TreeNode *ast)
|
||||||
// there are two possibilities here: either a single function call or a compound statement. For a compound statement we also need to check if the last thing added was a return.
|
// there are two possibilities here: either a single function call or a compound statement. For a compound statement we also need to check if the last thing added was a return.
|
||||||
if (ast->NodeType == AST_ExprFuncCall)
|
if (ast->NodeType == AST_ExprFuncCall)
|
||||||
{
|
{
|
||||||
return new FxReturnStatement(ConvertNode(ast), *ast);
|
auto cp = new FxCompoundStatement(*ast);
|
||||||
|
cp->Add(new FxReturnStatement(ConvertNode(ast), *ast));
|
||||||
|
return cp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue