label.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,084 行 · 第 1/3 页
C
1,084 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "plusplus.h"
#include "fnbody.h"
#include "carve.h"
#include "cgfront.h"
#include "errdefns.h"
#include "ring.h"
#include "codegen.h"
#include "vstk.h"
#include "initdefs.h"
#include "pcheader.h"
typedef struct blk_init BLK_INIT;
struct blk_init { // BLK_INIT -- describes blocks for init. dcls
BLK_INIT *next; // - next at this level (in a ring)
BLK_INIT *containing; // - containing (enclosing) block
BLK_INIT *contains; // - ring of contained blocks
SCOPE scope; // - scope for block
SYMBOL first_init; // - first initialized symbol in block
SYMBOL sym; // - last symbol defined
SYMBOL sym_containing; // - last symbol defined for containing block
SYMBOL sym_dtored; // - last symbol DTORed
SYMBOL sym_dtored_containing;//- last symbol DTORed in containing block
SYMBOL dcled_dtored; // - last non-temporary DTORed
unsigned var_no; // - initialization no. for self
unsigned var_no_containing; // - initialization no. for containing block
void *try_id; // - id of try, when catch block
CGFILE_INS open_ins; // - location of IC_BLOCK_OPEN, IC_BLOCK_DEAD
TOKEN_LOCN locn; // - location of definition
LAB_POSN switch_posn; // - position at switch/try statement
unsigned open_zap : 1; // - need to zap IC_BLOCK_OPEN
unsigned dead_zap : 1; // - need to zap IC_BLOCK_DEAD
unsigned try_blk : 1; // - is a try block
unsigned catch_blk : 1; // - is a catch block
unsigned free : 1; // used for precompiled headers
};
static BLK_INIT *block_init_hdr;// - header for current block
static BLK_INIT block_init_mod; // - block initialization for module
static CGFILE_INS ins_temp; // - zapped to IC_EXPR_TEMP
// carving control
static carve_t carveLAB_DEF; // - LAB_DEF
static carve_t carveLAB_REF; // - LAB_REF
static carve_t carveBLK_INIT; // - BLK_INIT
typedef struct // COND_BLK -- conditional block
{ CGFILE_INS ins_true; // - zapped to IC_SET_TRUE
CGFILE_INS ins_false; // - zapped to IC_SET_FALSE
SYMBOL sym_dtored; // - last DTOR'ed symbol at start of block
unsigned has_false :1; // - TRUE ==> has false part (?:)
} COND_BLK;
static VSTK_CTL stack_cond; // stack of conditionals
static SYMBOL expr_dtor_bound; // last symbol requiring DTOR in block
static unsigned expr_dtor_depth;// depth of conditional DTORing
static struct {
unsigned has_setjmp : 1; // TRUE ==> setjmp in expression
unsigned has_newctor: 1; // TRUE ==> has a new-ctor
} labelFlags;
static SYMBOL blkDtorSymbol( // GET LAST DTORABLE SYMBOL FOR A BLOCK
BLK_INIT* blk ) // - initialization block
{
SYMBOL dtor_sym; // - the dtorable symbol
dtor_sym = blk->sym_dtored;
if( dtor_sym == NULL ) {
dtor_sym = blk->sym_dtored_containing;
}
return dtor_sym;
}
static SYMBOL blkDcledSymbol( // GET LAST DTORABLE DCL'ED SYMBOL FOR A BLOCK
BLK_INIT* blk ) // - initialization block
{
SYMBOL dtor_sym; // - the dtorable symbol
dtor_sym = blk->dcled_dtored;
if( dtor_sym == NULL ) {
dtor_sym = blk->sym_dtored_containing;
}
return dtor_sym;
}
static BLK_INIT *labelFindBlk( // FIND INITIALIZATION BLOCK FOR SCOPE
SCOPE scope ) // - search scope
{
BLK_INIT *curr; // - block for current scope
BLK_INIT *containing; // - block containing current scope
BLK_INIT **container; // - Addr( ring( contained blocks ) )
BLK_INIT *cont; // - current block in contained ring
BLK_INIT *next; // - next block in contained ring
BLK_INIT *last; // - last block in contained ring
containing = NULL;
container = &block_init_hdr;
for( ; ; ) {
// curr = RingLookup( *container, &labelBlockEncloses, scope );
curr = NULL;
RingIterBeg( *container, next ) {
if( ScopeEnclosed( next->scope, scope ) ) {
curr = next;
break;
}
} RingIterEnd( next );
if( curr == NULL ) {
curr = CarveAlloc( carveBLK_INIT );
curr->scope = scope;
curr->contains = NULL;
curr->containing = containing;
if( containing == NULL ) {
curr->var_no_containing = 0;
curr->sym_containing = NULL;
curr->sym_dtored_containing = NULL;
curr->dcled_dtored = NULL;
} else {
curr->var_no_containing = containing->var_no;
curr->sym_containing = containing->sym;
curr->sym_dtored_containing = blkDcledSymbol( containing );
curr->dcled_dtored = containing->dcled_dtored;
}
curr->var_no = 0;
curr->first_init = NULL;
curr->sym = NULL;
curr->sym_dtored = NULL;
curr->open_zap = FALSE;
curr->dead_zap = FALSE;
curr->try_blk = FALSE;
curr->catch_blk = FALSE;
curr->free = FALSE;
curr->locn.src_file = NULL;
curr->try_id = NULL;
curr->switch_posn.scope = NULL;
curr->switch_posn.sym = NULL;
curr->switch_posn.var_no = 0;
last = *container;
if( last != NULL ) {
next = last->next;
do{
cont = next;
next = cont->next;
if( ScopeEnclosed( scope, cont->scope ) ) {
RingPrune( container, cont );
RingAppend( &curr->contains, cont );
cont->containing = curr;
}
}while( cont != last );
}
RingAppend( container, curr );
break;
}
if( curr->scope == scope ) {
break;
}
containing = curr;
container = &curr->contains;
}
return( curr );
}
static SYMBOL scopeDtorSymbol( // GET LAST DTORABLE SYMBOL FOR A SCOPE
SCOPE scope )
{
return blkDtorSymbol( labelFindBlk( scope ) );
}
static SYMBOL scopeDcledSymbol( // GET LAST DCL'ED DTORABLE SYMBOL FOR A SCOPE
SCOPE scope )
{
return blkDcledSymbol( labelFindBlk( scope ) );
}
static SYMBOL currDtorSymbol( // GET LAST DTORABLE SYMBOL FOR CurrScope
void )
{
return scopeDtorSymbol( GetCurrScope() );
}
static SYMBOL currDcledSymbol( // GET LAST DTORABLE DCL'ED SYMBOL, CurrScope
void )
{
return scopeDcledSymbol( GetCurrScope() );
}
static SCOPE dtorScope( // FIND SIGNIFICANT SCOPE FOR DTOR'ING
BLK_INIT *blk ) // - starting initialization block
{
SCOPE scope; // - significant scope
for( ; ; blk = blk->containing ) {
if( blk == NULL ) {
scope = NULL;
break;
}
if( blk->catch_blk ) {
scope = blk->scope;
break;
}
if( blk->dcled_dtored != blk->sym_dtored_containing ) {
scope = blk->scope;
break;
}
}
return scope;
}
static boolean labelMarkDtorSym(// MARK A SYMBOL FOR DTORing
BLK_INIT *blk, // - current initialization block
SYMBOL sym ) // - symbol
{
boolean retn; // - TRUE ==> requires DTOR
SYMBOL dtor; // - DTOR for symbol
if( SymRequiresDtoring( sym ) ) {
if( TypeTruncByMemModel( sym->sym_type ) ) {
CErr1( ERR_DTOR_OBJ_MEM_MODEL );
}
if( TypeExactDtorable( sym->sym_type ) ) {
dtor = RoDtorFind( sym );
dtor->flag |= SF_ADDR_TAKEN;
if( ! SymIsModuleDtorable( sym ) ) {
blk->sym_dtored = sym;
blk->scope->dtor_reqd = TRUE;
ScopeKeep( blk->scope );
}
retn = TRUE;
} else {
retn = FALSE;
}
} else {
retn = FALSE;
}
return retn;
}
void LabelDeclInited( // SIGNAL NEXT INITIALIZATION IN BLOCK
SYMBOL sym ) // - symbol initialized
{
BLK_INIT *blk; // - current initialization block
if( SymRequiresDtoring( sym ) && ! SymRequiresCtoring( sym ) ) {
GetCurrScope()->dtor_naked = TRUE;
}
blk = labelFindBlk( SymScope( sym ) );
if( SymIsInitialized( sym ) ) {
blk->sym = sym;
++blk->var_no;
if( blk->first_init == NULL ) {
blk->first_init = sym;
}
}
if( SymIsAutomatic( sym ) ) {
if( labelMarkDtorSym( blk, sym ) ) {
blk->dcled_dtored = sym;
}
}
}
void LabelDeclInitedFileScope( // SIGNAL NEXT INITIALIZATION IN FILE SCOPE
SYMBOL sym ) // - symbol requiring DTORing
{
if( block_init_mod.scope == NULL ) {
block_init_mod.scope = ModuleInitScope();
}
block_init_mod.sym = sym;
++block_init_mod.var_no;
if( block_init_mod.first_init == NULL ) {
block_init_mod.first_init = sym;
}
labelMarkDtorSym( &block_init_mod, sym );
}
static void labelCurrPosn( // SET LABEL POSITION IN CURRENT SCOPE
LAB_POSN *posn ) // - current position
{
BLK_INIT *blk; // - current initialization block
ScopeKeep( GetCurrScope() );
blk = labelFindBlk( GetCurrScope() );
posn->sym = blkDcledSymbol( blk );
posn->scope = blk->scope;
posn->var_no = blk->var_no;
}
LAB_DEF *LabelAllocLabDef( // ALLOCATE A LABEL DEFINITION
void )
{
LAB_DEF *def; // - new label definition
def = CarveAlloc( carveLAB_DEF );
labelCurrPosn( &def->posn );
def->forward = NULL;
SrcFileGetTokenLocn( &def->locn );
return( def );
}
LAB_REF *LabelAllocLabRef( // ALLOCATE A LABEL REFERENCE
LAB_DEF *def ) // - definition for label
{
LAB_REF *ref; // - new label reference
ref = CarveAlloc( carveLAB_REF );
ref->defn = def;
ref->next = NULL;
ref->ins_exit.block = 0;
ref->ins_exit.offset = 0;
ref->ins_enter.block = 0;
ref->ins_enter.offset = 0;
labelCurrPosn( &ref->posn );
return( ref );
}
static BLK_INIT *findCommonBlk( // FIND BLK_INIT FOR COMMON SCOPE
SCOPE src, // - a scope
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?