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 #if !defined (GNU_DEMANGLING) && !defined (ARM_DEMANGLING)
36 # define GNU_DEMANGLING 1
39 /* This is '$' on systems where the assembler can deal with that.
40 Where the assembler can't, it's '.' (but on many systems '.' is
41 used for other things). */
43 #if !defined (CPLUS_MARKER)
44 #define CPLUS_MARKER '$'
51 /* Stuff that is shared between sub-routines.
52 * Using a shared structure allows cplus_demangle to be reentrant. */
62 int static_type
; /* A static member function */
63 int const_type
; /* A const member function */
66 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
67 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
69 static const struct optable
75 "nw", " new", DMGL_ANSI
, /* new (1.92, ansi) */
76 "dl", " delete", DMGL_ANSI
, /* new (1.92, ansi) */
77 "new", " new", 0, /* old (1.91, and 1.x) */
78 "delete", " delete", 0, /* old (1.91, and 1.x) */
79 "as", "=", DMGL_ANSI
, /* ansi */
80 "ne", "!=", DMGL_ANSI
, /* old, ansi */
81 "eq", "==", DMGL_ANSI
, /* old, ansi */
82 "ge", ">=", DMGL_ANSI
, /* old, ansi */
83 "gt", ">", DMGL_ANSI
, /* old, ansi */
84 "le", "<=", DMGL_ANSI
, /* old, ansi */
85 "lt", "<", DMGL_ANSI
, /* old, ansi */
86 "plus", "+", 0, /* old */
87 "pl", "+", DMGL_ANSI
, /* ansi */
88 "apl", "+=", DMGL_ANSI
, /* ansi */
89 "minus", "-", 0, /* old */
90 "mi", "-", DMGL_ANSI
, /* ansi */
91 "ami", "-=", DMGL_ANSI
, /* ansi */
92 "mult", "*", 0, /* old */
93 "ml", "*", DMGL_ANSI
, /* ansi */
95 "amu", "*=", DMGL_ANSI
, /* ansi */
97 "aml", "*=", DMGL_ANSI
, /* ansi */
99 "convert", "+", 0, /* old (unary +) */
100 "negate", "-", 0, /* old (unary -) */
101 "trunc_mod", "%", 0, /* old */
102 "md", "%", DMGL_ANSI
, /* ansi */
103 "amd", "%=", DMGL_ANSI
, /* ansi */
104 "trunc_div", "/", 0, /* old */
105 "dv", "/", DMGL_ANSI
, /* ansi */
106 "adv", "/=", DMGL_ANSI
, /* ansi */
107 "truth_andif", "&&", 0, /* old */
108 "aa", "&&", DMGL_ANSI
, /* ansi */
109 "truth_orif", "||", 0, /* old */
110 "oo", "||", DMGL_ANSI
, /* ansi */
111 "truth_not", "!", 0, /* old */
112 "nt", "!", DMGL_ANSI
, /* ansi */
113 "postincrement","++", 0, /* old */
114 "pp", "++", DMGL_ANSI
, /* ansi */
115 "postdecrement","--", 0, /* old */
116 "mm", "--", DMGL_ANSI
, /* ansi */
117 "bit_ior", "|", 0, /* old */
118 "or", "|", DMGL_ANSI
, /* ansi */
119 "aor", "|=", DMGL_ANSI
, /* ansi */
120 "bit_xor", "^", 0, /* old */
121 "er", "^", DMGL_ANSI
, /* ansi */
122 "aer", "^=", DMGL_ANSI
, /* ansi */
123 "bit_and", "&", 0, /* old */
124 "ad", "&", DMGL_ANSI
, /* ansi */
125 "aad", "&=", DMGL_ANSI
, /* ansi */
126 "bit_not", "~", 0, /* old */
127 "co", "~", DMGL_ANSI
, /* ansi */
128 "call", "()", 0, /* old */
129 "cl", "()", DMGL_ANSI
, /* ansi */
130 "alshift", "<<", 0, /* old */
131 "ls", "<<", DMGL_ANSI
, /* ansi */
132 "als", "<<=", DMGL_ANSI
, /* ansi */
133 "arshift", ">>", 0, /* old */
134 "rs", ">>", DMGL_ANSI
, /* ansi */
135 "ars", ">>=", DMGL_ANSI
, /* ansi */
136 "component", "->", 0, /* old */
137 #ifdef LUCID_DEMANGLING
138 "pt", "->", DMGL_ANSI
, /* ansi; Lucid C++ form */
140 "rf", "->", DMGL_ANSI
, /* ansi */
142 "indirect", "*", 0, /* old */
143 "method_call", "->()", 0, /* old */
144 "addr", "&", 0, /* old (unary &) */
145 "array", "[]", 0, /* old */
146 "vc", "[]", DMGL_ANSI
, /* ansi */
147 "compound", ", ", 0, /* old */
148 "cm", ", ", DMGL_ANSI
, /* ansi */
149 "cond", "?:", 0, /* old */
150 "cn", "?:", DMGL_ANSI
, /* psuedo-ansi */
151 "max", ">?", 0, /* old */
152 "mx", ">?", DMGL_ANSI
, /* psuedo-ansi */
153 "min", "<?", 0, /* old */
154 "mn", "<?", DMGL_ANSI
, /* psuedo-ansi */
155 "nop", "", 0, /* old (for operator=) */
156 "rm", "->*", DMGL_ANSI
, /* ansi */
160 typedef struct string
/* Beware: these aren't required to be */
161 { /* '\0' terminated. */
162 char *b
; /* pointer to start of string */
163 char *p
; /* pointer after last character */
164 char *e
; /* pointer after end of allocated space */
167 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
168 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
169 string_prepend(str, " ");}
170 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
171 string_append(str, " ");}
173 /* Prototypes for local functions */
176 mop_up
PARAMS ((string
*, struct work_stuff
*, int));
179 demangle_method_args
PARAMS ((string
*, const char **, struct work_stuff
*));
182 demangle_template
PARAMS ((string
*declp
, const char **, struct work_stuff
*));
185 demangle_qualified
PARAMS ((string
*, const char **, struct work_stuff
*));
188 demangle_class
PARAMS ((string
*, const char **, struct work_stuff
*));
191 demangle_fund_type
PARAMS ((const char **, string
*, struct work_stuff
*));
194 demangle_signature
PARAMS ((string
*, const char **, struct work_stuff
*));
197 demangle_prefix
PARAMS ((string
*, const char **, struct work_stuff
*));
200 gnu_special
PARAMS ((string
*, const char **, struct work_stuff
*));
203 string_need
PARAMS ((string
*, int));
206 string_delete
PARAMS ((string
*));
209 string_init
PARAMS ((string
*));
212 string_clear
PARAMS ((string
*));
215 string_empty
PARAMS ((string
*));
218 string_append
PARAMS ((string
*, const char *));
221 string_appends
PARAMS ((string
*, string
*));
224 string_appendn
PARAMS ((string
*, const char *, int));
227 string_prepend
PARAMS ((string
*, const char *));
230 string_prependn
PARAMS ((string
*, const char *, int));
233 get_count
PARAMS ((const char **, int *));
236 consume_count
PARAMS ((const char **));
239 demangle_args
PARAMS ((string
*, const char **, struct work_stuff
*));
242 do_type
PARAMS ((const char **, string
*, struct work_stuff
*));
245 do_arg
PARAMS ((const char **, string
*, struct work_stuff
*));
248 demangle_function_name
PARAMS ((string
*, const char **, struct work_stuff
*,
252 remember_type
PARAMS ((const char *, int, struct work_stuff
*));
256 string_prepends
PARAMS ((string
*, string
*));
259 /* Translate count to integer, consuming tokens in the process.
260 Conversion terminates on the first non-digit character. */
271 count
+= **type
- '0';
273 } while (isdigit (**type
));
277 /* Takes operator name as e.g. "++" and returns mangled
278 operator name (e.g. "postincrement_expr"), or NULL if not found.
280 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
281 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
284 cplus_mangle_opname (opname
, options
)
291 len
= strlen (opname
);
292 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
294 if (strlen (optable
[i
].out
) == len
295 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
296 && memcmp (optable
[i
].out
, opname
, len
) == 0)
297 return ((char *)optable
[i
].in
);
302 /* char *cplus_demangle (const char *name, int options)
304 If NAME is a mangled function name produced by GNU C++, then
305 a pointer to a malloced string giving a C++ representation
306 of the name will be returned; otherwise NULL will be returned.
307 It is the caller's responsibility to free the string which
310 The OPTIONS arg may contain one or more of the following bits:
312 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
314 DMGL_PARAMS Function parameters are included.
318 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
319 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
320 cplus_demangle ("foo__1Ai", 0) => "A::foo"
322 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
323 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
324 cplus_demangle ("foo__1Afe", 0) => "A::foo"
326 Note that any leading underscores, or other such characters prepended by
327 the compilation system, are presumed to have already been stripped from
331 cplus_demangle (mangled
, options
)
337 struct work_stuff work
[1];
339 char *demangled
= NULL
;
341 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
343 (void) memset ((char *) work
, 0, sizeof (work
));
344 work
-> options
= options
;
347 success
= demangle_prefix (&decl
, &mangled
, work
);
348 if (success
&& (*mangled
!= '\0'))
350 success
= demangle_signature (&decl
, &mangled
, work
);
352 demangled
= mop_up (&decl
, work
, success
);
358 mop_up (declp
, work
, success
)
360 struct work_stuff
*work
;
364 char *demangled
= NULL
;
366 /* Discard the remembered types, if any. */
368 for (i
= 0; i
< work
-> ntypes
; i
++)
370 if (work
-> typevec
[i
] != NULL
)
372 free (work
-> typevec
[i
]);
375 if (work
-> typevec
!= NULL
)
377 free ((char *) work
-> typevec
);
380 /* If demangling was successful, ensure that the demangled string is null
381 terminated and return it. Otherwise, free the demangling decl. */
385 string_delete (declp
);
389 string_appendn (declp
, "", 1);
390 demangled
= declp
-> b
;
399 demangle_signature -- demangle the signature part of a mangled name
404 demangle_signature (string *declp, const char **mangled,
405 struct work_stuff *work);
409 Consume and demangle the signature portion of the mangled name.
411 DECLP is the string where demangled output is being built. At
412 entry it contains the demangled root name from the mangled name
413 prefix. I.E. either a demangled operator name or the root function
414 name. In some special cases, it may contain nothing.
416 *MANGLED points to the current unconsumed location in the mangled
417 name. As tokens are consumed and demangling is performed, the
418 pointer is updated to continuously point at the next token to
421 Demangling GNU style mangled names is nasty because there is no
422 explicit token that marks the start of the outermost function
427 demangle_signature (declp
, mangled
, work
)
429 const char **mangled
;
430 struct work_stuff
*work
;
434 #ifdef GNU_DEMANGLING
438 const char *premangle
;
442 premangle
= *mangled
;
445 while (success
&& (**mangled
!= '\0'))
450 success
= demangle_qualified (declp
, mangled
, work
);
451 #ifdef GNU_DEMANGLING
457 /* Static member function */
459 work
-> static_type
= 1;
463 /* a const member function */
465 work
-> const_type
= 1;
468 case '0': case '1': case '2': case '3': case '4':
469 case '5': case '6': case '7': case '8': case '9':
470 success
= demangle_class (declp
, mangled
, work
);
474 remember_type (premangle
, *mangled
- premangle
, work
);
477 #ifdef GNU_DEMANGLING
484 /* ARM style demangling includes a specific 'F' character after
485 the class name. For GNU style, it is just implied. So we can
486 safely just consume any 'F' at this point and be compatible
487 with either style. */
490 success
= demangle_args (declp
, mangled
, work
);
495 success
= demangle_template (declp
, mangled
, work
);
499 /* At the outermost level, we cannot have a return type specified,
500 so if we run into another '_' at this point we are dealing with
501 a mangled name that is either bogus, or has been mangled by
502 some algorithm we don't know how to deal with. So just
503 reject the entire demangling. */
508 #ifdef GNU_DEMANGLING
509 /* Assume we have stumbled onto the first outermost function
510 argument token, and start processing args. */
512 success
= demangle_args (declp
, mangled
, work
);
514 /* Non-GNU demanglers use a specific token to mark the start
515 of the outermost function argument tokens. Typically 'F',
516 for ARM-demangling, for example. So if we find something
517 we are not prepared for, it must be an error. */
522 #ifdef GNU_DEMANGLING
523 if (success
&& expect_func
)
526 success
= demangle_args (declp
, mangled
, work
);
530 if (success
&& !func_done
)
532 /* Even with ARM style demangling, sometimes there is no explicit
533 function argument tokens if the function takes no arguments. */
534 success
= demangle_args (declp
, mangled
, work
);
536 if (success
&& work
-> static_type
&& PRINT_ARG_TYPES
)
538 string_append (declp
, " static");
540 if (success
&& work
-> const_type
&& PRINT_ARG_TYPES
)
542 string_append (declp
, " const");
550 demangle_method_args (declp
, mangled
, work
)
552 const char **mangled
;
553 struct work_stuff
*work
;
557 if (work
-> static_type
)
559 string_append (declp
, *mangled
+ 1);
560 *mangled
+= strlen (*mangled
);
565 success
= demangle_args (declp
, mangled
, work
);
573 demangle_template (declp
, mangled
, work
)
575 const char **mangled
;
576 struct work_stuff
*work
;
594 string_init (&tname
);
595 string_init (&trawname
);
596 /* get template name */
597 if (!get_count (mangled
, &r
))
601 string_appendn (&tname
, *mangled
, r
);
602 string_appendn (&trawname
, *mangled
, r
);
603 string_appendn (&trawname
, "", 1);
605 string_append (&tname
, "<");
606 /* get size of template parameter list */
607 if (!get_count (mangled
, &r
))
611 for (i
= 0; i
< r
; i
++)
615 string_append (&tname
, ", ");
617 /* Z for type parameters */
618 if (**mangled
== 'Z')
621 success
= do_type (mangled
, &temp
, work
);
622 string_appendn (&temp
, "", 1);
625 string_append (&tname
, temp
.b
);
627 string_delete(&temp
);
635 /* otherwise, value parameter */
641 success
= do_type (mangled
, &temp
, work
);
642 string_appendn (&temp
, "", 1);
645 string_append (&tname
, temp
.b
);
647 string_delete(&temp
);
652 string_append (&tname
, "=");
653 while (*old_p
&& !done
)
659 done
= is_pointer
= 1;
661 case 'C': /* const */
662 case 'S': /* explicitly signed [char] */
663 case 'U': /* unsigned */
664 case 'V': /* volatile */
665 case 'F': /* function */
666 case 'M': /* member function */
670 case 'Q': /* repetition of following */
671 case 'T': /* remembered type */
677 case 'x': /* long long */
680 case 's': /* short */
682 done
= is_integral
= 1;
684 case 'r': /* long double */
685 case 'd': /* double */
686 case 'f': /* float */
695 if (**mangled
== 'm')
697 string_appendn (&tname
, "-", 1);
700 while (isdigit (**mangled
))
702 string_appendn (&tname
, *mangled
, 1);
708 if (**mangled
== 'm')
710 string_appendn (&tname
, "-", 1);
713 while (isdigit (**mangled
))
715 string_appendn (&tname
, *mangled
, 1);
718 if (**mangled
== '.') /* fraction */
720 string_appendn (&tname
, ".", 1);
722 while (isdigit (**mangled
))
724 string_appendn (&tname
, *mangled
, 1);
728 if (**mangled
== 'e') /* exponent */
730 string_appendn (&tname
, "e", 1);
732 while (isdigit (**mangled
))
734 string_appendn (&tname
, *mangled
, 1);
741 if (!get_count (mangled
, &symbol_len
))
746 string_appendn (&tname
, *mangled
, symbol_len
);
747 *mangled
+= symbol_len
;
752 string_append (&tname
, ">::");
753 if (work
-> destructor
)
755 string_append (&tname
, "~");
757 if (work
-> constructor
|| work
-> destructor
)
759 string_append (&tname
, trawname
.b
);
761 string_delete(&trawname
);
765 string_delete(&tname
);
769 string_prepend (declp
, tname
.b
);
770 string_delete (&tname
);
772 if (work
-> static_type
)
774 string_append (declp
, *mangled
+ 1);
775 *mangled
+= strlen (*mangled
);
780 success
= demangle_args (declp
, mangled
, work
);
789 demangle_class -- demangle a mangled class sequence
794 demangle_class (string *declp, const char **mangled,
795 struct work_stuff *work)
799 DECLP points to the buffer into which demangling is being done.
801 *MANGLED points to the current token to be demangled. On input,
802 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
803 On exit, it points to the next token after the mangled class on
804 success, or the first unconsumed token on failure.
806 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
807 we are demangling a constructor or destructor. In this case
808 we prepend "class::class" or "class::~class" to DECLP.
810 Otherwise, we prepend "class::" to the current DECLP.
812 Reset the constructor/destructor flags once they have been
813 "consumed". This allows demangle_class to be called later during
814 the same demangling, to do normal class demangling.
816 Returns 1 if demangling is successful, 0 otherwise.
821 demangle_class (declp
, mangled
, work
)
823 const char **mangled
;
824 struct work_stuff
*work
;
829 n
= consume_count (mangled
);
830 if (strlen (*mangled
) >= n
)
832 if (work
-> constructor
|| work
-> destructor
)
834 string_prependn (declp
, *mangled
, n
);
835 if (work
-> destructor
)
837 string_prepend (declp
, "~");
839 work
-> constructor
= work
-> destructor
= 0;
841 string_prepend (declp
, "::");
842 string_prependn (declp
, *mangled
, n
);
853 demangle_prefix -- consume the mangled name prefix and find signature
858 demangle_prefix (string *declp, const char **mangled,
859 struct work_stuff *work)
863 Consume and demangle the prefix of the mangled name.
865 DECLP points to the string buffer into which demangled output is
866 placed. On entry, the buffer is empty. On exit it contains
867 the root function name, the demangled operator name, or in some
868 special cases either nothing or the completely demangled result.
870 MANGLED points to the current pointer into the mangled name. As each
871 token of the mangled name is consumed, it is updated. Upon entry
872 the current mangled name pointer points to the first character of
873 the mangled name. Upon exit, it should point to the first character
874 of the signature if demangling was successful, or to the first
875 unconsumed character if demangling of the prefix was unsuccessful.
877 Returns 1 on success, 0 otherwise.
881 demangle_prefix (declp
, mangled
, work
)
883 const char **mangled
;
884 struct work_stuff
*work
;
889 if ((scan
= strstr (*mangled
, "__")) == NULL
)
891 success
= gnu_special (declp
, mangled
, work
);
893 else if (work
-> static_type
)
895 if (!isdigit (scan
[0]) && (scan
[0] != 't'))
900 else if ((scan
== *mangled
) && (isdigit (scan
[2]) || (scan
[2] == 'Q')))
902 /* A GNU style constructor starts with "__<digit>" or "__Q". */
903 work
-> constructor
= 1;
906 else if ((scan
== *mangled
) && !isdigit (scan
[2]) && (scan
[2] != 't'))
908 /* Mangled name starts with "__". Skip over any leading '_' characters,
909 then find the next "__" that separates the prefix from the signature.
915 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
917 /* No separator (I.E. "__not_mangled"), or empty signature
918 (I.E. "__not_mangled_either__") */
923 demangle_function_name (declp
, mangled
, work
, scan
);
926 else if (*(scan
+ 2) != '\0')
928 /* Mangled name does not start with "__" but does have one somewhere
929 in there with non empty stuff after it. Looks like a global
931 demangle_function_name (declp
, mangled
, work
, scan
);
935 /* Doesn't look like a mangled name */
945 gnu_special -- special handling of gnu mangled strings
950 gnu_special (string *declp, const char **mangled,
951 struct work_stuff *work)
956 Process some special GNU style mangling forms that don't fit
957 the normal pattern. For example:
959 _$_3foo (destructor for class foo)
960 _vt$foo (virtual table)
961 _3foo$varname (static data member)
965 gnu_special (declp
, mangled
, work
)
967 const char **mangled
;
968 struct work_stuff
*work
;
974 if ((*mangled
)[0] == '_'
975 && (*mangled
)[1] == CPLUS_MARKER
976 && (*mangled
)[2] == '_')
978 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
980 work
-> destructor
= 1;
982 else if ((*mangled
)[0] == '_'
983 && (*mangled
)[1] == 'v'
984 && (*mangled
)[2] == 't'
985 && (*mangled
)[3] == CPLUS_MARKER
)
987 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
988 and create the decl. Note that we consume the entire mangled
989 input string, which means that demangle_signature has no work
992 n
= strlen (*mangled
);
993 string_appendn (declp
, *mangled
, n
);
994 string_append (declp
, " virtual table");
997 else if ((*mangled
)[0] == '_'
998 && isdigit ((*mangled
)[1])
999 && (p
= strchr (*mangled
, CPLUS_MARKER
)) != NULL
)
1001 /* static data member, "_3foo$varname" for example */
1004 n
= consume_count (mangled
);
1005 string_appendn (declp
, *mangled
, n
);
1006 string_append (declp
, "::");
1008 string_appendn (declp
, p
, n
);
1018 /* Do a qualified name, such as "Q25Outer5Inner" for "Outer::Inner" */
1021 demangle_qualified (declp
, mangled
, work
)
1023 const char **mangled
;
1024 struct work_stuff
*work
;
1031 n
= (*mangled
)[1] - '0';
1032 if (n
>= 0 && n
<= 9)
1034 if ((*mangled
)[2] == '_')
1040 string_init (&class);
1043 success
= do_type (mangled
, &tmp
, work
);
1044 string_appends (&class, &tmp
);
1045 string_append (&class, "::");
1046 if (n
== 0 && (work
-> constructor
|| work
-> destructor
))
1048 if (work
-> destructor
)
1050 string_append (&class, "~");
1052 string_appends (&class, &tmp
);
1054 string_delete (&tmp
);
1056 work
-> constructor
= work
-> destructor
= 0;
1057 string_prependn (declp
, class.b
, class.p
- class.b
);
1058 string_delete (&class);
1067 get_count -- convert an ascii count to integer, consuming tokens
1072 get_count (const char **type, int *count)
1076 Return 0 if no conversion is performed, 1 if a string is converted.
1080 get_count (type
, count
)
1087 if (!isdigit (**type
))
1093 *count
= **type
- '0';
1095 if (isdigit (**type
))
1105 while (isdigit (*p
));
1116 /* result will be initialised here; it will be freed on failure */
1119 do_type (type
, result
, work
)
1122 struct work_stuff
*work
;
1128 const char *remembered_type
;
1132 string_init (&decl
);
1133 string_init (result
);
1137 while (success
&& !done
)
1142 /* A qualified name, such as "Outer::Inner". Note qualifier count
1143 is limited to a single digit (0-9 qualifiers). */
1145 n
= (*type
)[1] - '0';
1150 if ((*type
)[2] == '_') /* cfront style */
1157 do_type (type
, result
, work
);
1161 /* A pointer type */
1164 string_prepend (&decl
, "*");
1167 /* A reference type */
1170 string_prepend (&decl
, "&");
1173 /* A back reference to a previously seen type */
1176 if (!get_count (type
, &n
) || n
>= work
-> ntypes
)
1182 remembered_type
= work
-> typevec
[n
];
1183 type
= &remembered_type
;
1190 if (!STRING_EMPTY (&decl
) && decl
.b
[0] == '*')
1192 string_prepend (&decl
, "(");
1193 string_append (&decl
, ")");
1195 /* After picking off the function args, we expect to either find the
1196 function return type (preceded by an '_') or the end of the
1198 if (!demangle_args (&decl
, type
, work
)
1199 || (**type
!= '_' && **type
!= '\0'))
1203 if (success
&& (**type
== '_'))
1215 member
= **type
== 'M';
1217 if (!isdigit (**type
))
1222 n
= consume_count (type
);
1223 if (strlen (*type
) < n
)
1228 string_append (&decl
, ")");
1229 string_prepend (&decl
, "::");
1230 string_prependn (&decl
, *type
, n
);
1231 string_prepend (&decl
, "(");
1245 if (*(*type
)++ != 'F')
1251 if ((member
&& !demangle_args (&decl
, type
, work
))
1258 if (! PRINT_ANSI_QUALIFIERS
)
1264 APPEND_BLANK (&decl
);
1265 string_append (&decl
, "const");
1269 APPEND_BLANK (&decl
);
1270 string_append (&decl
, "volatile");
1276 if ((*type
)[1] == 'P')
1279 if (PRINT_ANSI_QUALIFIERS
)
1281 if (!STRING_EMPTY (&decl
))
1283 string_prepend (&decl
, " ");
1285 string_prepend (&decl
, "const");
1297 success
= demangle_fund_type (type
, result
, work
);
1301 if (!STRING_EMPTY (&decl
))
1303 string_append (result
, " ");
1304 string_appends (result
, &decl
);
1309 string_delete (result
);
1311 string_delete (&decl
);
1315 /* Given a pointer to a type string that represents a fundamental type
1316 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
1317 string in which the demangled output is being built in RESULT, and
1318 the WORK structure, decode the types and add them to the result.
1323 "Sl" => "signed long"
1324 "CUs" => "const unsigned short"
1329 demangle_fund_type (type
, result
, work
)
1332 struct work_stuff
*work
;
1338 /* First pick off any type qualifiers. There can be more than one. */
1346 if (PRINT_ANSI_QUALIFIERS
)
1348 APPEND_BLANK (result
);
1349 string_append (result
, "const");
1354 APPEND_BLANK (result
);
1355 string_append (result
, "unsigned");
1357 case 'S': /* signed char only */
1359 APPEND_BLANK (result
);
1360 string_append (result
, "signed");
1364 if (PRINT_ANSI_QUALIFIERS
)
1366 APPEND_BLANK (result
);
1367 string_append (result
, "volatile");
1376 /* Now pick off the fundamental type. There can be only one. */
1385 APPEND_BLANK (result
);
1386 string_append (result
, "void");
1390 APPEND_BLANK (result
);
1391 string_append (result
, "long long");
1395 APPEND_BLANK (result
);
1396 string_append (result
, "long");
1400 APPEND_BLANK (result
);
1401 string_append (result
, "int");
1405 APPEND_BLANK (result
);
1406 string_append (result
, "short");
1410 APPEND_BLANK (result
);
1411 string_append (result
, "char");
1415 APPEND_BLANK (result
);
1416 string_append (result
, "long double");
1420 APPEND_BLANK (result
);
1421 string_append (result
, "double");
1425 APPEND_BLANK (result
);
1426 string_append (result
, "float");
1430 if (!isdigit (**type
))
1436 /* An explicit type, such as "6mytype" or "7integer" */
1447 n
= consume_count (type
);
1448 if (strlen (*type
) < n
)
1453 APPEND_BLANK (result
);
1454 string_appendn (result
, *type
, n
);
1465 /* `result' will be initialized in do_type; it will be freed on failure */
1468 do_arg (type
, result
, work
)
1471 struct work_stuff
*work
;
1473 const char *start
= *type
;
1475 if (!do_type (type
, result
, work
))
1481 remember_type (start
, *type
- start
, work
);
1487 remember_type (start
, len
, work
)
1490 struct work_stuff
*work
;
1494 if (work
-> ntypes
>= work
-> typevec_size
)
1496 if (work
-> typevec_size
== 0)
1498 work
-> typevec_size
= 3;
1500 (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
1504 work
-> typevec_size
*= 2;
1506 (char **) xrealloc ((char *)work
-> typevec
,
1507 sizeof (char *) * work
-> typevec_size
);
1510 tem
= (char *) xmalloc (len
+ 1);
1511 memcpy (tem
, start
, len
);
1513 work
-> typevec
[work
-> ntypes
++] = tem
;
1516 /* Process the argument list part of the signature, after any class spec
1517 has been consumed, as well as the first 'F' character (if any). For
1520 "__als__3fooRT0" => process "RT0"
1521 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
1523 DECLP must be already initialised, usually non-empty. It won't be freed
1527 demangle_args (declp
, type
, work
)
1530 struct work_stuff
*work
;
1539 if (PRINT_ARG_TYPES
)
1541 string_append (declp
, "(");
1544 string_append (declp
, "void");
1548 while (**type
!= '_' && **type
!= '\0' && **type
!= 'e')
1550 if ((**type
== 'N') || (**type
== 'T'))
1552 temptype
= *(*type
)++;
1554 if (temptype
== 'N')
1556 if (!get_count (type
, &r
))
1565 if (!get_count (type
, &t
))
1569 #ifdef ARM_DEMANGLING
1572 if (t
>= work
-> ntypes
)
1578 tem
= work
-> typevec
[t
];
1579 if (need_comma
&& PRINT_ARG_TYPES
)
1581 string_append (declp
, ", ");
1583 if (!do_arg (&tem
, &arg
, work
))
1587 if (PRINT_ARG_TYPES
)
1589 string_appends (declp
, &arg
);
1591 string_delete (&arg
);
1597 if (need_comma
& PRINT_ARG_TYPES
)
1599 string_append (declp
, ", ");
1601 if (!do_arg (type
, &arg
, work
))
1605 if (PRINT_ARG_TYPES
)
1607 string_appends (declp
, &arg
);
1609 string_delete (&arg
);
1617 if (PRINT_ARG_TYPES
)
1621 string_append (declp
, ",");
1623 string_append (declp
, "...");
1627 if (PRINT_ARG_TYPES
)
1629 string_append (declp
, ")");
1635 demangle_function_name (declp
, mangled
, work
, scan
)
1637 const char **mangled
;
1638 struct work_stuff
*work
;
1646 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
1647 string_need (declp
, 1);
1648 *(declp
-> p
) = '\0';
1650 /* Consume the function name, including the "__" separating the name
1651 from the signature. We are guaranteed that SCAN points to the
1654 (*mangled
) = scan
+ 2;
1656 #ifdef ARM_DEMANGLING
1658 /* See if we have an ARM style constructor or destructor operator.
1659 If so, then just record it, clear the decl, and return.
1660 We can't build the actual constructor/destructor decl until later,
1661 when we recover the class name from the signature. */
1663 if (strcmp (declp
-> b
, "__ct") == 0)
1665 work
-> constructor
= 1;
1666 string_clear (declp
);
1669 else if (strcmp (declp
-> b
, "__dt") == 0)
1671 work
-> destructor
= 1;
1672 string_clear (declp
);
1678 if (declp
->p
- declp
->b
>= 3
1679 && declp
->b
[0] == 'o'
1680 && declp
->b
[1] == 'p'
1681 && declp
->b
[2] == CPLUS_MARKER
)
1683 /* see if it's an assignment expression */
1684 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
1685 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
1687 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1689 len
= declp
->p
- declp
->b
- 10;
1690 if (strlen (optable
[i
].in
) == len
1691 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
1693 string_clear (declp
);
1694 string_append (declp
, "operator");
1695 string_append (declp
, optable
[i
].out
);
1696 string_append (declp
, "=");
1703 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1705 int len
= declp
->p
- declp
->b
- 3;
1706 if (strlen (optable
[i
].in
) == len
1707 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
1709 string_clear (declp
);
1710 string_append (declp
, "operator");
1711 string_append (declp
, optable
[i
].out
);
1717 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type$", 5) == 0)
1719 /* type conversion operator */
1721 if (do_type (&tem
, &type
, work
))
1723 string_clear (declp
);
1724 string_append (declp
, "operator ");
1725 string_appends (declp
, &type
);
1726 string_delete (&type
);
1729 else if (declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
1732 /* type conversion operator. */
1734 if (do_type (&tem
, &type
, work
))
1736 string_clear (declp
);
1737 string_append (declp
, "operator ");
1738 string_appends (declp
, &type
);
1739 string_delete (&type
);
1742 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
1743 && declp
->b
[2] >= 'a' && declp
->b
[2] <= 'z'
1744 && declp
->b
[3] >= 'a' && declp
->b
[3] <= 'z')
1746 if (declp
->b
[4] == '\0')
1749 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1751 if (strlen (optable
[i
].in
) == 2
1752 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
1754 string_clear (declp
);
1755 string_append (declp
, "operator");
1756 string_append (declp
, optable
[i
].out
);
1763 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
1766 for (i
= 0; i
< sizeof (optable
) / sizeof (optable
[0]); i
++)
1768 if (strlen (optable
[i
].in
) == 3
1769 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
1771 string_clear (declp
);
1772 string_append (declp
, "operator");
1773 string_append (declp
, optable
[i
].out
);
1782 /* a mini string-handling package */
1797 s
->p
= s
->b
= (char *) xmalloc (n
);
1800 else if (s
->e
- s
->p
< n
)
1805 s
->b
= (char *) xrealloc (s
->b
, n
);
1818 s
->b
= s
->e
= s
->p
= NULL
;
1826 s
->b
= s
->p
= s
->e
= NULL
;
1840 return (s
->b
== s
->p
);
1844 string_append (p
, s
)
1849 if (s
== NULL
|| *s
== '\0')
1853 memcpy (p
->p
, s
, n
);
1858 string_appends (p
, s
)
1867 memcpy (p
->p
, s
->b
, n
);
1873 string_appendn (p
, s
, n
)
1881 memcpy (p
->p
, s
, n
);
1887 string_prepend (p
, s
)
1891 if (s
!= NULL
&& *s
!= '\0')
1893 string_prependn (p
, s
, strlen (s
));
1899 string_prepends (p
, s
)
1904 string_prependn (p
, s
->b
, s
->p
- s
->b
);
1910 string_prependn (p
, s
, n
)
1920 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
1924 memcpy (p
->b
, s
, n
);
1929 /* To generate a standalone demangler program for testing purposes, just
1930 compile and link this file with -DMAIN. When run, it demangles each
1931 command line arg, or each stdin string, and prints the result on stdout. */
1936 demangle_it (mangled_name
)
1941 result
= cplus_demangle (mangled_name
, DMGL_PARAMS
| DMGL_ANSI
);
1944 printf ("%s\n", mangled_name
);
1948 printf ("%s\n", result
);
1959 if ((newmem
= malloc ((int) size
)) == NULL
)
1961 fprintf (stderr
, "\nCan't allocate %u bytes\n", size
);
1968 xrealloc (oldmem
, size
)
1974 if ((newmem
= realloc ((char *) oldmem
, (int) size
)) == NULL
)
1976 fprintf (stderr
, "\nCan't reallocate %u bytes\n", size
);
1986 char mangled_name
[128];
1995 demangle_it (*argv
);
2000 while (gets (mangled_name
))
2002 demangle_it (mangled_name
);
This page took 0.071234 seconds and 4 git commands to generate.