ReactOS 0.4.15-dev-7842-g558ab78
undname.c File Reference
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "msvcrt.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
 

Macros

#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

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

1650{
1651 return __unDNameEx(buffer, mangled, buflen, memget, memfree, NULL, flags);
1652}
#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:1600

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

1603{
1604 struct parsed_symbol sym;
1605 const char* result;
1606
1607 TRACE("(%p,%s,%d,%p,%p,%p,%x)\n",
1608 buffer, debugstr_a(mangled), buflen, memget, memfree, unknown, flags);
1609
1610 /* The flags details is not documented by MS. However, it looks exactly
1611 * like the UNDNAME_ manifest constants from imagehlp.h and dbghelp.h
1612 * So, we copied those (on top of the file)
1613 */
1614 memset(&sym, 0, sizeof(struct parsed_symbol));
1619
1620 sym.flags = flags;
1621 sym.mem_alloc_ptr = memget;
1622 sym.mem_free_ptr = memfree;
1623 sym.current = mangled;
1624 str_array_init( &sym.names );
1625 str_array_init( &sym.stack );
1626
1627 result = symbol_demangle(&sym) ? sym.result : mangled;
1628 if (buffer && buflen)
1629 {
1630 lstrcpynA( buffer, result, buflen);
1631 }
1632 else
1633 {
1634 buffer = memget(strlen(result) + 1);
1635 if (buffer) strcpy(buffer, result);
1636 }
1637
1638 und_free_all(&sym);
1639
1640 return buffer;
1641}
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:141
static BOOL symbol_demangle(struct parsed_symbol *sym)
Definition: undname.c:1341
static void str_array_init(struct array *a)
Definition: undname.c:158

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

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

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

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

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

689{
690 *call_conv = *exported = NULL;
691
693 {
695 {
696 if (((ch - 'A') % 2) == 1) *exported = "dll_export ";
697 switch (ch)
698 {
699 case 'A': case 'B': *call_conv = "cdecl"; break;
700 case 'C': case 'D': *call_conv = "pascal"; break;
701 case 'E': case 'F': *call_conv = "thiscall"; break;
702 case 'G': case 'H': *call_conv = "stdcall"; break;
703 case 'I': case 'J': *call_conv = "fastcall"; break;
704 case 'K': case 'L': break;
705 case 'M': *call_conv = "clrcall"; break;
706 default: ERR("Unknown calling convention %c\n", ch); return FALSE;
707 }
708 }
709 else
710 {
711 if (((ch - 'A') % 2) == 1) *exported = "__dll_export ";
712 switch (ch)
713 {
714 case 'A': case 'B': *call_conv = "__cdecl"; break;
715 case 'C': case 'D': *call_conv = "__pascal"; break;
716 case 'E': case 'F': *call_conv = "__thiscall"; break;
717 case 'G': case 'H': *call_conv = "__stdcall"; break;
718 case 'I': case 'J': *call_conv = "__fastcall"; break;
719 case 'K': case 'L': break;
720 case 'M': *call_conv = "__clrcall"; break;
721 default: ERR("Unknown calling convention %c\n", ch); return FALSE;
722 }
723 }
724 }
725 return TRUE;
726}
#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 580 of file undname.c.

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

Referenced by get_class_name(), and symbol_demangle().

◆ get_class_name()

static char * get_class_name ( struct parsed_symbol sym)
static

Definition at line 671 of file undname.c.

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

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

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

762{
763 const char* type_string;
764
765 switch (c)
766 {
767 case 'D': type_string = "__int8"; break;
768 case 'E': type_string = "unsigned __int8"; break;
769 case 'F': type_string = "__int16"; break;
770 case 'G': type_string = "unsigned __int16"; break;
771 case 'H': type_string = "__int32"; break;
772 case 'I': type_string = "unsigned __int32"; break;
773 case 'J': type_string = "__int64"; break;
774 case 'K': type_string = "unsigned __int64"; break;
775 case 'L': type_string = "__int128"; break;
776 case 'M': type_string = "unsigned __int128"; break;
777 case 'N': type_string = "bool"; break;
778 case 'W': type_string = "wchar_t"; break;
779 default: type_string = NULL; break;
780 }
781 return type_string;
782}
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 514 of file undname.c.

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

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

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

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

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

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

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

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

Referenced by demangle_datatype().

◆ get_template_name()

static char * get_template_name ( struct parsed_symbol sym)
static

Definition at line 544 of file undname.c.

545{
546 char *name, *args;
547 unsigned num_mark = sym->names.num;
548 unsigned start_mark = sym->names.start;
549 unsigned stack_mark = sym->stack.num;
550 struct array array_pmt;
551
552 sym->names.start = sym->names.num;
553 if (!(name = get_literal_string(sym))) {
554 sym->names.start = start_mark;
555 return FALSE;
556 }
557 str_array_init(&array_pmt);
558 args = get_args(sym, &array_pmt, FALSE, '<', '>');
559 if (args != NULL)
560 name = str_printf(sym, "%s%s", name, args);
561 sym->names.num = num_mark;
562 sym->names.start = start_mark;
563 sym->stack.num = stack_mark;
564 return name;
565}
#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 1058 of file undname.c.

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

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

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

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

159{
160 a->start = a->num = a->max = a->alloc = 0;
161 a->elts = NULL;
162}

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

170{
171 char** new;
172
173 assert(ptr);
174 assert(a);
175
176 if (!a->alloc)
177 {
178 new = und_alloc(sym, (a->alloc = 32) * sizeof(a->elts[0]));
179 if (!new) return FALSE;
180 a->elts = new;
181 }
182 else if (a->max >= a->alloc)
183 {
184 new = und_alloc(sym, (a->alloc * 2) * sizeof(a->elts[0]));
185 if (!new) return FALSE;
186 memcpy(new, a->elts, a->alloc * sizeof(a->elts[0]));
187 a->alloc *= 2;
188 a->elts = new;
189 }
190 if (len == -1) len = strlen(ptr);
191 a->elts[a->num] = und_alloc(sym, len + 1);
192 assert(a->elts[a->num]);
193 memcpy(a->elts[a->num], ptr, len);
194 a->elts[a->num][len] = '\0';
195 if (++a->num >= a->max) a->max = a->num;
196 {
197 int i;
198 char c;
199
200 for (i = a->max - 1; i >= 0; i--)
201 {
202 c = '>';
203 if (i < a->start) c = '-';
204 else if (i >= a->num) c = '}';
205 TRACE("%p\t%d%c %s\n", a, i, c, debugstr_a(a->elts[i]));
206 }
207 }
208
209 return TRUE;
210}
#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 236 of file undname.c.

237{
239 unsigned int len = 1, i, sz;
240 char* tmp;
241 char* p;
242 char* t;
243
245 for (i = 0; format[i]; i++)
246 {
247 if (format[i] == '%')
248 {
249 switch (format[++i])
250 {
251 case 's': t = va_arg(args, char*); if (t) len += strlen(t); break;
252 case 'c': (void)va_arg(args, int); len++; break;
253 default: i--; /* fall through */
254 case '%': len++; break;
255 }
256 }
257 else len++;
258 }
259 va_end(args);
260 if (!(tmp = und_alloc(sym, len))) return NULL;
262 for (p = tmp, i = 0; format[i]; i++)
263 {
264 if (format[i] == '%')
265 {
266 switch (format[++i])
267 {
268 case 's':
269 t = va_arg(args, char*);
270 if (t)
271 {
272 sz = strlen(t);
273 memcpy(p, t, sz);
274 p += sz;
275 }
276 break;
277 case 'c':
278 *p++ = (char)va_arg(args, int);
279 break;
280 default: i--; /* fall through */
281 case '%': *p++ = '%'; break;
282 }
283 }
284 else *p++ = format[i];
285 }
286 va_end(args);
287 *p = '\0';
288 return tmp;
289}
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 1341 of file undname.c.

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

100{
101 void* ptr;
102
103#define BLOCK_SIZE 1024
104#define AVAIL_SIZE (1024 - sizeof(void*))
105
106 if (len > AVAIL_SIZE)
107 {
108 /* allocate a specific block */
109 ptr = sym->mem_alloc_ptr(sizeof(void*) + len);
110 if (!ptr) return NULL;
111 *(void**)ptr = sym->alloc_list;
112 sym->alloc_list = ptr;
113 sym->avail_in_first = 0;
114 ptr = (char*)sym->alloc_list + sizeof(void*);
115 }
116 else
117 {
118 if (len > sym->avail_in_first)
119 {
120 /* add a new block */
122 if (!ptr) return NULL;
123 *(void**)ptr = sym->alloc_list;
124 sym->alloc_list = ptr;
126 }
127 /* grab memory from head block */
128 ptr = (char*)sym->alloc_list + BLOCK_SIZE - sym->avail_in_first;
129 sym->avail_in_first -= len;
130 }
131 return ptr;
132#undef BLOCK_SIZE
133#undef AVAIL_SIZE
134}
void * alloc_list
Definition: undname.c:79
malloc_func_t mem_alloc_ptr
Definition: undname.c:70
unsigned avail_in_first
Definition: undname.c:80
#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 141 of file undname.c.

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

Referenced by __unDNameEx().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msvcrt  )