datainit.c

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

C
2,028
字号

    if( ! currInit->dtor_done ) {
        _dumpDtor( "emitDtorInitSymbol -- dtor for symbol\n" );
        sym = dtorableObjectInitSymbol();
        currInit->dtor_done = 1;
        _dumpDtorSymbol( sym );
        PtdInitSymEnd( NULL, sym );
        if( SymIsAutomatic( sym ) ) {
            IcEmitDtorAutoSym( sym );
        } else {
            IcEmitDtorStaticSym( sym );
        }
    }
}

static void dtorableObjectEnd(  // EMIT COMPLETION FOR DTORABLE OBJECT IF REQ'D
    INITIALIZE_INFO* info )     // - info on current entry
{
    TYPE type;                  // - NULL or type of dtorable element

    _dumpDtorPtr( "dtorableObjectEnd( %x )\n", info );
    type = dtorableObjectType( info );
    if( type != NULL ) {
        dataInitCodeFileOpen( TRUE );
        DataDtorObjPop( NULL );
        if( info->entry == DE_ROOT_TYPE ) {
            emitDtorInitSymbol();
        }
        dataInitCodeFileClose();
    }
}

static void dataInitPopStack( void )
/**********************************/
{
    INITIALIZE_INFO *nest;

    dtorableObjectEnd( currInit->nest );
    nest = StackPop( &currInit->nest );
    _dump( "Popped " );
    _dumpInitInfo( nest );
    CarveFree( carveNEST, nest );
}

static void dataInitAbandon( void )
/*********************************/
// called when initialization is being abandoned
{
    _dump( "dataInitAbandon" );
    if( currInit->bracketed ) {
        DgInitDone();
    }
    while( currInit->nest != NULL ) {
        dataInitPopStack();
    }
    if( currInit->once_only ) {
        StaticInitFuncEnd( currInit->once_only_label );
    }

    currInit->state = DS_ABANDONED;
    currInit = currInit->prev;
}

static SYMBOL dataInitScopeOrderedNext( SYMBOL stop, SYMBOL curr )
/****************************************************************/
{
    SYMBOL prev;

    prev = curr;
    for(;;) {
        curr = ScopeOrderedNext( stop, curr );
        if( curr == NULL ) break;
        if( SymIsNextInitializableMember( &prev, curr ) ) {
            break;
        }
    }
    return( curr );
}

static SEGID_CONTROL dataInitSegIdControl( void )
/***********************************************/
{
    SEGID_CONTROL control;

    control = SI_DEFAULT;
    if( currInit->all_zero ) {
        control |= SI_ALL_ZERO;
    }
    if( currInit->emit_code ) {
        control |= SI_NEEDS_CODE;
    }
    return( control);
}

static target_size_t dataInitFieldSize( INITIALIZE_INFO *entry )
/**************************************************************/
{
    type_flag       flags;
    target_size_t   size;
    target_offset_t curr_off;
    target_offset_t next_off;
    SYMBOL          curr;
    SYMBOL          next;

    curr = entry->u.c.curr;
    curr_off = curr->u.offset;
    next = curr;
    flags = StructType( entry->type )->flag;
    if( flags & TF1_UNION ) {
        for(;;) {
            DbgAssert( next != NULL );
            next = dataInitScopeOrderedNext( entry->u.c.stop, next );
            if( next == NULL ) break;
            next_off = next->u.offset;
            if( next_off == 0 ) {
                // member of the union so quit
                next = NULL;
                break;
            }
            if( next_off != curr_off ) {
                // member of an anonymous struct
                break;
            }
        }
    } else {
        for(;;) {
            DbgAssert( next != NULL );
            next = dataInitScopeOrderedNext( entry->u.c.stop, next );
            if( next == NULL ) break;
            next_off = next->u.offset;
            if( next_off != curr_off ) {
                // next field
                break;
            }
        }
    }
    if( next == NULL ) {
        size = entry->padded_size - curr_off;
    } else {
        size = next_off - curr_off;
    }
    return( size );
}

static void dataInitComputeTarget( INITIALIZE_INFO *top )
/*******************************************************/
{
    TYPE type;

    if( top->entry != DE_BRACE ) {
        type = TypedefModifierRemoveOnly( top->type );
        if( type->id == TYP_CLASS && type->u.c.info->corrupted ) {
            top->target = DT_ERROR;
            currInit->state = DS_ERROR;
        } else if( IsCgTypeAggregate( type, FALSE ) ) {
            if( type->id == TYP_CLASS ) {
                top->target = DT_CLASS;
                top->u.c.stop = ScopeOrderedStart( type->u.c.scope );
                top->u.c.curr = dataInitScopeOrderedNext( top->u.c.stop
                                                        , NULL );
            } else if( type->id == TYP_ARRAY ) {
                top->target = DT_ARRAY;
                top->u.a.index = 0;
            } else if( type->id == TYP_BITFIELD ) {
                top->target = DT_BITFIELD;
                top->u.b.type = type->of;
                top->u.b.mask = 0;
            }
        } else {
            top->target = DT_SCALAR;
            if( ( top->previous != NULL )
              &&( top->previous->target == DT_BITFIELD ) ) {
                top->u.s.bitf = TRUE;
            } else {
                top->u.s.bitf = FALSE;
            }
        }
    }
}

static TYPE_SIG *dataInitTypeSigFind( TYPE base_type, TYPE_SIG_ACCESS access )
/****************************************************************************/
{
    TYPE_SIG    *sig;          // - type signature
    boolean     errors;        // - TRUE ==> errors occurred

    dataInitCodeFileOpen( FALSE );
    if( SymIsStaticMember( currInit->sym ) ) {
        ModuleInitResumeScoped( SymScope( currInit->sym ) );
    }
    sig = TypeSigFind( access
                     , base_type
                     , NULL
                     , &errors );
    TypeSigReferenced( sig );
    dataInitCodeFileClose();
    return( sig );
}

static TYPE arrayBaseStructType( // GET STRUCT TYPE OF ARRAY BASE TYPE
    TYPE type )                 // - array type
{
    type = ArrayBaseType( type );
    type = StructType( type );
    return type;
}

static void dtorableObjectBeg(  // EMIT START FOR DTORABLE OBJECT IF REQ'D
    INITIALIZE_INFO* info )     // - info on current entry
{
    TYPE type;                  // - NULL or type of dtorable element
    SYMBOL sym;                 // - symbol to be initialized

    _dumpDtorPtr( "dtorableObjectBeg( %x )\n", info );
    type = dtorableObjectType( info );
    if( type != NULL ) {
        dataInitCodeFileOpen( TRUE );
        sym = dtorableObjectInitSymbol();
#if 0
        if( info->entry == DE_ROOT_TYPE ) {
            CgFrontCode( IC_INIT_SYM_BEG );
        }
#endif
        dataInitTypeSigFind( type, TSA_DTOR );
        DataDtorObjPush( NULL, type, sym, info->base );
        dataInitCodeFileClose();
    }
}

static SYMBOL getCtorCalled(    // GET SCOPE-CALL TYPE FOR A CTOR
    PTREE expr )                // - expression
{
    SYMBOL ctor;                // - ctor called

    if( NodeIsBinaryOp( expr, CO_CALL_EXEC ) ) {
        expr = PTreeOpLeft( expr );
        DbgVerify( NodeIsUnaryOp( expr, CO_CALL_SETUP )
                 , "getCtorCallState -- not CO_CALL_SETUP" );
        expr = PTreeOpLeft( expr );
        DbgVerify( expr->op == PT_SYMBOL
                 , "getCtorCallState -- not PT_SYMBOL" );
        ctor = expr->u.symcg.symbol;
    } else {
        ctor = NULL;
    }
    return ctor;
}


static PTREE emitDtorInitExpr(  // EMIT DTOR MARKING FOR AN EXPRESSION
    PTREE expr )                // - initialization expression
{
    SYMBOL sym;                 // - symbol to be initialized
    PTREE done;                 // - NULL or CO_DONE node

    if( ! currInit->dtor_done ) {
        _dumpDtor( "emitDtorInitExpr -- dtor for symbol\n" );
        sym = dtorableObjectInitSymbol();
        currInit->dtor_done = 1;
        _dumpDtorSymbol( sym );
        if( NodeIsUnaryOp( expr, CO_EXPR_DONE ) ) {
            done = expr;
            expr = expr->u.subtree[0];
        } else {
            done = NULL;
        }
        if( currInit->nest->entry == DE_ROOT_TYPE ) {
            // the following code comes out ahead of the expression; it should
            // be made a side effect if we attempt to optimize statement scopes
            SYMBOL ctor = getCtorCalled( expr );
            if( TypeReallyDtorable( sym->sym_type ) ) {
                if( SymIsAutomatic( sym ) ) {
                    expr = PtdCtoredScopeType( expr, ctor, sym->sym_type );
                } else {
                    expr = PtdScopeCall( expr, ctor );
                }
            } else {
                expr = PtdScopeCall( expr, ctor );
            }
            // end of scope-call optimization
            expr = PtdInitSymEnd( expr, sym );
        }
        expr = NodeDtorExpr( expr, sym );
        if( done != NULL ) {
            done->u.subtree[0] = expr;
            expr = done;
        }
    }
    return expr;
}

static PTREE dtorableObjectCtored(// EMIT INDEX OF DTORABLE OBJECT, IF REQ'D
    INITIALIZE_INFO* curr,      // - info on current entry
    PTREE expr,                 // - expression to be emitted
    boolean index_updated )     // - TRUE ==> index has been updated
{
    TYPE type;                  // - NULL or type of dtorable element
    INITIALIZE_INFO* info;      // - info on previous entry
    INITIALIZE_INFO* prev;      // - used in searching previous entries

    _dumpDtorPtr( "dtorableObjectCtored( %x )\n", curr );
    info = curr->previous;
    if( info == NULL ) {
        type = dtorableObjectType( curr );
        if( type != NULL ) {
            dataInitCodeFileOpen( TRUE );
            if( expr == NULL ) {
                emitDtorInitSymbol();
            } else {
                expr = emitDtorInitExpr( expr );
            }
            dataInitCodeFileClose();
        }
    } else {
        type = dtorableObjectType( info );
        if( type != NULL ) {
            if( info->target == DT_ARRAY ) {
                unsigned index;
                TYPE artype;
                TYPE eltype;
                eltype = arrayBaseStructType( info->type );
                index = info->u.a.index;
                for( prev = info; ; ) {
                    prev = prev->previous;
                    if( prev == NULL ) break;
                    if( prev->target != DT_ARRAY ) break;
                    artype = ArrayType( prev->type );
                    if( eltype != arrayBaseStructType( artype ) ) break;
                    index += prev->u.a.index * artype->u.a.array_size;
                }
                if( index_updated ) {
                    -- index;
                }
                dataInitCodeFileOpen( TRUE );
                _dumpDtorInt( "dtorableObjectCtored -- index %x\n", index );
                expr = DataDtorCompArrEl( expr, index );
                dataInitCodeFileClose();
            } else {
                for( prev = curr
                   ; prev != NULL && prev->type == curr->type
                   ; prev = prev->previous );
                if( prev != NULL ) {
                    dataInitCodeFileOpen( TRUE );
                    _dumpDtorInt( "dtorableObjectCtored -- class offset %x\n"
                                , info->offset );
                    expr = DataDtorCompClass( expr, info->offset, DTC_COMP_MEMB );
                    dataInitCodeFileClose();
                }
            }
        }
    }
    return expr;
}

static void dataInitPushStack( INITIALIZE_ENTRY entry, INITIALIZE_INFO *prev )
/****************************************************************************/
// allocate and push a stack item
// initialize the stack item based on the entry
{
    target_size_t size;
    INITIALIZE_INFO *newtop;

    newtop = StackCarveAlloc( carveNEST, &currInit->nest );
    newtop->entry = entry;
    newtop->previous = prev;
    newtop->offset = 0;
    switch( entry ) {
    case DE_BRACE:
        newtop->type = NULL;
        newtop->base = 0;
        newtop->mem_size = 0;
        newtop->padded_size = 0;
        break;
    case DE_ROOT_TYPE:
        newtop->type = currInit->sym_type;
        dataInitComputeTarget( newtop );
        size = CgMemorySize( currInit->sym_type );
        newtop->mem_size = size;
        newtop->padded_size = size;
        newtop->base = 0;
        break;
    case DE_TYPE:
        if( prev->entry == DE_ROOT_TYPE ) {
            // just propagate root info for first push of aggregate
            newtop->type = prev->type;
            newtop->target = prev->target;
            newtop->u = prev->u;
            newtop->mem_size = prev->mem_size;
            newtop->padded_size = prev->padded_size;
        } else {
            if( prev->target == DT_CLASS ) {
                newtop->type = prev->u.c.curr->sym_type;
                dataInitComputeTarget( newtop );
                size = CgMemorySize( newtop->type );
                newtop->mem_size = size;
                newtop->padded_size = dataInitFieldSize( prev );
            } else {
                newtop->type = TypedefModifierRemoveOnly( prev->type )->of;
                dataInitComputeTarget( newtop );
                size = CgMemorySize( newtop->type );
                newtop->mem_size = size;
                newtop->padded_size = size;
            }
        }
        newtop->base = prev->base + prev->offset;
        break;

⌨️ 快捷键说明

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