fnname.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,410 行 · 第 1/3 页
C
1,410 行
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "plusplus.h"
#include <stdarg.h>
#include <stddef.h>
#include <ctype.h>
#include "ppintnam.h"
#include "errdefns.h"
#include "memmgr.h"
#include "class.h"
#include "ppops.h"
#include "vbuf.h"
#include "specname.h"
#include "name.h"
#include "toggle.h"
#include "cgfront.h"
#include "fmttype.h"
#include "initdefs.h"
#include "preproc.h"
#include "pcheader.h"
#include "stats.h"
#include "srcfile.h"
#include "pragdefn.h"
typedef enum { // type mangling control
TM_INCLUDE_FIRST_DIM= 0x01, // - include first dimension in array type mangling
TM_NO_INITIAL_MOD = 0x02, // - don't include initial mods
TM_FIRST_DIM = 0x80, // * local flag used in appendTypeContinue
TM_NULL = 0x00
} tm_control;
static char *operatorNamesStr[] = {
#include "ppopfstr.h"
};
#define MAX_OP_NAMES ARRAY_SIZE( operatorNamesStr )
static CGOP const operatorSameAs[] = {
#define PPOPOP( s, sa ) delim CO_##sa
#include "ppopsdef.h"
};
static char *specialNamesStr[] = {
#define SPECNAME_DEFINE
#include "specname.h"
};
#define MAX_SPECIAL_NAMES ARRAY_SIZE( specialNamesStr )
static VBUF mangled_name; // buffer for working on name
static char *objNameBuff;
static char *specialNames[ MAX_SPECIAL_NAMES ];
static char *operatorNames[ MAX_OP_NAMES + 1 ]; // one more for sentinel
#define MAX_REPLICATE 10
typedef struct replicate_desc {
char *ptr;
size_t len;
} replicate_desc;
static replicate_desc replicate[MAX_REPLICATE];
static int next_replicate;
ExtraRptCtr( ctr_lookups );
ExtraRptCtr( ctr_lookups_slow );
ExtraRptCtr( ctr_debug_names );
ExtraRptCtr( ctr_debug_scoped_names );
static void replicateInit( void )
{
next_replicate = 0;
}
static int replicateSearch( char *name )
{
int i;
int len = strlen( name );
#if 0 // fix assertion failures next release
// demangler will not insert these names into its replicate table
DbgAssert( name[0] != '$' );
#endif
for( i = 0 ; i < next_replicate ; i++ ) {
if( len == replicate[i].len ) {
if( strcmp( name, replicate[i].ptr ) == 0 ) return( i );
}
}
if( i < MAX_REPLICATE ) {
replicate[i].len = len;
replicate[i].ptr = name;
next_replicate++;
}
return( -1 );
}
static uint_32 objNameHash( uint_32 h, char *s )
{
uint_32 c;
uint_32 g;
// don't change this in a patch
for(;;) {
/* ( h & ~0x0ffffff ) == 0 is always true here */
c = *s;
if( c == 0 ) break;
h = (h << 4) + c;
g = h & ~0x0ffffff;
h ^= g;
h ^= g >> 24;
++s;
}
return( h );
}
static TYPE typeLookAhead( TYPE type, type_flag *flags, void **base )
{
return TypeModExtract( type
, flags
, base
, TC1_NOT_MEM_MODEL | TC1_NOT_ENUM_CHAR );
}
static boolean nameHasPrefix( // TEST IF NAME HAS A PREFIX
const char *name, // - name to be tested
const char *prefix ) // - prefix
{
boolean retn; // - TRUE ==> has prefix
for( ; ; ++name, ++prefix ) {
if( *prefix == '\0' ) {
retn = TRUE;
break;
}
if( *prefix != *name ) {
retn = FALSE;
break;
}
}
return retn;
}
static void appendChar( // APPEND A CHARACTER
char chr ) // - the character
{
VStrConcChr( &mangled_name, chr );
}
static void prependChar( // PREPEND A CHARACTER
char chr ) // - the character
{
VStrPrepChr( &mangled_name, chr );
}
static void appendStr( // APPEND A STRING
char *str ) // - the string
{
if( str != NULL ) {
VStrConcStr( &mangled_name, str );
}
}
static void appendZZLen( // CONCATENATE A 'ZZ' length
unsigned len ) // - the length
{
char sbuf[16];
ultoa( len, sbuf, 36 );
switch( strlen( sbuf ) ){
case 1:
appendChar( '0' );
/* fall through */
case 2:
appendStr( sbuf );
break;
default:
CFatal( "internal name length > 36*36" );
break;
}
}
static void appendStrWithLen( // APPEND A STRING FOR LENGTH CHARS
char *str, // - the string
unsigned len ) // - how many chars to concatenate
{
while( len != 0 ) {
appendChar( *str );
++str;
--len;
}
}
static void prependStr( // PREPEND A STRING
char *str ) // - the string
{
if( str != NULL ) {
VStrPrepStr( &mangled_name, str );
}
}
static void prependLen( // PREPEND A THE CURRENT STRING LEN
void )
{
int len;
char sbuf[16]; // - buffer
len = VStrLen( &mangled_name );
DbgAssert( len == strlen( mangled_name.buf ) );
ultoa( len, sbuf, 36 );
switch( strlen( sbuf ) ){
case 1:
prependStr( sbuf );
prependChar( '0' );
break;
case 2:
prependStr( sbuf );
break;
default:
CFatal( "internal name length > 36*36" );
break;
}
}
static void appendInt( // APPEND AN INTEGER
int val ) // - value
{
char sbuf[16]; // - buffer
ultoa( val, sbuf, 10 );
appendStr( sbuf );
}
static void appendBase36Int( // APPEND A BASE 36 INTEGER
unsigned val ) // - value
{
char sbuf[16]; // - buffer
ultoa( val, sbuf, 36 );
appendStr( sbuf );
}
static void appendReplName( // APPEND A REPLICATIBLE NAME
char *id ) // - the name
{
int index;
index = replicateSearch( id );
if( index >= 0 ) {
appendChar( index + '0' );
} else {
appendStr( id );
appendStr( IN_NAME_SUFFIX );
}
}
static void appendNameSpaceName(// APPEND A NAMESPACE NAME
SCOPE scope ) // - the scope
{
char *name;
name = ScopeNameSpaceName( scope );
if( name != NULL ) {
if( ScopeIsUnnamedNameSpace( scope ) != NULL ) {
// we don't want unnamed namespace name in replicate table
// (demangler never stores anything with '$' prefix in rep table)
appendChar( IN_CLASS_DELIM );
appendStr( name );
appendStr( IN_NAME_SUFFIX );
} else {
appendChar( IN_CLASS_DELIM );
appendReplName( name );
}
}
}
static void appendSymName( // APPEND A SYMBOL's MANGLED NAME
SYMBOL sym ) // - the symbol
{
char *name;
name = sym->name->name;
if( nameHasPrefix( name, IN_OP_PREFIX ) ) {
appendStr( IN_NAME_PREFIX );
appendStr( &name[ sizeof( IN_NAME_PREFIX ) ] );
} else {
appendReplName( name );
}
}
static void appendScopeMangling(// APPEND CLASS SCOPES
SCOPE scope ); // - current scope
static void appendScopedSymName(// APPEND A SCOPED SYMBOL NAME
SYMBOL sym )
{
appendSymName( sym );
appendScopeMangling( sym->name->containing );
}
static char *className( // GET CLASS' NAME
TYPE class_type ) // - the class type
{
CLASSINFO *info;
info = class_type->u.c.info;
if( info->name == NULL ) {
ClassMakeUniqueName( class_type, NULL );
}
return( info->name );
}
static void appendClassName( // APPEND A CLASS' NAME
TYPE class_type ) // - the class type
{
appendReplName( className( class_type ) );
}
static void appendBasedMod( // APPEND A BASED MODIFIER
type_flag flags, // - the flags
void *base ) // - base modifier
{
STRING_CONSTANT str;
appendChar( IN_BASED );
flags &= TF1_BASED;
switch( flags ) {
case TF1_BASED_SELF:
appendChar( IN_BASED_SELF );
break;
case TF1_BASED_VOID:
appendChar( IN_BASED_VOID );
break;
case TF1_BASED_STRING:
#ifndef NDEBUG
if( base == NULL ) {
CFatal( "invalid based modifier" );
}
#endif
appendChar( IN_BASED_STRING );
str = base;
appendZZLen( str->len );
appendStrWithLen( str->string, str->len );
break;
case TF1_BASED_FETCH:
#ifndef NDEBUG
if( base == NULL ) {
CFatal( "invalid based modifier" );
}
#endif
appendChar( IN_BASED_FETCH );
appendStr( IN_NAME_PREFIX );
appendScopedSymName( base );
break;
case TF1_BASED_ADD:
#ifndef NDEBUG
if( base == NULL ) {
CFatal( "invalid based modifier" );
}
#endif
appendChar( IN_BASED_ADD );
appendStr( IN_NAME_PREFIX );
appendScopedSymName( base );
break;
#ifndef NDEBUG
default:
CFatal( "invalid based modifier" );
#endif
}
}
static void appendModifier( // APPEND A MODIFIER
type_flag flags, // - the flags
void *base ) // - base modifier
{
if( flags & TF1_BASED ) {
appendBasedMod( flags, base );
}
if( flags & TF1_FAR ) {
appendChar( IN_FAR );
}
if( flags & TF1_FAR16 ) {
appendChar( IN_FAR16 );
}
if( flags & TF1_HUGE ) {
appendChar( IN_HUGE );
}
if( flags & TF1_NEAR ) {
appendChar( IN_NEAR );
}
if( flags & TF1_VOLATILE ) {
appendChar( IN_VOLATILE );
}
if( flags & TF1_CONST ) {
appendChar( IN_CONST );
}
}
static void appendTypeFlags( // APPEND TYPE FLAGS
type_flag flags ) // - the flags
{
appendModifier( flags, NULL );
}
static void appendTypeContinue( // APPEND A TYPE MANGLING (NO NEAR/FAR PREFIX)
TYPE type, // - type
char *name, // - original name of symbol
tm_control control ) // - control mask
{
TYPE *aptr; // - arg.s structure
unsigned acount; // - arguments count
type_flag flags; // - look ahead flags
void *base; // - look ahead base
control |= TM_FIRST_DIM;
while( type != NULL ) {
switch( type->id ) {
case TYP_BOOL:
appendChar( IN_BOOL );
type = TypeError;
break;
case TYP_CHAR:
appendChar( IN_CHAR );
type = TypeError;
break;
case TYP_SCHAR:
appendChar( IN_SCHAR );
break;
case TYP_UCHAR:
appendChar( IN_UNSIGNED );
appendChar( IN_UCHAR );
break;
case TYP_WCHAR:
appendChar( IN_WCHAR );
break;
case TYP_SSHORT:
appendChar( IN_SSHORT );
break;
case TYP_USHORT:
appendChar( IN_UNSIGNED );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?