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 + -
显示快捷键?