mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-13 07:31:04 +00:00
Fix definition order of ZScript structs
Do a first pass over the Structs array in CompileAllFields() to reorder them such that if a struct uses other structs, those structs will be resolved first.
This commit is contained in:
parent
742ae8c907
commit
b9501a7291
4 changed files with 86 additions and 1 deletions
|
@ -334,6 +334,7 @@ void PType::StaticInit()
|
||||||
TypeVector2->moveOp = OP_MOVEV2;
|
TypeVector2->moveOp = OP_MOVEV2;
|
||||||
TypeVector2->RegType = REGT_FLOAT;
|
TypeVector2->RegType = REGT_FLOAT;
|
||||||
TypeVector2->RegCount = 2;
|
TypeVector2->RegCount = 2;
|
||||||
|
TypeVector2->isOrdered = true;
|
||||||
|
|
||||||
TypeVector3 = new PStruct(NAME_Vector3, nullptr);
|
TypeVector3 = new PStruct(NAME_Vector3, nullptr);
|
||||||
TypeVector3->AddField(NAME_X, TypeFloat64);
|
TypeVector3->AddField(NAME_X, TypeFloat64);
|
||||||
|
@ -347,6 +348,7 @@ void PType::StaticInit()
|
||||||
TypeVector3->moveOp = OP_MOVEV3;
|
TypeVector3->moveOp = OP_MOVEV3;
|
||||||
TypeVector3->RegType = REGT_FLOAT;
|
TypeVector3->RegType = REGT_FLOAT;
|
||||||
TypeVector3->RegCount = 3;
|
TypeVector3->RegCount = 3;
|
||||||
|
TypeVector3->isOrdered = true;
|
||||||
|
|
||||||
|
|
||||||
TypeFVector2 = new PStruct(NAME_FVector2, nullptr);
|
TypeFVector2 = new PStruct(NAME_FVector2, nullptr);
|
||||||
|
@ -358,6 +360,7 @@ void PType::StaticInit()
|
||||||
TypeFVector2->moveOp = OP_MOVEV2;
|
TypeFVector2->moveOp = OP_MOVEV2;
|
||||||
TypeFVector2->RegType = REGT_FLOAT;
|
TypeFVector2->RegType = REGT_FLOAT;
|
||||||
TypeFVector2->RegCount = 2;
|
TypeFVector2->RegCount = 2;
|
||||||
|
TypeFVector2->isOrdered = true;
|
||||||
|
|
||||||
TypeFVector3 = new PStruct(NAME_FVector3, nullptr);
|
TypeFVector3 = new PStruct(NAME_FVector3, nullptr);
|
||||||
TypeFVector3->AddField(NAME_X, TypeFloat32);
|
TypeFVector3->AddField(NAME_X, TypeFloat32);
|
||||||
|
@ -371,6 +374,7 @@ void PType::StaticInit()
|
||||||
TypeFVector3->moveOp = OP_MOVEV3;
|
TypeFVector3->moveOp = OP_MOVEV3;
|
||||||
TypeFVector3->RegType = REGT_FLOAT;
|
TypeFVector3->RegType = REGT_FLOAT;
|
||||||
TypeFVector3->RegCount = 3;
|
TypeFVector3->RegCount = 3;
|
||||||
|
TypeFVector3->isOrdered = true;
|
||||||
|
|
||||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_sByte, TypeSInt8));
|
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_sByte, TypeSInt8));
|
||||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Byte, TypeUInt8));
|
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_Byte, TypeUInt8));
|
||||||
|
|
|
@ -537,6 +537,7 @@ public:
|
||||||
PStruct(FName name, PTypeBase *outer, bool isnative = false);
|
PStruct(FName name, PTypeBase *outer, bool isnative = false);
|
||||||
|
|
||||||
bool isNative;
|
bool isNative;
|
||||||
|
bool isOrdered = false;
|
||||||
// Some internal structs require explicit construction and destruction of fields the VM cannot handle directly so use these two functions for it.
|
// Some internal structs require explicit construction and destruction of fields the VM cannot handle directly so use these two functions for it.
|
||||||
VMFunction *mConstructor = nullptr;
|
VMFunction *mConstructor = nullptr;
|
||||||
VMFunction *mDestructor = nullptr;
|
VMFunction *mDestructor = nullptr;
|
||||||
|
|
|
@ -1325,7 +1325,7 @@ void ZCCCompiler::CompileAllFields()
|
||||||
{
|
{
|
||||||
// Create copies of the arrays which can be altered
|
// Create copies of the arrays which can be altered
|
||||||
auto Classes = this->Classes;
|
auto Classes = this->Classes;
|
||||||
auto Structs = this->Structs;
|
auto Structs = OrderStructs();
|
||||||
TMap<FName, bool> HasNativeChildren;
|
TMap<FName, bool> HasNativeChildren;
|
||||||
|
|
||||||
// first step: Look for native classes with native children.
|
// first step: Look for native classes with native children.
|
||||||
|
@ -1612,6 +1612,83 @@ bool ZCCCompiler::CompileFields(PContainerType *type, TArray<ZCC_VarDeclarator *
|
||||||
return Fields.Size() == 0;
|
return Fields.Size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// ZCCCompiler :: OrderStructs
|
||||||
|
//
|
||||||
|
// Order the Structs array so that the least-dependant structs come first
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
TArray<ZCC_StructWork *> ZCCCompiler::OrderStructs()
|
||||||
|
{
|
||||||
|
TArray<ZCC_StructWork *> new_order;
|
||||||
|
|
||||||
|
for (auto struct_def : Structs)
|
||||||
|
{
|
||||||
|
if (std::find(new_order.begin(), new_order.end(), struct_def) != new_order.end())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AddStruct(new_order, struct_def);
|
||||||
|
}
|
||||||
|
return new_order;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// ZCCCompiler :: AddStruct
|
||||||
|
//
|
||||||
|
// Adds a struct to the Structs array, preceded by all its dependant structs
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void ZCCCompiler::AddStruct(TArray<ZCC_StructWork *> &new_order, ZCC_StructWork *my_def)
|
||||||
|
{
|
||||||
|
PStruct *my_type = static_cast<PStruct *>(my_def->Type());
|
||||||
|
if (my_type)
|
||||||
|
{
|
||||||
|
if (my_type->isOrdered)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
my_type->isOrdered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all struct fields and add them before this one
|
||||||
|
for (const auto field : my_def->Fields)
|
||||||
|
{
|
||||||
|
PType *fieldtype = DetermineType(my_type, field, field->Names->Name, field->Type, true, true);
|
||||||
|
if (fieldtype->isStruct() && !static_cast<PStruct *>(fieldtype)->isOrdered)
|
||||||
|
{
|
||||||
|
AddStruct(new_order, StructTypeToWork(static_cast<PStruct *>(fieldtype)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_order.Push(my_def);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// ZCCCompiler :: StructTypeToWork
|
||||||
|
//
|
||||||
|
// Find the ZCC_StructWork that corresponds to a PStruct
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
ZCC_StructWork *ZCCCompiler::StructTypeToWork(const PStruct *type) const
|
||||||
|
{
|
||||||
|
assert(type->isStruct());
|
||||||
|
for (auto &def : Structs)
|
||||||
|
{
|
||||||
|
if (def->Type() == type)
|
||||||
|
{
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(false && "Struct not found");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// ZCCCompiler :: FieldFlagsToString
|
// ZCCCompiler :: FieldFlagsToString
|
||||||
|
|
|
@ -135,6 +135,9 @@ protected:
|
||||||
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, bool *nosize);
|
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);
|
||||||
|
TArray<ZCC_StructWork *> OrderStructs();
|
||||||
|
void AddStruct(TArray<ZCC_StructWork *> &new_order, ZCC_StructWork *struct_def);
|
||||||
|
ZCC_StructWork *StructTypeToWork(const PStruct *type) const;
|
||||||
|
|
||||||
void CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool forclass);
|
void CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool forclass);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue