1 /* Demangler for GNU C++
2 Copyright 1989, 1991 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program 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
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* This is for g++ 1.95.03 (November 13 version). */
22 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
24 This file imports xmalloc and xrealloc, which are like malloc and
25 realloc except that they generate a fatal error if there is no
28 /* GDB-specific, FIXME. */
35 /* In order to allow a single demangler executable to demangle strings
36 using various common values of CPLUS_MARKER, as well as any specific
37 one set at compile time, we maintain a string containing all the
38 commonly used ones, and check to see if the marker we are looking for
39 is in that string. CPLUS_MARKER is usually '$' on systems where the
40 assembler can deal with that. Where the assembler can't, it's usually
41 '.' (but on many systems '.' is used for other things). We put the
42 current defined CPLUS_MARKER first (which defaults to '$'), followed
43 by the next most common value, followed by an explicit '$' in case
44 the value of CPLUS_MARKER is not '$'.
46 We could avoid this if we could just get g++ to tell us what the actual
47 cplus marker character is as part of the debug information, perhaps by
48 ensuring that it is the character that terminates the gcc<n>_compiled
49 marker symbol (FIXME). */
51 #if !defined (CPLUS_MARKER)
52 #define CPLUS_MARKER '$'
55 static const char cplus_markers
[] = { CPLUS_MARKER
, '.', '$', '\0' };
61 /* Stuff that is shared between sub-routines.
62 * Using a shared structure allows cplus_demangle to be reentrant. */
72 int static_type
; /* A static member function */
73 int const_type
; /* A const member function */
76 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
77 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
79 static const struct optable
85 "nw", " new", DMGL_ANSI
, /* new (1.92, ansi) */
86 "dl", " delete", DMGL_ANSI
, /* new (1.92, ansi) */
87 "new", " new", 0, /* old (1.91, and 1.x) */
88 "delete", " delete", 0, /* old (1.91, and 1.x) */
89 "as", "=", DMGL_ANSI
, /* ansi */
90 "ne", "!=", DMGL_ANSI
, /* old, ansi */
91 "eq", "==", DMGL_ANSI
, /* old, ansi */
92 "ge", ">=", DMGL_ANSI
, /* old, ansi */
93 "gt", ">", DMGL_ANSI
, /* old, ansi */
94 "le", "<=", DMGL_ANSI
, /* old, ansi */
95 "lt", "<", DMGL_ANSI
, /* old, ansi */
96 "plus", "+", 0, /* old */
97 "pl", "+", DMGL_ANSI
, /* ansi */
98 "apl", "+=", DMGL_ANSI
, /* ansi */
99 "minus", "-", 0, /* old */
100 "mi", "-", DMGL_ANSI
, /* ansi */
101 "ami", "-=", DMGL_ANSI
, /* ansi */
102 "mult", "*", 0, /* old */
103 "ml", "*", DMGL_ANSI
, /* ansi */
104 "amu", "*=", DMGL_ANSI
, /* ansi (ARM/Lucid) */
105 "aml", "*=", DMGL_ANSI
, /* ansi (GNU/g++) */
106 "convert", "+", 0, /* old (unary +) */
107 "negate", "-", 0, /* old (unary -) */
108 "trunc_mod", "%", 0, /* old */
109 "md", "%", DMGL_ANSI
, /* ansi */
110 "amd", "%=", DMGL_ANSI
, /* ansi */
111 "trunc_div", "/", 0, /* old */
112 "dv", "/", DMGL_ANSI
, /* ansi */
113 "adv", "/=", DMGL_ANSI
, /* ansi */
114 "truth_andif", "&&", 0, /* old */
115 "aa", "&&", DMGL_ANSI
, /* ansi */
116 "truth_orif", "||", 0, /* old */
117 "oo", "||", DMGL_ANSI
, /* ansi */
118 "truth_not", "!", 0, /* old */
119 "nt", "!", DMGL_ANSI
, /* ansi */
120 "postincrement","++", 0, /* old */
121 "pp", "++", DMGL_ANSI
, /* ansi */
122 "postdecrement","--", 0, /* old */
123 "mm", "--", DMGL_ANSI
, /* ansi */
124 "bit_ior", "|", 0, /* old */
125 "or", "|", DMGL_ANSI
, /* ansi */
126 "aor", "|=", DMGL_ANSI
, /* ansi */
127 "bit_xor", "^", 0, /* old */
128 "er", "^", DMGL_ANSI
, /* ansi */
129 "aer", "^=", DMGL_ANSI
, /* ansi */
130 "bit_and", "&", 0, /* old */
131 "ad", "&", DMGL_ANSI
, /* ansi */
132 "aad", "&=", DMGL_ANSI
, /* ansi */
133 "bit_not", "~", 0, /* old */
134 "co", "~", DMGL_ANSI
, /* ansi */
135 "call", "()", 0, /* old */
136 "cl", "()", DMGL_ANSI
, /* ansi */
137 "alshift", "<<", 0, /* old */
138 "ls", "<<", DMGL_ANSI
, /* ansi */
139 "als", "<<=", DMGL_ANSI
, /* ansi */
140 "arshift", ">>", 0, /* old */
141 "rs", ">>", DMGL_ANSI
, /* ansi */
142 "ars", ">>=", DMGL_ANSI
, /* ansi */
143 "component", "->", 0, /* old */
144 "pt", "->", DMGL_ANSI
, /* ansi; Lucid C++ form */
145 "rf", "->", DMGL_ANSI
, /* ansi; ARM/GNU form */
146 "indirect", "*", 0, /* old */
147 "method_call", "->()", 0, /* old */
148 "addr", "&", 0, /* old (unary &) */
149 "array", "[]", 0, /* old */
150 "vc", "[]", DMGL_ANSI
, /* ansi */
151 "compound", ", ", 0, /* old */
152 "cm", ", ", DMGL_ANSI
, /* ansi */
153 "cond", "?:", 0, /* old */
154 "cn", "?:", DMGL_ANSI
, /* psuedo-ansi */
155 "max", ">?", 0, /* old */
156 "mx", ">?", DMGL_ANSI
, /* psuedo-ansi */
157 "min", "<?", 0, /* old */
158 "mn", "<?", DMGL_ANSI
, /* psuedo-ansi */
159 "nop", "", 0, /* old (for operator=) */
160 "rm", "->*", DMGL_ANSI
, /* ansi */
164 typedef struct string
/* Beware: these aren't required to be */
165 { /* '\0' terminated. */
166 char *b
; /* pointer to start of string */
167 char *p
; /* pointer after last character */
168 char *e
; /* pointer after end of allocated space */
171 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
172 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
173 string_prepend(str, " ");}
174 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
175 string_append(str, " ");}
177 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/cfront virtual table prefix */
178 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
180 /* Prototypes for local functions */
183 mop_up
PARAMS ((struct work_stuff
*, string
*, int));
187 demangle_method_args
PARAMS ((struct work_stuff
*work
, const char **, string
*));
191 demangle_template
PARAMS ((struct work_stuff
*work
, const char **, string
*));
194 demangle_qualified
PARAMS ((struct work_stuff
*, const char **, string
*,
198 demangle_class
PARAMS ((struct work_stuff
*, const char **, string
*));
201 demangle_fund_type
PARAMS ((struct work_stuff
*, const char **, string
*));
204 demangle_signature
PARAMS ((struct work_stuff
*, const char **, string
*));
207 demangle_prefix
PARAMS ((struct work_stuff
*, const char **, string
*));
210 gnu_special
PARAMS ((struct work_stuff
*, const char **, string
*));
213 cfront_special
PARAMS ((struct work_stuff
*, const char **, string
*));
216 string_need
PARAMS ((string
*, int));
219 string_delete
PARAMS ((string
*));
222 string_init
PARAMS ((string
*));
225 string_clear
PARAMS ((string
*));
229 string_empty
PARAMS ((string
*));
233 string_append
PARAMS ((string
*, const char *));
236 string_appends
PARAMS ((string
*, string
*));
239 string_appendn
PARAMS ((string
*, const char *, int));
242 string_prepend
PARAMS ((string
*, const char *));
245 string_prependn
PARAMS ((string
*, const char *, int));
248 get_count
PARAMS ((const char **, int *));
251 consume_count
PARAMS ((const char **));
254 demangle_args
PARAMS ((struct work_stuff
*, const char **, string
*));
257 do_type
PARAMS ((struct work_stuff
*, const char **, string
*));
260 do_arg
PARAMS ((struct work_stuff
*, const char **, string
*));
263 demangle_function_name
PARAMS ((struct work_stuff
*, const char **, string
*,
267 remember_type
PARAMS ((struct work_stuff
*, const char *, int));
270 forget_types
PARAMS ((struct work_stuff
*));
274 string_prepends
PARAMS ((string
*, string
*));
277 /* Translate count to integer, consuming tokens in the process.
278 Conversion terminates on the first non-digit character. */
289 count
+= **type
- '0';
291 } while (isdigit (**type
));
295 /* Takes operator name as e.g. "++" and returns mangled
296 operator name (e.g. "postincrement_expr"), or NULL if not found.
298 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
299 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
302 cplus_mangle_opname (opname
, options
)
309 len
= strlen (opname
);
310 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
312 if (strlen (optable
[i
].out
) == len
313 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
314 && memcmp (optable
[i
].out
, opname
, len
) == 0)
315 return ((char *)optable
[i
].in
);
320 /* char *cplus_demangle (const char *name, int options)
322 If NAME is a mangled function name produced by GNU C++, then
323 a pointer to a malloced string giving a C++ representation
324 of the name will be returned; otherwise NULL will be returned.
325 It is the caller's responsibility to free the string which
328 The OPTIONS arg may contain one or more of the following bits:
330 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
332 DMGL_PARAMS Function parameters are included.
336 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
337 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
338 cplus_demangle ("foo__1Ai", 0) => "A::foo"
340 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
341 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
342 cplus_demangle ("foo__1Afe", 0) => "A::foo"
344 Note that any leading underscores, or other such characters prepended by
345 the compilation system, are presumed to have already been stripped from
349 cplus_demangle (mangled
, options
)
355 struct work_stuff work
[1];
356 char *demangled
= NULL
;
358 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
360 memset ((char *) work
, 0, sizeof (work
));
361 work
-> options
= options
;
365 /* First check to see if gnu style demangling is active and if the
366 string to be demangled contains a CPLUS_MARKER. If so, attempt to
367 recognize one of the gnu special forms rather than looking for a
368 standard prefix. In particular, don't worry about whether there
369 is a "__" string in the mangled string. Consider "_$_5__foo" for
372 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
)
373 && (strpbrk (mangled
, cplus_markers
)) != NULL
)
375 success
= gnu_special (work
, &mangled
, &decl
);
379 success
= demangle_prefix (work
, &mangled
, &decl
);
381 if (success
&& (*mangled
!= '\0'))
383 success
= demangle_signature (work
, &mangled
, &decl
);
385 demangled
= mop_up (work
, &decl
, success
);
391 mop_up (work
, declp
, success
)
392 struct work_stuff
*work
;
397 char *demangled
= NULL
;
399 /* Discard the remembered types, if any. */
402 if (work
-> typevec
!= NULL
)
404 free ((char *) work
-> typevec
);
407 /* If demangling was successful, ensure that the demangled string is null
408 terminated and return it. Otherwise, free the demangling decl. */
412 string_delete (declp
);
416 string_appendn (declp
, "", 1);
417 demangled
= declp
-> b
;
426 demangle_signature -- demangle the signature part of a mangled name
431 demangle_signature (struct work_stuff *work, const char **mangled,
436 Consume and demangle the signature portion of the mangled name.
438 DECLP is the string where demangled output is being built. At
439 entry it contains the demangled root name from the mangled name
440 prefix. I.E. either a demangled operator name or the root function
441 name. In some special cases, it may contain nothing.
443 *MANGLED points to the current unconsumed location in the mangled
444 name. As tokens are consumed and demangling is performed, the
445 pointer is updated to continuously point at the next token to
448 Demangling GNU style mangled names is nasty because there is no
449 explicit token that marks the start of the outermost function
454 demangle_signature (work
, mangled
, declp
)
455 struct work_stuff
*work
;
456 const char **mangled
;
462 const char *oldmangled
;
464 while (success
&& (**mangled
!= '\0'))
469 oldmangled
= *mangled
;
470 success
= demangle_qualified (work
, mangled
, declp
, 1);
473 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
475 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
482 /* Static member function */
484 work
-> static_type
= 1;
488 /* a const member function */
490 work
-> const_type
= 1;
493 case '0': case '1': case '2': case '3': case '4':
494 case '5': case '6': case '7': case '8': case '9':
495 oldmangled
= *mangled
;
496 success
= demangle_class (work
, mangled
, declp
);
499 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
501 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
509 /* ARM style demangling includes a specific 'F' character after
510 the class name. For GNU style, it is just implied. So we can
511 safely just consume any 'F' at this point and be compatible
512 with either style. */
517 /* For lucid/cfront style we have to forget any types we might
518 have remembered up to this point, since they were not argument
519 types. GNU style considers all types seen as available for
520 back references. See comment in demangle_args() */
522 if (LUCID_DEMANGLING
|| CFRONT_DEMANGLING
)
526 success
= demangle_args (work
, mangled
, declp
);
531 success
= demangle_template (work
, mangled
, declp
);
535 /* At the outermost level, we cannot have a return type specified,
536 so if we run into another '_' at this point we are dealing with
537 a mangled name that is either bogus, or has been mangled by
538 some algorithm we don't know how to deal with. So just
539 reject the entire demangling. */
544 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
546 /* Assume we have stumbled onto the first outermost function
547 argument token, and start processing args. */
549 success
= demangle_args (work
, mangled
, declp
);
553 /* Non-GNU demanglers use a specific token to mark the start
554 of the outermost function argument tokens. Typically 'F',
555 for ARM-demangling, for example. So if we find something
556 we are not prepared for, it must be an error. */
561 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
563 if (success
&& expect_func
)
566 success
= demangle_args (work
, mangled
, declp
);
570 if (success
&& !func_done
)
572 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
574 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
575 bar__3fooi is 'foo::bar(int)'. We get here when we find the
576 first case, and need to ensure that the '(void)' gets added to
577 the current declp. Note that with ARM, the first case
578 represents the name of a static data member 'foo::bar',
579 which is in the current declp, so we leave it alone. */
580 success
= demangle_args (work
, mangled
, declp
);
583 if (success
&& work
-> static_type
&& PRINT_ARG_TYPES
)
585 string_append (declp
, " static");
587 if (success
&& work
-> const_type
&& PRINT_ARG_TYPES
)
589 string_append (declp
, " const");
597 demangle_method_args (work
, mangled
, declp
)
598 struct work_stuff
*work
;
599 const char **mangled
;
604 if (work
-> static_type
)
606 string_append (declp
, *mangled
+ 1);
607 *mangled
+= strlen (*mangled
);
612 success
= demangle_args (work
, mangled
, declp
);
620 demangle_template (work
, mangled
, declp
)
621 struct work_stuff
*work
;
622 const char **mangled
;
640 string_init (&tname
);
641 string_init (&trawname
);
642 /* get template name */
643 if (!get_count (mangled
, &r
))
647 string_appendn (&tname
, *mangled
, r
);
648 string_appendn (&trawname
, *mangled
, r
);
649 string_appendn (&trawname
, "", 1);
651 string_append (&tname
, "<");
652 /* get size of template parameter list */
653 if (!get_count (mangled
, &r
))
657 for (i
= 0; i
< r
; i
++)
661 string_append (&tname
, ", ");
663 /* Z for type parameters */
664 if (**mangled
== 'Z')
667 success
= do_type (work
, mangled
, &temp
);
668 string_appendn (&temp
, "", 1);
671 string_append (&tname
, temp
.b
);
673 string_delete(&temp
);
681 /* otherwise, value parameter */
687 success
= do_type (work
, mangled
, &temp
);
688 string_appendn (&temp
, "", 1);
691 string_append (&tname
, temp
.b
);
693 string_delete(&temp
);
698 string_append (&tname
, "=");
699 while (*old_p
&& !done
)
705 done
= is_pointer
= 1;
707 case 'C': /* const */
708 case 'S': /* explicitly signed [char] */
709 case 'U': /* unsigned */
710 case 'V': /* volatile */
711 case 'F': /* function */
712 case 'M': /* member function */
716 case 'Q': /* repetition of following */
717 case 'T': /* remembered type */
723 case 'x': /* long long */
726 case 's': /* short */
728 done
= is_integral
= 1;
730 case 'r': /* long double */
731 case 'd': /* double */
732 case 'f': /* float */
741 if (**mangled
== 'm')
743 string_appendn (&tname
, "-", 1);
746 while (isdigit (**mangled
))
748 string_appendn (&tname
, *mangled
, 1);
754 if (**mangled
== 'm')
756 string_appendn (&tname
, "-", 1);
759 while (isdigit (**mangled
))
761 string_appendn (&tname
, *mangled
, 1);
764 if (**mangled
== '.') /* fraction */
766 string_appendn (&tname
, ".", 1);
768 while (isdigit (**mangled
))
770 string_appendn (&tname
, *mangled
, 1);
774 if (**mangled
== 'e') /* exponent */
776 string_appendn (&tname
, "e", 1);
778 while (isdigit (**mangled
))
780 string_appendn (&tname
, *mangled
, 1);
787 if (!get_count (mangled
, &symbol_len
))
792 string_appendn (&tname
, *mangled
, symbol_len
);
793 *mangled
+= symbol_len
;
798 string_append (&tname
, ">::");
799 if (work
-> destructor
)
801 string_append (&tname
, "~");
803 if (work
-> constructor
|| work
-> destructor
)
805 string_append (&tname
, trawname
.b
);
807 string_delete(&trawname
);
811 string_delete(&tname
);
815 string_prepend (declp
, tname
.b
);
816 string_delete (&tname
);
818 if (work
-> static_type
)
820 string_append (declp
, *mangled
+ 1);
821 *mangled
+= strlen (*mangled
);
826 success
= demangle_args (work
, mangled
, declp
);
836 demangle_class -- demangle a mangled class sequence
841 demangle_class (struct work_stuff *work, const char **mangled,
846 DECLP points to the buffer into which demangling is being done.
848 *MANGLED points to the current token to be demangled. On input,
849 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
850 On exit, it points to the next token after the mangled class on
851 success, or the first unconsumed token on failure.
853 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
854 we are demangling a constructor or destructor. In this case
855 we prepend "class::class" or "class::~class" to DECLP.
857 Otherwise, we prepend "class::" to the current DECLP.
859 Reset the constructor/destructor flags once they have been
860 "consumed". This allows demangle_class to be called later during
861 the same demangling, to do normal class demangling.
863 Returns 1 if demangling is successful, 0 otherwise.
868 demangle_class (work
, mangled
, declp
)
869 struct work_stuff
*work
;
870 const char **mangled
;
876 n
= consume_count (mangled
);
877 if (strlen (*mangled
) >= n
)
879 if (work
-> constructor
|| work
-> destructor
)
881 string_prependn (declp
, *mangled
, n
);
882 if (work
-> destructor
)
884 string_prepend (declp
, "~");
886 work
-> constructor
= work
-> destructor
= 0;
888 string_prepend (declp
, "::");
889 string_prependn (declp
, *mangled
, n
);
900 demangle_prefix -- consume the mangled name prefix and find signature
905 demangle_prefix (struct work_stuff *work, const char **mangled,
910 Consume and demangle the prefix of the mangled name.
912 DECLP points to the string buffer into which demangled output is
913 placed. On entry, the buffer is empty. On exit it contains
914 the root function name, the demangled operator name, or in some
915 special cases either nothing or the completely demangled result.
917 MANGLED points to the current pointer into the mangled name. As each
918 token of the mangled name is consumed, it is updated. Upon entry
919 the current mangled name pointer points to the first character of
920 the mangled name. Upon exit, it should point to the first character
921 of the signature if demangling was successful, or to the first
922 unconsumed character if demangling of the prefix was unsuccessful.
924 Returns 1 on success, 0 otherwise.
928 demangle_prefix (work
, mangled
, declp
)
929 struct work_stuff
*work
;
930 const char **mangled
;
937 scan
= strstr (*mangled
, "__");
941 /* We found a sequence of two or more '_', ensure that we start at
942 the last pair in the sequence. */
943 i
= strspn (scan
, "_");
954 else if (work
-> static_type
)
956 if (!isdigit (scan
[0]) && (scan
[0] != 't'))
961 else if ((scan
== *mangled
) && (isdigit (scan
[2]) || (scan
[2] == 'Q')))
963 /* A GNU style constructor starts with "__<digit>" or "__Q". */
964 work
-> constructor
= 1;
967 else if ((scan
== *mangled
) && !isdigit (scan
[2]) && (scan
[2] != 't'))
969 /* Mangled name starts with "__". Skip over any leading '_' characters,
970 then find the next "__" that separates the prefix from the signature.
972 if (!(CFRONT_DEMANGLING
|| LUCID_DEMANGLING
)
973 || (cfront_special (work
, mangled
, declp
) == 0))
979 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
981 /* No separator (I.E. "__not_mangled"), or empty signature
982 (I.E. "__not_mangled_either__") */
987 demangle_function_name (work
, mangled
, declp
, scan
);
991 else if (*(scan
+ 2) != '\0')
993 /* Mangled name does not start with "__" but does have one somewhere
994 in there with non empty stuff after it. Looks like a global
996 demangle_function_name (work
, mangled
, declp
, scan
);
1000 /* Doesn't look like a mangled name */
1010 gnu_special -- special handling of gnu mangled strings
1015 gnu_special (struct work_stuff *work, const char **mangled,
1021 Process some special GNU style mangling forms that don't fit
1022 the normal pattern. For example:
1024 _$_3foo (destructor for class foo)
1025 _vt$foo (foo virtual table)
1026 _vt$foo$bar (foo::bar virtual table)
1027 _3foo$varname (static data member)
1031 gnu_special (work
, mangled
, declp
)
1032 struct work_stuff
*work
;
1033 const char **mangled
;
1040 if ((*mangled
)[0] == '_'
1041 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
1042 && (*mangled
)[2] == '_')
1044 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1046 work
-> destructor
= 1;
1048 else if ((*mangled
)[0] == '_'
1049 && (*mangled
)[1] == 'v'
1050 && (*mangled
)[2] == 't'
1051 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)
1053 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1054 and create the decl. Note that we consume the entire mangled
1055 input string, which means that demangle_signature has no work
1058 while (**mangled
!= '\0')
1060 n
= strcspn (*mangled
, cplus_markers
);
1061 string_appendn (declp
, *mangled
, n
);
1063 if (**mangled
!= '\0')
1065 string_append (declp
, "::");
1069 string_append (declp
, " virtual table");
1071 else if ((*mangled
)[0] == '_'
1072 && isdigit ((*mangled
)[1])
1073 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
1075 /* static data member, "_3foo$varname" for example */
1078 n
= consume_count (mangled
);
1079 string_appendn (declp
, *mangled
, n
);
1080 string_append (declp
, "::");
1082 string_appendn (declp
, p
, n
);
1096 cfront_special -- special handling of cfront/lucid mangled strings
1101 cfront_special (struct work_stuff *work, const char **mangled,
1107 Process some special cfront style mangling forms that don't fit
1108 the normal pattern. For example:
1110 __vtbl__3foo (foo virtual table)
1111 __vtbl__3foo__3bar (bar::foo virtual table)
1116 cfront_special (work
, mangled
, declp
)
1117 struct work_stuff
*work
;
1118 const char **mangled
;
1126 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
1128 /* Found a cfront style virtual table, get past ARM_VTABLE_STRING
1129 and create the decl. Note that we consume the entire mangled
1130 input string, which means that demangle_signature has no work
1132 (*mangled
) += ARM_VTABLE_STRLEN
;
1133 while (**mangled
!= '\0')
1135 n
= consume_count (mangled
);
1136 string_prependn (declp
, *mangled
, n
);
1138 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
1140 string_prepend (declp
, "::");
1144 string_append (declp
, " virtual table");
1157 demangle_qualified -- demangle 'Q' qualified name strings
1162 demangle_qualified (struct work_stuff *, const char *mangled,
1163 string *result, int isfuncname);
1167 Demangle a qualified name, such as "Q25Outer5Inner" which is
1168 the mangled form of "Outer::Inner". The demangled output is
1169 appended to the result string.
1171 If isfuncname is nonzero, then the qualified name we are building
1172 is going to be used as a member function name, so if it is a
1173 constructor or destructor function, append an appropriate
1174 constructor or destructor name. I.E. for the above example,
1175 the result for use as a constructor is "Outer::Inner::Inner"
1176 and the result for use as a destructor is "Outer::Inner::~Inner".
1180 Numeric conversion is ASCII dependent (FIXME).
1185 demangle_qualified (work
, mangled
, result
, isfuncname
)
1186 struct work_stuff
*work
;
1187 const char **mangled
;
1195 qualifiers
= (*mangled
)[1] - '0';
1196 if (qualifiers
> 0 && qualifiers
< 10)
1198 /* Assume success until we discover otherwise. Skip over the 'Q', the
1199 qualifier count, and any '_' between the qualifier count and the
1200 first name (cfront qualified names). */
1203 if ((*mangled
)[2] == '_')
1210 /* Pick off the names and append them to the result string as they
1211 are found, separated by '::'. */
1213 while (qualifiers
-- > 0)
1215 namelength
= consume_count (mangled
);
1216 if (strlen (*mangled
) < namelength
)
1218 /* Simple sanity check failed */
1222 string_appendn (result
, *mangled
, namelength
);
1225 string_appendn (result
, "::", 2);
1227 *mangled
+= namelength
;
1230 /* If we are using the result as a function name, we need to append
1231 the appropriate '::' separated constructor or destructor name.
1232 We do this here because this is the most convenient place, where
1233 we already have a pointer to the name and the length of the name. */
1235 if (isfuncname
&& (work
-> constructor
|| work
-> destructor
))
1237 string_appendn (result
, "::", 2);
1238 if (work
-> destructor
)
1240 string_append (result
, "~");
1242 string_appendn (result
, (*mangled
) - namelength
, namelength
);
1252 get_count -- convert an ascii count to integer, consuming tokens
1257 get_count (const char **type, int *count)
1261 Return 0 if no conversion is performed, 1 if a string is converted.
1265 get_count (type
, count
)
1272 if (!isdigit (**type
))
1278 *count
= **type
- '0';
1280 if (isdigit (**type
))
1290 while (isdigit (*p
));
1301 /* result will be initialised here; it will be freed on failure */
1304 do_type (work
, mangled
, result
)
1305 struct work_stuff
*work
;
1306 const char **mangled
;
1313 const char *remembered_type
;
1317 string_init (&decl
);
1318 string_init (result
);
1322 while (success
&& !done
)
1328 /* A pointer type */
1331 string_prepend (&decl
, "*");
1334 /* A reference type */
1337 string_prepend (&decl
, "&");
1340 /* A back reference to a previously seen type */
1343 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
1349 remembered_type
= work
-> typevec
[n
];
1350 mangled
= &remembered_type
;
1357 if (!STRING_EMPTY (&decl
) && decl
.b
[0] == '*')
1359 string_prepend (&decl
, "(");
1360 string_append (&decl
, ")");
1362 /* After picking off the function args, we expect to either find the
1363 function return type (preceded by an '_') or the end of the
1365 if (!demangle_args (work
, mangled
, &decl
)
1366 || (**mangled
!= '_' && **mangled
!= '\0'))
1370 if (success
&& (**mangled
== '_'))
1382 member
= **mangled
== 'M';
1384 if (!isdigit (**mangled
))
1389 n
= consume_count (mangled
);
1390 if (strlen (*mangled
) < n
)
1395 string_append (&decl
, ")");
1396 string_prepend (&decl
, "::");
1397 string_prependn (&decl
, *mangled
, n
);
1398 string_prepend (&decl
, "(");
1402 if (**mangled
== 'C')
1407 if (**mangled
== 'V')
1412 if (*(*mangled
)++ != 'F')
1418 if ((member
&& !demangle_args (work
, mangled
, &decl
))
1419 || **mangled
!= '_')
1425 if (! PRINT_ANSI_QUALIFIERS
)
1431 APPEND_BLANK (&decl
);
1432 string_append (&decl
, "const");
1436 APPEND_BLANK (&decl
);
1437 string_append (&decl
, "volatile");
1443 if ((*mangled
)[1] == 'P')
1446 if (PRINT_ANSI_QUALIFIERS
)
1448 if (!STRING_EMPTY (&decl
))
1450 string_prepend (&decl
, " ");
1452 string_prepend (&decl
, "const");
1466 /* A qualified name, such as "Outer::Inner". */
1468 success
= demangle_qualified (work
, mangled
, result
, 0);
1472 success
= demangle_fund_type (work
, mangled
, result
);
1478 if (!STRING_EMPTY (&decl
))
1480 string_append (result
, " ");
1481 string_appends (result
, &decl
);
1486 string_delete (result
);
1488 string_delete (&decl
);
1492 /* Given a pointer to a type string that represents a fundamental type
1493 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
1494 string in which the demangled output is being built in RESULT, and
1495 the WORK structure, decode the types and add them to the result.
1500 "Sl" => "signed long"
1501 "CUs" => "const unsigned short"
1506 demangle_fund_type (work
, mangled
, result
)
1507 struct work_stuff
*work
;
1508 const char **mangled
;
1515 /* First pick off any type qualifiers. There can be more than one. */
1523 if (PRINT_ANSI_QUALIFIERS
)
1525 APPEND_BLANK (result
);
1526 string_append (result
, "const");
1531 APPEND_BLANK (result
);
1532 string_append (result
, "unsigned");
1534 case 'S': /* signed char only */
1536 APPEND_BLANK (result
);
1537 string_append (result
, "signed");
1541 if (PRINT_ANSI_QUALIFIERS
)
1543 APPEND_BLANK (result
);
1544 string_append (result
, "volatile");
1553 /* Now pick off the fundamental type. There can be only one. */
1562 APPEND_BLANK (result
);
1563 string_append (result
, "void");
1567 APPEND_BLANK (result
);
1568 string_append (result
, "long long");
1572 APPEND_BLANK (result
);
1573 string_append (result
, "long");
1577 APPEND_BLANK (result
);
1578 string_append (result
, "int");
1582 APPEND_BLANK (result
);
1583 string_append (result
, "short");
1587 APPEND_BLANK (result
);
1588 string_append (result
, "char");
1592 APPEND_BLANK (result
);
1593 string_append (result
, "long double");
1597 APPEND_BLANK (result
);
1598 string_append (result
, "double");
1602 APPEND_BLANK (result
);
1603 string_append (result
, "float");
1607 if (!isdigit (**mangled
))
1613 /* An explicit type, such as "6mytype" or "7integer" */
1624 n
= consume_count (mangled
);
1625 if (strlen (*mangled
) < n
)
1630 APPEND_BLANK (result
);
1631 string_appendn (result
, *mangled
, n
);
1642 /* `result' will be initialized in do_type; it will be freed on failure */
1645 do_arg (work
, mangled
, result
)
1646 struct work_stuff
*work
;
1647 const char **mangled
;
1650 const char *start
= *mangled
;
1652 if (!do_type (work
, mangled
, result
))
1658 remember_type (work
, start
, *mangled
- start
);
1664 remember_type (work
, start
, len
)
1665 struct work_stuff
*work
;
1671 if (work
-> ntypes
>= work
-> typevec_size
)
1673 if (work
-> typevec_size
== 0)
1675 work
-> typevec_size
= 3;
1677 (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
1681 work
-> typevec_size
*= 2;
1683 (char **) xrealloc ((char *)work
-> typevec
,
1684 sizeof (char *) * work
-> typevec_size
);
1687 tem
= (char *) xmalloc (len
+ 1);
1688 memcpy (tem
, start
, len
);
1690 work
-> typevec
[work
-> ntypes
++] = tem
;
1693 /* Forget the remembered types, but not the type vector itself. */
1697 struct work_stuff
*work
;
1701 while (work
-> ntypes
> 0)
1703 i
= --(work
-> ntypes
);
1704 if (work
-> typevec
[i
] != NULL
)
1706 free (work
-> typevec
[i
]);
1707 work
-> typevec
[i
] = NULL
;
1712 /* Process the argument list part of the signature, after any class spec
1713 has been consumed, as well as the first 'F' character (if any). For
1716 "__als__3fooRT0" => process "RT0"
1717 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
1719 DECLP must be already initialised, usually non-empty. It won't be freed
1722 Note that g++ differs significantly from cfront and lucid style mangling
1723 with regards to references to previously seen types. For example, given
1724 the source fragment:
1728 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
1731 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
1732 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
1734 g++ produces the names:
1739 while lcc (and presumably cfront as well) produces:
1741 foo__FiR3fooT1T2T1T2
1742 __ct__3fooFiR3fooT1T2T1T2
1744 Note that g++ bases it's type numbers starting at zero and counts all
1745 previously seen types, while lucid/cfront bases it's type numbers starting
1746 at one and only considers types after it has seen the 'F' character
1747 indicating the start of the function args. For lucid/cfront style, we
1748 account for this difference by discarding any previously seen types when
1749 we see the 'F' character, and subtracting one from the type number
1755 demangle_args (work
, mangled
, declp
)
1756 struct work_stuff
*work
;
1757 const char **mangled
;
1767 if (PRINT_ARG_TYPES
)
1769 string_append (declp
, "(");
1770 if (**mangled
== '\0')
1772 string_append (declp
, "void");
1776 while (**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
1778 if ((**mangled
== 'N') || (**mangled
== 'T'))
1780 temptype
= *(*mangled
)++;
1782 if (temptype
== 'N')
1784 if (!get_count (mangled
, &r
))
1793 if (!get_count (mangled
, &t
))
1797 if (LUCID_DEMANGLING
|| CFRONT_DEMANGLING
)
1801 /* Validate the type index. Protect against illegal indices from
1802 malformed type strings. */
1803 if ((t
< 0) || (t
>= work
-> ntypes
))
1809 tem
= work
-> typevec
[t
];
1810 if (need_comma
&& PRINT_ARG_TYPES
)
1812 string_append (declp
, ", ");
1814 if (!do_arg (work
, &tem
, &arg
))
1818 if (PRINT_ARG_TYPES
)
1820 string_appends (declp
, &arg
);
1822 string_delete (&arg
);
1828 if (need_comma
& PRINT_ARG_TYPES
)
1830 string_append (declp
, ", ");
1832 if (!do_arg (work
, mangled
, &arg
))
1836 if (PRINT_ARG_TYPES
)
1838 string_appends (declp
, &arg
);
1840 string_delete (&arg
);
1845 if (**mangled
== 'e')
1848 if (PRINT_ARG_TYPES
)
1852 string_append (declp
, ",");
1854 string_append (declp
, "...");
1858 if (PRINT_ARG_TYPES
)
1860 string_append (declp
, ")");
1866 demangle_function_name (work
, mangled
, declp
, scan
)
1867 struct work_stuff
*work
;
1868 const char **mangled
;
1877 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
1878 string_need (declp
, 1);
1879 *(declp
-> p
) = '\0';
1881 /* Consume the function name, including the "__" separating the name
1882 from the signature. We are guaranteed that SCAN points to the
1885 (*mangled
) = scan
+ 2;
1887 if (LUCID_DEMANGLING
|| CFRONT_DEMANGLING
)
1890 /* See if we have an ARM style constructor or destructor operator.
1891 If so, then just record it, clear the decl, and return.
1892 We can't build the actual constructor/destructor decl until later,
1893 when we recover the class name from the signature. */
1895 if (strcmp (declp
-> b
, "__ct") == 0)
1897 work
-> constructor
= 1;
1898 string_clear (declp
);
1901 else if (strcmp (declp
-> b
, "__dt") == 0)
1903 work
-> destructor
= 1;
1904 string_clear (declp
);
1909 if (declp
->p
- declp
->b
>= 3
1910 && declp
->b
[0] == 'o'
1911 && declp
->b
[1] == 'p'
1912 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
1914 /* see if it's an assignment expression */
1915 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
1916 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
1918 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1920 len
= declp
->p
- declp
->b
- 10;
1921 if (strlen (optable
[i
].in
) == len
1922 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
1924 string_clear (declp
);
1925 string_append (declp
, "operator");
1926 string_append (declp
, optable
[i
].out
);
1927 string_append (declp
, "=");
1934 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1936 int len
= declp
->p
- declp
->b
- 3;
1937 if (strlen (optable
[i
].in
) == len
1938 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
1940 string_clear (declp
);
1941 string_append (declp
, "operator");
1942 string_append (declp
, optable
[i
].out
);
1948 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type$", 5) == 0)
1950 /* type conversion operator */
1952 if (do_type (work
, &tem
, &type
))
1954 string_clear (declp
);
1955 string_append (declp
, "operator ");
1956 string_appends (declp
, &type
);
1957 string_delete (&type
);
1960 else if (declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
1963 /* type conversion operator. */
1965 if (do_type (work
, &tem
, &type
))
1967 string_clear (declp
);
1968 string_append (declp
, "operator ");
1969 string_appends (declp
, &type
);
1970 string_delete (&type
);
1973 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
1974 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
1975 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
1977 if (declp
->b
[4] == '\0')
1980 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1982 if (strlen (optable
[i
].in
) == 2
1983 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
1985 string_clear (declp
);
1986 string_append (declp
, "operator");
1987 string_append (declp
, optable
[i
].out
);
1994 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
1997 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1999 if (strlen (optable
[i
].in
) == 3
2000 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
2002 string_clear (declp
);
2003 string_append (declp
, "operator");
2004 string_append (declp
, optable
[i
].out
);
2013 /* a mini string-handling package */
2028 s
->p
= s
->b
= (char *) xmalloc (n
);
2031 else if (s
->e
- s
->p
< n
)
2036 s
->b
= (char *) xrealloc (s
->b
, n
);
2049 s
->b
= s
->e
= s
->p
= NULL
;
2057 s
->b
= s
->p
= s
->e
= NULL
;
2073 return (s
->b
== s
->p
);
2079 string_append (p
, s
)
2084 if (s
== NULL
|| *s
== '\0')
2088 memcpy (p
->p
, s
, n
);
2093 string_appends (p
, s
)
2102 memcpy (p
->p
, s
->b
, n
);
2108 string_appendn (p
, s
, n
)
2116 memcpy (p
->p
, s
, n
);
2122 string_prepend (p
, s
)
2126 if (s
!= NULL
&& *s
!= '\0')
2128 string_prependn (p
, s
, strlen (s
));
2135 string_prepends (p
, s
)
2140 string_prependn (p
, s
->b
, s
->p
- s
->b
);
2147 string_prependn (p
, s
, n
)
2157 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
2161 memcpy (p
->b
, s
, n
);
2166 /* To generate a standalone demangler program for testing purposes, just
2167 compile and link this file with -DMAIN. When run, it demangles each
2168 command line arg, or each stdin string, and prints the result on stdout. */
2173 demangle_it (mangled_name
)
2178 result
= cplus_demangle (mangled_name
, DMGL_PARAMS
| DMGL_ANSI
);
2181 printf ("%s\n", mangled_name
);
2185 printf ("%s\n", result
);
2196 if ((newmem
= malloc ((int) size
)) == NULL
)
2198 fprintf (stderr
, "\nCan't allocate %u bytes\n", size
);
2205 xrealloc (oldmem
, size
)
2211 if ((newmem
= realloc ((char *) oldmem
, (int) size
)) == NULL
)
2213 fprintf (stderr
, "\nCan't reallocate %u bytes\n", size
);
2221 enum demangling_styles current_demangling_style
= gnu_demangling
;
2227 char mangled_name
[128];
2230 extern char *optarg
;
2233 while ((c
= getopt (argc
, argv
, "s:?")) != EOF
)
2238 fprintf (stderr
, "usage: demangle [-s style] [arg1 [arg2]] ...\n");
2239 fprintf (stderr
, "style = { gnu, lucid, cfront }\n");
2240 fprintf (stderr
, "reads args from stdin if none supplied\n");
2244 if (strcmp (optarg
, "gnu") == 0)
2246 current_demangling_style
= gnu_demangling
;
2248 else if (strcmp (optarg
, "lucid") == 0)
2250 current_demangling_style
= lucid_demangling
;
2252 else if (strcmp (optarg
, "cfront") == 0)
2254 current_demangling_style
= cfront_demangling
;
2258 fprintf (stderr
, "unknown demangling style `%s'\n", optarg
);
2266 for ( ; optind
< argc
; optind
++)
2268 demangle_it (argv
[optind
]);
2273 while (gets (mangled_name
))
2275 demangle_it (mangled_name
);