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 /* This is '$' on systems where the assembler can deal with that.
36 Where the assembler can't, it's '.' (but on many systems '.' is
37 used for other things). */
39 #if !defined (CPLUS_MARKER)
40 #define CPLUS_MARKER '$'
47 /* Stuff that is shared between sub-routines.
48 * Using a shared structure allows cplus_demangle to be reentrant. */
58 int static_type
; /* A static member function */
59 int const_type
; /* A const member function */
62 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
63 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
65 static const struct optable
71 "nw", " new", DMGL_ANSI
, /* new (1.92, ansi) */
72 "dl", " delete", DMGL_ANSI
, /* new (1.92, ansi) */
73 "new", " new", 0, /* old (1.91, and 1.x) */
74 "delete", " delete", 0, /* old (1.91, and 1.x) */
75 "as", "=", DMGL_ANSI
, /* ansi */
76 "ne", "!=", DMGL_ANSI
, /* old, ansi */
77 "eq", "==", DMGL_ANSI
, /* old, ansi */
78 "ge", ">=", DMGL_ANSI
, /* old, ansi */
79 "gt", ">", DMGL_ANSI
, /* old, ansi */
80 "le", "<=", DMGL_ANSI
, /* old, ansi */
81 "lt", "<", DMGL_ANSI
, /* old, ansi */
82 "plus", "+", 0, /* old */
83 "pl", "+", DMGL_ANSI
, /* ansi */
84 "apl", "+=", DMGL_ANSI
, /* ansi */
85 "minus", "-", 0, /* old */
86 "mi", "-", DMGL_ANSI
, /* ansi */
87 "ami", "-=", DMGL_ANSI
, /* ansi */
88 "mult", "*", 0, /* old */
89 "ml", "*", DMGL_ANSI
, /* ansi */
90 "amu", "*=", DMGL_ANSI
, /* ansi (ARM/Lucid) */
91 "aml", "*=", DMGL_ANSI
, /* ansi (GNU/g++) */
92 "convert", "+", 0, /* old (unary +) */
93 "negate", "-", 0, /* old (unary -) */
94 "trunc_mod", "%", 0, /* old */
95 "md", "%", DMGL_ANSI
, /* ansi */
96 "amd", "%=", DMGL_ANSI
, /* ansi */
97 "trunc_div", "/", 0, /* old */
98 "dv", "/", DMGL_ANSI
, /* ansi */
99 "adv", "/=", DMGL_ANSI
, /* ansi */
100 "truth_andif", "&&", 0, /* old */
101 "aa", "&&", DMGL_ANSI
, /* ansi */
102 "truth_orif", "||", 0, /* old */
103 "oo", "||", DMGL_ANSI
, /* ansi */
104 "truth_not", "!", 0, /* old */
105 "nt", "!", DMGL_ANSI
, /* ansi */
106 "postincrement","++", 0, /* old */
107 "pp", "++", DMGL_ANSI
, /* ansi */
108 "postdecrement","--", 0, /* old */
109 "mm", "--", DMGL_ANSI
, /* ansi */
110 "bit_ior", "|", 0, /* old */
111 "or", "|", DMGL_ANSI
, /* ansi */
112 "aor", "|=", DMGL_ANSI
, /* ansi */
113 "bit_xor", "^", 0, /* old */
114 "er", "^", DMGL_ANSI
, /* ansi */
115 "aer", "^=", DMGL_ANSI
, /* ansi */
116 "bit_and", "&", 0, /* old */
117 "ad", "&", DMGL_ANSI
, /* ansi */
118 "aad", "&=", DMGL_ANSI
, /* ansi */
119 "bit_not", "~", 0, /* old */
120 "co", "~", DMGL_ANSI
, /* ansi */
121 "call", "()", 0, /* old */
122 "cl", "()", DMGL_ANSI
, /* ansi */
123 "alshift", "<<", 0, /* old */
124 "ls", "<<", DMGL_ANSI
, /* ansi */
125 "als", "<<=", DMGL_ANSI
, /* ansi */
126 "arshift", ">>", 0, /* old */
127 "rs", ">>", DMGL_ANSI
, /* ansi */
128 "ars", ">>=", DMGL_ANSI
, /* ansi */
129 "component", "->", 0, /* old */
130 "pt", "->", DMGL_ANSI
, /* ansi; Lucid C++ form */
131 "rf", "->", DMGL_ANSI
, /* ansi; ARM/GNU form */
132 "indirect", "*", 0, /* old */
133 "method_call", "->()", 0, /* old */
134 "addr", "&", 0, /* old (unary &) */
135 "array", "[]", 0, /* old */
136 "vc", "[]", DMGL_ANSI
, /* ansi */
137 "compound", ", ", 0, /* old */
138 "cm", ", ", DMGL_ANSI
, /* ansi */
139 "cond", "?:", 0, /* old */
140 "cn", "?:", DMGL_ANSI
, /* psuedo-ansi */
141 "max", ">?", 0, /* old */
142 "mx", ">?", DMGL_ANSI
, /* psuedo-ansi */
143 "min", "<?", 0, /* old */
144 "mn", "<?", DMGL_ANSI
, /* psuedo-ansi */
145 "nop", "", 0, /* old (for operator=) */
146 "rm", "->*", DMGL_ANSI
, /* ansi */
150 typedef struct string
/* Beware: these aren't required to be */
151 { /* '\0' terminated. */
152 char *b
; /* pointer to start of string */
153 char *p
; /* pointer after last character */
154 char *e
; /* pointer after end of allocated space */
157 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
158 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
159 string_prepend(str, " ");}
160 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
161 string_append(str, " ");}
163 /* Prototypes for local functions */
166 mop_up
PARAMS ((string
*, struct work_stuff
*, int));
170 demangle_method_args
PARAMS ((string
*, const char **, struct work_stuff
*));
174 demangle_template
PARAMS ((string
*declp
, const char **, struct work_stuff
*));
177 demangle_qualified
PARAMS ((string
*, const char **, struct work_stuff
*));
180 demangle_class
PARAMS ((string
*, const char **, struct work_stuff
*));
183 demangle_fund_type
PARAMS ((const char **, string
*, struct work_stuff
*));
186 demangle_signature
PARAMS ((string
*, const char **, struct work_stuff
*));
189 demangle_prefix
PARAMS ((string
*, const char **, struct work_stuff
*));
192 gnu_special
PARAMS ((string
*, const char **, struct work_stuff
*));
195 string_need
PARAMS ((string
*, int));
198 string_delete
PARAMS ((string
*));
201 string_init
PARAMS ((string
*));
204 string_clear
PARAMS ((string
*));
208 string_empty
PARAMS ((string
*));
212 string_append
PARAMS ((string
*, const char *));
215 string_appends
PARAMS ((string
*, string
*));
218 string_appendn
PARAMS ((string
*, const char *, int));
221 string_prepend
PARAMS ((string
*, const char *));
224 string_prependn
PARAMS ((string
*, const char *, int));
227 get_count
PARAMS ((const char **, int *));
230 consume_count
PARAMS ((const char **));
233 demangle_args
PARAMS ((string
*, const char **, struct work_stuff
*));
236 do_type
PARAMS ((const char **, string
*, struct work_stuff
*));
239 do_arg
PARAMS ((const char **, string
*, struct work_stuff
*));
242 demangle_function_name
PARAMS ((string
*, const char **, struct work_stuff
*,
246 remember_type
PARAMS ((const char *, int, struct work_stuff
*));
250 string_prepends
PARAMS ((string
*, string
*));
253 /* Translate count to integer, consuming tokens in the process.
254 Conversion terminates on the first non-digit character. */
265 count
+= **type
- '0';
267 } while (isdigit (**type
));
271 /* Takes operator name as e.g. "++" and returns mangled
272 operator name (e.g. "postincrement_expr"), or NULL if not found.
274 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
275 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
278 cplus_mangle_opname (opname
, options
)
285 len
= strlen (opname
);
286 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
288 if (strlen (optable
[i
].out
) == len
289 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
290 && memcmp (optable
[i
].out
, opname
, len
) == 0)
291 return ((char *)optable
[i
].in
);
296 /* char *cplus_demangle (const char *name, int options)
298 If NAME is a mangled function name produced by GNU C++, then
299 a pointer to a malloced string giving a C++ representation
300 of the name will be returned; otherwise NULL will be returned.
301 It is the caller's responsibility to free the string which
304 The OPTIONS arg may contain one or more of the following bits:
306 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
308 DMGL_PARAMS Function parameters are included.
312 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
313 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
314 cplus_demangle ("foo__1Ai", 0) => "A::foo"
316 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
317 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
318 cplus_demangle ("foo__1Afe", 0) => "A::foo"
320 Note that any leading underscores, or other such characters prepended by
321 the compilation system, are presumed to have already been stripped from
325 cplus_demangle (mangled
, options
)
331 struct work_stuff work
[1];
332 char *demangled
= NULL
;
334 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
336 memset ((char *) work
, 0, sizeof (work
));
337 work
-> options
= options
;
340 success
= demangle_prefix (&decl
, &mangled
, work
);
341 if (success
&& (*mangled
!= '\0'))
343 success
= demangle_signature (&decl
, &mangled
, work
);
345 demangled
= mop_up (&decl
, work
, success
);
351 mop_up (declp
, work
, success
)
353 struct work_stuff
*work
;
357 char *demangled
= NULL
;
359 /* Discard the remembered types, if any. */
361 for (i
= 0; i
< work
-> ntypes
; i
++)
363 if (work
-> typevec
[i
] != NULL
)
365 free (work
-> typevec
[i
]);
368 if (work
-> typevec
!= NULL
)
370 free ((char *) work
-> typevec
);
373 /* If demangling was successful, ensure that the demangled string is null
374 terminated and return it. Otherwise, free the demangling decl. */
378 string_delete (declp
);
382 string_appendn (declp
, "", 1);
383 demangled
= declp
-> b
;
392 demangle_signature -- demangle the signature part of a mangled name
397 demangle_signature (string *declp, const char **mangled,
398 struct work_stuff *work);
402 Consume and demangle the signature portion of the mangled name.
404 DECLP is the string where demangled output is being built. At
405 entry it contains the demangled root name from the mangled name
406 prefix. I.E. either a demangled operator name or the root function
407 name. In some special cases, it may contain nothing.
409 *MANGLED points to the current unconsumed location in the mangled
410 name. As tokens are consumed and demangling is performed, the
411 pointer is updated to continuously point at the next token to
414 Demangling GNU style mangled names is nasty because there is no
415 explicit token that marks the start of the outermost function
420 demangle_signature (declp
, mangled
, work
)
422 const char **mangled
;
423 struct work_stuff
*work
;
429 const char *premangle
;
433 premangle
= *mangled
;
436 while (success
&& (**mangled
!= '\0'))
441 success
= demangle_qualified (declp
, mangled
, work
);
442 if (current_demangling_style
== auto_demangling
||
443 current_demangling_style
== gnu_demangling
)
450 /* Static member function */
452 work
-> static_type
= 1;
456 /* a const member function */
458 work
-> const_type
= 1;
461 case '0': case '1': case '2': case '3': case '4':
462 case '5': case '6': case '7': case '8': case '9':
463 success
= demangle_class (declp
, mangled
, work
);
467 remember_type (premangle
, *mangled
- premangle
, work
);
470 if (current_demangling_style
== auto_demangling
||
471 current_demangling_style
== gnu_demangling
)
479 /* ARM style demangling includes a specific 'F' character after
480 the class name. For GNU style, it is just implied. So we can
481 safely just consume any 'F' at this point and be compatible
482 with either style. */
485 success
= demangle_args (declp
, mangled
, work
);
490 success
= demangle_template (declp
, mangled
, work
);
494 /* At the outermost level, we cannot have a return type specified,
495 so if we run into another '_' at this point we are dealing with
496 a mangled name that is either bogus, or has been mangled by
497 some algorithm we don't know how to deal with. So just
498 reject the entire demangling. */
503 if (current_demangling_style
== auto_demangling
||
504 current_demangling_style
== gnu_demangling
)
506 /* Assume we have stumbled onto the first outermost function
507 argument token, and start processing args. */
509 success
= demangle_args (declp
, mangled
, work
);
513 /* Non-GNU demanglers use a specific token to mark the start
514 of the outermost function argument tokens. Typically 'F',
515 for ARM-demangling, for example. So if we find something
516 we are not prepared for, it must be an error. */
521 if (current_demangling_style
== auto_demangling
||
522 current_demangling_style
== gnu_demangling
)
524 if (success
&& expect_func
)
527 success
= demangle_args (declp
, mangled
, work
);
531 if (success
&& !func_done
)
533 if (current_demangling_style
== auto_demangling
||
534 current_demangling_style
== gnu_demangling
)
536 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
537 bar__3fooi is 'foo::bar(int)'. We get here when we find the
538 first case, and need to ensure that the '(void)' gets added to
539 the current declp. Note that with ARM, the first case
540 represents the name of a static data member 'foo::bar',
541 which is in the current declp, so we leave it alone. */
542 success
= demangle_args (declp
, mangled
, work
);
545 if (success
&& work
-> static_type
&& PRINT_ARG_TYPES
)
547 string_append (declp
, " static");
549 if (success
&& work
-> const_type
&& PRINT_ARG_TYPES
)
551 string_append (declp
, " const");
559 demangle_method_args (declp
, mangled
, work
)
561 const char **mangled
;
562 struct work_stuff
*work
;
566 if (work
-> static_type
)
568 string_append (declp
, *mangled
+ 1);
569 *mangled
+= strlen (*mangled
);
574 success
= demangle_args (declp
, mangled
, work
);
582 demangle_template (declp
, mangled
, work
)
584 const char **mangled
;
585 struct work_stuff
*work
;
602 string_init (&tname
);
603 string_init (&trawname
);
604 /* get template name */
605 if (!get_count (mangled
, &r
))
609 string_appendn (&tname
, *mangled
, r
);
610 string_appendn (&trawname
, *mangled
, r
);
611 string_appendn (&trawname
, "", 1);
613 string_append (&tname
, "<");
614 /* get size of template parameter list */
615 if (!get_count (mangled
, &r
))
619 for (i
= 0; i
< r
; i
++)
623 string_append (&tname
, ", ");
625 /* Z for type parameters */
626 if (**mangled
== 'Z')
629 success
= do_type (mangled
, &temp
, work
);
630 string_appendn (&temp
, "", 1);
633 string_append (&tname
, temp
.b
);
635 string_delete(&temp
);
643 /* otherwise, value parameter */
649 success
= do_type (mangled
, &temp
, work
);
650 string_appendn (&temp
, "", 1);
653 string_append (&tname
, temp
.b
);
655 string_delete(&temp
);
660 string_append (&tname
, "=");
661 while (*old_p
&& !done
)
667 done
= is_pointer
= 1;
669 case 'C': /* const */
670 case 'S': /* explicitly signed [char] */
671 case 'U': /* unsigned */
672 case 'V': /* volatile */
673 case 'F': /* function */
674 case 'M': /* member function */
678 case 'Q': /* repetition of following */
679 case 'T': /* remembered type */
685 case 'x': /* long long */
688 case 's': /* short */
690 done
= is_integral
= 1;
692 case 'r': /* long double */
693 case 'd': /* double */
694 case 'f': /* float */
703 if (**mangled
== 'm')
705 string_appendn (&tname
, "-", 1);
708 while (isdigit (**mangled
))
710 string_appendn (&tname
, *mangled
, 1);
716 if (**mangled
== 'm')
718 string_appendn (&tname
, "-", 1);
721 while (isdigit (**mangled
))
723 string_appendn (&tname
, *mangled
, 1);
726 if (**mangled
== '.') /* fraction */
728 string_appendn (&tname
, ".", 1);
730 while (isdigit (**mangled
))
732 string_appendn (&tname
, *mangled
, 1);
736 if (**mangled
== 'e') /* exponent */
738 string_appendn (&tname
, "e", 1);
740 while (isdigit (**mangled
))
742 string_appendn (&tname
, *mangled
, 1);
749 if (!get_count (mangled
, &symbol_len
))
754 string_appendn (&tname
, *mangled
, symbol_len
);
755 *mangled
+= symbol_len
;
760 string_append (&tname
, ">::");
761 if (work
-> destructor
)
763 string_append (&tname
, "~");
765 if (work
-> constructor
|| work
-> destructor
)
767 string_append (&tname
, trawname
.b
);
769 string_delete(&trawname
);
773 string_delete(&tname
);
777 string_prepend (declp
, tname
.b
);
778 string_delete (&tname
);
780 if (work
-> static_type
)
782 string_append (declp
, *mangled
+ 1);
783 *mangled
+= strlen (*mangled
);
788 success
= demangle_args (declp
, mangled
, work
);
798 demangle_class -- demangle a mangled class sequence
803 demangle_class (string *declp, const char **mangled,
804 struct work_stuff *work)
808 DECLP points to the buffer into which demangling is being done.
810 *MANGLED points to the current token to be demangled. On input,
811 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
812 On exit, it points to the next token after the mangled class on
813 success, or the first unconsumed token on failure.
815 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
816 we are demangling a constructor or destructor. In this case
817 we prepend "class::class" or "class::~class" to DECLP.
819 Otherwise, we prepend "class::" to the current DECLP.
821 Reset the constructor/destructor flags once they have been
822 "consumed". This allows demangle_class to be called later during
823 the same demangling, to do normal class demangling.
825 Returns 1 if demangling is successful, 0 otherwise.
830 demangle_class (declp
, mangled
, work
)
832 const char **mangled
;
833 struct work_stuff
*work
;
838 n
= consume_count (mangled
);
839 if (strlen (*mangled
) >= n
)
841 if (work
-> constructor
|| work
-> destructor
)
843 string_prependn (declp
, *mangled
, n
);
844 if (work
-> destructor
)
846 string_prepend (declp
, "~");
848 work
-> constructor
= work
-> destructor
= 0;
850 string_prepend (declp
, "::");
851 string_prependn (declp
, *mangled
, n
);
862 demangle_prefix -- consume the mangled name prefix and find signature
867 demangle_prefix (string *declp, const char **mangled,
868 struct work_stuff *work)
872 Consume and demangle the prefix of the mangled name.
874 DECLP points to the string buffer into which demangled output is
875 placed. On entry, the buffer is empty. On exit it contains
876 the root function name, the demangled operator name, or in some
877 special cases either nothing or the completely demangled result.
879 MANGLED points to the current pointer into the mangled name. As each
880 token of the mangled name is consumed, it is updated. Upon entry
881 the current mangled name pointer points to the first character of
882 the mangled name. Upon exit, it should point to the first character
883 of the signature if demangling was successful, or to the first
884 unconsumed character if demangling of the prefix was unsuccessful.
886 Returns 1 on success, 0 otherwise.
890 demangle_prefix (declp
, mangled
, work
)
892 const char **mangled
;
893 struct work_stuff
*work
;
898 scan
= strstr (*mangled
, "__");
901 if (current_demangling_style
== auto_demangling
||
902 current_demangling_style
== gnu_demangling
)
904 success
= gnu_special (declp
, mangled
, work
);
911 else if (work
-> static_type
)
913 if (!isdigit (scan
[0]) && (scan
[0] != 't'))
918 else if ((scan
== *mangled
) && (isdigit (scan
[2]) || (scan
[2] == 'Q')))
920 /* A GNU style constructor starts with "__<digit>" or "__Q". */
921 work
-> constructor
= 1;
924 else if ((scan
== *mangled
) && !isdigit (scan
[2]) && (scan
[2] != 't'))
926 /* Mangled name starts with "__". Skip over any leading '_' characters,
927 then find the next "__" that separates the prefix from the signature.
933 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
935 /* No separator (I.E. "__not_mangled"), or empty signature
936 (I.E. "__not_mangled_either__") */
941 demangle_function_name (declp
, mangled
, work
, scan
);
944 else if (*(scan
+ 2) != '\0')
946 /* Mangled name does not start with "__" but does have one somewhere
947 in there with non empty stuff after it. Looks like a global
949 demangle_function_name (declp
, mangled
, work
, scan
);
953 /* Doesn't look like a mangled name */
963 gnu_special -- special handling of gnu mangled strings
968 gnu_special (string *declp, const char **mangled,
969 struct work_stuff *work)
974 Process some special GNU style mangling forms that don't fit
975 the normal pattern. For example:
977 _$_3foo (destructor for class foo)
978 _vt$foo (virtual table)
979 _3foo$varname (static data member)
983 gnu_special (declp
, mangled
, work
)
985 const char **mangled
;
986 struct work_stuff
*work
;
992 if ((*mangled
)[0] == '_'
993 && (*mangled
)[1] == CPLUS_MARKER
994 && (*mangled
)[2] == '_')
996 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
998 work
-> destructor
= 1;
1000 else if ((*mangled
)[0] == '_'
1001 && (*mangled
)[1] == 'v'
1002 && (*mangled
)[2] == 't'
1003 && (*mangled
)[3] == CPLUS_MARKER
)
1005 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1006 and create the decl. Note that we consume the entire mangled
1007 input string, which means that demangle_signature has no work
1010 n
= strlen (*mangled
);
1011 string_appendn (declp
, *mangled
, n
);
1012 string_append (declp
, " virtual table");
1015 else if ((*mangled
)[0] == '_'
1016 && isdigit ((*mangled
)[1])
1017 && (p
= strchr (*mangled
, CPLUS_MARKER
)) != NULL
)
1019 /* static data member, "_3foo$varname" for example */
1022 n
= consume_count (mangled
);
1023 string_appendn (declp
, *mangled
, n
);
1024 string_append (declp
, "::");
1026 string_appendn (declp
, p
, n
);
1036 /* Do a qualified name, such as "Q25Outer5Inner" for "Outer::Inner" */
1039 demangle_qualified (declp
, mangled
, work
)
1041 const char **mangled
;
1042 struct work_stuff
*work
;
1049 n
= (*mangled
)[1] - '0';
1050 if (n
>= 0 && n
<= 9)
1052 if ((*mangled
)[2] == '_')
1058 string_init (&class);
1061 success
= do_type (mangled
, &tmp
, work
);
1062 string_appends (&class, &tmp
);
1063 string_append (&class, "::");
1064 if (n
== 0 && (work
-> constructor
|| work
-> destructor
))
1066 if (work
-> destructor
)
1068 string_append (&class, "~");
1070 string_appends (&class, &tmp
);
1072 string_delete (&tmp
);
1074 work
-> constructor
= work
-> destructor
= 0;
1075 string_prependn (declp
, class.b
, class.p
- class.b
);
1076 string_delete (&class);
1085 get_count -- convert an ascii count to integer, consuming tokens
1090 get_count (const char **type, int *count)
1094 Return 0 if no conversion is performed, 1 if a string is converted.
1098 get_count (type
, count
)
1105 if (!isdigit (**type
))
1111 *count
= **type
- '0';
1113 if (isdigit (**type
))
1123 while (isdigit (*p
));
1134 /* result will be initialised here; it will be freed on failure */
1137 do_type (type
, result
, work
)
1140 struct work_stuff
*work
;
1146 const char *remembered_type
;
1150 string_init (&decl
);
1151 string_init (result
);
1155 while (success
&& !done
)
1160 /* A qualified name, such as "Outer::Inner". Note qualifier count
1161 is limited to a single digit (0-9 qualifiers). */
1163 n
= (*type
)[1] - '0';
1168 if ((*type
)[2] == '_') /* cfront style */
1175 do_type (type
, result
, work
);
1179 /* A pointer type */
1182 string_prepend (&decl
, "*");
1185 /* A reference type */
1188 string_prepend (&decl
, "&");
1191 /* A back reference to a previously seen type */
1194 if (!get_count (type
, &n
) || n
>= work
-> ntypes
)
1200 remembered_type
= work
-> typevec
[n
];
1201 type
= &remembered_type
;
1208 if (!STRING_EMPTY (&decl
) && decl
.b
[0] == '*')
1210 string_prepend (&decl
, "(");
1211 string_append (&decl
, ")");
1213 /* After picking off the function args, we expect to either find the
1214 function return type (preceded by an '_') or the end of the
1216 if (!demangle_args (&decl
, type
, work
)
1217 || (**type
!= '_' && **type
!= '\0'))
1221 if (success
&& (**type
== '_'))
1233 member
= **type
== 'M';
1235 if (!isdigit (**type
))
1240 n
= consume_count (type
);
1241 if (strlen (*type
) < n
)
1246 string_append (&decl
, ")");
1247 string_prepend (&decl
, "::");
1248 string_prependn (&decl
, *type
, n
);
1249 string_prepend (&decl
, "(");
1263 if (*(*type
)++ != 'F')
1269 if ((member
&& !demangle_args (&decl
, type
, work
))
1276 if (! PRINT_ANSI_QUALIFIERS
)
1282 APPEND_BLANK (&decl
);
1283 string_append (&decl
, "const");
1287 APPEND_BLANK (&decl
);
1288 string_append (&decl
, "volatile");
1294 if ((*type
)[1] == 'P')
1297 if (PRINT_ANSI_QUALIFIERS
)
1299 if (!STRING_EMPTY (&decl
))
1301 string_prepend (&decl
, " ");
1303 string_prepend (&decl
, "const");
1315 success
= demangle_fund_type (type
, result
, work
);
1319 if (!STRING_EMPTY (&decl
))
1321 string_append (result
, " ");
1322 string_appends (result
, &decl
);
1327 string_delete (result
);
1329 string_delete (&decl
);
1333 /* Given a pointer to a type string that represents a fundamental type
1334 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
1335 string in which the demangled output is being built in RESULT, and
1336 the WORK structure, decode the types and add them to the result.
1341 "Sl" => "signed long"
1342 "CUs" => "const unsigned short"
1347 demangle_fund_type (type
, result
, work
)
1350 struct work_stuff
*work
;
1356 /* First pick off any type qualifiers. There can be more than one. */
1364 if (PRINT_ANSI_QUALIFIERS
)
1366 APPEND_BLANK (result
);
1367 string_append (result
, "const");
1372 APPEND_BLANK (result
);
1373 string_append (result
, "unsigned");
1375 case 'S': /* signed char only */
1377 APPEND_BLANK (result
);
1378 string_append (result
, "signed");
1382 if (PRINT_ANSI_QUALIFIERS
)
1384 APPEND_BLANK (result
);
1385 string_append (result
, "volatile");
1394 /* Now pick off the fundamental type. There can be only one. */
1403 APPEND_BLANK (result
);
1404 string_append (result
, "void");
1408 APPEND_BLANK (result
);
1409 string_append (result
, "long long");
1413 APPEND_BLANK (result
);
1414 string_append (result
, "long");
1418 APPEND_BLANK (result
);
1419 string_append (result
, "int");
1423 APPEND_BLANK (result
);
1424 string_append (result
, "short");
1428 APPEND_BLANK (result
);
1429 string_append (result
, "char");
1433 APPEND_BLANK (result
);
1434 string_append (result
, "long double");
1438 APPEND_BLANK (result
);
1439 string_append (result
, "double");
1443 APPEND_BLANK (result
);
1444 string_append (result
, "float");
1448 if (!isdigit (**type
))
1454 /* An explicit type, such as "6mytype" or "7integer" */
1465 n
= consume_count (type
);
1466 if (strlen (*type
) < n
)
1471 APPEND_BLANK (result
);
1472 string_appendn (result
, *type
, n
);
1483 /* `result' will be initialized in do_type; it will be freed on failure */
1486 do_arg (type
, result
, work
)
1489 struct work_stuff
*work
;
1491 const char *start
= *type
;
1493 if (!do_type (type
, result
, work
))
1499 remember_type (start
, *type
- start
, work
);
1505 remember_type (start
, len
, work
)
1508 struct work_stuff
*work
;
1512 if (work
-> ntypes
>= work
-> typevec_size
)
1514 if (work
-> typevec_size
== 0)
1516 work
-> typevec_size
= 3;
1518 (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
1522 work
-> typevec_size
*= 2;
1524 (char **) xrealloc ((char *)work
-> typevec
,
1525 sizeof (char *) * work
-> typevec_size
);
1528 tem
= (char *) xmalloc (len
+ 1);
1529 memcpy (tem
, start
, len
);
1531 work
-> typevec
[work
-> ntypes
++] = tem
;
1534 /* Process the argument list part of the signature, after any class spec
1535 has been consumed, as well as the first 'F' character (if any). For
1538 "__als__3fooRT0" => process "RT0"
1539 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
1541 DECLP must be already initialised, usually non-empty. It won't be freed
1545 demangle_args (declp
, type
, work
)
1548 struct work_stuff
*work
;
1557 if (PRINT_ARG_TYPES
)
1559 string_append (declp
, "(");
1562 string_append (declp
, "void");
1566 while (**type
!= '_' && **type
!= '\0' && **type
!= 'e')
1568 if ((**type
== 'N') || (**type
== 'T'))
1570 temptype
= *(*type
)++;
1572 if (temptype
== 'N')
1574 if (!get_count (type
, &r
))
1583 if (!get_count (type
, &t
))
1587 if (current_demangling_style
== lucid_demangling
||
1588 current_demangling_style
== cfront_demangling
)
1592 /* Validate the type index. Protect against illegal indices from
1593 malformed type strings. */
1594 if ((t
< 0) || (t
>= work
-> ntypes
))
1600 tem
= work
-> typevec
[t
];
1601 if (need_comma
&& PRINT_ARG_TYPES
)
1603 string_append (declp
, ", ");
1605 if (!do_arg (&tem
, &arg
, work
))
1609 if (PRINT_ARG_TYPES
)
1611 string_appends (declp
, &arg
);
1613 string_delete (&arg
);
1619 if (need_comma
& PRINT_ARG_TYPES
)
1621 string_append (declp
, ", ");
1623 if (!do_arg (type
, &arg
, work
))
1627 if (PRINT_ARG_TYPES
)
1629 string_appends (declp
, &arg
);
1631 string_delete (&arg
);
1639 if (PRINT_ARG_TYPES
)
1643 string_append (declp
, ",");
1645 string_append (declp
, "...");
1649 if (PRINT_ARG_TYPES
)
1651 string_append (declp
, ")");
1657 demangle_function_name (declp
, mangled
, work
, scan
)
1659 const char **mangled
;
1660 struct work_stuff
*work
;
1668 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
1669 string_need (declp
, 1);
1670 *(declp
-> p
) = '\0';
1672 /* Consume the function name, including the "__" separating the name
1673 from the signature. We are guaranteed that SCAN points to the
1676 (*mangled
) = scan
+ 2;
1678 if (current_demangling_style
== lucid_demangling
||
1679 current_demangling_style
== cfront_demangling
)
1682 /* See if we have an ARM style constructor or destructor operator.
1683 If so, then just record it, clear the decl, and return.
1684 We can't build the actual constructor/destructor decl until later,
1685 when we recover the class name from the signature. */
1687 if (strcmp (declp
-> b
, "__ct") == 0)
1689 work
-> constructor
= 1;
1690 string_clear (declp
);
1693 else if (strcmp (declp
-> b
, "__dt") == 0)
1695 work
-> destructor
= 1;
1696 string_clear (declp
);
1701 if (declp
->p
- declp
->b
>= 3
1702 && declp
->b
[0] == 'o'
1703 && declp
->b
[1] == 'p'
1704 && declp
->b
[2] == CPLUS_MARKER
)
1706 /* see if it's an assignment expression */
1707 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
1708 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
1710 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1712 len
= declp
->p
- declp
->b
- 10;
1713 if (strlen (optable
[i
].in
) == len
1714 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
1716 string_clear (declp
);
1717 string_append (declp
, "operator");
1718 string_append (declp
, optable
[i
].out
);
1719 string_append (declp
, "=");
1726 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1728 int len
= declp
->p
- declp
->b
- 3;
1729 if (strlen (optable
[i
].in
) == len
1730 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
1732 string_clear (declp
);
1733 string_append (declp
, "operator");
1734 string_append (declp
, optable
[i
].out
);
1740 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type$", 5) == 0)
1742 /* type conversion operator */
1744 if (do_type (&tem
, &type
, work
))
1746 string_clear (declp
);
1747 string_append (declp
, "operator ");
1748 string_appends (declp
, &type
);
1749 string_delete (&type
);
1752 else if (declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
1755 /* type conversion operator. */
1757 if (do_type (&tem
, &type
, work
))
1759 string_clear (declp
);
1760 string_append (declp
, "operator ");
1761 string_appends (declp
, &type
);
1762 string_delete (&type
);
1765 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
1766 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
1767 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
1769 if (declp
->b
[4] == '\0')
1772 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1774 if (strlen (optable
[i
].in
) == 2
1775 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
1777 string_clear (declp
);
1778 string_append (declp
, "operator");
1779 string_append (declp
, optable
[i
].out
);
1786 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
1789 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1791 if (strlen (optable
[i
].in
) == 3
1792 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
1794 string_clear (declp
);
1795 string_append (declp
, "operator");
1796 string_append (declp
, optable
[i
].out
);
1805 /* a mini string-handling package */
1820 s
->p
= s
->b
= (char *) xmalloc (n
);
1823 else if (s
->e
- s
->p
< n
)
1828 s
->b
= (char *) xrealloc (s
->b
, n
);
1841 s
->b
= s
->e
= s
->p
= NULL
;
1849 s
->b
= s
->p
= s
->e
= NULL
;
1865 return (s
->b
== s
->p
);
1871 string_append (p
, s
)
1876 if (s
== NULL
|| *s
== '\0')
1880 memcpy (p
->p
, s
, n
);
1885 string_appends (p
, s
)
1894 memcpy (p
->p
, s
->b
, n
);
1900 string_appendn (p
, s
, n
)
1908 memcpy (p
->p
, s
, n
);
1914 string_prepend (p
, s
)
1918 if (s
!= NULL
&& *s
!= '\0')
1920 string_prependn (p
, s
, strlen (s
));
1927 string_prepends (p
, s
)
1932 string_prependn (p
, s
->b
, s
->p
- s
->b
);
1939 string_prependn (p
, s
, n
)
1949 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
1953 memcpy (p
->b
, s
, n
);
1958 /* To generate a standalone demangler program for testing purposes, just
1959 compile and link this file with -DMAIN. When run, it demangles each
1960 command line arg, or each stdin string, and prints the result on stdout. */
1965 demangle_it (mangled_name
)
1970 result
= cplus_demangle (mangled_name
, DMGL_PARAMS
| DMGL_ANSI
);
1973 printf ("%s\n", mangled_name
);
1977 printf ("%s\n", result
);
1988 if ((newmem
= malloc ((int) size
)) == NULL
)
1990 fprintf (stderr
, "\nCan't allocate %u bytes\n", size
);
1997 xrealloc (oldmem
, size
)
2003 if ((newmem
= realloc ((char *) oldmem
, (int) size
)) == NULL
)
2005 fprintf (stderr
, "\nCan't reallocate %u bytes\n", size
);
2013 enum demangling_styles current_demangling_style
= gnu_demangling
;
2019 char mangled_name
[128];
2022 extern char *optarg
;
2025 while ((c
= getopt (argc
, argv
, "s:?")) != EOF
)
2030 fprintf (stderr
, "usage: demangle [-s style] [arg1 [arg2]] ...\n");
2031 fprintf (stderr
, "style = { gnu, lucid, cfront }\n");
2032 fprintf (stderr
, "reads args from stdin if none supplied\n");
2036 if (strcmp (optarg
, "gnu") == 0)
2038 current_demangling_style
= gnu_demangling
;
2040 else if (strcmp (optarg
, "lucid") == 0)
2042 current_demangling_style
= lucid_demangling
;
2044 else if (strcmp (optarg
, "cfront") == 0)
2046 current_demangling_style
= cfront_demangling
;
2050 fprintf (stderr
, "unknown demangling style `%s'\n", optarg
);
2058 for ( ; optind
< argc
; optind
++)
2060 demangle_it (argv
[optind
]);
2065 while (gets (mangled_name
))
2067 demangle_it (mangled_name
);