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