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