- make PClass not inherit from PStruct.

Having these two types related can cause problems with detection in the compiler because for some parts they need quite different handling.
Common handling for the fields has been moved into PSymbolTable but overall redundancy was quite minor as both types share surprisingly little functionality.
This commit is contained in:
Christoph Oelckers 2017-04-12 17:21:13 +02:00
parent 0d7b7d6ab1
commit 96631e8808
12 changed files with 221 additions and 237 deletions

View File

@ -438,17 +438,17 @@ PBasicType::PBasicType(unsigned int size, unsigned int align)
IMPLEMENT_CLASS(PCompoundType, true, false)
/* PNamedType *************************************************************/
/* PContainerType *************************************************************/
IMPLEMENT_CLASS(PNamedType, true, false)
IMPLEMENT_CLASS(PContainerType, true, false)
//==========================================================================
//
// PNamedType :: IsMatch
// PContainerType :: IsMatch
//
//==========================================================================
bool PNamedType::IsMatch(intptr_t id1, intptr_t id2) const
bool PContainerType::IsMatch(intptr_t id1, intptr_t id2) const
{
const DObject *outer = (const DObject *)id1;
FName name = (ENamedName)(intptr_t)id2;
@ -458,11 +458,11 @@ bool PNamedType::IsMatch(intptr_t id1, intptr_t id2) const
//==========================================================================
//
// PNamedType :: GetTypeIDs
// PContainerType :: GetTypeIDs
//
//==========================================================================
void PNamedType::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
void PContainerType::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
{
id1 = (intptr_t)Outer;
id2 = TypeName;
@ -2280,6 +2280,25 @@ PMap *NewMap(PType *keytype, PType *valuetype)
IMPLEMENT_CLASS(PStruct, false, false)
//==========================================================================
//
// WriteFields
//
//==========================================================================
static void WriteFields(FSerializer &ar, const void *addr, const TArray<PField *> &fields)
{
for (unsigned i = 0; i < fields.Size(); ++i)
{
const PField *field = fields[i];
// Skip fields without or with native serialization
if (!(field->Flags & (VARF_Transient | VARF_Meta)))
{
field->Type->WriteValue(ar, field->SymbolName.GetChars(), (const uint8_t *)addr + field->Offset);
}
}
}
//==========================================================================
//
// PStruct - Default Constructor
@ -2299,7 +2318,7 @@ PStruct::PStruct()
//==========================================================================
PStruct::PStruct(FName name, PTypeBase *outer, bool isnative)
: PNamedType(name, outer)
: PContainerType(name, outer)
{
mDescriptiveName.Format("%sStruct<%s>", isnative? "Native" : "", name.GetChars());
Size = 0;
@ -2365,72 +2384,13 @@ bool PStruct::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
if (ar.BeginObject(key))
{
bool ret = ReadFields(ar, addr);
bool ret = Symbols.ReadFields(ar, addr, DescriptiveName());
ar.EndObject();
return ret;
}
return false;
}
//==========================================================================
//
// PStruct :: WriteFields STATIC
//
//==========================================================================
void PStruct::WriteFields(FSerializer &ar, const void *addr, const TArray<PField *> &fields)
{
for (unsigned i = 0; i < fields.Size(); ++i)
{
const PField *field = fields[i];
// Skip fields without or with native serialization
if (!(field->Flags & (VARF_Transient|VARF_Meta)))
{
field->Type->WriteValue(ar, field->SymbolName.GetChars(), (const uint8_t *)addr + field->Offset);
}
}
}
//==========================================================================
//
// PStruct :: ReadFields
//
//==========================================================================
bool PStruct::ReadFields(FSerializer &ar, void *addr) const
{
bool readsomething = false;
bool foundsomething = false;
const char *label;
while ((label = ar.GetKey()))
{
foundsomething = true;
const PSymbol *sym = Symbols.FindSymbol(FName(label, true), true);
if (sym == nullptr)
{
DPrintf(DMSG_ERROR, "Cannot find field %s in %s\n",
label, TypeName.GetChars());
}
else if (!sym->IsKindOf(RUNTIME_CLASS(PField)))
{
DPrintf(DMSG_ERROR, "Symbol %s in %s is not a field\n",
label, TypeName.GetChars());
}
else if ((static_cast<const PField *>(sym)->Flags & (VARF_Transient | VARF_Meta)))
{
DPrintf(DMSG_ERROR, "Symbol %s in %s is not a serializable field\n",
label, TypeName.GetChars());
}
else
{
readsomething |= static_cast<const PField *>(sym)->Type->ReadValue(ar, nullptr,
(uint8_t *)addr + static_cast<const PField *>(sym)->Offset);
}
}
return readsomething || !foundsomething;
}
//==========================================================================
//
// PStruct :: AddField
@ -2442,25 +2402,8 @@ bool PStruct::ReadFields(FSerializer &ar, void *addr) const
PField *PStruct::AddField(FName name, PType *type, uint32_t flags)
{
PField *field = new PField(name, type, flags);
// The new field is added to the end of this struct, alignment permitting.
field->Offset = (Size + (type->Align - 1)) & ~(type->Align - 1);
// Enlarge this struct to enclose the new field.
Size = unsigned(field->Offset + type->Size);
// This struct's alignment is the same as the largest alignment of any of
// its fields.
Align = MAX(Align, type->Align);
if (Symbols.AddSymbol(field) == nullptr)
{ // name is already in use
field->Destroy();
return nullptr;
}
Fields.Push(field);
auto field = Symbols.AddField(name, type, flags, Size, &Align);
if (field != nullptr) Fields.Push(field);
return field;
}
@ -2699,7 +2642,7 @@ static void RecurseWriteFields(const PClass *type, FSerializer &ar, const void *
key.Format("class:%s", type->TypeName.GetChars());
if (ar.BeginObject(key.GetChars()))
{
PStruct::WriteFields(ar, addr, type->Fields);
WriteFields(ar, addr, type->Fields);
ar.EndObject();
}
break;
@ -2708,15 +2651,6 @@ static void RecurseWriteFields(const PClass *type, FSerializer &ar, const void *
}
}
void PClass::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
if (ar.BeginObject(key))
{
RecurseWriteFields(this, ar, addr);
ar.EndObject();
}
}
// Same as WriteValue, but does not create a new object in the serializer
// This is so that user variables do not contain unnecessary subblocks.
void PClass::WriteAllFields(FSerializer &ar, const void *addr) const
@ -2726,21 +2660,10 @@ void PClass::WriteAllFields(FSerializer &ar, const void *addr) const
//==========================================================================
//
// PClass :: ReadValue
// PClass :: ReadAllFields
//
//==========================================================================
bool PClass::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
if (ar.BeginObject(key))
{
bool ret = ReadAllFields(ar, addr);
ar.EndObject();
return ret;
}
return true;
}
bool PClass::ReadAllFields(FSerializer &ar, void *addr) const
{
bool readsomething = false;
@ -2778,7 +2701,7 @@ bool PClass::ReadAllFields(FSerializer &ar, void *addr) const
{
if (ar.BeginObject(nullptr))
{
readsomething |= type->ReadFields(ar, addr);
readsomething |= type->Symbols.ReadFields(ar, addr, DescriptiveName());
ar.EndObject();
}
}
@ -3358,39 +3281,6 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size)
return type;
}
//==========================================================================
//
// PStruct :: AddField
//
// Appends a new metadata field to the end of a struct. Returns either the new field
// or nullptr if a symbol by that name already exists.
//
//==========================================================================
PField *PClass::AddMetaField(FName name, PType *type, uint32_t flags)
{
PField *field = new PField(name, type, flags);
// The new field is added to the end of this struct, alignment permitting.
field->Offset = (MetaSize + (type->Align - 1)) & ~(type->Align - 1);
// Enlarge this struct to enclose the new field.
MetaSize = unsigned(field->Offset + type->Size);
// This struct's alignment is the same as the largest alignment of any of
// its fields.
Align = MAX(Align, type->Align);
if (Symbols.AddSymbol(field) == nullptr)
{ // name is already in use
field->Destroy();
return nullptr;
}
Fields.Push(field);
return field;
}
//==========================================================================
//
// PClass :: AddField
@ -3399,10 +3289,11 @@ PField *PClass::AddMetaField(FName name, PType *type, uint32_t flags)
PField *PClass::AddField(FName name, PType *type, uint32_t flags)
{
PField *field;
if (!(flags & VARF_Meta))
{
unsigned oldsize = Size;
PField *field = Super::AddField(name, type, flags);
field = Symbols.AddField(name, type, flags, Size);
// Only initialize the defaults if they have already been created.
// For ZScript this is not the case, it will first define all fields before
@ -3412,23 +3303,42 @@ PField *PClass::AddField(FName name, PType *type, uint32_t flags)
Defaults = (uint8_t *)M_Realloc(Defaults, Size);
memset(Defaults + oldsize, 0, Size - oldsize);
}
return field;
}
else
{
// Same as above, but a different data storage.
unsigned oldsize = MetaSize;
PField *field = AddMetaField(name, type, flags);
field = Symbols.AddField(name, type, flags, MetaSize);
// Only initialize the defaults if they have already been created.
// For ZScript this is not the case, it will first define all fields before
// setting up any defaults for any class.
if (field != nullptr && !(flags & VARF_Native) && Meta != nullptr)
{
Meta = (uint8_t *)M_Realloc(Meta, MetaSize);
memset(Meta + oldsize, 0, MetaSize - oldsize);
}
}
if (field != nullptr) Fields.Push(field);
return field;
}
//==========================================================================
//
// PClass :: AddNativeField
//
// This looks the same as the struct version but that will change later.
//
//==========================================================================
PField *PClass::AddNativeField(FName name, PType *type, size_t address, uint32_t flags, int bitvalue)
{
PField *field = new PField(name, type, flags | VARF_Native | VARF_Transient, address, bitvalue);
if (Symbols.AddSymbol(field) == nullptr)
{ // name is already in use
field->Destroy();
return nullptr;
}
Fields.Push(field);
return field;
}
//==========================================================================

View File

@ -216,22 +216,24 @@ class PCompoundType : public PType
DECLARE_ABSTRACT_CLASS(PCompoundType, PType);
};
class PNamedType : public PCompoundType
class PContainerType : public PCompoundType
{
DECLARE_ABSTRACT_CLASS(PNamedType, PCompoundType);
DECLARE_ABSTRACT_CLASS(PContainerType, PCompoundType);
public:
PTypeBase *Outer; // object this type is contained within
FName TypeName; // this type's name
PNamedType() : Outer(NULL) {
PContainerType() : Outer(NULL) {
mDescriptiveName = "NamedType";
}
PNamedType(FName name, PTypeBase *outer) : Outer(outer), TypeName(name) {
PContainerType(FName name, PTypeBase *outer) : Outer(outer), TypeName(name) {
mDescriptiveName = name.GetChars();
}
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
virtual PField *AddField(FName name, PType *type, uint32_t flags = 0) = 0;
virtual PField *AddNativeField(FName name, PType *type, size_t address, uint32_t flags = 0, int bitvalue = 0) = 0;
};
// Basic types --------------------------------------------------------------
@ -537,9 +539,9 @@ protected:
PMap();
};
class PStruct : public PNamedType
class PStruct : public PContainerType
{
DECLARE_CLASS(PStruct, PNamedType);
DECLARE_CLASS(PStruct, PContainerType);
public:
PStruct(FName name, PTypeBase *outer, bool isnative = false);
@ -558,8 +560,6 @@ public:
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *specials) override;
static void WriteFields(FSerializer &ar, const void *addr, const TArray<PField *> &fields);
bool ReadFields(FSerializer &ar, void *addr) const;
protected:
PStruct();
};
@ -588,20 +588,17 @@ enum
TentativeClass = UINT_MAX,
};
class PClass : public PStruct
class PClass : public PContainerType
{
DECLARE_CLASS(PClass, PStruct);
DECLARE_CLASS(PClass, PContainerType);
// We unravel _WITH_META here just as we did for PType.
protected:
TArray<FTypeAndOffset> MetaInits;
void Derive(PClass *newclass, FName name);
void InitializeSpecials(void *addr, void *defaults, TArray<FTypeAndOffset> PClass::*Inits);
void SetSuper();
PField *AddMetaField(FName name, PType *type, uint32_t flags);
public:
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
void WriteAllFields(FSerializer &ar, const void *addr) const;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
bool ReadAllFields(FSerializer &ar, void *addr) const;
void InitializeDefaults();
int FindVirtualIndex(FName name, PPrototype *proto);
@ -625,6 +622,7 @@ public:
bool bDecorateClass; // may be subject to some idiosyncracies due to DECORATE backwards compatibility
TArray<VMFunction*> Virtuals; // virtual function table
FName SourceLumpName;
TArray<PField *> Fields;
void (*ConstructNative)(void *);
@ -635,6 +633,8 @@ public:
DObject *CreateNew();
PClass *CreateDerivedClass(FName name, unsigned int size);
PField *AddField(FName name, PType *type, uint32_t flags=0) override;
PField *AddNativeField(FName name, PType *type, size_t address, uint32_t flags = 0, int bitvalue = 0) override;
void InitializeActorInfo();
void BuildFlatPointers();
void BuildArrayPointers();

View File

@ -114,7 +114,7 @@ FCompileContext::FCompileContext(PNamespace *cg, PFunction *fnc, PPrototype *ret
if (fnc != nullptr) Class = fnc->OwningClass;
}
FCompileContext::FCompileContext(PNamespace *cg, PStruct *cls, bool fromdecorate)
FCompileContext::FCompileContext(PNamespace *cg, PContainerType *cls, bool fromdecorate)
: ReturnProto(nullptr), Function(nullptr), Class(cls), FromDecorate(fromdecorate), StateIndex(-1), StateCount(0), Lump(-1), CurGlobals(cg)
{
}
@ -200,14 +200,14 @@ FxLocalVariableDeclaration *FCompileContext::FindLocalVariable(FName name)
}
}
static PStruct *FindStructType(FName name, FCompileContext &ctx)
static PContainerType *FindContainerType(FName name, FCompileContext &ctx)
{
auto sym = ctx.Class->Symbols.FindSymbol(name, true);
if (sym == nullptr) sym = ctx.CurGlobals->Symbols.FindSymbol(name, true);
if (sym && sym->IsKindOf(RUNTIME_CLASS(PSymbolType)))
{
auto type = static_cast<PSymbolType*>(sym);
return dyn_cast<PStruct>(type->Type);
return dyn_cast<PContainerType>(type->Type);
}
return nullptr;
}
@ -224,7 +224,7 @@ static PClass *FindClassType(FName name, FCompileContext &ctx)
return nullptr;
}
bool isActor(PStruct *type)
bool isActor(PContainerType *type)
{
auto cls = dyn_cast<PClass>(type);
return cls ? cls->IsDescendantOf(RUNTIME_CLASS(AActor)) : false;
@ -6121,7 +6121,7 @@ foundit:
//
//==========================================================================
FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PStruct *classctx, FxExpression *&object, PStruct *objtype)
FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PContainerType *classctx, FxExpression *&object, PContainerType *objtype)
{
PSymbol *sym;
PSymbolTable *symtbl;
@ -6269,7 +6269,7 @@ FxMemberIdentifier::~FxMemberIdentifier()
FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx)
{
PStruct *ccls = nullptr;
PContainerType *ccls = nullptr;
CHECKRESOLVED();
if (Object->ExprType == EFX_Identifier)
@ -6277,7 +6277,7 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx)
auto id = static_cast<FxIdentifier *>(Object)->Identifier;
// If the left side is a class name for a static member function call it needs to be resolved manually
// because the resulting value type would cause problems in nearly every other place where identifiers are being used.
ccls = FindStructType(id, ctx);
ccls = FindContainerType(id, ctx);
if (ccls != nullptr)
{
static_cast<FxIdentifier *>(Object)->noglobal = true;
@ -6398,9 +6398,9 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx)
if (Object->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)))
{
auto ptype = static_cast<PPointer *>(Object->ValueType)->PointedType;
if (ptype->IsKindOf(RUNTIME_CLASS(PStruct)))
if (ptype->IsKindOf(RUNTIME_CLASS(PContainerType)))
{
auto ret = ResolveMember(ctx, ctx.Class, Object, static_cast<PStruct *>(ptype));
auto ret = ResolveMember(ctx, ctx.Class, Object, static_cast<PContainerType *>(ptype));
delete this;
return ret;
}
@ -7023,7 +7023,7 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
if (classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)))
{
PPointer *ptrtype = dyn_cast<PPointer>(classx->ValueType);
if (ptrtype == nullptr || !ptrtype->PointedType->IsKindOf(RUNTIME_CLASS(PStruct)))
if (ptrtype == nullptr || !ptrtype->PointedType->IsKindOf(RUNTIME_CLASS(PContainerType)))
{
ScriptPosition.Message(MSG_ERROR, "Member variable requires a struct or class object");
delete this;
@ -7925,12 +7925,12 @@ FxMemberFunctionCall::~FxMemberFunctionCall()
FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
{
PStruct *cls;
PContainerType *cls = nullptr;
bool staticonly = false;
bool novirtual = false;
bool isreadonly = false;
PStruct *ccls = nullptr;
PContainerType *ccls = nullptr;
if (ctx.Class == nullptr)
{
@ -7957,7 +7957,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
// because the resulting value type would cause problems in nearly every other place where identifiers are being used.
// [ZZ] substitute ccls for String internal type.
if (id == NAME_String) ccls = TypeStringStruct;
else ccls = FindStructType(id, ctx);
else ccls = FindContainerType(id, ctx);
if (ccls != nullptr) static_cast<FxIdentifier *>(Self)->noglobal = true;
}
@ -8228,7 +8228,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
if (Self->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && !Self->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
{
auto ptype = static_cast<PPointer *>(Self->ValueType)->PointedType;
if (ptype->IsKindOf(RUNTIME_CLASS(PStruct)))
if (ptype->IsKindOf(RUNTIME_CLASS(PContainerType)))
{
if (ptype->IsKindOf(RUNTIME_CLASS(PClass)) && MethodName == NAME_GetClass)
{
@ -8243,7 +8243,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
}
cls = static_cast<PStruct *>(ptype);
cls = static_cast<PContainerType *>(ptype);
}
else
{
@ -8825,9 +8825,9 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
ArgList[i] = ArgList[i]->Resolve(ctx); // nust be resolved before the address is requested.
if (ArgList[i] != nullptr && ArgList[i]->ValueType != TypeNullPtr)
{
if (type == ArgList[i]->ValueType && type->IsA(RUNTIME_CLASS(PPointer)) && static_cast<PPointer*>(type)->IsA(RUNTIME_CLASS(PStruct)))
if (type == ArgList[i]->ValueType && type->IsA(RUNTIME_CLASS(PPointer)) && static_cast<PPointer*>(type)->PointedType->IsA(RUNTIME_CLASS(PStruct)))
{
// trying to pass a struct reference as a struct refg
// trying to pass a struct reference as a struct reference. This must preserve the type.
}
else
{

View File

@ -78,7 +78,7 @@ struct FCompileContext
FxCompoundStatement *Block = nullptr;
PPrototype *ReturnProto;
PFunction *Function; // The function that is currently being compiled (or nullptr for constant evaluation.)
PStruct *Class; // The type of the owning class.
PContainerType *Class; // The type of the owning class.
bool FromDecorate; // DECORATE must silence some warnings and demote some errors.
int StateIndex; // index in actor's state table for anonymous functions, otherwise -1 (not used by DECORATE which pre-resolves state indices)
int StateCount; // amount of states an anoymous function is being used on (must be 1 for state indices to be allowed.)
@ -90,7 +90,7 @@ struct FCompileContext
FString VersionString;
FCompileContext(PNamespace *spc, PFunction *func, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump, const VersionInfo &ver);
FCompileContext(PNamespace *spc, PStruct *cls, bool fromdecorate); // only to be used to resolve constants!
FCompileContext(PNamespace *spc, PContainerType *cls, bool fromdecorate); // only to be used to resolve constants!
PSymbol *FindInClass(FName identifier, PSymbolTable *&symt);
PSymbol *FindInSelfClass(FName identifier, PSymbolTable *&symt);
@ -373,7 +373,7 @@ public:
FxIdentifier(FName i, const FScriptPosition &p);
FxExpression *Resolve(FCompileContext&);
FxExpression *ResolveMember(FCompileContext&, PStruct*, FxExpression*&, PStruct*);
FxExpression *ResolveMember(FCompileContext&, PContainerType*, FxExpression*&, PContainerType*);
};

View File

@ -36,6 +36,8 @@
#include <float.h>
#include "dobject.h"
#include "i_system.h"
#include "templates.h"
#include "serializer.h"
// PUBLIC DATA DEFINITIONS -------------------------------------------------
@ -102,7 +104,7 @@ unsigned PFunction::AddVariant(PPrototype *proto, TArray<uint32_t> &argflags, TA
assert(proto->ArgumentTypes.Size() > 0);
auto selftypeptr = dyn_cast<PPointer>(proto->ArgumentTypes[0]);
assert(selftypeptr != nullptr);
variant.SelfClass = dyn_cast<PStruct>(selftypeptr->PointedType);
variant.SelfClass = dyn_cast<PContainerType>(selftypeptr->PointedType);
assert(variant.SelfClass != nullptr);
}
else
@ -238,6 +240,78 @@ PSymbol *PSymbolTable::AddSymbol (PSymbol *sym)
//
//==========================================================================
PField *PSymbolTable::AddField(FName name, PType *type, uint32_t flags, unsigned &Size, unsigned *Align)
{
PField *field = new PField(name, type, flags);
// The new field is added to the end of this struct, alignment permitting.
field->Offset = (Size + (type->Align - 1)) & ~(type->Align - 1);
// Enlarge this struct to enclose the new field.
Size = unsigned(field->Offset + type->Size);
// This struct's alignment is the same as the largest alignment of any of
// its fields.
if (Align != nullptr)
{
*Align = MAX(*Align, type->Align);
}
if (AddSymbol(field) == nullptr)
{ // name is already in use
field->Destroy();
return nullptr;
}
return field;
}
//==========================================================================
//
// PClass :: ReadFields
//
// This will need some changes later.
//==========================================================================
bool PSymbolTable::ReadFields(FSerializer &ar, void *addr, const char *TypeName) const
{
bool readsomething = false;
bool foundsomething = false;
const char *label;
while ((label = ar.GetKey()))
{
foundsomething = true;
const PSymbol *sym = FindSymbol(FName(label, true), false);
if (sym == nullptr)
{
DPrintf(DMSG_ERROR, "Cannot find field %s in %s\n",
label, TypeName);
}
else if (!sym->IsKindOf(RUNTIME_CLASS(PField)))
{
DPrintf(DMSG_ERROR, "Symbol %s in %s is not a field\n",
label, TypeName);
}
else if ((static_cast<const PField *>(sym)->Flags & (VARF_Transient | VARF_Meta)))
{
DPrintf(DMSG_ERROR, "Symbol %s in %s is not a serializable field\n",
label, TypeName);
}
else
{
readsomething |= static_cast<const PField *>(sym)->Type->ReadValue(ar, nullptr,
(uint8_t *)addr + static_cast<const PField *>(sym)->Offset);
}
}
return readsomething || !foundsomething;
}
//==========================================================================
//
//
//
//==========================================================================
void PSymbolTable::RemoveSymbol(PSymbol *sym)
{
auto mysym = Symbols.CheckKey(sym->SymbolName);
@ -387,7 +461,7 @@ void RemoveUnusedSymbols()
{
for (PType *ty = TypeTable.TypeHash[i]; ty != nullptr; ty = ty->HashNext)
{
if (ty->IsKindOf(RUNTIME_CLASS(PStruct)))
if (ty->IsKindOf(RUNTIME_CLASS(PContainerType)))
{
auto it = ty->Symbols.GetIterator();
PSymbolTable::MapType::Pair *pair;

View File

@ -10,7 +10,7 @@ class VMFunction;
class PType;
class PPrototype;
struct ZCC_TreeNode;
class PStruct;
class PContainerType;
// Symbol information -------------------------------------------------------
@ -175,15 +175,15 @@ public:
TArray<FName> ArgNames; // we need the names to access them later when the function gets compiled.
uint32_t Flags;
int UseFlags;
PStruct *SelfClass;
PContainerType *SelfClass;
};
TArray<Variant> Variants;
PStruct *OwningClass = nullptr;
PContainerType *OwningClass = nullptr;
unsigned AddVariant(PPrototype *proto, TArray<uint32_t> &argflags, TArray<FName> &argnames, VMFunction *impl, int flags, int useflags);
int GetImplicitArgs();
PFunction(PStruct *owner = nullptr, FName name = NAME_None) : PSymbol(name), OwningClass(owner) {}
PFunction(PContainerType *owner = nullptr, FName name = NAME_None) : PSymbol(name), OwningClass(owner) {}
};
// A symbol table -----------------------------------------------------------
@ -215,6 +215,8 @@ struct PSymbolTable
// a symbol with the same name is already in the table. This symbol is
// not copied and will be freed when the symbol table is destroyed.
PSymbol *AddSymbol (PSymbol *sym);
PField *AddField(FName name, PType *type, uint32_t flags, unsigned &Size, unsigned *Align = nullptr);
bool ReadFields(FSerializer &ar, void *addr, const char *TypeName) const;
// Similar to AddSymbol but always succeeds. Returns the symbol that used
// to be in the table with this name, if any.

View File

@ -101,7 +101,7 @@ FScriptPosition & GetStateSource(FState *state)
//
//==========================================================================
void SetImplicitArgs(TArray<PType *> *args, TArray<uint32_t> *argflags, TArray<FName> *argnames, PStruct *cls, uint32_t funcflags, int useflags)
void SetImplicitArgs(TArray<PType *> *args, TArray<uint32_t> *argflags, TArray<FName> *argnames, PContainerType *cls, uint32_t funcflags, int useflags)
{
// Must be called before adding any other arguments.
assert(args == nullptr || args->Size() == 0);
@ -154,7 +154,7 @@ void SetImplicitArgs(TArray<PType *> *args, TArray<uint32_t> *argflags, TArray<F
//
//==========================================================================
PFunction *CreateAnonymousFunction(PClass *containingclass, PType *returntype, int flags)
PFunction *CreateAnonymousFunction(PContainerType *containingclass, PType *returntype, int flags)
{
TArray<PType *> rets(1);
TArray<PType *> args;
@ -184,7 +184,7 @@ PFunction *CreateAnonymousFunction(PClass *containingclass, PType *returntype, i
//
//==========================================================================
PFunction *FindClassMemberFunction(PStruct *selfcls, PStruct *funccls, FName name, FScriptPosition &sc, bool *error)
PFunction *FindClassMemberFunction(PContainerType *selfcls, PContainerType *funccls, FName name, FScriptPosition &sc, bool *error)
{
// Skip ACS_NamedExecuteWithResult. Anything calling this should use the builtin instead.
if (name == NAME_ACS_NamedExecuteWithResult) return nullptr;

View File

@ -148,8 +148,8 @@ inline void ResetBaggage (Baggage *bag, PClassActor *stateclass)
//
//==========================================================================
AFuncDesc *FindFunction(PStruct *cls, const char * string);
FieldDesc *FindField(PStruct *cls, const char * string);
AFuncDesc *FindFunction(PContainerType *cls, const char * string);
FieldDesc *FindField(PContainerType *cls, const char * string);
FxExpression *ParseExpression(FScanner &sc, PClassActor *cls, PNamespace *resolvenspc = nullptr);
@ -159,9 +159,9 @@ void ParseFunctionParameters(FScanner &sc, PClassActor *cls, TArray<FxExpression
FxExpression *ParseActions(FScanner &sc, FState state, FString statestring, Baggage &bag, bool &endswithret);
class FxVMFunctionCall *ParseAction(FScanner &sc, FState state, FString statestring, Baggage &bag);
FName CheckCastKludges(FName in);
void SetImplicitArgs(TArray<PType *> *args, TArray<uint32_t> *argflags, TArray<FName> *argnames, PStruct *cls, uint32_t funcflags, int useflags);
PFunction *CreateAnonymousFunction(PClass *containingclass, PType *returntype, int flags);
PFunction *FindClassMemberFunction(PStruct *cls, PStruct *funccls, FName name, FScriptPosition &sc, bool *error);
void SetImplicitArgs(TArray<PType *> *args, TArray<uint32_t> *argflags, TArray<FName> *argnames, PContainerType *cls, uint32_t funcflags, int useflags);
PFunction *CreateAnonymousFunction(PContainerType *containingclass, PType *returntype, int flags);
PFunction *FindClassMemberFunction(PContainerType *cls, PContainerType *funccls, FName name, FScriptPosition &sc, bool *error);
void CreateDamageFunction(PNamespace *ns, const VersionInfo &ver, PClassActor *info, AActor *defaults, FxExpression *id, bool fromDecorate, int lumpnum);
//==========================================================================

View File

@ -667,7 +667,7 @@ static int CompareClassNames(const Desc& a, const Desc& b)
//
//==========================================================================
AFuncDesc *FindFunction(PStruct *cls, const char * string)
AFuncDesc *FindFunction(PContainerType *cls, const char * string)
{
int min = 0, max = AFTable.Size() - 1;
@ -698,7 +698,7 @@ AFuncDesc *FindFunction(PStruct *cls, const char * string)
//
//==========================================================================
FieldDesc *FindField(PStruct *cls, const char * string)
FieldDesc *FindField(PContainerType *cls, const char * string)
{
int min = 0, max = FieldTable.Size() - 1;
const char * cname = cls ? cls->TypeName.GetChars() : "";

View File

@ -75,7 +75,7 @@ const char * ZCCCompiler::GetStringConst(FxExpression *ex, FCompileContext &ctx)
return AST.Strings.Alloc(static_cast<FxConstant*>(ex)->GetValue().GetString())->GetChars();
}
int ZCCCompiler::IntConstFromNode(ZCC_TreeNode *node, PStruct *cls)
int ZCCCompiler::IntConstFromNode(ZCC_TreeNode *node, PContainerType *cls)
{
FCompileContext ctx(OutNamespace, cls, false);
FxExpression *ex = new FxIntCast(ConvertNode(node), false);
@ -89,7 +89,7 @@ int ZCCCompiler::IntConstFromNode(ZCC_TreeNode *node, PStruct *cls)
return static_cast<FxConstant*>(ex)->GetValue().GetInt();
}
FString ZCCCompiler::StringConstFromNode(ZCC_TreeNode *node, PStruct *cls)
FString ZCCCompiler::StringConstFromNode(ZCC_TreeNode *node, PContainerType *cls)
{
FCompileContext ctx(OutNamespace, cls, false);
FxExpression *ex = new FxStringCast(ConvertNode(node));
@ -641,7 +641,7 @@ void ZCCCompiler::CreateClassTypes()
{
Error(c->cls, "Class name %s already exists", c->NodeName().GetChars());
}
else DPrintf(DMSG_SPAMMY, "Created class %s with parent %s\n", c->Type()->TypeName.GetChars(), c->Type()->ParentClass->TypeName.GetChars());
else DPrintf(DMSG_SPAMMY, "Created class %s with parent %s\n", c->Type()->TypeName.GetChars(), c->ClassType()->ParentClass->TypeName.GetChars());
}
catch (CRecoverableError &err)
{
@ -689,7 +689,7 @@ void ZCCCompiler::CreateClassTypes()
c->Type()->ObjectFlags = FScopeBarrier::ChangeSideInObjectFlags(c->Type()->ObjectFlags, FScopeBarrier::Side_Play);
}
c->Type()->bExported = true; // this class is accessible to script side type casts. (The reason for this flag is that types like PInt need to be skipped.)
c->ClassType()->bExported = true; // this class is accessible to script side type casts. (The reason for this flag is that types like PInt need to be skipped.)
c->cls->Symbol = new PSymbolType(c->NodeName(), c->Type());
OutNamespace->Symbols.AddSymbol(c->cls->Symbol);
Classes.Push(c);
@ -746,7 +746,7 @@ void ZCCCompiler::CreateClassTypes()
// Link the tree node tables. We only can do this after we know the class relations.
for (auto cc : Classes)
{
if (cc->Type() == cd->Type()->ParentClass)
if (cc->ClassType() == cd->ClassType()->ParentClass)
{
cd->TreeNodes.SetParentTable(&cc->TreeNodes);
break;
@ -769,7 +769,7 @@ void ZCCCompiler::CreateClassTypes()
//
//==========================================================================
void ZCCCompiler::CopyConstants(TArray<ZCC_ConstantWork> &dest, TArray<ZCC_ConstantDef*> &Constants, PStruct *cls, PSymbolTable *ot)
void ZCCCompiler::CopyConstants(TArray<ZCC_ConstantWork> &dest, TArray<ZCC_ConstantDef*> &Constants, PContainerType *cls, PSymbolTable *ot)
{
for (auto c : Constants)
{
@ -1155,7 +1155,7 @@ void ZCCCompiler::CompileAllFields()
}
for (unsigned i = 0; i < Classes.Size(); i++)
{
auto type = Classes[i]->Type();
auto type = Classes[i]->ClassType();
if (type->Size == TentativeClass)
{
@ -1167,7 +1167,7 @@ void ZCCCompiler::CompileAllFields()
else
{
// Inherit the size of the parent class
type->Size = Classes[i]->Type()->ParentClass->Size;
type->Size = Classes[i]->ClassType()->ParentClass->Size;
}
}
if (type->TypeName == NAME_Actor)
@ -1175,8 +1175,8 @@ void ZCCCompiler::CompileAllFields()
assert(type->MetaSize == 0);
AddActorInfo(type); // AActor needs the actor info manually added to its meta data before adding any scripted fields.
}
else if (Classes[i]->Type()->ParentClass)
type->MetaSize = Classes[i]->Type()->ParentClass->MetaSize;
else if (Classes[i]->ClassType()->ParentClass)
type->MetaSize = Classes[i]->ClassType()->ParentClass->MetaSize;
else
type->MetaSize = 0;
@ -1207,7 +1207,7 @@ void ZCCCompiler::CompileAllFields()
//
//==========================================================================
bool ZCCCompiler::CompileFields(PStruct *type, TArray<ZCC_VarDeclarator *> &Fields, PClass *Outer, PSymbolTable *TreeNodes, bool forstruct, bool hasnativechildren)
bool ZCCCompiler::CompileFields(PContainerType *type, TArray<ZCC_VarDeclarator *> &Fields, PClass *Outer, PSymbolTable *TreeNodes, bool forstruct, bool hasnativechildren)
{
while (Fields.Size() > 0)
{
@ -1372,7 +1372,7 @@ void ZCCCompiler::CompileAllProperties()
for (auto c : Classes)
{
if (c->Properties.Size() > 0)
CompileProperties(c->Type(), c->Properties, c->Type()->TypeName);
CompileProperties(c->ClassType(), c->Properties, c->Type()->TypeName);
}
}
@ -1727,7 +1727,7 @@ PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, PSymbolTable *symt, boo
//
//==========================================================================
PType *ZCCCompiler::ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PStruct *cls)
PType *ZCCCompiler::ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls)
{
TArray<ZCC_Expression *> indices;
@ -2189,28 +2189,26 @@ void ZCCCompiler::InitDefaults()
for (auto c : Classes)
{
// This may be removed if the conditions change, but right now only subclasses of Actor can define a Default block.
if (!c->Type()->IsDescendantOf(RUNTIME_CLASS(AActor)))
if (!c->ClassType()->IsDescendantOf(RUNTIME_CLASS(AActor)))
{
if (c->Defaults.Size()) Error(c->cls, "%s: Non-actor classes may not have defaults", c->Type()->TypeName.GetChars());
if (c->Type()->ParentClass)
if (c->ClassType()->ParentClass)
{
auto ti = static_cast<PClassActor *>(c->Type());
FString mename = ti->TypeName.GetChars();
auto ti = static_cast<PClassActor *>(c->ClassType());
ti->InitializeDefaults();
}
}
else
{
// This should never happen.
if (c->Type()->Defaults != nullptr)
if (c->ClassType()->Defaults != nullptr)
{
Error(c->cls, "%s already has defaults", c->Type()->TypeName.GetChars());
}
// This can only occur if a native parent is not initialized. In all other cases the sorting of the class list should prevent this from ever happening.
else if (c->Type()->ParentClass->Defaults == nullptr && c->Type() != RUNTIME_CLASS(AActor))
else if (c->ClassType()->ParentClass->Defaults == nullptr && c->ClassType() != RUNTIME_CLASS(AActor))
{
Error(c->cls, "Parent class %s of %s is not initialized", c->Type()->ParentClass->TypeName.GetChars(), c->Type()->TypeName.GetChars());
Error(c->cls, "Parent class %s of %s is not initialized", c->ClassType()->ParentClass->TypeName.GetChars(), c->ClassType()->TypeName.GetChars());
}
else
{
@ -2295,7 +2293,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
do
{
auto type = DetermineType(c->Type(), f, f->Name, t, false, false);
if (type->IsKindOf(RUNTIME_CLASS(PStruct)) && type != TypeVector2 && type != TypeVector3)
if (type->IsKindOf(RUNTIME_CLASS(PContainerType)) && type != TypeVector2 && type != TypeVector3)
{
// structs and classes only get passed by pointer.
type = NewPointer(type);
@ -2749,9 +2747,9 @@ void ZCCCompiler::InitFunctions()
for (auto c : Classes)
{
// cannot be done earlier because it requires the parent class to be processed by this code, too.
if (c->Type()->ParentClass != nullptr)
if (c->ClassType()->ParentClass != nullptr)
{
c->Type()->Virtuals = c->Type()->ParentClass->Virtuals;
c->ClassType()->Virtuals = c->ClassType()->ParentClass->Virtuals;
}
for (auto f : c->Functions)
{
@ -2847,7 +2845,7 @@ void ZCCCompiler::CompileStates()
for (auto c : Classes)
{
if (!c->Type()->IsDescendantOf(RUNTIME_CLASS(AActor)))
if (!c->ClassType()->IsDescendantOf(RUNTIME_CLASS(AActor)))
{
if (c->States.Size()) Error(c->cls, "%s: States can only be defined for actors.", c->Type()->TypeName.GetChars());
continue;
@ -2855,7 +2853,7 @@ void ZCCCompiler::CompileStates()
FString statename; // The state builder wants the label as one complete string, not separated into tokens.
FStateDefinitions statedef;
statedef.MakeStateDefines(ValidateActor(c->Type()->ParentClass));
statedef.MakeStateDefines(ValidateActor(c->ClassType()->ParentClass));
int numframes = 0;
for (auto s : c->States)
@ -3050,7 +3048,7 @@ void ZCCCompiler::CompileStates()
}
try
{
GetDefaultByType(c->Type())->Finalize(statedef);
GetDefaultByType(c->ClassType())->Finalize(statedef);
}
catch (CRecoverableError &err)
{
@ -3065,7 +3063,7 @@ void ZCCCompiler::CompileStates()
//
//==========================================================================
FxExpression *ZCCCompiler::ConvertAST(PStruct *cls, ZCC_TreeNode *ast)
FxExpression *ZCCCompiler::ConvertAST(PContainerType *cls, ZCC_TreeNode *ast)
{
ConvertClass = cls;
// 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.

View File

@ -41,7 +41,7 @@ struct ZCC_StructWork
return strct->NodeName;
}
PStruct *Type()
PContainerType *Type()
{
return strct->Type;
}
@ -64,7 +64,7 @@ struct ZCC_ClassWork : public ZCC_StructWork
Outer = nullptr;
}
PClass *Type()
PClass *ClassType()
{
return static_cast<PClass *>(strct->Type);
}
@ -79,7 +79,7 @@ struct ZCC_PropertyWork
struct ZCC_ConstantWork
{
ZCC_ConstantDef *node;
PStruct *cls;
PContainerType *cls;
PSymbolTable *Outputtable;
ExpVal constval;
};
@ -94,25 +94,25 @@ public:
private:
const char * GetStringConst(FxExpression *ex, FCompileContext &ctx);
int IntConstFromNode(ZCC_TreeNode *node, PStruct *cls);
FString StringConstFromNode(ZCC_TreeNode *node, PStruct *cls);
int IntConstFromNode(ZCC_TreeNode *node, PContainerType *cls);
FString StringConstFromNode(ZCC_TreeNode *node, PContainerType *cls);
void ProcessClass(ZCC_Class *node, PSymbolTreeNode *tnode);
void ProcessStruct(ZCC_Struct *node, PSymbolTreeNode *tnode, ZCC_Class *outer);
void CreateStructTypes();
void CreateClassTypes();
void CopyConstants(TArray<ZCC_ConstantWork> &dest, TArray<ZCC_ConstantDef*> &Constants, PStruct *cls, PSymbolTable *ot);
void CopyConstants(TArray<ZCC_ConstantWork> &dest, TArray<ZCC_ConstantDef*> &Constants, PContainerType *cls, PSymbolTable *ot);
void CompileAllConstants();
void AddConstant(ZCC_ConstantWork &constant);
bool CompileConstant(ZCC_ConstantWork *def);
void CompileArrays(ZCC_StructWork *work);
void CompileAllFields();
bool CompileFields(PStruct *type, TArray<ZCC_VarDeclarator *> &Fields, PClass *Outer, PSymbolTable *TreeNodes, bool forstruct, bool hasnativechildren = false);
bool CompileFields(PContainerType *type, TArray<ZCC_VarDeclarator *> &Fields, PClass *Outer, PSymbolTable *TreeNodes, bool forstruct, bool hasnativechildren = false);
void CompileAllProperties();
bool CompileProperties(PClass *type, TArray<ZCC_Property *> &Properties, FName prefix);
FString FlagsToString(uint32_t flags);
PType *DetermineType(PType *outertype, ZCC_TreeNode *field, FName name, ZCC_Type *ztype, bool allowarraytypes, bool formember);
PType *ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PStruct *cls);
PType *ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls);
PType *ResolveUserType(ZCC_BasicType *type, PSymbolTable *sym, bool nativetype);
void InitDefaults();
@ -143,12 +143,12 @@ private:
void Error(ZCC_TreeNode *node, const char *msg, ...) GCCPRINTF(3,4);
void MessageV(ZCC_TreeNode *node, const char *txtcolor, const char *msg, va_list argptr);
FxExpression *ConvertAST(PStruct *cclass, ZCC_TreeNode *ast);
FxExpression *ConvertAST(PContainerType *cclass, ZCC_TreeNode *ast);
FxExpression *ConvertNode(ZCC_TreeNode *node);
FArgumentList &ConvertNodeList(FArgumentList &, ZCC_TreeNode *head);
DObject *Outer;
PStruct *ConvertClass; // class type to be used when resoving symbols while converting an AST
PContainerType *ConvertClass; // class type to be used when resoving symbols while converting an AST
PSymbolTable *GlobalTreeNodes;
PNamespace *OutNamespace;
ZCC_AST &AST;

View File

@ -195,7 +195,7 @@ struct ZCC_Struct : ZCC_NamedNode
{
VM_UWORD Flags;
ZCC_TreeNode *Body;
PStruct *Type;
PContainerType *Type;
VersionInfo Version;
};