?? cfeinfo.c
字號:
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Callback functions invoked from cg - communicate
* auxiliary information to the backend.
*
****************************************************************************/
#include <ctype.h>
#include "cvars.h"
#include "cg.h"
#include "cgswitch.h"
#include "pragdefn.h"
#include "pdefn2.h"
#include "iopath.h"
#include "compcfg.h"
#include <sys/stat.h>
#include "autodept.h"
static unsigned char VarFuncWeights[] = {
//a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y,z
0, 0,13, 0, 2, 1, 0, 0, 0, 0, 0,12, 0,14, 4,10, 0, 0, 6, 0, 0, 0, 0, 0, 0,0
};
static char *VarParmFuncs[] =
{ /* functions with var parm lists */
"", // 0
"", // 1
"", // 2
"", // 3
"", // 4
"", // 5
"", // 6
"", // 7
"fscanf", // 8
"fprintf", // 9
"execle", // 10
"execlpe", // 11
"scanf", // 12
"sscanf", // 13
"sprintf", // 14
"spawnle", // 15
"spawnlpe", // 16
"printf", // 17
"execlp", // 18
"execl", // 19
"cscanf", // 20
"cprintf", // 21
"open", // 22
"spawnlp", // 23
"spawnl", // 24
"sopen", // 25
"", // 26
"", // 27
"", // 28
"", // 29
"", // 30
"", // 31
};
#ifdef __SEH__
#if _CPU == 386
hw_reg_set TryParms[] =
{
HW_D_1( HW_EAX ),
0
};
#else
hw_reg_set TryParms[] =
{
HW_D( HW_EMPTY ),
0
};
#endif
#endif
/*
// does the specified symbol take variable parameters? manual search.
*/
int VarParm( SYMPTR sym )
{
TYPEPTR *parm;
TYPEPTR typ;
TYPEPTR fn_typ;
if( sym == NULL )
return( 0 );
if( sym->flags & SYM_FUNCTION )
{
fn_typ = sym->sym_type;
while( fn_typ->decl_type == TYPE_TYPEDEF )
fn_typ = fn_typ->object;
parm = fn_typ->u.parms;
if( parm != NULL )
{
for(; (typ = *parm); ++parm )
{
if( typ->decl_type == TYPE_DOT_DOT_DOT )
return( 1 );
}
}
}
return( 0 );
}
/*
// does the specified symbol take variable args? hash calc'ed
//
*/
int VarFunc( SYMPTR sym )
{
int hash;
int len;
char * p;
if( sym == NULL )
return( 0 );
if( sym->flags & SYM_FUNCTION )
{
p = sym->name;
len = strlen( p );
hash = (len + VarFuncWeights[ p[0] - 'a' ]
+ VarFuncWeights[ p[len-1] -'a' ]) & 31;
if( strcmp( p, VarParmFuncs[ hash ] ) == 0 )
return( 1 );
return( VarParm( sym ) );
}
return( 0 );
}
#if _MACHINE == _PC
static struct inline_funcs __FAR *Flat( struct inline_funcs __FAR *ifunc )
{
#if _CPU == 386
extern byte_seq * FlatAlternates[];
byte_seq ** p;
if( TargetSwitches & FLAT_MODEL )
{
for( p = FlatAlternates; p[0] != NULL; p += 2 )
{
if( p[0] == ifunc->code )
{
ifunc->code = p[1];
return( ifunc );
}
}
}
#endif
return( ifunc );
}
#endif
#if _MACHINE == _PC
struct inline_funcs __FAR *IF_Lookup( char *name )
{
struct inline_funcs __FAR * ifunc;
if( GET_FPU( ProcRevision ) > FPU_NONE )
{
ifunc = _8087_Functions;
while( ifunc->name )
{
if( strcmp( ifunc->name, name ) == 0 )
return( Flat( ifunc ) );
++ifunc;
}
}
if( OptSize == 100 )
{ /* if /os specified */
ifunc = SInline_Functions;
if( TargetSwitches & BIG_DATA )
{
#if _CPU == 8086
if( TargetSwitches & FLOATING_DS )
{
ifunc = ZF_Data_Functions;
}
else
{
ifunc = ZP_Data_Functions;
}
#else
ifunc = SBigData_Functions;
#endif
}
while( ifunc->name )
{
if( strcmp( ifunc->name, name ) == 0 )
return( Flat( ifunc ) );
++ifunc;
}
}
#if _CPU == 386
if( TargetSwitches & FLAT_MODEL )
{
ifunc = Flat_Functions;
while( ifunc->name )
{
if( strcmp( ifunc->name, name ) == 0 )
return( ifunc );
++ifunc;
}
}
#endif
ifunc = Inline_Functions;
if( TargetSwitches & BIG_DATA )
{
#if _CPU == 8086
if( TargetSwitches & FLOATING_DS )
{
ifunc = DF_Data_Functions;
}
else
{
ifunc = DP_Data_Functions;
}
#else
ifunc = BigData_Functions;
#endif
}
while( ifunc->name )
{
if( strcmp( ifunc->name, name ) == 0 )
return( Flat( ifunc ) );
++ifunc;
}
ifunc = Common_Functions;
while( ifunc->name )
{
if( strcmp( ifunc->name, name ) == 0 )
return( Flat( ifunc ) );
++ifunc;
}
return( NULL );
}
#endif
/*
// return language specific info
*/
struct aux_info *LangInfo( int flags, struct aux_info *inf )
{
if( inf != &DefaultInfo )
return( inf );
switch( flags & FLAG_LANGUAGES )
{
case LANG_CDECL:
inf = &CdeclInfo;
break;
case LANG_PASCAL:
inf = &PascalInfo;
break;
case LANG_FORTRAN:
inf = &FortranInfo;
break;
case LANG_SYSCALL: /* 04-jul-91 */
inf = &SyscallInfo;
break;
case LANG_STDCALL: /* 08-jan-92 */
inf = &StdcallInfo;
break;
case LANG_OPTLINK: /* 08-jan-92 */
inf = &OptlinkInfo;
break;
case LANG_FASTCALL: /* 08-jan-92 */
inf = &FastCallInfo;
break;
}
return( inf );
}
int ParmsToBeReversed( int flags, struct aux_info *inf )
{
#ifdef REVERSE
inf = LangInfo( flags, inf );
if( inf != NULL )
{
if( inf->class & REVERSE_PARMS )
return( 1 );
}
#else
flags = flags;
inf = inf;
#endif
return( 0 );
}
struct aux_info *ModifyLookup( SYMPTR sym )
{
#if _CPU == 386 || _CPU == 8086
char * p;
struct aux_info * inf;
int len;
int hash;
static unsigned char NoModifyWeights[] =
{
//a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y,z
1, 4, 5, 0, 0,11, 0, 0, 8, 0, 0,15, 0,14,10, 0, 0, 9, 3, 7, 0, 0, 0, 0, 0,0
};
static char *NoModifyFuncs[] =
{
"sqrt",
"ceil",
"cos",
"fabs",
"atan2",
"sinh",
"atan",
"labs",
"abs",
"tanh",
"floor",
"tan",
"cosh",
"asin",
"sin",
"acos",
};
p = sym->name;
if( p != NULL )
{ /* 01-jun-90 */
len = strlen( p );
hash = (len + NoModifyWeights[ p[0] - 'a' ]
+ NoModifyWeights[ p[len-2] - 'a' ]) & 15;
if( strcmp( NoModifyFuncs[ hash ], p ) == 0 )
{
inf = &InlineInfo;
inf->class = DefaultInfo.class | NO_MEMORY_READ | NO_MEMORY_CHANGED;
inf->code = NULL;
inf->parms = DefaultInfo.parms;
inf->returns = DefaultInfo.returns;
HW_CAsgn( inf->streturn, HW_EMPTY );
inf->save = DefaultInfo.save;
inf->objname = DefaultInfo.objname;
inf->use = 1;
return( inf );
}
}
#else
sym = sym;
#endif
return( &DefaultInfo );
}
struct aux_info *InfoLookup( SYMPTR sym )
{
char * name;
struct aux_info * inf;
struct aux_entry * ent;
name = sym->name;
inf = &DefaultInfo; /* assume default */
if( name == NULL )
return( inf ); /* 01-jun-90 */
ent = AuxLookup( name );
if( ent != NULL )
{
inf = ent->info;
}
else
{
if( sym->flags & SYM_DEFINED )
return( inf );
if( ! (sym->flags & SYM_INTRINSIC) )
{ /* 12-oct-92 */
if( memcmp( name, "_inline_", 8 ) != 0 )
return( inf );
name += 8;
}
#if _MACHINE == _PC
{
struct inline_funcs __FAR *ifunc;
ifunc = IF_Lookup( name );
if( ifunc == NULL )
return( inf );
if( HW_CEqual( ifunc->returns, HW_DX_AX ) ||
HW_CEqual( ifunc->returns, HW_DS_SI ) ||
HW_CEqual( ifunc->returns, HW_ES_DI ) ||
HW_CEqual( ifunc->returns, HW_CX_DI ) )
{
if( SizeOfArg( sym->sym_type->object ) != 4 )
return( inf );
}
inf = &InlineInfo;
inf->class = (DefaultInfo.class & FAR) | MODIFY_EXACT;
inf->code = ifunc->code;
inf->parms = ifunc->parms;
inf->returns = ifunc->returns;
if( !HW_CEqual( inf->returns, HW_AX )
&& !HW_CEqual( inf->returns, HW_EMPTY ) )
{
inf->class |= SPECIAL_RETURN;
}
HW_CAsgn( inf->streturn, HW_EMPTY );
inf->save = ifunc->save;
inf->objname = DefaultInfo.objname; /* 26-jan-93 */
inf->use = 1;
}
#endif
}
return( inf );
}
struct aux_info *FindInfo( SYM_ENTRY *sym, SYM_HANDLE sym_handle )
{
auto SYM_ENTRY sym_typedef;
struct aux_entry *ent;
TYPEPTR typ;
struct aux_info *inf;
inf = &DefaultInfo; /* assume default */
if( sym_handle == 0 )
return( inf );
SymGet( sym, sym_handle );
#if _CPU == 386
if( sym_handle == SymSTOSB || sym_handle == SymSTOSD )
{
return( &STOSBInfo );
}
if( sym_handle == SymFinally )
{ /* 28-mar-94 */
static byte_seq FinallyCode = { 1, {0xc3} };
InlineInfo = DefaultInfo;
InlineInfo.code = &FinallyCode;
return( &InlineInfo );
}
if( sym_handle == SymTryFini )
{
static hw_reg_set TryFiniParms[] =
{
HW_D( HW_EAX ),
HW_D( HW_EMPTY )
};
static byte_seq TryFiniCode =
{
6, {0x64, 0xA3, 0,0,0,0}
}; /* mov fs:0,eax */
InlineInfo = DefaultInfo;
InlineInfo.parms = TryFiniParms;
InlineInfo.code = &TryFiniCode;
return( &InlineInfo );
}
#endif
if( !( sym->flags & SYM_TEMP ) )
{ /* not an indirect func call*/
inf = InfoLookup( sym );
if( inf == &DefaultInfo )
inf = ModifyLookup( sym );
}
if( inf == &DefaultInfo )
{
typ = SkipDummyTypedef( sym->sym_type );
if( typ->decl_type == TYPE_TYPEDEF )
{
SymGet( &sym_typedef, typ->u.typedefn );
if( sym_typedef.name != NULL )
{
ent = AuxLookup( sym_typedef.name );
if( ent != NULL )
{
inf = ent->info;
}
}
}
}
#if _CPU == 386
if( ( inf->flags & AUX_FLAG_FAR16 ) ||
( sym->attrib & FLAG_FAR16 ) )
{
if( ( (sym->attrib & FLAG_LANGUAGES) == LANG_PASCAL ) ||
( inf->class & REVERSE_PARMS ) )
{
return( &Far16PascalInfo );
}
else
{
return( &Far16CdeclInfo );
}
}
#endif
return( inf );
}
int FunctionAborts( SYM_ENTRY *sym, SYM_HANDLE sym_handle ) /* 09-apr-93 */
{
struct aux_entry *ent;
if( sym_handle != 0 )
{ /* 19-apr-93 */
SymGet( sym, sym_handle );
ent = AuxLookup( SymName( sym, sym_handle ) );
if( ent != NULL )
{
if( ent->info->class & SUICIDAL )
return( 1 );
}
}
return( 0 );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -