scope.c

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

C
2,318
字号
        printf( "- this = *(this - sizeof(unsigned))\n" );
        if( thunk->input_virtual ) {
            printf( "- this += %xh\n", thunk->in.vb_offset );
            printf( "- this += (*this)[%u]\n", thunk->in.vb_index );
        }
        if( thunk->in.delta ) {
            printf( "- this += %xh\n", thunk->in.delta );
        }
    }
    sym = thunk->override;
    if( sym != NULL ) {
        printf( "- " );
        printSymbolName( sym );
        putchar( '\n' );
    } else {
        printf( "- (no override)\n" );
    }
    if( thunk->output_virtual ) {
        printf( "- ret += %xh\n", thunk->out.vb_offset );
        printf( "- ret += (*ret)[%u]\n", thunk->out.vb_index );
    }
    if( thunk->out.delta ) {
        printf( "- ret += %xh\n", thunk->out.delta );
    }
    printf( "--\n" );
}

static void dumpVFN( SYMBOL sym, vftable_walk *data, CLASS_VFTABLE *table, unsigned vf_index )
{
    BASE_STACK *top;
    BASE_CLASS *base;

    if( ! PragDbgToggle.dump_vftables ) {
        return;
    }
    printSymbolName( sym );
    printf( "offset=%04xh index=%u\n", table->h.exact_delta, vf_index + 1 );
    top = data->top;
    for(;;) {
        if( top == NULL ) break;
        printScopeName( top->scope, NULL );
        base = top->base;
        if( base != NULL ) {
            if( _IsDirectVirtualBase( base ) ) {
                printf( "===> " );
            } else {
                printf( "-%xh-> ", base->delta );
            }
        }
        top = top->parent;
    }
    putchar( '\n' );
}

static void dumpDerivation( MEMBER_PTR_CAST *data )
{
    if( ! PragDbgToggle.dump_member_ptr ) {
        return;
    }
    if( data->safe ) {
        printScopeName( data->base, "-> " );
    } else {
        printScopeName( data->base, "<- " );
    }
    printScopeName( data->derived, "\n" );
}

static void dumpData( MEMBER_PTR_CAST *data )
{
    if( ! PragDbgToggle.dump_member_ptr ) {
        return;
    }
    printf(
        "delta:         %u "
        "single_test:   %u "
        "vb_index:      %u "
        "mapping:       %08x "
        "\n"
        "init_conv:     %u "
        "mapping_reqd:  %u "
        "delta_reqd:    %u "
        "test_reqd:     %u "
        "\n"
        "singlemapping: %u "
        "\n"
        ,
        data->delta,
        data->single_test,
        data->vb_index,
        data->mapping,
        data->init_conv,
        data->mapping_reqd,
        data->delta_reqd,
        data->test_reqd,
        data->single_mapping
        );

}

static boolean recordableScope( SCOPE scope )
{
    switch( scope->id ) {
    case SCOPE_TEMPLATE_DECL:
    case SCOPE_TEMPLATE_INST:
        return( FALSE );
    }
    return( TRUE );
}
#else
#define printSymbolName( s )
#define dumpThunk( t )
#define dumpVFN( s, d, t, i )
#define dumpDerivation( d )
#define dumpData( d )
#endif

static void reinitScope( SCOPE scope )
{
    // keep ->in_unnamed setting
    scope->dtor_reqd = FALSE;
    scope->dtor_naked = FALSE;
    scope->try_catch = FALSE;
    scope->ordered = NULL;
    scope->owner.sym = NULL;
    scope->names = HashCreate( hashTableSize[scope->id] );
}

static SCOPE makeScope( scope_type_t scope_type )
{
    SCOPE new_scope;

    ExtraRptIncrementCtr( scopes_alloced );
    ExtraRptIncrementCtr( scopes_kept );
    new_scope = CarveAlloc( carveSCOPE );
    new_scope->id = scope_type;
    new_scope->keep = FALSE;
    new_scope->dtor_reqd = FALSE;
    new_scope->dtor_naked = FALSE;
    new_scope->try_catch = FALSE;
    new_scope->arg_check = FALSE;
    new_scope->cg_stab = FALSE;
    new_scope->in_unnamed = FALSE;
    new_scope->fn_template = FALSE;
    new_scope->dirty = FALSE;
    new_scope->enclosing = NULL;
    new_scope->ordered = NULL;
    new_scope->owner.sym = NULL;
    new_scope->names = HashCreate( hashTableSize[scope_type] );
    new_scope->using_list = NULL;
    DbgStmt( if( recordableScope( new_scope ) ) DbgRememberScope( new_scope ); );
    return( new_scope );
}

static SYMBOL injectOpDel( char *name )
{
    SYMBOL sym;

    sym = SymCreateFileScope( TypeVoidFunOfPtrVoid()
                            , SC_EXTERN
                            , 0
                            , name );
    LinkageSet( sym, "C++" );
    return( sym );
}

static void injectGlobalOpDelete( void )
{
    /* extern void operator delete( void * ); */
    injectOpDel( CppOperatorName( CO_DELETE ) );

    /* extern void operator delete []( void * ); */
    injectOpDel( CppOperatorName( CO_DELETE_ARRAY ) );
}

static void injectOpNew( TYPE fn_type, char *name )
{
    SYMBOL sym;

    sym = SymCreateFileScope( fn_type
                            , SC_EXTERN
                            , 0
                            , name );
    LinkageSet( sym, "C++" );
}

static void injectGlobalOpNew( void )
{
    TYPE pvoid_type;
    TYPE size_type;
    TYPE size_fn_type;
    TYPE placement_fn_type;
    char *simple_name;
    char *array_name;

    pvoid_type = TypePtrToVoid();
    size_type = GetBasicType( TYP_UINT );
    simple_name = CppOperatorName( CO_NEW );
    array_name = CppOperatorName( CO_NEW_ARRAY );

    /* extern void *operator new( unsigned ); */
    size_fn_type = MakeSimpleFunction( pvoid_type, size_type, NULL );
    injectOpNew( size_fn_type, simple_name );

    /* extern void *operator new []( unsigned ); */
    injectOpNew( size_fn_type, array_name );

    /* extern void *operator new( unsigned, void * ); */
    placement_fn_type = MakeSimpleFunction( pvoid_type, size_type, pvoid_type, NULL );
    injectOpNew( placement_fn_type, simple_name );

    /* extern void *operator new []( unsigned, void * ); */
    injectOpNew( placement_fn_type, array_name );
}

static void injectChipBug( void )
{
    TYPE type;
    char *name;
    SYMBOL sym;

    name = CppSpecialName( SPECIAL_CHIPBUG );
    type = GetBasicType( TYP_UINT );
    type = MakeModifiedType( type, TF1_NEAR );
    sym = SymCreateFileScope( type, SC_EXTERN, 0, name );
    LinkageSet( sym, "C" );
    ChipBugSym = sym;
}

static void injectBool( void )
{
    char *name;

    /* 'bool' cannot be a keyword because the idiots at MS use it as an id */
    if( CompFlags.extensions_enabled ) {
        name = NameCreateNoLen( Tokens[T_BOOL] );
        bool_zapped_char = KwDisable( T_BOOL );
        SymCreateFileScope( GetBasicType( TYP_BOOL ), SC_TYPEDEF, 0, name );
    }
}

static void injectDwarfAbbrev( void )
{
    TYPE type;
    char *name;
    SYMBOL sym;

    name = CppSpecialName( SPECIAL_DWARF_ABBREV );
    type = GetBasicType( TYP_CHAR );
    sym = SymCreateFileScope( type, SC_EXTERN, 0, name );
    LinkageSet( sym, "C" );
    DFAbbrevSym = sym;
}

void ScopeCreatePCHDebugSym( void )
/*********************************/
{
    TYPE type;
    char *name;
    SYMBOL sym;

    if( CompFlags.pch_debug_info_write ) {
        name = PCHDebugInfoName();
        type = GetBasicType( TYP_CHAR );
        sym = SymCreateFileScope( type, SC_PUBLIC, 0, name );
        PCHDebugSym = sym;
    }else if( CompFlags.pch_debug_info_read ){
        name = PCHDebugInfoName();
        type = GetBasicType( TYP_CHAR );
        sym = SymCreateFileScope( type, SC_EXTERN, 0, name );
        PCHDebugSym = sym;
    }else{
        PCHDebugSym = NULL;
    }
}

static SCOPE initGlobalNamespaceScope( SCOPE scope )
{
    scope->names = HashMakeMax( scope->names );
    ScopeKeep( scope );
    return( scope );
}

static SCOPE makeFileScope( fs_control control, SYMBOL sym )
{
    SCOPE scope;
    NAME_SPACE *ns;

    scope = makeScope( SCOPE_FILE );
    ns = CarveAlloc( carveNAME_SPACE );
    ns->sym = sym;
    ns->scope = scope;
    ns->last_sym = NULL;
    ns->all = allNameSpaces;
    ns->global_fs = FALSE;
    ns->free = FALSE;
    ns->unnamed = FALSE;
    if( control & FS_GLOBAL ) {
        ns->global_fs = TRUE;
    } else if( control & FS_UNNAMED ) {
        ns->unnamed = TRUE;
        scope->in_unnamed = TRUE;
    }
    allNameSpaces = ns;
    scope->owner.ns = ns;
    return( scope );
}

static void scopeOpenMaybeNull( SCOPE scope )
{
    SCOPE enclosing;

    enclosing = GetCurrScope();
    scope->enclosing = enclosing;
    if( enclosing != NULL && enclosing->in_unnamed ) {
        scope->in_unnamed = TRUE;
    }
    SetCurrScope(scope);
}

static void scopeBeginFileScope( void )
{
    SCOPE scope;

    scope = makeFileScope( FS_GLOBAL, NULL );
    scopeOpenMaybeNull( scope );
}

static void scopeInit(          // SCOPES INITIALIZATION
    INITFINI* defn )            // - definition
{
    defn = defn;
    DbgStmt( bool_zapped_char = '\0' );
    DbgStmt( static_assert_zapped_char = '\0' );
    PCHActivate();
    carveSYM_REGION = CarveCreate( sizeof( SYM_REGION ), BLOCK_SYM_REGION );
    carveUSING_NS = CarveCreate( sizeof( USING_NS ), BLOCK_USING_NS );
    carveNAME_SPACE = CarveCreate( sizeof( NAME_SPACE ), BLOCK_NAME_SPACE );
    carveSCOPE = CarveCreate( sizeof( struct scope ), BLOCK_SCOPE );
    carveSYMBOL = CarveCreate( sizeof( struct symbol ), BLOCK_SYMBOL );
    carveSYMBOL_NAME = CarveCreate( sizeof( struct symbol_name ),
                                    BLOCK_SYMBOL_NAME );
    carveBASE_STACK = CarveCreate( sizeof( BASE_STACK ), BLOCK_BASE_STACK );
    carveBASE_PATH = CarveCreate( sizeof( BASE_PATH ), BLOCK_BASE_PATH );
    carvePATH_CAP = CarveCreate( sizeof( PATH_CAP ), BLOCK_PATH_CAP );
    carveSEARCH_RESULT = CarveCreate( sizeof( SEARCH_RESULT ),
                                      BLOCK_SEARCH_RESULT );
    carveGEN_LEAP = CarveCreate( sizeof( GEN_LEAP ),
                                      BLOCK_GEN_LEAP );
    carveQUALIFICATION = CarveCreate( sizeof( QUALIFICATION ),
                                      BLOCK_QUALIFICATION );
    carveSYMBOL_EXCLUDE = CarveCreate( sizeof( SYMBOL_EXCLUDE ),
                                       BLOCK_SYMBOL_EXCLUDE );
    SetCurrScope(NULL);
    uniqueNameSpaceName = NULL;
    allNameSpaces = NULL;
    PCHDebugSym = NULL;
    mappingList = NULL;
    HashPostInit( NULL );
    scopeBeginFileScope();
    SetFileScope(initGlobalNamespaceScope( GetCurrScope() ));
    scopeBeginFileScope();
    SetInternalScope(GetCurrScope());
    ScopeKeep( GetInternalScope());
    SetCurrScope(GetFileScope());
    HashPostInit( GetFileScope() );
    BrinfOpenScope( GetFileScope() );
    BrinfOpenScope( GetInternalScope() );
    injectGlobalOpNew();
    injectGlobalOpDelete();
    injectChipBug();
    injectDwarfAbbrev();
    injectBool();
    if( ! CompFlags.enable_std0x ) {
        static_assert_zapped_char = KwDisable( T_STATIC_ASSERT );
    }
    ExtraRptRegisterCtr( &syms_defined, "symbols defined" );
    ExtraRptRegisterCtr( &scopes_alloced, "scopes allocated" );
    ExtraRptRegisterCtr( &scopes_kept, "scopes kept" );
    ExtraRptRegisterCtr( &scopes_searched, "scopes searched" );
    ExtraRptRegisterCtr( &scopes_closed, "scopes closed" );
    ExtraRptRegisterCtr( &nonempty_scopes_closed, "non-empty scopes closed" );
    ExtraRptRegisterCtr( &cnv_total, "ScopeBestConversion calls" );
    ExtraRptRegisterCtr( &cnv_quick, "ScopeBestConversion quick exits" );
    ExtraRptRegisterCtr( &cnv_found, "ScopeBestConversion finds a UDC" );
}

static void scopeFini(          // SCOPES COMPLETION
    INITFINI* defn )            // - definition
{
    defn = defn;
#ifndef NDEBUG
    CarveVerifyAllGone( carveBASE_STACK, "BASE_STACK" );
    CarveVerifyAllGone( carveBASE_PATH, "BASE_PATH" );
    CarveVerifyAllGone( carvePATH_CAP, "PATH_CAP" );
    CarveVerifyAllGone( carveSEARCH_RESULT, "SEARCH_RESULT" );
    CarveVerifyAllGone( carveGEN_LEAP, "GEN_LEAP" );
    CarveVerifyAllGone( carveQUALIFICATION, "QUALIFICATION" );
    CarveVerifyAllGone( carveSYMBOL_EXCLUDE, "SYMBOL_EXCLUDE" );
#endif
    if( CompFlags.extensions_enabled ) {
        KwEnable( T_BOOL, bool_zapped_char );
    }
    if( ! CompFlags.enable_std0x ) {
        KwEnable( T_STATIC_ASSERT, static_assert_zapped_char );
    }
    CarveDestroy( carveSYM_REGION );
    CarveDestroy( carveUSING_NS );
    CarveDestroy( carveNAME_SPACE );
    CarveDestroy( carveSCOPE );
    CarveDestroy( carveSYMBOL );
    CarveDestroy( carveSYMBOL_NAME );
    CarveDestroy( carveBASE_STACK );
    CarveDestroy( carveBASE_PATH );
    CarveDestroy( carvePATH_CAP );
    CarveDestroy( carveSEARCH_RESULT );
    CarveDestroy( carveGEN_LEAP );
    CarveDestroy( carveQUALIFICATION );
    CarveDestroy( carveSYMBOL_EXCLUDE );
}

INITDEFN( scopes, scopeInit, scopeFini )

static SCOPE findCommonEnclosing( SCOPE scope1, SCOPE scope2 )
{
    SCOPE i1;
    SCOPE i2;
    SCOPE it;

    for( i1 = scope1; i1 != NULL; i1 = i1->enclosing ) {
        if( i1 == scope2 ) {
            return( i1 );
        }
        i1->colour = TRUE;
    }
    for( i2 = scope2; i2 != NULL; i2 = i2->enclosing ) {
        if( i2 == scope1 ) {
            return( i2 );
        }
        i2->colour = FALSE;
    }
    for( it = scope1; it != NULL; it = it->enclosing ) {
        if( ! it->colour ) {
            return( it );
        }
    }
    DbgNever();
    return( GetFileScope() );
}

static void addLexicalTrigger( SCOPE gets_trigger, SCOPE using_scope )
{
    USING_NS *lexical_entry;

    // trigger == NULL: push
    lexical_entry = CarveAlloc( carveUSING_NS );
    lexical_entry->using_scope = using_scope;
    lexical_entry->trigger = NULL;
    RingPush( &gets_trigger->using_list, lexical_entry );
}

static void addUsingDirective( SCOPE gets_using, SCOPE using_scope, SCOPE trigger )
{
    USING_NS *using_entry;
    USING_NS *curr;

⌨️ 快捷键说明

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