ReactOS 0.4.15-dev-5863-g1fe3ab7
undname.c File Reference
#include <precomp.h>
#include <assert.h>
#include <internal/wine/msvcrt.h>
#include <internal/wine/cppexcept.h>
Include dependency graph for undname.c:

Go to the source code of this file.

Classes

struct  array
 
struct  parsed_symbol
 
struct  datatype_t
 

Macros

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

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msvcrt)
 
static BOOL symbol_demangle (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 charstr_printf (struct parsed_symbol *sym, const char *format,...)
 
static BOOL demangle_datatype (struct parsed_symbol *sym, struct datatype_t *ct, struct array *pmt, BOOL in_args)
 
static const charget_number (struct parsed_symbol *sym)
 
static charget_args (struct parsed_symbol *sym, struct array *pmt_ref, BOOL z_term, char open_char, char close_char)
 
static BOOL get_modifier (struct parsed_symbol *sym, const char **ret, const char **ptr_modif)
 
static BOOL get_modified_type (struct datatype_t *ct, struct parsed_symbol *sym, struct array *pmt_ref, char modif, BOOL in_args)
 
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 charget_class_name (struct parsed_symbol *sym)
 
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 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

◆ __WINE_DEBUG_CHANNEL__

#define __WINE_DEBUG_CHANNEL__

Definition at line 22 of file undname.c.

◆ AVAIL_SIZE

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

◆ BLOCK_SIZE

#define BLOCK_SIZE   1024

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 1645 of file undname.c.

1648{
1649 return __unDNameEx(buffer, mangled, buflen, memget, memfree, NULL, flags);
1650}
#define NULL
Definition: types.h:112
GLuint buffer
Definition: glext.h:5915
GLbitfield flags
Definition: glext.h:7161
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:1598

Referenced by MSVCRT_type_info_name().

◆ __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 1598 of file undname.c.

1601{
1602 struct parsed_symbol sym;
1603 const char* result;
1604
1605 TRACE("(%p,%s,%d,%p,%p,%p,%x)\n",
1606 buffer, debugstr_a(mangled), buflen, memget, memfree, unknown, flags);
1607
1608 /* The flags details is not documented by MS. However, it looks exactly
1609 * like the UNDNAME_ manifest constants from imagehlp.h and dbghelp.h
1610 * So, we copied those (on top of the file)
1611 */
1612 memset(&sym, 0, sizeof(struct parsed_symbol));
1617
1618 sym.flags = flags;
1619 sym.mem_alloc_ptr = memget;
1620 sym.mem_free_ptr = memfree;
1621 sym.current = mangled;
1622 str_array_init( &sym.names );
1623 str_array_init( &sym.stack );
1624
1625 result = symbol_demangle(&sym) ? sym.result : mangled;
1626 if (buffer && buflen)
1627 {
1628 lstrcpynA( buffer, result, buflen);
1629 }
1630 else
1631 {
1632 buffer = memget(strlen(result) + 1);
1633 if (buffer) strcpy(buffer, result);
1634 }
1635
1636 und_free_all(&sym);
1637
1638 return buffer;
1639}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#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
GLuint64EXT * result
Definition: glext.h:11304
#define debugstr_a
Definition: kernel32.h:31
#define UNDNAME_NO_COMPLEX_TYPE
Definition: msvcrt.h:140
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
static void und_free_all(struct parsed_symbol *sym)
Definition: undname.c:138
static BOOL symbol_demangle(struct parsed_symbol *sym)
Definition: undname.c:1339
static void str_array_init(struct array *a)
Definition: undname.c:155

Referenced by __unDName().

◆ demangle_datatype()

static BOOL demangle_datatype ( struct parsed_symbol sym,
struct datatype_t ct,
struct array pmt,
BOOL  in_args 
)
static

Definition at line 789 of file undname.c.

791{
792 char dt;
793 BOOL add_pmt = TRUE;
794
795 assert(ct);
796 ct->left = ct->right = NULL;
797
798 switch (dt = *sym->current++)
799 {
800 case '_':
801 /* MS type: __int8,__int16 etc */
802 ct->left = get_extended_type(*sym->current++);
803 break;
804 case 'C': case 'D': case 'E': case 'F': case 'G':
805 case 'H': case 'I': case 'J': case 'K': case 'M':
806 case 'N': case 'O': case 'X': case 'Z':
807 /* Simple data types */
808 ct->left = get_simple_type(dt);
809 add_pmt = FALSE;
810 break;
811 case 'T': /* union */
812 case 'U': /* struct */
813 case 'V': /* class */
814 case 'Y': /* cointerface */
815 /* Class/struct/union/cointerface */
816 {
817 const char* struct_name = NULL;
818 const char* type_name = NULL;
819
820 if (!(struct_name = get_class_name(sym)))
821 goto done;
822 if (!(sym->flags & UNDNAME_NO_COMPLEX_TYPE))
823 {
824 switch (dt)
825 {
826 case 'T': type_name = "union "; break;
827 case 'U': type_name = "struct "; break;
828 case 'V': type_name = "class "; break;
829 case 'Y': type_name = "cointerface "; break;
830 }
831 }
832 ct->left = str_printf(sym, "%s%s", type_name, struct_name);
833 }
834 break;
835 case '?':
836 /* not all the time is seems */
837 if (in_args)
838 {
839 const char* ptr;
840 if (!(ptr = get_number(sym))) goto done;
841 ct->left = str_printf(sym, "`template-parameter-%s'", ptr);
842 }
843 else
844 {
845 if (!get_modified_type(ct, sym, pmt_ref, '?', in_args)) goto done;
846 }
847 break;
848 case 'A': /* reference */
849 case 'B': /* volatile reference */
850 if (!get_modified_type(ct, sym, pmt_ref, dt, in_args)) goto done;
851 break;
852 case 'Q': /* const pointer */
853 case 'R': /* volatile pointer */
854 case 'S': /* const volatile pointer */
855 if (!get_modified_type(ct, sym, pmt_ref, in_args ? dt : 'P', in_args)) goto done;
856 break;
857 case 'P': /* Pointer */
858 if (isdigit(*sym->current))
859 {
860 /* FIXME:
861 * P6 = Function pointer
862 * P8 = Member function pointer
863 * others who knows.. */
864 if (*sym->current == '8')
865 {
866 char* args = NULL;
867 const char* call_conv;
868 const char* exported;
869 struct datatype_t sub_ct;
870 unsigned mark = sym->stack.num;
871 const char* class;
872 const char* modifier;
873 const char* ptr_modif;
874
875 sym->current++;
876
877 if (!(class = get_class_name(sym)))
878 goto done;
879 if (!get_modifier(sym, &modifier, &ptr_modif))
880 goto done;
881 if (modifier)
882 modifier = str_printf(sym, "%s %s", modifier, ptr_modif);
883 else if(ptr_modif[0])
884 modifier = str_printf(sym, " %s", ptr_modif);
885 if (!get_calling_convention(*sym->current++,
886 &call_conv, &exported,
888 goto done;
889 if (!demangle_datatype(sym, &sub_ct, pmt_ref, FALSE))
890 goto done;
891
892 args = get_args(sym, pmt_ref, TRUE, '(', ')');
893 if (!args) goto done;
894 sym->stack.num = mark;
895
896 ct->left = str_printf(sym, "%s%s (%s %s::*",
897 sub_ct.left, sub_ct.right, call_conv, class);
898 ct->right = str_printf(sym, ")%s%s", args, modifier);
899 }
900 else if (*sym->current == '6')
901 {
902 char* args = NULL;
903 const char* call_conv;
904 const char* exported;
905 struct datatype_t sub_ct;
906 unsigned mark = sym->stack.num;
907
908 sym->current++;
909
910 if (!get_calling_convention(*sym->current++,
911 &call_conv, &exported,
913 !demangle_datatype(sym, &sub_ct, pmt_ref, FALSE))
914 goto done;
915
916 args = get_args(sym, pmt_ref, TRUE, '(', ')');
917 if (!args) goto done;
918 sym->stack.num = mark;
919
920 ct->left = str_printf(sym, "%s%s (%s*",
921 sub_ct.left, sub_ct.right, call_conv);
922 ct->right = str_printf(sym, ")%s", args);
923 }
924 else goto done;
925 }
926 else if (!get_modified_type(ct, sym, pmt_ref, 'P', in_args)) goto done;
927 break;
928 case 'W':
929 if (*sym->current == '4')
930 {
931 char* enum_name;
932 sym->current++;
933 if (!(enum_name = get_class_name(sym)))
934 goto done;
936 ct->left = enum_name;
937 else
938 ct->left = str_printf(sym, "enum %s", enum_name);
939 }
940 else goto done;
941 break;
942 case '0': case '1': case '2': case '3': case '4':
943 case '5': case '6': case '7': case '8': case '9':
944 /* Referring back to previously parsed type */
945 /* left and right are pushed as two separate strings */
946 if (!pmt_ref) goto done;
947 ct->left = str_array_get_ref(pmt_ref, (dt - '0') * 2);
948 ct->right = str_array_get_ref(pmt_ref, (dt - '0') * 2 + 1);
949 if (!ct->left) goto done;
950 add_pmt = FALSE;
951 break;
952 case '$':
953 switch (*sym->current++)
954 {
955 case '0':
956 if (!(ct->left = get_number(sym))) goto done;
957 break;
958 case 'D':
959 {
960 const char* ptr;
961 if (!(ptr = get_number(sym))) goto done;
962 ct->left = str_printf(sym, "`template-parameter%s'", ptr);
963 }
964 break;
965 case 'F':
966 {
967 const char* p1;
968 const char* p2;
969 if (!(p1 = get_number(sym))) goto done;
970 if (!(p2 = get_number(sym))) goto done;
971 ct->left = str_printf(sym, "{%s,%s}", p1, p2);
972 }
973 break;
974 case 'G':
975 {
976 const char* p1;
977 const char* p2;
978 const char* p3;
979 if (!(p1 = get_number(sym))) goto done;
980 if (!(p2 = get_number(sym))) goto done;
981 if (!(p3 = get_number(sym))) goto done;
982 ct->left = str_printf(sym, "{%s,%s,%s}", p1, p2, p3);
983 }
984 break;
985 case 'Q':
986 {
987 const char* ptr;
988 if (!(ptr = get_number(sym))) goto done;
989 ct->left = str_printf(sym, "`non-type-template-parameter%s'", ptr);
990 }
991 break;
992 case '$':
993 if (*sym->current == 'B')
994 {
995 unsigned mark = sym->stack.num;
996 struct datatype_t sub_ct;
997 const char* arr = NULL;
998 sym->current++;
999
1000 /* multidimensional arrays */
1001 if (*sym->current == 'Y')
1002 {
1003 const char* n1;
1004 int num;
1005
1006 sym->current++;
1007 if (!(n1 = get_number(sym))) goto done;
1008 num = atoi(n1);
1009
1010 while (num--)
1011 arr = str_printf(sym, "%s[%s]", arr, get_number(sym));
1012 }
1013
1014 if (!demangle_datatype(sym, &sub_ct, pmt_ref, FALSE)) goto done;
1015
1016 if (arr)
1017 ct->left = str_printf(sym, "%s %s", sub_ct.left, arr);
1018 else
1019 ct->left = sub_ct.left;
1020 ct->right = sub_ct.right;
1021 sym->stack.num = mark;
1022 }
1023 else if (*sym->current == 'C')
1024 {
1025 const char *ptr, *ptr_modif;
1026
1027 sym->current++;
1028 if (!get_modifier(sym, &ptr, &ptr_modif)) goto done;
1029 if (!demangle_datatype(sym, ct, pmt_ref, in_args)) goto done;
1030 ct->left = str_printf(sym, "%s %s", ct->left, ptr);
1031 }
1032 break;
1033 }
1034 break;
1035 default :
1036 ERR("Unknown type %c\n", dt);
1037 break;
1038 }
1039 if (add_pmt && pmt_ref && in_args)
1040 {
1041 /* left and right are pushed as two separate strings */
1042 if (!str_array_push(sym, ct->left ? ct->left : "", -1, pmt_ref) ||
1043 !str_array_push(sym, ct->right ? ct->right : "", -1, pmt_ref))
1044 return FALSE;
1045 }
1046done:
1047
1048 return ct->left != NULL;
1049}
#define isdigit(c)
Definition: acclib.h:68
#define ERR(fmt,...)
Definition: debug.h:110
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint num
Definition: glext.h:9618
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
static PVOID ptr
Definition: dispmode.c:27
int n1
Definition: dwarfget.c:148
Definition: match.c:390
const char * right
Definition: undname.c:84
const char * left
Definition: undname.c:83
unsigned flags
Definition: undname.c:66
struct array stack
Definition: undname.c:74
const char * current
Definition: undname.c:70
static BOOL demangle_datatype(struct parsed_symbol *sym, struct datatype_t *ct, struct array *pmt, BOOL in_args)
Definition: undname.c:789
static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol *sym, struct array *pmt_ref, char modif, BOOL in_args)
Definition: undname.c:426
static const char * get_number(struct parsed_symbol *sym)
Definition: undname.c:293
static char * str_printf(struct parsed_symbol *sym, const char *format,...)
Definition: undname.c:234
static BOOL get_modifier(struct parsed_symbol *sym, const char **ret, const char **ptr_modif)
Definition: undname.c:402
static char * get_args(struct parsed_symbol *sym, struct array *pmt_ref, BOOL z_term, char open_char, char close_char)
Definition: undname.c:344
static BOOL get_calling_convention(char ch, const char **call_conv, const char **exported, unsigned flags)
Definition: undname.c:685
static BOOL str_array_push(struct parsed_symbol *sym, const char *ptr, int len, struct array *a)
Definition: undname.c:165
static const char * get_extended_type(char c)
Definition: undname.c:759
static char * str_array_get_ref(struct array *cref, unsigned idx)
Definition: undname.c:215
static const char * get_simple_type(char c)
Definition: undname.c:730
static char * get_class_name(struct parsed_symbol *sym)
Definition: undname.c:669

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

◆ get_args()

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

Definition at line 344 of file undname.c.

347{
348 struct datatype_t ct;
349 struct array arg_collect;
350 char* args_str = NULL;
351 char* last;
352 unsigned int i;
353
354 str_array_init(&arg_collect);
355
356 /* Now come the function arguments */
357 while (*sym->current)
358 {
359 /* Decode each data type and append it to the argument list */
360 if (*sym->current == '@')
361 {
362 sym->current++;
363 break;
364 }
365 if (!demangle_datatype(sym, &ct, pmt_ref, TRUE))
366 return NULL;
367 /* 'void' terminates an argument list in a function */
368 if (z_term && !strcmp(ct.left, "void")) break;
369 if (!str_array_push(sym, str_printf(sym, "%s%s", ct.left, ct.right), -1,
370 &arg_collect))
371 return NULL;
372 if (!strcmp(ct.left, "...")) break;
373 }
374 /* Functions are always terminated by 'Z'. If we made it this far and
375 * don't find it, we have incorrectly identified a data type.
376 */
377 if (z_term && *sym->current++ != 'Z') return NULL;
378
379 if (arg_collect.num == 0 ||
380 (arg_collect.num == 1 && !strcmp(arg_collect.elts[0], "void")))
381 return str_printf(sym, "%cvoid%c", open_char, close_char);
382 for (i = 1; i < arg_collect.num; i++)
383 {
384 args_str = str_printf(sym, "%s,%s", args_str, arg_collect.elts[i]);
385 }
386
387 last = args_str ? args_str : arg_collect.elts[0];
388 if (close_char == '>' && last[strlen(last) - 1] == '>')
389 args_str = str_printf(sym, "%c%s%s %c",
390 open_char, arg_collect.elts[0], args_str, close_char);
391 else
392 args_str = str_printf(sym, "%c%s%s%c",
393 open_char, arg_collect.elts[0], args_str, close_char);
394
395 return args_str;
396}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
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
POINT last
Definition: font.c:46
static char close_char
Definition: i386-dis.c:2055
static char open_char
Definition: i386-dis.c:2054

Referenced by demangle_datatype(), 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 685 of file undname.c.

687{
688 *call_conv = *exported = NULL;
689
691 {
693 {
694 if (((ch - 'A') % 2) == 1) *exported = "dll_export ";
695 switch (ch)
696 {
697 case 'A': case 'B': *call_conv = "cdecl"; break;
698 case 'C': case 'D': *call_conv = "pascal"; break;
699 case 'E': case 'F': *call_conv = "thiscall"; break;
700 case 'G': case 'H': *call_conv = "stdcall"; break;
701 case 'I': case 'J': *call_conv = "fastcall"; break;
702 case 'K': case 'L': break;
703 case 'M': *call_conv = "clrcall"; break;
704 default: ERR("Unknown calling convention %c\n", ch); return FALSE;
705 }
706 }
707 else
708 {
709 if (((ch - 'A') % 2) == 1) *exported = "__dll_export ";
710 switch (ch)
711 {
712 case 'A': case 'B': *call_conv = "__cdecl"; break;
713 case 'C': case 'D': *call_conv = "__pascal"; break;
714 case 'E': case 'F': *call_conv = "__thiscall"; break;
715 case 'G': case 'H': *call_conv = "__stdcall"; break;
716 case 'I': case 'J': *call_conv = "__fastcall"; break;
717 case 'K': case 'L': break;
718 case 'M': *call_conv = "__clrcall"; break;
719 default: ERR("Unknown calling convention %c\n", ch); return FALSE;
720 }
721 }
722 }
723 return TRUE;
724}
#define UNDNAME_NO_MS_KEYWORDS
Definition: dbghelp.h:1253
#define UNDNAME_NO_LEADING_UNDERSCORES
Definition: dbghelp.h:1252

Referenced by demangle_datatype(), and handle_method().

◆ get_class()

static BOOL get_class ( struct parsed_symbol sym)
static

Definition at line 578 of file undname.c.

579{
580 const char* name = NULL;
581
582 while (*sym->current != '@')
583 {
584 switch (*sym->current)
585 {
586 case '\0': return FALSE;
587
588 case '0': case '1': case '2': case '3':
589 case '4': case '5': case '6': case '7':
590 case '8': case '9':
591 name = str_array_get_ref(&sym->names, *sym->current++ - '0');
592 break;
593 case '?':
594 switch (*++sym->current)
595 {
596 case '$':
597 sym->current++;
598 if ((name = get_template_name(sym)) &&
599 !str_array_push(sym, name, -1, &sym->names))
600 return FALSE;
601 break;
602 case '?':
603 {
604 struct array stack = sym->stack;
605 unsigned int start = sym->names.start;
606 unsigned int num = sym->names.num;
607
608 str_array_init( &sym->stack );
609 if (symbol_demangle( sym )) name = str_printf( sym, "`%s'", sym->result );
610 sym->names.start = start;
611 sym->names.num = num;
612 sym->stack = stack;
613 }
614 break;
615 default:
616 if (!(name = get_number( sym ))) return FALSE;
617 name = str_printf( sym, "`%s'", name );
618 break;
619 }
620 break;
621 default:
623 break;
624 }
625 if (!name || !str_array_push(sym, name, -1, &sym->stack))
626 return FALSE;
627 }
628 sym->current++;
629 return TRUE;
630}
Definition: _stack.h:55
GLuint start
Definition: gl.h:1545
Definition: name.c:39
char * result
Definition: undname.c:71
struct array names
Definition: undname.c:73
static char * get_literal_string(struct parsed_symbol *sym)
Definition: undname.c:512
static char * get_template_name(struct parsed_symbol *sym)
Definition: undname.c:542

Referenced by get_class_name(), and symbol_demangle().

◆ get_class_name()

static char * get_class_name ( struct parsed_symbol sym)
static

Definition at line 669 of file undname.c.

670{
671 unsigned mark = sym->stack.num;
672 char* s = NULL;
673
674 if (get_class(sym))
675 s = get_class_string(sym, mark);
676 sym->stack.num = mark;
677 return s;
678}
GLdouble s
Definition: gl.h:2039
static BOOL get_class(struct parsed_symbol *sym)
Definition: undname.c:578
static char * get_class_string(struct parsed_symbol *sym, int start)
Definition: undname.c:637

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 637 of file undname.c.

638{
639 int i;
640 unsigned int len, sz;
641 char* ret;
642 struct array *a = &sym->stack;
643
644 for (len = 0, i = start; i < a->num; i++)
645 {
646 assert(a->elts[i]);
647 len += 2 + strlen(a->elts[i]);
648 }
649 if (!(ret = und_alloc(sym, len - 1))) return NULL;
650 for (len = 0, i = a->num - 1; i >= start; i--)
651 {
652 sz = strlen(a->elts[i]);
653 memcpy(ret + len, a->elts[i], sz);
654 len += sz;
655 if (i > start)
656 {
657 ret[len++] = ':';
658 ret[len++] = ':';
659 }
660 }
661 ret[len] = '\0';
662 return ret;
663}
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
static void * und_alloc(struct parsed_symbol *sym, unsigned int len)
Definition: undname.c:96
int ret

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

◆ get_extended_type()

static const char * get_extended_type ( char  c)
static

Definition at line 759 of file undname.c.

760{
761 const char* type_string;
762
763 switch (c)
764 {
765 case 'D': type_string = "__int8"; break;
766 case 'E': type_string = "unsigned __int8"; break;
767 case 'F': type_string = "__int16"; break;
768 case 'G': type_string = "unsigned __int16"; break;
769 case 'H': type_string = "__int32"; break;
770 case 'I': type_string = "unsigned __int32"; break;
771 case 'J': type_string = "__int64"; break;
772 case 'K': type_string = "unsigned __int64"; break;
773 case 'L': type_string = "__int128"; break;
774 case 'M': type_string = "unsigned __int128"; break;
775 case 'N': type_string = "bool"; break;
776 case 'W': type_string = "wchar_t"; break;
777 default: type_string = NULL; break;
778 }
779 return type_string;
780}
const GLubyte * c
Definition: glext.h:8905

Referenced by demangle_datatype().

◆ get_literal_string()

static char * get_literal_string ( struct parsed_symbol sym)
static

Definition at line 512 of file undname.c.

513{
514 const char *ptr = sym->current;
515
516 do {
517 if (!((*sym->current >= 'A' && *sym->current <= 'Z') ||
518 (*sym->current >= 'a' && *sym->current <= 'z') ||
519 (*sym->current >= '0' && *sym->current <= '9') ||
520 *sym->current == '_' || *sym->current == '$')) {
521 TRACE("Failed at '%c' in %s\n", *sym->current, debugstr_a(ptr));
522 return NULL;
523 }
524 } while (*++sym->current != '@');
525 sym->current++;
526 if (!str_array_push(sym, ptr, sym->current - 1 - ptr, &sym->names))
527 return NULL;
528
529 return str_array_get_ref(&sym->names, sym->names.num - sym->names.start - 1);
530}

Referenced by get_class(), and get_template_name().

◆ get_modified_type()

static BOOL get_modified_type ( struct datatype_t ct,
struct parsed_symbol sym,
struct array pmt_ref,
char  modif,
BOOL  in_args 
)
static

Definition at line 426 of file undname.c.

428{
429 const char* modifier;
430 const char* str_modif;
431 const char *ptr_modif = "";
432
433 if (*sym->current == 'E')
434 {
435 if (!(sym->flags & UNDNAME_NO_MS_KEYWORDS))
436 {
438 ptr_modif = " ptr64";
439 else
440 ptr_modif = " __ptr64";
441 }
442 sym->current++;
443 }
444
445 switch (modif)
446 {
447 case 'A': str_modif = str_printf(sym, " &%s", ptr_modif); break;
448 case 'B': str_modif = str_printf(sym, " &%s volatile", ptr_modif); break;
449 case 'P': str_modif = str_printf(sym, " *%s", ptr_modif); break;
450 case 'Q': str_modif = str_printf(sym, " *%s const", ptr_modif); break;
451 case 'R': str_modif = str_printf(sym, " *%s volatile", ptr_modif); break;
452 case 'S': str_modif = str_printf(sym, " *%s const volatile", ptr_modif); break;
453 case '?': str_modif = ""; break;
454 default: return FALSE;
455 }
456
457 if (get_modifier(sym, &modifier, &ptr_modif))
458 {
459 unsigned mark = sym->stack.num;
460 struct datatype_t sub_ct;
461
462 /* multidimensional arrays */
463 if (*sym->current == 'Y')
464 {
465 const char* n1;
466 int num;
467
468 sym->current++;
469 if (!(n1 = get_number(sym))) return FALSE;
470 num = atoi(n1);
471
472 if (str_modif[0] == ' ' && !modifier)
473 str_modif++;
474
475 if (modifier)
476 {
477 str_modif = str_printf(sym, " (%s%s)", modifier, str_modif);
478 modifier = NULL;
479 }
480 else
481 str_modif = str_printf(sym, " (%s)", str_modif);
482
483 while (num--)
484 str_modif = str_printf(sym, "%s[%s]", str_modif, get_number(sym));
485 }
486
487 /* Recurse to get the referred-to type */
488 if (!demangle_datatype(sym, &sub_ct, pmt_ref, FALSE))
489 return FALSE;
490 if (modifier)
491 ct->left = str_printf(sym, "%s %s%s", sub_ct.left, modifier, str_modif );
492 else
493 {
494 /* don't insert a space between duplicate '*' */
495 if (!in_args && str_modif[0] && str_modif[1] == '*' && sub_ct.left[strlen(sub_ct.left)-1] == '*')
496 str_modif++;
497 ct->left = str_printf(sym, "%s%s", sub_ct.left, str_modif );
498 }
499 ct->right = sub_ct.right;
500 sym->stack.num = mark;
501 }
502 return TRUE;
503}

Referenced by demangle_datatype().

◆ get_modifier()

static BOOL get_modifier ( struct parsed_symbol sym,
const char **  ret,
const char **  ptr_modif 
)
static

Definition at line 402 of file undname.c.

403{
404 *ptr_modif = NULL;
405 if (*sym->current == 'E')
406 {
407 if (!(sym->flags & UNDNAME_NO_MS_KEYWORDS))
408 {
409 *ptr_modif = "__ptr64";
411 *ptr_modif = *ptr_modif + 2;
412 }
413 sym->current++;
414 }
415 switch (*sym->current++)
416 {
417 case 'A': *ret = NULL; break;
418 case 'B': *ret = "const"; break;
419 case 'C': *ret = "volatile"; break;
420 case 'D': *ret = "const volatile"; break;
421 default: return FALSE;
422 }
423 return TRUE;
424}

Referenced by demangle_datatype(), get_modified_type(), handle_data(), and handle_method().

◆ get_number()

static const char * get_number ( struct parsed_symbol sym)
static

Definition at line 293 of file undname.c.

294{
295 char* ptr;
296 BOOL sgn = FALSE;
297
298 if (*sym->current == '?')
299 {
300 sgn = TRUE;
301 sym->current++;
302 }
303 if (*sym->current >= '0' && *sym->current <= '8')
304 {
305 ptr = und_alloc(sym, 3);
306 if (sgn) ptr[0] = '-';
307 ptr[sgn ? 1 : 0] = *sym->current + 1;
308 ptr[sgn ? 2 : 1] = '\0';
309 sym->current++;
310 }
311 else if (*sym->current == '9')
312 {
313 ptr = und_alloc(sym, 4);
314 if (sgn) ptr[0] = '-';
315 ptr[sgn ? 1 : 0] = '1';
316 ptr[sgn ? 2 : 1] = '0';
317 ptr[sgn ? 3 : 2] = '\0';
318 sym->current++;
319 }
320 else if (*sym->current >= 'A' && *sym->current <= 'P')
321 {
322 int ret = 0;
323
324 while (*sym->current >= 'A' && *sym->current <= 'P')
325 {
326 ret *= 16;
327 ret += *sym->current++ - 'A';
328 }
329 if (*sym->current != '@') return NULL;
330
331 ptr = und_alloc(sym, 17);
332 sprintf(ptr, "%s%u", sgn ? "-" : "", ret);
333 sym->current++;
334 }
335 else return NULL;
336 return ptr;
337}
#define sprintf(buf, format,...)
Definition: sprintf.c:55
long sgn(REAL x)
Definition: varray.cc:48

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

◆ get_simple_type()

static const char * get_simple_type ( char  c)
static

Definition at line 730 of file undname.c.

731{
732 const char* type_string;
733
734 switch (c)
735 {
736 case 'C': type_string = "signed char"; break;
737 case 'D': type_string = "char"; break;
738 case 'E': type_string = "unsigned char"; break;
739 case 'F': type_string = "short"; break;
740 case 'G': type_string = "unsigned short"; break;
741 case 'H': type_string = "int"; break;
742 case 'I': type_string = "unsigned int"; break;
743 case 'J': type_string = "long"; break;
744 case 'K': type_string = "unsigned long"; break;
745 case 'M': type_string = "float"; break;
746 case 'N': type_string = "double"; break;
747 case 'O': type_string = "long double"; break;
748 case 'X': type_string = "void"; break;
749 case 'Z': type_string = "..."; break;
750 default: type_string = NULL; break;
751 }
752 return type_string;
753}

Referenced by demangle_datatype().

◆ get_template_name()

static char * get_template_name ( struct parsed_symbol sym)
static

Definition at line 542 of file undname.c.

543{
544 char *name, *args;
545 unsigned num_mark = sym->names.num;
546 unsigned start_mark = sym->names.start;
547 unsigned stack_mark = sym->stack.num;
548 struct array array_pmt;
549
550 sym->names.start = sym->names.num;
551 if (!(name = get_literal_string(sym))) {
552 sym->names.start = start_mark;
553 return FALSE;
554 }
555 str_array_init(&array_pmt);
556 args = get_args(sym, &array_pmt, FALSE, '<', '>');
557 if (args != NULL)
558 name = str_printf(sym, "%s%s", name, args);
559 sym->names.num = num_mark;
560 sym->names.start = start_mark;
561 sym->stack.num = stack_mark;
562 return name;
563}
#define args
Definition: format.c:66

Referenced by get_class(), and symbol_demangle().

◆ handle_data()

static BOOL handle_data ( struct parsed_symbol sym)
static

Definition at line 1056 of file undname.c.

1057{
1058 const char* access = NULL;
1059 const char* member_type = NULL;
1060 const char* modifier = NULL;
1061 const char* ptr_modif;
1062 struct datatype_t ct;
1063 char* name = NULL;
1064 BOOL ret = FALSE;
1065
1066 /* 0 private static
1067 * 1 protected static
1068 * 2 public static
1069 * 3 private non-static
1070 * 4 protected non-static
1071 * 5 public non-static
1072 * 6 ?? static
1073 * 7 ?? static
1074 */
1075
1076 if (!(sym->flags & UNDNAME_NO_ACCESS_SPECIFIERS))
1077 {
1078 /* we only print the access for static members */
1079 switch (*sym->current)
1080 {
1081 case '0': access = "private: "; break;
1082 case '1': access = "protected: "; break;
1083 case '2': access = "public: "; break;
1084 }
1085 }
1086
1087 if (!(sym->flags & UNDNAME_NO_MEMBER_TYPE))
1088 {
1089 if (*sym->current >= '0' && *sym->current <= '2')
1090 member_type = "static ";
1091 }
1092
1093 name = get_class_string(sym, 0);
1094
1095 switch (*sym->current++)
1096 {
1097 case '0': case '1': case '2':
1098 case '3': case '4': case '5':
1099 {
1100 unsigned mark = sym->stack.num;
1101 struct array pmt;
1102
1103 str_array_init(&pmt);
1104
1105 if (!demangle_datatype(sym, &ct, &pmt, FALSE)) goto done;
1106 if (!get_modifier(sym, &modifier, &ptr_modif)) goto done;
1107 if (modifier && ptr_modif) modifier = str_printf(sym, "%s %s", modifier, ptr_modif);
1108 else if (!modifier) modifier = ptr_modif;
1109 sym->stack.num = mark;
1110 }
1111 break;
1112 case '6' : /* compiler generated static */
1113 case '7' : /* compiler generated static */
1114 ct.left = ct.right = NULL;
1115 if (!get_modifier(sym, &modifier, &ptr_modif)) goto done;
1116 if (*sym->current != '@')
1117 {
1118 char* cls = NULL;
1119
1120 if (!(cls = get_class_name(sym)))
1121 goto done;
1122 ct.right = str_printf(sym, "{for `%s'}", cls);
1123 }
1124 break;
1125 case '8':
1126 case '9':
1127 modifier = ct.left = ct.right = NULL;
1128 break;
1129 default: goto done;
1130 }
1131 if (sym->flags & UNDNAME_NAME_ONLY) ct.left = ct.right = modifier = NULL;
1132
1133 sym->result = str_printf(sym, "%s%s%s%s%s%s%s%s", access,
1134 member_type, ct.left,
1135 modifier && ct.left ? " " : NULL, modifier,
1136 modifier || ct.left ? " " : NULL, name, ct.right);
1137 ret = TRUE;
1138done:
1139 return ret;
1140}
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866

Referenced by symbol_demangle().

◆ handle_method()

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

Definition at line 1147 of file undname.c.

1148{
1149 char accmem;
1150 const char* access = NULL;
1151 int access_id = -1;
1152 const char* member_type = NULL;
1153 struct datatype_t ct_ret;
1154 const char* call_conv;
1155 const char* modifier = NULL;
1156 const char* exported;
1157 const char* args_str = NULL;
1158 const char* name = NULL;
1159 BOOL ret = FALSE, has_args = TRUE, has_ret = TRUE;
1160 unsigned mark;
1161 struct array array_pmt;
1162
1163 /* FIXME: why 2 possible letters for each option?
1164 * 'A' private:
1165 * 'B' private:
1166 * 'C' private: static
1167 * 'D' private: static
1168 * 'E' private: virtual
1169 * 'F' private: virtual
1170 * 'G' private: thunk
1171 * 'H' private: thunk
1172 * 'I' protected:
1173 * 'J' protected:
1174 * 'K' protected: static
1175 * 'L' protected: static
1176 * 'M' protected: virtual
1177 * 'N' protected: virtual
1178 * 'O' protected: thunk
1179 * 'P' protected: thunk
1180 * 'Q' public:
1181 * 'R' public:
1182 * 'S' public: static
1183 * 'T' public: static
1184 * 'U' public: virtual
1185 * 'V' public: virtual
1186 * 'W' public: thunk
1187 * 'X' public: thunk
1188 * 'Y'
1189 * 'Z'
1190 * "$0" private: thunk vtordisp
1191 * "$1" private: thunk vtordisp
1192 * "$2" protected: thunk vtordisp
1193 * "$3" protected: thunk vtordisp
1194 * "$4" public: thunk vtordisp
1195 * "$5" public: thunk vtordisp
1196 * "$B" vcall thunk
1197 * "$R" thunk vtordispex
1198 */
1199 accmem = *sym->current++;
1200 if (accmem == '$')
1201 {
1202 if (*sym->current >= '0' && *sym->current <= '5')
1203 access_id = (*sym->current - '0') / 2;
1204 else if (*sym->current == 'R')
1205 access_id = (sym->current[1] - '0') / 2;
1206 else if (*sym->current != 'B')
1207 goto done;
1208 }
1209 else if (accmem >= 'A' && accmem <= 'Z')
1210 access_id = (accmem - 'A') / 8;
1211 else
1212 goto done;
1213
1214 switch (access_id)
1215 {
1216 case 0: access = "private: "; break;
1217 case 1: access = "protected: "; break;
1218 case 2: access = "public: "; break;
1219 }
1220 if (accmem == '$' || (accmem - 'A') % 8 == 6 || (accmem - 'A') % 8 == 7)
1221 access = str_printf(sym, "[thunk]:%s", access ? access : " ");
1222
1223 if (accmem == '$' && *sym->current != 'B')
1224 member_type = "virtual ";
1225 else if (accmem <= 'X')
1226 {
1227 switch ((accmem - 'A') % 8)
1228 {
1229 case 2: case 3: member_type = "static "; break;
1230 case 4: case 5: case 6: case 7: member_type = "virtual "; break;
1231 }
1232 }
1233
1235 access = NULL;
1236 if (sym->flags & UNDNAME_NO_MEMBER_TYPE)
1237 member_type = NULL;
1238
1239 name = get_class_string(sym, 0);
1240
1241 if (accmem == '$' && *sym->current == 'B') /* vcall thunk */
1242 {
1243 const char *n;
1244
1245 sym->current++;
1246 n = get_number(sym);
1247
1248 if(!n || *sym->current++ != 'A') goto done;
1249 name = str_printf(sym, "%s{%s,{flat}}' }'", name, n);
1250 has_args = FALSE;
1251 has_ret = FALSE;
1252 }
1253 else if (accmem == '$' && *sym->current == 'R') /* vtordispex thunk */
1254 {
1255 const char *n1, *n2, *n3, *n4;
1256
1257 sym->current += 2;
1258 n1 = get_number(sym);
1259 n2 = get_number(sym);
1260 n3 = get_number(sym);
1261 n4 = get_number(sym);
1262
1263 if(!n1 || !n2 || !n3 || !n4) goto done;
1264 name = str_printf(sym, "%s`vtordispex{%s,%s,%s,%s}' ", name, n1, n2, n3, n4);
1265 }
1266 else if (accmem == '$') /* vtordisp thunk */
1267 {
1268 const char *n1, *n2;
1269
1270 sym->current++;
1271 n1 = get_number(sym);
1272 n2 = get_number(sym);
1273
1274 if (!n1 || !n2) goto done;
1275 name = str_printf(sym, "%s`vtordisp{%s,%s}' ", name, n1, n2);
1276 }
1277 else if ((accmem - 'A') % 8 == 6 || (accmem - 'A') % 8 == 7) /* a thunk */
1278 name = str_printf(sym, "%s`adjustor{%s}' ", name, get_number(sym));
1279
1280 if (has_args && (accmem == '$' ||
1281 (accmem <= 'X' && (accmem - 'A') % 8 != 2 && (accmem - 'A') % 8 != 3)))
1282 {
1283 const char *ptr_modif;
1284 /* Implicit 'this' pointer */
1285 /* If there is an implicit this pointer, const modifier follows */
1286 if (!get_modifier(sym, &modifier, &ptr_modif)) goto done;
1287 if (modifier || ptr_modif) modifier = str_printf(sym, "%s %s", modifier, ptr_modif);
1288 }
1289
1290 if (!get_calling_convention(*sym->current++, &call_conv, &exported,
1291 sym->flags))
1292 goto done;
1293
1294 str_array_init(&array_pmt);
1295
1296 /* Return type, or @ if 'void' */
1297 if (has_ret && *sym->current == '@')
1298 {
1299 ct_ret.left = "void";
1300 ct_ret.right = NULL;
1301 sym->current++;
1302 }
1303 else if (has_ret)
1304 {
1305 if (!demangle_datatype(sym, &ct_ret, &array_pmt, FALSE))
1306 goto done;
1307 }
1308 if (!has_ret || sym->flags & UNDNAME_NO_FUNCTION_RETURNS)
1309 ct_ret.left = ct_ret.right = NULL;
1310 if (cast_op)
1311 {
1312 name = str_printf(sym, "%s%s%s", name, ct_ret.left, ct_ret.right);
1313 ct_ret.left = ct_ret.right = NULL;
1314 }
1315
1316 mark = sym->stack.num;
1317 if (has_args && !(args_str = get_args(sym, &array_pmt, TRUE, '(', ')'))) goto done;
1318 if (sym->flags & UNDNAME_NAME_ONLY) args_str = modifier = NULL;
1319 if (sym->flags & UNDNAME_NO_THISTYPE) modifier = NULL;
1320 sym->stack.num = mark;
1321
1322 /* Note: '()' after 'Z' means 'throws', but we don't care here
1323 * Yet!!! FIXME
1324 */
1325 sym->result = str_printf(sym, "%s%s%s%s%s%s%s%s%s%s%s",
1326 access, member_type, ct_ret.left,
1327 (ct_ret.left && !ct_ret.right) ? " " : NULL,
1328 call_conv, call_conv ? " " : NULL, exported,
1329 name, args_str, modifier, ct_ret.right);
1330 ret = TRUE;
1331done:
1332 return ret;
1333}
#define UNDNAME_NO_THISTYPE
Definition: dbghelp.h:1259
GLdouble n
Definition: glext.h:7729
int n4
Definition: dwarfget.c:148
int n2
Definition: dwarfget.c:148
int n3
Definition: dwarfget.c:148

Referenced by symbol_demangle().

◆ str_array_get_ref()

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

Definition at line 215 of file undname.c.

216{
217 assert(cref);
218 if (cref->start + idx >= cref->max)
219 {
220 WARN("Out of bounds: %p %d + %d >= %d\n",
221 cref, cref->start, idx, cref->max);
222 return NULL;
223 }
224 TRACE("Returning %p[%d] => %s\n",
225 cref, idx, debugstr_a(cref->elts[cref->start + idx]));
226 return cref->elts[cref->start + idx];
227}
#define WARN(fmt,...)
Definition: debug.h:112
unsigned int idx
Definition: utils.c:41
char ** elts
Definition: undname.c:60
unsigned start
Definition: undname.c:56
unsigned max
Definition: undname.c:58

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 155 of file undname.c.

156{
157 a->start = a->num = a->max = a->alloc = 0;
158 a->elts = NULL;
159}

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 165 of file undname.c.

167{
168 char** new;
169
170 assert(ptr);
171 assert(a);
172
173 if (!a->alloc)
174 {
175 new = und_alloc(sym, (a->alloc = 32) * sizeof(a->elts[0]));
176 if (!new) return FALSE;
177 a->elts = new;
178 }
179 else if (a->max >= a->alloc)
180 {
181 new = und_alloc(sym, (a->alloc * 2) * sizeof(a->elts[0]));
182 if (!new) return FALSE;
183 memcpy(new, a->elts, a->alloc * sizeof(a->elts[0]));
184 a->alloc *= 2;
185 a->elts = new;
186 }
187 if (len == -1) len = strlen(ptr);
188 a->elts[a->num] = und_alloc(sym, len + 1);
189 assert(a->elts[a->num]);
190 memcpy(a->elts[a->num], ptr, len);
191 a->elts[a->num][len] = '\0';
192 if (++a->num >= a->max) a->max = a->num;
193 {
194 int i;
195 char c;
196
197 for (i = a->max - 1; i >= 0; i--)
198 {
199 c = '>';
200 if (i < a->start) c = '-';
201 else if (i >= a->num) c = '}';
202 /* This check is as useless as the unused-but-set gcc warning that we want to silence here */
203 if (c != 0) TRACE("%p\t%d%c %s\n", a, i, c, debugstr_a(a->elts[i]));
204 }
205 }
206
207 return TRUE;
208}
#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 * str_printf ( struct parsed_symbol sym,
const char format,
  ... 
)
static

Definition at line 234 of file undname.c.

235{
237 unsigned int len = 1, i, sz;
238 char* tmp;
239 char* p;
240 char* t;
241
243 for (i = 0; format[i]; i++)
244 {
245 if (format[i] == '%')
246 {
247 switch (format[++i])
248 {
249 case 's': t = va_arg(args, char*); if (t) len += strlen(t); break;
250 case 'c': (void)va_arg(args, int); len++; break;
251 default: i--; /* fall through */
252 case '%': len++; break;
253 }
254 }
255 else len++;
256 }
257 va_end(args);
258 if (!(tmp = und_alloc(sym, len))) return NULL;
260 for (p = tmp, i = 0; format[i]; i++)
261 {
262 if (format[i] == '%')
263 {
264 switch (format[++i])
265 {
266 case 's':
267 t = va_arg(args, char*);
268 if (t)
269 {
270 sz = strlen(t);
271 memcpy(p, t, sz);
272 p += sz;
273 }
274 break;
275 case 'c':
276 *p++ = (char)va_arg(args, int);
277 break;
278 default: i--; /* fall through */
279 case '%': *p++ = '%'; break;
280 }
281 }
282 else *p++ = format[i];
283 }
284 va_end(args);
285 *p = '\0';
286 return tmp;
287}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define va_arg(ap, T)
Definition: acmsvcex.h:89
unsigned char
Definition: typeof.h:29
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLdouble GLdouble t
Definition: gl.h:2047
GLfloat GLfloat p
Definition: glext.h:8902

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

◆ symbol_demangle()

static BOOL symbol_demangle ( struct parsed_symbol sym)
static

Definition at line 1339 of file undname.c.

1340{
1341 BOOL ret = FALSE;
1342 unsigned do_after = 0;
1343 static CHAR dashed_null[] = "--null--";
1344
1345 /* FIXME seems wrong as name, as it demangles a simple data type */
1346 if (sym->flags & UNDNAME_NO_ARGUMENTS)
1347 {
1348 struct datatype_t ct;
1349
1350 if (demangle_datatype(sym, &ct, NULL, FALSE))
1351 {
1352 sym->result = str_printf(sym, "%s%s", ct.left, ct.right);
1353 ret = TRUE;
1354 }
1355 goto done;
1356 }
1357
1358 /* MS mangled names always begin with '?' */
1359 if (*sym->current != '?') return FALSE;
1360 sym->current++;
1361
1362 /* Then function name or operator code */
1363 if (*sym->current == '?' && (sym->current[1] != '$' || sym->current[2] == '?'))
1364 {
1365 const char* function_name = NULL;
1366
1367 if (sym->current[1] == '$')
1368 {
1369 do_after = 6;
1370 sym->current += 2;
1371 }
1372
1373 /* C++ operator code (one character, or two if the first is '_') */
1374 switch (*++sym->current)
1375 {
1376 case '0': do_after = 1; break;
1377 case '1': do_after = 2; break;
1378 case '2': function_name = "operator new"; break;
1379 case '3': function_name = "operator delete"; break;
1380 case '4': function_name = "operator="; break;
1381 case '5': function_name = "operator>>"; break;
1382 case '6': function_name = "operator<<"; break;
1383 case '7': function_name = "operator!"; break;
1384 case '8': function_name = "operator=="; break;
1385 case '9': function_name = "operator!="; break;
1386 case 'A': function_name = "operator[]"; break;
1387 case 'B': function_name = "operator "; do_after = 3; break;
1388 case 'C': function_name = "operator->"; break;
1389 case 'D': function_name = "operator*"; break;
1390 case 'E': function_name = "operator++"; break;
1391 case 'F': function_name = "operator--"; break;
1392 case 'G': function_name = "operator-"; break;
1393 case 'H': function_name = "operator+"; break;
1394 case 'I': function_name = "operator&"; break;
1395 case 'J': function_name = "operator->*"; break;
1396 case 'K': function_name = "operator/"; break;
1397 case 'L': function_name = "operator%"; break;
1398 case 'M': function_name = "operator<"; break;
1399 case 'N': function_name = "operator<="; break;
1400 case 'O': function_name = "operator>"; break;
1401 case 'P': function_name = "operator>="; break;
1402 case 'Q': function_name = "operator,"; break;
1403 case 'R': function_name = "operator()"; break;
1404 case 'S': function_name = "operator~"; break;
1405 case 'T': function_name = "operator^"; break;
1406 case 'U': function_name = "operator|"; break;
1407 case 'V': function_name = "operator&&"; break;
1408 case 'W': function_name = "operator||"; break;
1409 case 'X': function_name = "operator*="; break;
1410 case 'Y': function_name = "operator+="; break;
1411 case 'Z': function_name = "operator-="; break;
1412 case '_':
1413 switch (*++sym->current)
1414 {
1415 case '0': function_name = "operator/="; break;
1416 case '1': function_name = "operator%="; break;
1417 case '2': function_name = "operator>>="; break;
1418 case '3': function_name = "operator<<="; break;
1419 case '4': function_name = "operator&="; break;
1420 case '5': function_name = "operator|="; break;
1421 case '6': function_name = "operator^="; break;
1422 case '7': function_name = "`vftable'"; break;
1423 case '8': function_name = "`vbtable'"; break;
1424 case '9': function_name = "`vcall'"; break;
1425 case 'A': function_name = "`typeof'"; break;
1426 case 'B': function_name = "`local static guard'"; break;
1427 case 'C': function_name = "`string'"; do_after = 4; break;
1428 case 'D': function_name = "`vbase destructor'"; break;
1429 case 'E': function_name = "`vector deleting destructor'"; break;
1430 case 'F': function_name = "`default constructor closure'"; break;
1431 case 'G': function_name = "`scalar deleting destructor'"; break;
1432 case 'H': function_name = "`vector constructor iterator'"; break;
1433 case 'I': function_name = "`vector destructor iterator'"; break;
1434 case 'J': function_name = "`vector vbase constructor iterator'"; break;
1435 case 'K': function_name = "`virtual displacement map'"; break;
1436 case 'L': function_name = "`eh vector constructor iterator'"; break;
1437 case 'M': function_name = "`eh vector destructor iterator'"; break;
1438 case 'N': function_name = "`eh vector vbase constructor iterator'"; break;
1439 case 'O': function_name = "`copy constructor closure'"; break;
1440 case 'R':
1442 switch (*++sym->current)
1443 {
1444 case '0':
1445 {
1446 struct datatype_t ct;
1447 struct array pmt;
1448
1449 sym->current++;
1450 str_array_init(&pmt);
1451 demangle_datatype(sym, &ct, &pmt, FALSE);
1452 if (!demangle_datatype(sym, &ct, NULL, FALSE))
1453 goto done;
1454 function_name = str_printf(sym, "%s%s `RTTI Type Descriptor'",
1455 ct.left, ct.right);
1456 sym->current--;
1457 }
1458 break;
1459 case '1':
1460 {
1461 const char* n1, *n2, *n3, *n4;
1462 sym->current++;
1463 n1 = get_number(sym);
1464 n2 = get_number(sym);
1465 n3 = get_number(sym);
1466 n4 = get_number(sym);
1467 sym->current--;
1468 function_name = str_printf(sym, "`RTTI Base Class Descriptor at (%s,%s,%s,%s)'",
1469 n1, n2, n3, n4);
1470 }
1471 break;
1472 case '2': function_name = "`RTTI Base Class Array'"; break;
1473 case '3': function_name = "`RTTI Class Hierarchy Descriptor'"; break;
1474 case '4': function_name = "`RTTI Complete Object Locator'"; break;
1475 default:
1476 ERR("Unknown RTTI operator: _R%c\n", *sym->current);
1477 break;
1478 }
1479 break;
1480 case 'S': function_name = "`local vftable'"; break;
1481 case 'T': function_name = "`local vftable constructor closure'"; break;
1482 case 'U': function_name = "operator new[]"; break;
1483 case 'V': function_name = "operator delete[]"; break;
1484 case 'X': function_name = "`placement delete closure'"; break;
1485 case 'Y': function_name = "`placement delete[] closure'"; break;
1486 default:
1487 ERR("Unknown operator: _%c\n", *sym->current);
1488 return FALSE;
1489 }
1490 break;
1491 default:
1492 /* FIXME: Other operators */
1493 ERR("Unknown operator: %c\n", *sym->current);
1494 return FALSE;
1495 }
1496 sym->current++;
1497 switch (do_after)
1498 {
1499 case 1: case 2:
1500 if (!str_array_push(sym, dashed_null, -1, &sym->stack))
1501 return FALSE;
1502 break;
1503 case 4:
1504 sym->result = (char*)function_name;
1505 ret = TRUE;
1506 goto done;
1507 case 6:
1508 {
1509 char *args;
1510 struct array array_pmt;
1511
1512 str_array_init(&array_pmt);
1513 args = get_args(sym, &array_pmt, FALSE, '<', '>');
1514 if (args != NULL) function_name = str_printf(sym, "%s%s", function_name, args);
1515 sym->names.num = 0;
1516 }
1517 /* fall through */
1518 default:
1519 if (!str_array_push(sym, function_name, -1, &sym->stack))
1520 return FALSE;
1521 break;
1522 }
1523 }
1524 else if (*sym->current == '$')
1525 {
1526 /* Strange construct, it's a name with a template argument list
1527 and that's all. */
1528 sym->current++;
1529 ret = (sym->result = get_template_name(sym)) != NULL;
1530 goto done;
1531 }
1532 else if (*sym->current == '?' && sym->current[1] == '$')
1533 do_after = 5;
1534
1535 /* Either a class name, or '@' if the symbol is not a class member */
1536 switch (*sym->current)
1537 {
1538 case '@': sym->current++; break;
1539 case '$': break;
1540 default:
1541 /* Class the function is associated with, terminated by '@@' */
1542 if (!get_class(sym)) goto done;
1543 break;
1544 }
1545
1546 switch (do_after)
1547 {
1548 case 0: default: break;
1549 case 1: case 2:
1550 /* it's time to set the member name for ctor & dtor */
1551 if (sym->stack.num <= 1) goto done;
1552 if (do_after == 1)
1553 sym->stack.elts[0] = sym->stack.elts[1];
1554 else
1555 sym->stack.elts[0] = str_printf(sym, "~%s", sym->stack.elts[1]);
1556 /* ctors and dtors don't have return type */
1558 break;
1559 case 3:
1560 sym->flags &= ~UNDNAME_NO_FUNCTION_RETURNS;
1561 break;
1562 case 5:
1563 sym->names.start++;
1564 break;
1565 }
1566
1567 /* Function/Data type and access level */
1568 if (*sym->current >= '0' && *sym->current <= '9')
1569 ret = handle_data(sym);
1570 else if ((*sym->current >= 'A' && *sym->current <= 'Z') || *sym->current == '$')
1571 ret = handle_method(sym, do_after == 3);
1572 else ret = FALSE;
1573done:
1574 if (ret) assert(sym->result);
1575 else WARN("Failed at %s\n", debugstr_a(sym->current));
1576
1577 return ret;
1578}
#define UNDNAME_NO_ARGUMENTS
Definition: dbghelp.h:1266
static BOOL handle_method(struct parsed_symbol *sym, BOOL cast_op)
Definition: undname.c:1147
static BOOL handle_data(struct parsed_symbol *sym)
Definition: undname.c:1056
char CHAR
Definition: xmlstorage.h:175

Referenced by __unDNameEx(), and get_class().

◆ und_alloc()

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

Definition at line 96 of file undname.c.

97{
98 void* ptr;
99
100#define BLOCK_SIZE 1024
101#define AVAIL_SIZE (1024 - sizeof(void*))
102
103 if (len > AVAIL_SIZE)
104 {
105 /* allocate a specific block */
106 ptr = sym->mem_alloc_ptr(sizeof(void*) + len);
107 if (!ptr) return NULL;
108 *(void**)ptr = sym->alloc_list;
109 sym->alloc_list = ptr;
110 sym->avail_in_first = 0;
111 ptr = (char*)sym->alloc_list + sizeof(void*);
112 }
113 else
114 {
115 if (len > sym->avail_in_first)
116 {
117 /* add a new block */
119 if (!ptr) return NULL;
120 *(void**)ptr = sym->alloc_list;
121 sym->alloc_list = ptr;
123 }
124 /* grab memory from head block */
125 ptr = (char*)sym->alloc_list + BLOCK_SIZE - sym->avail_in_first;
126 sym->avail_in_first -= len;
127 }
128 return ptr;
129#undef BLOCK_SIZE
130#undef AVAIL_SIZE
131}
void * alloc_list
Definition: undname.c:76
malloc_func_t mem_alloc_ptr
Definition: undname.c:67
unsigned avail_in_first
Definition: undname.c:77
#define AVAIL_SIZE
#define BLOCK_SIZE

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 138 of file undname.c.

139{
140 void* next;
141
142 while (sym->alloc_list)
143 {
144 next = *(void**)sym->alloc_list;
145 if(sym->mem_free_ptr) sym->mem_free_ptr(sym->alloc_list);
146 sym->alloc_list = next;
147 }
148 sym->avail_in_first = 0;
149}
static unsigned __int64 next
Definition: rand_nt.c:6
free_func_t mem_free_ptr
Definition: undname.c:68

Referenced by __unDNameEx().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msvcrt  )