typesig.c

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

C
499
字号
        } else {
            acc_ind = acc;
        }
        switch( thr ) {
          case THROBJ_PTR_SCALAR :
          case THROBJ_PTR_CLASS :
            sig->base = TypeSigFind( acc_ind & TSA_INDIRECT
                                   , TypePointedAtModified( type )
                                   , err_locn
                                   , &err_this_time );
            size = typeSigHdrSize();
            break;
          case THROBJ_SCALAR :
          case THROBJ_PTR_FUN :
          case THROBJ_VOID_STAR :
            size = typeSigHdrSize() + SizeTargetSizeT();
            break;
          case THROBJ_REFERENCE :
            sig->base = TypeSigFind( acc_ind
                                   , TypeReference( type )
                                   , err_locn
                                   , &err_this_time );
            size = 0;
            break;
          case THROBJ_CLASS :
          case THROBJ_CLASS_VIRT :
            size = 3 * CgCodePtrSize() + CgDataPtrSize() + typeSigHdrSize();
            break;
          case THROBJ_ANYTHING :
            size = 0;
            break;
          default :
#ifndef NDEBUG
            CFatal( "cgTypeSignature -- invalid throw category" );
#endif
            size = 0;
        }
        size += typeSigNameSize( thr );
        if( size == 0 ) {
            sym = NULL;
        } else {                // - type for TYPE SIGNATURE variable
            typesig_name = CppNameTypeSig( type );
            sym = ScopeAlreadyExists( GetFileScope(), typesig_name );
            if( sym == NULL ) {
                typesig_type = MakeInternalType( size );
                typesig_type = MakeCompilerConstCommonData( typesig_type );
                sym = SymCreateFileScope( typesig_type
                                        , SC_PUBLIC
                                        , SF_REFERENCED | SF_ADDR_TAKEN
                                        , typesig_name );
                LinkageSet( sym, "C++" );
                CgSegId( sym );
            }
        }
        sig->sym = sym;
    }
    if( err_this_time ) {
        *error_occurred = TRUE;
    } else {
        if( NULL != sig->sym ) {
            SegmentMarkUsed( sig->sym->segid );
        }
        *error_occurred = FALSE;
        typeSigAccess( acc, sig, err_locn, error_occurred );
    }
    return sig;
}


void TypeSigWalk(               // WALK THRU TYPE SIGNATURES
    void (*walker)              // - walking routine
        ( TYPE_SIG *sig ) )     // - - type signature
{
    TYPE_SIG *ts;

    RingIterBegSafe( type_sigs, ts ) {
        (*walker)( ts );
    } RingIterEndSafe( ts )
}


void TypeSigReferenced(         // EMIT CODE NOTING A TYPE-SIGNATURE REFERENCE
    TYPE_SIG *sig )             // - type signature
{
    CgFrontCodePtr( IC_EXPR_TS, sig->type );
}


void TypeSigSymOffset(          // GET SYMBOL,OFFSET FOR TYPE-SIG REFERENCE
    TYPE_SIG* sig,              // - type signature
    SYMBOL* a_sym,              // - addr[ symbol ]
    target_offset_t* a_offset ) // - addr[ offset ]
{
    target_offset_t offset;     // - offset

    if( NULL == sig->base ) {
        *a_sym = sig->sym;
        offset = offsetof( TS_HDR, hdr_actual );
    } else {
        *a_sym = sig->base->sym;
        if( NULL == TypeReference( sig->type ) ) {
            offset = offsetof( TS_HDR, hdr_ptr );
        } else {
            offset = offsetof( TS_HDR, hdr_ref );
        }
    }
    *a_offset = offset;
    DbgVerify( sig->type == NULL || *a_sym != NULL
             , "TypeSigSymOffset -- no symbol found" );
}


static void typeSigFini(        // COMPLETION OF TYPE SIGNATURING
    INITFINI* defn )            // - definition
{
    defn = defn;
    CarveDestroy( carveTYPE_SIG );
}


static void typeSigInit(        // INITIALIZATION OF TYPE SIGNATURING
    INITFINI* defn )            // - definition
{
    defn = defn;
    type_sigs = NULL;
    carveTYPE_SIG = CarveCreate( sizeof( TYPE_SIG ), 16 );
}


INITDEFN( type_signature, typeSigInit, typeSigFini )

pch_status PCHReadTypeSigs( void )
{
    cv_index i;
    TYPE_SIG *s;
    auto cvinit_t data;

    PCHRead( &type_sigs, sizeof( type_sigs ) );
    type_sigs = TypeSigMapIndex( type_sigs );
    CarveInitStart( carveTYPE_SIG, &data );
    for(;;) {
        i = PCHReadCVIndex();
        if( i == CARVE_NULL_INDEX ) break;
        s = CarveInitElement( &data, i );
        PCHRead( s, sizeof( *s ) );
        s->next = TypeSigMapIndex( s->next );
        s->base = TypeSigMapIndex( s->base );
        s->type = TypeMapIndex( s->type );
        s->sym = SymbolMapIndex( s->sym );
        s->dtor = SymbolMapIndex( s->dtor );
        s->default_ctor = SymbolMapIndex( s->default_ctor );
        s->copy_ctor = SymbolMapIndex( s->copy_ctor );
    }
    return( PCHCB_OK );
}

static void markFreeTypeSig( void *p )
{
    TYPE_SIG *s = p;

    s->free = TRUE;
}

static void saveTypeSig( void *e, carve_walk_base *d )
{
    TYPE_SIG *s = e;
    TYPE_SIG *save_next;
    TYPE_SIG *save_base;
    TYPE save_type;
    SYMBOL save_sym;
    SYMBOL save_dtor;
    SYMBOL save_default_ctor;
    SYMBOL save_copy_ctor;

    if( s->free ) {
        return;
    }
    save_next = s->next;
    s->next = TypeSigGetIndex( save_next );
    save_base = s->base;
    s->base = TypeSigGetIndex( save_base );
    save_type = s->type;
    s->type = TypeGetIndex( save_type );
    save_sym = s->sym;
    s->sym = SymbolGetIndex( save_sym );
    save_dtor = s->dtor;
    s->dtor = SymbolGetIndex( save_dtor );
    save_default_ctor = s->default_ctor;
    s->default_ctor = SymbolGetIndex( save_default_ctor );
    save_copy_ctor = s->copy_ctor;
    s->copy_ctor = SymbolGetIndex( save_copy_ctor );
    PCHWriteCVIndex( d->index );
    PCHWrite( s, sizeof( *s ) );
    s->next = save_next;
    s->base = save_base;
    s->type = save_type;
    s->sym = save_sym;
    s->dtor = save_dtor;
    s->default_ctor = save_default_ctor;
    s->copy_ctor = save_copy_ctor;
}

pch_status PCHWriteTypeSigs( void )
{
    TYPE_SIG *list_head;
    cv_index terminator = CARVE_NULL_INDEX;
    auto carve_walk_base data;

    list_head = TypeSigGetIndex( type_sigs );
    PCHWrite( &list_head, sizeof( list_head ) );
    CarveWalkAllFree( carveTYPE_SIG, markFreeTypeSig );
    CarveWalkAll( carveTYPE_SIG, saveTypeSig, &data );
    PCHWriteCVIndex( terminator );
    return( PCHCB_OK );
}

TYPE_SIG *TypeSigGetIndex( TYPE_SIG *e )
{
    return( CarveGetIndex( carveTYPE_SIG, e ) );
}

TYPE_SIG *TypeSigMapIndex( TYPE_SIG *e )
{
    return( CarveMapIndex( carveTYPE_SIG, e ) );
}

pch_status PCHInitTypeSigs( boolean writing )
{
    cv_index n;

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

pch_status PCHFiniTypeSigs( boolean writing )
{
    if( ! writing ) {
        CarveMapUnoptimize( carveTYPE_SIG );
    }
    return( PCHCB_OK );
}

⌨️ 快捷键说明

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