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