datainit.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,028 行 · 第 1/5 页
C
2,028 行
if( ! currInit->dtor_done ) {
_dumpDtor( "emitDtorInitSymbol -- dtor for symbol\n" );
sym = dtorableObjectInitSymbol();
currInit->dtor_done = 1;
_dumpDtorSymbol( sym );
PtdInitSymEnd( NULL, sym );
if( SymIsAutomatic( sym ) ) {
IcEmitDtorAutoSym( sym );
} else {
IcEmitDtorStaticSym( sym );
}
}
}
static void dtorableObjectEnd( // EMIT COMPLETION FOR DTORABLE OBJECT IF REQ'D
INITIALIZE_INFO* info ) // - info on current entry
{
TYPE type; // - NULL or type of dtorable element
_dumpDtorPtr( "dtorableObjectEnd( %x )\n", info );
type = dtorableObjectType( info );
if( type != NULL ) {
dataInitCodeFileOpen( TRUE );
DataDtorObjPop( NULL );
if( info->entry == DE_ROOT_TYPE ) {
emitDtorInitSymbol();
}
dataInitCodeFileClose();
}
}
static void dataInitPopStack( void )
/**********************************/
{
INITIALIZE_INFO *nest;
dtorableObjectEnd( currInit->nest );
nest = StackPop( &currInit->nest );
_dump( "Popped " );
_dumpInitInfo( nest );
CarveFree( carveNEST, nest );
}
static void dataInitAbandon( void )
/*********************************/
// called when initialization is being abandoned
{
_dump( "dataInitAbandon" );
if( currInit->bracketed ) {
DgInitDone();
}
while( currInit->nest != NULL ) {
dataInitPopStack();
}
if( currInit->once_only ) {
StaticInitFuncEnd( currInit->once_only_label );
}
currInit->state = DS_ABANDONED;
currInit = currInit->prev;
}
static SYMBOL dataInitScopeOrderedNext( SYMBOL stop, SYMBOL curr )
/****************************************************************/
{
SYMBOL prev;
prev = curr;
for(;;) {
curr = ScopeOrderedNext( stop, curr );
if( curr == NULL ) break;
if( SymIsNextInitializableMember( &prev, curr ) ) {
break;
}
}
return( curr );
}
static SEGID_CONTROL dataInitSegIdControl( void )
/***********************************************/
{
SEGID_CONTROL control;
control = SI_DEFAULT;
if( currInit->all_zero ) {
control |= SI_ALL_ZERO;
}
if( currInit->emit_code ) {
control |= SI_NEEDS_CODE;
}
return( control);
}
static target_size_t dataInitFieldSize( INITIALIZE_INFO *entry )
/**************************************************************/
{
type_flag flags;
target_size_t size;
target_offset_t curr_off;
target_offset_t next_off;
SYMBOL curr;
SYMBOL next;
curr = entry->u.c.curr;
curr_off = curr->u.offset;
next = curr;
flags = StructType( entry->type )->flag;
if( flags & TF1_UNION ) {
for(;;) {
DbgAssert( next != NULL );
next = dataInitScopeOrderedNext( entry->u.c.stop, next );
if( next == NULL ) break;
next_off = next->u.offset;
if( next_off == 0 ) {
// member of the union so quit
next = NULL;
break;
}
if( next_off != curr_off ) {
// member of an anonymous struct
break;
}
}
} else {
for(;;) {
DbgAssert( next != NULL );
next = dataInitScopeOrderedNext( entry->u.c.stop, next );
if( next == NULL ) break;
next_off = next->u.offset;
if( next_off != curr_off ) {
// next field
break;
}
}
}
if( next == NULL ) {
size = entry->padded_size - curr_off;
} else {
size = next_off - curr_off;
}
return( size );
}
static void dataInitComputeTarget( INITIALIZE_INFO *top )
/*******************************************************/
{
TYPE type;
if( top->entry != DE_BRACE ) {
type = TypedefModifierRemoveOnly( top->type );
if( type->id == TYP_CLASS && type->u.c.info->corrupted ) {
top->target = DT_ERROR;
currInit->state = DS_ERROR;
} else if( IsCgTypeAggregate( type, FALSE ) ) {
if( type->id == TYP_CLASS ) {
top->target = DT_CLASS;
top->u.c.stop = ScopeOrderedStart( type->u.c.scope );
top->u.c.curr = dataInitScopeOrderedNext( top->u.c.stop
, NULL );
} else if( type->id == TYP_ARRAY ) {
top->target = DT_ARRAY;
top->u.a.index = 0;
} else if( type->id == TYP_BITFIELD ) {
top->target = DT_BITFIELD;
top->u.b.type = type->of;
top->u.b.mask = 0;
}
} else {
top->target = DT_SCALAR;
if( ( top->previous != NULL )
&&( top->previous->target == DT_BITFIELD ) ) {
top->u.s.bitf = TRUE;
} else {
top->u.s.bitf = FALSE;
}
}
}
}
static TYPE_SIG *dataInitTypeSigFind( TYPE base_type, TYPE_SIG_ACCESS access )
/****************************************************************************/
{
TYPE_SIG *sig; // - type signature
boolean errors; // - TRUE ==> errors occurred
dataInitCodeFileOpen( FALSE );
if( SymIsStaticMember( currInit->sym ) ) {
ModuleInitResumeScoped( SymScope( currInit->sym ) );
}
sig = TypeSigFind( access
, base_type
, NULL
, &errors );
TypeSigReferenced( sig );
dataInitCodeFileClose();
return( sig );
}
static TYPE arrayBaseStructType( // GET STRUCT TYPE OF ARRAY BASE TYPE
TYPE type ) // - array type
{
type = ArrayBaseType( type );
type = StructType( type );
return type;
}
static void dtorableObjectBeg( // EMIT START FOR DTORABLE OBJECT IF REQ'D
INITIALIZE_INFO* info ) // - info on current entry
{
TYPE type; // - NULL or type of dtorable element
SYMBOL sym; // - symbol to be initialized
_dumpDtorPtr( "dtorableObjectBeg( %x )\n", info );
type = dtorableObjectType( info );
if( type != NULL ) {
dataInitCodeFileOpen( TRUE );
sym = dtorableObjectInitSymbol();
#if 0
if( info->entry == DE_ROOT_TYPE ) {
CgFrontCode( IC_INIT_SYM_BEG );
}
#endif
dataInitTypeSigFind( type, TSA_DTOR );
DataDtorObjPush( NULL, type, sym, info->base );
dataInitCodeFileClose();
}
}
static SYMBOL getCtorCalled( // GET SCOPE-CALL TYPE FOR A CTOR
PTREE expr ) // - expression
{
SYMBOL ctor; // - ctor called
if( NodeIsBinaryOp( expr, CO_CALL_EXEC ) ) {
expr = PTreeOpLeft( expr );
DbgVerify( NodeIsUnaryOp( expr, CO_CALL_SETUP )
, "getCtorCallState -- not CO_CALL_SETUP" );
expr = PTreeOpLeft( expr );
DbgVerify( expr->op == PT_SYMBOL
, "getCtorCallState -- not PT_SYMBOL" );
ctor = expr->u.symcg.symbol;
} else {
ctor = NULL;
}
return ctor;
}
static PTREE emitDtorInitExpr( // EMIT DTOR MARKING FOR AN EXPRESSION
PTREE expr ) // - initialization expression
{
SYMBOL sym; // - symbol to be initialized
PTREE done; // - NULL or CO_DONE node
if( ! currInit->dtor_done ) {
_dumpDtor( "emitDtorInitExpr -- dtor for symbol\n" );
sym = dtorableObjectInitSymbol();
currInit->dtor_done = 1;
_dumpDtorSymbol( sym );
if( NodeIsUnaryOp( expr, CO_EXPR_DONE ) ) {
done = expr;
expr = expr->u.subtree[0];
} else {
done = NULL;
}
if( currInit->nest->entry == DE_ROOT_TYPE ) {
// the following code comes out ahead of the expression; it should
// be made a side effect if we attempt to optimize statement scopes
SYMBOL ctor = getCtorCalled( expr );
if( TypeReallyDtorable( sym->sym_type ) ) {
if( SymIsAutomatic( sym ) ) {
expr = PtdCtoredScopeType( expr, ctor, sym->sym_type );
} else {
expr = PtdScopeCall( expr, ctor );
}
} else {
expr = PtdScopeCall( expr, ctor );
}
// end of scope-call optimization
expr = PtdInitSymEnd( expr, sym );
}
expr = NodeDtorExpr( expr, sym );
if( done != NULL ) {
done->u.subtree[0] = expr;
expr = done;
}
}
return expr;
}
static PTREE dtorableObjectCtored(// EMIT INDEX OF DTORABLE OBJECT, IF REQ'D
INITIALIZE_INFO* curr, // - info on current entry
PTREE expr, // - expression to be emitted
boolean index_updated ) // - TRUE ==> index has been updated
{
TYPE type; // - NULL or type of dtorable element
INITIALIZE_INFO* info; // - info on previous entry
INITIALIZE_INFO* prev; // - used in searching previous entries
_dumpDtorPtr( "dtorableObjectCtored( %x )\n", curr );
info = curr->previous;
if( info == NULL ) {
type = dtorableObjectType( curr );
if( type != NULL ) {
dataInitCodeFileOpen( TRUE );
if( expr == NULL ) {
emitDtorInitSymbol();
} else {
expr = emitDtorInitExpr( expr );
}
dataInitCodeFileClose();
}
} else {
type = dtorableObjectType( info );
if( type != NULL ) {
if( info->target == DT_ARRAY ) {
unsigned index;
TYPE artype;
TYPE eltype;
eltype = arrayBaseStructType( info->type );
index = info->u.a.index;
for( prev = info; ; ) {
prev = prev->previous;
if( prev == NULL ) break;
if( prev->target != DT_ARRAY ) break;
artype = ArrayType( prev->type );
if( eltype != arrayBaseStructType( artype ) ) break;
index += prev->u.a.index * artype->u.a.array_size;
}
if( index_updated ) {
-- index;
}
dataInitCodeFileOpen( TRUE );
_dumpDtorInt( "dtorableObjectCtored -- index %x\n", index );
expr = DataDtorCompArrEl( expr, index );
dataInitCodeFileClose();
} else {
for( prev = curr
; prev != NULL && prev->type == curr->type
; prev = prev->previous );
if( prev != NULL ) {
dataInitCodeFileOpen( TRUE );
_dumpDtorInt( "dtorableObjectCtored -- class offset %x\n"
, info->offset );
expr = DataDtorCompClass( expr, info->offset, DTC_COMP_MEMB );
dataInitCodeFileClose();
}
}
}
}
return expr;
}
static void dataInitPushStack( INITIALIZE_ENTRY entry, INITIALIZE_INFO *prev )
/****************************************************************************/
// allocate and push a stack item
// initialize the stack item based on the entry
{
target_size_t size;
INITIALIZE_INFO *newtop;
newtop = StackCarveAlloc( carveNEST, &currInit->nest );
newtop->entry = entry;
newtop->previous = prev;
newtop->offset = 0;
switch( entry ) {
case DE_BRACE:
newtop->type = NULL;
newtop->base = 0;
newtop->mem_size = 0;
newtop->padded_size = 0;
break;
case DE_ROOT_TYPE:
newtop->type = currInit->sym_type;
dataInitComputeTarget( newtop );
size = CgMemorySize( currInit->sym_type );
newtop->mem_size = size;
newtop->padded_size = size;
newtop->base = 0;
break;
case DE_TYPE:
if( prev->entry == DE_ROOT_TYPE ) {
// just propagate root info for first push of aggregate
newtop->type = prev->type;
newtop->target = prev->target;
newtop->u = prev->u;
newtop->mem_size = prev->mem_size;
newtop->padded_size = prev->padded_size;
} else {
if( prev->target == DT_CLASS ) {
newtop->type = prev->u.c.curr->sym_type;
dataInitComputeTarget( newtop );
size = CgMemorySize( newtop->type );
newtop->mem_size = size;
newtop->padded_size = dataInitFieldSize( prev );
} else {
newtop->type = TypedefModifierRemoveOnly( prev->type )->of;
dataInitComputeTarget( newtop );
size = CgMemorySize( newtop->type );
newtop->mem_size = size;
newtop->padded_size = size;
}
}
newtop->base = prev->base + prev->offset;
break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?