cgbkmain.c

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

C
1,832
字号
                        , cdtor );
    }
}


static SE* nextDirectSe(        // POSITION TO NEXT SE (DIRECT DESTRUCTION)
    SE* se,                     // - current entry
    DGRP_FLAGS flags )          // - control flags
{
    if( flags & DGRP_TEMPS ) {
        se = FstabPrecedes( se );
    } else {
        se = FstabPrevious( se );
    }
    return se;
}


static DGRP_FLAGS emitXstBeg(   // IF REQ'D, EMIT START DTOR-OF-CTOR CODE
    FN_CTL* fctl,               // - file information
    DGRP_FLAGS flags )
{
    #define EMIT_MASK ( DGRP_CTOR       \
                      | DGRP_CTOR_BEG )
    #define EMIT_REQD ( DGRP_CTOR )

    if( EMIT_REQD == ( flags & EMIT_MASK ) ) {
        CgCtorTestTempsRegister( fctl );
        flags |= DGRP_CTOR_BEG;
    }
    return flags;

    #undef EMIT_MASK
    #undef EMIT_REQD
}


#if 0
static DGRP_FLAGS emitXstEnd(   // IF REQ'D, EMIT END DTOR-OF-CTOR CODE
    FN_CTL* fctl,               // - file information
    DGRP_FLAGS flags )
{
    #define EMIT_MASK ( DGRP_CTOR       \
                      | DGRP_XST        \
                      | DGRP_CTOR_BEG   \
                      | DGRP_CTOR_END )
    #define EMIT_REQD ( DGRP_CTOR       \
                      | DGRP_XST        \
                      | DGRP_CTOR_BEG )

    if( EMIT_REQD == ( flags & EMIT_MASK ) ) {
        CgCtorTestTempsDeregister( fctl );
        flags |= DGRP_CTOR_END;
    }
    return flags;

    #undef EMIT_MASK
    #undef EMIT_REQD
}
#endif


static DGRP_FLAGS emitTryedPosn // EMIT POSN AFTER POPPING TRY
    ( SE* try_se                // - the position
    , FN_CTL* fctl              // - file information
    , DGRP_FLAGS flags )        // - flags
{
    if( flags & DGRP_TRY_EMIT ) {
        FstabEmitStateVarExpr( try_se, fctl );
        flags &= ~ DGRP_TRY_EMIT;
    }
    return flags;
}


static void cgDtorTabCall(      // DESTRUCT UP TO ENTRY (TABULAR)
    SE* start,                  // - starting entry
    SE* bound )                 // - bounding entry
{
    bound = SeSetSvPosition( bound );
    if( bound == NULL ) {
        if( NULL != SeSetSvPosition( start ) ) {
            CgDtorAll();
        }
    } else {
        CgDtorSe( bound );
    }
}


static unsigned cgDestructGroup(// DESTRUCT UP TO STATE ENTRY
    FN_CTL* fctl,               // - file information
    SE* start,                  // - starting state entry
    SE* bound,                  // - bounding state entry
    DGRP_FLAGS flags )          // - control flags
{
    SE* se;                     // - state entry in state table
    SE* try_se;                 // - position preceding last try
    unsigned cdtor;             // - current CDTOR parameter
    label_handle virt_label;    // - label for virtual by-pass test
    unsigned destructions;      // - # destructions
    COND_LABEL* lab_ring;       // - ring hdr. for conditional labels

    lab_ring = NULL;
    destructions = 0;
    cdtor = DTOR_NULL;
    try_se = NULL;
    switch( fctl->dtor_method ) {
      case DTM_DIRECT_TABLE :
        flags |= DGRP_LIVE | DGRP_XST;
        break;
      default :
        flags |= DGRP_LIVE;
        break;
    }
    for( se = start; se != NULL && se != bound; ) {
        if( flags & DGRP_DIRECT ) {
            if( CondLabelEmit( &lab_ring, se ) ) {
                flags |= DGRP_LIVE;
            }
        }
        if( 0 == ( flags & DGRP_LIVE ) ) {
            se = nextDirectSe( se, flags );
            continue;
        }
        switch( se->base.se_type ) {
          case DTC_SYM_AUTO :
            if( flags & DGRP_DIRECT ) {
                flags = emitXstBeg( fctl, flags );
                FstabSetDtorState( se, fctl );
                CgDone( CgDestructSymOffset( fctl
                                           , se->sym_auto.dtor
                                           , se->sym_auto.sym
                                           , 0
                                           , cdtor )
                      , T_POINTER );
            } else {
                ++ destructions;
                flags |= DGRP_TAB_CALL;
            }
            flags &= ~ DGRP_TRY_EMIT;
            se = nextDirectSe( se, flags );
            continue;
          case DTC_TEST_FLAG :
            if( flags & DGRP_DIRECT ) {
                COND_INFO cond;             // - conditional information
                label_handle lab;           // - conditional label
                cg_name expr;               // - expression being generated
                flags = emitXstBeg( fctl, flags );
                lab = CondLabelAdd( &lab_ring, se->test_flag.se_true );
                CondInfoSetup( se->test_flag.index, &cond, fctl );
                expr = CgSymbolPlusOffset( cond.sym, cond.offset );
                expr = CgFetchType( expr, T_UINT_1 );
                expr = CGBinary( O_AND, expr, CgOffset( cond.mask ), T_UINT_1 );
                CgControl( O_IF_TRUE, expr, T_UINT_1, lab );
                lab = CondLabelAdd( &lab_ring, se->test_flag.se_false );
                CGControl( O_GOTO, NULL, lab );
                flags &= ~ DGRP_LIVE;
            }
            se = nextDirectSe( se, flags );
            continue;
          case DTC_CTOR_TEST :
            se = nextDirectSe( se, flags );
            if( se == bound ) break;
            se = nextDirectSe( se, flags );
            continue;
          case DTC_SET_SV :
            if( flags & DGRP_DIRECT ) {
                label_handle lab;           // - conditional label
                flags = emitXstBeg( fctl, flags );
                lab = CondLabelAdd( &lab_ring, se->set_sv.se );
                CGControl( O_GOTO, NULL, lab );
                flags &= ~ DGRP_LIVE;
                if( flags & DGRP_TEMPS ) {
                    se = nextDirectSe( se, flags );
                } else {
                    se = CondLabelNext( &lab_ring, se->set_sv.se );
                }
            } else {
                if( flags & DGRP_TEMPS ) {
                    se = nextDirectSe( se, flags );
                } else {
                    se = se->set_sv.se;
                }
            }
            continue;
          case DTC_DLT_1 :
          case DTC_DLT_2 :
          case DTC_DLT_1_ARRAY :
          case DTC_DLT_2_ARRAY :
          case DTC_FN_EXC :
          case DTC_ARRAY_INIT :
            se = nextDirectSe( se, flags );
            continue;
          case DTC_TRY :
            se = FstabPrevious( se );
            try_se = se;
            flags |= DGRP_TRY_EMIT;
            continue;
          case DTC_CATCH :
            if( flags & DGRP_DIRECT ) {
                RT_DEF def;                 // - call definition
                flags = emitXstBeg( fctl, flags );
                flags = emitTryedPosn( try_se, fctl, flags );
                CgRtCallInit( &def, RTF_CATCH_END );
              #if _CPU == _AXP
                CgRtParamAddrSym( &def, FstabExcRw() );
              #endif
                CgRtCallExecDone( &def );
            } else {
                ++ destructions;
                flags |= DGRP_TAB_CALL;
            }
            se = se->catch_blk.try_blk;
            continue;
          case DTC_COMP_VBASE :
            if( flags & DGRP_DIRECT ) {
                if( ! fctl->ctor_complete ) {
                    if( flags & DGRP_COMPS ) {
                        flags = emitTryedPosn( try_se, fctl, flags );
                        if( ! ( flags & DGRP_VTEST ) ) {
                            cg_name expr;       // - expression
                            cg_type type;       // - expression type
                            type = CgExprType( fctl->cdtor_sym->sym_type );
                            expr = CGBinary( O_AND
                                           , CgFetchSym( fctl->cdtor_sym )
                                           , CgOffset( DTOR_COMPONENT )
                                           , type );
                            virt_label = BENewLabel();
                            CgControl( O_IF_TRUE, expr, type, virt_label );
                            flags |= DGRP_VTEST;
                        }
                        flags = emitXstBeg( fctl, flags );
                        emitDtorComponent( fctl, se, DTOR_COMPONENT );
                    }
                }
            }
            se = nextDirectSe( se, flags );
            continue;
          case DTC_ACTUAL_VBASE :
          case DTC_ACTUAL_DBASE :
          case DTC_COMP_DBASE :
            if( flags & DGRP_DIRECT ) {
                if( flags & DGRP_COMPS ) {
                    flags = emitXstBeg( fctl, flags );
                    flags = emitTryedPosn( try_se, fctl, flags );
                    emitDtorComponent( fctl, se, DTOR_COMPONENT );
                }
            }
            se = nextDirectSe( se, flags );
            continue;
          case DTC_COMP_MEMB :
            if( flags & DGRP_DIRECT ) {
                if( flags & DGRP_COMPS ) {
                    flags = emitXstBeg( fctl, flags );
                    flags = emitTryedPosn( try_se, fctl, flags );
                    emitDtorComponent( fctl, se, DTOR_NULL );
                }
            }
            se = nextDirectSe( se, flags );
            continue;
          DbgDefault( "CgDestructGroup -- bad DTC code" );
        }
        break;
    }
    if( flags & DGRP_DIRECT ) {
        CondLabelEmit( &lab_ring, se );
        flags = emitTryedPosn( try_se, fctl, flags );
        if( flags & DGRP_VTEST ) {
            CGControl( O_LABEL, NULL, virt_label );
            BEFiniLabel( virt_label );
        }
        CondLabelsEmit( &lab_ring );
    } else {
        if( ! ( flags & DGRP_COUNT ) ) {
            if( flags & DGRP_TAB_CALL ) {
                flags = emitXstBeg( fctl, flags );
                cgDtorTabCall( start, bound );
            }
            flags = emitTryedPosn( try_se, fctl, flags );
        }
    }
    if( ! ( flags & DGRP_COUNT ) ) {
        FstabMarkedPosnSet( bound );
        if( 0 == destructions
         && bound != start ) {
            FstabEmitStateVarExpr( bound, fctl );
        }
    }
    return destructions;
}



static void cgDestructStab(     // DESTRUCT STATE TABLE UP TO STATE ENTRY
    SE* bound,                  // - bounding state entry
    FN_CTL* fctl,               // - function information
    SE* start,                  // - starting state entry
    DGRP_FLAGS flags )          // - controlling flags
{
    int count;                  // - # of destructions

    switch( fctl->dtor_method ) {
      default :
        count = cgDestructGroup( fctl, start, bound, flags | DGRP_COUNT );
        if( count >= 2 ) {
            count = cgDestructGroup( fctl, start, bound, flags );
            break;
        }
        // drops thru
      case DTM_DIRECT :
      case DTM_DIRECT_TABLE :
      case DTM_DIRECT_SMALL :
        cgDestructGroup( fctl, start, bound, flags | DGRP_DIRECT );
        break;
    }
    FstabSetSvSe( bound );
}


static void cgDestruct(         // DESTRUCT UP TO STATE ENTRY
    SE* bound,                  // - state entry
    FN_CTL* fctl )              // - function information
{
    cgDestructStab( bound, fctl, FstabActualPosn(), 0 );
}


static SE* buildObjectSe        // BUILD SUBOBJ STATE ENTRY
    ( CDOPT_ITER* iter          // - object iterator
    , unsigned object_kind )    // - kind of object
{
    SE* se;                     // - current state entry
    TYPE type;                  // - type of object
    TYPE array_type;            // - array type

    se = SeAlloc( DTC_SUBOBJ );
    se->subobj.original = CDoptIterOffsetComp( iter );
    se->subobj.offset = CDoptIterOffsetExact( iter );
    se->subobj.kind = object_kind;
    type = CDoptIterType( iter );
    array_type = ArrayType( type );
    if( NULL == array_type ) {
        se->subobj.type = StructType( type );
        se->subobj.dtor = CDoptIterFunction( iter );
    } else {
        se->subobj.type = array_type;
        se->subobj.dtor = RoDtorFindType( type );
    }
    return se;
}


static STAB_OBJ* buildObjectStateTable( // BUILD STATE TABLE FOR OBJECT
    TYPE type )                 // - type of object
{
    STAB_OBJ* curr;             // - current object ptr
    STAB_OBJ* obj;              // - object ptr for type
    CD_DESCR *dtinfo;           // - descriptive information
    CDOPT_ITER* iter;           // - iterator for components
    TITER comp_type;            // - type of component
    SE* se;                     // - current state entry

    type = StructType( type );
    if( ! TypeRequiresDtoring( type ) ) {
        obj = NULL;
    } else {

⌨️ 快捷键说明

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