ptreedec.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,078 行 · 第 1/3 页
C
1,078 行
PTREE PtdGetOffsetofExpr( // GET OFFSETOF EXPR
PTREE expr ) // - expr
{
PTREE tree;
PTD *ptd;
RingIterBeg( expr->decor, ptd ) {
if( ptd->base.kind == PTD_OFFSETOF_EXPR ) {
// detach and return
tree = ptd->ptree.tree;
ptd->ptree.tree = NULL;
return( tree );
}
} RingIterEnd( ptd );
return( NULL );
}
void PtdGenBefore // GENERATE BEFORE NODE PROCESSED
( PTD* ring ) // - ring of entries
{
PTD* ptd; // - current decoration
RingIterBeg( ring, ptd ) {
switch( ptd->base.kind ) {
case PTD_CTORCOMP :
CgFrontCodeUint( IC_COMPCTOR_BEG, ptd->off.offset );
break;
case PTD_DTOR_KIND :
CgFrontCodeUint( IC_DTOR_KIND, ptd->off.offset );
break;
case PTD_OBJ_OFFSET :
CgFrontCodeUint( IC_DTOBJ_OFF, ptd->off.offset );
break;
case PTD_OBJ_PUSH :
CgFrontCodePtr( IC_DTOBJ_PUSH, ptd->type.type );
break;
case PTD_OBJ_SYM :
CgFrontCodePtr( IC_DTOBJ_SYM, ptd->symbol.sym );
break;
case PTD_VB_DELTA :
CgFrontCodeUint( IC_VB_DELTA, ptd->off.offset );
break;
case PTD_VB_EXACT :
CgFrontCodeUint( IC_VB_EXACT, ptd->off.offset );
break;
case PTD_VB_INDEX :
CgFrontCodeUint( IC_VB_INDEX, ptd->off.offset );
break;
case PTD_VB_OFFSET :
CgFrontCodeUint( IC_VB_OFFSET, ptd->off.offset );
break;
case PTD_VF_INDEX :
CgFrontCodeUint( IC_VF_INDEX, ptd->off.offset );
break;
case PTD_VF_OFFSET :
CgFrontCodeUint( IC_VF_OFFSET, ptd->off.offset );
break;
case PTD_VF_SYM :
CgFrontCodePtr( IC_VF_THIS, ptd->symbol.sym );
break;
}
} RingIterEnd( ptd );
}
void PtdGenAfter // GENERATE AFTER NODE PROCESSED
( PTD* ring ) // - ring of entries
{
PTD* ptd; // - current decoration
SYMBOL fun; // - function called
SYMBOL dtor; // - destructor
DTOR_KIND kind; // - kind of dtoring
fun = NULL;
dtor = NULL;
kind = DTORING_NONE;
RingIterBeg( ring, ptd ) {
switch( ptd->base.kind ) {
case PTD_CTORED_COMP :
DbgVerify( kind == DTORING_NONE, "PtdGenAfter: dtoring twice" );
kind = DTORING_COMPONENT;
dtor = ptd->symbol.sym;
break;
case PTD_CTORCOMP :
CgFrontCodeUint( IC_COMPCTOR_END, ptd->off.offset );
break;
case PTD_DEL_DTORED :
CgFrontCode( IC_DLT_DTORED );
break;
case PTD_DEL_DTOR_ARR :
CgFrontCodePtr( IC_DLT_DTOR_ARR, ptd->symbol.sym );
break;
case PTD_DEL_DTOR_ELM :
CgFrontCodePtr( IC_DLT_DTOR_ELM, ptd->symbol.sym );
break;
case PTD_DEL_DTOR_SIZE :
CgFrontCodeUint( IC_DLT_DTOR_SIZE, ptd->size.size );
break;
case PTD_DTOR_EXPR :
DbgVerify( kind == DTORING_NONE, "PtdGenAfter: dtoring twice" );
kind = DTORING_TEMP;
dtor = ptd->symbol.sym;
break;
case PTD_DTOR_REF :
CgFrontCodePtr( IC_DTOR_REF, ptd->symbol.sym );
break;
case PTD_DTOR_SCOPE :
DbgVerify( kind == DTORING_NONE, "PtdGenAfter: dtoring twice" );
kind = DTORING_SCOPE;
dtor = ptd->symbol.sym;
break;
case PTD_DTOR_USE :
CgFrontCodePtr( IC_DTOR_USE, ptd->symbol.sym );
break;
case PTD_EXPR_CONST :
CgFrontCode( IC_EXPR_CONST );
break;
case PTD_INIT_SYM_END :
PtdInitSymEnd( NULL, ptd->symbol.sym );
break;
case PTD_NEW_ALLOC :
CgFrontCode( IC_NEW_ALLOC );
break;
case PTD_NEW_CTOR :
LabelExprNewCtor();
CgFrontCodePtr( IC_NEW_CTORED, ptd->type.type );
break;
case PTD_OBJ_POP :
CgFrontCode( IC_DTOBJ_POP );
break;
case PTD_SCOPE_CALL :
fun = ptd->symbol.sym;
break;
case PTD_RETNOPT_VAR :
PtdRetnOptVar( NULL, ptd->symbol.sym );
break;
case PTD_RETNOPT_END :
PtdRetnOptEnd( NULL );
break;
case PTD_THROW :
CgFrontCode( IC_SCOPE_THROW );
break;
}
} RingIterEnd( ptd );
if( fun != NULL || dtor != NULL ) {
CgFrontScopeCall( fun, dtor, kind );
}
}
static void init( // INITIALIZE PTREEDEC
INITFINI* defn ) // - definition
{
defn = defn;
carvePTD = CarveCreate( sizeof( PTD ), 128 );
}
static void fini( // COMPLETE PTREEDEC
INITFINI* defn ) // - definition
{
defn = defn;
CarveDestroy( carvePTD );
}
INITDEFN( parse_tree_decoration, init, fini )
PTD *PtdGetIndex( PTD *e )
{
return( CarveGetIndex( carvePTD, e ) );
}
PTD *PtdMapIndex( PTD *e )
{
return( CarveMapIndex( carvePTD, e ) );
}
static void markFreePtd( void *p )
{
PTD *s = p;
s->base.kind = PTD_PCH_FREE;
}
static void savePtd( void *p, carve_walk_base *d )
{
PTD *s = p;
PTD *save_next;
PTREE save_tree;
SYMBOL save_sym;
TYPE save_type;
if( s->base.kind == PTD_PCH_FREE ) {
return;
}
save_next = s->base.next;
s->base.next = PtdGetIndex( save_next );
switch( s->base.fmt ) {
case PTD_FMT_SYMBOL:
save_sym = s->symbol.sym;
s->symbol.sym = SymbolGetIndex( save_sym );
break;
case PTD_FMT_TYPE:
save_type = s->type.type;
s->type.type = TypeGetIndex( save_type );
break;
case PTD_FMT_PTREE:
save_tree = s->ptree.tree;
s->ptree.tree = PTreeGetIndex( save_tree );
break;
}
PCHWriteCVIndex( d->index );
PCHWrite( s, sizeof( *s ) );
s->base.next = save_next;
switch( s->base.fmt ) {
case PTD_FMT_SYMBOL:
s->symbol.sym = save_sym;
break;
case PTD_FMT_TYPE:
s->type.type = save_type;
break;
case PTD_FMT_PTREE:
s->ptree.tree = save_tree;
break;
}
}
pch_status PCHWritePtds( void )
{
cv_index terminator = CARVE_NULL_INDEX;
auto carve_walk_base data;
CarveWalkAllFree( carvePTD, markFreePtd );
CarveWalkAll( carvePTD, savePtd, &data );
PCHWriteCVIndex( terminator );
return( PCHCB_OK );
}
pch_status PCHReadPtds( void )
{
cv_index i;
PTD *r;
PTD *pch;
auto cvinit_t data;
CarveInitStart( carvePTD, &data );
for(;;) {
PCHReadMapped( pch, r, i, data );
r->base.next = PtdMapIndex( pch->base.next );
r->base.kind = pch->base.kind;
r->base.fmt = pch->base.fmt;
switch( pch->base.fmt ) {
case PTD_FMT_BASE:
break;
case PTD_FMT_OFFSET:
r->off.offset = pch->off.offset;
break;
case PTD_FMT_SIZE:
r->size.size = pch->size.size;
break;
case PTD_FMT_SYMBOL:
r->symbol.sym = SymbolMapIndex( pch->symbol.sym );
break;
case PTD_FMT_TYPE:
r->type.type = TypeMapIndex( pch->type.type );
break;
case PTD_FMT_PTREE:
r->ptree.tree = PTreeMapIndex( pch->ptree.tree );
break;
DbgDefault( "incorrect PTD format" );
}
}
return( PCHCB_OK );
}
pch_status PCHInitPtds( boolean writing )
{
cv_index n;
if( writing ) {
n = CarveLastValidIndex( carvePTD );
PCHWriteCVIndex( n );
} else {
carvePTD = CarveRestart( carvePTD );
n = PCHReadCVIndex();
CarveMapOptimize( carvePTD, n );
}
return( PCHCB_OK );
}
pch_status PCHFiniPtds( boolean writing )
{
if( ! writing ) {
CarveMapUnoptimize( carvePTD );
}
return( PCHCB_OK );
}
#ifndef NDEBUG
#include <stdio.h>
#include "dbg.h"
#include "fmttype.h"
static char const *name_kind[] = // names
{
#define PTD_DEF( a ) #a
PTD_DEFS
#undef PTD_DEF
};
void PtdPrint( // DEBUG: print decoration for a node
int numb, // - number for node
PTREE node ) // - the node
{
PTD* curr; // - current entry
char const * name; // - name to be printed
printf( "%d. Decorated Node: %x\n", numb, node );
RingIterBeg( node->decor, curr ) {
if( curr->base.kind >= MAX_PTD_KIND ) {
name = "PtdPrint -- bad PTD type";
} else {
name = name_kind[ curr->base.kind ];
}
printf( " %s:", name );
switch( curr->base.fmt ) {
DbgDefault( "PtdPrint -- bad PTD format" );
case PTD_FMT_BASE :
printf( "\n" );
break;
case PTD_FMT_SYMBOL :
printf( " %s\n", DbgSymNameFull( curr->symbol.sym ) );
break;
case PTD_FMT_OFFSET :
printf( " offset = %x\n", curr->off.offset );
break;
case PTD_FMT_SIZE :
printf( " size = %x\n", curr->size.size );
break;
case PTD_FMT_TYPE :
{ VBUF fmt_prefix, fmt_suffix;
FormatType( curr->type.type, &fmt_prefix, &fmt_suffix );
printf( " %s<id>%s\n", fmt_prefix.buf, fmt_suffix.buf );
VbufFree( &fmt_prefix );
VbufFree( &fmt_suffix );
} break;
}
} RingIterEnd( curr );
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?