- 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:
Christoph Oelckers 2016-11-12 15:21:59 +01:00
parent fe74a14431
commit a603af805c
3 changed files with 27 additions and 11 deletions

View file

@ -2495,6 +2495,10 @@ unsigned PFunction::AddVariant(PPrototype *proto, TArray<DWORD> &argflags, TArra
variant.SelfClass = dyn_cast<PClass>(selftypeptr->PointedType);
assert(variant.SelfClass != nullptr);
}
else
{
variant.SelfClass = nullptr;
}
return Variants.Push(variant);
}

View file

@ -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...
// see if the current class (if valid) defines something with this name.
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)))
{
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 (sym->IsKindOf(RUNTIME_CLASS(PField)))
{
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);
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
{
if (sym->IsKindOf(RUNTIME_CLASS(PFunction)))
@ -5177,7 +5186,7 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
}
// 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)))
{
@ -5197,12 +5206,13 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
}
// 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);
newex = new FxConstant(num, ScriptPosition);
}
else
if (newex == nullptr)
{
ScriptPosition.Message(MSG_ERROR, "Unknown identifier '%s'", Identifier.GetChars());
delete this;

View file

@ -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.
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
{