demangle.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,208 行 · 第 1/5 页

C
2,208
字号
    }
    return( FALSE );
}

int __is_mangled( char const *name, size_t len )
{
    int offset;
    len = len;

    offset = 2;
    if( name[0] == '_' && memicmp( name, IMPORT_PREFIX_STR, IMPORT_PREFIX_LEN ) == 0 ) {
        name += IMPORT_PREFIX_LEN;
        offset += IMPORT_PREFIX_LEN;
    }
    switch( name[0] ) {
    case TRUNCATED_PREFIX1:
        offset += TRUNCATED_HASH_LEN;
        /* fall through */
    case MANGLE_PREFIX1:
        if( name[1] == MANGLE_PREFIX2 ) {
            return( offset );
        }
        break;
    }
    return( 0 );
}

static int checkInternal( char const *n )
{
    if( n[0] == '.' || (n[0] == OPNAME_PREFIX && tolower(n[1]) == WAT_FUN_PREFIX)) {
        return( __MANGLED_INTERNAL );
    }
    if( n[0] == OPNAME_PREFIX && tolower(n[1]) == 'c' && tolower(n[2]) == 't' ) {
        return( __MANGLED_CTOR );
    }
    if( n[0] == OPNAME_PREFIX && tolower(n[1]) == 'd' && tolower(n[2]) == 't' ) {
        return( __MANGLED_DTOR );
    }
    return( __MANGLED );
}

int __is_mangled_internal( char const *name, size_t len )
{
    unsigned offset;
    len = len;

    offset = 2;
    switch( name[0] ) {
    case TRUNCATED_PREFIX1:
        offset += TRUNCATED_HASH_LEN;
        /* fall through */
    case MANGLE_PREFIX1:
        if( name[1] == MANGLE_PREFIX2 ) {
            return( checkInternal( name + offset ) );
        }
        break;
    }
    return( __NOT_MANGLED );
}

int __unmangled_name(                           // FIND UNMANGLED BASE NAME
    char const *name,                           // - mangled C++ name
    size_t len,                                 // - length of mangled name
    char const **base,                          // - location of base name
    size_t *size )                              // - size of base name
{                                               // return TRUE if name mangled
    char const *end;
    int   mangled;

    *size = 0;
    *base = name;
    if( len == 0 ) {
        len = strlen( name );
    }
    end = name + len;
    mangled = __is_mangled( name, len );
    if( mangled ) {
        name += mangled; // skip magic cookie
        *base = name;
        if( *name == OPNAME_PREFIX ) {
            (*size) += 3;
            name++;
            if( tolower(*name) == WAT_FUN_PREFIX ) {
                (*size) += 1;
            }
        } else {
            for( ; name != end ; ++name ) {
                if( *name == SYMBOL_SUFFIX ) break;
                (*size)++;
            }
        }
        return( TRUE );
    }
    *size = len;
    return( FALSE );
}



size_t __demangled_basename(                    // CREATE DEMANGLED BASE NAME
    char const *input,                          // - mangled C++ name
    size_t len,                                 // - length of mangled name
    char *output,                               // - for demangled C++ name
    size_t size )                               // - size of output buffer
{                                               // return len of output
    int                 mangled;
    size_t              outlen;
    auto output_desc    data;

    init_globals( NULL );
    mangled = __is_mangled( input, len );
    init_descriptor( &data, &demangleEmit, &data, input, len, output, size );
    data.suppress_output = 0;
    data.base_name = 1;
    if( mangled ) {
        do_demangle( &data );
    } else {
        do_copy( &data );
    }
    outlen = terminateOutput( &data );
    /* size does not include '\0' */
    return( outlen );
}

#ifdef __DIP__

void __parse_mangled_name(                      // PARSE MANGLED NAME
    char const *input,                          // - mangled C++ name
    size_t len,                                 // - length of mangled name
    void *cookie,                               // - data to carry around
    outfunPtr ofn )                             // - function to invoke
{
    int                 mangled;
    auto output_desc    data;

    init_globals( NULL );
    mangled = __is_mangled( input, len );
    init_descriptor( &data, ofn, cookie, input, len, NULL, 0 );
    data.suppress_output = 0;
    if( mangled ) {
        do_demangle( &data );
    } else {
        do_copy( &data );
    }
}


size_t __mangle_operator(                       // MANGLE OPERATOR NAME
    char const *op,                             // - operator token
    size_t len,                                 // - length of operator token
    char *result )                              // - operator name
                                                // return len of operator name
{
    int i;
    if( len == 0 ) {
        len = strlen( op );
    }

    for( i = 0 ; i < num_elements( operatorFunction ) ; i++ ) {
        if( strncmp( op, operatorFunction[i], len ) == 0 ) {
            if( operatorFunction[i][len] == NULL_CHAR ) {
                *result++ = OPNAME_PREFIX;
                *result++ = OP_FUN_PREFIX;
                *result++ = i + 'a';
                return( 3 );
            }
        }
    }
    for( i = 0 ; i < num_elements( relationalFunction ) ; i++ ) {
        if( strncmp( op, relationalFunction[i], len ) == 0 ) {
            if( relationalFunction[i][len] == NULL_CHAR ) {
                *result++ = OPNAME_PREFIX;
                *result++ = REL_FUN_PREFIX;
                *result++ = i + 'a';
                return( 3 );
            }
        }
    }
    for( i = 0 ; i < num_elements( assignmentFunction ) ; i++ ) {
        if( strncmp( op, assignmentFunction[i], len ) == 0 ) {
            if( assignmentFunction[i][len] == NULL_CHAR ) {
                *result++ = OPNAME_PREFIX;
                *result++ = ASGN_FUN_PREFIX;
                *result++ = i + 'a';
                return( 3 );
            }
        }
    }
    return( 0 );
}
#endif //__DIP__

#endif //!__LIB__

#if 0 || defined(TEST) || defined(DUMP)
void dump( output_desc *data )
{
    int i;

    printf( "input:   [%x]>%s<\n", data->input, data->input );
    printf( "end:     [%x]\n", data->end );
    printf( "output:  [%x]>%s<\n", data->output, data->output );
    printf( "realloc: [%x]\n", user_realloc );
    printf( "size: %d, count: %d, index: %d, suppress_output: %d\n",
            data->size,
            data->count,
            data->index,
            data->suppress_output );
    for( i = 0 ; i < next_replicate ; i++ ) {
        printf( "replicate#%d: ptr: [%x]>%s< len: %d\n",
                i,
                replicate[i].ptr,
                replicate[i].ptr,
                replicate[i].len );
    }
    printf( "pending_loc: %d, ctdt_pending: %d, cv_pending: %d, base_name: %d\n",
            data->pending_loc,
            data->ctdt_pending,
            data->cv_pending,
            data->base_name );
    printf( "scope_name: %d, scope_index: %d, scope_ptr: %x, scope_len %d\n",
            data->scope_name,
            data->scope_index,
            data->scope_ptr,
            data->scope_len );
}

#endif

#if 0 || defined(TEST)
#define TRUNC_BUFFER    256
#define GUARD_CHAR      '@'
#define ALLOC_SIZE      2
#define BUF_SIZE        256

typedef struct test_stream {
    char *mangle;               // mangled name
    char *full_demangle;        // complete demangled name
    char *unmangled;            // unmangled name
    char *basename;             // demangled basename
} test_stream;

test_stream testVector[] = {
#if 1
    "W?foo$n(pn(uauaua)v)v",
        "void near foo( void (near *)( char, char, char ))",
        "foo",
        "foo",
    "W?a$ni",
        "int near a",
        "a",
        "a",
    "W?$CT:S$n()_",
        "near S::S()",
        "$CT",
        "S",
    "W?$DT:S$n()_",
        "near S::~S()",
        "$DT",
        "~S",
    "W?$DLn(pv)v",
        "void near operator delete( void * )",
        "$DL",
        "operator delete",
    "W?foo$n(iuipua)v",
        "void near foo( int, int unsigned, char * )",
        "foo",
        "foo",
    "W?$CV:opCONV$n()i",
        "near opCONV::operator int ()",
        "$CV",
        "operator int",
    "W?foo$n(pn$opCONV$$)pn$opCONV$$",
        "opCONV near * near foo( opCONV near * )",
        "foo",
        "foo",
    "W?foo$n(pn$opCONV$$)pn$1$",
        "opCONV near * near foo( opCONV near * )",
        "foo",
        "foo",
    "W?$NWn(ui)pnv",
        "void near * near operator new( int unsigned )",
        "$NW",
        "operator new",
    "W?bar$n($opnew$$)$1$",
        "opnew near bar( opnew )",
        "bar",
        "bar",
    "W?foo$n(pn[2][3][4]ipn[6]ua)v",
        "void near foo( int (near *)[2][3][4], char (near *)[6])",
        "foo",
        "foo",
    "W?bar$n(pn(uab)ipn(pn(d)it)v)v",
        "void near bar( int (near *)( char, float ), void (near *)( int (near *)( double ), long double ))",
        "bar",
        "bar",
    "W?pff$npn(db)ua",
        "char (near * near pff)( double, float )",
        "pff",
        "pff",
    "W?goo$nm$Base$$ni",
        "int near Base::* near goo",
        "goo",
        "goo",
    "W?goo$n(nm$Base$$ni)v",
        "void near goo( int near Base::* near )",
        "goo",
        "goo",
    "W?$Wvm07:H$$:E$$nx[]ui",
        "int unsigned const near __vmtbl[]",
        "$Wvm",
        "__vmtbl",
    "W?$Wvt0qset_v1:A$c$:A$set_v1$n(i)v$:V1$n(i)v",
        "void near V1::__vfthunk( int )",
        "$Wvt",
        "__vfthunk",
    "W?foo$:S$n(ua)i",
        "int near S::foo( char )",
        "foo",
        "foo",
    "W?foo$:S$n.x(ua)i",
        "int near S::foo( char ) const",
        "foo",
        "foo",
    "W?$CV:S$n()i",
        "near S::operator int ()",
        "$CV",
        "operator int",
    "W?$CV:S$n.x()i",
        "near S::operator int () const",
        "$CV",
        "operator int",
    "W?$WAA19ios:$opDTOR$$istream:c$$istream:$$opDTOR$?n()$n()pnv",
        "void near * near __internal()",
        "$WAA",
        "__internal",
    "W?_trmem_open$n(pn(ui)pnvpn(pnv)vpn(pnvui)pnvpn(pnvui)pnvpnvpn(pnvpnxuaui)vui)pn$_trmem_internal$$",
        "_trmem_internal near * near _trmem_open( void near * (near *)( int unsigned ), void (near *)( void near * ), void near * (near *)( void near "
        "*, int unsigned ), void near * (near *)( void near *, int unsigned ), void near *, void (near *)( void near *, char const near *, int unsigned ), int unsigned )",
        "_trmem_open",
        "_trmem_open",
    "W?s$n$Stack$::1ni0az?ok$n()v$",
        "Stack<int near,10,void near ok()> near s",
        "s",
        "s",
    "W?dummy$:Stack$::1ni0az?ok$n()vn()v",
        "void near Stack<int near,10,void near ok()>::dummy()",
        "dummy",
        "dummy",
    "W?$CT:Stack$::1ni0ay?ok$n()vn()_",
        "near Stack<int near,-10,void near ok()>::Stack()",
        "$CT",
        "Stack",
    "W?s$n$Inner$:Stack$::1ni0az?ok$n()v:xyz$$",
        "xyz::Stack<int near,10,void near ok()>::Inner near s",
        "s",
        "s",
    "W?s$n$Inner$:Stack$::1ni0az1n$xyz$::1ni$:abc$$",
        "abc::Stack<int near,10,xyz<int near > near >::Inner near s",
        "s",
        "s",
    "W?dummy$:Stack$::1ni0az?ok$n()v:xyz$n()v",
        "void near xyz::Stack<int near,10,void near ok()>::dummy()",
        "dummy",
        "dummy",
    "W?dummy$:Stack$::1ni0az?ok$n()v:xyz$::1nin()v",
        "void near xyz<int near >::Stack<int near,10,void near ok()>::dummy()",
        "dummy",
        "dummy",
    "W?a$:.1$:?foo$n()vn[]i",
        "int near void near foo()::.1::a[]",
        "a",
        "a",
    "W?cout$n$ostream$$",
        "ostream near cout",
        "cout",
        "cout",
    "W?$OB:ostream$n(pnxua)rn$ostream$$",
        "ostream near & near ostream::operator <<( char const near * )",
        "$OB",
        "operator <<",
    "W?endl$n(rn$ostream$$)rn$ostream$$",
        "ostream near & near endl( ostream near & )",
        "endl",
        "endl",
    "W?$OB:ostream$n(pn(rn$ostream$$)rn$ostream$$)rn$ostream$$",
        "ostream near & near ostream::operator <<( ostream near & (near *)( ostream near & ))",
        "$OB",
        "operator <<",
    "W?m$n()pjvv",
        "void __based(void) * near m()",
        "m",
        "m",
    "W?pv$npjvua",
        "char __based(void) * near pv",
        "pv",
        "pv",
    "W?ps$npjsua",
        "char __based(__self) * near ps",
        "ps",
        "ps",
    "W?pn$npjl03FOOuc",
        "char unsigned __based(\"FOO\") * near pn",
        "pn",
        "pn",
    "W?pa$npjf$s$uc",
        "char unsigned __based(s) * near pa",
        "pa",
        "pa",
    "W?pp$npja$b$ua",
        "char __based(b) * near pp",
        "pp",
        "pp",
    "W?bar$n(uaua)v",
        "void near bar( char, char )",
        "bar",
        "bar",
    "W?bar$n(cc)v",
        "void near bar( char signed, char signed )",
        "bar",
        "bar",
    "W?bar$n(ucuc)v",
        "void near bar( char unsigned, char unsigned )",
        "bar",
        "bar",
    "W?mpa$nm$S$$nxi",
        "int const near S::* near mpa",
        "mpa",
        "mpa",
    "W?mpb$nm$S$$nyi",
        "int volatile near S::* near mpb",
        "mpb",
        "mpb",
    "W?$Wmp05a$nxi$:S$n()pnxi",
        "int const near * near S::__mbrptrthunk()",
        "$Wmp",
        "__mbrptrthunk",
    "W?$Wmp05b$nyi$:S$n()pnyi",
        "int volatile near * near S::__mbrptrthunk()",
        "$Wmp

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?