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