⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csym.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*
*                            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"
#include "pragmas.h"

#pragma intrinsic(memcpy)

extern  void    CSegFree( SEGADDR_T );
extern  TREEPTR CurFuncNode;

static void NewSym( void );


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

void SymInit()
{
    int         i;
    unsigned    seg_num;

    Cached_sym_num = ~0u;
    SymLevel = 0;
    GblSymCount = 0;
    LclSymCount = 0;
    HashTab = (SYM_HASHPTR __FAR *)
                 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()
{
    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 );
    }
}

SYM_HANDLE SegSymbol( char *name )                      /* 15-mar-92 */
{
    auto SYM_ENTRY      sym;

    NewSym();
    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, NextSymHandle );
    return( NextSymHandle );
}

SYM_HANDLE SpcSymbol( char *name, int stg_class )
{
    auto 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, NextSymHandle );
    return( NextSymHandle );
}

void SpcSymInit()
{
    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 = NextSymHandle;               /* create special _try sym */
    sym.stg_class = SC_AUTO;
    sym.name = ".try";
    sym.sym_type = GetType( TYPE_VOID );
    SymReplace( &sym, NextSymHandle );
#endif
    /* create special symbol for "extern unsigned int __near __chipbug" */
    NewSym();
    SymChipBug = NextSymHandle;
    sym.stg_class = SC_EXTERN;
    sym.name = "__chipbug";
    sym.sym_type = GetType( TYPE_UINT );
    SymReplace( &sym, NextSymHandle );

    /* create special symbol table entry for __segname("_CODE") */
    Sym_CS = SegSymbol( ".CS" );                        /* 18-jan-92 */
    /* create special symbol table entry for __segname("_STACK") */
    Sym_SS = SegSymbol( ".SS" );                        /* 13-dec-92 */

    SpecialSyms = 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 ), 0, 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, NextSymHandle );
    sym.stg_class = SC_STATIC;
    SymReplace( &sym, NextSymHandle );
}


SYM_HANDLE MakeFunction( char *id, TYPEPTR typ )
{
    auto 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 = NextSymHandle;
    SymReplace( &sym, NextSymHandle );
    return( 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 )
{
    SYMPTR      symptr;

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

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

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


void SymReplace( SYMPTR sym, SYM_HANDLE sym_handle )
{
    ++SymStats.replace;
    if( sym_handle == CurFuncHandle ) {
        memcpy( &CurFuncSym, sym, sizeof( SYM_ENTRY ) );
    }
    if( sym_handle < PCH_MaxSymHandle ) {       /* 08-mar-94 */
        memcpy( PCH_SymArray[ sym_handle ], sym, sizeof( SYM_ENTRY ) );
    } else {
        if( sym_handle != Cached_sym_num ) SymAccess(sym_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;

    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 __FAR *head;

    if( sym == NULL ) return( 0 );
    if( SymLevel == 0 ) {
        ++GblSymCount;
    } else {

⌨️ 快捷键说明

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