ReactOS 0.4.16-dev-2104-gb84fa49
undname.c File Reference
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "msvcrt.h"
#include "winver.h"
#include "imagehlp.h"
#include "wine/debug.h"
Include dependency graph for undname.c:

Go to the source code of this file.

Classes

struct  array
 
struct  parsed_symbol
 
struct  datatype_t
 
struct  function_signature
 

Macros

#define UNDNAME_NO_COMPLEX_TYPE   (0x8000)
 
#define BLOCK_SIZE   1024
 
#define AVAIL_SIZE   (1024 - sizeof(void*))
 

Enumerations

enum  datatype_e { DT_NO_LEADING_WS = 0x01 , DT_NO_LRSEP_WS = 0x02 }
 
enum  datatype_flags { IN_ARGS = 0x01 , WS_AFTER_QUAL_IF = 0x02 }
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msvcrt)
 
static BOOL symbol_demangle (struct parsed_symbol *sym)
 
static charget_class_name (struct parsed_symbol *sym)
 
static voidund_alloc (struct parsed_symbol *sym, unsigned int len)
 
static void und_free_all (struct parsed_symbol *sym)
 
static void str_array_init (struct array *a)
 
static BOOL str_array_push (struct parsed_symbol *sym, const char *ptr, int len, struct array *a)
 
static charstr_array_get_ref (struct array *cref, unsigned idx)
 
static char *WINAPIV str_printf (struct parsed_symbol *sym, const char *format,...)
 
static BOOL demangle_datatype (struct parsed_symbol *sym, struct datatype_t *ct, enum datatype_flags flags)
 
static const charget_number (struct parsed_symbol *sym)
 
static charget_args (struct parsed_symbol *sym, BOOL z_term, char open_char, char close_char)
 
static void append_extended_qualifier (struct parsed_symbol *sym, const char **where, const char *str, BOOL is_ms_keyword)
 
static void get_extended_qualifier (struct parsed_symbol *sym, struct datatype_t *xdt)
 
static BOOL get_qualifier (struct parsed_symbol *sym, struct datatype_t *xdt, const char **pclass)
 
static BOOL get_function_qualifier (struct parsed_symbol *sym, const char **qualif)
 
static BOOL get_qualified_type (struct datatype_t *ct, struct parsed_symbol *sym, char qualif, enum datatype_flags flags)
 
static charget_literal_string (struct parsed_symbol *sym)
 
static charget_template_name (struct parsed_symbol *sym)
 
static BOOL get_class (struct parsed_symbol *sym)
 
static charget_class_string (struct parsed_symbol *sym, int start)
 
static BOOL get_calling_convention (char ch, const char **call_conv, const char **exported, unsigned flags)
 
static const charget_simple_type (char c)
 
static const charget_extended_type (char c)
 
static BOOL get_function_signature (struct parsed_symbol *sym, struct function_signature *fs)
 
static BOOL handle_data (struct parsed_symbol *sym)
 
static BOOL handle_method (struct parsed_symbol *sym, BOOL cast_op)
 
char *CDECL __unDNameEx (char *buffer, const char *mangled, int buflen, malloc_func_t memget, free_func_t memfree, void *unknown, unsigned short int flags)
 
char *CDECL __unDName (char *buffer, const char *mangled, int buflen, malloc_func_t memget, free_func_t memfree, unsigned short int flags)
 

Macro Definition Documentation

◆ AVAIL_SIZE

#define AVAIL_SIZE   (1024 - sizeof(void*))

◆ BLOCK_SIZE

#define BLOCK_SIZE   1024

◆ UNDNAME_NO_COMPLEX_TYPE

#define UNDNAME_NO_COMPLEX_TYPE   (0x8000)

Definition at line 51 of file undname.c.

Enumeration Type Documentation

◆ datatype_e

Enumerator
DT_NO_LEADING_WS 
DT_NO_LRSEP_WS 

Definition at line 80 of file undname.c.

81{
82 DT_NO_LEADING_WS = 0x01,
83 DT_NO_LRSEP_WS = 0x02,
84};
@ DT_NO_LEADING_WS
Definition: undname.c:82
@ DT_NO_LRSEP_WS
Definition: undname.c:83

◆ datatype_flags

Enumerator
IN_ARGS 
WS_AFTER_QUAL_IF 

Definition at line 296 of file undname.c.

297{
298 IN_ARGS = 0x01,
299 WS_AFTER_QUAL_IF = 0x02,
300};
@ IN_ARGS
Definition: undname.c:298
@ WS_AFTER_QUAL_IF
Definition: undname.c:299

Function Documentation

◆ __unDName()

char *CDECL __unDName ( char buffer,
const char mangled,
int  buflen,
malloc_func_t  memget,
free_func_t  memfree,
unsigned short int  flags 
)

Definition at line 1783 of file undname.c.

1786{
1787 return __unDNameEx(buffer, mangled, buflen, memget, memfree, NULL, flags);
1788}
#define NULL
Definition: types.h:112
char *CDECL __unDNameEx(char *buffer, const char *mangled, int buflen, malloc_func_t memget, free_func_t memfree, void *unknown, unsigned short int flags)
Definition: undname.c:1736
GLuint buffer
Definition: glext.h:5915
GLbitfield flags
Definition: glext.h:7161

◆ __unDNameEx()

char *CDECL __unDNameEx ( char buffer,
const char mangled,
int  buflen,
malloc_func_t  memget,
free_func_t  memfree,
void unknown,
unsigned short int  flags 
)

Definition at line 1736 of file undname.c.

1739{
1740 struct parsed_symbol sym;
1741 const char* result;
1742
1743 TRACE("(%p,%s,%d,%p,%p,%p,%x)\n",
1744 buffer, debugstr_a(mangled), buflen, memget, memfree, unknown, flags);
1745
1746 /* The flags details is not documented by MS. However, it looks exactly
1747 * like the UNDNAME_ manifest constants from imagehlp.h and dbghelp.h
1748 * So, we copied those (on top of the file)
1749 */
1750 memset(&sym, 0, sizeof(struct parsed_symbol));
1755
1756 sym.flags = flags;
1757 sym.mem_alloc_ptr = memget;
1758 sym.mem_free_ptr = memfree;
1759 sym.current = mangled;
1760 str_array_init( &sym.names );
1761 str_array_init( &sym.stack );
1762
1763 result = symbol_demangle(&sym) ? sym.result : mangled;
1764 if (buffer && buflen)
1765 {
1766 lstrcpynA( buffer, result, buflen);
1767 }
1768 else
1769 {
1770 buffer = memget(strlen(result) + 1);
1771 if (buffer) strcpy(buffer, result);
1772 }
1773
1774 und_free_all(&sym);
1775
1776 return buffer;
1777}
#define UNDNAME_NO_ALLOCATION_LANGUAGE
Definition: dbghelp.h:1256
#define UNDNAME_NO_FUNCTION_RETURNS
Definition: dbghelp.h:1254
#define UNDNAME_NO_ACCESS_SPECIFIERS
Definition: dbghelp.h:1260
#define UNDNAME_NO_MEMBER_TYPE
Definition: dbghelp.h:1262
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
#define lstrcpynA
Definition: compat.h:751
#define UNDNAME_NAME_ONLY
Definition: compat.h:1017
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
static void und_free_all(struct parsed_symbol *sym)
Definition: undname.c:146
static BOOL symbol_demangle(struct parsed_symbol *sym)
Definition: undname.c:1475
static void str_array_init(struct array *a)
Definition: undname.c:163
#define UNDNAME_NO_COMPLEX_TYPE
Definition: undname.c:51
GLuint64EXT * result
Definition: glext.h:11304
#define debugstr_a
Definition: kernel32.h:31
strcpy
Definition: string.h:131
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4

Referenced by __unDName().

◆ append_extended_qualifier()

static void append_extended_qualifier ( struct parsed_symbol sym,
const char **  where,
const char str,
BOOL  is_ms_keyword 
)
static

Definition at line 434 of file undname.c.

436{
437 if (!is_ms_keyword || !(sym->flags & UNDNAME_NO_MS_KEYWORDS))
438 {
439 if (is_ms_keyword && (sym->flags & UNDNAME_NO_LEADING_UNDERSCORES))
440 str += 2;
441 *where = *where ? str_printf(sym, "%s%s%s%s", *where, is_ms_keyword ? " " : "", str, is_ms_keyword ? "" : " ") :
442 str_printf(sym, "%s%s", str, is_ms_keyword ? "" : " ");
443 }
444}
#define UNDNAME_NO_MS_KEYWORDS
Definition: dbghelp.h:1253
#define UNDNAME_NO_LEADING_UNDERSCORES
Definition: dbghelp.h:1252
static char *WINAPIV str_printf(struct parsed_symbol *sym, const char *format,...)
Definition: undname.c:241
const WCHAR * str
unsigned flags
Definition: undname.c:65

Referenced by get_extended_qualifier().

◆ demangle_datatype()

static BOOL demangle_datatype ( struct parsed_symbol sym,
struct datatype_t ct,
enum datatype_flags  flags 
)
static

Definition at line 938 of file undname.c.

940{
941 char dt;
942
943 assert(ct);
944 ct->left = ct->right = NULL;
945 ct->flags = 0;
946
947 switch (dt = *sym->current++)
948 {
949 case '_':
950 /* MS type: __int8,__int16 etc */
951 ct->left = get_extended_type(*sym->current++);
952 break;
953 case 'C': case 'D': case 'E': case 'F': case 'G':
954 case 'H': case 'I': case 'J': case 'K': case 'M':
955 case 'N': case 'O': case 'X': case 'Z':
956 /* Simple data types */
957 ct->left = get_simple_type(dt);
958 break;
959 case 'T': /* union */
960 case 'U': /* struct */
961 case 'V': /* class */
962 case 'Y': /* cointerface */
963 /* Class/struct/union/cointerface */
964 {
965 const char* struct_name = NULL;
966 const char* type_name = NULL;
967
968 if (!(struct_name = get_class_name(sym)))
969 goto done;
970 if (!(sym->flags & UNDNAME_NO_COMPLEX_TYPE))
971 {
972 switch (dt)
973 {
974 case 'T': type_name = "union "; break;
975 case 'U': type_name = "struct "; break;
976 case 'V': type_name = "class "; break;
977 case 'Y': type_name = "cointerface "; break;
978 }
979 }
980 ct->left = str_printf(sym, "%s%s", type_name, struct_name);
981 }
982 break;
983 case '?':
984 /* not all the time is seems */
985 if (flags & IN_ARGS)
986 {
987 const char* ptr;
988 if (!(ptr = get_number(sym))) goto done;
989 ct->left = str_printf(sym, "`template-parameter-%s'", ptr);
990 }
991 else
992 {
993 if (!get_qualified_type(ct, sym, '?', flags)) goto done;
994 }
995 break;
996 case 'A': /* reference */
997 case 'B': /* volatile reference */
998 if (!get_qualified_type(ct, sym, dt, flags)) goto done;
999 break;
1000 case 'P': /* Pointer */
1001 case 'Q': /* const pointer */
1002 case 'R': /* volatile pointer */
1003 case 'S': /* const volatile pointer */
1004 if (!(flags & IN_ARGS)) dt = 'P';
1005 if (isdigit(*sym->current))
1006 {
1007 const char *ptr_qualif;
1008 switch (dt)
1009 {
1010 default:
1011 case 'P': ptr_qualif = NULL; break;
1012 case 'Q': ptr_qualif = "const"; break;
1013 case 'R': ptr_qualif = "volatile"; break;
1014 case 'S': ptr_qualif = "const volatile"; break;
1015 }
1016 /* FIXME:
1017 * P6 = Function pointer
1018 * P8 = Member function pointer
1019 * others who knows.. */
1020 if (*sym->current == '8')
1021 {
1022 struct function_signature fs;
1023 const char* class;
1024 const char* function_qualifier;
1025
1026 sym->current++;
1027
1028 if (!(class = get_class_name(sym)))
1029 goto done;
1030 if (!get_function_qualifier(sym, &function_qualifier))
1031 goto done;
1032 if (!get_function_signature(sym, &fs))
1033 goto done;
1034
1035 ct->left = str_printf(sym, "%s%s (%s %s::*%s",
1036 fs.return_ct.left, fs.return_ct.right, fs.call_conv, class, ptr_qualif);
1037 ct->right = str_printf(sym, ")%s%s", fs.arguments, function_qualifier);
1038 }
1039 else if (*sym->current == '6')
1040 {
1041 struct function_signature fs;
1042
1043 sym->current++;
1044
1045 if (!get_function_signature(sym, &fs))
1046 goto done;
1047
1048 ct->left = str_printf(sym, "%s%s (%s*%s",
1049 fs.return_ct.left, fs.return_ct.right, fs.call_conv, ptr_qualif);
1050 ct->flags = DT_NO_LEADING_WS;
1051 ct->right = str_printf(sym, ")%s", fs.arguments);
1052 }
1053 else goto done;
1054 }
1055 else if (!get_qualified_type(ct, sym, dt, flags)) goto done;
1056 break;
1057 case 'W':
1058 if (*sym->current == '4')
1059 {
1060 char* enum_name;
1061 sym->current++;
1062 if (!(enum_name = get_class_name(sym)))
1063 goto done;
1064 if (sym->flags & UNDNAME_NO_COMPLEX_TYPE)
1065 ct->left = enum_name;
1066 else
1067 ct->left = str_printf(sym, "enum %s", enum_name);
1068 }
1069 else goto done;
1070 break;
1071 case '0': case '1': case '2': case '3': case '4':
1072 case '5': case '6': case '7': case '8': case '9':
1073 /* Referring back to previously parsed type */
1074 /* left and right are pushed as two separate strings */
1075 ct->left = str_array_get_ref(&sym->args, (dt - '0') * 2);
1076 ct->right = str_array_get_ref(&sym->args, (dt - '0') * 2 + 1);
1077 if (!ct->left) goto done;
1078 break;
1079 case '$':
1080 switch (*sym->current++)
1081 {
1082 case '0':
1083 if (!(ct->left = get_number(sym))) goto done;
1084 break;
1085 case 'D':
1086 {
1087 const char* ptr;
1088 if (!(ptr = get_number(sym))) goto done;
1089 ct->left = str_printf(sym, "`template-parameter%s'", ptr);
1090 }
1091 break;
1092 case 'F':
1093 {
1094 const char* p1;
1095 const char* p2;
1096 if (!(p1 = get_number(sym))) goto done;
1097 if (!(p2 = get_number(sym))) goto done;
1098 ct->left = str_printf(sym, "{%s,%s}", p1, p2);
1099 }
1100 break;
1101 case 'G':
1102 {
1103 const char* p1;
1104 const char* p2;
1105 const char* p3;
1106 if (!(p1 = get_number(sym))) goto done;
1107 if (!(p2 = get_number(sym))) goto done;
1108 if (!(p3 = get_number(sym))) goto done;
1109 ct->left = str_printf(sym, "{%s,%s,%s}", p1, p2, p3);
1110 }
1111 break;
1112 case 'Q':
1113 {
1114 const char* ptr;
1115 if (!(ptr = get_number(sym))) goto done;
1116 ct->left = str_printf(sym, "`non-type-template-parameter%s'", ptr);
1117 }
1118 break;
1119 case '$':
1120 if (*sym->current == 'A')
1121 {
1122 sym->current++;
1123 if (*sym->current == '6')
1124 {
1125 struct function_signature fs;
1126
1127 sym->current++;
1128
1129 if (!get_function_signature(sym, &fs))
1130 goto done;
1131 ct->left = str_printf(sym, "%s%s %s%s",
1132 fs.return_ct.left, fs.return_ct.right, fs.call_conv, fs.arguments);
1133 }
1134 }
1135 else if (*sym->current == 'B')
1136 {
1137 unsigned mark = sym->stack.num;
1138 struct datatype_t sub_ct;
1139 const char* arr = NULL;
1140 sym->current++;
1141
1142 /* multidimensional arrays */
1143 if (*sym->current == 'Y')
1144 {
1145 const char* n1;
1146 int num;
1147
1148 sym->current++;
1149 if (!(n1 = get_number(sym))) goto done;
1150 num = atoi(n1);
1151
1152 while (num--)
1153 arr = str_printf(sym, "%s[%s]", arr, get_number(sym));
1154 }
1155
1156 if (!demangle_datatype(sym, &sub_ct, 0)) goto done;
1157
1158 if (arr)
1159 ct->left = str_printf(sym, "%s %s", sub_ct.left, arr);
1160 else
1161 ct->left = sub_ct.left;
1162 ct->right = sub_ct.right;
1163 sym->stack.num = mark;
1164 }
1165 else if (*sym->current == 'C')
1166 {
1167 struct datatype_t xdt;
1168
1169 sym->current++;
1170 if (!get_qualifier(sym, &xdt, NULL)) goto done;
1171 if (!demangle_datatype(sym, ct, flags)) goto done;
1172 ct->left = str_printf(sym, "%s %s", ct->left, xdt.left);
1173 }
1174 else if (*sym->current == 'Q')
1175 {
1176 sym->current++;
1177 if (!get_qualified_type(ct, sym, '$', flags)) goto done;
1178 }
1179 else if (*sym->current == 'T')
1180 {
1181 sym->current++;
1182 ct->left = str_printf(sym, "std::nullptr_t");
1183 }
1184 break;
1185 }
1186 break;
1187 default :
1188 ERR("Unknown type %c\n", dt);
1189 break;
1190 }
1191done:
1192
1193 return ct->left != NULL;
1194}
#define isdigit(c)
Definition: acclib.h:68
#define ERR(fmt,...)
Definition: precomp.h:57
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl atoi(const char *)
Definition: string.c:1715
static BOOL demangle_datatype(struct parsed_symbol *sym, struct datatype_t *ct, enum datatype_flags flags)
Definition: undname.c:938
static BOOL get_qualified_type(struct datatype_t *ct, struct parsed_symbol *sym, char qualif, enum datatype_flags flags)
Definition: undname.c:520
static const char * get_number(struct parsed_symbol *sym)
Definition: undname.c:306
static BOOL get_function_qualifier(struct parsed_symbol *sym, const char **qualif)
Definition: undname.c:510
static const char * get_extended_type(char c)
Definition: undname.c:880
static BOOL get_qualifier(struct parsed_symbol *sym, struct datatype_t *xdt, const char **pclass)
Definition: undname.c:472
static char * str_array_get_ref(struct array *cref, unsigned idx)
Definition: undname.c:222
static BOOL get_function_signature(struct parsed_symbol *sym, struct function_signature *fs)
Definition: undname.c:914
static const char * get_simple_type(char c)
Definition: undname.c:851
static char * get_class_name(struct parsed_symbol *sym)
Definition: undname.c:790
GLuint GLuint num
Definition: glext.h:9618
static PVOID ptr
Definition: dispmode.c:27
int n1
Definition: dwarfget.c:147
enum datatype_e flags
Definition: undname.c:91
const char * right
Definition: undname.c:90
const char * left
Definition: undname.c:89
Definition: ffs.h:70
const char * current
Definition: undname.c:69
struct array args
Definition: undname.c:73
struct array stack
Definition: undname.c:74

Referenced by demangle_datatype(), get_args(), get_function_signature(), get_modified_type(), get_qualified_type(), handle_data(), handle_method(), and symbol_demangle().

◆ get_args()

static char * get_args ( struct parsed_symbol sym,
BOOL  z_term,
char  open_char,
char  close_char 
)
static

Definition at line 357 of file undname.c.

360{
361 struct datatype_t ct;
362 struct array arg_collect;
363 char* args_str = NULL;
364 char* last;
365 unsigned int i;
366 const char *p;
367
368 if (z_term && sym->current[0] == 'X' && sym->current[1] == 'Z')
369 {
370 sym->current += 2;
371 return str_printf(sym, "%cvoid%c", open_char, close_char);
372 }
373
374 str_array_init(&arg_collect);
375
376 /* Now come the function arguments */
377 while (*sym->current)
378 {
379 p = sym->current;
380
381 /* Decode each data type and append it to the argument list */
382 if (*sym->current == '@')
383 {
384 sym->current++;
385 break;
386 }
387 if (z_term && sym->current[0] == 'Z')
388 {
389 sym->current++;
390 if (!str_array_push(sym, "...", -1, &arg_collect))
391 return NULL;
392 break;
393 }
394 /* Handle empty list in variadic template */
395 if (!z_term && sym->current[0] == '$' && sym->current[1] == '$' && sym->current[2] == 'V')
396 {
397 sym->current += 3;
398 continue;
399 }
400 if (!demangle_datatype(sym, &ct, IN_ARGS))
401 return NULL;
402 if (!str_array_push(sym, str_printf(sym, "%s%s", ct.left, ct.right), -1,
403 &arg_collect))
404 return NULL;
405 if (z_term && sym->current - p > 1 && sym->args.num < 20)
406 {
407 if (!str_array_push(sym, ct.left ? ct.left : "", -1, &sym->args) ||
408 !str_array_push(sym, ct.right ? ct.right : "", -1, &sym->args))
409 return NULL;
410 }
411 }
412 /* Functions are always terminated by 'Z'. If we made it this far and
413 * don't find it, we have incorrectly identified a data type.
414 */
415 if (z_term && *sym->current++ != 'Z') return NULL;
416
417 if (!arg_collect.num) return str_printf(sym, "%c%c", open_char, close_char);
418 for (i = 1; i < arg_collect.num; i++)
419 {
420 args_str = str_printf(sym, "%s,%s", args_str, arg_collect.elts[i]);
421 }
422
423 last = args_str ? args_str : arg_collect.elts[0];
424 if (close_char == '>' && last[strlen(last) - 1] == '>')
425 args_str = str_printf(sym, "%c%s%s %c",
426 open_char, arg_collect.elts[0], args_str, close_char);
427 else
428 args_str = str_printf(sym, "%c%s%s%c",
429 open_char, arg_collect.elts[0], args_str, close_char);
430
431 return args_str;
432}
static BOOL str_array_push(struct parsed_symbol *sym, const char *ptr, int len, struct array *a)
Definition: undname.c:173
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static char close_char
Definition: i386-dis.c:2054
static char open_char
Definition: i386-dis.c:2053
static UINT UINT last
Definition: font.c:45
Definition: undname.c:54

Referenced by demangle_datatype(), get_function_signature(), get_template_name(), handle_method(), and symbol_demangle().

◆ get_calling_convention()

static BOOL get_calling_convention ( char  ch,
const char **  call_conv,
const char **  exported,
unsigned  flags 
)
static

Definition at line 806 of file undname.c.

808{
809 *call_conv = *exported = NULL;
810
812 {
814 {
815 if (((ch - 'A') % 2) == 1) *exported = "dll_export ";
816 switch (ch)
817 {
818 case 'A': case 'B': *call_conv = "cdecl"; break;
819 case 'C': case 'D': *call_conv = "pascal"; break;
820 case 'E': case 'F': *call_conv = "thiscall"; break;
821 case 'G': case 'H': *call_conv = "stdcall"; break;
822 case 'I': case 'J': *call_conv = "fastcall"; break;
823 case 'K': case 'L': break;
824 case 'M': *call_conv = "clrcall"; break;
825 default: ERR("Unknown calling convention %c\n", ch); return FALSE;
826 }
827 }
828 else
829 {
830 if (((ch - 'A') % 2) == 1) *exported = "__dll_export ";
831 switch (ch)
832 {
833 case 'A': case 'B': *call_conv = "__cdecl"; break;
834 case 'C': case 'D': *call_conv = "__pascal"; break;
835 case 'E': case 'F': *call_conv = "__thiscall"; break;
836 case 'G': case 'H': *call_conv = "__stdcall"; break;
837 case 'I': case 'J': *call_conv = "__fastcall"; break;
838 case 'K': case 'L': break;
839 case 'M': *call_conv = "__clrcall"; break;
840 default: ERR("Unknown calling convention %c\n", ch); return FALSE;
841 }
842 }
843 }
844 return TRUE;
845}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned char ch[4][2]
Definition: console.c:118

Referenced by demangle_datatype(), get_function_signature(), and handle_method().

◆ get_class()

static BOOL get_class ( struct parsed_symbol sym)
static

Definition at line 699 of file undname.c.

700{
701 const char* name = NULL;
702
703 while (*sym->current != '@')
704 {
705 switch (*sym->current)
706 {
707 case '\0': return FALSE;
708
709 case '0': case '1': case '2': case '3':
710 case '4': case '5': case '6': case '7':
711 case '8': case '9':
712 name = str_array_get_ref(&sym->names, *sym->current++ - '0');
713 break;
714 case '?':
715 switch (*++sym->current)
716 {
717 case '$':
718 sym->current++;
719 if ((name = get_template_name(sym)) &&
720 !str_array_push(sym, name, -1, &sym->names))
721 return FALSE;
722 break;
723 case '?':
724 {
725 struct array stack = sym->stack;
726 unsigned int start = sym->names.start;
727 unsigned int num = sym->names.num;
728
729 str_array_init( &sym->stack );
730 if (symbol_demangle( sym )) name = str_printf( sym, "`%s'", sym->result );
731 sym->names.start = start;
732 sym->names.num = num;
733 sym->stack = stack;
734 }
735 break;
736 default:
737 if (!(name = get_number( sym ))) return FALSE;
738 name = str_printf( sym, "`%s'", name );
739 break;
740 }
741 break;
742 default:
744 break;
745 }
746 if (!name || !str_array_push(sym, name, -1, &sym->stack))
747 return FALSE;
748 }
749 sym->current++;
750 return TRUE;
751}
static char * get_literal_string(struct parsed_symbol *sym)
Definition: undname.c:632
static char * get_template_name(struct parsed_symbol *sym)
Definition: undname.c:663
GLuint start
Definition: gl.h:1545
Definition: name.c:39
char * result
Definition: undname.c:70
struct array names
Definition: undname.c:72
Definition: format.c:80

Referenced by get_class_name(), and symbol_demangle().

◆ get_class_name()

static char * get_class_name ( struct parsed_symbol sym)
static

Definition at line 790 of file undname.c.

791{
792 unsigned mark = sym->stack.num;
793 char* s = NULL;
794
795 if (get_class(sym))
796 s = get_class_string(sym, mark);
797 sym->stack.num = mark;
798 return s;
799}
static BOOL get_class(struct parsed_symbol *sym)
Definition: undname.c:699
static char * get_class_string(struct parsed_symbol *sym, int start)
Definition: undname.c:758
GLdouble s
Definition: gl.h:2039

Referenced by demangle_datatype(), and handle_data().

◆ get_class_string()

static char * get_class_string ( struct parsed_symbol sym,
int  start 
)
static

Definition at line 758 of file undname.c.

759{
760 int i;
761 unsigned int len, sz;
762 char* ret;
763 struct array *a = &sym->stack;
764
765 for (len = 0, i = start; i < a->num; i++)
766 {
767 assert(a->elts[i]);
768 len += 2 + strlen(a->elts[i]);
769 }
770 if (!(ret = und_alloc(sym, len - 1))) return NULL;
771 for (len = 0, i = a->num - 1; i >= start; i--)
772 {
773 sz = strlen(a->elts[i]);
774 memcpy(ret + len, a->elts[i], sz);
775 len += sz;
776 if (i > start)
777 {
778 ret[len++] = ':';
779 ret[len++] = ':';
780 }
781 }
782 ret[len] = '\0';
783 return ret;
784}
static void * und_alloc(struct parsed_symbol *sym, unsigned int len)
Definition: undname.c:104
return ret
Definition: mutex.c:146
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by get_class_name(), handle_data(), and handle_method().

◆ get_extended_qualifier()

static void get_extended_qualifier ( struct parsed_symbol sym,
struct datatype_t xdt 
)
static

Definition at line 446 of file undname.c.

447{
448 unsigned fl = 0;
449 xdt->left = xdt->right = NULL;
450 xdt->flags = 0;
451 for (;;)
452 {
453 switch (*sym->current)
454 {
455 case 'E': append_extended_qualifier(sym, &xdt->right, "__ptr64", TRUE); fl |= 2; break;
456 case 'F': append_extended_qualifier(sym, &xdt->left, "__unaligned", TRUE); fl |= 2; break;
457#ifdef _UCRT
458 case 'G': append_extended_qualifier(sym, &xdt->right, "&", FALSE); fl |= 1; break;
459 case 'H': append_extended_qualifier(sym, &xdt->right, "&&", FALSE); fl |= 1; break;
460#endif
461 case 'I': append_extended_qualifier(sym, &xdt->right, "__restrict", TRUE); fl |= 2; break;
462 default: if (fl == 1 || (fl == 3 && (sym->flags & UNDNAME_NO_MS_KEYWORDS))) xdt->flags = DT_NO_LRSEP_WS; return;
463 }
464 sym->current++;
465 }
466}
static void append_extended_qualifier(struct parsed_symbol *sym, const char **where, const char *str, BOOL is_ms_keyword)
Definition: undname.c:434
_In_ FLONG fl
Definition: winddi.h:1279

Referenced by get_qualified_type(), and get_qualifier().

◆ get_extended_type()

static const char * get_extended_type ( char  c)
static

Definition at line 880 of file undname.c.

881{
882 const char* type_string;
883
884 switch (c)
885 {
886 case 'D': type_string = "__int8"; break;
887 case 'E': type_string = "unsigned __int8"; break;
888 case 'F': type_string = "__int16"; break;
889 case 'G': type_string = "unsigned __int16"; break;
890 case 'H': type_string = "__int32"; break;
891 case 'I': type_string = "unsigned __int32"; break;
892 case 'J': type_string = "__int64"; break;
893 case 'K': type_string = "unsigned __int64"; break;
894 case 'L': type_string = "__int128"; break;
895 case 'M': type_string = "unsigned __int128"; break;
896 case 'N': type_string = "bool"; break;
897 case 'Q': type_string = "char8_t"; break;
898 case 'S': type_string = "char16_t"; break;
899 case 'U': type_string = "char32_t"; break;
900 case 'W': type_string = "wchar_t"; break;
901 default: type_string = NULL; break;
902 }
903 return type_string;
904}
const GLubyte * c
Definition: glext.h:8905

Referenced by demangle_datatype().

◆ get_function_qualifier()

static BOOL get_function_qualifier ( struct parsed_symbol sym,
const char **  qualif 
)
static

Definition at line 510 of file undname.c.

511{
512 struct datatype_t xdt;
513
514 if (!get_qualifier(sym, &xdt, NULL)) return FALSE;
515 *qualif = (xdt.left || xdt.right) ?
516 str_printf(sym, "%s%s%s", xdt.left, (xdt.flags & DT_NO_LRSEP_WS) ? "" : " ", xdt.right) : NULL;
517 return TRUE;
518}

Referenced by demangle_datatype(), and handle_method().

◆ get_function_signature()

static BOOL get_function_signature ( struct parsed_symbol sym,
struct function_signature fs 
)
static

Definition at line 914 of file undname.c.

915{
916 unsigned mark = sym->stack.num;
917
918 if (!get_calling_convention(*sym->current++,
919 &fs->call_conv, &fs->exported,
921 !demangle_datatype(sym, &fs->return_ct, 0))
922 return FALSE;
923
924 if (!(fs->arguments = get_args(sym, TRUE, '(', ')')))
925 return FALSE;
926 sym->stack.num = mark;
927
928 return TRUE;
929}
static BOOL get_calling_convention(char ch, const char **call_conv, const char **exported, unsigned flags)
Definition: undname.c:806
static char * get_args(struct parsed_symbol *sym, BOOL z_term, char open_char, char close_char)
Definition: undname.c:357

Referenced by demangle_datatype().

◆ get_literal_string()

static char * get_literal_string ( struct parsed_symbol sym)
static

Definition at line 632 of file undname.c.

633{
634 const char *ptr = sym->current;
635
636 do {
637 if (!((*sym->current >= 'A' && *sym->current <= 'Z') ||
638 (*sym->current >= 'a' && *sym->current <= 'z') ||
639 (*sym->current >= '0' && *sym->current <= '9') ||
640 *sym->current == '_' || *sym->current == '$' ||
641 *sym->current == '<' || *sym->current == '>')) {
642 TRACE("Failed at '%c' in %s\n", *sym->current, debugstr_a(ptr));
643 return NULL;
644 }
645 } while (*++sym->current != '@');
646 sym->current++;
647 if (!str_array_push(sym, ptr, sym->current - 1 - ptr, &sym->names))
648 return NULL;
649
650 return str_array_get_ref(&sym->names, sym->names.num - sym->names.start - 1);
651}

Referenced by get_class(), get_template_name(), and symbol_demangle().

◆ get_number()

static const char * get_number ( struct parsed_symbol sym)
static

Definition at line 306 of file undname.c.

307{
308 char* ptr;
309 BOOL sgn = FALSE;
310
311 if (*sym->current == '?')
312 {
313 sgn = TRUE;
314 sym->current++;
315 }
316 if (*sym->current >= '0' && *sym->current <= '8')
317 {
318 ptr = und_alloc(sym, 3);
319 if (sgn) ptr[0] = '-';
320 ptr[sgn ? 1 : 0] = *sym->current + 1;
321 ptr[sgn ? 2 : 1] = '\0';
322 sym->current++;
323 }
324 else if (*sym->current == '9')
325 {
326 ptr = und_alloc(sym, 4);
327 if (sgn) ptr[0] = '-';
328 ptr[sgn ? 1 : 0] = '1';
329 ptr[sgn ? 2 : 1] = '0';
330 ptr[sgn ? 3 : 2] = '\0';
331 sym->current++;
332 }
333 else if (*sym->current >= 'A' && *sym->current <= 'P')
334 {
335 int ret = 0;
336
337 while (*sym->current >= 'A' && *sym->current <= 'P')
338 {
339 ret *= 16;
340 ret += *sym->current++ - 'A';
341 }
342 if (*sym->current != '@') return NULL;
343
344 ptr = und_alloc(sym, 17);
345 sprintf(ptr, "%s%u", sgn ? "-" : "", ret);
346 sym->current++;
347 }
348 else return NULL;
349 return ptr;
350}
unsigned int BOOL
Definition: ntddk_ex.h:94
#define sprintf
Definition: sprintf.c:45
long sgn(REAL x)
Definition: varray.cc:48

Referenced by demangle_datatype(), get_class(), get_modified_type(), get_qualified_type(), handle_method(), and symbol_demangle().

◆ get_qualified_type()

static BOOL get_qualified_type ( struct datatype_t ct,
struct parsed_symbol sym,
char  qualif,
enum datatype_flags  flags 
)
static

Definition at line 520 of file undname.c.

522{
523 struct datatype_t xdt1;
524 struct datatype_t xdt2;
525 const char* ref;
526 const char* str_qualif;
527 const char* class;
528
529 get_extended_qualifier(sym, &xdt1);
530
531 switch (qualif)
532 {
533 case 'A': ref = " &"; str_qualif = NULL; break;
534 case 'B': ref = " &"; str_qualif = " volatile"; break;
535 case 'P': ref = " *"; str_qualif = NULL; break;
536 case 'Q': ref = " *"; str_qualif = " const"; break;
537 case 'R': ref = " *"; str_qualif = " volatile"; break;
538 case 'S': ref = " *"; str_qualif = " const volatile"; break;
539 case '?': ref = NULL; str_qualif = NULL; break;
540 case '$': ref = " &&"; str_qualif = NULL; break;
541 default: return FALSE;
542 }
543 ct->right = NULL;
544 ct->flags = 0;
545
546 /* parse managed handle information */
547 if (sym->current[0] == '$' && sym->current[1] == 'A')
548 {
549 sym->current += 2;
550
551 switch (qualif)
552 {
553 case 'A':
554 case 'B':
555 ref = " %";
556 break;
557 case 'P':
558 case 'Q':
559 case 'R':
560 case 'S':
561 ref = " ^";
562 break;
563 default:
564 return FALSE;
565 }
566 }
567
568 if (get_qualifier(sym, &xdt2, &class))
569 {
570 unsigned mark = sym->stack.num;
571 struct datatype_t sub_ct;
572
573 if (ref || str_qualif || xdt1.left || xdt1.right)
574 {
575 if (class)
576 ct->left = str_printf(sym, "%s%s%s%s::%s%s%s",
577 xdt1.left ? " " : NULL, xdt1.left,
578 class ? " " : NULL, class, ref ? ref + 1 : NULL,
579 xdt1.right ? " " : NULL, xdt1.right, str_qualif);
580 else
581 ct->left = str_printf(sym, "%s%s%s%s%s%s",
582 xdt1.left ? " " : NULL, xdt1.left, ref,
583 xdt1.right ? " " : NULL, xdt1.right, str_qualif);
584 }
585 else
586 ct->left = NULL;
587 /* multidimensional arrays */
588 if (*sym->current == 'Y')
589 {
590 const char* n1;
591 int num;
592
593 sym->current++;
594 if (!(n1 = get_number(sym))) return FALSE;
595 num = atoi(n1);
596
597 ct->left = str_printf(sym, " (%s%s", xdt2.left, ct->left && !xdt2.left ? ct->left + 1 : ct->left);
598 ct->right = ")";
599 xdt2.left = NULL;
600
601 while (num--)
602 ct->right = str_printf(sym, "%s[%s]", ct->right, get_number(sym));
603 }
604
605 /* Recurse to get the referred-to type */
606 if (!demangle_datatype(sym, &sub_ct, 0))
607 return FALSE;
608 if (sub_ct.flags & DT_NO_LEADING_WS)
609 ct->left++;
610 ct->left = str_printf(sym, "%s%s%s%s%s", sub_ct.left, xdt2.left ? " " : NULL,
611 xdt2.left, ct->left,
612 ((xdt2.left || str_qualif) && (flags & WS_AFTER_QUAL_IF)) ? " " : NULL);
613 if (sub_ct.right) ct->right = str_printf(sym, "%s%s", ct->right, sub_ct.right);
614 sym->stack.num = mark;
615 }
616 else if (ref || str_qualif || xdt1.left || xdt1.right)
617 ct->left = str_printf(sym, "%s%s%s%s%s%s",
618 xdt1.left ? " " : NULL, xdt1.left, ref,
619 xdt1.right ? " " : NULL, xdt1.right, str_qualif);
620 else
621 ct->left = NULL;
622 return TRUE;
623}
static void get_extended_qualifier(struct parsed_symbol *sym, struct datatype_t *xdt)
Definition: undname.c:446
Definition: send.c:48

Referenced by demangle_datatype().

◆ get_qualifier()

static BOOL get_qualifier ( struct parsed_symbol sym,
struct datatype_t xdt,
const char **  pclass 
)
static

Definition at line 472 of file undname.c.

473{
474 char ch;
475 const char* qualif;
476
477 get_extended_qualifier(sym, xdt);
478 switch (ch = *sym->current++)
479 {
480 case 'A': qualif = NULL; break;
481 case 'B': qualif = "const"; break;
482 case 'C': qualif = "volatile"; break;
483 case 'D': qualif = "const volatile"; break;
484 case 'Q': qualif = NULL; break;
485 case 'R': qualif = "const"; break;
486 case 'S': qualif = "volatile"; break;
487 case 'T': qualif = "const volatile"; break;
488 default: return FALSE;
489 }
490 if (qualif)
491 {
492 xdt->flags &= ~DT_NO_LRSEP_WS;
493 xdt->left = xdt->left ? str_printf(sym, "%s %s", qualif, xdt->left) : qualif;
494 }
495 if (ch >= 'Q' && ch <= 'T') /* pointer to member, fetch class */
496 {
497 const char* class = get_class_name(sym);
498 if (!class) return FALSE;
499 if (!pclass)
500 {
501 FIXME("Got pointer to class %s member without storage\n", class);
502 return FALSE;
503 }
504 *pclass = class;
505 }
506 else if (pclass) *pclass = NULL;
507 return TRUE;
508}
#define FIXME(fmt,...)
Definition: precomp.h:53

Referenced by demangle_datatype(), get_function_qualifier(), get_qualified_type(), and handle_data().

◆ get_simple_type()

static const char * get_simple_type ( char  c)
static

Definition at line 851 of file undname.c.

852{
853 const char* type_string;
854
855 switch (c)
856 {
857 case 'C': type_string = "signed char"; break;
858 case 'D': type_string = "char"; break;
859 case 'E': type_string = "unsigned char"; break;
860 case 'F': type_string = "short"; break;
861 case 'G': type_string = "unsigned short"; break;
862 case 'H': type_string = "int"; break;
863 case 'I': type_string = "unsigned int"; break;
864 case 'J': type_string = "long"; break;
865 case 'K': type_string = "unsigned long"; break;
866 case 'M': type_string = "float"; break;
867 case 'N': type_string = "double"; break;
868 case 'O': type_string = "long double"; break;
869 case 'X': type_string = "void"; break;
870/* case 'Z': (...) variadic function arguments. Handled in get_args() */
871 default: type_string = NULL; break;
872 }
873 return type_string;
874}

Referenced by demangle_datatype().

◆ get_template_name()

static char * get_template_name ( struct parsed_symbol sym)
static

Definition at line 663 of file undname.c.

664{
665 char *name, *args;
666 unsigned num_mark = sym->names.num;
667 unsigned start_mark = sym->names.start;
668 unsigned stack_mark = sym->stack.num;
669 unsigned args_mark = sym->args.num;
670
671 sym->names.start = sym->names.num;
672 if (!(name = get_literal_string(sym))) {
673 sym->names.start = start_mark;
674 return FALSE;
675 }
676 args = get_args(sym, FALSE, '<', '>');
677 if (args != NULL)
678 name = str_printf(sym, "%s%s", name, args);
679 sym->names.num = num_mark;
680 sym->names.start = start_mark;
681 sym->stack.num = stack_mark;
682 sym->args.num = args_mark;
683 return name;
684}
#define args
Definition: format.c:66
Definition: match.c:390

Referenced by get_class(), and symbol_demangle().

◆ handle_data()

static BOOL handle_data ( struct parsed_symbol sym)
static

Definition at line 1201 of file undname.c.

1202{
1203 const char* access = NULL;
1204 const char* member_type = NULL;
1205 struct datatype_t xdt = {NULL};
1206 struct datatype_t ct;
1207 char* name = NULL;
1208 BOOL ret = FALSE;
1209
1210 /* 0 private static
1211 * 1 protected static
1212 * 2 public static
1213 * 3 private non-static
1214 * 4 protected non-static
1215 * 5 public non-static
1216 * 6 ?? static
1217 * 7 ?? static
1218 */
1219
1220 if (!(sym->flags & UNDNAME_NO_ACCESS_SPECIFIERS))
1221 {
1222 /* we only print the access for static members */
1223 switch (*sym->current)
1224 {
1225 case '0': access = "private: "; break;
1226 case '1': access = "protected: "; break;
1227 case '2': access = "public: "; break;
1228 }
1229 }
1230
1231 if (!(sym->flags & UNDNAME_NO_MEMBER_TYPE))
1232 {
1233 if (*sym->current >= '0' && *sym->current <= '2')
1234 member_type = "static ";
1235 }
1236
1237 name = get_class_string(sym, 0);
1238
1239 switch (*sym->current++)
1240 {
1241 case '0': case '1': case '2':
1242 case '3': case '4': case '5':
1243 {
1244 unsigned mark = sym->stack.num;
1245 const char* class;
1246
1247 if (!demangle_datatype(sym, &ct, 0)) goto done;
1248 if (!get_qualifier(sym, &xdt, &class)) goto done; /* class doesn't seem to be displayed */
1249 if (xdt.left && xdt.right) xdt.left = str_printf(sym, "%s %s", xdt.left, xdt.right);
1250 else if (!xdt.left) xdt.left = xdt.right;
1251 sym->stack.num = mark;
1252 }
1253 break;
1254 case '6' : /* compiler generated static */
1255 case '7' : /* compiler generated static */
1256 ct.left = ct.right = NULL;
1257 if (!get_qualifier(sym, &xdt, NULL)) goto done;
1258 if (*sym->current != '@')
1259 {
1260 char* cls = NULL;
1261
1262 if (!(cls = get_class_name(sym)))
1263 goto done;
1264 ct.right = str_printf(sym, "{for `%s'}", cls);
1265 }
1266 break;
1267 case '8':
1268 case '9':
1269 xdt.left = ct.left = ct.right = NULL;
1270 break;
1271 default: goto done;
1272 }
1273 if (sym->flags & UNDNAME_NAME_ONLY) ct.left = ct.right = xdt.left = NULL;
1274
1275 sym->result = str_printf(sym, "%s%s%s%s%s%s%s%s", access,
1276 member_type, ct.left,
1277 xdt.left && ct.left ? " " : NULL, xdt.left,
1278 xdt.left || ct.left ? " " : NULL, name, ct.right);
1279 ret = TRUE;
1280done:
1281 return ret;
1282}
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866

Referenced by accumulate_inheritable_handles(), execute_command(), and symbol_demangle().

◆ handle_method()

static BOOL handle_method ( struct parsed_symbol sym,
BOOL  cast_op 
)
static

Definition at line 1289 of file undname.c.

1290{
1291 char accmem;
1292 const char* access = NULL;
1293 int access_id = -1;
1294 const char* member_type = NULL;
1295 struct datatype_t ct_ret;
1296 const char* call_conv;
1297 const char* function_qualifier = NULL;
1298 const char* exported;
1299 const char* args_str = NULL;
1300 const char* name = NULL;
1301 BOOL ret = FALSE, has_args = TRUE, has_ret = TRUE;
1302 unsigned mark;
1303
1304 /* FIXME: why 2 possible letters for each option?
1305 * 'A' private:
1306 * 'B' private:
1307 * 'C' private: static
1308 * 'D' private: static
1309 * 'E' private: virtual
1310 * 'F' private: virtual
1311 * 'G' private: thunk
1312 * 'H' private: thunk
1313 * 'I' protected:
1314 * 'J' protected:
1315 * 'K' protected: static
1316 * 'L' protected: static
1317 * 'M' protected: virtual
1318 * 'N' protected: virtual
1319 * 'O' protected: thunk
1320 * 'P' protected: thunk
1321 * 'Q' public:
1322 * 'R' public:
1323 * 'S' public: static
1324 * 'T' public: static
1325 * 'U' public: virtual
1326 * 'V' public: virtual
1327 * 'W' public: thunk
1328 * 'X' public: thunk
1329 * 'Y'
1330 * 'Z'
1331 * "$0" private: thunk vtordisp
1332 * "$1" private: thunk vtordisp
1333 * "$2" protected: thunk vtordisp
1334 * "$3" protected: thunk vtordisp
1335 * "$4" public: thunk vtordisp
1336 * "$5" public: thunk vtordisp
1337 * "$B" vcall thunk
1338 * "$R" thunk vtordispex
1339 */
1340 accmem = *sym->current++;
1341 if (accmem == '$')
1342 {
1343 if (*sym->current >= '0' && *sym->current <= '5')
1344 access_id = (*sym->current - '0') / 2;
1345 else if (*sym->current == 'R')
1346 access_id = (sym->current[1] - '0') / 2;
1347 else if (*sym->current != 'B')
1348 goto done;
1349 }
1350 else if (accmem >= 'A' && accmem <= 'Z')
1351 access_id = (accmem - 'A') / 8;
1352 else
1353 goto done;
1354
1355 switch (access_id)
1356 {
1357 case 0: access = "private: "; break;
1358 case 1: access = "protected: "; break;
1359 case 2: access = "public: "; break;
1360 }
1361 if (accmem == '$' || (accmem - 'A') % 8 == 6 || (accmem - 'A') % 8 == 7)
1362 access = str_printf(sym, "[thunk]:%s", access ? access : " ");
1363
1364 if (accmem == '$' && *sym->current != 'B')
1365 member_type = "virtual ";
1366 else if (accmem <= 'X')
1367 {
1368 switch ((accmem - 'A') % 8)
1369 {
1370 case 2: case 3: member_type = "static "; break;
1371 case 4: case 5: case 6: case 7: member_type = "virtual "; break;
1372 }
1373 }
1374
1376 access = NULL;
1377 if (sym->flags & UNDNAME_NO_MEMBER_TYPE)
1378 member_type = NULL;
1379
1380 name = get_class_string(sym, 0);
1381
1382 if (accmem == '$' && *sym->current == 'B') /* vcall thunk */
1383 {
1384 const char *n;
1385
1386 sym->current++;
1387 n = get_number(sym);
1388
1389 if(!n || *sym->current++ != 'A') goto done;
1390 name = str_printf(sym, "%s{%s,{flat}}' }'", name, n);
1391 has_args = FALSE;
1392 has_ret = FALSE;
1393 }
1394 else if (accmem == '$' && *sym->current == 'R') /* vtordispex thunk */
1395 {
1396 const char *n1, *n2, *n3, *n4;
1397
1398 sym->current += 2;
1399 n1 = get_number(sym);
1400 n2 = get_number(sym);
1401 n3 = get_number(sym);
1402 n4 = get_number(sym);
1403
1404 if(!n1 || !n2 || !n3 || !n4) goto done;
1405 name = str_printf(sym, "%s`vtordispex{%s,%s,%s,%s}' ", name, n1, n2, n3, n4);
1406 }
1407 else if (accmem == '$') /* vtordisp thunk */
1408 {
1409 const char *n1, *n2;
1410
1411 sym->current++;
1412 n1 = get_number(sym);
1413 n2 = get_number(sym);
1414
1415 if (!n1 || !n2) goto done;
1416 name = str_printf(sym, "%s`vtordisp{%s,%s}' ", name, n1, n2);
1417 }
1418 else if ((accmem - 'A') % 8 == 6 || (accmem - 'A') % 8 == 7) /* a thunk */
1419 name = str_printf(sym, "%s`adjustor{%s}' ", name, get_number(sym));
1420
1421 if (has_args && (accmem == '$' ||
1422 (accmem <= 'X' && (accmem - 'A') % 8 != 2 && (accmem - 'A') % 8 != 3)))
1423 {
1424 /* Implicit 'this' pointer */
1425 if (!get_function_qualifier(sym, &function_qualifier)) goto done;
1426 }
1427
1428 if (!get_calling_convention(*sym->current++, &call_conv, &exported,
1429 sym->flags))
1430 goto done;
1431
1432 /* Return type, or @ if 'void' */
1433 if (has_ret && *sym->current == '@')
1434 {
1435 ct_ret.left = "void";
1436 ct_ret.right = NULL;
1437 sym->current++;
1438 }
1439 else if (has_ret)
1440 {
1441 if (!demangle_datatype(sym, &ct_ret, cast_op ? WS_AFTER_QUAL_IF : 0))
1442 goto done;
1443 }
1444 if (!has_ret || sym->flags & UNDNAME_NO_FUNCTION_RETURNS)
1445 ct_ret.left = ct_ret.right = NULL;
1446 if (cast_op)
1447 {
1448 name = str_printf(sym, "%s %s%s", name, ct_ret.left, ct_ret.right);
1449 ct_ret.left = ct_ret.right = NULL;
1450 }
1451
1452 mark = sym->stack.num;
1453 if (has_args && !(args_str = get_args(sym, TRUE, '(', ')'))) goto done;
1454 if (sym->flags & UNDNAME_NAME_ONLY) args_str = function_qualifier = NULL;
1455 if (sym->flags & UNDNAME_NO_THISTYPE) function_qualifier = NULL;
1456 sym->stack.num = mark;
1457
1458 /* Note: '()' after 'Z' means 'throws', but we don't care here
1459 * Yet!!! FIXME
1460 */
1461 sym->result = str_printf(sym, "%s%s%s%s%s%s%s%s%s%s%s",
1462 access, member_type, ct_ret.left,
1463 (ct_ret.left && !ct_ret.right) ? " " : NULL,
1464 call_conv, call_conv ? " " : NULL, exported,
1465 name, args_str, function_qualifier, ct_ret.right);
1466 ret = TRUE;
1467done:
1468 return ret;
1469}
#define UNDNAME_NO_THISTYPE
Definition: dbghelp.h:1259
GLdouble n
Definition: glext.h:7729
int n4
Definition: dwarfget.c:147
int n2
Definition: dwarfget.c:147
int n3
Definition: dwarfget.c:147

Referenced by symbol_demangle().

◆ str_array_get_ref()

static char * str_array_get_ref ( struct array cref,
unsigned  idx 
)
static

Definition at line 222 of file undname.c.

223{
224 assert(cref);
225 if (cref->start + idx >= cref->max)
226 {
227 WARN("Out of bounds: %p %d + %d >= %d\n",
228 cref, cref->start, idx, cref->max);
229 return NULL;
230 }
231 TRACE("Returning %p[%d] => %s\n",
232 cref, idx, debugstr_a(cref->elts[cref->start + idx]));
233 return cref->elts[cref->start + idx];
234}
#define WARN(fmt,...)
Definition: precomp.h:61
unsigned int idx
Definition: utils.c:41
char ** elts
Definition: undname.c:59
unsigned start
Definition: undname.c:55
unsigned max
Definition: undname.c:57

Referenced by demangle_datatype(), get_class(), and get_literal_string().

◆ str_array_init()

static void str_array_init ( struct array a)
static

Definition at line 163 of file undname.c.

164{
165 a->start = a->num = a->max = a->alloc = 0;
166 a->elts = NULL;
167}

Referenced by __unDNameEx(), get_args(), get_class(), get_template_name(), handle_data(), handle_method(), and symbol_demangle().

◆ str_array_push()

static BOOL str_array_push ( struct parsed_symbol sym,
const char ptr,
int  len,
struct array a 
)
static

Definition at line 173 of file undname.c.

175{
176 char** new;
177
178 assert(ptr);
179 assert(a);
180
181 if (!a->alloc)
182 {
183 new = und_alloc(sym, (a->alloc = 32) * sizeof(a->elts[0]));
184 if (!new) return FALSE;
185 a->elts = new;
186 }
187 else if (a->max >= a->alloc)
188 {
189 new = und_alloc(sym, (a->alloc * 2) * sizeof(a->elts[0]));
190 if (!new) return FALSE;
191 memcpy(new, a->elts, a->alloc * sizeof(a->elts[0]));
192 a->alloc *= 2;
193 a->elts = new;
194 }
195 if (len == -1) len = strlen(ptr);
196 a->elts[a->num] = und_alloc(sym, len + 1);
197 assert(a->elts[a->num]);
198 memcpy(a->elts[a->num], ptr, len);
199 a->elts[a->num][len] = '\0';
200 if (++a->num >= a->max) a->max = a->num;
201 {
202 int i;
203 char c;
204
205 for (i = a->max - 1; i >= 0; i--)
206 {
207 c = '>';
208 if (i < a->start) c = '-';
209 else if (i >= a->num) c = '}';
210 TRACE("%p\t%d%c %s\n", a, i, c, debugstr_a(a->elts[i]));
211 }
212 }
213
214 return TRUE;
215}
#define c
Definition: ke_i.h:80

Referenced by demangle_datatype(), get_args(), get_class(), get_literal_string(), and symbol_demangle().

◆ str_printf()

static char *WINAPIV str_printf ( struct parsed_symbol sym,
const char format,
  ... 
)
static

Definition at line 241 of file undname.c.

242{
244 unsigned int len = 1, i, sz;
245 char* tmp;
246 char* p;
247 char* t;
248
250 for (i = 0; format[i]; i++)
251 {
252 if (format[i] == '%')
253 {
254 switch (format[++i])
255 {
256 case 's': t = va_arg(args, char*); if (t) len += strlen(t); break;
257 case 'c': (void)va_arg(args, int); len++; break;
258 default: i--; /* fall through */
259 case '%': len++; break;
260 }
261 }
262 else len++;
263 }
264 va_end(args);
265 if (!(tmp = und_alloc(sym, len))) return NULL;
267 for (p = tmp, i = 0; format[i]; i++)
268 {
269 if (format[i] == '%')
270 {
271 switch (format[++i])
272 {
273 case 's':
274 t = va_arg(args, char*);
275 if (t)
276 {
277 sz = strlen(t);
278 memcpy(p, t, sz);
279 p += sz;
280 }
281 break;
282 case 'c':
283 *p++ = (char)va_arg(args, int);
284 break;
285 default: i--; /* fall through */
286 case '%': *p++ = '%'; break;
287 }
288 }
289 else *p++ = format[i];
290 }
291 va_end(args);
292 *p = '\0';
293 return tmp;
294}
#define va_end(v)
Definition: stdarg.h:28
#define va_arg(v, l)
Definition: stdarg.h:27
#define va_start(v, l)
Definition: stdarg.h:26
char * va_list
Definition: vadefs.h:50
unsigned char
Definition: typeof.h:29
GLdouble GLdouble t
Definition: gl.h:2047
Definition: format.c:58

Referenced by append_extended_qualifier(), demangle_datatype(), get_args(), get_class(), get_function_qualifier(), get_modified_type(), get_qualified_type(), get_qualifier(), get_template_name(), handle_data(), handle_method(), and symbol_demangle().

◆ symbol_demangle()

static BOOL symbol_demangle ( struct parsed_symbol sym)
static

Definition at line 1475 of file undname.c.

1476{
1477 BOOL ret = FALSE;
1478 enum {
1479 PP_NONE,
1480 PP_CONSTRUCTOR,
1481 PP_DESTRUCTOR,
1482 PP_CAST_OPERATOR,
1483 } post_process = PP_NONE;
1484
1485 /* FIXME seems wrong as name, as it demangles a simple data type */
1486 if (sym->flags & UNDNAME_NO_ARGUMENTS)
1487 {
1488 struct datatype_t ct;
1489
1490 if (demangle_datatype(sym, &ct, 0))
1491 {
1492 sym->result = str_printf(sym, "%s%s", ct.left, ct.right);
1493 ret = TRUE;
1494 }
1495 goto done;
1496 }
1497
1498 /* MS mangled names always begin with '?' */
1499 if (*sym->current != '?') return FALSE;
1500 sym->current++;
1501
1502 /* Then function name or operator code */
1503 if (*sym->current == '?')
1504 {
1505 const char* function_name = NULL;
1506 BOOL in_template = FALSE;
1507
1508 if (sym->current[1] == '$' && sym->current[2] == '?')
1509 {
1510 in_template = TRUE;
1511 sym->current += 2;
1512 }
1513
1514 /* C++ operator code (one character, or two if the first is '_') */
1515 switch (*++sym->current)
1516 {
1517 case '0': function_name = ""; post_process = PP_CONSTRUCTOR; break;
1518 case '1': function_name = ""; post_process = PP_DESTRUCTOR; break;
1519 case '2': function_name = "operator new"; break;
1520 case '3': function_name = "operator delete"; break;
1521 case '4': function_name = "operator="; break;
1522 case '5': function_name = "operator>>"; break;
1523 case '6': function_name = "operator<<"; break;
1524 case '7': function_name = "operator!"; break;
1525 case '8': function_name = "operator=="; break;
1526 case '9': function_name = "operator!="; break;
1527 case 'A': function_name = "operator[]"; break;
1528 case 'B': function_name = "operator"; post_process = PP_CAST_OPERATOR; break;
1529 case 'C': function_name = "operator->"; break;
1530 case 'D': function_name = "operator*"; break;
1531 case 'E': function_name = "operator++"; break;
1532 case 'F': function_name = "operator--"; break;
1533 case 'G': function_name = "operator-"; break;
1534 case 'H': function_name = "operator+"; break;
1535 case 'I': function_name = "operator&"; break;
1536 case 'J': function_name = "operator->*"; break;
1537 case 'K': function_name = "operator/"; break;
1538 case 'L': function_name = "operator%"; break;
1539 case 'M': function_name = "operator<"; break;
1540 case 'N': function_name = "operator<="; break;
1541 case 'O': function_name = "operator>"; break;
1542 case 'P': function_name = "operator>="; break;
1543 case 'Q': function_name = "operator,"; break;
1544 case 'R': function_name = "operator()"; break;
1545 case 'S': function_name = "operator~"; break;
1546 case 'T': function_name = "operator^"; break;
1547 case 'U': function_name = "operator|"; break;
1548 case 'V': function_name = "operator&&"; break;
1549 case 'W': function_name = "operator||"; break;
1550 case 'X': function_name = "operator*="; break;
1551 case 'Y': function_name = "operator+="; break;
1552 case 'Z': function_name = "operator-="; break;
1553 case '_':
1554 switch (*++sym->current)
1555 {
1556 case '0': function_name = "operator/="; break;
1557 case '1': function_name = "operator%="; break;
1558 case '2': function_name = "operator>>="; break;
1559 case '3': function_name = "operator<<="; break;
1560 case '4': function_name = "operator&="; break;
1561 case '5': function_name = "operator|="; break;
1562 case '6': function_name = "operator^="; break;
1563 case '7': function_name = "`vftable'"; break;
1564 case '8': function_name = "`vbtable'"; break;
1565 case '9': function_name = "`vcall'"; break;
1566 case 'A': function_name = "`typeof'"; break;
1567 case 'B': function_name = "`local static guard'"; break;
1568 case 'C': sym->result = (char*)"`string'"; /* string literal: followed by string encoding (native never undecode it) */
1569 /* FIXME: should unmangle the whole string for error reporting */
1570 if (*sym->current && sym->current[strlen(sym->current) - 1] == '@') ret = TRUE;
1571 goto done;
1572 case 'D': function_name = "`vbase destructor'"; break;
1573 case 'E': function_name = "`vector deleting destructor'"; break;
1574 case 'F': function_name = "`default constructor closure'"; break;
1575 case 'G': function_name = "`scalar deleting destructor'"; break;
1576 case 'H': function_name = "`vector constructor iterator'"; break;
1577 case 'I': function_name = "`vector destructor iterator'"; break;
1578 case 'J': function_name = "`vector vbase constructor iterator'"; break;
1579 case 'K': function_name = "`virtual displacement map'"; break;
1580 case 'L': function_name = "`eh vector constructor iterator'"; break;
1581 case 'M': function_name = "`eh vector destructor iterator'"; break;
1582 case 'N': function_name = "`eh vector vbase constructor iterator'"; break;
1583 case 'O': function_name = "`copy constructor closure'"; break;
1584 case 'R':
1586 switch (*++sym->current)
1587 {
1588 case '0':
1589 {
1590 struct datatype_t ct;
1591
1592 sym->current++;
1593 if (!demangle_datatype(sym, &ct, 0))
1594 goto done;
1595 function_name = str_printf(sym, "%s%s `RTTI Type Descriptor'",
1596 ct.left, ct.right);
1597 sym->current--;
1598 }
1599 break;
1600 case '1':
1601 {
1602 const char* n1, *n2, *n3, *n4;
1603 sym->current++;
1604 n1 = get_number(sym);
1605 n2 = get_number(sym);
1606 n3 = get_number(sym);
1607 n4 = get_number(sym);
1608 sym->current--;
1609 function_name = str_printf(sym, "`RTTI Base Class Descriptor at (%s,%s,%s,%s)'",
1610 n1, n2, n3, n4);
1611 }
1612 break;
1613 case '2': function_name = "`RTTI Base Class Array'"; break;
1614 case '3': function_name = "`RTTI Class Hierarchy Descriptor'"; break;
1615 case '4': function_name = "`RTTI Complete Object Locator'"; break;
1616 default:
1617 ERR("Unknown RTTI operator: _R%c\n", *sym->current);
1618 break;
1619 }
1620 break;
1621 case 'S': function_name = "`local vftable'"; break;
1622 case 'T': function_name = "`local vftable constructor closure'"; break;
1623 case 'U': function_name = "operator new[]"; break;
1624 case 'V': function_name = "operator delete[]"; break;
1625 case 'X': function_name = "`placement delete closure'"; break;
1626 case 'Y': function_name = "`placement delete[] closure'"; break;
1627 case '_':
1628 switch (*++sym->current)
1629 {
1630 case 'K':
1631 sym->current++;
1632 function_name = str_printf(sym, "operator \"\" %s", get_literal_string(sym));
1633 --sym->current;
1634 break;
1635 default:
1636 FIXME("Unknown operator: __%c\n", *sym->current);
1637 return FALSE;
1638 }
1639 break;
1640 default:
1641 ERR("Unknown operator: _%c\n", *sym->current);
1642 return FALSE;
1643 }
1644 break;
1645 case '$':
1646 sym->current++;
1647 if (!(function_name = get_template_name(sym))) goto done;
1648 --sym->current;
1649 break;
1650 default:
1651 /* FIXME: Other operators */
1652 ERR("Unknown operator: %c\n", *sym->current);
1653 return FALSE;
1654 }
1655 sym->current++;
1656 if (in_template)
1657 {
1658 unsigned args_mark = sym->args.num;
1659 const char *args;
1660
1661 args = get_args(sym, FALSE, '<', '>');
1663 sym->args.num = args_mark;
1664 sym->names.num = 0;
1665 }
1666 if (!str_array_push(sym, function_name, -1, &sym->stack))
1667 return FALSE;
1668 }
1669 else if (*sym->current == '$')
1670 {
1671 /* Strange construct, it's a name with a template argument list
1672 and that's all. */
1673 sym->current++;
1674 ret = (sym->result = get_template_name(sym)) != NULL;
1675 goto done;
1676 }
1677
1678 /* Either a class name, or '@' if the symbol is not a class member */
1679 switch (*sym->current)
1680 {
1681 case '@': sym->current++; break;
1682 case '$': break;
1683 default:
1684 /* Class the function is associated with, terminated by '@@' */
1685 if (!get_class(sym)) goto done;
1686 break;
1687 }
1688
1689 switch (post_process)
1690 {
1691 case PP_NONE: default: break;
1692 case PP_CONSTRUCTOR: case PP_DESTRUCTOR:
1693 /* it's time to set the member name for ctor & dtor */
1694 if (sym->stack.num <= 1) goto done;
1695 sym->stack.elts[0] = str_printf(sym, "%s%s%s", post_process == PP_DESTRUCTOR ? "~" : NULL,
1696 sym->stack.elts[1], sym->stack.elts[0]);
1697 /* ctors and dtors don't have return type */
1699 break;
1700 case PP_CAST_OPERATOR:
1701 sym->flags &= ~UNDNAME_NO_FUNCTION_RETURNS;
1702 break;
1703 }
1704
1705 /* Function/Data type and access level */
1706 if (*sym->current >= '0' && *sym->current <= '9')
1707 ret = handle_data(sym);
1708 else if ((*sym->current >= 'A' && *sym->current <= 'Z') || *sym->current == '$')
1709 ret = handle_method(sym, post_process == PP_CAST_OPERATOR);
1710 else ret = FALSE;
1711done:
1712 if (ret) assert(sym->result);
1713 else WARN("Failed at %s\n", debugstr_a(sym->current));
1714
1715 return ret;
1716}
#define UNDNAME_NO_ARGUMENTS
Definition: dbghelp.h:1266
static BOOL handle_method(struct parsed_symbol *sym, BOOL cast_op)
Definition: undname.c:1289
static BOOL handle_data(struct parsed_symbol *sym)
Definition: undname.c:1201
wchar_t const *const function_name

Referenced by __unDNameEx(), and get_class().

◆ und_alloc()

static void * und_alloc ( struct parsed_symbol sym,
unsigned int  len 
)
static

Definition at line 104 of file undname.c.

105{
106 void* ptr;
107
108#define BLOCK_SIZE 1024
109#define AVAIL_SIZE (1024 - sizeof(void*))
110
111 if (len > AVAIL_SIZE)
112 {
113 /* allocate a specific block */
114 ptr = sym->mem_alloc_ptr(sizeof(void*) + len);
115 if (!ptr) return NULL;
116 *(void**)ptr = sym->alloc_list;
117 sym->alloc_list = ptr;
118 sym->avail_in_first = 0;
119 ptr = (char*)sym->alloc_list + sizeof(void*);
120 }
121 else
122 {
123 if (len > sym->avail_in_first)
124 {
125 /* add a new block */
127 if (!ptr) return NULL;
128 *(void**)ptr = sym->alloc_list;
129 sym->alloc_list = ptr;
131 }
132 /* grab memory from head block */
133 ptr = (char*)sym->alloc_list + BLOCK_SIZE - sym->avail_in_first;
134 sym->avail_in_first -= len;
135 }
136 return ptr;
137#undef BLOCK_SIZE
138#undef AVAIL_SIZE
139}
#define AVAIL_SIZE
#define BLOCK_SIZE
malloc_func_t mem_alloc_ptr
Definition: undname.c:66
unsigned avail_in_first
Definition: undname.c:77
void * alloc_list
Definition: undname.c:76

Referenced by get_class_string(), get_number(), str_array_push(), and str_printf().

◆ und_free_all()

static void und_free_all ( struct parsed_symbol sym)
static

Definition at line 146 of file undname.c.

147{
148 void* next;
149
150 while (sym->alloc_list)
151 {
152 next = *(void**)sym->alloc_list;
153 if(sym->mem_free_ptr) sym->mem_free_ptr(sym->alloc_list);
154 sym->alloc_list = next;
155 }
156 sym->avail_in_first = 0;
157}
static unsigned __int64 next
Definition: rand_nt.c:6
free_func_t mem_free_ptr
Definition: undname.c:67

Referenced by __unDNameEx().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msvcrt  )