⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfeinfo.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*
*                            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 + -