2 * Demangle VC++ symbols into C function prototypes
4 * Copyright 2000 Jon Griffiths
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
26 /* Type for parsing mangled types */
27 typedef struct _compound_type
36 /* Initialise a compound type structure */
37 #define INIT_CT(ct) do { memset (&ct, 0, sizeof (ct)); } while (0)
39 /* free the memory used by a compound structure */
40 #define FREE_CT(ct) free (ct.expression)
42 /* Flags for data types */
43 #define DATA_VTABLE 0x1
45 /* Internal functions */
46 static char *demangle_datatype (char **str
, compound_type
*ct
,
49 static char *get_constraints_convention_1 (char **str
, compound_type
*ct
);
51 static char *get_constraints_convention_2 (char **str
, compound_type
*ct
);
53 static char *get_type_string (const char c
, const int constraints
);
55 static int get_type_constant (const char c
, const int constraints
);
57 static char *get_pointer_type_string (compound_type
*ct
,
58 const char *expression
);
61 /*******************************************************************
64 * Demangle a C++ linker symbol into a C prototype
66 int symbol_demangle (parsed_symbol
*sym
)
69 int is_static
= 0, is_const
= 0;
70 char *function_name
= NULL
;
71 char *class_name
= NULL
;
73 const char *const_status
;
74 static unsigned int hash
= 0; /* In case of overloaded functions */
75 unsigned int data_flags
= 0;
77 assert (globals
.do_code
);
78 assert (sym
&& sym
->symbol
);
82 /* MS mangled names always begin with '?' */
88 puts ("Attempting to demangle symbol");
90 /* Then function name or operator code */
93 /* C++ operator code (one character, or two if the first is '_') */
96 case '0': function_name
= strdup ("ctor"); break;
97 case '1': function_name
= strdup ("dtor"); break;
98 case '2': function_name
= strdup ("operator_new"); break;
99 case '3': function_name
= strdup ("operator_delete"); break;
100 case '4': function_name
= strdup ("operator_equals"); break;
101 case '5': function_name
= strdup ("operator_shiftright"); break;
102 case '6': function_name
= strdup ("operator_shiftleft"); break;
103 case '7': function_name
= strdup ("operator_not"); break;
104 case '8': function_name
= strdup ("operator_equalsequals"); break;
105 case '9': function_name
= strdup ("operator_notequals"); break;
106 case 'A': function_name
= strdup ("operator_array"); break;
107 case 'C': function_name
= strdup ("operator_dereference"); break;
108 case 'D': function_name
= strdup ("operator_multiply"); break;
109 case 'E': function_name
= strdup ("operator_plusplus"); break;
110 case 'F': function_name
= strdup ("operator_minusminus"); break;
111 case 'G': function_name
= strdup ("operator_minus"); break;
112 case 'H': function_name
= strdup ("operator_plus"); break;
113 case 'I': function_name
= strdup ("operator_address"); break;
114 case 'J': function_name
= strdup ("operator_dereferencememberptr"); break;
115 case 'K': function_name
= strdup ("operator_divide"); break;
116 case 'L': function_name
= strdup ("operator_modulo"); break;
117 case 'M': function_name
= strdup ("operator_lessthan"); break;
118 case 'N': function_name
= strdup ("operator_lessthanequal"); break;
119 case 'O': function_name
= strdup ("operator_greaterthan"); break;
120 case 'P': function_name
= strdup ("operator_greaterthanequal"); break;
121 case 'Q': function_name
= strdup ("operator_comma"); break;
122 case 'R': function_name
= strdup ("operator_functioncall"); break;
123 case 'S': function_name
= strdup ("operator_complement"); break;
124 case 'T': function_name
= strdup ("operator_xor"); break;
125 case 'U': function_name
= strdup ("operator_logicalor"); break;
126 case 'V': function_name
= strdup ("operator_logicaland"); break;
127 case 'W': function_name
= strdup ("operator_or"); break;
128 case 'X': function_name
= strdup ("operator_multiplyequals"); break;
129 case 'Y': function_name
= strdup ("operator_plusequals"); break;
130 case 'Z': function_name
= strdup ("operator_minusequals"); break;
134 case '0': function_name
= strdup ("operator_divideequals"); break;
135 case '1': function_name
= strdup ("operator_moduloequals"); break;
136 case '2': function_name
= strdup ("operator_shiftrightequals"); break;
137 case '3': function_name
= strdup ("operator_shiftleftequals"); break;
138 case '4': function_name
= strdup ("operator_andequals"); break;
139 case '5': function_name
= strdup ("operator_orequals"); break;
140 case '6': function_name
= strdup ("operator_xorequals"); break;
141 case '7': function_name
= strdup ("vftable"); data_flags
= DATA_VTABLE
; break;
142 case '8': function_name
= strdup ("vbtable"); data_flags
= DATA_VTABLE
; break;
143 case '9': function_name
= strdup ("vcall"); data_flags
= DATA_VTABLE
; break;
144 case 'A': function_name
= strdup ("typeof"); data_flags
= DATA_VTABLE
; break;
145 case 'B': function_name
= strdup ("local_static_guard"); data_flags
= DATA_VTABLE
; break;
146 case 'C': function_name
= strdup ("string"); data_flags
= DATA_VTABLE
; break;
147 case 'D': function_name
= strdup ("vbase_dtor"); data_flags
= DATA_VTABLE
; break;
148 case 'E': function_name
= strdup ("vector_dtor"); break;
149 case 'G': function_name
= strdup ("scalar_dtor"); break;
150 case 'H': function_name
= strdup ("vector_ctor_iter"); break;
151 case 'I': function_name
= strdup ("vector_dtor_iter"); break;
152 case 'J': function_name
= strdup ("vector_vbase_ctor_iter"); break;
153 case 'L': function_name
= strdup ("eh_vector_ctor_iter"); break;
154 case 'M': function_name
= strdup ("eh_vector_dtor_iter"); break;
155 case 'N': function_name
= strdup ("eh_vector_vbase_ctor_iter"); break;
156 case 'O': function_name
= strdup ("copy_ctor_closure"); break;
157 case 'S': function_name
= strdup ("local_vftable"); data_flags
= DATA_VTABLE
; break;
158 case 'T': function_name
= strdup ("local_vftable_ctor_closure"); break;
159 case 'U': function_name
= strdup ("operator_new_vector"); break;
160 case 'V': function_name
= strdup ("operator_delete_vector"); break;
161 case 'X': function_name
= strdup ("placement_new_closure"); break;
162 case 'Y': function_name
= strdup ("placement_delete_closure"); break;
168 /* FIXME: Other operators */
175 /* Type or function name terminated by '@' */
176 function_name
= name
;
177 while (*name
&& *name
++ != '@') ;
180 function_name
= str_substring (function_name
, name
- 1);
183 /* Either a class name, or '@' if the symbol is not a class member */
186 class_name
= strdup ("global"); /* Non member function (or a datatype) */
191 /* Class the function is associated with, terminated by '@@' */
193 while (*name
&& *name
++ != '@') ;
194 if (*name
++ != '@') {
195 free (function_name
);
198 class_name
= str_substring (class_name
, name
- 2); /* Allocates a new string */
201 /* Function/Data type and access level */
202 /* FIXME: why 2 possible letters for each option? */
207 case '0' : /* private static */
208 case '1' : /* protected static */
209 case '2' : /* public static */
212 case '3' : /* non static */
213 case '4' : /* non static */
214 /* Data members need to be implemented: report */
216 if (!demangle_datatype (&name
, &ct
, sym
))
219 printf ("/*FIXME: %s: unknown data*/\n", sym
->symbol
);
220 free (function_name
);
224 sym
->flags
|= SYM_DATA
;
226 sym
->arg_name
[0] = str_create (5, OUTPUT_UC_DLL_NAME
, "_", class_name
,
227 is_static
? "static_" : "_", function_name
);
228 sym
->arg_text
[0] = str_create (3, ct
.expression
, " ", sym
->arg_name
[0]);
230 free (function_name
);
234 case '6' : /* compiler generated static */
235 case '7' : /* compiler generated static */
236 if (data_flags
& DATA_VTABLE
)
238 sym
->flags
|= SYM_DATA
;
240 sym
->arg_name
[0] = str_create (5, OUTPUT_UC_DLL_NAME
, "_", class_name
,
242 sym
->arg_text
[0] = str_create (2, "void *", sym
->arg_name
[0]);
245 puts ("Demangled symbol OK [vtable]");
246 free (function_name
);
250 free (function_name
);
256 case 'E' : /* private virtual */
257 case 'F' : /* private virtual */
258 case 'M' : /* protected virtual */
259 case 'N' : /* protected virtual */
260 case 'U' : /* public virtual */
261 case 'V' : /* public virtual */
262 /* Virtual functions need to be added to the exported vtable: report */
264 printf ("/*FIXME %s: %s::%s is virtual-add to vftable*/\n", sym
->symbol
,
265 class_name
, function_name
);
267 case 'A' : /* private */
268 case 'B' : /* private */
269 case 'I' : /* protected */
270 case 'J' : /* protected */
271 case 'Q' : /* public */
272 case 'R' : /* public */
273 /* Implicit 'this' pointer */
274 sym
->arg_text
[sym
->argc
] = str_create (3, "struct ", class_name
, " *");
275 sym
->arg_type
[sym
->argc
] = ARG_POINTER
;
276 sym
->arg_flag
[sym
->argc
] = 0;
277 sym
->arg_name
[sym
->argc
++] = strdup ("_this");
278 /* New struct definitions can be 'grep'ed out for making a fixup header */
280 printf ("struct %s { void **vtable; /*FIXME: class definition */ };\n", class_name
);
282 case 'C' : /* private: static */
283 case 'D' : /* private: static */
284 case 'K' : /* protected: static */
285 case 'L' : /* protected: static */
286 case 'S' : /* public: static */
287 case 'T' : /* public: static */
288 is_static
= 1; /* No implicit this pointer */
293 /* FIXME: G,H / O,P / W,X are private / protected / public thunks */
295 free (function_name
);
300 /* If there is an implicit this pointer, const status follows */
305 case 'A': break; /* non-const */
306 case 'B': is_const
= CT_CONST
; break;
307 case 'C': is_const
= CT_VOLATILE
; break;
308 case 'D': is_const
= (CT_CONST
| CT_VOLATILE
); break;
310 free (function_name
);
316 /* Next is the calling convention */
319 case 'A': /* __cdecl */
320 case 'B': /* __cdecl __declspec(dllexport) */
323 sym
->flags
|= SYM_CDECL
;
326 /* Else fall through */
327 case 'C': /* __pascal */
328 case 'D': /* __pascal __declspec(dllexport) */
329 case 'E': /* __thiscall */
330 case 'F': /* __thiscall __declspec(dllexport) */
331 case 'G': /* __stdcall */
332 case 'H': /* __stdcall __declspec(dllexport) */
333 case 'I': /* __fastcall */
334 case 'J': /* __fastcall __declspec(dllexport)*/
335 case 'K': /* default (none given) */
337 sym
->flags
|= SYM_THISCALL
;
339 sym
->flags
|= SYM_STDCALL
;
342 free (function_name
);
347 /* Return type, or @ if 'void' */
350 sym
->return_text
= strdup ("void");
351 sym
->return_type
= ARG_VOID
;
357 if (!demangle_datatype (&name
, &ct
, sym
)) {
358 free (function_name
);
362 sym
->return_text
= ct
.expression
;
363 sym
->return_type
= get_type_constant(ct
.dest_type
, ct
.flags
);
364 ct
.expression
= NULL
;
368 /* Now come the function arguments */
369 while (*name
&& *name
!= 'Z')
371 /* Decode each data type and append it to the argument list */
375 if (!demangle_datatype(&name
, &ct
, sym
)) {
376 free (function_name
);
381 if (strcmp (ct
.expression
, "void"))
383 sym
->arg_text
[sym
->argc
] = ct
.expression
;
384 ct
.expression
= NULL
;
385 sym
->arg_type
[sym
->argc
] = get_type_constant (ct
.dest_type
, ct
.flags
);
386 sym
->arg_flag
[sym
->argc
] = ct
.flags
;
387 sym
->arg_name
[sym
->argc
] = str_create_num (1, sym
->argc
, "arg");
391 break; /* 'void' terminates an argument list */
401 /* Functions are always terminated by 'Z'. If we made it this far and
402 * Don't find it, we have incorrectly identified a data type.
405 free (function_name
);
410 /* Note: '()' after 'Z' means 'throws', but we don't care here */
412 /* Create the function name. Include a unique number because otherwise
413 * overloaded functions could have the same c signature.
417 case (CT_CONST
| CT_VOLATILE
): const_status
= "_const_volatile"; break;
418 case CT_CONST
: const_status
= "_const"; break;
419 case CT_VOLATILE
: const_status
= "_volatile"; break;
420 default: const_status
= "_"; break;
422 sym
->function_name
= str_create_num (4, hash
, class_name
, "_",
423 function_name
, is_static
? "_static" : const_status
);
425 assert (sym
->return_text
);
427 assert (sym
->function_name
);
430 free (function_name
);
433 puts ("Demangled symbol OK");
439 /*******************************************************************
442 * Attempt to demangle a C++ data type, which may be compound.
443 * a compound type is made up of a number of simple types. e.g:
444 * char** = (pointer to (pointer to (char)))
446 * Uses a simple recursive descent algorithm that is broken
447 * and/or incomplete, without a doubt ;-)
449 static char *demangle_datatype (char **str
, compound_type
*ct
,
454 assert (str
&& *str
);
459 if (!get_constraints_convention_1 (&iter
, ct
))
464 /* MS type: __int8,__int16 etc */
465 ct
->flags
|= CT_EXTENDED
;
471 case 'C': case 'D': case 'E': case 'F': case 'G':
472 case 'H': case 'I': case 'J': case 'K': case 'M':
473 case 'N': case 'O': case 'X': case 'Z':
474 /* Simple data types */
475 ct
->dest_type
= *iter
++;
476 if (!get_constraints_convention_2 (&iter
, ct
))
478 ct
->expression
= get_type_string (ct
->dest_type
, ct
->flags
);
482 /* Class/struct/union */
483 ct
->dest_type
= *iter
++;
484 if (*iter
== '0' || *iter
== '1')
486 /* Referring to class type (implicit 'this') */
492 /* Apply our constraints to the base type (struct xxx *) */
493 stripped
= strdup (sym
->arg_text
[0]);
495 fatal ("Out of Memory");
497 /* If we're a reference, re-use the pointer already in the type */
498 if (!(ct
->flags
& CT_BY_REFERENCE
))
499 stripped
[ strlen (stripped
) - 2] = '\0'; /* otherwise, strip it */
501 ct
->expression
= str_create (2, ct
->flags
& CT_CONST
? "const " :
502 ct
->flags
& CT_VOLATILE
? "volatile " : "", stripped
);
505 else if (*iter
!= '@')
507 /* The name of the class/struct, followed by '@@' */
508 char *struct_name
= iter
;
509 while (*iter
&& *iter
++ != '@') ;
512 struct_name
= str_substring (struct_name
, iter
- 2);
513 ct
->expression
= str_create (4, ct
->flags
& CT_CONST
? "const " :
514 ct
->flags
& CT_VOLATILE
? "volatile " : "", "struct ",
515 struct_name
, ct
->flags
& CT_BY_REFERENCE
? " *" : "");
519 case 'Q': /* FIXME: Array Just treated as pointer currently */
520 case 'P': /* Pointer */
522 compound_type sub_ct
;
525 ct
->dest_type
= *iter
++;
526 if (!get_constraints_convention_2 (&iter
, ct
))
529 /* FIXME: P6 = Function pointer, others who knows.. */
534 int sub_expressions
= 0;
535 /* FIXME: there are tons of memory leaks here */
536 /* FIXME: this is still broken in some cases and it has to be
537 * merged with the function prototype parsing above...
539 iter
+= iter
[1] == 'A' ? 2 : 3; /* FIXME */
540 if (!demangle_datatype (&iter
, &sub_ct
, sym
))
542 ct
->expression
= str_create(2, sub_ct
.expression
, " (*)(");
549 if (!demangle_datatype (&iter
, &sub_ct
, sym
))
552 ct
->expression
= str_create(3, ct
->expression
, ", ", sub_ct
.expression
);
554 ct
->expression
= str_create(2, ct
->expression
, sub_ct
.expression
);
555 while (*iter
== '@') iter
++;
558 } else while (*iter
== '@') iter
++;
560 ct
->expression
= str_create(2, ct
->expression
, ")");
567 /* Recurse to get the pointed-to type */
568 if (!demangle_datatype (&iter
, &sub_ct
, sym
))
571 ct
->expression
= get_pointer_type_string (ct
, sub_ct
.expression
);
577 case '0': case '1': case '2': case '3': case '4':
578 case '5': case '6': case '7': case '8': case '9':
579 /* Referring back to previously parsed type */
580 if (sym
->argc
>= (size_t)('0' - *iter
))
582 ct
->dest_type
= sym
->arg_type
['0' - *iter
];
583 ct
->expression
= strdup (sym
->arg_text
['0' - *iter
]);
592 return (char *)(*str
= iter
);
597 * There are two conventions for specifying data type constants. I
598 * don't know how the compiler chooses between them, but I suspect it
599 * is based on ensuring that linker names are unique.
600 * Convention 1. The data type modifier is given first, followed
601 * by the data type it operates on. '?' means passed by value,
602 * 'A' means passed by reference. Note neither of these characters
603 * is a valid base data type. This is then followed by a character
604 * specifying constness or volatility.
605 * Convention 2. The base data type (which is never '?' or 'A') is
606 * given first. The character modifier is optionally given after
607 * the base type character. If a valid character modifier is present,
608 * then it only applies to the current data type if the character
609 * after that is not 'A' 'B' or 'C' (Because this makes a convention 1
610 * constraint for the next data type).
612 * The conventions are usually mixed within the same symbol.
613 * Since 'C' is both a qualifier and a data type, I suspect that
614 * convention 1 allows specifying e.g. 'volatile signed char*'. In
615 * convention 2 this would be 'CC' which is ambiguous (i.e. Is it two
616 * pointers, or a single pointer + modifier?). In convention 1 it
617 * is encoded as '?CC' which is not ambiguous. This probably
618 * holds true for some other types as well.
621 /*******************************************************************
622 * get_constraints_convention_1
624 * Get type constraint information for a data type
626 static char *get_constraints_convention_1 (char **str
, compound_type
*ct
)
628 char *iter
= *str
, **retval
= str
;
630 if (ct
->have_qualifiers
)
631 return (char *)*str
; /* Previously got constraints for this type */
633 if (*iter
== '?' || *iter
== 'A')
635 ct
->have_qualifiers
= 1;
636 ct
->flags
|= (*iter
++ == '?' ? 0 : CT_BY_REFERENCE
);
641 break; /* non-const, non-volatile */
643 ct
->flags
|= CT_CONST
;
646 ct
->flags
|= CT_VOLATILE
;
653 return (char *)(*retval
= iter
);
657 /*******************************************************************
658 * get_constraints_convention_2
660 * Get type constraint information for a data type
662 static char *get_constraints_convention_2 (char **str
, compound_type
*ct
)
664 char *iter
= *str
, **retval
= str
;
666 /* FIXME: Why do arrays have both convention 1 & 2 constraints? */
667 if (ct
->have_qualifiers
&& ct
->dest_type
!= 'Q')
668 return (char *)*str
; /* Previously got constraints for this type */
670 ct
->have_qualifiers
= 1; /* Even if none, we've got all we're getting */
675 if (iter
[1] != 'A' && iter
[1] != 'B' && iter
[1] != 'C')
679 ct
->flags
|= CT_CONST
;
683 /* See note above, if we find 'C' it is _not_ a signed char */
684 ct
->flags
|= CT_VOLATILE
;
689 return (char *)(*retval
= iter
);
693 /*******************************************************************
696 * Return a string containing the name of a data type
698 static char *get_type_string (const char c
, const int constraints
)
700 const char *type_string
;
702 if (constraints
& CT_EXTENDED
)
706 case 'D': type_string
= "__int8"; break;
707 case 'E': type_string
= "unsigned __int8"; break;
708 case 'F': type_string
= "__int16"; break;
709 case 'G': type_string
= "unsigned __int16"; break;
710 case 'H': type_string
= "__int32"; break;
711 case 'I': type_string
= "unsigned __int32"; break;
712 case 'J': type_string
= "__int64"; break;
713 case 'K': type_string
= "unsigned __int64"; break;
714 case 'L': type_string
= "__int128"; break;
715 case 'M': type_string
= "unsigned __int128"; break;
716 case 'N': type_string
= "int"; break; /* bool */
717 case 'W': type_string
= "WCHAR"; break; /* wchar_t */
726 case 'C': /* Signed char, fall through */
727 case 'D': type_string
= "char"; break;
728 case 'E': type_string
= "unsigned char"; break;
729 case 'F': type_string
= "short int"; break;
730 case 'G': type_string
= "unsigned short int"; break;
731 case 'H': type_string
= "int"; break;
732 case 'I': type_string
= "unsigned int"; break;
733 case 'J': type_string
= "long"; break;
734 case 'K': type_string
= "unsigned long"; break;
735 case 'M': type_string
= "float"; break;
736 case 'N': type_string
= "double"; break;
737 case 'O': type_string
= "long double"; break;
738 /* FIXME: T = union */
740 case 'V': type_string
= "struct"; break;
741 case 'X': return strdup ("void");
742 case 'Z': return strdup ("...");
748 return str_create (3, constraints
& CT_CONST
? "const " :
749 constraints
& CT_VOLATILE
? "volatile " : "", type_string
,
750 constraints
& CT_BY_REFERENCE
? " *" : "");
754 /*******************************************************************
757 * Get the ARG_* constant for this data type
759 static int get_type_constant (const char c
, const int constraints
)
761 /* Any reference type is really a pointer */
762 if (constraints
& CT_BY_REFERENCE
)
767 case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I':
787 /*******************************************************************
788 * get_pointer_type_string
790 * Return a string containing 'pointer to expression'
792 static char *get_pointer_type_string (compound_type
*ct
,
793 const char *expression
)
795 /* FIXME: set a compound flag for bracketing expression if needed */
796 return str_create (3, ct
->flags
& CT_CONST
? "const " :
797 ct
->flags
& CT_VOLATILE
? "volatile " : "", expression
,
798 ct
->flags
& CT_BY_REFERENCE
? " **" : " *");