- 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); 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);
} }

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... // 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;

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