demangle.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,208 行 · 第 1/5 页
C
2,208 行
case DM_NAME:
case DM_SCOPE:
case DM_MANGLED_NAME:
case DM_TRUNCATED_NAME:
// ignore these for demangling
break;
case DM_TYPE_ENCODING:
if( data->base_name ) {
forceSuppression( data );
}
break;
case DM_SET_INDEX:
setEmitIndex( data, value );
break;
case DM_RESET_INDEX:
resetEmitIndex( data, value );
break;
case DM_ZAP_SPACE:
zapSpace( data );
break;
case DM_EMIT_SPACE:
emitChar( data, ' ' );
break;
case DM_IDENTIFIER:
case DM_COPY_STRING:
if( data->base_name && data->ctdt_pending ) {
unforceSuppression( data );
}
if( value == 0 ) {
emitStr( data, ptr );
} else {
while( value-- ) {
emitChar( data, *ptr++ );
}
}
if( data->base_name && data->ctdt_pending ) {
forceSuppression( data );
}
break;
case DM_INTEGER:
{
char buff[12];
itoa( value, buff, 10 );
emitStr( data, buff );
}
break;
case DM_ARRAY_SIZE:
if( value != 0 ) {
char buff[12];
itoa( value, buff, 10 );
emitStr( data, buff );
}
break;
case DM_OPEN_PAREN:
emitChar( data, openParen );
break;
case DM_CLOSE_PAREN:
emitChar( data, closeParen );
break;
case DM_CHAR_ENCODING_SIGNED:
emitStr( data, signedPrefix );
break;
case DM_ARRAY_PREFIX:
emitStr( data, arrayPrefix );
break;
case DM_ARRAY_SUFFIX:
emitStr( data, arraySuffix );
break;
case DM_FUNCTION_PREFIX:
emitStr( data, functionPrefix );
break;
case DM_FUNCTION_SUFFIX:
emitStr( data, functionSuffix );
if( data->cv_pending ) {
unforceSuppression( data );
}
break;
case DM_FUNCTION_ARG_SEPARATOR:
emitStr( data, functionSeparator );
break;
case DM_BASED_SUFFIX:
emitStr( data, basedSuffix );
break;
case DM_BASED_STRING_PREFIX:
emitStr( data, basedStrPrefix );
break;
case DM_BASED_SELF:
emitStr( data, basedSelf );
break;
case DM_BASED_VOID:
emitStr( data, basedVoid );
break;
case DM_BASED_STRING_SUFFIX:
emitStr( data, basedStrSuffix );
break;
case DM_TEMPLATE_PREFIX:
emitStr( data, templatePrefix );
break;
case DM_TEMPLATE_SUFFIX:
emitStr( data, templateSuffix );
break;
case DM_TEMPLATE_ARG_SEPARATOR:
emitStr( data, templateSeparator );
break;
case DM_ANONYMOUS_ENUM:
emitStr( data, anonymousEnum );
break;
case DM_OPERATOR_PREFIX:
emitStr( data, operatorName );
break;
case DM_OPERATOR_NEW:
emitStr( data, newFunction );
break;
case DM_OPERATOR_NEW_ARRAY:
emitStr( data, newArrayFunction );
break;
case DM_OPERATOR_DELETE:
emitStr( data, deleteFunction );
break;
case DM_OPERATOR_DELETE_ARRAY:
emitStr( data, deleteArrayFunction );
break;
case DM_DESTRUCTOR_CHAR:
emitChar( data, dtorChar );
break;
case DM_SCOPE_SEPARATOR:
if( data->base_name ) {
forceSuppression( data );
}
emitStr( data, scopeSeparator );
break;
case DM_CHAR_ENCODING:
emitStr( data, translate_type_encoding[ value ].string );
break;
case DM_WATCOM_OBJECT:
emitStr( data, watcomObject[ value ].name );
break;
case DM_OPERATOR_FUNCTION:
emitStr( data, operatorFunction[ value ] );
break;
case DM_RELATIONAL_FUNCTION:
emitStr( data, relationalFunction[ value ] );
break;
case DM_ASSIGNMENT_FUNCTION:
emitStr( data, assignmentFunction[ value ] );
break;
case DM_DECLSPEC_IMPORT:
emitStr( data, "__declspec(dllimport) " );
break;
default:
#if 0 || defined(TEST)
printf( "ERROR: demangleEmit unknown dm_pts(%d)\n", dp );
++errors;
#endif
break;
}
}
// ==========================================================================
// everything before this point deals with output to the demangled name
// ==========================================================================
static int typeChar( char c, int grouping )
{
c -= LOWER_TABLE_LIMIT;
if( c < num_elements( translate_type_encoding ) ) {
return( translate_type_encoding[c].grouping == grouping );
}
return( FALSE );
}
static int check_recurse( void ) {
#ifdef __NO_STACK_CHECKING__
return( 1 );
#else
return( (int) alloca( RECURSE_CHECK ) );
#endif
}
static char prevChar( output_desc *data )
{
char c;
c = *(data->input-1);
return( toupper( c ) );
}
static char nextChar( output_desc *data )
{
char c;
c = *data->input;
if( data->input == data->end ) {
c = NULL_CHAR;
} else {
c = toupper( c );
}
return( c );
}
static void advanceChar( output_desc *data )
{
if( data->input != data->end && *data->input ) {
data->input++;
}
}
#ifndef __LIB__
static int strRecog( output_desc *data, char *str, unsigned len )
{
if(( data->end - data->input ) < len ) {
return( 0 );
}
if( memicmp( data->input, str, len ) != 0 ) {
return( 0 );
}
data->input += len;
return( 1 );
}
#endif
static int is_identifier( char c )
{
if( isalnum( c ) || c == UNDERSCORE || c == PERIOD ) {
return( TRUE );
} else {
return( FALSE );
}
}
static unsigned char_to_digit( char c )
{
if( c >= '0' && c <= '9' ) return( c - '0' );
if( c >= 'A' && c <= 'Z' ) return( c - 'A' + 10 );
if( c >= 'a' && c <= 'z' ) return( c - 'a' + 10 );
return( -1 );
}
static int base_32_num( output_desc *data, int *value )
{
unsigned dig;
int v;
v = 0;
for( ;; ) {
dig = char_to_digit( nextChar( data ) );
if( dig >= 32 ) break;
v = v * 32 + dig;
advanceChar( data );
}
*value = v;
return( TRUE );
}
static int base_10_num( output_desc *data, int *value )
{
unsigned dig;
int v;
v = 0;
for( ;; ) {
dig = char_to_digit( nextChar( data ) );
if( dig >= 10 ) break;
v = v * 10 + dig;
advanceChar( data );
}
*value = v;
return( TRUE );
}
static int base_36_2digit( output_desc *data, size_t *value )
{
unsigned first;
unsigned second;
first = char_to_digit( nextChar( data ) );
if( first < 36 ) {
advanceChar( data );
second = char_to_digit( nextChar( data ) );
if( second < 36 ) {
advanceChar( data );
*value = (first * 36) + second;
return( TRUE );
}
}
return( FALSE );
}
static int basic_type( output_desc *data, state_desc *state )
{
char c;
_output1( DM_BASIC_TYPE );
c = nextChar( data );
if( typeChar( c, CHAR_BASIC_TYPE ) ) {
// put a signed before signed char
if( c == 'C' && prevChar( data ) != 'U' ) {
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_CHAR_ENCODING_SIGNED );
}
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output2( DM_CHAR_ENCODING, (int)c - LOWER_TABLE_LIMIT );
return( TRUE );
}
return( FALSE );
}
static int pointer( output_desc *data, state_desc *state )
{
char c;
_output1( DM_POINTER );
c = nextChar( data );
if( typeChar( c, CHAR_POINTER ) ) {
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output2( DM_CHAR_ENCODING, (int)c - LOWER_TABLE_LIMIT );
if( c == MEMBER_POINTER ) {
c = nextChar( data );
if( c == TYPE_NAME_PREFIX ) {
advanceChar( data );
if( !scoped_name( data, state ) ) {
return( FALSE );
}
c = nextChar( data );
if( c != TYPE_NAME_PREFIX ) {
return( FALSE );
}
advanceChar( data );
_output1( DM_ZAP_SPACE );
}
}
return( TRUE );
}
return( FALSE );
}
static int dimension( output_desc *data, state_desc *state )
{
char c;
int value;
_output2( DM_RESET_INDEX, state->suffix );
_output1( DM_ARRAY_PREFIX );
if( base_10_num( data, &value ) ) {
_output2( DM_ARRAY_SIZE, value );
c = nextChar( data );
if( c == ARRAY_SUFFIX ) {
advanceChar( data );
_output1( DM_ARRAY_SUFFIX );
return( TRUE );
}
}
return( FALSE );
}
static int array( output_desc *data, state_desc *state )
{
char c;
_output1( DM_ARRAY );
_output2( DM_RESET_INDEX, state->suffix );
_output1( DM_ZAP_SPACE );
if( state->right ) {
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_OPEN_PAREN );
_output2( DM_RESET_INDEX, state->suffix );
_output1( DM_CLOSE_PAREN );
state->right = FALSE;
}
c = nextChar( data );
while( c == ARRAY_PREFIX ) {
advanceChar( data );
if( !dimension( data, state ) ) {
return( FALSE );
}
c = nextChar( data );
}
return( type_encoding( data, state ) );
}
static int function( output_desc *data, state_desc *state )
{
auto state_desc new_state;
size_t conv_offset = 0;
int first_arg = 0;
char c;
_output1( DM_FUNCTION );
_output2( DM_RESET_INDEX, state->suffix );
if( data->cv_pending ) {
_output1( DM_EMIT_SPACE );
conv_offset = data->index;
} else {
_output1( DM_ZAP_SPACE );
}
if( state->right ) {
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_OPEN_PAREN );
_output2( DM_RESET_INDEX, state->suffix );
_output1( DM_CLOSE_PAREN );
state->right = FALSE;
}
new_state = *state;
_output1( DM_FUNCTION_PREFIX );
setSuppression( data );
c = nextChar( data );
while( c != FUNCTION_SUFFIX ) {
if( first_arg ) {
_output2( DM_RESET_INDEX, state->suffix );
_output1( DM_ZAP_SPACE );
_output1( DM_FUNCTION_ARG_SEPARATOR );
}
new_state.prefix = data->index;
if( !type_encoding( data, &new_state ) ) {
return( FALSE );
}
first_arg = 1;
c = nextChar( data );
}
advanceChar( data );
_output2( DM_RESET_INDEX, state->suffix );
if( !first_arg ) {
_output1( DM_ZAP_SPACE );
}
resetSuppression( data );
_output1( DM_FUNCTION_SUFFIX );
if( data->cv_pending ) {
_output2( DM_SET_INDEX, conv_offset );
} else {
_output2( DM_SET_INDEX, state->prefix );
}
new_state.prefix = data->index;
if( type_encoding( data, &new_state ) ) {
data->cv_pending = FALSE;
return( TRUE );
} else {
return( FALSE );
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?