Beispiel #1
0
unsigned StaticInitFuncBeg(     // START INITIALIZATION OF STATIC IN FUNCTION
    void )
{
    CGLABEL init_label;         // - label #
    INIT_VAR *init_var;

    CgFrontStatInit();
    init_var = FunctionBodyGetInit( NULL );
    if( init_var->var == NULL ) {
        init_var->var = staticInitFuncVar();
    } else {
        init_var->mask <<= 1;
        if( init_var->mask >= 0x100 ) {
            ++init_var->var->sym_type->u.a.array_size;
            init_var->mask = 1;
        }
    }
    if( CompFlags.bm_switch_used ) {
        SYMBOL rtf;
        rtf = RunTimeCallSymbol( RTF_STATIC_INIT );
        CgFrontSymbol( rtf );
        CgSetType( GetBasicType( TYP_SINT ) );
        CgFrontCodePtr( IC_CALL_SETUP, rtf );
        CgSetType( GetBasicType( TYP_SINT ) );
        CgFrontCodeUint( IC_LEAF_CONST_INT, init_var->mask );
        CgFrontCode( IC_CALL_PARM );
        moduleInitVar( init_var->var, false );
        CgFrontCode( IC_CALL_PARM );
        CgFrontCode( IC_CALL_EXEC );
    } else {
        moduleInitVar( init_var->var, true );
        CgFrontCodeUint( IC_OPR_UNARY, CO_FETCH );
        CgFrontCodeUint( IC_LEAF_CONST_INT, init_var->mask );
        CgFrontCodeUint( IC_OPR_BINARY, CO_AND );
    }
    CgFrontCodeUint( IC_LEAF_CONST_INT, 0 );
    CgFrontCodeUint( IC_OPR_BINARY, CO_NE );
    init_label = CgFrontLabelCs();
    CgFrontGotoNear( IC_LABEL_CS, O_IF_TRUE, init_label );
    if( !CompFlags.bm_switch_used ) {
        moduleInitVar( init_var->var, true );
        CgFrontCodeUint( IC_LEAF_CONST_INT, init_var->mask );
        CgFrontCodeUint( IC_OPR_BINARY, CO_OR_EQUAL );
        CgFrontCode( IC_EXPR_DONE );
    }
    return( init_label );
}
Beispiel #2
0
// This is kluge because of the lack of a code-generation interface to
// signal a virtual function reference.
//
// This is accomplished by putting out a fake virtual call in dead-code.
//
void VfnReference(              // EMIT VIRTUAL FUNCTION REFERENCE
    SYMBOL vfun )               // - a virtual function
{
    CGLABEL around;             // - label for jump around
    PTREE fake;                 // - fake call expression

    around = CgFrontLabelCs();
    CgFrontGotoNear( IC_LABEL_CS, O_GOTO, around );
    fake = NodeAssignTemporary( MakePointerTo( vfun->sym_type )
                              , NodeMakeCallee( vfun ) );
    fake = NodeRvalue( fake );
    fake = NodeUnaryCopy( CO_CALL_SETUP_IND, fake );
    fake = VfnDecorateCall( fake, vfun );
    fake = NodeBinary( CO_CALL_EXEC_IND, fake, NULL );
    fake->type = SymFuncReturnType( vfun );
    fake->flags |= PTF_MEANINGFUL | PTF_SIDE_EFF;
    fake = NodeDone( fake );
    IcEmitExpr( fake );
    CgFrontLabdefCs( around );
    CgFrontLabfreeCs( 1 );
}