scope.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,318 行 · 第 1/5 页
C
2,318 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "plusplus.h"
#include <stddef.h>
#include <stdio.h>
#include <limits.h>
#include "errdefns.h"
#include "memmgr.h"
#include "ring.h"
#include "stack.h"
#include "name.h"
#include "hashtab.h"
#include "carve.h"
#include "cgfront.h"
#include "class.h"
#include "decl.h"
#include "dbg.h"
#include "fnovload.h"
#include "cgsegid.h"
#include "vstk.h"
#include "pstk.h"
#include "pragdefn.h"
#include "yydriver.h"
#include "fnbody.h"
#include "initdefs.h"
#include "pcheader.h"
#include "template.h"
#include "stats.h"
#include "preproc.h"
#include "typesig.h"
#include "brinfo.h"
#include "conpool.h"
#define _ScopeMask( i ) ( 1 << (i) )
#define _IsClassScope( s ) \
((s)->id == SCOPE_CLASS)
#define _IsFunctionScope( s ) \
((s)->id == SCOPE_FUNCTION)
#define _IsBlockScope( s ) \
((s)->id == SCOPE_BLOCK)
#define _IsFileScope( s ) \
((s)->id == SCOPE_FILE)
static int hashTableSize[SCOPE_MAX] = {
#define SCOPE_DEF(a,b) b
SCOPE_DEFS
#undef SCOPE_DEF
};
typedef enum file_scope_control {
FS_GLOBAL = 0x01,
FS_UNNAMED = 0x02,
FS_NULL = 0x00
} fs_control;
typedef boolean (*special_name_fn)( SYMBOL_NAME );
typedef struct save_mapping SAVE_MAPPING;
struct save_mapping {
SAVE_MAPPING *next;
SCOPE from;
SCOPE to;
SYMBOL sym;
target_offset_t map_0;
};
typedef struct base_path BASE_PATH;
struct base_path {
BASE_PATH *next;
BASE_PATH *prev;
BASE_CLASS *base;
SCOPE scope;
inherit_flag flag;
unsigned checked_private : 1;
unsigned failed_private : 1;
};
typedef struct symbol_exclude SYMBOL_EXCLUDE;
struct symbol_exclude {
SYMBOL_EXCLUDE *next;
SYMBOL sym;
};
typedef struct path_cap PATH_CAP;
struct path_cap {
PATH_CAP *next; /* NULL terminated list */
BASE_PATH *head;
BASE_PATH *tail;
SCOPE access_decl;
SYMBOL_EXCLUDE *exclude;
SYMBOL_NAME sym_name;
SYMBOL sym;
inherit_flag flag;
unsigned throw_away : 1;
unsigned across_virtual_base : 1;
};
typedef struct base_stack BASE_STACK;
struct base_stack {
BASE_STACK *next;
BASE_STACK *parent;
BASE_CLASS *base;
SCOPE scope;
SYMBOL access_changed;
void *hold;
inherit_flag access_perm;
unsigned used : 1;
};
typedef enum { /* return value for base class walking routines */
WALK_NORMAL, /* keep going; nothing special has happened */
WALK_FINISH, /* terminate entire walk traversal */
WALK_ABANDON, /* abandon this base class and its base classes */
} walk_status;
typedef walk_status (*walk_routine)( BASE_STACK *, void * );
typedef struct {
SCOPE derived;
SCOPE base;
unsigned copies;
unsigned virtual_base : 1;
unsigned is_derived : 1;
} scope_derived_walk;
typedef struct {
SCOPE start;
GEN_LEAP *list;
unsigned count;
} rtti_leap_walk;
typedef struct {
char *name;
TYPE found;
} bound_base_walk;
typedef struct {
SCOPE found;
unsigned copies;
} count_copy_walk;
typedef struct {
SCOPE base;
unsigned virtual_base : 1;
unsigned is_derived : 1;
} derived_walk;
typedef struct {
PSTK_CTL common_bases;
int colour;
} common_base_walk;
typedef struct {
unsigned depth;
SCOPE base;
unsigned many_pathes : 1;
} base_depth_walk;
typedef struct {
void (*rtn)( SCOPE, void * );
void *data;
} all_bases_walk;
typedef struct {
SCOPE derived;
SCOPE base;
SCOPE found;
SYMBOL vfn_sym;
SYMBOL vfn_override;
target_offset_t this_delta;
target_offset_t retn_delta;
} vfn_opt_walk;
typedef struct {
CLASS_VBTABLE *tables;
SCOPE start;
unsigned already_done : 1;
} vbtable_walk;
typedef struct {
CLASS_VFTABLE *tables;
CLASS_VFTABLE *curr;
BASE_STACK *top;
BASE_STACK *parent;
SCOPE start;
SCOPE final;
SCOPE base;
SCOPE derived;
THUNK_ACTION *thunk;
VSTK_CTL disambig;
unsigned OK_to_diagnose : 1;
unsigned already_done : 1;
unsigned thunk_code : 1;
} vftable_walk;
typedef struct { /* I - input, O - output */
SCOPE start; /* I: type of (*p) in "p->C::a" */
SCOPE disambiguate; /* I: C in "p->C::a" */
SCOPE ignore; /* I: don't search here */
char *name; /* I: a in "p->C::a" */
TYPE type; /* I: T in "p->operator T()" */
TYPE fn_type; /* I: type of virtual fn */
SYMBOL fn_sym; /* I: sym of virtual fn */
special_name_fn is_special; /* I: fn to check for special names */
unsigned consider_mask; /* I: mask to check curr scope */
BASE_STACK *top; /* T: temp for storing 'top' */
MSG_NUM error_msg; /* O: error message to use */
MSG_NUM info_msg; /* O: info message for above msg */
SYMBOL info1; /* O: parm for first info msg */
SYMBOL info2; /* O: parm for second info msg */
SYMBOL_NAME vfn_name; /* O: vfn that shares table */
FNOV_LIST *user_conv_list; /* O: list of user convs in hierarchy */
PATH_CAP *paths; /* O: paths to name */
unsigned path_count; /* O: # of paths to name */
inherit_flag perm; /* O: permission of path to name */
type_flag this_qualifier; /* I: T cv-qual *this; cv-qual */
unsigned virtual_override : 1; /* I: find vfns with same name*/
unsigned user_conversion : 1; /* I: find conversion to 'type' */
unsigned specific_user_conv : 1; /* I: must find specific conv */
unsigned best_user_conv : 1; /* I: must find best conv */
unsigned check_special : 1; /* I: use is_special() */
unsigned no_inherit : 1; /* I: no base classes searched */
unsigned only_inherit : 1; /* I: only base classes searched */
unsigned only_bases : 1; /* I: direct base classes searched */
unsigned ok_to_diagnose : 1; /* I: flag any errors found */
unsigned find_all : 1; /* I: find all pathes to base */
unsigned ignore_access : 1; /* I: access isn't important */
unsigned saw_class : 1; /* I: class scope was seen */
unsigned ambiguous : 1; /* O: ambiguity detected */
unsigned overload_reqd : 1; /* O: overload affects ambiguity */
unsigned use_this : 1; /* O: access could use "this" */
unsigned no_this : 1; /* O: access can't use "this" */
unsigned saw_function : 1; /* O: function scope was seen */
unsigned use_index : 1; /* O: use index of virtual fn */
unsigned return_thunk : 1; /* O: vfn needs return thunk */
unsigned protected_OK : 1; /* O: protected sym can be accessed */
unsigned file_class_done : 1; /* O: C::id search from file-scope done */
unsigned file_ns_done : 1; /* O: N::id search from file-scope done */
unsigned same_table : 1; /* O: vfn name is in same table */
unsigned lookup_error : 1; /* O: error to report from lookup */
} lookup_walk;
typedef struct access_data {
BASE_PATH *path;
SCOPE access;
SCOPE member;
SCOPE located;
inherit_flag perm;
unsigned protected_OK : 1;
} access_data;
typedef struct qualify_stack QUALIFICATION;
struct qualify_stack {
QUALIFICATION *next;
SCOPE reset;
SCOPE access;
};
SCOPE g_CurrScope;
SCOPE g_FileScope;
SCOPE g_InternalScope;
SYMBOL ChipBugSym;
SYMBOL DFAbbrevSym;
SYMBOL PCHDebugSym;
static char bool_zapped_char;
static char static_assert_zapped_char;
extern SCOPE GetCurrScope(void)
{
return g_CurrScope;
}
extern SCOPE SetCurrScope(SCOPE newScope)
{
SCOPE oldScope = g_CurrScope;
g_CurrScope = newScope;
#ifndef NDEBUG
if( PragDbgToggle.dump_scopes )
{
printf("Set new scope to 0x%.08X\n", newScope);
if(newScope)
{
printf("===============================================================================\n");
DumpScope(newScope);
printf("===============================================================================\n");
}
}
#endif
return oldScope;
}
extern SCOPE GetFileScope(void)
{
return g_FileScope;
}
extern SCOPE SetFileScope(SCOPE newScope)
{
SCOPE oldScope = g_FileScope;
g_FileScope = newScope;
return oldScope;
}
extern SCOPE GetInternalScope(void)
{
return g_InternalScope;
}
extern SCOPE SetInternalScope(SCOPE newScope)
{
SCOPE oldScope = g_InternalScope;
g_InternalScope = newScope;
return oldScope;
}
#define BLOCK_SYM_REGION 64
#define BLOCK_USING_NS 64
#define BLOCK_NAME_SPACE 64
#define BLOCK_SCOPE 64
#define BLOCK_SYMBOL 64
#define BLOCK_SYMBOL_NAME 64
#define BLOCK_BASE_STACK 16
#define BLOCK_BASE_PATH 16
#define BLOCK_PATH_CAP 16
#define BLOCK_SEARCH_RESULT 16
#define BLOCK_GEN_LEAP 16
#define BLOCK_QUALIFICATION 16
#define BLOCK_SYMBOL_EXCLUDE 16
static carve_t carveSYM_REGION;
static carve_t carveUSING_NS;
static carve_t carveNAME_SPACE;
static carve_t carveSCOPE;
static carve_t carveSYMBOL;
static carve_t carveSYMBOL_NAME;
static carve_t carveBASE_STACK;
static carve_t carveBASE_PATH;
static carve_t carvePATH_CAP;
static carve_t carveSEARCH_RESULT;
static carve_t carveGEN_LEAP;
static carve_t carveQUALIFICATION;
static carve_t carveSYMBOL_EXCLUDE;
ExtraRptCtr( syms_defined );
ExtraRptCtr( scopes_alloced );
ExtraRptCtr( scopes_kept );
ExtraRptCtr( scopes_searched );
ExtraRptCtr( scopes_closed );
ExtraRptCtr( nonempty_scopes_closed );
ExtraRptCtr( cnv_total );
ExtraRptCtr( cnv_quick );
ExtraRptCtr( cnv_found );
static SAVE_MAPPING *mappingList; // member pointer mapping array list
static char *uniqueNameSpaceName; // name for unique namespaces
static NAME_SPACE *allNameSpaces; // list of all namespaces
static inherit_flag verifyAccess( access_data * );
static inherit_flag checkBaseAccess( SCOPE, SCOPE, derived_status );
#ifndef NDEBUG
static void printScopeName( SCOPE scope, char *suffix )
{
char *name;
switch( scope->id ) {
case SCOPE_CLASS:
name = ScopeClass( scope )->u.c.info->name;
if( name == NULL ) {
name = "**un-named**";
}
printf( "%s ", name );
break;
case SCOPE_FILE:
name = ScopeNameSpaceFormatName( scope );
if( name == NULL ) {
printf( "FILE " );
} else {
printf( "%s ", name );
}
break;
case SCOPE_FUNCTION:
printf( "%s() ", ScopeFunction( scope )->name->name );
break;
case SCOPE_BLOCK:
printf( "{} " );
break;
default:
printf( "SCOPE(%02x) ", scope->id );
}
if( suffix != NULL ) {
fputs( suffix, stdout );
}
}
static void printSymbolName( SYMBOL sym )
{
printScopeName( SymScope( sym ), NULL );
printf( ":: %s ", sym->name->name );
}
static void dumpThunk( THUNK_ACTION *thunk )
{
SYMBOL sym;
if( ! PragDbgToggle.dump_vftables ) {
return;
}
printf( "thunk:" );
if( thunk->last_entry ) {
printf( " last_entry" );
}
if( thunk->possible_ambiguity ) {
printf( " possible_ambiguity" );
}
if( ScopePureVirtualThunk( thunk ) != NULL ) {
printf( " pure_virtual" );
}
putchar( '\n' );
printf( "- " );
sym = thunk->sym;
printSymbolName( sym );
putchar( '\n' );
if( thunk->delta ) {
printf( "- this -= %xh\n", thunk->delta );
}
if( thunk->ctor_disp ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?