csym.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,120 行 · 第 1/3 页
C
1,120 行
sym_len = strlen( sym->name );
hsym = SymHashAlloc( sizeof( struct sym_hash_entry ) + sym_len );
hsym->sym_type = NULL;
if( sym->stg_class == SC_TYPEDEF ) { /* 28-feb-92 */
typ = sym->sym_type; {
typ = TypeNode( TYPE_TYPEDEF, typ );
typ->u.typedefn = sym_handle;
sym->sym_type = typ;
}
hsym->sym_type = typ;
}
hsym->level = sym->level;
far_memcpy( hsym->name, sym->name, sym_len + 1 );
if( sym->name[0] != '.' ) { /* 19-mar-93 */
CMemFree( sym->name );
}
sym->name = NULL;
hsym->handle = sym_handle;
return( hsym );
}
SYM_HANDLE SymAdd( int h, SYMPTR sym )
{
SYM_HASHPTR hsym;
SYM_HASHPTR *head;
if( sym == NULL ) return( 0 );
if( SymLevel == 0 ) {
++GblSymCount;
} else {
++LclSymCount;
}
NewSym();
sym->level = SymLevel;
hsym = SymHash( sym, (SYM_HANDLE)NextSymHandle );
sym->info.hash_value = h;
head = &HashTab[ h ]; /* add name to head of list */
for( ;; ) {
if( *head == NULL ) break;
if( ((*head)->level & 0x7F) <= SymLevel ) break;
head = &(*head)->next_sym;
}
hsym->next_sym = *head; /* add name to head of list */
*head = hsym;
return( hsym->handle );
}
SYM_HANDLE SymAddL0( int h, SYMPTR new_sym ) /* add symbol to level 0 */
{
SYM_HASHPTR hsym;
SYM_HASHPTR new_hsym;
if( new_sym == NULL ) return( 0 );
++GblSymCount;
NewSym();
new_sym->level = 0;
new_hsym = SymHash( new_sym, (SYM_HANDLE)NextSymHandle );
new_hsym->next_sym = NULL;
new_sym->info.hash_value = h;
hsym = HashTab[h];
if( hsym == NULL ) {
HashTab[h] = new_hsym;
} else {
while( hsym->next_sym != NULL ) {
hsym = hsym->next_sym;
}
hsym->next_sym = new_hsym; /* add new symbol to end of list */
}
return( new_hsym->handle );
}
SYM_HANDLE GetNewSym( SYMPTR sym, char id, TYPEPTR typ, int stg_class )
{
char name[3];
SYM_HANDLE sym_handle;
name[0] = '.';
name[1] = id;
name[2] = '\0';
SymCreate( sym, name );
sym_handle = SymAdd( 0, sym );
sym->sym_type = typ;
sym->stg_class = stg_class;
sym->flags |= SYM_REFERENCED | SYM_TEMP;
return( sym_handle );
}
SYM_HANDLE MakeNewSym( SYMPTR sym, char id, TYPEPTR typ, int stg_class )
{
SYM_HANDLE sym_handle;
sym_handle = GetNewSym( sym, id, typ, stg_class );
if( SymLevel != 0 ) { /* 07-may-91 */
sym->handle = CurFunc->u.func.locals;
CurFunc->u.func.locals = sym_handle;
}
++TmpSymCount;
return( sym_handle );
}
SYM_HANDLE SymLook( int h, char *id )
{
int len;
SYM_HASHPTR hsym;
len = strlen( id ) + 1;
for( hsym = HashTab[h]; hsym; hsym = hsym->next_sym ) {
if( far_strcmp( hsym->name, id, len ) == 0 ) {
return( hsym->handle );
}
}
return( 0 );
}
SYM_HANDLE SymLookTypedef( int h, char *id, SYMPTR sym ) /* 28-feb-92 */
{
int len;
SYM_HASHPTR hsym;
len = strlen( id ) + 1;
for( hsym = HashTab[h]; hsym; hsym = hsym->next_sym ) {
if( far_strcmp( hsym->name, id, len ) == 0 ) {
if( hsym->sym_type == NULL ) break;
sym->sym_type = hsym->sym_type;
sym->stg_class = SC_TYPEDEF;
sym->level = hsym->level;
return( hsym->handle );
}
}
return( 0 );
}
SYM_HANDLE Sym0Look( int h, char *id ) /* look for symbol on level 0 */
{
int len;
SYM_HASHPTR hsym;
len = strlen( id ) + 1;
for( hsym = HashTab[h]; hsym; hsym = hsym->next_sym ) {
if( far_strcmp( hsym->name, id, len ) == 0 ) { /* name matches */
if( hsym->level == 0 ) return( hsym->handle );
}
}
return( 0 );
}
local void ChkReference( SYM_ENTRY *sym, SYM_NAMEPTR name )
{
if( sym->flags & SYM_DEFINED ) {
if( sym->stg_class != SC_EXTERN ) {
if( !(sym->flags & SYM_REFERENCED) ) {
if( !(sym->flags & SYM_IGNORE_UNREFERENCE) ) { /*25-apr-91*/
SetSymLoc( sym );
if( sym->is_parm ) {
CWarn( WARN_PARM_NOT_REFERENCED,
ERR_PARM_NOT_REFERENCED, name );
} else {
CWarn( WARN_SYM_NOT_REFERENCED,
ERR_SYM_NOT_REFERENCED, name );
}
}
} else if( ! (sym->flags & SYM_ASSIGNED) ) {
if( sym->sym_type->decl_type != TYPE_ARRAY
&& sym->stg_class != SC_STATIC ) { /* 06-aug-90 */
SetSymLoc( sym );
CWarn( WARN_SYM_NOT_ASSIGNED,
ERR_SYM_NOT_ASSIGNED, name );
}
}
}
}
}
local void ChkIncomplete( SYM_ENTRY *sym, SYM_NAMEPTR name )
{
TYPEPTR typ;
if( sym->stg_class != SC_TYPEDEF ) {
if( !(sym->flags & (SYM_FUNCTION | SYM_TEMP)) ) {
if( (sym->flags & SYM_REFERENCED) == 0 ) {
/* if it wasn't referenced, don't worry 19-sep-90 AFS */
if( sym->stg_class == SC_EXTERN ) { /* 08-nov-91 */
return;
}
}
typ = sym->sym_type;
SKIP_TYPEDEFS( typ );
if( SizeOfArg( typ ) == 0 && typ->decl_type != TYPE_FUNCTION
&& typ->decl_type != TYPE_DOT_DOT_DOT ) {
if( !(sym->stg_class == SC_EXTERN) ) {
SetSymLoc( sym );
CErr( ERR_INCOMPLETE_TYPE, name );
}
}
}
}
}
local void ChkDefined( SYM_ENTRY *sym, SYM_NAMEPTR name )
{
if( sym->flags & SYM_DEFINED ) {
if( sym->stg_class == SC_STATIC ) {
if( !(sym->flags & SYM_REFERENCED) ) {
if( !(sym->flags & SYM_IGNORE_UNREFERENCE) ) { /*14-may-91*/
SetSymLoc( sym );
CWarn( WARN_SYM_NOT_REFERENCED,
ERR_SYM_NOT_REFERENCED, name );
}
}
}
} else { /* not defined */
if( sym->flags & SYM_REFERENCED ) { /* 28-apr-88 AFS */
if( sym->stg_class == SC_STATIC ) {
if( sym->flags & SYM_FUNCTION ) {
SetSymLoc( sym );
CErr( ERR_FUNCTION_NOT_DEFINED, name );
}
} else if( sym->stg_class == SC_FORWARD ) {
SetSymLoc( sym ); /* 03-jun-91 */
sym->stg_class = SC_EXTERN;
if( CompFlags.extensions_enabled ) {
/* No prototype ever found. In ISO mode, we already warned
* in cexpr.c when unprototyped function was first seen.
*/
CWarn( WARN_ASSUMED_IMPORT, ERR_ASSUMED_IMPORT, name );
}
}
}
}
}
local void ChkFunction( SYMPTR sym, SYM_NAMEPTR name )
{
#if _CPU == 8086 || _CPU == 386 /* 05-nov-91 */
if( sym->stg_class == SC_STATIC ) {
if( sym->flags & SYM_ADDR_TAKEN ) {
if( CompFlags.using_overlays ) {
CWarn( WARN_ADDR_OF_STATIC_FUNC_TAKEN, /* 25-may-92 */
ERR_ADDR_OF_STATIC_FUNC_TAKEN, name );
}
} else {
if( (sym->attrib & (FLAG_FAR | FLAG_NEAR)) == 0
&& (TargetSwitches & BIG_CODE)
&& !CompFlags.multiple_code_segments ) {
sym->attrib |= FLAG_NEAR;
}
}
}
#else
sym = sym;
name = name;
#endif
}
#if _CPU == 370
/*** External name control for IBM 370 restrictions ***/
struct xlist {
struct xlist *next;
char xname[8+1];
};
local void InitExtName( struct xlist **where )
/*** Init extern name list***/
{
*where = NULL;
}
local void ChkExtName( struct xlist **link, SYM_ENTRY *sym,
SYM_NAMEPTR name )
/***Restricted extern names i.e 8 char upper check *****/
{
struct xlist *new, *curr;
new = CMemAlloc( sizeof ( struct xlist ) );
Copy8( name, new->xname );
strupr( new->xname );
while( (curr = *link) != NULL ){
int cmp;
cmp = strcmp( new->xname, curr->xname );
if( cmp == 0 ){
SetSymLoc( sym );
CErr( ERR_DUPLICATE_ID, name, new->xname );
CMemFree( new );
return;
}else if( cmp < 0 ){
break;
}
link = &curr->next;
}
new->next = *link;
*link = new;
}
local void FiniExtName( struct xlist *head )
/*** Free xname list **********************/
{
struct xlist *next;
while( head != NULL ) {
next = head->next;
CMemFree( head );
head = next;
}
}
static void Copy8( char const *nstr, char *name )
/***************************************************/
{
char *curr;
for( curr = name; curr < &name[8]; curr++,nstr++ ) {
if( *nstr == '\0' ) break;
*curr = *nstr;
}
*curr = '\0';
}
#endif /* IBM370 names */
/* divide all the global symbols into buckets based on size of the item
0 - functions
1 - 1-byte items
2 - odd-length items
3 - 2-byte items
4 - even-length items (that are not a multiple of 4 in size)
5 - 4-byte items (or multiple of 4, but not a multiple of 8)
6 - 8-byte items (or multiple of 8)
*/
#define BUCKETS 7
local int SymBucket( SYM_ENTRY *sym ) /* determine bucket # for symbol */
{
int bucket;
unsigned long size;
bucket = 0; /* assume its a function */
if( (sym->flags & SYM_FUNCTION) == 0 ) { /* if variable */
size = SizeOfArg( sym->sym_type );
switch( size % 8 ) {
case 0: /* multiple of 8 */
bucket = 6;
break;
case 4: /* multiple of 4 */
bucket = 5;
break;
case 1:
case 3:
case 5:
case 7:
bucket = 2; /* odd length objects */
if( size == 1 )
bucket = 1;
break;
case 2:
case 6:
bucket = 4; /* even length objects */
if( size == 2 )
bucket = 3;
break;
}
}
return( bucket );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?