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();