mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
Added support for implicitly-sized initialized arrays.
Also fixed dynamic arrays not being cleared before initializing.
This commit is contained in:
parent
a1ae01e392
commit
4fdcc47edc
4 changed files with 62 additions and 8 deletions
|
@ -11406,6 +11406,7 @@ FxLocalArrayDeclaration::FxLocalArrayDeclaration(PType *type, FName name, FArgum
|
||||||
{
|
{
|
||||||
ExprType = EFX_LocalArrayDeclaration;
|
ExprType = EFX_LocalArrayDeclaration;
|
||||||
values = std::move(args);
|
values = std::move(args);
|
||||||
|
clearExpr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FxExpression *FxLocalArrayDeclaration::Resolve(FCompileContext &ctx)
|
FxExpression *FxLocalArrayDeclaration::Resolve(FCompileContext &ctx)
|
||||||
|
@ -11421,6 +11422,16 @@ FxExpression *FxLocalArrayDeclaration::Resolve(FCompileContext &ctx)
|
||||||
auto elementType = (static_cast<PArray *> (ValueType))->ElementType;
|
auto elementType = (static_cast<PArray *> (ValueType))->ElementType;
|
||||||
auto elementCount = (static_cast<PArray *> (ValueType))->ElementCount;
|
auto elementCount = (static_cast<PArray *> (ValueType))->ElementCount;
|
||||||
|
|
||||||
|
// We HAVE to clear dynamic arrays before initializing them
|
||||||
|
if (IsDynamicArray())
|
||||||
|
{
|
||||||
|
FArgumentList argsList;
|
||||||
|
argsList.Clear();
|
||||||
|
|
||||||
|
clearExpr = new FxMemberFunctionCall(stackVar, "Clear", argsList, (const FScriptPosition) ScriptPosition);
|
||||||
|
SAFE_RESOLVE(clearExpr, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (values.Size() > elementCount)
|
if (values.Size() > elementCount)
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "Initializer contains more elements than the array can contain");
|
ScriptPosition.Message(MSG_ERROR, "Initializer contains more elements than the array can contain");
|
||||||
|
@ -11477,6 +11488,11 @@ ExpEmit FxLocalArrayDeclaration::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
assert(!(VarFlags & VARF_Out)); // 'out' variables should never be initialized, they can only exist as function parameters.
|
assert(!(VarFlags & VARF_Out)); // 'out' variables should never be initialized, they can only exist as function parameters.
|
||||||
|
|
||||||
|
if (IsDynamicArray() && clearExpr != nullptr)
|
||||||
|
{
|
||||||
|
clearExpr->Emit(build);
|
||||||
|
}
|
||||||
|
|
||||||
auto elementSizeConst = build->GetConstantInt(static_cast<PArray *>(ValueType)->ElementSize);
|
auto elementSizeConst = build->GetConstantInt(static_cast<PArray *>(ValueType)->ElementSize);
|
||||||
auto arrOffsetReg = build->Registers[REGT_INT].Get(1);
|
auto arrOffsetReg = build->Registers[REGT_INT].Get(1);
|
||||||
build->Emit(OP_LK, arrOffsetReg, build->GetConstantInt(StackOffset));
|
build->Emit(OP_LK, arrOffsetReg, build->GetConstantInt(StackOffset));
|
||||||
|
|
|
@ -2194,6 +2194,7 @@ class FxLocalArrayDeclaration : public FxLocalVariableDeclaration
|
||||||
{
|
{
|
||||||
PType *ElementType;
|
PType *ElementType;
|
||||||
FArgumentList values;
|
FArgumentList values;
|
||||||
|
FxExpression *clearExpr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -1288,7 +1288,13 @@ bool ZCCCompiler::CompileFields(PContainerType *type, TArray<ZCC_VarDeclarator *
|
||||||
|
|
||||||
if (field->Type->ArraySize != nullptr)
|
if (field->Type->ArraySize != nullptr)
|
||||||
{
|
{
|
||||||
fieldtype = ResolveArraySize(fieldtype, field->Type->ArraySize, type);
|
bool nosize;
|
||||||
|
fieldtype = ResolveArraySize(fieldtype, field->Type->ArraySize, type, &nosize);
|
||||||
|
|
||||||
|
if (nosize)
|
||||||
|
{
|
||||||
|
Error(field, "Must specify array size");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = field->Names;
|
auto name = field->Names;
|
||||||
|
@ -1304,7 +1310,13 @@ bool ZCCCompiler::CompileFields(PContainerType *type, TArray<ZCC_VarDeclarator *
|
||||||
auto thisfieldtype = fieldtype;
|
auto thisfieldtype = fieldtype;
|
||||||
if (name->ArraySize != nullptr)
|
if (name->ArraySize != nullptr)
|
||||||
{
|
{
|
||||||
thisfieldtype = ResolveArraySize(thisfieldtype, name->ArraySize, type);
|
bool nosize;
|
||||||
|
thisfieldtype = ResolveArraySize(thisfieldtype, name->ArraySize, type, &nosize);
|
||||||
|
|
||||||
|
if (nosize)
|
||||||
|
{
|
||||||
|
Error(field, "Must specify array size");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varflags & VARF_Native)
|
if (varflags & VARF_Native)
|
||||||
|
@ -1805,7 +1817,7 @@ PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, PSymbolTable *symt, boo
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
PType *ZCCCompiler::ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls)
|
PType *ZCCCompiler::ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls, bool *nosize)
|
||||||
{
|
{
|
||||||
TArray<ZCC_Expression *> indices;
|
TArray<ZCC_Expression *> indices;
|
||||||
|
|
||||||
|
@ -1817,6 +1829,11 @@ PType *ZCCCompiler::ResolveArraySize(PType *baseType, ZCC_Expression *arraysize,
|
||||||
node = static_cast<ZCC_Expression*>(node->SiblingNext);
|
node = static_cast<ZCC_Expression*>(node->SiblingNext);
|
||||||
} while (node != arraysize);
|
} while (node != arraysize);
|
||||||
|
|
||||||
|
if (indices.Size() == 1 && indices [0]->Operation == PEX_Nil)
|
||||||
|
{
|
||||||
|
*nosize = true;
|
||||||
|
return baseType;
|
||||||
|
}
|
||||||
|
|
||||||
FCompileContext ctx(OutNamespace, cls, false);
|
FCompileContext ctx(OutNamespace, cls, false);
|
||||||
for (auto node : indices)
|
for (auto node : indices)
|
||||||
|
@ -1839,6 +1856,8 @@ PType *ZCCCompiler::ResolveArraySize(PType *baseType, ZCC_Expression *arraysize,
|
||||||
}
|
}
|
||||||
baseType = NewArray(baseType, size);
|
baseType = NewArray(baseType, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*nosize = false;
|
||||||
return baseType;
|
return baseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3541,30 +3560,48 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
||||||
|
|
||||||
if (loc->Type->ArraySize != nullptr)
|
if (loc->Type->ArraySize != nullptr)
|
||||||
{
|
{
|
||||||
ztype = ResolveArraySize(ztype, loc->Type->ArraySize, ConvertClass);
|
bool nosize;
|
||||||
|
ztype = ResolveArraySize(ztype, loc->Type->ArraySize, ConvertClass, &nosize);
|
||||||
|
|
||||||
|
if (nosize)
|
||||||
|
{
|
||||||
|
Error(node, "Must specify array size");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
PType *type;
|
PType *type;
|
||||||
|
|
||||||
|
bool nosize = false;
|
||||||
if (node->ArraySize != nullptr)
|
if (node->ArraySize != nullptr)
|
||||||
{
|
{
|
||||||
type = ResolveArraySize(ztype, node->ArraySize, ConvertClass);
|
type = ResolveArraySize(ztype, node->ArraySize, ConvertClass, &nosize);
|
||||||
|
|
||||||
|
if (nosize && !node->InitIsArray)
|
||||||
|
{
|
||||||
|
Error(node, "Must specify array size for non-initialized arrays");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
type = ztype;
|
type = ztype;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->InitIsArray)
|
if (node->InitIsArray && (type->isArray() || type->isDynArray() || nosize))
|
||||||
{
|
{
|
||||||
if (static_cast<PArray *>(type)->ElementType->isArray ())
|
auto arrtype = static_cast<PArray *>(type);
|
||||||
|
if (!nosize && (arrtype->ElementType->isArray() || arrtype->ElementType->isDynArray()))
|
||||||
{
|
{
|
||||||
Error(node, "Compound initializer not implemented yet for multi-dimensional arrays");
|
Error(node, "Compound initializer not implemented yet for multi-dimensional arrays");
|
||||||
}
|
}
|
||||||
FArgumentList args;
|
FArgumentList args;
|
||||||
ConvertNodeList(args, node->Init);
|
ConvertNodeList(args, node->Init);
|
||||||
|
|
||||||
|
if (nosize)
|
||||||
|
{
|
||||||
|
type = NewArray(type, args.Size());
|
||||||
|
}
|
||||||
list->Add(new FxLocalArrayDeclaration(type, node->Name, args, 0, *node));
|
list->Add(new FxLocalArrayDeclaration(type, node->Name, args, 0, *node));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -114,7 +114,7 @@ private:
|
||||||
bool CompileFlagDefs(PClass *type, TArray<ZCC_FlagDef *> &FlagDefs, FName prefix);
|
bool CompileFlagDefs(PClass *type, TArray<ZCC_FlagDef *> &FlagDefs, FName prefix);
|
||||||
FString FlagsToString(uint32_t flags);
|
FString FlagsToString(uint32_t flags);
|
||||||
PType *DetermineType(PType *outertype, ZCC_TreeNode *field, FName name, ZCC_Type *ztype, bool allowarraytypes, bool formember);
|
PType *DetermineType(PType *outertype, ZCC_TreeNode *field, FName name, ZCC_Type *ztype, bool allowarraytypes, bool formember);
|
||||||
PType *ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls);
|
PType *ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls, bool *nosize);
|
||||||
PType *ResolveUserType(ZCC_BasicType *type, PSymbolTable *sym, bool nativetype);
|
PType *ResolveUserType(ZCC_BasicType *type, PSymbolTable *sym, bool nativetype);
|
||||||
|
|
||||||
void InitDefaults();
|
void InitDefaults();
|
||||||
|
|
Loading…
Reference in a new issue