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 + -
显示快捷键?