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 @<name>.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 @<name>.clp files directly to Harbour
compiler so it can compile them just like Clipper does and
generate single output file: <name>.<ext>
* harbour/config/instsh.mk
* disabled install command echo
This commit is contained in:
@@ -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 @<name>.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 @<name>.clp files directly to Harbour
|
||||
compiler so it can compile them just like Clipper does and
|
||||
generate single output file: <name>.<ext>
|
||||
|
||||
* 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
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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=<n>) */
|
||||
int iHidden; /* hide strings */
|
||||
int iWarnings; /* enable parse warnings */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 )
|
||||
|
||||
Reference in New Issue
Block a user