From 388dcfbd18fc6cf2b181bf26fec69791ba73d9c1 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Wed, 2 Sep 2009 12:08:30 +0000 Subject: [PATCH] 2009-09-02 14:08 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbcomp.h * harbour/include/hbcompdf.h * harbour/source/compiler/hbmain.c * harbour/source/compiler/genc.c * harbour/source/compiler/genhrb.c + added support for compiling multiple .prg modules into single compilation unit with repeated static or init/exit functions with the same name. Now Harbour compiler compiling .prg code from different .prg modules included by @.clp or by SET PROCEDURE TO ... / DO ... [ WITH ... ] works exactly like Clipper. It supports separated file wide definitions for each compiled .prg module when -n switch is used and allows to use static or init/exit functions/procedures with the same names but in different modules. It resolves incompatibility often reported by [x]Harbour users. Now it's not longer necessary to update existing Clipper code. @.clp files and SET PROCEDURE TO ... / DO ... [ WITH ... ] are fully functional like in Clipper. AFAIR it was the last unintentional incompatibility with Clipper. TODO: add support for multiple static functions with the same name in .HRB files - it's necessary to change used format so I'll probably to that with .HRL support. Now when -gh switch is used harbour and such functions exists then compiler generates: Error E0002 Redefinition of procedure or function ... TODO: modify hbmk2 to pass @.clp files directly to Harbour compiler so it can compile them just like Clipper does and generate single output file: . * harbour/config/instsh.mk * disabled install command echo --- harbour/ChangeLog | 33 ++++++ harbour/config/instsh.mk | 2 +- harbour/include/hbcomp.h | 3 +- harbour/include/hbcompdf.h | 12 +- harbour/source/compiler/genc.c | 44 ++++---- harbour/source/compiler/genhrb.c | 2 +- harbour/source/compiler/hbmain.c | 181 +++++++++++++++++++++---------- 7 files changed, 192 insertions(+), 85 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index fe1c51fe3d..62e76923a9 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,39 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-09-02 14:08 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbcomp.h + * harbour/include/hbcompdf.h + * harbour/source/compiler/hbmain.c + * harbour/source/compiler/genc.c + * harbour/source/compiler/genhrb.c + + added support for compiling multiple .prg modules into single + compilation unit with repeated static or init/exit functions + with the same name. + Now Harbour compiler compiling .prg code from different .prg modules + included by @.clp or by SET PROCEDURE TO ... / DO ... [ WITH ... ] + works exactly like Clipper. It supports separated file wide definitions + for each compiled .prg module when -n switch is used and allows to + use static or init/exit functions/procedures with the same names but + in different modules. + It resolves incompatibility often reported by [x]Harbour users. + Now it's not longer necessary to update existing Clipper code. + @.clp files and SET PROCEDURE TO ... / DO ... [ WITH ... ] are + fully functional like in Clipper. + AFAIR it was the last unintentional incompatibility with Clipper. + + TODO: add support for multiple static functions with the same name + in .HRB files - it's necessary to change used format so I'll + probably to that with .HRL support. Now when -gh switch is used + harbour and such functions exists then compiler generates: + Error E0002 Redefinition of procedure or function ... + TODO: modify hbmk2 to pass @.clp files directly to Harbour + compiler so it can compile them just like Clipper does and + generate single output file: . + + * harbour/config/instsh.mk + * disabled install command echo + 2009-09-02 02:51 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/source/compiler/hbmain.c % farther optimizations and simplifications diff --git a/harbour/config/instsh.mk b/harbour/config/instsh.mk index 27152085d2..1ed0fae025 100644 --- a/harbour/config/instsh.mk +++ b/harbour/config/instsh.mk @@ -21,7 +21,7 @@ endif ifeq ($(HB_SHELL),sh) INSTALL_RULE := \ - $(MDP) $(subst \,/,$(INSTALL_DIR)); \ + @$(MDP) $(subst \,/,$(INSTALL_DIR)); \ if [ ! -d "$(subst \,/,$(INSTALL_DIR))" ]; \ then \ $(ECHO) "! Can't install, path not found: '$(subst \,/,$(INSTALL_DIR))'" 1>&2; \ diff --git a/harbour/include/hbcomp.h b/harbour/include/hbcomp.h index 10d7fdbe3e..70f0726d42 100644 --- a/harbour/include/hbcomp.h +++ b/harbour/include/hbcomp.h @@ -135,7 +135,8 @@ extern int hb_compVariableScope( HB_COMP_DECL, const char * ); #define FUN_WITH_RETURN 0x0020 /* there was RETURN statement in previous line */ #define FUN_EXTBLOCK 0x0040 /* it's extended codeblock */ #define FUN_FILE_DECL 0x0080 /* pseudo function with file wide declarations */ -#define FUN_ATTACHED 0x0100 /* function attached to function list */ +#define FUN_FILE_FIRST 0x0100 /* 1-st real or pseudo function in compiled .prg module */ +#define FUN_ATTACHED 0x0200 /* function attached to function list */ extern void hb_compFunctionAdd( HB_COMP_DECL, const char * szFunName, HB_SYMBOLSCOPE cScope, int iType ); /* starts a new Clipper language function definition */ extern BOOL hb_compFunCallCheck( HB_COMP_DECL, const char *, int ); diff --git a/harbour/include/hbcompdf.h b/harbour/include/hbcompdf.h index a6b2a4b2ad..b93a3cf7f3 100644 --- a/harbour/include/hbcompdf.h +++ b/harbour/include/hbcompdf.h @@ -399,6 +399,7 @@ typedef struct __FUNC ULONG lPCodeSize; /* total memory size for pcode */ ULONG lPCodePos; /* actual pcode offset */ int iStaticsBase; /* base for this function statics */ + int iFuncSuffix; /* function suffix for multiple static functions with the same name */ ULONG * pNOOPs; /* pointer to the NOOP array */ ULONG * pJumps; /* pointer to the Jumps array */ ULONG iNOOPs; /* NOOPs Counter */ @@ -462,10 +463,10 @@ typedef struct /* compiler symbol support structure */ typedef struct _COMSYMBOL { - const char * szName; /* the name of the symbol */ - HB_SYMBOLSCOPE cScope; /* the scope of the symbol */ - BOOL bFunc; /* is it a function name (TRUE) or memvar (FALSE) */ - PCOMCLASS pClass; + const char * szName; /* the name of the symbol */ + HB_SYMBOLSCOPE cScope; /* the scope of the symbol */ + int iFunc; /* is it a function name (TRUE) or memvar (FALSE) */ + PFUNCTION pFunc; struct _COMSYMBOL * pNext; /* pointer to the next defined symbol */ } COMSYMBOL, * PCOMSYMBOL; @@ -677,7 +678,8 @@ typedef struct _HB_COMP char cCastType; /* current casting type */ int iErrorCount; - BOOL iStartProc; /* holds if we need to create the starting procedure */ + int iModulesCount; /* number of compiled .prg modules */ + int iStartProc; /* holds if we need to create the starting procedure */ int iMaxTransCycles; /* maximum translate cycles in PP (-r=) */ int iHidden; /* hide strings */ int iWarnings; /* enable parse warnings */ diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c index 1c8d57d2ca..762a61b5d8 100644 --- a/harbour/source/compiler/genc.c +++ b/harbour/source/compiler/genc.c @@ -32,7 +32,7 @@ static void hb_compGenCReadable( HB_COMP_DECL, PFUNCTION pFunc, FILE * yyc ); static void hb_compGenCCompact( PFUNCTION pFunc, FILE * yyc ); -static void hb_compGenCFunc( FILE *yyc, const char *cDecor, const char *szName, BOOL fStrip ); +static void hb_compGenCFunc( FILE *yyc, const char *cDecor, const char *szName, BOOL fStrip, int iFuncSuffix ); static void hb_writeEndInit( HB_COMP_DECL, FILE* yyc, const char * szModulname, const char * szSourceFile ); /* helper structure to pass information */ @@ -163,6 +163,7 @@ void hb_compGenCCode( HB_COMP_DECL, PHB_FNAME pFileName ) /* generates the PINLINE pInline; FILE * yyc; /* file handle for C output */ BOOL fHasHbInline = FALSE; + int iFuncSuffix; hb_fsFNameMerge( szFileName, pFileName ); if( ! pFileName->szExtension ) @@ -226,7 +227,7 @@ void hb_compGenCCode( HB_COMP_DECL, PHB_FNAME pFileName ) /* generates the pSym = HB_COMP_PARAM->symbols.pFirst; while( pSym ) { - if( pSym->bFunc ) + if( pSym->iFunc ) { if( pSym->szName[ 0 ] == '(' ) { @@ -236,17 +237,18 @@ void hb_compGenCCode( HB_COMP_DECL, PHB_FNAME pFileName ) /* generates the } else if( pSym->cScope & HB_FS_LOCAL ) /* is it a function defined in this module */ { + iFuncSuffix = pSym->pFunc ? pSym->pFunc->iFuncSuffix : 0; if( pSym->cScope & HB_FS_INIT ) - hb_compGenCFunc( yyc, "HB_FUNC_INIT( %s );\n", pSym->szName, TRUE ); + hb_compGenCFunc( yyc, "HB_FUNC_INIT( %s );\n", pSym->szName, TRUE, iFuncSuffix ); else if( pSym->cScope & HB_FS_EXIT ) - hb_compGenCFunc( yyc, "HB_FUNC_EXIT( %s );\n", pSym->szName, TRUE ); + hb_compGenCFunc( yyc, "HB_FUNC_EXIT( %s );\n", pSym->szName, TRUE, iFuncSuffix ); else if( pSym->cScope & HB_FS_STATIC ) - hb_compGenCFunc( yyc, "HB_FUNC_STATIC( %s );\n", pSym->szName, FALSE ); + hb_compGenCFunc( yyc, "HB_FUNC_STATIC( %s );\n", pSym->szName, FALSE, iFuncSuffix ); else - hb_compGenCFunc( yyc, "HB_FUNC( %s );\n", pSym->szName, FALSE ); + hb_compGenCFunc( yyc, "HB_FUNC( %s );\n", pSym->szName, FALSE, iFuncSuffix ); } else if( ( pSym->cScope & HB_FS_DEFERRED ) == 0 ) /* it's not a function declared as dynamic */ - hb_compGenCFunc( yyc, "HB_FUNC_EXTERN( %s );\n", pSym->szName, FALSE ); + hb_compGenCFunc( yyc, "HB_FUNC_EXTERN( %s );\n", pSym->szName, FALSE, 0 ); } pSym = pSym->pNext; } @@ -309,17 +311,18 @@ void hb_compGenCCode( HB_COMP_DECL, PHB_FNAME pFileName ) /* generates the { fprintf( yyc, " | HB_FS_LOCAL" ); + iFuncSuffix = pSym->pFunc ? pSym->pFunc->iFuncSuffix : 0; if( pSym->cScope & HB_FS_INIT ) - hb_compGenCFunc( yyc, "}, {HB_INIT_FUNCNAME( %s )}, NULL }", pSym->szName, TRUE ); + hb_compGenCFunc( yyc, "}, {HB_INIT_FUNCNAME( %s )}, NULL }", pSym->szName, TRUE, iFuncSuffix ); else if( pSym->cScope & HB_FS_EXIT ) - hb_compGenCFunc( yyc, "}, {HB_EXIT_FUNCNAME( %s )}, NULL }", pSym->szName, TRUE ); + hb_compGenCFunc( yyc, "}, {HB_EXIT_FUNCNAME( %s )}, NULL }", pSym->szName, TRUE, iFuncSuffix ); else - hb_compGenCFunc( yyc, "}, {HB_FUNCNAME( %s )}, NULL }", pSym->szName, FALSE ); + hb_compGenCFunc( yyc, "}, {HB_FUNCNAME( %s )}, NULL }", pSym->szName, FALSE, iFuncSuffix ); } else if( pSym->cScope & HB_FS_DEFERRED ) /* is it a function declared as dynamic */ fprintf( yyc, " | HB_FS_DEFERRED}, {NULL}, NULL }" ); - else if( pSym->bFunc ) /* is it a function called from this module */ - hb_compGenCFunc( yyc, "}, {HB_FUNCNAME( %s )}, NULL }", pSym->szName, FALSE ); + else if( pSym->iFunc ) /* is it a function called from this module */ + hb_compGenCFunc( yyc, "}, {HB_FUNCNAME( %s )}, NULL }", pSym->szName, FALSE, 0 ); else fprintf( yyc, "}, {NULL}, NULL }" ); /* memvar | alias | message */ } @@ -347,15 +350,15 @@ void hb_compGenCCode( HB_COMP_DECL, PHB_FNAME pFileName ) /* generates the fprintf( yyc, "HB_FUNC_INITLINES()\n" ); /* Is it an INIT FUNCTION/PROCEDURE */ else if( pFunc->cScope & HB_FS_INIT ) - hb_compGenCFunc( yyc, "HB_FUNC_INIT( %s )\n", pFunc->szName, TRUE ); + hb_compGenCFunc( yyc, "HB_FUNC_INIT( %s )\n", pFunc->szName, TRUE, pFunc->iFuncSuffix ); /* Is it an EXIT FUNCTION/PROCEDURE */ else if( pFunc->cScope & HB_FS_EXIT ) - hb_compGenCFunc( yyc, "HB_FUNC_EXIT( %s )\n", pFunc->szName, TRUE ); + hb_compGenCFunc( yyc, "HB_FUNC_EXIT( %s )\n", pFunc->szName, TRUE, pFunc->iFuncSuffix ); /* Is it a STATIC FUNCTION/PROCEDURE */ else if( pFunc->cScope & HB_FS_STATIC ) - hb_compGenCFunc( yyc, "HB_FUNC_STATIC( %s )\n", pFunc->szName, FALSE ); + hb_compGenCFunc( yyc, "HB_FUNC_STATIC( %s )\n", pFunc->szName, FALSE, pFunc->iFuncSuffix ); else /* Then it must be PUBLIC FUNCTION/PROCEDURE */ - hb_compGenCFunc( yyc, "HB_FUNC( %s )\n", pFunc->szName, FALSE ); + hb_compGenCFunc( yyc, "HB_FUNC( %s )\n", pFunc->szName, FALSE, pFunc->iFuncSuffix ); if( HB_COMP_PARAM->iGenCOutput == HB_COMPGENC_REALCODE ) hb_compGenCRealCode( HB_COMP_PARAM, pFunc, yyc ); @@ -384,7 +387,7 @@ void hb_compGenCCode( HB_COMP_DECL, PHB_FNAME pFileName ) /* generates the fprintf( yyc, "\n" ); if( pInline->szName ) - hb_compGenCFunc( yyc, "HB_FUNC_STATIC( %s )\n", pInline->szName, FALSE ); + hb_compGenCFunc( yyc, "HB_FUNC_STATIC( %s )\n", pInline->szName, FALSE, 0 ); fprintf( yyc, "%s", pInline->pCode ); } @@ -409,7 +412,7 @@ void hb_compGenCCode( HB_COMP_DECL, PHB_FNAME pFileName ) /* generates the fprintf( yyc, "\n" ); if( pInline->szName ) - hb_compGenCFunc( yyc, "HB_FUNC_STATIC( %s )\n", pInline->szName, FALSE ); + hb_compGenCFunc( yyc, "HB_FUNC_STATIC( %s )\n", pInline->szName, FALSE, 0 ); fprintf( yyc, "%s", pInline->pCode ); } @@ -452,7 +455,8 @@ static void hb_writeEndInit( HB_COMP_DECL, FILE* yyc, const char * szModulname, HB_COMP_PARAM->szPrefix, szModulname ); } -static void hb_compGenCFunc( FILE * yyc, const char *cDecor, const char *szName, BOOL fStrip ) +static void hb_compGenCFunc( FILE * yyc, const char *cDecor, const char *szName, + BOOL fStrip, int iFuncSuffix ) { int i = 0; @@ -475,6 +479,8 @@ static void hb_compGenCFunc( FILE * yyc, const char *cDecor, const char *szName, fprintf( yyc, "x%02x", ( UCHAR ) c ); } } + if( iFuncSuffix ) + fprintf( yyc, "v%d", iFuncSuffix ); i += 2; } else diff --git a/harbour/source/compiler/genhrb.c b/harbour/source/compiler/genhrb.c index 75f352c943..c5ff9db3eb 100644 --- a/harbour/source/compiler/genhrb.c +++ b/harbour/source/compiler/genhrb.c @@ -110,7 +110,7 @@ void hb_compGenBufPortObj( HB_COMP_DECL, BYTE ** pBufPtr, ULONG * pulSize ) *ptr++ = SYM_FUNC; /* function defined in this module */ else if( pSym->cScope & HB_FS_DEFERRED ) *ptr++ = SYM_DEFERRED; /* lately bound function */ - else if( pSym->bFunc ) + else if( pSym->iFunc ) *ptr++ = SYM_EXTERN; /* external function */ else *ptr++ = SYM_NOLINK; /* other symbol */ diff --git a/harbour/source/compiler/hbmain.c b/harbour/source/compiler/hbmain.c index 291c20d690..e7f821bee4 100644 --- a/harbour/source/compiler/hbmain.c +++ b/harbour/source/compiler/hbmain.c @@ -263,7 +263,7 @@ static PCOMSYMBOL hb_compSymbolAdd( HB_COMP_DECL, const char * szSymbolName, USH pSym->szName = szSymbolName; pSym->cScope = 0; pSym->pNext = NULL; - pSym->bFunc = bFunction; + pSym->iFunc = bFunction ? HB_COMP_PARAM->iModulesCount : 0; if( ! HB_COMP_PARAM->symbols.iCount ) { @@ -287,12 +287,13 @@ static PCOMSYMBOL hb_compSymbolFind( HB_COMP_DECL, const char * szSymbolName, US { PCOMSYMBOL pSym = HB_COMP_PARAM->symbols.pFirst; USHORT wCnt = 0; + int iFunc = bFunction ? HB_COMP_PARAM->iModulesCount : 0; while( pSym ) { if( ! strcmp( pSym->szName, szSymbolName ) ) { - if( bFunction == pSym->bFunc ) + if( iFunc == pSym->iFunc ) { if( pwPos ) *pwPos = wCnt; @@ -1938,15 +1939,28 @@ static void hb_compAddFunc( HB_COMP_DECL, PFUNCTION pFunc ) HB_COMP_PARAM->functions.iCount++; } -static PFUNCTION hb_compFunctionFind( HB_COMP_DECL, const char * szFunctionName ) +static PFUNCTION hb_compFunctionFind( HB_COMP_DECL, const char * szName, BOOL fLocal ) { - PFUNCTION pFunc = HB_COMP_PARAM->functions.pFirst; + PFUNCTION pFunc; + if( HB_COMP_PARAM->iModulesCount <= 1 ) + { + pFunc = HB_COMP_PARAM->functions.pFirst; + fLocal = TRUE; + } + else + pFunc = fLocal ? HB_COMP_PARAM->pDeclFunc : + HB_COMP_PARAM->functions.pFirst; while( pFunc ) { + if( pFunc == HB_COMP_PARAM->pDeclFunc ) + fLocal = TRUE; + if( ( pFunc->funFlags & FUN_FILE_DECL ) == 0 && - ! strcmp( pFunc->szName, szFunctionName ) ) + ( fLocal || ( pFunc->cScope & ( HB_FS_STATIC | HB_FS_INITEXIT ) ) == 0 ) && + strcmp( pFunc->szName, szName ) == 0 ) break; + pFunc = pFunc->pNext; } return pFunc; @@ -1966,12 +1980,38 @@ static BOOL hb_compIsModuleFunc( HB_COMP_DECL, const char * szFunctionName ) return pFunc != NULL; } +static void hb_compUpdateFunctionNames( HB_COMP_DECL ) +{ + if( HB_COMP_PARAM->iModulesCount > 1 ) + { + PFUNCTION pFunc = HB_COMP_PARAM->functions.pFirst; + + while( pFunc ) + { + if( ( pFunc->cScope & ( HB_FS_STATIC | HB_FS_INITEXIT ) ) != 0 ) + { + BOOL fGlobal = FALSE; + PFUNCTION pSeek = HB_COMP_PARAM->functions.pFirst; + + while( pSeek ) + { + if( pFunc == pSeek ) + fGlobal = TRUE; + else if( ( !fGlobal || ( pSeek->cScope & ( HB_FS_STATIC | HB_FS_INITEXIT ) ) == 0 ) && + strcmp( pFunc->szName, pSeek->szName ) == 0 ) + pFunc->iFuncSuffix++; + pSeek = pSeek->pNext; + } + } + pFunc = pFunc->pNext; + } + } +} + static BOOL hb_compRegisterFunc( HB_COMP_DECL, PFUNCTION pFunc, BOOL fError ) { - /* TODO: ignore static functions from other modules and set number - * such functions in pSym - */ - if( hb_compFunctionFind( HB_COMP_PARAM, pFunc->szName ) ) + if( hb_compFunctionFind( HB_COMP_PARAM, pFunc->szName, + ( pFunc->cScope & HB_FS_STATIC ) != 0 ) ) { /* The name of a function/procedure is already defined */ if( fError ) @@ -1991,6 +2031,7 @@ static BOOL hb_compRegisterFunc( HB_COMP_DECL, PFUNCTION pFunc, BOOL fError ) if( ! pSym ) pSym = hb_compSymbolAdd( HB_COMP_PARAM, pFunc->szName, NULL, HB_SYM_FUNCNAME ); pSym->cScope |= pFunc->cScope | HB_FS_LOCAL; + pSym->pFunc = pFunc; return TRUE; } } @@ -2028,7 +2069,8 @@ void hb_compFunctionAdd( HB_COMP_DECL, const char * szFunName, HB_SYMBOLSCOPE cS if( ( iType & FUN_FILE_DECL ) == 0 ) hb_compRegisterFunc( HB_COMP_PARAM, pFunc, TRUE ); - else + + if( ( iType & ( FUN_FILE_DECL | FUN_FILE_FIRST ) ) != 0 ) HB_COMP_PARAM->pDeclFunc = pFunc; hb_compAddFunc( HB_COMP_PARAM, pFunc ); @@ -2045,6 +2087,50 @@ void hb_compFunctionAdd( HB_COMP_DECL, const char * szFunName, HB_SYMBOLSCOPE cS HB_COMP_PARAM->lastLine = -1; } +/* create an ANNOUNCEd procedure + */ +static void hb_compAnnounce( HB_COMP_DECL, const char * szFunName ) +{ + PFUNCTION pFunc; + + /* Clipper call this function after compiling .prg module when ANNOUNCE + * symbol was deined not after compiling all .prg modules and search for + * public ANNOUNCEd function/procedure in all compiled so far modules + * and then for static one in currently compiler module. + */ + + pFunc = hb_compFunctionFind( HB_COMP_PARAM, szFunName, FALSE ); + if( pFunc ) + { + /* there is a function/procedure defined already - ANNOUNCEd procedure + * have to be a public symbol - check if existing symbol is public + */ + if( pFunc->cScope & HB_FS_STATIC ) + hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'F', HB_COMP_ERR_FUNC_ANNOUNCE, szFunName, NULL ); + } + else + { + PCOMSYMBOL pSym; + + /* create a new procedure + */ + pFunc = hb_compFunctionNew( HB_COMP_PARAM, szFunName, HB_FS_LOCAL ); + pFunc->funFlags |= FUN_PROCEDURE; + + pSym = hb_compSymbolFind( HB_COMP_PARAM, szFunName, NULL, HB_SYM_FUNCNAME ); + if( ! pSym ) + pSym = hb_compSymbolAdd( HB_COMP_PARAM, szFunName, NULL, HB_SYM_FUNCNAME ); + pSym->cScope |= pFunc->cScope; + pSym->pFunc = pFunc; + + hb_compAddFunc( HB_COMP_PARAM, pFunc ); + + /* this function have a very limited functionality + */ + hb_compGenPCode1( HB_P_ENDPROC, HB_COMP_PARAM ); + } +} + void hb_compFunctionMarkStatic( HB_COMP_DECL, const char * szFunName ) { PCOMSYMBOL pSym = hb_compSymbolFind( HB_COMP_PARAM, szFunName, NULL, HB_SYM_FUNCNAME ); @@ -2086,43 +2172,6 @@ PINLINE hb_compInlineAdd( HB_COMP_DECL, const char * szFunName, int iLine ) return pInline; } -/* create an ANNOUNCEd procedure - */ -static void hb_compAnnounce( HB_COMP_DECL, const char * szFunName ) -{ - PFUNCTION pFunc; - - pFunc = hb_compFunctionFind( HB_COMP_PARAM, szFunName ); - if( pFunc ) - { - /* there is a function/procedure defined already - ANNOUNCEd procedure - * have to be a public symbol - check if existing symbol is public - */ - if( pFunc->cScope & HB_FS_STATIC ) - hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'F', HB_COMP_ERR_FUNC_ANNOUNCE, szFunName, NULL ); - } - else - { - PCOMSYMBOL pSym; - - /* create a new procedure - */ - pSym = hb_compSymbolFind( HB_COMP_PARAM, szFunName, NULL, HB_SYM_FUNCNAME ); - if( ! pSym ) - pSym = hb_compSymbolAdd( HB_COMP_PARAM, szFunName, NULL, HB_SYM_FUNCNAME ); - pSym->cScope = HB_FS_PUBLIC | HB_FS_LOCAL; - - pFunc = hb_compFunctionNew( HB_COMP_PARAM, szFunName, pSym->cScope ); - pFunc->funFlags |= FUN_PROCEDURE; - - hb_compAddFunc( HB_COMP_PARAM, pFunc ); - - /* this function have a very limited functionality - */ - hb_compGenPCode1( HB_P_ENDPROC, HB_COMP_PARAM ); - } -} - void hb_compGenBreak( HB_COMP_DECL ) { hb_compGenPushFunCall( "BREAK", HB_COMP_PARAM ); @@ -2133,9 +2182,6 @@ static void hb_compExternGen( HB_COMP_DECL ) { PEXTERN pDelete; - if( HB_COMP_PARAM->fDebugInfo ) - hb_compExternAdd( HB_COMP_PARAM, "__DBGENTRY", 0 ); - while( HB_COMP_PARAM->externs ) { HB_SYMBOLSCOPE cScope = HB_COMP_PARAM->externs->cScope; @@ -3202,10 +3248,9 @@ void hb_compStaticDefStart( HB_COMP_DECL ) { BYTE pBuffer[ 5 ]; - HB_COMP_PARAM->pInitFunc = hb_compFunctionNew( HB_COMP_PARAM, "(_INITSTATICS)", HB_FS_INITEXIT ); + HB_COMP_PARAM->pInitFunc = hb_compFunctionNew( HB_COMP_PARAM, "(_INITSTATICS)", HB_FS_INITEXIT | HB_FS_LOCAL ); HB_COMP_PARAM->pInitFunc->pOwner = HB_COMP_PARAM->functions.pLast; HB_COMP_PARAM->pInitFunc->funFlags = FUN_USES_STATICS | FUN_PROCEDURE; - HB_COMP_PARAM->pInitFunc->cScope = HB_FS_INITEXIT | HB_FS_LOCAL; HB_COMP_PARAM->functions.pLast = HB_COMP_PARAM->pInitFunc; pBuffer[ 0 ] = HB_P_STATICS; @@ -3336,10 +3381,9 @@ static void hb_compLineNumberDefStart( HB_COMP_DECL ) { if( ! HB_COMP_PARAM->pLineFunc ) { - HB_COMP_PARAM->pLineFunc = hb_compFunctionNew( HB_COMP_PARAM, "(_INITLINES)", HB_FS_INITEXIT ); + HB_COMP_PARAM->pLineFunc = hb_compFunctionNew( HB_COMP_PARAM, "(_INITLINES)", HB_FS_INITEXIT | HB_FS_LOCAL ); HB_COMP_PARAM->pLineFunc->pOwner = HB_COMP_PARAM->functions.pLast; HB_COMP_PARAM->pLineFunc->funFlags = 0; - HB_COMP_PARAM->pLineFunc->cScope = HB_FS_INITEXIT | HB_FS_LOCAL; HB_COMP_PARAM->functions.pLast = HB_COMP_PARAM->pLineFunc; if( HB_COMP_PARAM->fDebugInfo ) @@ -3639,6 +3683,8 @@ static void hb_compInitVars( HB_COMP_DECL ) HB_COMP_PARAM->inlines.pLast = NULL; HB_COMP_PARAM->szFile = NULL; + + HB_COMP_PARAM->iModulesCount = 0; } static void hb_compGenOutput( HB_COMP_DECL, int iLanguage ) @@ -3719,6 +3765,7 @@ static void hb_compAddInitFunc( HB_COMP_DECL, PFUNCTION pFunc ) PCOMSYMBOL pSym = hb_compSymbolAdd( HB_COMP_PARAM, pFunc->szName, NULL, HB_SYM_FUNCNAME ); pSym->cScope |= pFunc->cScope; + pSym->pFunc = pFunc; pFunc->funFlags |= FUN_ATTACHED; hb_compAddFunc( HB_COMP_PARAM, pFunc ); hb_compGenPCode1( HB_P_ENDPROC, HB_COMP_PARAM ); @@ -3943,6 +3990,21 @@ static int hb_compCompile( HB_COMP_DECL, const char * szPrg, const char * szBuff if( !fSkip ) { +#if !defined( HB_MODULES_MERGE ) + /* TODO: HRB format does not support yet multiple static functions + * with the same name. Such functionality needs extended .HRB + * file format. + */ + if( HB_COMP_PARAM->iLanguage != HB_LANG_PORT_OBJ && + HB_COMP_PARAM->iLanguage != HB_LANG_PORT_OBJ_BUF ) + { + if( HB_COMP_PARAM->iModulesCount++ ) + hb_compExternGen( HB_COMP_PARAM ); + } + else +#else + HB_COMP_PARAM->iModulesCount = 1; +#endif HB_COMP_PARAM->currLine = 1; HB_COMP_PARAM->currModule = hb_compIdentifierNew( HB_COMP_PARAM, szFileName, HB_IDENT_COPY ); @@ -3950,7 +4012,7 @@ static int hb_compCompile( HB_COMP_DECL, const char * szPrg, const char * szBuff HB_COMP_PARAM->szFile = HB_COMP_PARAM->currModule; if( szBuffer ) - hb_compFunctionAdd( HB_COMP_PARAM, "", 0, FUN_PROCEDURE | FUN_FILE_DECL ); + hb_compFunctionAdd( HB_COMP_PARAM, "", 0, FUN_PROCEDURE | FUN_FILE_FIRST | FUN_FILE_DECL ); else { if( ! HB_COMP_PARAM->fQuiet ) @@ -3968,11 +4030,9 @@ static int hb_compCompile( HB_COMP_DECL, const char * szPrg, const char * szBuff /* Generate the starting procedure frame */ hb_compFunctionAdd( HB_COMP_PARAM, hb_compIdentifierNew( HB_COMP_PARAM, hb_strupr( hb_strdup( pFileName->szName ) ), HB_IDENT_FREE ), - HB_FS_PUBLIC, FUN_PROCEDURE | ( HB_COMP_PARAM->iStartProc == 0 ? 0 : FUN_FILE_DECL ) ); + HB_FS_PUBLIC, FUN_PROCEDURE | FUN_FILE_FIRST | ( HB_COMP_PARAM->iStartProc == 0 ? 0 : FUN_FILE_DECL ) ); } - /* TODO: set first function and function symbol in given module */ - if( !HB_COMP_PARAM->fExit ) { int iExitLevel = HB_COMP_PARAM->iExitLevel; @@ -4004,6 +4064,9 @@ static int hb_compCompile( HB_COMP_DECL, const char * szPrg, const char * szBuff /* fix all previous function returns offsets */ hb_compFinalizeFunction( HB_COMP_PARAM ); + if( HB_COMP_PARAM->fDebugInfo ) + hb_compExternAdd( HB_COMP_PARAM, "__DBGENTRY", 0 ); + hb_compExternGen( HB_COMP_PARAM ); /* generates EXTERN symbols names */ if( HB_COMP_PARAM->pInitFunc ) @@ -4059,6 +4122,8 @@ static int hb_compCompile( HB_COMP_DECL, const char * szPrg, const char * szBuff if( HB_COMP_PARAM->szAnnounce ) hb_compAnnounce( HB_COMP_PARAM, HB_COMP_PARAM->szAnnounce ); + hb_compUpdateFunctionNames( HB_COMP_PARAM ); + /* End of finalization phase. */ if( HB_COMP_PARAM->iErrorCount || HB_COMP_PARAM->fAnyWarning )