📄 csym.c
字号:
/****************************************************************************
*
* 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 + -