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

📄 cgen2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        SrcLineCount = SrcLineNum;      /* for error msgs 14-jul-89 */
        if( tree->op.unroll_count != unroll_count ) {
            unroll_count = tree->op.unroll_count;
            BEUnrollCount( unroll_count );
        }
        if( tree->right->op.opr == OPR_FUNCTION ) {     // if start of func
            TREEPTR right;
            SYM_ENTRY sym;

             right = tree->right;
             SymGet( &sym,  right->op.func.sym_handle );
             if( ! (sym.flags & SYM_REFERENCED) ) {
                 if( (sym.attrib & FLAG_INLINE)
                  && (sym.stg_class != SC_NULL) ){
                    while( tree->right->op.opr != OPR_FUNCEND ){
                        tree = tree->left;
                    }
                    break;
                 }
            }
        }
        EmitNodes( LinearizeTree( tree->right ) );
#ifdef __SEH__
        if( tree->right->op.opr == OPR_FUNCTION ) {     // if start of func
           if( FuncNodePtr->func.flags & FUNC_USES_SEH ) {
                GenerateTryBlock( tree->left );
           }
        }
#endif
        if( tree->right->op.opr == OPR_FUNCEND ) break;
        tree = tree->left;
    }
    return( tree );
}

static void DoInLineFunction( TREEPTR tree )
{   // Push some state info and use InLineDepth for turning some stuff off
    struct func_save  save;
    ++InLineDepth;
    save.func  = CurFunc;
    save.func_handle = CurFuncHandle;
    save.funcnode    = FuncNodePtr;
    save.cglabel_handles = CGLabelHandles;
    save.labelindex = LabelIndex;
    CurFuncHandle = 0;
    FuncNodePtr = NULL;
    CGLabelHandles = NULL;
    LabelIndex = 0;
    GenOptimizedCode( tree );
    CurFunc = save.func;
    SymGet( CurFunc, save.func_handle );  // must be done before changing CurFuncHandle
    CurFuncHandle = save.func_handle;
    FuncNodePtr = save.funcnode;
    CGLabelHandles = save.cglabel_handles;
    LabelIndex = save.labelindex;
    --InLineDepth;
}

static TREEPTR FindFuncStmtTree( SYM_HANDLE sym_handle )
{
    SYMPTR      symptr;

    symptr = SymGetPtr( sym_handle );
    return( symptr->u.func.start_of_func );
}

void GenInLineFunc( SYM_HANDLE sym_handle )
{
    TREEPTR     tree;

    tree = FindFuncStmtTree(sym_handle);
    if( tree != NULL ) {
        DoInLineFunction( tree );
    }
}

bool IsInLineFunc( SYM_HANDLE sym_handle )
{
    bool        ret;
    TREEPTR     tree;
    TREEPTR     right;

    ret = FALSE;
    if( InLineDepth < MAX_INLINE_DEPTH ){
        tree = FindFuncStmtTree(sym_handle);
        if( tree != NULL ) {
           right = tree->right;
           if( !(right->op.func.flags & FUNC_INUSE) ){
               ret =  right->op.func.flags & FUNC_OK_TO_INLINE;
           }
        }
    }
    return( ret );
}

local void GenModuleCode()
{
    TREEPTR     tree;

    tree = FirstStmt;
    InLineDepth = 0;
//  InLineFuncStack = NULL;
    while( tree != NULL ) {
        tree = GenOptimizedCode( tree );
        tree = tree->left;
    }
}

static void NoCodeGenDLL()
{
    extern void FEMessage( msg_class, void * );
    FEMessage( MSG_FATAL, "Unable to load code generator DLL" );
}

void DoCompile()
{
    unsigned int /*jmp_buf*/ *old_env;
    auto jmp_buf env;
    auto cg_init_info cgi_info;

    old_env = Environment;
    if( ! setjmp( env ) ) {
        Environment = &env;
        if( BEDLLLoad( NULL ) ) {
#if _MACHINE == _PC
            BEMemInit(); // cg has a strange static var that doesn't get reset
#endif
            if( ! CompFlags.zu_switch_used )  TargetSwitches &= ~ FLOATING_SS;
            if( Toggles & TOGGLE_DUMP_CG ){
                GenSwitches |= ECHO_API_CALLS;
            }
#ifdef POSITION_INDEPENDANT
            if( CompFlags.rent ){
                GenSwitches |= POSITION_INDEPENDANT;
            }
#endif
            cgi_info = BEInit( GenSwitches, TargetSwitches, OptSize, ProcRevision );
            if( cgi_info.success ) {
#if 0
                if( cgi_info.version.revision != II_REVISION ) WrongCodeGen();
#if _CPU == 386
                if( cgi_info.version.target != II_TARG_80386 ) WrongCodeGen();
#elif _CPU == 370
                if( cgi_info.version.target != II_TARG_370 ) WrongCodeGen();
#elif _CPU == 8086
                if( cgi_info.version.target != II_TARG_8086 ) WrongCodeGen();
#elif _CPU == 0000
                if( cgi_info.version.target != II_TARG_AXP ) WrongCodeGen();
#else
#error "Undefined _CPU type"
#endif
#endif
#if _CPU == 386
                if( TargetSwitches & (P5_PROFILING|NEW_P5_PROFILING) ) {
                    FunctionProfileSegment = AddSegName( "TI", "DATA", SEGTYPE_INITFINI );
                }
#endif
                SetSegs();
                BEStart();
                EmitSegLabels();                        /* 15-mar-92 */
                if( GenSwitches & DBG_TYPES ) EmitDBType();
                EmitSyms();
                EmitCS_Strings();
                SrcLineCount = 0;
                FListSrcQue();
                EmitDataQuads();
                FreeDataQuads();
                #ifdef __SEH__
                    TryRefno = NewRefno();
                    BEDefType( TryRefno, 1, sizeof( struct try_block ) );
                    TryTableBackHandles = NULL;
                #endif
                GenModuleCode();
                FreeStrings();
                FiniSegLabels();                        /* 15-mar-92 */
                if( ErrCount != 0 ) {
                    BEAbort();
                }
                BEStop();
                FiniSegBacks();                /* 15-mar-92 */
                FreeGblVars( GlobalSym );
                FreeGblVars( SpecialSyms );     /* 05-dec-89 */
                FreeExtVars();                          /* 02-apr-92 */
                #ifdef __SEH__
                    FreeTryTableBackHandles();
                #endif
                BEFini();
                BEDLLUnload();
            }
        } else {
            NoCodeGenDLL();
        }
    }
    Environment = old_env;
}


local void EmitSyms( void )
{
    SYM_HANDLE          sym_handle;
    auto SYM_ENTRY      sym;

    for( sym_handle = GlobalSym; sym_handle; ) {
        SymGet( &sym, sym_handle );
        EmitSym( &sym, sym_handle );
        if( ( GenSwitches & DBG_LOCALS ) &&
            ( sym.sym_type->decl_type != TYPE_FUNCTION ) &&
            ( (sym.flags & SYM_TEMP) == 0 )  && /* 06-oct-93 */
            ( sym.stg_class != SC_TYPEDEF )) {
#if _CPU == 370
                if( sym.stg_class != SC_EXTERN || sym.flags & SYM_REFERENCED){
                    DBModSym( sym_handle, TY_DEFAULT );
                }
#else
                DBModSym( sym_handle, TY_DEFAULT );
#endif
        }
        sym_handle = sym.handle;
    }
}


local void EmitSym( SYMPTR sym, SYM_HANDLE sym_handle )
{
    TYPEPTR             typ;
    int                 segment;
    auto unsigned long  size;

    typ = sym->sym_type;
    if( (GenSwitches & DBG_TYPES) && (sym->stg_class == SC_TYPEDEF) ) {
        if( typ->decl_type != TYPE_TYPEDEF ) {
            DBEndName( DBBegName( sym->name, DBG_NIL_TYPE ),
                                  DBType( typ ) );
        }
    }
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    CGenType( typ );    /* create refno for ARRAY type, etc */
    if( sym->stg_class != SC_EXTERN     &&  /* if not imported */
        sym->stg_class != SC_TYPEDEF ) {
        if( ( sym->flags & SYM_FUNCTION ) == 0 ) {
            segment = sym->u.var.segment;
            if( (sym->flags & SYM_INITIALIZED) == 0 || segment == SEG_BSS){
                BESetSeg( segment );
                AlignIt( typ );
                DGLabel( FEBack( sym_handle ) );
                /* initialize all bytes to 0 */
                /* if size > 64k, have to break it into chunks of 64k */
                size = SizeOfArg( typ );
                if( segment == SEG_BSS ) {
                    DGUBytes( size );
                } else {
#if _CPU == 8086
                    while( size >= 0x10000 ) {
                        EmitZeros( 0x10000 );
                        size -= 0x10000;
                        if( size == 0 ) break;
                        if( segment != SEG_CONST && segment != SEG_DATA ) {
                            ++segment;
                            BESetSeg( segment );
                        }
                    }
#endif
                    if( size != 0 ) EmitZeros( size );
                }
            }
        }
    }
}

local int DoFuncDefn( SYM_HANDLE funcsym_handle )
{
    int         parms_reversed;
    SYM_HANDLE  sym_handle;
    int         ret_type;

    SSVar = NULL;
    CurFunc = &CurFuncSym;
    SymGet( CurFunc, funcsym_handle );
    CurFuncHandle = funcsym_handle;
#if _MACHINE == _PC
    if( ! CompFlags.zu_switch_used ) {
        if( (CurFunc->attrib & FLAG_INTERRUPT) == FLAG_INTERRUPT ){
            /* interrupt function */
            TargetSwitches |= FLOATING_SS;      /* force -zu switch on */
        } else {
            TargetSwitches &= ~ FLOATING_SS;    /* turn it back off */
        }
    }
#endif
    ret_type = CGenType( CurFunc->sym_type->object );
    if( CompFlags.returns_promoted ) {
        ret_type = FEParmType( NULL, NULL, ret_type );
    }
    CGProcDecl( funcsym_handle, ret_type );
#if _CPU == 386
    if( TargetSwitches & P5_PROFILING ) {
        char *fn_name = FEName( funcsym_handle );
        size_t len = strlen( fn_name )+1;
        segment_id old_segment;

        old_segment = BESetSeg( FunctionProfileSegment );
        FunctionProfileBlock = BENewBack( NULL );
        DGLabel( FunctionProfileBlock );
        DGInteger( 0,   T_INTEGER );
        DGInteger( -1,  T_INTEGER );
        DGInteger( 0,   T_INTEGER );
        DGInteger( 0,   T_INTEGER );
        DGBytes( len, fn_name );
        len &= 0x03;
        if( len ) {
            DGIBytes( 4 - len, 0 );
        }
        BESetSeg( old_segment );
    }
#endif
    if( GenSwitches & DBG_LOCALS ) {
        if( InLineDepth == 0 ){
            DBModSym( CurFuncHandle, TY_DEFAULT );
        }else{
            DBBegBlock();
        }
    }
    parms_reversed = 0;
    sym_handle = CurFunc->u.func.parms;
    if( sym_handle ) {
        GetCallClass( CurFuncHandle );
        if( CallClass & REVERSE_PARMS ) {                       /* 22-jan-90 */
            ParmReverse( sym_handle );
            parms_reversed = 1;
        } else {
            for( ; sym_handle; ) {
                SYMPTR      sym;

                sym = SymGetPtr( sym_handle );
                if( sym->sym_type->decl_type == TYPE_DOT_DOT_DOT ) break;
                DoParmDecl( sym, sym_handle );
                sym_handle = sym->handle;
            }
        }
    }
    CGLastParm();
    DoAutoDecl( CurFunc->u.func.locals );
#ifdef __SEH__
    if( FuncNodePtr->func.flags & FUNC_USES_SEH ) {
        CGAutoDecl( TrySymHandle, TryRefno );
        CallTryInit();                  // generate call to __TryInit
    }
#endif
    return( parms_reversed );
}

local void DoParmDecl( SYMPTR sym, SYM_HANDLE sym_handle )
{
    TYPEPTR typ;
    int     dtype;

    typ = sym->sym_type;
    while( typ->decl_type == TYPE_TYPEDEF )  typ = typ->object;
    dtype = CGenType( typ );
    CGParmDecl( sym_handle, dtype );
    if( (GenSwitches & NO_OPTIMIZATION)     /* 20-sep-88 */
#if _CPU == 386
        || ((! CompFlags.register_conventions) &&
        CompFlags.debug_info_some)
#endif
    ) {
        if( GenSwitches & DBG_LOCALS ) {
            DBLocalSym( sym_handle, TY_DEFAULT );
        }
    }
}

local void ParmReverse( SYM_HANDLE sym_handle ) /* 22-jan-90 */
{
    SYMPTR      sym;

    sym = SymGetPtr( sym_handle );
    if( sym->handle ) {
        ParmReverse( sym->handle );
        sym = SymGetPtr( sym_handle );
    }
    DoParmDecl( sym, sym_handle );
}

local void DoAutoDecl( SYM_HANDLE sym_handle )
{
    TYPEPTR             typ;
    cg_type             dtype;
    char                emit_debug_info;                /* 01-mar-91 */
    char                emit_extra_info;                /* 25-nov-91 */
    auto SYM_ENTRY      sym;

    while( sym_handle != 0 ) {
        SymGet( &sym, sym_handle );
        emit_debug_info = 0;
        emit_extra_info = 0;
        if( (GenSwitches & NO_OPTIMIZATION) )  emit_debug_info = 1;
        if( sym.stg_class == SC_STATIC ) {
            emit_debug_info = 0;
            if( (sym.flags & SYM_EMITTED) == 0 ) {
                if( sym.sym_type->decl_type != TYPE_VOID ) {
                    EmitSym( &sym, sym_handle );
                    emit_debug_info = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -