rtti.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 545 行 · 第 1/2 页

C
545
字号
        // to typeids must be satisfied
        TypeidRef( sym );
    }
    return( sym );
}

void TypeidRef( SYMBOL sym )
/**************************/
{
    if( sym != NULL ) {
        sym->flag |= SF_REFERENCED;
        CgSegId( sym );
        SegmentMarkUsed( sym->segid );
    }
}

void TypeidWalk( void (*walker)( RTTI_TYPEID * ) )
/************************************************/
{
    RTTI_TYPEID *curr;

    RingIterBegSafe( rttiTypeids, curr ) {
        (*walker)( curr );
    } RingIterEndSafe( curr )
}

unsigned TypeidSize( unsigned len )
/*********************************/
{
    len += CgDataPtrSize() + 1;
    return( len );
}

static void init( INITFINI* defn )
{
    defn = defn;
    rttiClasses = NULL;
    rttiTypeids = NULL;
    carveRTTI_CLASS = CarveCreate( sizeof( RTTI_CLASS ), BLOCK_RTTI_CLASS );
    carveRTTI_TYPEID = CarveCreate( sizeof( RTTI_TYPEID ), BLOCK_RTTI_TYPEID );
    carveRTTI_VFPTR = CarveCreate( sizeof( RTTI_VFPTR ), BLOCK_RTTI_VFPTR );
}

static void fini( INITFINI* defn )
{
    defn = defn;
    CarveDestroy( carveRTTI_CLASS );
    CarveDestroy( carveRTTI_TYPEID );
    CarveDestroy( carveRTTI_VFPTR );
}

INITDEFN( rtti_descriptors, init, fini )

static RTTI_CLASS *rttiClassGetIndex( RTTI_CLASS *e )
{
    return( CarveGetIndex( carveRTTI_CLASS, e ) );
}

static RTTI_CLASS *rttiClassMapIndex( RTTI_CLASS *e )
{
    return( CarveMapIndex( carveRTTI_CLASS, e ) );
}

static RTTI_VFPTR *rttiVfptrGetIndex( RTTI_VFPTR *e )
{
    return( CarveGetIndex( carveRTTI_VFPTR, e ) );
}

static RTTI_VFPTR *rttiVfptrMapIndex( RTTI_VFPTR *e )
{
    return( CarveMapIndex( carveRTTI_VFPTR, e ) );
}

static RTTI_TYPEID *rttiTypeidGetIndex( RTTI_TYPEID *e )
{
    return( CarveGetIndex( carveRTTI_TYPEID, e ) );
}

static RTTI_TYPEID *rttiTypeidMapIndex( RTTI_TYPEID *e )
{
    return( CarveMapIndex( carveRTTI_TYPEID, e ) );
}

pch_status PCHReadRttiDescriptors( void )
{
    cv_index i;
    RTTI_CLASS *c;
    RTTI_VFPTR *v;
    RTTI_TYPEID *t;
    auto cvinit_t data;

    // NYI: use read in place optimizations
    PCHRead( &rttiClasses, sizeof( rttiClasses ) );
    rttiClasses = rttiClassMapIndex( rttiClasses );
    PCHRead( &rttiTypeids, sizeof( rttiTypeids ) );
    rttiTypeids = rttiTypeidMapIndex( rttiTypeids );
    CarveInitStart( carveRTTI_CLASS, &data );
    for(;;) {
        i = PCHReadCVIndex();
        if( i == CARVE_NULL_INDEX ) break;
        c = CarveInitElement( &data, i );
        PCHRead( c, sizeof( *c ) );
        c->next = rttiClassMapIndex( c->next );
        c->vfptrs = rttiVfptrMapIndex( c->vfptrs );
        c->class_type = TypeMapIndex( c->class_type );
        c->sym = SymbolMapIndex( c->sym );
    }
    CarveInitStart( carveRTTI_VFPTR, &data );
    for(;;) {
        i = PCHReadCVIndex();
        if( i == CARVE_NULL_INDEX ) break;
        v = CarveInitElement( &data, i );
        PCHRead( v, sizeof( *v ) );
        v->next = rttiVfptrMapIndex( v->next );
    }
    CarveInitStart( carveRTTI_TYPEID, &data );
    for(;;) {
        i = PCHReadCVIndex();
        if( i == CARVE_NULL_INDEX ) break;
        t = CarveInitElement( &data, i );
        PCHRead( t, sizeof( *t ) );
        t->next = rttiTypeidMapIndex( t->next );
        t->type = TypeMapIndex( t->type );
        t->sym = SymbolMapIndex( t->sym );
    }
    return( PCHCB_OK );
}

static void markFreeClass( void *p )
{
    RTTI_CLASS *s = p;

    s->free = TRUE;
}

static void markFreeVfptr( void *p )
{
    RTTI_VFPTR *s = p;

    s->free = TRUE;
}

static void markFreeTypeid( void *p )
{
    RTTI_TYPEID *s = p;

    s->free = TRUE;
}

static void saveClass( void *e, carve_walk_base *d )
{
    RTTI_CLASS *s = e;
    RTTI_CLASS *save_next;
    RTTI_VFPTR *save_vfptrs;
    TYPE save_class_type;
    SYMBOL save_sym;

    if( s->free ) {
        return;
    }
    save_next = s->next;
    s->next = rttiClassGetIndex( save_next );
    save_vfptrs = s->vfptrs;
    s->vfptrs = rttiVfptrGetIndex( save_vfptrs );
    save_class_type = s->class_type;
    s->class_type = TypeGetIndex( save_class_type );
    save_sym = s->sym;
    s->sym = SymbolGetIndex( save_sym );
    PCHWriteCVIndex( d->index );
    PCHWrite( s, sizeof( *s ) );
    s->next = save_next;
    s->vfptrs = save_vfptrs;
    s->class_type = save_class_type;
    s->sym = save_sym;
}

static void saveVfptr( void *e, carve_walk_base *d )
{
    RTTI_VFPTR *s = e;
    RTTI_VFPTR *save_next;

    if( s->free ) {
        return;
    }
    save_next = s->next;
    s->next = rttiVfptrGetIndex( save_next );
    PCHWriteCVIndex( d->index );
    PCHWrite( s, sizeof( *s ) );
    s->next = save_next;
}

static void saveTypeid( void *e, carve_walk_base *d )
{
    RTTI_TYPEID *s = e;
    RTTI_TYPEID *save_next;
    TYPE save_type;
    SYMBOL save_sym;

    if( s->free ) {
        return;
    }
    save_next = s->next;
    s->next = rttiTypeidGetIndex( save_next );
    save_type = s->type;
    s->type = TypeGetIndex( save_type );
    save_sym = s->sym;
    s->sym = SymbolGetIndex( save_sym );
    PCHWriteCVIndex( d->index );
    PCHWrite( s, sizeof( *s ) );
    s->next = save_next;
    s->type = save_type;
    s->sym = save_sym;
}

pch_status PCHWriteRttiDescriptors( void )
{
    RTTI_CLASS *list_head;
    RTTI_TYPEID *head_typeid;
    cv_index terminator = CARVE_NULL_INDEX;
    auto carve_walk_base data;

    list_head = rttiClassGetIndex( rttiClasses );
    PCHWrite( &list_head, sizeof( list_head ) );
    head_typeid = rttiTypeidGetIndex( rttiTypeids );
    PCHWrite( &head_typeid, sizeof( head_typeid ) );
    CarveWalkAllFree( carveRTTI_CLASS, markFreeClass );
    CarveWalkAll( carveRTTI_CLASS, saveClass, &data );
    PCHWriteCVIndex( terminator );
    CarveWalkAllFree( carveRTTI_VFPTR, markFreeVfptr );
    CarveWalkAll( carveRTTI_VFPTR, saveVfptr, &data );
    PCHWriteCVIndex( terminator );
    CarveWalkAllFree( carveRTTI_TYPEID, markFreeTypeid );
    CarveWalkAll( carveRTTI_TYPEID, saveTypeid, &data );
    PCHWriteCVIndex( terminator );
    return( PCHCB_OK );
}

pch_status PCHInitRttiDescriptors( boolean writing )
{
    cv_index n;

    if( writing ) {
        n = CarveLastValidIndex( carveRTTI_CLASS );
        PCHWriteCVIndex( n );
        n = CarveLastValidIndex( carveRTTI_VFPTR );
        PCHWriteCVIndex( n );
        n = CarveLastValidIndex( carveRTTI_TYPEID );
        PCHWriteCVIndex( n );
    } else {
        carveRTTI_CLASS = CarveRestart( carveRTTI_CLASS );
        n = PCHReadCVIndex();
        CarveMapOptimize( carveRTTI_CLASS, n );
        carveRTTI_VFPTR = CarveRestart( carveRTTI_VFPTR );
        n = PCHReadCVIndex();
        CarveMapOptimize( carveRTTI_VFPTR, n );
        carveRTTI_TYPEID = CarveRestart( carveRTTI_TYPEID );
        n = PCHReadCVIndex();
        CarveMapOptimize( carveRTTI_TYPEID, n );
    }
    return( PCHCB_OK );
}

pch_status PCHFiniRttiDescriptors( boolean writing )
{
    if( ! writing ) {
        CarveMapUnoptimize( carveRTTI_CLASS );
        CarveMapUnoptimize( carveRTTI_VFPTR );
        CarveMapUnoptimize( carveRTTI_TYPEID );
    }
    return( PCHCB_OK );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?