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