From 479b216c06bbcd176cbeed8d8476c723b71bda8c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 12 Nov 2016 13:09:19 +0100 Subject: [PATCH] - fixed: ZScript did not properly fill in tentatively created classes from defaults processing. The proper setup for such classes was only done in CreateDerivedClass, but not in FindClassTentative itself. This extends CreateDerivedClass to allow it to create a class without fully initializing it. --- src/dobjtype.cpp | 28 ++++++++++++++++++--------- src/dobjtype.h | 11 +---------- src/scripting/zscript/zcc_compile.cpp | 25 +++++++++++++++--------- src/scripting/zscript/zcc_parser.cpp | 1 - 4 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index a7d70ca39..a6408c307 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -3120,12 +3120,19 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size) { if (existclass->Size == TentativeClass) { - type = const_cast(existclass); - if (!IsDescendantOf(type->ParentClass)) + if (!IsDescendantOf(existclass->ParentClass)) { - I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars()); + I_Error("%s must inherit from %s but doesn't.", name.GetChars(), existclass->ParentClass->TypeName.GetChars()); + } + + if (size == TentativeClass) + { + // see if we can reuse the existing class. This is only possible if the inheritance is identical. Otherwise it needs to be replaced. + if (this == existclass->ParentClass) + { + return existclass; + } } - DPrintf(DMSG_SPAMMY, "Defining placeholder class %s\n", name.GetChars()); notnew = true; } else @@ -3142,11 +3149,14 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size) // Create a new type object of the same type as us. (We may be a derived class of PClass.) type = static_cast(GetClass()->CreateNew()); - type->Size = size; Derive(type, name); - type->InitializeDefaults(); - type->Virtuals = Virtuals; - DeriveData(type); + type->Size = size; + if (size != TentativeClass) + { + type->InitializeDefaults(); + type->Virtuals = Virtuals; + DeriveData(type); + } if (!notnew) { type->InsertIntoHash(); @@ -3197,7 +3207,7 @@ PField *PClass::AddField(FName name, PType *type, DWORD flags) // //========================================================================== -PClass *PClass::FindClassTentative(FName name, bool fatal) +PClass *PClass::FindClassTentative(FName name) { if (name == NAME_None) { diff --git a/src/dobjtype.h b/src/dobjtype.h index 7746dce29..be15193a4 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -145,15 +145,6 @@ struct PSymbolTable return MapType::Iterator(Symbols); } - // add a name to help debugging. -#ifdef _DEBUG - FString name; - void SetName(const char *nm) { name = nm; } -#else - void SetName(const char *) {} -#endif - - private: PSymbolTable *ParentSymbolTable; @@ -828,7 +819,7 @@ public: static PClassActor *FindActor(const FString &name) { return FindActor(FName(name, true)); } static PClassActor *FindActor(ENamedName name) { return FindActor(FName(name)); } static PClassActor *FindActor(FName name); - PClass *FindClassTentative(FName name, bool fatal = true); // not static! + PClass *FindClassTentative(FName name); static TArray AllClasses; diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index f52e0e062..c42ef299a 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -89,10 +89,6 @@ void ZCCCompiler::ProcessClass(ZCC_Class *cnode, PSymbolTreeNode *treenode) PSymbolTreeNode *childnode; ZCC_Enum *enumType = nullptr; - FString name; - name << "nodes - " << FName(cnode->NodeName); - cls->TreeNodes.SetName(name); - // Need to check if the class actually has a body. if (node != nullptr) do { @@ -418,7 +414,6 @@ void ZCCCompiler::CreateStructTypes() s->Outer = s->OuterDef == nullptr? nullptr : s->OuterDef->Type; s->strct->Type = NewStruct(s->NodeName(), s->Outer); s->strct->Symbol = new PSymbolType(s->NodeName(), s->Type()); - s->Type()->Symbols.SetName(FName(s->NodeName())); GlobalSymbols.AddSymbol(s->strct->Symbol); for (auto e : s->Enums) @@ -486,6 +481,7 @@ void ZCCCompiler::CreateClassTypes() if (me == nullptr) { Error(c->cls, "Unknown native class %s", c->NodeName().GetChars()); + // Create a placeholder so that the compiler can continue looking for errors. me = parent->FindClassTentative(c->NodeName()); } else if (me->bRuntimeClass) @@ -523,12 +519,25 @@ void ZCCCompiler::CreateClassTypes() } // We will never get here if the name is a duplicate, so we can just do the assignment. - c->cls->Type = parent->FindClassTentative(c->NodeName()); + try + { + c->cls->Type = parent->CreateDerivedClass(c->NodeName(), TentativeClass); + if (c->Type() == nullptr) + { + Error(c->cls, "Class name %s already exists", c->NodeName().GetChars()); + } + } + catch (CRecoverableError &err) + { + Error(c->cls, "%s", err.GetMessage()); + // create a placeholder so that the compiler can continue looking for errors. + c->cls->Type = nullptr; + } } + if (c->Type() == nullptr) c->cls->Type = parent->FindClassTentative(c->NodeName()); 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->cls->Symbol = new PSymbolType(c->NodeName(), c->Type()); GlobalSymbols.AddSymbol(c->cls->Symbol); - c->Type()->Symbols.SetName(c->NodeName()); Classes.Push(c); OrigClasses.Delete(i--); donesomething = true; @@ -553,7 +562,6 @@ void ZCCCompiler::CreateClassTypes() c->cls->Type = RUNTIME_CLASS(DObject)->FindClassTentative(c->NodeName()); c->cls->Symbol = new PSymbolType(c->NodeName(), c->Type()); GlobalSymbols.AddSymbol(c->cls->Symbol); - c->Type()->Symbols.SetName(c->NodeName()); Classes.Push(c); OrigClasses.Delete(i--); donesomething = true; @@ -569,7 +577,6 @@ void ZCCCompiler::CreateClassTypes() Error(c->cls, "Class %s has circular inheritance", FName(c->NodeName()).GetChars()); c->cls->Type = RUNTIME_CLASS(DObject)->FindClassTentative(c->NodeName()); c->cls->Symbol = new PSymbolType(c->NodeName(), c->Type()); - c->Type()->Symbols.SetName(FName(c->NodeName()).GetChars()); GlobalSymbols.AddSymbol(c->cls->Symbol); Classes.Push(c); } diff --git a/src/scripting/zscript/zcc_parser.cpp b/src/scripting/zscript/zcc_parser.cpp index 098a38d82..de3d2c7e1 100644 --- a/src/scripting/zscript/zcc_parser.cpp +++ b/src/scripting/zscript/zcc_parser.cpp @@ -375,7 +375,6 @@ static void DoParse(int lumpnum) } PSymbolTable symtable; - symtable.SetName("Global_Node"); ZCCCompiler cc(state, NULL, symtable, GlobalSymbols, lumpnum); cc.Compile();