demangle.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,208 行 · 第 1/5 页
C
2,208 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: C++ name demangling.
*
****************************************************************************/
#ifdef TEST
#define __DIP__
#endif
#ifdef __DIP__
#define __NO_STACK_CHECKING__
#endif
#if 0 || defined(TEST) || defined(DUMP)
#include <stdio.h>
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "walloca.h"
#include "watcom.h"
#include "demangle.h"
#ifndef _WCI86FAR
#define _WCI86FAR
#endif
#define IMPORT_PREFIX_STR "__imp_"
#define IMPORT_PREFIX_LEN ( sizeof( IMPORT_PREFIX_STR ) - 1 )
#undef TRUE
#undef FALSE
#define TRUE (1)
#define FALSE (0)
#define RECURSE_CHECK (100*sizeof(int))
#define AUTO_BUFFER_SIZE 80
#define SUPPRESS_LIMIT 2
#define NULL_CHAR '\0'
#define TRUNCATED_HASH_LEN 4
#define TRUNCATED_PREFIX1 'T'
#define MANGLE_PREFIX1 'W'
#define MANGLE_PREFIX2 '?'
#define PREFIX_EMBEDDED '?'
#define MEMBER_POINTER 'M'
#define UNDERSCORE '_'
#define PERIOD '.'
#define SCOPE_PREFIX ':'
#define TEMPLATE_PREFIX ':'
#define TEMPLATE_INT '0'
#define TEMPLATE_TYPE '1'
#define POSITIVE_INT 'Z'
#define NEGATIVE_INT 'Y'
#define OPNAME_PREFIX '$'
#define SYMBOL_SUFFIX '$'
#define MANGLE_RECURSE_SUFFIX '$'
#define TYPE_NAME_PREFIX '$'
#define TYPE_NAME_SUFFIX '$'
#define THIS_QUAL_PREFIX '.'
#define ARRAY_PREFIX '['
#define ARRAY_SUFFIX ']'
#define FUNCTION_PREFIX '('
#define FUNCTION_SUFFIX ')'
#define OP_FUN_PREFIX 'o'
#define REL_FUN_PREFIX 'r'
#define SPEC_TYPE_PREFIX 't'
#define WAT_FUN_PREFIX 'w'
#define ASGN_FUN_PREFIX 'a'
typedef char *(*realloc_fn_t)( char *, size_t );
#define MAX_REPLICATE 10
typedef struct replicate_desc {
char const *ptr;
size_t len;
} replicate_desc;
// static R/W data
static realloc_fn_t user_realloc;
static replicate_desc replicate[MAX_REPLICATE];
static int next_replicate;
typedef struct output_desc {
outfunPtr outfun;
void *cookie;
char const *input;
char const *end;
char const *scope_ptr;
char *output;
size_t size;
size_t count;
size_t index;
size_t pending_loc;
size_t scope_len;
int suppress_output;
int scope_index;
unsigned ctdt_pending : 1;
unsigned cv_pending : 1;
unsigned scope_name : 1;
unsigned base_name : 1;
unsigned dllimport : 1;
} output_desc;
// the simple demangler uses these to output & count chars in the output buffer
// the parser callback uses these to extract the structure of the name
#define _output1( _a ) (data->outfun)( &(data->cookie), _a, 0, 0 )
#define _output2( _a, _b ) (data->outfun)( &(data->cookie), _a, _b, 0 )
#define _output3( _a, _b, _c ) (data->outfun)( &(data->cookie), _a, _b, _c )
typedef struct state_desc {
size_t prefix;
size_t suffix;
char right : 1;
} state_desc;
static char const _WCI86FAR dtorChar = '~';
static char const _WCI86FAR openParen = '(';
static char const _WCI86FAR closeParen = ')';
static char const _WCI86FAR signedPrefix[] = "signed ";
static char const _WCI86FAR operatorName[] = "operator ";
static char const _WCI86FAR deleteFunction[] = "delete";
static char const _WCI86FAR deleteArrayFunction[] = "delete []";
static char const _WCI86FAR anonymousEnum[] = "__anonymous_enum ";
static char const _WCI86FAR newFunction[] = "new";
static char const _WCI86FAR newArrayFunction[] = "new []";
static char const _WCI86FAR scopeSeparator[] = "::";
static char const _WCI86FAR templatePrefix[] = "<";
static char const _WCI86FAR templateSuffix[] = ">";
static char const _WCI86FAR templateSeparator[] = ",";
static char const _WCI86FAR arrayPrefix[] = "[";
static char const _WCI86FAR arraySuffix[] = "]";
static char const _WCI86FAR functionPrefix[] = "( ";
static char const _WCI86FAR functionSuffix[] = ")";
static char const _WCI86FAR functionSeparator[] = ", ";
static char const _WCI86FAR basedSuffix[] = ") ";
static char const _WCI86FAR basedStrPrefix[] = "\"";
static char const _WCI86FAR basedStrSuffix[] = "\"";
static char const _WCI86FAR basedSelf[] = "__self";
static char const _WCI86FAR basedVoid[] = "void";
// mangled character translations
typedef struct table_t {
char const _WCI86FAR *string; // translated string
char grouping; // flavour of character
} table_t;
#define LOWER_TABLE_LIMIT 'A'
static table_t const _WCI86FAR translate_type_encoding[] = {
#define CHAR_UNUSED 0
#define CHAR_BASIC_TYPE 1
#define CHAR_POINTER 2
#define CHAR_MODIFIER 3
/* 'A' */ { "char ", CHAR_BASIC_TYPE },
/* 'B' */ { "float ", CHAR_BASIC_TYPE },
/* 'C' */ { "char ", CHAR_BASIC_TYPE },
/* 'D' */ { "double ", CHAR_BASIC_TYPE },
/* 'E' */ { "... ", CHAR_BASIC_TYPE },
/* 'F' */ { "far ", CHAR_MODIFIER },
/* 'G' */ { "far16 ", CHAR_MODIFIER },
/* 'H' */ { "huge ", CHAR_MODIFIER },
/* 'I' */ { "int ", CHAR_BASIC_TYPE },
/* 'J' */ { "__based(", CHAR_MODIFIER },
/* 'K' */ { NULL, CHAR_UNUSED },
/* 'L' */ { "long ", CHAR_BASIC_TYPE },
/* 'M' */ { "::* ", CHAR_POINTER },
/* 'N' */ { "near ", CHAR_MODIFIER },
/* 'O' */ { NULL, CHAR_UNUSED },
/* 'P' */ { "* ", CHAR_POINTER },
/* 'Q' */ { "bool ", CHAR_BASIC_TYPE },
/* 'R' */ { "& ", CHAR_POINTER },
/* 'S' */ { "short ", CHAR_BASIC_TYPE },
/* 'T' */ { "long double ",CHAR_BASIC_TYPE },
/* 'U' */ { "unsigned ", CHAR_MODIFIER },
/* 'V' */ { "void ", CHAR_BASIC_TYPE },
/* 'W' */ { "wchar_t ", CHAR_BASIC_TYPE },
/* 'X' */ { "const ", CHAR_MODIFIER },
/* 'Y' */ { "volatile ", CHAR_MODIFIER },
/* 'Z' */ { "__int64 ", CHAR_BASIC_TYPE },
/* '[' */ { NULL, CHAR_UNUSED },
/* '\' */ { NULL, CHAR_UNUSED },
/* ']' */ { NULL, CHAR_UNUSED },
/* '^' */ { NULL, CHAR_UNUSED },
/* '_' */ { "", CHAR_BASIC_TYPE } // for ctor/dtor return type
};
static char _WCI86FAR * const _WCI86FAR operatorFunction[] = {
/* A */ ">>",
/* B */ "<<",
/* C */ "!",
/* D */ "[]",
/* E */ "->",
/* F */ "*",
/* G */ "++",
/* H */ "--",
/* I */ "-",
/* J */ "+",
/* K */ "&",
/* L */ "->*",
/* M */ "/",
/* N */ "%",
/* O */ ",",
/* P */ "()",
/* Q */ "~",
/* R */ "^",
/* S */ "|",
/* T */ "&&",
/* U */ "||"
};
static char const _WCI86FAR * const _WCI86FAR relationalFunction[] = {
/* A */ "==",
/* B */ "!=",
/* C */ "<",
/* D */ "<=",
/* E */ ">",
/* F */ ">="
};
static char const _WCI86FAR * const _WCI86FAR assignmentFunction[] = {
/* A */ "=",
/* B */ "*=",
/* C */ "+=",
/* D */ "-=",
/* E */ "/=",
/* F */ "%=",
/* G */ ">>=",
/* H */ "<<=",
/* I */ "&=",
/* J */ "|=",
/* K */ "^="
};
#define num_elements( __a ) (sizeof(__a) / sizeof(__a[0]))
typedef union key_desc {
char str[2];
short val;
} key_desc;
typedef struct assoc_desc {
key_desc u;
char _WCI86FAR *name;
} assoc_desc;
static assoc_desc const _WCI86FAR watcomObject[] = {
{ {"A*"}, "__internal" },
{ {"BI"}, "__onceonly" },
{ {"DA"}, "__arrdtorblk" },
{ {"DF"}, "__defarg" },
{ {"DI"}, "__debuginfo" },
{ {"DO"}, "__dtorobjblk" },
{ {"MP"}, "__mbrptrthunk" },
{ {"SI"}, "__staticinit" },
{ {"TH"}, "__throwblk" },
{ {"TI"}, "__typeid" },
{ {"TS"}, "__typesig" },
{ {"VA"}, "__rtti" },
{ {"VB"}, "__vbtbl" },
{ {"VF"}, "__vftbl" },
{ {"VM"}, "__vmtbl" },
{ {"VT"}, "__vfthunk" },
{ {"ST"}, "__typstattab" },
{ {"CM"}, "__stattabcmd" },
{ {"UN"}, "<unique>" },
};
#define MAX_WATCOM_OBJECT num_elements( watcomObject )
#if 0 || defined(TEST) || defined(DUMP)
int no_errors;
unsigned errors;
#endif
static int scoped_name( output_desc *data, state_desc *state );
static int type_encoding( output_desc *data, state_desc *state );
static int recursive_mangled_name( output_desc *data, state_desc *state );
static void zapSpace( output_desc *data )
{
if( data->output == NULL ) {
/* count the characters mode */
return;
}
if( data->index > data->size ) {
return;
}
if( data->output[data->index-1] != ' ' ) {
return;
}
data->count--;
if( data->index != (data->count+1) ) {
size_t last = min( data->size, data->count );
if( last >= data->index ) {
memmove( &data->output[data->index-1],
&data->output[data->index],
(last - data->index) + 1 );
}
}
data->index--;
}
#define START_ADJUST ( 1 << 8 )
static void emitChar( output_desc *data, char c )
{
size_t adjust_size;
size_t test_size;
char *test_realloc;
if( data->suppress_output > SUPPRESS_LIMIT ) {
return;
}
data->count++;
if( data->output == NULL ) {
/* count the characters mode */
return;
}
if( data->count == (data->size-1) ) {
if( user_realloc != NULL ) {
adjust_size = START_ADJUST;
for(;;) {
if( adjust_size == 0 ) {
return;
}
test_size = data->size + adjust_size;
test_realloc = user_realloc( data->output, test_size );
if( test_realloc != NULL ) break;
adjust_size >>= 1;
}
data->output = test_realloc;
data->size = test_size;
}
}
if( data->index < data->size ) {
if( data->index < (data->count-1) ) {
size_t last = min( data->size, data->count );
memmove( &data->output[data->index+1],
&data->output[data->index],
(last - data->index) - 1);
}
data->output[data->index] = c;
data->index++;
}
}
static void emitStr( output_desc *data, const char _WCI86FAR *p )
{
if( p ) {
while( *p ) {
emitChar( data, *p );
++p;
}
}
}
#define setEmitIndex( data, idx ) ((data)->index = (idx))
static void resetEmitIndex( output_desc *data, size_t offset_from_end )
{
size_t index;
index = data->count - offset_from_end;
if( index < data->size ) {
data->index = index;
} else {
data->index = data->size-1;
}
}
static void setSuppression( output_desc *data )
{
if( data->suppress_output ) {
data->suppress_output++;
}
}
static void resetSuppression( output_desc *data )
{
if( data->suppress_output ) {
--data->suppress_output;
}
}
static void forceSuppression( output_desc *data )
{
if( data->suppress_output <= SUPPRESS_LIMIT ) {
data->suppress_output += SUPPRESS_LIMIT+1;
}
}
static void unforceSuppression( output_desc *data )
{
if( data->suppress_output > SUPPRESS_LIMIT ) {
data->suppress_output -= SUPPRESS_LIMIT+1;
}
}
static void demangleEmit( void **cookie, dm_pts dp, int value, char const *ptr )
{
output_desc *data = *((output_desc **)cookie);
switch( dp ) {
case DM_BASIC_TYPE:
case DM_POINTER:
case DM_ARRAY:
case DM_FUNCTION:
case DM_THIS_FUNCTION:
case DM_UNMODIFIED_TYPE:
case DM_BASED_ENCODING:
case DM_MODIFIER_LIST:
case DM_TEMPLATE_ARG:
case DM_RECURSE_BEGIN:
case DM_RECURSE_END:
case DM_TEMPLATE_NAME:
case DM_DESTRUCTOR:
case DM_CONSTRUCTOR:
case DM_OPERATOR_CONVERT:
case DM_CTOR_DTOR_NAME:
case DM_SCOPED_NAME:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?