cfeinfo.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,344 行 · 第 1/3 页
C
1,344 行
void GetCallClass( SYM_HANDLE sym_handle )
{
struct aux_info *inf;
SYM_ENTRY sym;
CallClass = DefaultInfo.cclass;
if( sym_handle != 0 ) {
inf = FindInfo( &sym, sym_handle );
if( sym.flags & SYM_FUNCTION ) {
if( inf != &DefaultInfo ) {
CallClass = inf->cclass;
} else {
CallClass = GetLangInfo( sym.attrib )->cclass;
#if _CPU == 8086
if( TargSys == TS_WINDOWS ) {
if( sym.attrib & (LANG_CDECL | LANG_PASCAL) ) {
CallClass |= FAT_WINDOWS_PROLOG;
}
}
#endif
}
#if ( _CPU == 8086 ) || ( _CPU == 386 )
if( CompFlags.emit_names ) {
CallClass |= EMIT_FUNCTION_NAME;
}
if( sym.attrib & FLAG_FAR ) {
CallClass |= FAR;
if( sym.attrib & FLAG_NEAR ) {
CallClass |= INTERRUPT;
}
} else if( sym.attrib & FLAG_NEAR ) {
CallClass &= ~ FAR;
}
#endif
#ifdef DLL_EXPORT
if( sym.attrib & FLAG_EXPORT ) { /* 12-mar-90 */
CallClass |= DLL_EXPORT;
}
#endif
#ifdef LOAD_DS_ON_ENTRY
if( sym.attrib & FLAG_LOADDS ) { /* 26-apr-90 */
#if 0 /* John - 11-mar-93 */ /* 21-feb-93 */
if( TargSys == TS_WINDOWS ) {
CallClass |= FAT_WINDOWS_PROLOG;
} else {
CallClass |= LOAD_DS_ON_ENTRY;
}
#else
CallClass |= LOAD_DS_ON_ENTRY;
#endif
}
#endif
#ifdef MAKE_CALL_INLINE
if( IsInLineFunc( sym_handle ) ) {
CallClass |= MAKE_CALL_INLINE;
}
#endif
if( VarFunc( &sym ) ) {
CallClass |= CALLER_POPS | HAS_VARARGS;
}
}
}
#ifdef REVERSE
CallClass &= ~ REVERSE_PARMS; /* 28-may-89 */
#endif
#if ( _CPU == 8086 ) || ( _CPU == 386 )
if( sym_handle != 0 && sym.flags & SYM_FUNC_NEEDS_THUNK ) {
CallClass |= THUNK_PROLOG;
}
#endif
#ifdef PROLOG_HOOKS
if( CompFlags.ep_switch_used != 0 ) {
CallClass |= PROLOG_HOOKS;
}
#endif
#ifdef EPILOG_HOOKS
if( CompFlags.ee_switch_used != 0 ) {
CallClass |= EPILOG_HOOKS;
}
#endif
#ifdef GROW_STACK
if( CompFlags.sg_switch_used ) {
CallClass |= GROW_STACK;
}
#endif
#ifdef TOUCH_STACK
if( CompFlags.st_switch_used ) {
CallClass |= TOUCH_STACK;
}
#endif
}
static time_t *getFileDepTimeStamp( FNAMEPTR flist )
{
static time_t stamp;
#if ( ( _CPU == 8086 ) || ( _CPU == 386 ) ) && ( COMP_CFG_COFF == 0 )
stamp = _timet2dos( flist->mtime );
#else
stamp = flist->mtime;
#endif
return( &stamp );
}
static FNAMEPTR NextDependency( FNAMEPTR curr )
{
if( !CompFlags.emit_dependencies ) {
return( NULL );
}
if( curr == NULL ) {
curr = FNames;
} else {
curr = curr->next;
}
while( curr != NULL ) {
if( curr->rwflag && !SrcFileInRDir( curr ) )
break;
curr = curr->next;
}
return( curr );
}
/*
// NextLibrary
// Called (indirectly) from the code generator to inject automagically defined symbols.
// Inputs:
// index (n-1)
// Usually called from a loop until we return 0/NULL to show no more libraries
// request
// NEXT_LIBRARY
// examines the current flags to see if any libraries should be
// automagically referenced and returns the relevant index if so.
// LIBRARY_NAME
// returns the requested name.
//
*/
static VOIDPTR NextLibrary( int index, aux_class request )
{
struct library_list *liblist;
char *name = NULL;
int i;
i = 0;
if( request == NEXT_LIBRARY )
++index;
for( liblist = HeadLibs; liblist; liblist = liblist->next ) {
name = &liblist->prio;
++i;
if( i == index ) {
break;
}
}
if( liblist == NULL ) {
switch( index - i ) {
case 1: /* return 1 for CLIB */
name = CLIB_Name;
if( CompFlags.emit_library_any )
break;
if( CompFlags.emit_library_with_main ) {
if( CompFlags.has_main )
break;
if( CompFlags.has_winmain )
break;
if( CompFlags.bd_switch_used )
break;
if( CompFlags.has_libmain )
break;
if( CompFlags.bm_switch_used )
break; /* JBS */
++index;
} else {
name = NULL;
index = 0; // indicate all done
}
break;
/*
// MATHLIB is always referenced as a default library because
// the linker wont include anything without a 'real' referenced
// symbol
*/
case 2: /* return 2 for MATHLIB */
name = MATHLIB_Name;
break;
case 3: /* return 3 for EMULIB */
name = EmuLib_Name;
if( EmuLib_Name != NULL )
break;
// fall through
case 4: /* used to be PCODE */
name = NULL;
index = 0; // indicate all done
break;
default:
break;
}
}
/*
// return library name, or
*/
if( request == LIBRARY_NAME )
return( name );
/*
// library index
*/
return( (char *)index );
}
/* Return the size of function parameters or -1 if size could
* not be determined (symbol isn't a function or is variadic)
*/
static int GetParmsSize( CGSYM_HANDLE sym_handle )
{
int total_parm_size = 0;
int parm_size;
TYPEPTR fn_typ;
TYPEPTR *parm;
TYPEPTR typ;
SYM_ENTRY sym;
SymGet( &sym, sym_handle );
fn_typ = sym.sym_type;
SKIP_TYPEDEFS( fn_typ );
if( fn_typ->decl_type == TYPE_FUNCTION ) {
parm = fn_typ->u.fn.parms;
if( parm != NULL ) {
for( ; (typ = *parm); ++parm ) {
if( typ->decl_type == TYPE_DOT_DOT_DOT ) {
total_parm_size = -1;
break;
}
SKIP_TYPEDEFS( typ );
if( typ->decl_type == TYPE_VOID )
break;
parm_size = TypeSize( typ );
parm_size = (parm_size + sizeof( target_int ) - 1)
& -sizeof( target_int );
total_parm_size += parm_size;
}
}
} else {
total_parm_size = -1;
}
return( total_parm_size );
}
/*
// Return name pattern manipulator string
*/
static char *GetNamePattern( CGSYM_HANDLE sym_handle )
{
char *pattern;
SYM_ENTRY sym;
struct aux_info *inf;
inf = FindInfo( &sym, sym_handle );
#ifdef __SEH__
if(( sym_handle == SymTryInit )
|| ( sym_handle == SymTryFini )
|| ( sym_handle == SymTryUnwind )
|| ( sym_handle == SymExcept )) {
pattern = "*";
} else {
#endif
inf = LangInfo( sym.attrib, inf );
if( sym.flags & SYM_FUNCTION ) {
pattern = inf->objname;
#if ( _CPU == 386 ) || ( _CPU == 8086 )
if( VarFunc( &sym ) ) {
if( inf == &DefaultInfo )
inf = DftCallConv;
if( inf == &StdcallInfo ) {
pattern = CdeclInfo.objname;
} else if( inf == &FastcallInfo ) {
pattern = CdeclInfo.objname;
}
}
#endif
if( pattern == NULL ) {
pattern = TS_CODE_MANGLE;
}
} else {
pattern = VarNamePattern( inf );
if( pattern == NULL ) {
pattern = TS_DATA_MANGLE;
}
}
#ifdef __SEH__
} // close that else
#endif
return( pattern );
}
static char *GetBaseName( CGSYM_HANDLE sym_handle )
{
SYM_ENTRY sym;
SymGet( &sym, sym_handle );
return( sym.name );
}
extern char *FEExtName( CGSYM_HANDLE sym_handle, int request )
/************************************************************/
{
switch( request ) {
case EXTN_BASENAME:
return( GetBaseName( sym_handle ) );
case EXTN_PATTERN:
return( GetNamePattern( sym_handle ) );
case EXTN_PRMSIZE:
return( (char *)GetParmsSize( sym_handle ) );
default:
return( NULL );
}
}
#if ( _CPU == 8086 ) || ( _CPU == 386 )
/*
// NextImport
// Called (indirectly) from the code generator to inject automagically defined symbols.
// Inputs:
// index (n-1)
// Usually called from a loop until we return 0/NULL to show no more symbols
// are required.
// request
// NEXT_IMPORT
// examines the current flags to see if any symbols should be
// automagically inserted and returns the relevant index if so.
// IMPORT_NAME
// returns the requested name. if we have returned an index for
// the current compiler settings we should be called with a valid
// index but we still perform exactly the same checks as this is
// good practise.
//
*/
static VOIDPTR NextImport( int index, aux_class request )
{
char *name;
if(!CompFlags.emit_targimp_symbols)
return (NULL);
if( request == NEXT_IMPORT )
++index;
switch( index ) {
/* handle entry points */
case 1:
/* wide char or MBCS entry */
if( CompFlags.has_wchar_entry ) {
name = "__DLLstartw_";
} else {
name = "__DLLstart_";
}
if( CompFlags.bd_switch_used ) /* build target == DLL ? */
break;
if( CompFlags.has_libmain ) { /* object has defined symbol (w)LibMain/(w)DllMain */
/* build target == console or gui application ? */
if( !(CompFlags.bc_switch_used || CompFlags.bg_switch_used ) ) {
break;
}
}
/* wide char or MBCS entry */
if( CompFlags.has_wchar_entry ) {
name = "_wstartw_";
} else {
name = "_wstart_";
}
/* symbol (w)WinMain defined */
if( CompFlags.has_winmain ) {
/* gui application */
if( CompFlags.bg_switch_used )
break;
/* target == DLL or target == console*/
if( !(CompFlags.bd_switch_used || CompFlags.bc_switch_used ) ) {
break;
}
}
#if _CPU == 8086
/* is target windows AND symbol (w)main is defined */
if(( TargetSwitches & WINDOWS ) && CompFlags.has_main )
break;
#endif
/* wide char or MBCS entry */
if( CompFlags.has_wchar_entry ) {
name = "_cstartw_";
} else {
name = "_cstart_";
}
/* is symbol (w)main is defined ? */
if( CompFlags.has_main ) {
/* build target == console ? */
if( CompFlags.bc_switch_used )
break;
/* target == DLL or target = GUI app ? */
if( !(CompFlags.bd_switch_used || CompFlags.bg_switch_used ) ) {
break;
}
}
++index;
/* handle floating point support */
case 2:
/* floating point used */
name = "_fltused_";
if( CompFlags.emit_library_with_main /* emit default library info? */
|| CompFlags.emit_library_any ) { /* -zlf emit all library info? */
/* 12-mar-90 */
if( CompFlags.float_used ) { /* has this object used any floating point code? */
break;
}
}
++index;
/* handle code model library support */
case 3:
#if _CPU == 8086
name = "_small_code_";
if( TargetSwitches & BIG_CODE ) { /* big code model ? */
name = "_big_code_";
}
if( CompFlags.emit_library_with_main /* emit default library info? */
|| CompFlags.emit_library_any ) { /* -zlf emit all library info? */
/* 12-mar-90 */
if( FirstStmt != 0 ) {
break;
}
}
#endif
++index;
/* handle floating point emulator */
case 4:
/* generating FPU instructions OR this object used floats ?*/
if( CompFlags.pgm_used_8087 || CompFlags.float_used ) {
#if _CPU == 386
name = "__init_387_emulator";
#else
name = "__init_87_emulator";
#endif
if( GET_FPU( ProcRevision ) & FPU_EMU ) { /* using emulated FPU code? */
break;
}
}
++index;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?