diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index e9892ea2e..66ee86f5a 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -920,6 +920,34 @@ PStruct::PStruct(FName name, DObject *outer) { } +//========================================================================== +// +// PStruct :: AddField +// +// Appends a new field to the end of a struct. +// +//========================================================================== + +PField *PStruct::AddField(FName name, PType *type) +{ + PField *field = new PField(name, type); + + // The new field is added to the end of this struct, alignment permitting. + field->FieldOffset = (Size + (type->Align - 1)) & ~(type->Align - 1); + + // Enlarge this struct to enclose the new field. + Size = field->FieldOffset + type->Size; + + // This struct's alignment is the same as the largest alignment of any of + // its fields. + Align = MAX(Align, type->Align); + + Fields.Push(field); + Symbols.AddSymbol(field); + + return field; +} + //========================================================================== // // PStruct :: PropagateMark diff --git a/src/dobjtype.h b/src/dobjtype.h index 91b5ae269..4e867c102 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -325,6 +325,8 @@ class PField : public PSymbol DECLARE_CLASS(PField, PSymbol); HAS_OBJECT_POINTERS public: + PField(FName name, PType *type) : PSymbol(name), FieldOffset(0), FieldType(type) {} + unsigned int FieldOffset; PType *FieldType; }; @@ -411,6 +413,8 @@ public: TArray Fields; PSymbolTable Symbols; + PField *AddField(FName name, PType *type); + size_t PropagateMark(); protected: PStruct();