From 2e5bc3e962e554ad233b0eea6fa60ff74d1d9250 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 11 Apr 2020 19:38:59 +0200 Subject: [PATCH] - moved compiler frontend to 'common'. --- src/CMakeLists.txt | 18 +- src/common/scripting/core/imports.cpp | 230 ++++++++++++++++++ src/common/scripting/core/symbols.h | 6 + .../scripting/frontend}/ast.cpp | 0 .../scripting/frontend}/zcc-parse.lemon | 0 .../scripting/frontend}/zcc_compile.cpp | 3 - .../scripting/frontend}/zcc_compile.h | 12 +- .../scripting/frontend}/zcc_exprlist.h | 0 .../scripting/frontend}/zcc_parser.cpp | 0 .../scripting/frontend}/zcc_parser.h | 0 src/scripting/thingdef_data.cpp | 149 +----------- 11 files changed, 250 insertions(+), 168 deletions(-) create mode 100644 src/common/scripting/core/imports.cpp rename src/{scripting/zscript => common/scripting/frontend}/ast.cpp (100%) rename src/{scripting/zscript => common/scripting/frontend}/zcc-parse.lemon (100%) rename src/{scripting/zscript => common/scripting/frontend}/zcc_compile.cpp (99%) rename src/{scripting/zscript => common/scripting/frontend}/zcc_compile.h (88%) rename src/{scripting/zscript => common/scripting/frontend}/zcc_exprlist.h (100%) rename src/{scripting/zscript => common/scripting/frontend}/zcc_parser.cpp (100%) rename src/{scripting/zscript => common/scripting/frontend}/zcc_parser.h (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c06ae3eed5..e6e523d23c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -559,8 +559,8 @@ add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CUR DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/gamedata/xlat/xlat_parser.y ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h - COMMAND lemon -C${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/scripting/zscript/zcc-parse.lemon - DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/scripting/zscript/zcc-parse.lemon ) + COMMAND lemon -C${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/frontend/zcc-parse.lemon + DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/frontend/zcc-parse.lemon ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h COMMAND re2c --no-generation-date -s -o ${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h ${CMAKE_CURRENT_SOURCE_DIR}/common/engine/sc_man_scanner.re @@ -618,6 +618,7 @@ file( GLOB HEADER_FILES common/scripting/jit/*h common/scripting/interface/*.h common/scripting/backend/*.h + common/scripting/frontend/*.h utility/*.h scripting/*.h scripting/backend/*.h @@ -730,7 +731,7 @@ set( NOT_COMPILED_SOURCE_FILES gamedata/xlat/xlat_parser.y xlat_parser.c xlat_parser.h - scripting/zscript/zcc-parse.lemon + common/scripting/frontend/zcc-parse.lemon zcc-parse.c zcc-parse.h win32/zdoom.natvis @@ -1042,10 +1043,7 @@ set (PCH_SOURCES scripting/decorate/thingdef_exp.cpp scripting/decorate/thingdef_parse.cpp scripting/decorate/thingdef_states.cpp - scripting/zscript/ast.cpp - scripting/zscript/zcc_compile.cpp scripting/zscript/zcc_compile_doom.cpp - scripting/zscript/zcc_parser.cpp rendering/swrenderer/textures/r_swtexture.cpp rendering/swrenderer/textures/warptexture.cpp rendering/swrenderer/textures/swcanvastexture.cpp @@ -1150,9 +1148,14 @@ set (PCH_SOURCES common/scripting/core/types.cpp common/scripting/core/scopebarrier.cpp common/scripting/core/vmdisasm.cpp + common/scripting/core/imports.cpp common/scripting/vm/vmexec.cpp common/scripting/vm/vmframe.cpp common/scripting/interface/stringformat.cpp + #common/scripting/interface/exports.cpp + common/scripting/frontend/ast.cpp + common/scripting/frontend/zcc_compile.cpp + common/scripting/frontend/zcc_parser.cpp common/scripting/backend/vmbuilder.cpp common/scripting/backend/codegen.cpp @@ -1434,7 +1437,7 @@ source_group("Platforms\\Unix Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE source_group("Platforms\\SDL Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/sdl/.+") source_group("Platforms\\Win32 Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/win32/.+") source_group("Scripting\\Decorate frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/decorate/.+") -source_group("Scripting\\ZScript frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/zscript/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h) +source_group("Scripting\\ZScript frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/zscript/.+") source_group("Scripting\\Compiler backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/backend/.+") source_group("Scripting" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/scripting/.+") source_group("Common" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/.+") @@ -1450,6 +1453,7 @@ source_group("Common\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/co source_group("Common\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/.+") source_group("Common\\Scripting" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/.+") source_group("Common\\Scripting\\Interface" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/interface/.+") +source_group("Common\\Scripting\\Frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/frontend/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h) source_group("Common\\Scripting\\Backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/backend/.+") source_group("Common\\Scripting\\Core" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/core/.+") source_group("Common\\Scripting\\JIT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/jit/.+") diff --git a/src/common/scripting/core/imports.cpp b/src/common/scripting/core/imports.cpp new file mode 100644 index 0000000000..2b4d567568 --- /dev/null +++ b/src/common/scripting/core/imports.cpp @@ -0,0 +1,230 @@ +/* +** thingdef_data.cpp +** +** DECORATE data tables +** +**--------------------------------------------------------------------------- +** Copyright 2002-2020 Christoph Oelckers +** Copyright 2004-2008 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** 4. When not used as part of ZDoom or a ZDoom derivative, this code will be +** covered by the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or (at +** your option) any later version. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "gstrings.h" +#include "v_font.h" +#include "menu/menu.h" +#include "types.h" +#include "dictionary.h" +#include "vm.h" +#include "symbols.h" + +static TArray AFTable; +static TArray FieldTable; + + +//========================================================================== +// +// +// +//========================================================================== + +template +static int CompareClassNames(const char* const aname, const Desc& b) +{ + // ++ to get past the prefix letter of the native class name, which gets omitted by the FName for the class. + const char* bname = b.ClassName; + if ('\0' != *bname) ++bname; + return stricmp(aname, bname); +} + +template +static int CompareClassNames(const Desc& a, const Desc& b) +{ + // ++ to get past the prefix letter of the native class name, which gets omitted by the FName for the class. + const char* aname = a.ClassName; + if ('\0' != *aname) ++aname; + return CompareClassNames(aname, b); +} + +//========================================================================== +// +// Find a function by name using a binary search +// +//========================================================================== + +AFuncDesc *FindFunction(PContainerType *cls, const char * string) +{ + int min = 0, max = AFTable.Size() - 1; + + while (min <= max) + { + int mid = (min + max) / 2; + int lexval = CompareClassNames(cls->TypeName.GetChars(), AFTable[mid]); + if (lexval == 0) lexval = stricmp(string, AFTable[mid].FuncName); + if (lexval == 0) + { + return &AFTable[mid]; + } + else if (lexval > 0) + { + min = mid + 1; + } + else + { + max = mid - 1; + } + } + return nullptr; +} + +//========================================================================== +// +// Find a function by name using a binary search +// +//========================================================================== + +FieldDesc *FindField(PContainerType *cls, const char * string) +{ + int min = 0, max = FieldTable.Size() - 1; + const char * cname = cls ? cls->TypeName.GetChars() : ""; + + while (min <= max) + { + int mid = (min + max) / 2; + int lexval = CompareClassNames(cname, FieldTable[mid]); + if (lexval == 0) lexval = stricmp(string, FieldTable[mid].FieldName); + if (lexval == 0) + { + return &FieldTable[mid]; + } + else if (lexval > 0) + { + min = mid + 1; + } + else + { + max = mid - 1; + } + } + return nullptr; +} + + +//========================================================================== +// +// Find an action function in AActor's table +// +//========================================================================== + +VMFunction *FindVMFunction(PClass *cls, const char *name) +{ + auto f = dyn_cast(cls->FindSymbol(name, true)); + return f == nullptr ? nullptr : f->Variants[0].Implementation; +} + + +//========================================================================== +// +// Sorting helpers +// +//========================================================================== + +static int funccmp(const void * a, const void * b) +{ + int res = CompareClassNames(*(AFuncDesc*)a, *(AFuncDesc*)b); + if (res == 0) res = stricmp(((AFuncDesc*)a)->FuncName, ((AFuncDesc*)b)->FuncName); + return res; +} + +static int fieldcmp(const void * a, const void * b) +{ + int res = CompareClassNames(*(FieldDesc*)a, *(FieldDesc*)b); + if (res == 0) res = stricmp(((FieldDesc*)a)->FieldName, ((FieldDesc*)b)->FieldName); + return res; +} + +//========================================================================== +// +// Initialization +// +//========================================================================== + +void InitImports() +{ + auto fontstruct = NewStruct("FFont", nullptr, true); + fontstruct->Size = sizeof(FFont); + fontstruct->Align = alignof(FFont); + NewPointer(fontstruct, false)->InstallHandlers( + [](FSerializer &ar, const char *key, const void *addr) + { + ar(key, *(FFont **)addr); + }, + [](FSerializer &ar, const char *key, void *addr) + { + Serialize(ar, key, *(FFont **)addr, nullptr); + return true; + } + ); + + // Create a sorted list of native action functions + AFTable.Clear(); + if (AFTable.Size() == 0) + { + FAutoSegIterator probe(ARegHead, ARegTail); + + while (*++probe != NULL) + { + AFuncDesc *afunc = (AFuncDesc *)*probe; + assert(afunc->VMPointer != NULL); + *(afunc->VMPointer) = new VMNativeFunction(afunc->Function, afunc->FuncName); + (*(afunc->VMPointer))->PrintableName.Format("%s.%s [Native]", afunc->ClassName+1, afunc->FuncName); + (*(afunc->VMPointer))->DirectNativeCall = afunc->DirectNative; + AFTable.Push(*afunc); + } + AFTable.ShrinkToFit(); + qsort(&AFTable[0], AFTable.Size(), sizeof(AFTable[0]), funccmp); + } + + FieldTable.Clear(); + if (FieldTable.Size() == 0) + { + FAutoSegIterator probe(FRegHead, FRegTail); + + while (*++probe != NULL) + { + FieldDesc *afield = (FieldDesc *)*probe; + FieldTable.Push(*afield); + } + FieldTable.ShrinkToFit(); + qsort(&FieldTable[0], FieldTable.Size(), sizeof(FieldTable[0]), fieldcmp); + } +} + diff --git a/src/common/scripting/core/symbols.h b/src/common/scripting/core/symbols.h index 2ae194e89b..38412c0788 100644 --- a/src/common/scripting/core/symbols.h +++ b/src/common/scripting/core/symbols.h @@ -267,3 +267,9 @@ struct FNamespaceManager extern FNamespaceManager Namespaces; void RemoveUnusedSymbols(); + +struct AFuncDesc; +struct FieldDesc; +AFuncDesc *FindFunction(PContainerType *cls, const char * string); +FieldDesc *FindField(PContainerType *cls, const char * string); +void SetImplicitArgs(TArray* args, TArray* argflags, TArray* argnames, PContainerType* cls, uint32_t funcflags, int useflags); diff --git a/src/scripting/zscript/ast.cpp b/src/common/scripting/frontend/ast.cpp similarity index 100% rename from src/scripting/zscript/ast.cpp rename to src/common/scripting/frontend/ast.cpp diff --git a/src/scripting/zscript/zcc-parse.lemon b/src/common/scripting/frontend/zcc-parse.lemon similarity index 100% rename from src/scripting/zscript/zcc-parse.lemon rename to src/common/scripting/frontend/zcc-parse.lemon diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp similarity index 99% rename from src/scripting/zscript/zcc_compile.cpp rename to src/common/scripting/frontend/zcc_compile.cpp index 25ca97aac8..59870ee9b0 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -42,9 +42,6 @@ FSharedStringArena VMStringConstants; -FieldDesc* FindField(PContainerType* cls, const char* string); -AFuncDesc* FindFunction(PContainerType* cls, const char* string); - int GetIntConst(FxExpression *ex, FCompileContext &ctx) { diff --git a/src/scripting/zscript/zcc_compile.h b/src/common/scripting/frontend/zcc_compile.h similarity index 88% rename from src/scripting/zscript/zcc_compile.h rename to src/common/scripting/frontend/zcc_compile.h index c8c72552fd..5c90f77ddc 100644 --- a/src/scripting/zscript/zcc_compile.h +++ b/src/common/scripting/frontend/zcc_compile.h @@ -131,25 +131,15 @@ protected: void CompileAllFields(); bool CompileFields(PContainerType *type, TArray &Fields, PClass *Outer, PSymbolTable *TreeNodes, bool forstruct, bool hasnativechildren = false); - void CompileAllProperties(); - bool CompileProperties(PClass *type, TArray &Properties, FName prefix); - bool CompileFlagDefs(PClass *type, TArray &FlagDefs, 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, PContainerType *cls, bool *nosize); PType *ResolveUserType(ZCC_BasicType *type, PSymbolTable *sym, bool nativetype); - void InitDefaults(); - void ProcessDefaultFlag(PClassActor *cls, ZCC_FlagStmt *flg); - void ProcessDefaultProperty(PClassActor *cls, ZCC_PropertyStmt *flg, Baggage &bag); - void DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *pex, AActor *defaults, Baggage &bag); - void DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *pex, AActor *defaults, Baggage &bag); void CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool forclass); void InitFunctions(); - void CompileStates(); - FxExpression *SetupActionFunction(PClass *cls, ZCC_TreeNode *sl, int stateflags); - + TArray Constants; TArray Structs; TArray Classes; diff --git a/src/scripting/zscript/zcc_exprlist.h b/src/common/scripting/frontend/zcc_exprlist.h similarity index 100% rename from src/scripting/zscript/zcc_exprlist.h rename to src/common/scripting/frontend/zcc_exprlist.h diff --git a/src/scripting/zscript/zcc_parser.cpp b/src/common/scripting/frontend/zcc_parser.cpp similarity index 100% rename from src/scripting/zscript/zcc_parser.cpp rename to src/common/scripting/frontend/zcc_parser.cpp diff --git a/src/scripting/zscript/zcc_parser.h b/src/common/scripting/frontend/zcc_parser.h similarity index 100% rename from src/scripting/zscript/zcc_parser.h rename to src/common/scripting/frontend/zcc_parser.h diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 1ac18fa8a5..0dc60bc3c8 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -590,107 +590,6 @@ FPropertyInfo *FindProperty(const char * string) return NULL; } -//========================================================================== -// -// -// -//========================================================================== - -template -static int CompareClassNames(const char* const aname, const Desc& b) -{ - // ++ to get past the prefix letter of the native class name, which gets omitted by the FName for the class. - const char* bname = b.ClassName; - if ('\0' != *bname) ++bname; - return stricmp(aname, bname); -} - -template -static int CompareClassNames(const Desc& a, const Desc& b) -{ - // ++ to get past the prefix letter of the native class name, which gets omitted by the FName for the class. - const char* aname = a.ClassName; - if ('\0' != *aname) ++aname; - return CompareClassNames(aname, b); -} - -//========================================================================== -// -// Find a function by name using a binary search -// -//========================================================================== - -AFuncDesc *FindFunction(PContainerType *cls, const char * string) -{ - int min = 0, max = AFTable.Size() - 1; - - while (min <= max) - { - int mid = (min + max) / 2; - int lexval = CompareClassNames(cls->TypeName.GetChars(), AFTable[mid]); - if (lexval == 0) lexval = stricmp(string, AFTable[mid].FuncName); - if (lexval == 0) - { - return &AFTable[mid]; - } - else if (lexval > 0) - { - min = mid + 1; - } - else - { - max = mid - 1; - } - } - return nullptr; -} - -//========================================================================== -// -// Find a function by name using a binary search -// -//========================================================================== - -FieldDesc *FindField(PContainerType *cls, const char * string) -{ - int min = 0, max = FieldTable.Size() - 1; - const char * cname = cls ? cls->TypeName.GetChars() : ""; - - while (min <= max) - { - int mid = (min + max) / 2; - int lexval = CompareClassNames(cname, FieldTable[mid]); - if (lexval == 0) lexval = stricmp(string, FieldTable[mid].FieldName); - if (lexval == 0) - { - return &FieldTable[mid]; - } - else if (lexval > 0) - { - min = mid + 1; - } - else - { - max = mid - 1; - } - } - return nullptr; -} - - -//========================================================================== -// -// Find an action function in AActor's table -// -//========================================================================== - -VMFunction *FindVMFunction(PClass *cls, const char *name) -{ - auto f = dyn_cast(cls->FindSymbol(name, true)); - return f == nullptr ? nullptr : f->Variants[0].Implementation; -} - - //========================================================================== // // Sorting helpers @@ -707,25 +606,12 @@ static int propcmp(const void * a, const void * b) return stricmp( (*(FPropertyInfo**)a)->name, (*(FPropertyInfo**)b)->name); } -static int funccmp(const void * a, const void * b) -{ - int res = CompareClassNames(*(AFuncDesc*)a, *(AFuncDesc*)b); - if (res == 0) res = stricmp(((AFuncDesc*)a)->FuncName, ((AFuncDesc*)b)->FuncName); - return res; -} - -static int fieldcmp(const void * a, const void * b) -{ - int res = CompareClassNames(*(FieldDesc*)a, *(FieldDesc*)b); - if (res == 0) res = stricmp(((FieldDesc*)a)->FieldName, ((FieldDesc*)b)->FieldName); - return res; -} - //========================================================================== // // Initialization // //========================================================================== +void InitImports(); void InitThingdef() { @@ -871,25 +757,6 @@ void InitThingdef() qsort(&properties[0], properties.Size(), sizeof(properties[0]), propcmp); } - // Create a sorted list of native action functions - AFTable.Clear(); - if (AFTable.Size() == 0) - { - FAutoSegIterator probe(ARegHead, ARegTail); - - while (*++probe != NULL) - { - AFuncDesc *afunc = (AFuncDesc *)*probe; - assert(afunc->VMPointer != NULL); - *(afunc->VMPointer) = new VMNativeFunction(afunc->Function, afunc->FuncName); - (*(afunc->VMPointer))->PrintableName.Format("%s.%s [Native]", afunc->ClassName+1, afunc->FuncName); - (*(afunc->VMPointer))->DirectNativeCall = afunc->DirectNative; - AFTable.Push(*afunc); - } - AFTable.ShrinkToFit(); - qsort(&AFTable[0], AFTable.Size(), sizeof(AFTable[0]), funccmp); - } - // Add the constructor and destructor to FCheckPosition. auto fcp = NewStruct("FCheckPosition", nullptr); fcp->mConstructor = *FindFunction(fcp, "_Constructor")->VMPointer; @@ -908,19 +775,7 @@ void InitThingdef() fltd->Size = sizeof(FLineTraceData); fltd->Align = alignof(FLineTraceData); - FieldTable.Clear(); - if (FieldTable.Size() == 0) - { - FAutoSegIterator probe(FRegHead, FRegTail); - - while (*++probe != NULL) - { - FieldDesc *afield = (FieldDesc *)*probe; - FieldTable.Push(*afield); - } - FieldTable.ShrinkToFit(); - qsort(&FieldTable[0], FieldTable.Size(), sizeof(FieldTable[0]), fieldcmp); - } + InitImports(); } void SynthesizeFlagFields()