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