demangle.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,208 行 · 第 1/5 页
C
2,208 行
static int tq_function( output_desc *data, state_desc *state )
{
char c;
char const *tq_ptr;
size_t tq_len;
_output1( DM_THIS_FUNCTION );
tq_ptr = data->input;
tq_len = 0;
c = nextChar( data );
while( typeChar( c, CHAR_MODIFIER ) ) {
// note: doesn't handle based modifiers
tq_len++;
advanceChar( data );
c = nextChar( data );
}
if( c == FUNCTION_PREFIX ) {
advanceChar( data );
if( function( data, state ) ) {
_output2( DM_RESET_INDEX, state->suffix );
if( tq_len > 0 ) {
_output1( DM_EMIT_SPACE );
while( tq_len-- ) {
_output2( DM_CHAR_ENCODING, (int)toupper(*tq_ptr++) - LOWER_TABLE_LIMIT );
}
_output1( DM_ZAP_SPACE );
}
return( TRUE );
}
}
return( FALSE );
}
static int unmodified_type( output_desc *data, state_desc *state )
{
char c;
_output1( DM_UNMODIFIED_TYPE );
c = nextChar( data );
if( c == TYPE_NAME_PREFIX ) {
advanceChar( data );
if( scoped_name( data, state ) ) {
c = nextChar( data );
if( c == TYPE_NAME_SUFFIX ) {
advanceChar( data );
return( TRUE );
}
}
} else if( c == FUNCTION_PREFIX ) {
advanceChar( data );
return( function( data, state ) );
} else if( c == THIS_QUAL_PREFIX ) {
advanceChar( data );
return( tq_function( data, state ) );
} else if( c == ARRAY_PREFIX ) {
return( array( data, state ) );
} else if( typeChar( c, CHAR_POINTER ) ) {
if( pointer( data, state ) ) {
state->right = TRUE;
return( type_encoding( data, state ) );
}
} else {
return( basic_type( data, state ) );
}
return( FALSE );
}
static int based_encoding( output_desc *data, state_desc *state )
{
char c;
size_t len;
_output1( DM_BASED_ENCODING );
c = nextChar( data );
switch( c ) {
case 'S':
advanceChar( data );
_output1( DM_BASED_SELF );
_output1( DM_BASED_SUFFIX );
return( TRUE );
break;
case 'V':
advanceChar( data );
_output1( DM_BASED_VOID );
_output1( DM_BASED_SUFFIX );
return( TRUE );
break;
case 'L':
advanceChar( data );
if( base_36_2digit( data, &len ) ) {
_output1( DM_BASED_STRING_PREFIX );
_output3( DM_IDENTIFIER, len, data->input );
while( len-- ) {
advanceChar( data );
}
_output1( DM_BASED_STRING_SUFFIX );
_output1( DM_BASED_SUFFIX );
return( TRUE );
}
break;
case 'A':
case 'F':
advanceChar( data );
c = nextChar( data );
if( c == TYPE_NAME_PREFIX ) {
auto state_desc new_state;
advanceChar( data );
new_state = *state;
new_state.prefix = data->index;
new_state.suffix = data->count - data->index;
if( scoped_name( data, &new_state ) ) {
_output2( DM_RESET_INDEX, new_state.suffix );
_output1( DM_ZAP_SPACE );
_output1( DM_BASED_SUFFIX );
return( TRUE );
}
}
break;
}
return( FALSE );
}
static int modifier_list( output_desc *data, state_desc *state )
{
char c;
_output1( DM_MODIFIER_LIST );
c = nextChar( data );
while( typeChar( c, CHAR_MODIFIER ) ) {
advanceChar( data );
if( c == 'U' && nextChar( data ) == 'A' ) {
// don't emit unsigned before default char
} else {
_output2( DM_SET_INDEX, state->prefix );
_output2( DM_CHAR_ENCODING, (int)c - LOWER_TABLE_LIMIT );
}
if( c == 'J' ) {
if( !based_encoding( data, state ) ) {
return( FALSE );
}
}
c = nextChar( data );
}
return( TRUE );
}
static int type_encoding( output_desc *data, state_desc *state )
{
int ret;
char c;
ret = FALSE;
_output1( DM_TYPE_ENCODING );
c = nextChar( data );
if( typeChar( c, CHAR_MODIFIER ) ) {
if( modifier_list( data, state ) ) {
ret = unmodified_type( data, state );
}
} else {
ret = unmodified_type( data, state );
}
#if 0 // afs; this isn't the right place for this but we should output this
if( ret && data->dllimport ) {
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_DECLSPEC_IMPORT );
data->dllimport = 0;
}
#endif
return( ret );
}
static int template_arg( output_desc *data, state_desc *state )
{
char c;
_output1( DM_TEMPLATE_ARG );
c = nextChar( data );
if( c == TEMPLATE_INT ) {
int value;
advanceChar( data );
if( base_32_num( data, &value ) ) {
c = nextChar( data );
if( c == POSITIVE_INT ) {
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output2( DM_INTEGER, value );
return( TRUE );
} else if( c == NEGATIVE_INT ) {
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output2( DM_INTEGER, -value );
return( TRUE );
}
}
} else if( c == TEMPLATE_TYPE ) {
advanceChar( data );
return( type_encoding( data, state ) );
} else if( c == PREFIX_EMBEDDED ) {
advanceChar( data );
if( check_recurse() ) {
return( recursive_mangled_name( data, state ) );
}
}
return( FALSE );
}
static int template_name( output_desc *data, state_desc *state )
{
auto state_desc new_state;
int first_arg = 0;
char c;
_output1( DM_TEMPLATE_NAME );
new_state = *state;
_output2( DM_RESET_INDEX, state->suffix );
_output1( DM_TEMPLATE_PREFIX );
c = nextChar( data );
while( c == TEMPLATE_INT || c == TEMPLATE_TYPE || c == PREFIX_EMBEDDED ) {
if( first_arg ) {
_output2( DM_RESET_INDEX, state->suffix );
_output1( DM_ZAP_SPACE );
_output1( DM_TEMPLATE_ARG_SEPARATOR );
}
new_state.prefix = data->index;
if( !template_arg( data, &new_state ) ) {
return( FALSE );
}
first_arg = 1;
c = nextChar( data );
}
_output2( DM_RESET_INDEX, state->suffix );
if( !first_arg ) {
_output1( DM_ZAP_SPACE );
}
_output1( DM_TEMPLATE_SUFFIX );
return( TRUE );
}
static int watcom_object( output_desc *data, state_desc *state )
{
key_desc srch;
int i;
size_t len;
char c;
c = nextChar( data );
if( c == 'A' ) {
advanceChar( data );
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output2( DM_WATCOM_OBJECT, 0 );
} else {
srch.str[0] = c;
advanceChar( data );
c = nextChar( data );
srch.str[1] = c;
advanceChar( data );
for( i = 1 ; i < MAX_WATCOM_OBJECT ; i++ ) {
if( srch.val == watcomObject[i].u.val ) {
_output2( DM_SET_INDEX, state->prefix );
_output2( DM_WATCOM_OBJECT, i );
break;
}
}
// check to make sure we found something
if( i == MAX_WATCOM_OBJECT ) {
_output2( DM_SET_INDEX, state->prefix );
_output2( DM_WATCOM_OBJECT, 0 );
}
}
if( base_36_2digit( data, &len ) ) {
while( len-- ) {
advanceChar( data );
}
c = nextChar( data );
if( c == TYPE_NAME_SUFFIX ) {
advanceChar( data );
return( TRUE );
}
}
return( FALSE );
}
static int special_type_names( output_desc *data, state_desc *state )
{
char c;
c = nextChar( data );
if( c == 'E' ) {
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_ANONYMOUS_ENUM );
for(;;) {
c = nextChar( data );
if( c == NULL_CHAR ) {
return( FALSE );
}
advanceChar( data );
if( c == TYPE_NAME_SUFFIX ) {
return( TRUE );
}
}
}
return( FALSE );
}
static int operator_function( output_desc *data, state_desc *state )
{
char c;
c = nextChar( data ) - LOWER_TABLE_LIMIT;
if( c < num_elements( operatorFunction ) ) {
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_OPERATOR_PREFIX );
_output2( DM_OPERATOR_FUNCTION, (int)c );
return( TRUE );
}
return( FALSE );
}
static int relational_function( output_desc *data, state_desc *state )
{
char c;
c = nextChar( data ) - LOWER_TABLE_LIMIT;
if( c < num_elements( relationalFunction ) ) {
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_OPERATOR_PREFIX );
_output2( DM_RELATIONAL_FUNCTION, (int)c );
return( TRUE );
}
return( FALSE );
}
static int assignment_function( output_desc *data, state_desc *state )
{
char c;
c = nextChar( data ) - LOWER_TABLE_LIMIT;
if( c < num_elements( assignmentFunction ) ) {
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_OPERATOR_PREFIX );
_output2( DM_ASSIGNMENT_FUNCTION, (int)c );
return( TRUE );
}
return( FALSE );
}
static int op_new( output_desc *data, state_desc *state )
{
if( nextChar( data ) == 'W' ) {
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_OPERATOR_PREFIX );
_output1( DM_OPERATOR_NEW );
return( TRUE );
}
if( nextChar( data ) == 'A' ) {
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_OPERATOR_PREFIX );
_output1( DM_OPERATOR_NEW_ARRAY );
return( TRUE );
}
return( FALSE );
}
static int dtor_or_delete( output_desc *data, state_desc *state )
{
char c;
c = nextChar( data );
switch( c ) {
case 'T':
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_DESTRUCTOR_CHAR );
_output1( DM_DESTRUCTOR );
data->pending_loc = data->count - data->index;
data->ctdt_pending = TRUE;
return( TRUE );
case 'L':
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_OPERATOR_PREFIX );
_output1( DM_OPERATOR_DELETE );
return( TRUE );
case 'A':
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_OPERATOR_PREFIX );
_output1( DM_OPERATOR_DELETE_ARRAY );
return( TRUE );
}
return( FALSE );
}
static int ctor_or_convert( output_desc *data, state_desc *state )
{
char c;
c = nextChar( data );
if( c == 'T' ) {
advanceChar( data );
_output1( DM_CONSTRUCTOR );
data->pending_loc = data->count - data->index;
data->ctdt_pending = TRUE;
return( TRUE );
} else if( c == 'V' ) {
advanceChar( data );
_output2( DM_SET_INDEX, state->prefix );
_output1( DM_OPERATOR_PREFIX );
_output1( DM_OPERATOR_CONVERT );
data->cv_pending = TRUE;
return( TRUE );
}
return( FALSE );
}
static int op_name( output_desc *data, state_desc *state )
{
char c;
c = tolower( nextChar( data ) );
switch( c ) {
case 'c':
advanceChar( data );
return( ctor_or_convert( data, state ) );
break;
case 'd':
advanceChar( data );
return( dtor_or_delete( data, state ) );
break;
case 'n':
advanceChar( data );
return( op_new( data, state ) );
break;
case ASGN_FUN_PREFIX:
advanceChar( data );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?