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 ((string
*, struct work_stuff
*, int));
187 demangle_method_args
PARAMS ((string
*, const char **, struct work_stuff
*));
191 demangle_template
PARAMS ((string
*declp
, const char **, struct work_stuff
*));
194 demangle_qualified
PARAMS ((string
*, const char **, struct work_stuff
*));
197 demangle_class
PARAMS ((string
*, const char **, struct work_stuff
*));
200 demangle_fund_type
PARAMS ((const char **, string
*, struct work_stuff
*));
203 demangle_signature
PARAMS ((string
*, const char **, struct work_stuff
*));
206 demangle_prefix
PARAMS ((string
*, const char **, struct work_stuff
*));
209 gnu_special
PARAMS ((string
*, const char **, struct work_stuff
*));
212 cfront_special
PARAMS ((string
*, const char **, struct work_stuff
*));
215 string_need
PARAMS ((string
*, int));
218 string_delete
PARAMS ((string
*));
221 string_init
PARAMS ((string
*));
224 string_clear
PARAMS ((string
*));
228 string_empty
PARAMS ((string
*));
232 string_append
PARAMS ((string
*, const char *));
235 string_appends
PARAMS ((string
*, string
*));
238 string_appendn
PARAMS ((string
*, const char *, int));
241 string_prepend
PARAMS ((string
*, const char *));
244 string_prependn
PARAMS ((string
*, const char *, int));
247 get_count
PARAMS ((const char **, int *));
250 consume_count
PARAMS ((const char **));
253 demangle_args
PARAMS ((string
*, const char **, struct work_stuff
*));
256 do_type
PARAMS ((const char **, string
*, struct work_stuff
*));
259 do_arg
PARAMS ((const char **, string
*, struct work_stuff
*));
262 demangle_function_name
PARAMS ((string
*, const char **, struct work_stuff
*,
266 remember_type
PARAMS ((const char *, int, struct work_stuff
*));
269 forget_types
PARAMS ((struct work_stuff
*));
273 string_prepends
PARAMS ((string
*, string
*));
276 /* Translate count to integer, consuming tokens in the process.
277 Conversion terminates on the first non-digit character. */
288 count
+= **type
- '0';
290 } while (isdigit (**type
));
294 /* Takes operator name as e.g. "++" and returns mangled
295 operator name (e.g. "postincrement_expr"), or NULL if not found.
297 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
298 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
301 cplus_mangle_opname (opname
, options
)
308 len
= strlen (opname
);
309 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
311 if (strlen (optable
[i
].out
) == len
312 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
313 && memcmp (optable
[i
].out
, opname
, len
) == 0)
314 return ((char *)optable
[i
].in
);
319 /* char *cplus_demangle (const char *name, int options)
321 If NAME is a mangled function name produced by GNU C++, then
322 a pointer to a malloced string giving a C++ representation
323 of the name will be returned; otherwise NULL will be returned.
324 It is the caller's responsibility to free the string which
327 The OPTIONS arg may contain one or more of the following bits:
329 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
331 DMGL_PARAMS Function parameters are included.
335 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
336 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
337 cplus_demangle ("foo__1Ai", 0) => "A::foo"
339 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
340 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
341 cplus_demangle ("foo__1Afe", 0) => "A::foo"
343 Note that any leading underscores, or other such characters prepended by
344 the compilation system, are presumed to have already been stripped from
348 cplus_demangle (mangled
, options
)
354 struct work_stuff work
[1];
355 char *demangled
= NULL
;
357 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
359 memset ((char *) work
, 0, sizeof (work
));
360 work
-> options
= options
;
364 /* First check to see if gnu style demangling is active and if the
365 string to be demangled contains a CPLUS_MARKER. If so, attempt to
366 recognize one of the gnu special forms rather than looking for a
367 standard prefix. In particular, don't worry about whether there
368 is a "__" string in the mangled string. Consider "_$_5__foo" for
371 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
)
372 && (strpbrk (mangled
, cplus_markers
)) != NULL
)
374 success
= gnu_special (&decl
, &mangled
, work
);
378 success
= demangle_prefix (&decl
, &mangled
, work
);
380 if (success
&& (*mangled
!= '\0'))
382 success
= demangle_signature (&decl
, &mangled
, work
);
384 demangled
= mop_up (&decl
, work
, success
);
390 mop_up (declp
, work
, success
)
392 struct work_stuff
*work
;
396 char *demangled
= NULL
;
398 /* Discard the remembered types, if any. */
401 if (work
-> typevec
!= NULL
)
403 free ((char *) work
-> typevec
);
406 /* If demangling was successful, ensure that the demangled string is null
407 terminated and return it. Otherwise, free the demangling decl. */
411 string_delete (declp
);
415 string_appendn (declp
, "", 1);
416 demangled
= declp
-> b
;
425 demangle_signature -- demangle the signature part of a mangled name
430 demangle_signature (string *declp, const char **mangled,
431 struct work_stuff *work);
435 Consume and demangle the signature portion of the mangled name.
437 DECLP is the string where demangled output is being built. At
438 entry it contains the demangled root name from the mangled name
439 prefix. I.E. either a demangled operator name or the root function
440 name. In some special cases, it may contain nothing.
442 *MANGLED points to the current unconsumed location in the mangled
443 name. As tokens are consumed and demangling is performed, the
444 pointer is updated to continuously point at the next token to
447 Demangling GNU style mangled names is nasty because there is no
448 explicit token that marks the start of the outermost function
453 demangle_signature (declp
, mangled
, work
)
455 const char **mangled
;
456 struct work_stuff
*work
;
462 const char *premangle
;
466 premangle
= *mangled
;
469 while (success
&& (**mangled
!= '\0'))
474 success
= demangle_qualified (declp
, mangled
, work
);
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 success
= demangle_class (declp
, mangled
, work
);
499 remember_type (premangle
, *mangled
- premangle
, work
);
502 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
510 /* ARM style demangling includes a specific 'F' character after
511 the class name. For GNU style, it is just implied. So we can
512 safely just consume any 'F' at this point and be compatible
513 with either style. */
518 /* For lucid/cfront style we have to forget any types we might
519 have remembered up to this point, since they were not argument
520 types. GNU style considers all types seen as available for
521 back references. See comment in demangle_args() */
523 if (LUCID_DEMANGLING
|| CFRONT_DEMANGLING
)
527 success
= demangle_args (declp
, mangled
, work
);
532 success
= demangle_template (declp
, mangled
, work
);
536 /* At the outermost level, we cannot have a return type specified,
537 so if we run into another '_' at this point we are dealing with
538 a mangled name that is either bogus, or has been mangled by
539 some algorithm we don't know how to deal with. So just
540 reject the entire demangling. */
545 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
547 /* Assume we have stumbled onto the first outermost function
548 argument token, and start processing args. */
550 success
= demangle_args (declp
, mangled
, work
);
554 /* Non-GNU demanglers use a specific token to mark the start
555 of the outermost function argument tokens. Typically 'F',
556 for ARM-demangling, for example. So if we find something
557 we are not prepared for, it must be an error. */
562 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
564 if (success
&& expect_func
)
567 success
= demangle_args (declp
, mangled
, work
);
571 if (success
&& !func_done
)
573 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
575 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
576 bar__3fooi is 'foo::bar(int)'. We get here when we find the
577 first case, and need to ensure that the '(void)' gets added to
578 the current declp. Note that with ARM, the first case
579 represents the name of a static data member 'foo::bar',
580 which is in the current declp, so we leave it alone. */
581 success
= demangle_args (declp
, mangled
, work
);
584 if (success
&& work
-> static_type
&& PRINT_ARG_TYPES
)
586 string_append (declp
, " static");
588 if (success
&& work
-> const_type
&& PRINT_ARG_TYPES
)
590 string_append (declp
, " const");
598 demangle_method_args (declp
, mangled
, work
)
600 const char **mangled
;
601 struct work_stuff
*work
;
605 if (work
-> static_type
)
607 string_append (declp
, *mangled
+ 1);
608 *mangled
+= strlen (*mangled
);
613 success
= demangle_args (declp
, mangled
, work
);
621 demangle_template (declp
, mangled
, work
)
623 const char **mangled
;
624 struct work_stuff
*work
;
641 string_init (&tname
);
642 string_init (&trawname
);
643 /* get template name */
644 if (!get_count (mangled
, &r
))
648 string_appendn (&tname
, *mangled
, r
);
649 string_appendn (&trawname
, *mangled
, r
);
650 string_appendn (&trawname
, "", 1);
652 string_append (&tname
, "<");
653 /* get size of template parameter list */
654 if (!get_count (mangled
, &r
))
658 for (i
= 0; i
< r
; i
++)
662 string_append (&tname
, ", ");
664 /* Z for type parameters */
665 if (**mangled
== 'Z')
668 success
= do_type (mangled
, &temp
, work
);
669 string_appendn (&temp
, "", 1);
672 string_append (&tname
, temp
.b
);
674 string_delete(&temp
);
682 /* otherwise, value parameter */
688 success
= do_type (mangled
, &temp
, work
);
689 string_appendn (&temp
, "", 1);
692 string_append (&tname
, temp
.b
);
694 string_delete(&temp
);
699 string_append (&tname
, "=");
700 while (*old_p
&& !done
)
706 done
= is_pointer
= 1;
708 case 'C': /* const */
709 case 'S': /* explicitly signed [char] */
710 case 'U': /* unsigned */
711 case 'V': /* volatile */
712 case 'F': /* function */
713 case 'M': /* member function */
717 case 'Q': /* repetition of following */
718 case 'T': /* remembered type */
724 case 'x': /* long long */
727 case 's': /* short */
729 done
= is_integral
= 1;
731 case 'r': /* long double */
732 case 'd': /* double */
733 case 'f': /* float */
742 if (**mangled
== 'm')
744 string_appendn (&tname
, "-", 1);
747 while (isdigit (**mangled
))
749 string_appendn (&tname
, *mangled
, 1);
755 if (**mangled
== 'm')
757 string_appendn (&tname
, "-", 1);
760 while (isdigit (**mangled
))
762 string_appendn (&tname
, *mangled
, 1);
765 if (**mangled
== '.') /* fraction */
767 string_appendn (&tname
, ".", 1);
769 while (isdigit (**mangled
))
771 string_appendn (&tname
, *mangled
, 1);
775 if (**mangled
== 'e') /* exponent */
777 string_appendn (&tname
, "e", 1);
779 while (isdigit (**mangled
))
781 string_appendn (&tname
, *mangled
, 1);
788 if (!get_count (mangled
, &symbol_len
))
793 string_appendn (&tname
, *mangled
, symbol_len
);
794 *mangled
+= symbol_len
;
799 string_append (&tname
, ">::");
800 if (work
-> destructor
)
802 string_append (&tname
, "~");
804 if (work
-> constructor
|| work
-> destructor
)
806 string_append (&tname
, trawname
.b
);
808 string_delete(&trawname
);
812 string_delete(&tname
);
816 string_prepend (declp
, tname
.b
);
817 string_delete (&tname
);
819 if (work
-> static_type
)
821 string_append (declp
, *mangled
+ 1);
822 *mangled
+= strlen (*mangled
);
827 success
= demangle_args (declp
, mangled
, work
);
837 demangle_class -- demangle a mangled class sequence
842 demangle_class (string *declp, const char **mangled,
843 struct work_stuff *work)
847 DECLP points to the buffer into which demangling is being done.
849 *MANGLED points to the current token to be demangled. On input,
850 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
851 On exit, it points to the next token after the mangled class on
852 success, or the first unconsumed token on failure.
854 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
855 we are demangling a constructor or destructor. In this case
856 we prepend "class::class" or "class::~class" to DECLP.
858 Otherwise, we prepend "class::" to the current DECLP.
860 Reset the constructor/destructor flags once they have been
861 "consumed". This allows demangle_class to be called later during
862 the same demangling, to do normal class demangling.
864 Returns 1 if demangling is successful, 0 otherwise.
869 demangle_class (declp
, mangled
, work
)
871 const char **mangled
;
872 struct work_stuff
*work
;
877 n
= consume_count (mangled
);
878 if (strlen (*mangled
) >= n
)
880 if (work
-> constructor
|| work
-> destructor
)
882 string_prependn (declp
, *mangled
, n
);
883 if (work
-> destructor
)
885 string_prepend (declp
, "~");
887 work
-> constructor
= work
-> destructor
= 0;
889 string_prepend (declp
, "::");
890 string_prependn (declp
, *mangled
, n
);
901 demangle_prefix -- consume the mangled name prefix and find signature
906 demangle_prefix (string *declp, const char **mangled,
907 struct work_stuff *work)
911 Consume and demangle the prefix of the mangled name.
913 DECLP points to the string buffer into which demangled output is
914 placed. On entry, the buffer is empty. On exit it contains
915 the root function name, the demangled operator name, or in some
916 special cases either nothing or the completely demangled result.
918 MANGLED points to the current pointer into the mangled name. As each
919 token of the mangled name is consumed, it is updated. Upon entry
920 the current mangled name pointer points to the first character of
921 the mangled name. Upon exit, it should point to the first character
922 of the signature if demangling was successful, or to the first
923 unconsumed character if demangling of the prefix was unsuccessful.
925 Returns 1 on success, 0 otherwise.
929 demangle_prefix (declp
, mangled
, work
)
931 const char **mangled
;
932 struct work_stuff
*work
;
938 scan
= strstr (*mangled
, "__");
942 /* We found a sequence of two or more '_', ensure that we start at
943 the last pair in the sequence. */
944 i
= strspn (scan
, "_");
955 else if (work
-> static_type
)
957 if (!isdigit (scan
[0]) && (scan
[0] != 't'))
962 else if ((scan
== *mangled
) && (isdigit (scan
[2]) || (scan
[2] == 'Q')))
964 /* A GNU style constructor starts with "__<digit>" or "__Q". */
965 work
-> constructor
= 1;
968 else if ((scan
== *mangled
) && !isdigit (scan
[2]) && (scan
[2] != 't'))
970 /* Mangled name starts with "__". Skip over any leading '_' characters,
971 then find the next "__" that separates the prefix from the signature.
973 if (!(CFRONT_DEMANGLING
|| LUCID_DEMANGLING
)
974 || (cfront_special (declp
, mangled
, work
) == 0))
980 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
982 /* No separator (I.E. "__not_mangled"), or empty signature
983 (I.E. "__not_mangled_either__") */
988 demangle_function_name (declp
, mangled
, work
, scan
);
992 else if (*(scan
+ 2) != '\0')
994 /* Mangled name does not start with "__" but does have one somewhere
995 in there with non empty stuff after it. Looks like a global
997 demangle_function_name (declp
, mangled
, work
, scan
);
1001 /* Doesn't look like a mangled name */
1011 gnu_special -- special handling of gnu mangled strings
1016 gnu_special (string *declp, const char **mangled,
1017 struct work_stuff *work)
1022 Process some special GNU style mangling forms that don't fit
1023 the normal pattern. For example:
1025 _$_3foo (destructor for class foo)
1026 _vt$foo (foo virtual table)
1027 _vt$foo$bar (foo::bar virtual table)
1028 _3foo$varname (static data member)
1032 gnu_special (declp
, mangled
, work
)
1034 const char **mangled
;
1035 struct work_stuff
*work
;
1041 if ((*mangled
)[0] == '_'
1042 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
1043 && (*mangled
)[2] == '_')
1045 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1047 work
-> destructor
= 1;
1049 else if ((*mangled
)[0] == '_'
1050 && (*mangled
)[1] == 'v'
1051 && (*mangled
)[2] == 't'
1052 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)
1054 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1055 and create the decl. Note that we consume the entire mangled
1056 input string, which means that demangle_signature has no work
1059 while (**mangled
!= '\0')
1061 n
= strcspn (*mangled
, cplus_markers
);
1062 string_appendn (declp
, *mangled
, n
);
1064 if (**mangled
!= '\0')
1066 string_append (declp
, "::");
1070 string_append (declp
, " virtual table");
1072 else if ((*mangled
)[0] == '_'
1073 && isdigit ((*mangled
)[1])
1074 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
1076 /* static data member, "_3foo$varname" for example */
1079 n
= consume_count (mangled
);
1080 string_appendn (declp
, *mangled
, n
);
1081 string_append (declp
, "::");
1083 string_appendn (declp
, p
, n
);
1097 cfront_special -- special handling of cfront/lucid mangled strings
1102 cfront_special (string *declp, const char **mangled,
1103 struct work_stuff *work)
1108 Process some special cfront style mangling forms that don't fit
1109 the normal pattern. For example:
1111 __vtbl__3foo (foo virtual table)
1112 __vtbl__3foo__3bar (bar::foo virtual table)
1117 cfront_special (declp
, mangled
, work
)
1119 const char **mangled
;
1120 struct work_stuff
*work
;
1127 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
1129 /* Found a cfront style virtual table, get past ARM_VTABLE_STRING
1130 and create the decl. Note that we consume the entire mangled
1131 input string, which means that demangle_signature has no work
1133 (*mangled
) += ARM_VTABLE_STRLEN
;
1134 while (**mangled
!= '\0')
1136 n
= consume_count (mangled
);
1137 string_prependn (declp
, *mangled
, n
);
1139 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
1141 string_prepend (declp
, "::");
1145 string_append (declp
, " virtual table");
1154 /* Do a qualified name, such as "Q25Outer5Inner" for "Outer::Inner" */
1157 demangle_qualified (declp
, mangled
, work
)
1159 const char **mangled
;
1160 struct work_stuff
*work
;
1167 n
= (*mangled
)[1] - '0';
1168 if (n
>= 0 && n
<= 9)
1170 if ((*mangled
)[2] == '_')
1176 string_init (&class);
1179 success
= do_type (mangled
, &tmp
, work
);
1180 string_appends (&class, &tmp
);
1181 string_append (&class, "::");
1182 if (n
== 0 && (work
-> constructor
|| work
-> destructor
))
1184 if (work
-> destructor
)
1186 string_append (&class, "~");
1188 string_appends (&class, &tmp
);
1190 string_delete (&tmp
);
1192 work
-> constructor
= work
-> destructor
= 0;
1193 string_prependn (declp
, class.b
, class.p
- class.b
);
1194 string_delete (&class);
1203 get_count -- convert an ascii count to integer, consuming tokens
1208 get_count (const char **type, int *count)
1212 Return 0 if no conversion is performed, 1 if a string is converted.
1216 get_count (type
, count
)
1223 if (!isdigit (**type
))
1229 *count
= **type
- '0';
1231 if (isdigit (**type
))
1241 while (isdigit (*p
));
1252 /* result will be initialised here; it will be freed on failure */
1255 do_type (type
, result
, work
)
1258 struct work_stuff
*work
;
1264 const char *remembered_type
;
1268 string_init (&decl
);
1269 string_init (result
);
1273 while (success
&& !done
)
1278 /* A qualified name, such as "Outer::Inner". Note qualifier count
1279 is limited to a single digit (0-9 qualifiers). */
1281 n
= (*type
)[1] - '0';
1286 if ((*type
)[2] == '_') /* cfront style */
1293 do_type (type
, result
, work
);
1297 /* A pointer type */
1300 string_prepend (&decl
, "*");
1303 /* A reference type */
1306 string_prepend (&decl
, "&");
1309 /* A back reference to a previously seen type */
1312 if (!get_count (type
, &n
) || n
>= work
-> ntypes
)
1318 remembered_type
= work
-> typevec
[n
];
1319 type
= &remembered_type
;
1326 if (!STRING_EMPTY (&decl
) && decl
.b
[0] == '*')
1328 string_prepend (&decl
, "(");
1329 string_append (&decl
, ")");
1331 /* After picking off the function args, we expect to either find the
1332 function return type (preceded by an '_') or the end of the
1334 if (!demangle_args (&decl
, type
, work
)
1335 || (**type
!= '_' && **type
!= '\0'))
1339 if (success
&& (**type
== '_'))
1351 member
= **type
== 'M';
1353 if (!isdigit (**type
))
1358 n
= consume_count (type
);
1359 if (strlen (*type
) < n
)
1364 string_append (&decl
, ")");
1365 string_prepend (&decl
, "::");
1366 string_prependn (&decl
, *type
, n
);
1367 string_prepend (&decl
, "(");
1381 if (*(*type
)++ != 'F')
1387 if ((member
&& !demangle_args (&decl
, type
, work
))
1394 if (! PRINT_ANSI_QUALIFIERS
)
1400 APPEND_BLANK (&decl
);
1401 string_append (&decl
, "const");
1405 APPEND_BLANK (&decl
);
1406 string_append (&decl
, "volatile");
1412 if ((*type
)[1] == 'P')
1415 if (PRINT_ANSI_QUALIFIERS
)
1417 if (!STRING_EMPTY (&decl
))
1419 string_prepend (&decl
, " ");
1421 string_prepend (&decl
, "const");
1433 success
= demangle_fund_type (type
, result
, work
);
1437 if (!STRING_EMPTY (&decl
))
1439 string_append (result
, " ");
1440 string_appends (result
, &decl
);
1445 string_delete (result
);
1447 string_delete (&decl
);
1451 /* Given a pointer to a type string that represents a fundamental type
1452 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
1453 string in which the demangled output is being built in RESULT, and
1454 the WORK structure, decode the types and add them to the result.
1459 "Sl" => "signed long"
1460 "CUs" => "const unsigned short"
1465 demangle_fund_type (type
, result
, work
)
1468 struct work_stuff
*work
;
1474 /* First pick off any type qualifiers. There can be more than one. */
1482 if (PRINT_ANSI_QUALIFIERS
)
1484 APPEND_BLANK (result
);
1485 string_append (result
, "const");
1490 APPEND_BLANK (result
);
1491 string_append (result
, "unsigned");
1493 case 'S': /* signed char only */
1495 APPEND_BLANK (result
);
1496 string_append (result
, "signed");
1500 if (PRINT_ANSI_QUALIFIERS
)
1502 APPEND_BLANK (result
);
1503 string_append (result
, "volatile");
1512 /* Now pick off the fundamental type. There can be only one. */
1521 APPEND_BLANK (result
);
1522 string_append (result
, "void");
1526 APPEND_BLANK (result
);
1527 string_append (result
, "long long");
1531 APPEND_BLANK (result
);
1532 string_append (result
, "long");
1536 APPEND_BLANK (result
);
1537 string_append (result
, "int");
1541 APPEND_BLANK (result
);
1542 string_append (result
, "short");
1546 APPEND_BLANK (result
);
1547 string_append (result
, "char");
1551 APPEND_BLANK (result
);
1552 string_append (result
, "long double");
1556 APPEND_BLANK (result
);
1557 string_append (result
, "double");
1561 APPEND_BLANK (result
);
1562 string_append (result
, "float");
1566 if (!isdigit (**type
))
1572 /* An explicit type, such as "6mytype" or "7integer" */
1583 n
= consume_count (type
);
1584 if (strlen (*type
) < n
)
1589 APPEND_BLANK (result
);
1590 string_appendn (result
, *type
, n
);
1601 /* `result' will be initialized in do_type; it will be freed on failure */
1604 do_arg (type
, result
, work
)
1607 struct work_stuff
*work
;
1609 const char *start
= *type
;
1611 if (!do_type (type
, result
, work
))
1617 remember_type (start
, *type
- start
, work
);
1623 remember_type (start
, len
, work
)
1626 struct work_stuff
*work
;
1630 if (work
-> ntypes
>= work
-> typevec_size
)
1632 if (work
-> typevec_size
== 0)
1634 work
-> typevec_size
= 3;
1636 (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
1640 work
-> typevec_size
*= 2;
1642 (char **) xrealloc ((char *)work
-> typevec
,
1643 sizeof (char *) * work
-> typevec_size
);
1646 tem
= (char *) xmalloc (len
+ 1);
1647 memcpy (tem
, start
, len
);
1649 work
-> typevec
[work
-> ntypes
++] = tem
;
1652 /* Forget the remembered types, but not the type vector itself. */
1656 struct work_stuff
*work
;
1660 while (work
-> ntypes
> 0)
1662 i
= --(work
-> ntypes
);
1663 if (work
-> typevec
[i
] != NULL
)
1665 free (work
-> typevec
[i
]);
1666 work
-> typevec
[i
] = NULL
;
1671 /* Process the argument list part of the signature, after any class spec
1672 has been consumed, as well as the first 'F' character (if any). For
1675 "__als__3fooRT0" => process "RT0"
1676 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
1678 DECLP must be already initialised, usually non-empty. It won't be freed
1681 Note that g++ differs significantly from cfront and lucid style mangling
1682 with regards to references to previously seen types. For example, given
1683 the source fragment:
1687 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
1690 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
1691 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
1693 g++ produces the names:
1698 while lcc (and presumably cfront as well) produces:
1700 foo__FiR3fooT1T2T1T2
1701 __ct__3fooFiR3fooT1T2T1T2
1703 Note that g++ bases it's type numbers starting at zero and counts all
1704 previously seen types, while lucid/cfront bases it's type numbers starting
1705 at one and only considers types after it has seen the 'F' character
1706 indicating the start of the function args. For lucid/cfront style, we
1707 account for this difference by discarding any previously seen types when
1708 we see the 'F' character, and subtracting one from the type number
1714 demangle_args (declp
, type
, work
)
1717 struct work_stuff
*work
;
1726 if (PRINT_ARG_TYPES
)
1728 string_append (declp
, "(");
1731 string_append (declp
, "void");
1735 while (**type
!= '_' && **type
!= '\0' && **type
!= 'e')
1737 if ((**type
== 'N') || (**type
== 'T'))
1739 temptype
= *(*type
)++;
1741 if (temptype
== 'N')
1743 if (!get_count (type
, &r
))
1752 if (!get_count (type
, &t
))
1756 if (LUCID_DEMANGLING
|| CFRONT_DEMANGLING
)
1760 /* Validate the type index. Protect against illegal indices from
1761 malformed type strings. */
1762 if ((t
< 0) || (t
>= work
-> ntypes
))
1768 tem
= work
-> typevec
[t
];
1769 if (need_comma
&& PRINT_ARG_TYPES
)
1771 string_append (declp
, ", ");
1773 if (!do_arg (&tem
, &arg
, work
))
1777 if (PRINT_ARG_TYPES
)
1779 string_appends (declp
, &arg
);
1781 string_delete (&arg
);
1787 if (need_comma
& PRINT_ARG_TYPES
)
1789 string_append (declp
, ", ");
1791 if (!do_arg (type
, &arg
, work
))
1795 if (PRINT_ARG_TYPES
)
1797 string_appends (declp
, &arg
);
1799 string_delete (&arg
);
1807 if (PRINT_ARG_TYPES
)
1811 string_append (declp
, ",");
1813 string_append (declp
, "...");
1817 if (PRINT_ARG_TYPES
)
1819 string_append (declp
, ")");
1825 demangle_function_name (declp
, mangled
, work
, scan
)
1827 const char **mangled
;
1828 struct work_stuff
*work
;
1836 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
1837 string_need (declp
, 1);
1838 *(declp
-> p
) = '\0';
1840 /* Consume the function name, including the "__" separating the name
1841 from the signature. We are guaranteed that SCAN points to the
1844 (*mangled
) = scan
+ 2;
1846 if (LUCID_DEMANGLING
|| CFRONT_DEMANGLING
)
1849 /* See if we have an ARM style constructor or destructor operator.
1850 If so, then just record it, clear the decl, and return.
1851 We can't build the actual constructor/destructor decl until later,
1852 when we recover the class name from the signature. */
1854 if (strcmp (declp
-> b
, "__ct") == 0)
1856 work
-> constructor
= 1;
1857 string_clear (declp
);
1860 else if (strcmp (declp
-> b
, "__dt") == 0)
1862 work
-> destructor
= 1;
1863 string_clear (declp
);
1868 if (declp
->p
- declp
->b
>= 3
1869 && declp
->b
[0] == 'o'
1870 && declp
->b
[1] == 'p'
1871 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
1873 /* see if it's an assignment expression */
1874 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
1875 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
1877 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1879 len
= declp
->p
- declp
->b
- 10;
1880 if (strlen (optable
[i
].in
) == len
1881 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
1883 string_clear (declp
);
1884 string_append (declp
, "operator");
1885 string_append (declp
, optable
[i
].out
);
1886 string_append (declp
, "=");
1893 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1895 int len
= declp
->p
- declp
->b
- 3;
1896 if (strlen (optable
[i
].in
) == len
1897 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
1899 string_clear (declp
);
1900 string_append (declp
, "operator");
1901 string_append (declp
, optable
[i
].out
);
1907 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type$", 5) == 0)
1909 /* type conversion operator */
1911 if (do_type (&tem
, &type
, work
))
1913 string_clear (declp
);
1914 string_append (declp
, "operator ");
1915 string_appends (declp
, &type
);
1916 string_delete (&type
);
1919 else if (declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
1922 /* type conversion operator. */
1924 if (do_type (&tem
, &type
, work
))
1926 string_clear (declp
);
1927 string_append (declp
, "operator ");
1928 string_appends (declp
, &type
);
1929 string_delete (&type
);
1932 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
1933 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
1934 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
1936 if (declp
->b
[4] == '\0')
1939 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1941 if (strlen (optable
[i
].in
) == 2
1942 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
1944 string_clear (declp
);
1945 string_append (declp
, "operator");
1946 string_append (declp
, optable
[i
].out
);
1953 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
1956 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1958 if (strlen (optable
[i
].in
) == 3
1959 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
1961 string_clear (declp
);
1962 string_append (declp
, "operator");
1963 string_append (declp
, optable
[i
].out
);
1972 /* a mini string-handling package */
1987 s
->p
= s
->b
= (char *) xmalloc (n
);
1990 else if (s
->e
- s
->p
< n
)
1995 s
->b
= (char *) xrealloc (s
->b
, n
);
2008 s
->b
= s
->e
= s
->p
= NULL
;
2016 s
->b
= s
->p
= s
->e
= NULL
;
2032 return (s
->b
== s
->p
);
2038 string_append (p
, s
)
2043 if (s
== NULL
|| *s
== '\0')
2047 memcpy (p
->p
, s
, n
);
2052 string_appends (p
, s
)
2061 memcpy (p
->p
, s
->b
, n
);
2067 string_appendn (p
, s
, n
)
2075 memcpy (p
->p
, s
, n
);
2081 string_prepend (p
, s
)
2085 if (s
!= NULL
&& *s
!= '\0')
2087 string_prependn (p
, s
, strlen (s
));
2094 string_prepends (p
, s
)
2099 string_prependn (p
, s
->b
, s
->p
- s
->b
);
2106 string_prependn (p
, s
, n
)
2116 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
2120 memcpy (p
->b
, s
, n
);
2125 /* To generate a standalone demangler program for testing purposes, just
2126 compile and link this file with -DMAIN. When run, it demangles each
2127 command line arg, or each stdin string, and prints the result on stdout. */
2132 demangle_it (mangled_name
)
2137 result
= cplus_demangle (mangled_name
, DMGL_PARAMS
| DMGL_ANSI
);
2140 printf ("%s\n", mangled_name
);
2144 printf ("%s\n", result
);
2155 if ((newmem
= malloc ((int) size
)) == NULL
)
2157 fprintf (stderr
, "\nCan't allocate %u bytes\n", size
);
2164 xrealloc (oldmem
, size
)
2170 if ((newmem
= realloc ((char *) oldmem
, (int) size
)) == NULL
)
2172 fprintf (stderr
, "\nCan't reallocate %u bytes\n", size
);
2180 enum demangling_styles current_demangling_style
= gnu_demangling
;
2186 char mangled_name
[128];
2189 extern char *optarg
;
2192 while ((c
= getopt (argc
, argv
, "s:?")) != EOF
)
2197 fprintf (stderr
, "usage: demangle [-s style] [arg1 [arg2]] ...\n");
2198 fprintf (stderr
, "style = { gnu, lucid, cfront }\n");
2199 fprintf (stderr
, "reads args from stdin if none supplied\n");
2203 if (strcmp (optarg
, "gnu") == 0)
2205 current_demangling_style
= gnu_demangling
;
2207 else if (strcmp (optarg
, "lucid") == 0)
2209 current_demangling_style
= lucid_demangling
;
2211 else if (strcmp (optarg
, "cfront") == 0)
2213 current_demangling_style
= cfront_demangling
;
2217 fprintf (stderr
, "unknown demangling style `%s'\n", optarg
);
2225 for ( ; optind
< argc
; optind
++)
2227 demangle_it (argv
[optind
]);
2232 while (gets (mangled_name
))
2234 demangle_it (mangled_name
);