label.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,084 行 · 第 1/3 页

C
1,084
字号
    SCOPE tgt )                 // - a scope
{
    for( ; ! ScopeEnclosed( src, tgt ); src = src->enclosing );
    ScopeKeep( src );
    return( labelFindBlk( src ) );
}

static void bypassError(        // BYPASS OF INIT/CTOR DETECTED!
    SYMBOL var )                // - symbol by-passed
{
    if( SymRequiresCtoring( var ) ) {
        CErr2p( ERR_CTOR_BYPASSED, var );
    } else {
        CErr2p( ANSI_INIT_BYPASSED, var );
    }
}


static boolean popsTryCatch(    // CHECK IF JUMP POPS A TRY/CATCH BLOCK
    BLK_INIT* src,              // - source block
    BLK_INIT* tgt )             // - target block
{
    boolean popped;             // - TRUE ==> catch was popped

    popped = FALSE;
    for( ; tgt != src; src = src->containing ) {
        if( src->try_blk || src->catch_blk ) {
            popped = TRUE;
            break;
        }
    }
    return popped;
}


static boolean popsCatch(       // CHECK IF JUMP POPS A CATCH BLOCK
    BLK_INIT* src,              // - source block
    BLK_INIT* tgt )             // - target block
{
    boolean popped;             // - TRUE ==> catch was popped

    popped = FALSE;
    for( ; tgt != src; src = src->containing ) {
        if( src->catch_blk ) {
            popped = TRUE;
            break;
        }
    }
    return popped;
}


static boolean labelCheckJump(  // CHECK JUMP DOES NOT BY-PASS INITIALIZATION
    LAB_POSN *src,              // - source (goto)
    LAB_POSN *tgt,              // - target (label)
    BLK_INIT **cblk,            // - addr( common block ptr )
    SYMBOL *cvar )              // - addr( common variable )
{
    BLK_INIT *blk;              // - BLK_INIT's for label definition
    BLK_INIT *blk_com;          // - BLK_INIT's for common scope
    BLK_INIT *blk_src;          // - BLK_INIT for source of jump
    boolean retn;               // - TRUE ==> success
    unsigned src_var_no;        // - source: variable no.
    unsigned tgt_var_no;        // - target: variable no.
    SYMBOL tgt_sym;             // - target: init. symbol

    blk_src = labelFindBlk( src->scope );
    blk_com = findCommonBlk( src->scope, tgt->scope );
    tgt_sym = tgt->sym;
    tgt_var_no = tgt->var_no;
    for( blk = labelFindBlk( tgt->scope ); ; blk = blk->containing ) {
        if( blk == blk_com ) {
            src_var_no = src->var_no;
            for( blk = blk_src; ; blk = blk->containing ) {
                if( blk == blk_com ) {
                    if( src_var_no < tgt_var_no ) {
                        bypassError( blk->sym );
                        retn = FALSE;
                    } else {
                        *cblk = blk_com;
                        *cvar = tgt_sym;
                        retn = TRUE;
                    }
                    break;
                }
                src_var_no = blk->var_no_containing;
            }
            break;
        }
        if( blk->try_blk ) {
            CErr1( ERR_JUMP_INTO_TRY );
            InfMsgPtr( INF_PREVIOUS_TRY, &blk->locn );
            retn = FALSE;
            break;
        } else if( blk->catch_blk ) {
            CErr1( ERR_JUMP_INTO_CATCH );
            InfMsgPtr( INF_PREVIOUS_CATCH, &blk->locn );
            retn = FALSE;
            break;
        }
        if( tgt_var_no != 0 ) {
            bypassError( blk->first_init );
            retn = FALSE;
            break;
        }
        tgt_sym = blk->sym_containing;
        tgt_var_no = blk->var_no_containing;
    }
    return( retn );
}


// This routine is called for a label, after the label has been planted.
//
void LabelDefine(               // DEFINE A LABEL
    LAB_DEF *def )              // - label definition
{
    LAB_POSN curr;              // - current position
    BLK_INIT *com;              // - common BLK_INIT
    BLK_INIT *src;              // - goto source BLK_INIT
    BLK_INIT *tgt;              // - goto target BLK_INIT
    SYMBOL sym;                 // - common symbol
    boolean ok;                 // - label is ok
    LAB_REF *ref;               // - forward reference to label
    SYMBOL entry_sym;           // - DTORable symbol at label
    boolean set_label_state;    // - TRUE ==> set state at label

    labelCurrPosn( &curr );
    ok = labelCheckJump( &def->posn, &curr, &com, &sym );
    if( ok ) {
        set_label_state = FALSE;
        tgt = labelFindBlk( curr.scope );
        entry_sym = scopeDcledSymbol( curr.scope );
        RingIterBeg( def->forward, ref ) {
            SYMBOL label_dtor = curr.sym;
            src = labelFindBlk( ref->posn.scope );
            com = findCommonBlk( ref->posn.scope, curr.scope );
            if( blkDcledSymbol( src ) != entry_sym ) {
                label_dtor = entry_sym;
                CgFrontZapPtr( ref->ins_exit, IC_DESTRUCT_VAR, entry_sym );
            } else if( popsTryCatch( src, com ) ) {
                ScopeKeep( com->scope );
                CgFrontZapPtr( ref->ins_exit, IC_TRY_CATCH_DONE, com->scope );
            }
            if( com == tgt ) {
                if( ref->posn.sym != label_dtor ) {
                    set_label_state = TRUE;
                }
            } else {
                if( blkDtorSymbol( com ) != label_dtor ) {
                    set_label_state = TRUE;
                }
            }
        } RingIterEnd( ref );
        if( set_label_state ) {
            CgFrontCode( IC_SET_LABEL_SV );
        }
    }
    def->posn = curr;
    SrcFileGetTokenLocn( &def->locn );
}


static void checkLabelState(    // CHECK LABEL STATE SAME AS DEF'N STATE
    LAB_POSN* src,              // - source position
    LAB_POSN* tgt )             // - target position
{
    if( src->sym != tgt->sym ) {
        CgFrontCode( IC_SET_LABEL_SV );
    }
}


void LabelGotoFwd(              // CHECK A GOTO (FOREWARDS)
    LAB_REF *ref )              // - reference for goto (defined) label
{
    CgFrontCode( IC_NO_OP );    // zapped to IC_DESTRUCT
    ref->ins_exit = CgFrontLastIns();
    RingAppend( &ref->defn->forward, ref );
}


void LabelGotoBwd(              // CHECK A GOTO (BACKWARDS)
    LAB_REF *ref )              // - reference for goto (defined) label
{
    SYMBOL tgt_dtor;            // - dtorable symbol in target
    BLK_INIT *blk;              // - common BLK_INIT
    SYMBOL sym;                 // - common variable

    if( labelCheckJump( &ref->posn, &ref->defn->posn, &blk, &sym ) ) {
        tgt_dtor = ref->defn->posn.sym;
        if( tgt_dtor != currDcledSymbol() ) {
            CgFrontCodePtr( IC_DESTRUCT_VAR, tgt_dtor );
        } else {
            BLK_INIT *src_blk = labelFindBlk( GetCurrScope() );
            if( popsTryCatch( src_blk, blk ) ) {
                ScopeKeep( blk->scope );
                CgFrontCodePtr( IC_TRY_CATCH_DONE, blk->scope );
            }
        }
    }
    LabelRefFree( ref );
}


static void checkSwitchState(   // CHECK SWITCH STATE SAME AS DEF'N STATE
    SCOPE defn )                // - definition scope
{
    LAB_POSN curr;              // - current position
    BLK_INIT *sw_blk;           // - common BLK_INIT

    labelCurrPosn( &curr );
    sw_blk = labelFindBlk( defn );
    checkLabelState( &sw_blk->switch_posn, &curr );
}


void LabelSwitch(               // CHECK A CASE/DEFAULT LABEL
    SCOPE sw )                  // - scope containing switch
{
    LAB_POSN curr;              // - current position
    BLK_INIT *sw_blk;           // - common BLK_INIT
    SYMBOL sym;                 // - common variable

    labelCurrPosn( &curr );
    sw_blk = labelFindBlk( sw );
    labelCheckJump( &sw_blk->switch_posn, &curr, &sw_blk, &sym );
}


void LabelSwitchLabel(          // PROCESSING FOR A BLOCK OF SWITCH LABELS
    SCOPE defn,                 // - scope for switch
    boolean deadcode )          // - TRUE==> state is dead-code
{
    deadcode = deadcode;
    checkSwitchState( defn );
}


void LabelSwitchBeg(            // START OF A SWITCH STATEMENT
    void )
{
    BLK_INIT* blk;              // - block for switch/try

    blk = labelFindBlk( GetCurrScope() );
    labelCurrPosn( &blk->switch_posn );
}


void LabelSwitchEnd(            // COMPLETION OF A SWITCH STATEMENT
    void )
{
    CgFrontCode( IC_SWITCH_END );
}


void LabelReturn(               // RETURN STATEMENT PROCESSING
    void )
{
    if( NULL != currDtorSymbol()
     || popsCatch( labelFindBlk( GetCurrScope() )
                 , labelFindBlk( ScopeFunctionScopeInProgress() ) ) ) {
        if( FunctionBodyCtor() ) {
            CgFrontCode( IC_CTOR_COMPLETE );
        }
        CgFrontCode( IC_DESTRUCT );
    }
}


static void labelMemLoad(       // LOAD LABEL MEMORY FOR FUNCTION
    LAB_MEM *label_mem )        // - used to stack memory
{
    carveBLK_INIT = label_mem->carve;
    block_init_hdr = label_mem->blk_hdr;
}


static void labelMemSave(       // SAVE LABEL MEMORY FOR FUNCTION
    LAB_MEM *label_mem )        // - used to stack memory
{
    label_mem->carve = carveBLK_INIT;
    label_mem->blk_hdr = block_init_hdr;
}


void LabelInitFunc(             // INITIALIZE LABELS (FUNCTION)
    LAB_MEM *label_mem )        // - used to stack memory
{
    labelMemSave( label_mem );
    carveBLK_INIT = CarveCreate( sizeof( BLK_INIT ), BLOCK_BLK_INIT );
    block_init_hdr = NULL;
    labelFindBlk( ScopeFunctionScopeInProgress() );
}


void LabelSwitchFunc(           // SWITCH FUNCTION'S LABEL MEMORY
    LAB_MEM *label_mem )        // - used to stack memory
{
    LAB_MEM temp;               // - used to hold current info.

    labelMemSave( &temp );
    labelMemLoad( label_mem );
    *label_mem = temp;
}


void LabelFiniFunc(             // COMPLETION OF LABELS (FUNCTION)
    LAB_MEM *label_mem )        // - used to stack memory
{
    if( carveBLK_INIT != NULL ) {
        CarveDestroy( carveBLK_INIT );
    }
    if( label_mem != NULL ) {
        labelMemLoad( label_mem );
    }
}


// IC_BLOCK_OPEN is emitted with an operand of zero.
// When the block becomes significant, the operand is zapped with the
// address of the scope.
//
// Assumption: IC_BLOCK_OPEN never occurs at offset 0 in block 0
//
void LabelBlockOpen(            // EMIT OPENING OF CURRENT SCOPE
    boolean dead_code )         // - TRUE ==> in dead-code state
{
    BLK_INIT *blk;              // - BLK_INIT for scope

    blk = labelFindBlk( GetCurrScope() );
    if( dead_code ) {
        blk->dead_zap = TRUE;
        CgFrontCode( IC_BLOCK_DEAD );
    } else {
        blk->open_zap = TRUE;
        CgFrontCode( IC_BLOCK_OPEN );
    }
    blk->open_ins = CgFrontLastIns();
}


void LabelBlockClose(           // CLOSE CURRENT BLOCK SCOPE
    boolean dead_code )         // - TRUE ==> in dead-code state
{
    BLK_INIT *blk;              // - BLK_INIT for scope
    BLK_INIT *enclosing;        // - BLK_INIT for enclosing scope
    boolean  blk_end;           // - emit IC_BLOCK_END

    blk_end = FALSE;
    blk = labelFindBlk( GetCurrScope() );
    enclosing = blk->containing;
    if( GetCurrScope()->keep || blk->catch_blk ) {
        if( blk->open_zap ) {
            CgFrontZapPtr( blk->open_ins, IC_BLOCK_OPEN, GetCurrScope() );
            blk_end = TRUE;
        } else if( blk->dead_zap ) {
            CgFrontZapPtr( blk->open_ins, IC_BLOCK_DEAD, GetCurrScope() );
            blk_end = TRUE;
        }
        if( ! dead_code ) {
            CgFrontCodePtr( IC_BLOCK_CLOSE, GetCurrScope() );

⌨️ 快捷键说明

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