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