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 ); }
// 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 ); }