csym.c

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

C
1,120
字号
/****************************************************************************
*
*                            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:  C compiler symbol table management.
*
****************************************************************************/


#include "cvars.h"
#include "cgswitch.h"


#pragma intrinsic( memcpy )

extern  void    CSegFree( SEGADDR_T );
extern  TREEPTR CurFuncNode;

unsigned    SymTypedef;

static  void    NewSym( void );

static unsigned Cached_sym_num;
static void     *Cached_sym_addr;
static struct sym_stats {
    unsigned    get, getptr, replace, read, write;
} SymStats;
static unsigned FirstSymInBuf;
static char     *SymBufPtr;
static unsigned NextSymHandle;

void SymInit( void )
{
    int         i;
    unsigned    seg_num;

    NextSymHandle = 0;
    Cached_sym_num = ~0u;
    SymLevel = 0;
    GblSymCount = 0;
    LclSymCount = 0;
    HashTab = (SYM_HASHPTR *)SymHashAlloc( SYM_HASH_SIZE * sizeof( SYM_HASHPTR ) );
    for( i = 0; i < SYM_HASH_SIZE; i++ ) {
        HashTab[i] = NULL;
    }
    TagHead = NULL;
    DeadTags = NULL;
    LabelHead = NULL;
    HashFreeList = NULL;
    NextSymHandle = 0;
    ErrSym = (FIELDPTR)CPermAlloc( sizeof( FIELD_ENTRY ) );
    ErrSym->field_type = TypeDefault();
    SymBufNum = 0;
    FirstSymInBuf = 0;
    LastSymBuf = 0;
    SymBufDirty = 0;
    CurFuncHandle = 0;
    for( seg_num = 0; seg_num < MAX_SYM_SEGS; ++seg_num ) {
        SymSegs[ seg_num ].allocated = 0;
    }
    SymSegment = AllocSegment( &SymSegs[0] );
    SymBufPtr = (char *)SymSegment;
    EnumInit();
}


void SymFini( void )
{
    unsigned        seg_num;
    struct seg_info *si;

    for( seg_num = 0; seg_num < MAX_SYM_SEGS; ++seg_num ) {
        si = &SymSegs[ seg_num ];
        if( si->allocated ) {
            CSegFree( si->index );
        }
    }
    if( CompFlags.extra_stats_wanted ) {
        printf( "SymStats: get = %u, rep = %u, read = %u, write = %u"
            ", typedef = %u\n",
        SymStats.get, SymStats.replace, SymStats.read, SymStats.write,
        SymTypedef );
    }
}

unsigned SymGetNumSyms( void )
{
    return( NextSymHandle + 1 );
}

unsigned SymGetNumSpecialSyms( void )
{
    return( (unsigned)SpecialSyms );
}

SYM_HANDLE SymGetFirst( void )
{
    return( 0 );
}

SYM_HANDLE SymGetNext( SYM_HANDLE sym_handle )
{
    unsigned    handle = (unsigned)sym_handle;

    if( handle < NextSymHandle )
        return( (SYM_HANDLE)(handle + 1) );
    else
        return( SYM_INVALID );
}

// This is a temporary function, to be deleted later
void SetNextSymHandle( unsigned val )
{
    NextSymHandle = val;
}

SYM_HANDLE SegSymbol( char *name, int segment )             /* 15-mar-92 */
{
    SYM_ENTRY       sym;
    SYM_HANDLE      handle;

    NewSym();
    handle = (SYM_HANDLE)NextSymHandle;
    memset( &sym, 0, sizeof( SYM_ENTRY ) );
    sym.sym_type = GetType( TYPE_USHORT );
    sym.name = name;
    sym.stg_class = SC_STATIC;
    sym.level = 1;  // make invisible
    SymReplace( &sym, handle );
    if( segment ) {
        SetSegSymHandle( handle, segment );
    }
    return( handle );
}

SYM_HANDLE SpcSymbol( char *name, int stg_class )
{
    SYM_ENTRY       sym;

    NewSym();
    memset( &sym, 0, sizeof( SYM_ENTRY ) );
    sym.sym_type = GetType( TYPE_USHORT );
    sym.name = name;
    sym.stg_class = stg_class;
    SymReplace( &sym, (SYM_HANDLE)NextSymHandle );
    return( (SYM_HANDLE)NextSymHandle );
}

void SpcSymInit( void )
{
    TYPEPTR     ptr2char;
    TYPEPTR     typ;
    SYM_ENTRY   sym;

    /* first entry into SpecialSyms */
    memset( &sym, 0, sizeof( SYM_ENTRY ) );
    sym.handle = 0;
    sym.sym_type = GetType( TYPE_VOID );
    SymReplace( &sym, 0 );
#ifdef __SEH__
    NewSym();                           /* 05-dec-92 */
    TrySymHandle = (SYM_HANDLE)NextSymHandle;               /* create special _try sym */
    sym.stg_class = SC_AUTO;
    sym.name = ".try";
    sym.sym_type = GetType( TYPE_VOID );
    SymReplace( &sym, (SYM_HANDLE)NextSymHandle );
#endif
    /* create special symbol for "extern unsigned int __near __chipbug" */
    NewSym();
    SymChipBug = (SYM_HANDLE)NextSymHandle;
    sym.stg_class = SC_EXTERN;
    sym.name = "__chipbug";
    sym.sym_type = GetType( TYPE_UINT );
    SymReplace( &sym, (SYM_HANDLE)NextSymHandle );

    /* create special symbol table entry for __segname("_CODE") */
    Sym_CS = SegSymbol( ".CS", SEG_CODE );              /* 18-jan-92 */
    /* create special symbol table entry for __segname("_STACK") */
    Sym_SS = SegSymbol( ".SS", SEG_STACK );             /* 13-dec-92 */
    /* create special symbol table entry for __segname("_CONST") */
    SegSymbol( ".CONST", SEG_CONST );
    /* create special symbol table entry for __segname("_DATA") */
    SegSymbol( ".DS", SEG_DATA );

    SpecialSyms = (SYM_HANDLE)NextSymHandle;

    /* Create special symbol table entries for use by stosw, stosb pragmas
     * This should be a TYPE_FUNCTION returning pointer to char
     */
    ptr2char = PtrNode( GetType( TYPE_CHAR ), FLAG_NONE, SEG_DATA );
    typ = TypeNode( TYPE_FUNCTION, ptr2char );

    /* The ".stosw" functions are done through internal AUX entries */

    SymSTOW  = MakeFunction( "_inline_.stosw",  GetType( TYPE_VOID ) );
    SymSTOWB = MakeFunction( "_inline_.stoswb", GetType( TYPE_VOID ) );
    SymMIN       = MakeFunction( "_inline_.min", GetType( TYPE_UINT ) );
    SymMAX       = MakeFunction( "_inline_.max", GetType( TYPE_UINT ) );
    SymMEMCMP= MakeFunction( "_inline_memcmp", GetType( TYPE_INT ) );
    typ = TypeNode( TYPE_FUNCTION, GetType(TYPE_INT) );
#if _CPU == 386
    SymSTOD  = MakeFunction( "_inline_.stosd",  GetType( TYPE_VOID ) );
    SymSTOSB = MakeFunction( "__STOSB", GetType( TYPE_VOID ) );
    SymSTOSD = MakeFunction( "__STOSD", GetType( TYPE_VOID ) );
#endif
#ifdef __SEH__
    SymTryInit = MakeFunction( "__TryInit2", typ );      /* 05-dec-92 */
    SymTryFini = MakeFunction( "__TryFini2", typ );      /* 05-dec-92 */
    SymExcept  = MakeFunction( "__Except2", typ );       /* 05-dec-92 */
    SymFinally = MakeFunction( "__Finally2", typ );      /* 23-mar-94 */
    SymTryUnwind = MakeFunction( "__TryUnwind2", typ );  /* 16-apr-94 */
#endif
    SymCover = MakeFunction( "__COVERAGE", typ );       /* 04-apr-92 */
    MakeFunction( "__C", typ );                 /* 04-apr-92 */
    SymGet( &sym, (SYM_HANDLE)NextSymHandle );
    sym.stg_class = SC_STATIC;
    SymReplace( &sym, (SYM_HANDLE)NextSymHandle );
}


SYM_HANDLE MakeFunction( char *id, TYPEPTR typ )
{
    SYM_ENTRY   sym;

    memset( &sym, 0, sizeof( SYM_ENTRY ) );
    sym.name = id;
    sym.stg_class = SC_EXTERN;
    sym.flags = SYM_FUNCTION;
    sym.handle = SpecialSyms;
    sym.sym_type = typ;
    NewSym();
    SpecialSyms = (SYM_HANDLE)NextSymHandle;
    SymReplace( &sym, (SYM_HANDLE)NextSymHandle );
    return( (SYM_HANDLE)NextSymHandle );
}


static void NewSym( void )
{
    ++NextSymHandle;
    if( NextSymHandle >= LARGEST_SYM_INDEX ) {
        CErr1( ERR_INTERNAL_LIMIT_EXCEEDED );
        CSuicide();
    }
}


void SymCreate( SYMPTR sym, char *id )
{
    memset( sym, 0, sizeof( SYM_ENTRY ) );
    sym->name = CMemAlloc( strlen( id ) + 1 );
    strcpy( sym->name, id );
    if( SrcFile != NULL ) {     /* 26-feb-90: could be at end-of-file */
        sym->defn_file_index = SrcFile->src_flist->index; /* 21-dec-93 */
    }
    sym->d.defn_line = TokenLine;
}


void SymAccess( unsigned sym_num )
{
    unsigned        buf_num;
    unsigned        seg_num;
    struct seg_info *si;

    Cached_sym_num = sym_num;
    if( sym_num < FirstSymInBuf || sym_num >= FirstSymInBuf + SYMS_PER_BUF ) {
        buf_num = sym_num / SYMS_PER_BUF;
        if( SymBufDirty ) {
            ++SymStats.write;
            si = &SymSegs[ SymSegNum ];
            if( !si->allocated ) {
                SymSegment = AllocSegment( si );
            }
            SymBufDirty = 0;
        }
        seg_num = buf_num / SYMBUFS_PER_SEG;
        si = &SymSegs[ seg_num ];
        SymSegment = AccessSegment( si );
        SymBufPtr = (char *)SymSegment + (buf_num % SYMBUFS_PER_SEG) * SYM_BUF_SIZE;
        SymBufNum = buf_num;
        SymSegNum = seg_num;
        FirstSymInBuf = buf_num * SYMS_PER_BUF;
    }
    Cached_sym_addr = SymBufPtr + (sym_num - FirstSymInBuf) * sizeof( SYM_ENTRY );
}

SYMPTR SymGetPtr( SYM_HANDLE sym_handle )
{
    unsigned    handle = (unsigned)sym_handle;
    SYMPTR      symptr;

    ++SymStats.getptr;
    if( sym_handle == CurFuncHandle ) {
        symptr = &CurFuncSym;
    } else if( handle < PCH_MaxSymHandle ) {        /* 08-mar-94 */
        symptr = PCH_SymArray[ handle ];
    } else {
        if( handle != Cached_sym_num ) {
            SymAccess( handle );
        }
        symptr = Cached_sym_addr;
    }
    return( symptr );
}

void SymGet( SYMPTR sym, SYM_HANDLE sym_handle )
{
    unsigned    handle = (unsigned)sym_handle;
    SYMPTR      symptr;

    ++SymStats.get;
    if( sym_handle == CurFuncHandle ) {
        symptr = &CurFuncSym;
    } else if( handle < PCH_MaxSymHandle ) {        /* 08-mar-94 */
        symptr = PCH_SymArray[ handle ];
    } else {
        if( handle != Cached_sym_num ) {
            SymAccess( handle );
        }
        symptr = Cached_sym_addr;
    }
    memcpy( sym, symptr, sizeof( SYM_ENTRY ) );
}


void SymReplace( SYMPTR sym, SYM_HANDLE sym_handle )
{
    unsigned    handle = (unsigned)sym_handle;

    ++SymStats.replace;
    if( sym_handle == CurFuncHandle ) {
        memcpy( &CurFuncSym, sym, sizeof( SYM_ENTRY ) );
    }
    if( handle < PCH_MaxSymHandle ) {       /* 08-mar-94 */
        memcpy( PCH_SymArray[ handle ], sym, sizeof( SYM_ENTRY ) );
    } else {
        if( handle != Cached_sym_num ) {
            SymAccess( handle );
        }
        memcpy( Cached_sym_addr, sym, sizeof( SYM_ENTRY ) );
        SymBufDirty = 1;
    }
}


SYM_HASHPTR SymHash( SYMPTR sym, SYM_HANDLE sym_handle )
{
    SYM_HASHPTR     hsym;
    TYPEPTR         typ;
    int             sym_len;

⌨️ 快捷键说明

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