1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997 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 file is part of the libiberty library.
7 Libiberty is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 Libiberty is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with libiberty; see the file COPYING.LIB. If
19 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
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 /* This file lives in both GCC and libiberty. When making changes, please
29 try not to break either. */
32 #include <sys/types.h>
41 #undef CURRENT_DEMANGLING_STYLE
42 #define CURRENT_DEMANGLING_STYLE work->options
44 extern char *xmalloc PARAMS((unsigned));
45 extern char *xrealloc PARAMS((char *, unsigned));
47 static const char *mystrstr PARAMS ((const char *, const char *));
53 register const char *p = s1;
54 register int len = strlen (s2);
56 for (; (p = strchr (p, *s2)) != 0; p++)
58 if (strncmp (p, s2, len) == 0)
66 /* In order to allow a single demangler executable to demangle strings
67 using various common values of CPLUS_MARKER, as well as any specific
68 one set at compile time, we maintain a string containing all the
69 commonly used ones, and check to see if the marker we are looking for
70 is in that string. CPLUS_MARKER is usually '$' on systems where the
71 assembler can deal with that. Where the assembler can't, it's usually
72 '.' (but on many systems '.' is used for other things). We put the
73 current defined CPLUS_MARKER first (which defaults to '$'), followed
74 by the next most common value, followed by an explicit '$' in case
75 the value of CPLUS_MARKER is not '$'.
77 We could avoid this if we could just get g++ to tell us what the actual
78 cplus marker character is as part of the debug information, perhaps by
79 ensuring that it is the character that terminates the gcc<n>_compiled
80 marker symbol (FIXME). */
82 #if !defined (CPLUS_MARKER)
83 #define CPLUS_MARKER '$'
86 enum demangling_styles current_demangling_style = gnu_demangling;
88 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
91 set_cplus_marker_for_demangling (ch)
94 cplus_markers[0] = ch;
97 /* Stuff that is shared between sub-routines.
98 Using a shared structure allows cplus_demangle to be reentrant. */
108 int static_type; /* A static member function */
109 int const_type; /* A const member function */
110 char **tmpl_argvec; /* Template function arguments. */
111 int ntmpl_args; /* The number of template function arguments. */
114 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
115 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
117 static const struct optable
123 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
124 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
125 {"new", " new", 0}, /* old (1.91, and 1.x) */
126 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
127 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
128 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
129 {"as", "=", DMGL_ANSI}, /* ansi */
130 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
131 {"eq", "==", DMGL_ANSI}, /* old, ansi */
132 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
133 {"gt", ">", DMGL_ANSI}, /* old, ansi */
134 {"le", "<=", DMGL_ANSI}, /* old, ansi */
135 {"lt", "<", DMGL_ANSI}, /* old, ansi */
136 {"plus", "+", 0}, /* old */
137 {"pl", "+", DMGL_ANSI}, /* ansi */
138 {"apl", "+=", DMGL_ANSI}, /* ansi */
139 {"minus", "-", 0}, /* old */
140 {"mi", "-", DMGL_ANSI}, /* ansi */
141 {"ami", "-=", DMGL_ANSI}, /* ansi */
142 {"mult", "*", 0}, /* old */
143 {"ml", "*", DMGL_ANSI}, /* ansi */
144 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
145 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
146 {"convert", "+", 0}, /* old (unary +) */
147 {"negate", "-", 0}, /* old (unary -) */
148 {"trunc_mod", "%", 0}, /* old */
149 {"md", "%", DMGL_ANSI}, /* ansi */
150 {"amd", "%=", DMGL_ANSI}, /* ansi */
151 {"trunc_div", "/", 0}, /* old */
152 {"dv", "/", DMGL_ANSI}, /* ansi */
153 {"adv", "/=", DMGL_ANSI}, /* ansi */
154 {"truth_andif", "&&", 0}, /* old */
155 {"aa", "&&", DMGL_ANSI}, /* ansi */
156 {"truth_orif", "||", 0}, /* old */
157 {"oo", "||", DMGL_ANSI}, /* ansi */
158 {"truth_not", "!", 0}, /* old */
159 {"nt", "!", DMGL_ANSI}, /* ansi */
160 {"postincrement","++", 0}, /* old */
161 {"pp", "++", DMGL_ANSI}, /* ansi */
162 {"postdecrement","--", 0}, /* old */
163 {"mm", "--", DMGL_ANSI}, /* ansi */
164 {"bit_ior", "|", 0}, /* old */
165 {"or", "|", DMGL_ANSI}, /* ansi */
166 {"aor", "|=", DMGL_ANSI}, /* ansi */
167 {"bit_xor", "^", 0}, /* old */
168 {"er", "^", DMGL_ANSI}, /* ansi */
169 {"aer", "^=", DMGL_ANSI}, /* ansi */
170 {"bit_and", "&", 0}, /* old */
171 {"ad", "&", DMGL_ANSI}, /* ansi */
172 {"aad", "&=", DMGL_ANSI}, /* ansi */
173 {"bit_not", "~", 0}, /* old */
174 {"co", "~", DMGL_ANSI}, /* ansi */
175 {"call", "()", 0}, /* old */
176 {"cl", "()", DMGL_ANSI}, /* ansi */
177 {"alshift", "<<", 0}, /* old */
178 {"ls", "<<", DMGL_ANSI}, /* ansi */
179 {"als", "<<=", DMGL_ANSI}, /* ansi */
180 {"arshift", ">>", 0}, /* old */
181 {"rs", ">>", DMGL_ANSI}, /* ansi */
182 {"ars", ">>=", DMGL_ANSI}, /* ansi */
183 {"component", "->", 0}, /* old */
184 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
185 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
186 {"indirect", "*", 0}, /* old */
187 {"method_call", "->()", 0}, /* old */
188 {"addr", "&", 0}, /* old (unary &) */
189 {"array", "[]", 0}, /* old */
190 {"vc", "[]", DMGL_ANSI}, /* ansi */
191 {"compound", ", ", 0}, /* old */
192 {"cm", ", ", DMGL_ANSI}, /* ansi */
193 {"cond", "?:", 0}, /* old */
194 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
195 {"max", ">?", 0}, /* old */
196 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
197 {"min", "<?", 0}, /* old */
198 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
199 {"nop", "", 0}, /* old (for operator=) */
200 {"rm", "->*", DMGL_ANSI}, /* ansi */
201 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
205 typedef struct string /* Beware: these aren't required to be */
206 { /* '\0' terminated. */
207 char *b; /* pointer to start of string */
208 char *p; /* pointer after last character */
209 char *e; /* pointer after end of allocated space */
212 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
213 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
214 string_prepend(str, " ");}
215 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
216 string_append(str, " ");}
218 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
219 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
221 /* Prototypes for local functions */
224 mop_up PARAMS ((struct work_stuff *, string *, int));
228 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
232 demangle_template_template_parm PARAMS ((struct work_stuff *work,
233 const char **, string *));
236 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
240 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
244 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
247 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
250 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
254 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
257 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
260 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
263 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
266 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
269 arm_special PARAMS ((const char **, string *));
272 string_need PARAMS ((string *, int));
275 string_delete PARAMS ((string *));
278 string_init PARAMS ((string *));
281 string_clear PARAMS ((string *));
285 string_empty PARAMS ((string *));
289 string_append PARAMS ((string *, const char *));
292 string_appends PARAMS ((string *, string *));
295 string_appendn PARAMS ((string *, const char *, int));
298 string_prepend PARAMS ((string *, const char *));
301 string_prependn PARAMS ((string *, const char *, int));
304 get_count PARAMS ((const char **, int *));
307 consume_count PARAMS ((const char **));
310 consume_count_with_underscores PARAMS ((const char**));
313 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
316 do_type PARAMS ((struct work_stuff *, const char **, string *));
319 do_arg PARAMS ((struct work_stuff *, const char **, string *));
322 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
326 remember_type PARAMS ((struct work_stuff *, const char *, int));
329 forget_types PARAMS ((struct work_stuff *));
332 string_prepends PARAMS ((string *, string *));
335 demangle_template_value_parm PARAMS ((struct work_stuff*,
336 const char**, string*));
338 /* Translate count to integer, consuming tokens in the process.
339 Conversion terminates on the first non-digit character.
340 Trying to consume something that isn't a count results in
341 no consumption of input and a return of 0. */
349 while (isdigit (**type))
352 count += **type - '0';
359 /* Like consume_count, but for counts that are preceded and followed
360 by '_' if they are greater than 10. Also, -1 is returned for
361 failure, since 0 can be a valid value. */
364 consume_count_with_underscores (mangled)
365 const char **mangled;
369 if (**mangled == '_')
372 if (!isdigit (**mangled))
375 idx = consume_count (mangled);
376 if (**mangled != '_')
377 /* The trailing underscore was missing. */
384 if (**mangled < '0' || **mangled > '9')
387 idx = **mangled - '0';
395 cplus_demangle_opname (opname, result, options)
400 int len, i, len1, ret;
402 struct work_stuff work[1];
405 len = strlen(opname);
408 work->options = options;
410 if (opname[0] == '_' && opname[1] == '_'
411 && opname[2] == 'o' && opname[3] == 'p')
414 /* type conversion operator. */
416 if (do_type (work, &tem, &type))
418 strcat (result, "operator ");
419 strncat (result, type.b, type.p - type.b);
420 string_delete (&type);
424 else if (opname[0] == '_' && opname[1] == '_'
425 && opname[2] >= 'a' && opname[2] <= 'z'
426 && opname[3] >= 'a' && opname[3] <= 'z')
428 if (opname[4] == '\0')
431 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
433 if (strlen (optable[i].in) == 2
434 && memcmp (optable[i].in, opname + 2, 2) == 0)
436 strcat (result, "operator");
437 strcat (result, optable[i].out);
445 if (opname[2] == 'a' && opname[5] == '\0')
448 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
450 if (strlen (optable[i].in) == 3
451 && memcmp (optable[i].in, opname + 2, 3) == 0)
453 strcat (result, "operator");
454 strcat (result, optable[i].out);
465 && strchr (cplus_markers, opname[2]) != NULL)
467 /* see if it's an assignment expression */
468 if (len >= 10 /* op$assign_ */
469 && memcmp (opname + 3, "assign_", 7) == 0)
471 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
474 if (strlen (optable[i].in) == len1
475 && memcmp (optable[i].in, opname + 10, len1) == 0)
477 strcat (result, "operator");
478 strcat (result, optable[i].out);
479 strcat (result, "=");
487 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
490 if (strlen (optable[i].in) == len1
491 && memcmp (optable[i].in, opname + 3, len1) == 0)
493 strcat (result, "operator");
494 strcat (result, optable[i].out);
501 else if (len >= 5 && memcmp (opname, "type", 4) == 0
502 && strchr (cplus_markers, opname[4]) != NULL)
504 /* type conversion operator */
506 if (do_type (work, &tem, &type))
508 strcat (result, "operator ");
509 strncat (result, type.b, type.p - type.b);
510 string_delete (&type);
517 /* Takes operator name as e.g. "++" and returns mangled
518 operator name (e.g. "postincrement_expr"), or NULL if not found.
520 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
521 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
524 cplus_mangle_opname (opname, options)
531 len = strlen (opname);
532 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
534 if (strlen (optable[i].out) == len
535 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
536 && memcmp (optable[i].out, opname, len) == 0)
537 return optable[i].in;
542 /* char *cplus_demangle (const char *mangled, int options)
544 If MANGLED is a mangled function name produced by GNU C++, then
545 a pointer to a malloced string giving a C++ representation
546 of the name will be returned; otherwise NULL will be returned.
547 It is the caller's responsibility to free the string which
550 The OPTIONS arg may contain one or more of the following bits:
552 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
554 DMGL_PARAMS Function parameters are included.
558 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
559 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
560 cplus_demangle ("foo__1Ai", 0) => "A::foo"
562 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
563 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
564 cplus_demangle ("foo__1Afe", 0) => "A::foo"
566 Note that any leading underscores, or other such characters prepended by
567 the compilation system, are presumed to have already been stripped from
571 cplus_demangle (mangled, options)
577 struct work_stuff work[1];
578 char *demangled = NULL;
580 if ((mangled != NULL) && (*mangled != '\0'))
582 memset ((char *) work, 0, sizeof (work));
583 work -> options = options;
584 if ((work->options & DMGL_STYLE_MASK) == 0)
585 work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
589 /* First check to see if gnu style demangling is active and if the
590 string to be demangled contains a CPLUS_MARKER. If so, attempt to
591 recognize one of the gnu special forms rather than looking for a
592 standard prefix. In particular, don't worry about whether there
593 is a "__" string in the mangled string. Consider "_$_5__foo" for
596 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
598 success = gnu_special (work, &mangled, &decl);
602 success = demangle_prefix (work, &mangled, &decl);
604 if (success && (*mangled != '\0'))
606 success = demangle_signature (work, &mangled, &decl);
608 if (work->constructor == 2)
610 string_prepend(&decl, "global constructors keyed to ");
611 work->constructor = 0;
613 else if (work->destructor == 2)
615 string_prepend(&decl, "global destructors keyed to ");
616 work->destructor = 0;
618 demangled = mop_up (work, &decl, success);
624 mop_up (work, declp, success)
625 struct work_stuff *work;
629 char *demangled = NULL;
631 /* Discard the remembered types, if any. */
634 if (work -> typevec != NULL)
636 free ((char *) work -> typevec);
638 if (work->tmpl_argvec)
642 for (i = 0; i < work->ntmpl_args; i++)
643 if (work->tmpl_argvec[i])
644 free ((char*) work->tmpl_argvec[i]);
646 free ((char*) work->tmpl_argvec);
649 /* If demangling was successful, ensure that the demangled string is null
650 terminated and return it. Otherwise, free the demangling decl. */
654 string_delete (declp);
658 string_appendn (declp, "", 1);
659 demangled = declp -> b;
668 demangle_signature -- demangle the signature part of a mangled name
673 demangle_signature (struct work_stuff *work, const char **mangled,
678 Consume and demangle the signature portion of the mangled name.
680 DECLP is the string where demangled output is being built. At
681 entry it contains the demangled root name from the mangled name
682 prefix. I.E. either a demangled operator name or the root function
683 name. In some special cases, it may contain nothing.
685 *MANGLED points to the current unconsumed location in the mangled
686 name. As tokens are consumed and demangling is performed, the
687 pointer is updated to continuously point at the next token to
690 Demangling GNU style mangled names is nasty because there is no
691 explicit token that marks the start of the outermost function
695 demangle_signature (work, mangled, declp)
696 struct work_stuff *work;
697 const char **mangled;
703 int expect_return_type = 0;
704 const char *oldmangled = NULL;
708 while (success && (**mangled != '\0'))
713 oldmangled = *mangled;
714 success = demangle_qualified (work, mangled, declp, 1, 0);
717 remember_type (work, oldmangled, *mangled - oldmangled);
719 if (AUTO_DEMANGLING || GNU_DEMANGLING)
727 /* Static member function */
728 if (oldmangled == NULL)
730 oldmangled = *mangled;
733 work -> static_type = 1;
737 /* a const member function */
738 if (oldmangled == NULL)
740 oldmangled = *mangled;
743 work -> const_type = 1;
746 case '0': case '1': case '2': case '3': case '4':
747 case '5': case '6': case '7': case '8': case '9':
748 if (oldmangled == NULL)
750 oldmangled = *mangled;
752 success = demangle_class (work, mangled, declp);
755 remember_type (work, oldmangled, *mangled - oldmangled);
757 if (AUTO_DEMANGLING || GNU_DEMANGLING)
766 /* ARM style demangling includes a specific 'F' character after
767 the class name. For GNU style, it is just implied. So we can
768 safely just consume any 'F' at this point and be compatible
769 with either style. */
775 /* For lucid/ARM style we have to forget any types we might
776 have remembered up to this point, since they were not argument
777 types. GNU style considers all types seen as available for
778 back references. See comment in demangle_args() */
780 if (LUCID_DEMANGLING || ARM_DEMANGLING)
784 success = demangle_args (work, mangled, declp);
789 string_init(&trawname);
791 if (oldmangled == NULL)
793 oldmangled = *mangled;
795 success = demangle_template (work, mangled, &tname, &trawname, 1);
798 remember_type (work, oldmangled, *mangled - oldmangled);
800 string_append(&tname, (work -> options & DMGL_JAVA) ? "." : "::");
801 string_prepends(declp, &tname);
802 if (work -> destructor & 1)
804 string_prepend (&trawname, "~");
805 string_appends (declp, &trawname);
806 work->destructor -= 1;
808 if ((work->constructor & 1) || (work->destructor & 1))
810 string_appends (declp, &trawname);
811 work->constructor -= 1;
813 string_delete(&trawname);
814 string_delete(&tname);
820 if (GNU_DEMANGLING && expect_return_type)
822 /* Read the return type. */
824 string_init (&return_type);
827 success = do_type (work, mangled, &return_type);
828 APPEND_BLANK (&return_type);
830 string_prepends (declp, &return_type);
831 string_delete (&return_type);
835 /* At the outermost level, we cannot have a return type specified,
836 so if we run into another '_' at this point we are dealing with
837 a mangled name that is either bogus, or has been mangled by
838 some algorithm we don't know how to deal with. So just
839 reject the entire demangling. */
846 /* A G++ template function. Read the template arguments. */
847 success = demangle_template (work, mangled, declp, 0, 0);
848 if (!(work->constructor & 1))
849 expect_return_type = 1;
858 if (AUTO_DEMANGLING || GNU_DEMANGLING)
860 /* Assume we have stumbled onto the first outermost function
861 argument token, and start processing args. */
863 success = demangle_args (work, mangled, declp);
867 /* Non-GNU demanglers use a specific token to mark the start
868 of the outermost function argument tokens. Typically 'F',
869 for ARM-demangling, for example. So if we find something
870 we are not prepared for, it must be an error. */
876 if (AUTO_DEMANGLING || GNU_DEMANGLING)
879 if (success && expect_func)
882 success = demangle_args (work, mangled, declp);
883 /* Since template include the mangling of their return types,
884 we must set expect_func to 0 so that we don't try do
885 demangle more arguments the next time we get here. */
890 if (success && !func_done)
892 if (AUTO_DEMANGLING || GNU_DEMANGLING)
894 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
895 bar__3fooi is 'foo::bar(int)'. We get here when we find the
896 first case, and need to ensure that the '(void)' gets added to
897 the current declp. Note that with ARM, the first case
898 represents the name of a static data member 'foo::bar',
899 which is in the current declp, so we leave it alone. */
900 success = demangle_args (work, mangled, declp);
903 if (success && work -> static_type && PRINT_ARG_TYPES)
905 string_append (declp, " static");
907 if (success && work -> const_type && PRINT_ARG_TYPES)
909 string_append (declp, " const");
917 demangle_method_args (work, mangled, declp)
918 struct work_stuff *work;
919 const char **mangled;
924 if (work -> static_type)
926 string_append (declp, *mangled + 1);
927 *mangled += strlen (*mangled);
932 success = demangle_args (work, mangled, declp);
940 demangle_template_template_parm (work, mangled, tname)
941 struct work_stuff *work;
942 const char **mangled;
951 string_append (tname, "template <");
952 /* get size of template parameter list */
953 if (get_count (mangled, &r))
955 for (i = 0; i < r; i++)
959 string_append (tname, ", ");
962 /* Z for type parameters */
963 if (**mangled == 'Z')
966 string_append (tname, "class");
968 /* z for template parameters */
969 else if (**mangled == 'z')
973 demangle_template_template_parm (work, mangled, tname);
981 /* temp is initialized in do_type */
982 success = do_type (work, mangled, &temp);
985 string_appends (tname, &temp);
987 string_delete(&temp);
997 if (tname->p[-1] == '>')
998 string_append (tname, " ");
999 string_append (tname, "> class");
1004 demangle_integral_value (work, mangled, s)
1005 struct work_stuff *work;
1006 const char** mangled;
1011 if (**mangled == 'E')
1013 int need_operator = 0;
1016 string_appendn (s, "(", 1);
1018 while (success && **mangled != 'W' && **mangled != '\0')
1027 len = strlen (*mangled);
1030 i < sizeof (optable) / sizeof (optable [0]);
1033 size_t l = strlen (optable[i].in);
1036 && memcmp (optable[i].in, *mangled, l) == 0)
1038 string_appendn (s, " ", 1);
1039 string_append (s, optable[i].out);
1040 string_appendn (s, " ", 1);
1053 success = demangle_template_value_parm (work, mangled, s);
1056 if (**mangled != 'W')
1060 string_appendn (s, ")", 1);
1064 else if (**mangled == 'Q')
1065 success = demangle_qualified (work, mangled, s, 0, 1);
1070 if (**mangled == 'm')
1072 string_appendn (s, "-", 1);
1075 while (isdigit (**mangled))
1077 string_appendn (s, *mangled, 1);
1087 demangle_template_value_parm (work, mangled, s)
1088 struct work_stuff *work;
1089 const char **mangled;
1092 const char *old_p = *mangled;
1095 int is_integral = 0;
1101 while (*old_p && !done)
1108 done = is_pointer = 1;
1110 case 'C': /* const */
1111 case 'S': /* explicitly signed [char] */
1112 case 'U': /* unsigned */
1113 case 'V': /* volatile */
1114 case 'F': /* function */
1115 case 'M': /* member function */
1117 case 'J': /* complex */
1120 case 'E': /* expression */
1121 case 'Q': /* qualified name */
1122 done = is_integral = 1;
1124 case 'T': /* remembered type */
1127 case 'v': /* void */
1130 case 'x': /* long long */
1131 case 'l': /* long */
1133 case 's': /* short */
1134 case 'w': /* wchar_t */
1135 done = is_integral = 1;
1137 case 'b': /* bool */
1140 case 'c': /* char */
1143 case 'r': /* long double */
1144 case 'd': /* double */
1145 case 'f': /* float */
1149 /* it's probably user defined type, let's assume
1150 it's integral, it seems hard to figure out
1151 what it really is */
1152 done = is_integral = 1;
1155 if (**mangled == 'Y')
1157 /* The next argument is a template parameter. */
1161 idx = consume_count_with_underscores (mangled);
1163 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1164 || consume_count_with_underscores (mangled) == -1)
1166 if (work->tmpl_argvec)
1167 string_append (s, work->tmpl_argvec[idx]);
1171 sprintf(buf, "T%d", idx);
1172 string_append (s, buf);
1175 else if (is_integral)
1176 success = demangle_integral_value (work, mangled, s);
1181 if (**mangled == 'm')
1183 string_appendn (s, "-", 1);
1186 string_appendn (s, "'", 1);
1187 val = consume_count(mangled);
1192 string_appendn (s, &tmp[0], 1);
1193 string_appendn (s, "'", 1);
1197 int val = consume_count (mangled);
1199 string_appendn (s, "false", 5);
1201 string_appendn (s, "true", 4);
1207 if (**mangled == 'm')
1209 string_appendn (s, "-", 1);
1212 while (isdigit (**mangled))
1214 string_appendn (s, *mangled, 1);
1217 if (**mangled == '.') /* fraction */
1219 string_appendn (s, ".", 1);
1221 while (isdigit (**mangled))
1223 string_appendn (s, *mangled, 1);
1227 if (**mangled == 'e') /* exponent */
1229 string_appendn (s, "e", 1);
1231 while (isdigit (**mangled))
1233 string_appendn (s, *mangled, 1);
1238 else if (is_pointer)
1240 int symbol_len = consume_count (mangled);
1241 if (symbol_len == 0)
1243 if (symbol_len == 0)
1244 string_appendn (s, "0", 1);
1247 char *p = xmalloc (symbol_len + 1), *q;
1248 strncpy (p, *mangled, symbol_len);
1249 p [symbol_len] = '\0';
1250 q = cplus_demangle (p, work->options);
1251 string_appendn (s, "&", 1);
1254 string_append (s, q);
1258 string_append (s, p);
1261 *mangled += symbol_len;
1268 demangle_template (work, mangled, tname, trawname, is_type)
1269 struct work_stuff *work;
1270 const char **mangled;
1280 int is_java_array = 0;
1287 /* get template name */
1288 if (**mangled == 'z')
1294 idx = consume_count_with_underscores (mangled);
1296 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1297 || consume_count_with_underscores (mangled) == -1)
1301 if (work->tmpl_argvec)
1303 string_append (tname, work->tmpl_argvec[idx]);
1305 string_append (trawname, work->tmpl_argvec[idx]);
1310 sprintf(buf, "T%d", idx);
1311 string_append (tname, buf);
1313 string_append (trawname, work->tmpl_argvec[idx]);
1318 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
1323 string_appendn (trawname, *mangled, r);
1324 is_java_array = (work -> options & DMGL_JAVA)
1325 && strncmp (*mangled, "JArray1Z", 8) == 0;
1326 if (! is_java_array)
1328 string_appendn (tname, *mangled, r);
1334 string_append (tname, "<");
1335 /* get size of template parameter list */
1336 if (!get_count (mangled, &r))
1342 /* Create an array for saving the template argument values. */
1343 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1344 work->ntmpl_args = r;
1345 for (i = 0; i < r; i++)
1346 work->tmpl_argvec[i] = 0;
1348 for (i = 0; i < r; i++)
1352 string_append (tname, ", ");
1354 /* Z for type parameters */
1355 if (**mangled == 'Z')
1358 /* temp is initialized in do_type */
1359 success = do_type (work, mangled, &temp);
1362 string_appends (tname, &temp);
1366 /* Save the template argument. */
1367 int len = temp.p - temp.b;
1368 work->tmpl_argvec[i] = xmalloc (len + 1);
1369 memcpy (work->tmpl_argvec[i], temp.b, len);
1370 work->tmpl_argvec[i][len] = '\0';
1373 string_delete(&temp);
1379 /* z for template parameters */
1380 else if (**mangled == 'z')
1384 success = demangle_template_template_parm (work, mangled, tname);
1387 && (r2 = consume_count (mangled)) > 0 && strlen (*mangled) >= r2)
1389 string_append (tname, " ");
1390 string_appendn (tname, *mangled, r2);
1393 /* Save the template argument. */
1395 work->tmpl_argvec[i] = xmalloc (len + 1);
1396 memcpy (work->tmpl_argvec[i], *mangled, len);
1397 work->tmpl_argvec[i][len] = '\0';
1411 /* otherwise, value parameter */
1413 /* temp is initialized in do_type */
1414 success = do_type (work, mangled, &temp);
1418 string_appends (s, &temp);
1421 string_delete(&temp);
1427 string_append (s, "=");
1438 success = demangle_template_value_parm (work, mangled, s);
1450 int len = s->p - s->b;
1451 work->tmpl_argvec[i] = xmalloc (len + 1);
1452 memcpy (work->tmpl_argvec[i], s->b, len);
1453 work->tmpl_argvec[i][len] = '\0';
1455 string_appends (tname, s);
1463 string_append (tname, "[]");
1467 if (tname->p[-1] == '>')
1468 string_append (tname, " ");
1469 string_append (tname, ">");
1473 if (work -> static_type)
1475 string_append (declp, *mangled + 1);
1476 *mangled += strlen (*mangled);
1481 success = demangle_args (work, mangled, declp);
1489 arm_pt (work, mangled, n, anchor, args)
1490 struct work_stuff *work;
1491 const char *mangled;
1493 const char **anchor, **args;
1496 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1499 *args = *anchor + 6;
1500 len = consume_count (args);
1501 if (*args + len == mangled + n && **args == '_')
1511 demangle_arm_pt (work, mangled, n, declp)
1512 struct work_stuff *work;
1513 const char **mangled;
1519 const char *e = *mangled + n;
1522 if (arm_pt (work, *mangled, n, &p, &args))
1526 string_appendn (declp, *mangled, p - *mangled);
1527 string_append (declp, "<");
1528 /* should do error checking here */
1530 string_clear (&arg);
1531 do_type (work, &args, &arg);
1532 string_appends (declp, &arg);
1533 string_append (declp, ",");
1535 string_delete (&arg);
1537 string_append (declp, ">");
1541 string_appendn (declp, *mangled, n);
1547 demangle_class_name (work, mangled, declp)
1548 struct work_stuff *work;
1549 const char **mangled;
1555 n = consume_count (mangled);
1556 if (strlen (*mangled) >= n)
1558 demangle_arm_pt (work, mangled, n, declp);
1569 demangle_class -- demangle a mangled class sequence
1574 demangle_class (struct work_stuff *work, const char **mangled,
1579 DECLP points to the buffer into which demangling is being done.
1581 *MANGLED points to the current token to be demangled. On input,
1582 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1583 On exit, it points to the next token after the mangled class on
1584 success, or the first unconsumed token on failure.
1586 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1587 we are demangling a constructor or destructor. In this case
1588 we prepend "class::class" or "class::~class" to DECLP.
1590 Otherwise, we prepend "class::" to the current DECLP.
1592 Reset the constructor/destructor flags once they have been
1593 "consumed". This allows demangle_class to be called later during
1594 the same demangling, to do normal class demangling.
1596 Returns 1 if demangling is successful, 0 otherwise.
1601 demangle_class (work, mangled, declp)
1602 struct work_stuff *work;
1603 const char **mangled;
1609 string_init (&class_name);
1610 if (demangle_class_name (work, mangled, &class_name))
1612 if ((work->constructor & 1) || (work->destructor & 1))
1614 string_prepends (declp, &class_name);
1615 if (work -> destructor & 1)
1617 string_prepend (declp, "~");
1618 work -> destructor -= 1;
1622 work -> constructor -= 1;
1625 string_prepend (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1626 string_prepends (declp, &class_name);
1629 string_delete (&class_name);
1637 demangle_prefix -- consume the mangled name prefix and find signature
1642 demangle_prefix (struct work_stuff *work, const char **mangled,
1647 Consume and demangle the prefix of the mangled name.
1649 DECLP points to the string buffer into which demangled output is
1650 placed. On entry, the buffer is empty. On exit it contains
1651 the root function name, the demangled operator name, or in some
1652 special cases either nothing or the completely demangled result.
1654 MANGLED points to the current pointer into the mangled name. As each
1655 token of the mangled name is consumed, it is updated. Upon entry
1656 the current mangled name pointer points to the first character of
1657 the mangled name. Upon exit, it should point to the first character
1658 of the signature if demangling was successful, or to the first
1659 unconsumed character if demangling of the prefix was unsuccessful.
1661 Returns 1 on success, 0 otherwise.
1665 demangle_prefix (work, mangled, declp)
1666 struct work_stuff *work;
1667 const char **mangled;
1674 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1676 char *marker = strchr (cplus_markers, (*mangled)[8]);
1677 if (marker != NULL && *marker == (*mangled)[10])
1679 if ((*mangled)[9] == 'D')
1681 /* it's a GNU global destructor to be executed at program exit */
1683 work->destructor = 2;
1684 if (gnu_special (work, mangled, declp))
1687 else if ((*mangled)[9] == 'I')
1689 /* it's a GNU global constructor to be executed at program init */
1691 work->constructor = 2;
1692 if (gnu_special (work, mangled, declp))
1697 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1699 /* it's a ARM global destructor to be executed at program exit */
1701 work->destructor = 2;
1703 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1705 /* it's a ARM global constructor to be executed at program initial */
1707 work->constructor = 2;
1710 /* This block of code is a reduction in strength time optimization
1712 scan = mystrstr (*mangled, "__"); */
1718 scan = strchr (scan, '_');
1719 } while (scan != NULL && *++scan != '_');
1721 if (scan != NULL) --scan;
1726 /* We found a sequence of two or more '_', ensure that we start at
1727 the last pair in the sequence. */
1728 i = strspn (scan, "_");
1739 else if (work -> static_type)
1741 if (!isdigit (scan[0]) && (scan[0] != 't'))
1746 else if ((scan == *mangled)
1747 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
1748 || (scan[2] == 'H')))
1750 /* The ARM says nothing about the mangling of local variables.
1751 But cfront mangles local variables by prepending __<nesting_level>
1752 to them. As an extension to ARM demangling we handle this case. */
1753 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1755 *mangled = scan + 2;
1756 consume_count (mangled);
1757 string_append (declp, *mangled);
1758 *mangled += strlen (*mangled);
1763 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1764 names like __Q2_3foo3bar for nested type names. So don't accept
1765 this style of constructor for cfront demangling. A GNU
1766 style member-template constructor starts with 'H'. */
1767 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1768 work -> constructor += 1;
1769 *mangled = scan + 2;
1772 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1774 /* Mangled name starts with "__". Skip over any leading '_' characters,
1775 then find the next "__" that separates the prefix from the signature.
1777 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1778 || (arm_special (mangled, declp) == 0))
1780 while (*scan == '_')
1784 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1786 /* No separator (I.E. "__not_mangled"), or empty signature
1787 (I.E. "__not_mangled_either__") */
1792 demangle_function_name (work, mangled, declp, scan);
1796 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1798 /* Cfront-style parameterized type. Handled later as a signature. */
1802 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1804 else if (*(scan + 2) != '\0')
1806 /* Mangled name does not start with "__" but does have one somewhere
1807 in there with non empty stuff after it. Looks like a global
1809 demangle_function_name (work, mangled, declp, scan);
1813 /* Doesn't look like a mangled name */
1817 if (!success && (work->constructor == 2 || work->destructor == 2))
1819 string_append (declp, *mangled);
1820 *mangled += strlen (*mangled);
1830 gnu_special -- special handling of gnu mangled strings
1835 gnu_special (struct work_stuff *work, const char **mangled,
1841 Process some special GNU style mangling forms that don't fit
1842 the normal pattern. For example:
1844 _$_3foo (destructor for class foo)
1845 _vt$foo (foo virtual table)
1846 _vt$foo$bar (foo::bar virtual table)
1847 __vt_foo (foo virtual table, new style with thunks)
1848 _3foo$varname (static data member)
1849 _Q22rs2tu$vw (static data member)
1850 __t6vector1Zii (constructor with template)
1851 __thunk_4__$_7ostream (virtual function thunk)
1855 gnu_special (work, mangled, declp)
1856 struct work_stuff *work;
1857 const char **mangled;
1864 if ((*mangled)[0] == '_'
1865 && strchr (cplus_markers, (*mangled)[1]) != NULL
1866 && (*mangled)[2] == '_')
1868 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1870 work -> destructor += 1;
1872 else if ((*mangled)[0] == '_'
1873 && (((*mangled)[1] == '_'
1874 && (*mangled)[2] == 'v'
1875 && (*mangled)[3] == 't'
1876 && (*mangled)[4] == '_')
1877 || ((*mangled)[1] == 'v'
1878 && (*mangled)[2] == 't'
1879 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1881 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1882 and create the decl. Note that we consume the entire mangled
1883 input string, which means that demangle_signature has no work
1885 if ((*mangled)[2] == 'v')
1886 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1888 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1889 while (**mangled != '\0')
1891 p = strpbrk (*mangled, cplus_markers);
1895 success = demangle_qualified (work, mangled, declp, 0, 1);
1898 success = demangle_template (work, mangled, declp, 0, 1);
1901 if (isdigit(*mangled[0]))
1903 n = consume_count(mangled);
1904 /* We may be seeing a too-large size, or else a
1905 ".<digits>" indicating a static local symbol. In
1906 any case, declare victory and move on; *don't* try
1907 to use n to allocate. */
1908 if (n >= strlen (*mangled))
1916 n = strcspn (*mangled, cplus_markers);
1918 string_appendn (declp, *mangled, n);
1922 if (success && ((p == NULL) || (p == *mangled)))
1926 string_append (declp,
1927 (work -> options & DMGL_JAVA) ? "." : "::");
1938 string_append (declp, " virtual table");
1940 else if ((*mangled)[0] == '_'
1941 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1942 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1944 /* static data member, "_3foo$varname" for example */
1949 success = demangle_qualified (work, mangled, declp, 0, 1);
1952 success = demangle_template (work, mangled, declp, 0, 1);
1955 n = consume_count (mangled);
1956 string_appendn (declp, *mangled, n);
1959 if (success && (p == *mangled))
1961 /* Consumed everything up to the cplus_marker, append the
1964 string_append (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1965 n = strlen (*mangled);
1966 string_appendn (declp, *mangled, n);
1974 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1976 int delta = ((*mangled) += 8, consume_count (mangled));
1977 char *method = cplus_demangle (++*mangled, work->options);
1981 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1982 string_append (declp, buf);
1983 string_append (declp, method);
1985 n = strlen (*mangled);
1993 else if (strncmp (*mangled, "__t", 3) == 0
1994 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
1996 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2001 success = demangle_qualified (work, mangled, declp, 0, 1);
2004 success = demangle_template (work, mangled, declp, 0, 1);
2007 success = demangle_fund_type (work, mangled, declp);
2010 if (success && **mangled != '\0')
2013 string_append (declp, p);
2026 arm_special -- special handling of ARM/lucid mangled strings
2031 arm_special (const char **mangled,
2037 Process some special ARM style mangling forms that don't fit
2038 the normal pattern. For example:
2040 __vtbl__3foo (foo virtual table)
2041 __vtbl__3foo__3bar (bar::foo virtual table)
2046 arm_special (mangled, declp)
2047 const char **mangled;
2054 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2056 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2057 and create the decl. Note that we consume the entire mangled
2058 input string, which means that demangle_signature has no work
2060 scan = *mangled + ARM_VTABLE_STRLEN;
2061 while (*scan != '\0') /* first check it can be demangled */
2063 n = consume_count (&scan);
2066 return (0); /* no good */
2069 if (scan[0] == '_' && scan[1] == '_')
2074 (*mangled) += ARM_VTABLE_STRLEN;
2075 while (**mangled != '\0')
2077 n = consume_count (mangled);
2078 string_prependn (declp, *mangled, n);
2080 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2082 string_prepend (declp, "::");
2086 string_append (declp, " virtual table");
2099 demangle_qualified -- demangle 'Q' qualified name strings
2104 demangle_qualified (struct work_stuff *, const char *mangled,
2105 string *result, int isfuncname, int append);
2109 Demangle a qualified name, such as "Q25Outer5Inner" which is
2110 the mangled form of "Outer::Inner". The demangled output is
2111 prepended or appended to the result string according to the
2112 state of the append flag.
2114 If isfuncname is nonzero, then the qualified name we are building
2115 is going to be used as a member function name, so if it is a
2116 constructor or destructor function, append an appropriate
2117 constructor or destructor name. I.E. for the above example,
2118 the result for use as a constructor is "Outer::Inner::Inner"
2119 and the result for use as a destructor is "Outer::Inner::~Inner".
2123 Numeric conversion is ASCII dependent (FIXME).
2128 demangle_qualified (work, mangled, result, isfuncname, append)
2129 struct work_stuff *work;
2130 const char **mangled;
2142 string_init (&temp);
2143 switch ((*mangled)[1])
2146 /* GNU mangled name with more than 9 classes. The count is preceded
2147 by an underscore (to distinguish it from the <= 9 case) and followed
2148 by an underscore. */
2150 qualifiers = atoi (p);
2151 if (!isdigit (*p) || *p == '0')
2154 /* Skip the digits. */
2155 while (isdigit (*p))
2173 /* The count is in a single digit. */
2174 num[0] = (*mangled)[1];
2176 qualifiers = atoi (num);
2178 /* If there is an underscore after the digit, skip it. This is
2179 said to be for ARM-qualified names, but the ARM makes no
2180 mention of such an underscore. Perhaps cfront uses one. */
2181 if ((*mangled)[2] == '_')
2196 /* Pick off the names and collect them in the temp buffer in the order
2197 in which they are found, separated by '::'. */
2199 while (qualifiers-- > 0)
2201 if (*mangled[0] == '_')
2202 *mangled = *mangled + 1;
2203 if (*mangled[0] == 't')
2205 success = demangle_template(work, mangled, &temp, 0, 1);
2206 if (!success) break;
2208 else if (*mangled[0] == 'X')
2210 success = do_type (work, mangled, &temp);
2211 if (!success) break;
2215 namelength = consume_count (mangled);
2216 if (strlen (*mangled) < namelength)
2218 /* Simple sanity check failed */
2222 string_appendn (&temp, *mangled, namelength);
2223 *mangled += namelength;
2227 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2231 /* If we are using the result as a function name, we need to append
2232 the appropriate '::' separated constructor or destructor name.
2233 We do this here because this is the most convenient place, where
2234 we already have a pointer to the name and the length of the name. */
2236 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
2238 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2239 if (work -> destructor & 1)
2241 string_append (&temp, "~");
2243 string_appendn (&temp, (*mangled) - namelength, namelength);
2246 /* Now either prepend the temp buffer to the result, or append it,
2247 depending upon the state of the append flag. */
2251 string_appends (result, &temp);
2255 if (!STRING_EMPTY (result))
2257 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2259 string_prepends (result, &temp);
2262 string_delete (&temp);
2270 get_count -- convert an ascii count to integer, consuming tokens
2275 get_count (const char **type, int *count)
2279 Return 0 if no conversion is performed, 1 if a string is converted.
2283 get_count (type, count)
2290 if (!isdigit (**type))
2296 *count = **type - '0';
2298 if (isdigit (**type))
2308 while (isdigit (*p));
2319 /* result will be initialised here; it will be freed on failure */
2322 do_type (work, mangled, result)
2323 struct work_stuff *work;
2324 const char **mangled;
2331 const char *remembered_type;
2335 string_init (&decl);
2336 string_init (result);
2340 while (success && !done)
2346 /* A pointer type */
2350 if (! (work -> options & DMGL_JAVA))
2351 string_prepend (&decl, "*");
2354 /* A reference type */
2357 string_prepend (&decl, "&");
2363 const char *p = ++(*mangled);
2365 string_prepend (&decl, "(");
2366 string_append (&decl, ")[");
2367 /* Copy anything up until the next underscore (the size of the
2369 while (**mangled && **mangled != '_')
2371 if (**mangled == '_')
2373 string_appendn (&decl, p, *mangled - p);
2374 string_append (&decl, "]");
2382 /* A back reference to a previously seen type */
2385 if (!get_count (mangled, &n) || n >= work -> ntypes)
2391 remembered_type = work -> typevec[n];
2392 mangled = &remembered_type;
2399 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2401 string_prepend (&decl, "(");
2402 string_append (&decl, ")");
2404 /* After picking off the function args, we expect to either find the
2405 function return type (preceded by an '_') or the end of the
2407 if (!demangle_args (work, mangled, &decl)
2408 || (**mangled != '_' && **mangled != '\0'))
2412 if (success && (**mangled == '_'))
2424 member = **mangled == 'M';
2426 if (!isdigit (**mangled) && **mangled != 't')
2432 string_append (&decl, ")");
2433 string_prepend (&decl, (work -> options & DMGL_JAVA) ? "." : "::");
2434 if (isdigit (**mangled))
2436 n = consume_count (mangled);
2437 if (strlen (*mangled) < n)
2442 string_prependn (&decl, *mangled, n);
2448 string_init (&temp);
2449 success = demangle_template (work, mangled, &temp, NULL, 1);
2452 string_prependn (&decl, temp.b, temp.p - temp.b);
2453 string_clear (&temp);
2458 string_prepend (&decl, "(");
2461 if (**mangled == 'C')
2466 if (**mangled == 'V')
2471 if (*(*mangled)++ != 'F')
2477 if ((member && !demangle_args (work, mangled, &decl))
2478 || **mangled != '_')
2484 if (! PRINT_ANSI_QUALIFIERS)
2490 APPEND_BLANK (&decl);
2491 string_append (&decl, "const");
2495 APPEND_BLANK (&decl);
2496 string_append (&decl, "volatile");
2507 if ((*mangled)[1] == 'P')
2510 if (PRINT_ANSI_QUALIFIERS)
2512 if (!STRING_EMPTY (&decl))
2514 string_prepend (&decl, " ");
2516 string_prepend (&decl, "const");
2532 /* A qualified name, such as "Outer::Inner". */
2534 success = demangle_qualified (work, mangled, result, 0, 1);
2539 /* A template parm. We substitute the corresponding argument. */
2544 idx = consume_count_with_underscores (mangled);
2547 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2548 || consume_count_with_underscores (mangled) == -1)
2554 if (work->tmpl_argvec)
2555 string_append (result, work->tmpl_argvec[idx]);
2559 sprintf(buf, "T%d", idx);
2560 string_append (result, buf);
2568 success = demangle_fund_type (work, mangled, result);
2574 if (!STRING_EMPTY (&decl))
2576 string_append (result, " ");
2577 string_appends (result, &decl);
2582 string_delete (result);
2584 string_delete (&decl);
2588 /* Given a pointer to a type string that represents a fundamental type
2589 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2590 string in which the demangled output is being built in RESULT, and
2591 the WORK structure, decode the types and add them to the result.
2596 "Sl" => "signed long"
2597 "CUs" => "const unsigned short"
2602 demangle_fund_type (work, mangled, result)
2603 struct work_stuff *work;
2604 const char **mangled;
2610 /* First pick off any type qualifiers. There can be more than one. */
2618 if (PRINT_ANSI_QUALIFIERS)
2620 APPEND_BLANK (result);
2621 string_append (result, "const");
2626 APPEND_BLANK (result);
2627 string_append (result, "unsigned");
2629 case 'S': /* signed char only */
2631 APPEND_BLANK (result);
2632 string_append (result, "signed");
2636 if (PRINT_ANSI_QUALIFIERS)
2638 APPEND_BLANK (result);
2639 string_append (result, "volatile");
2644 APPEND_BLANK (result);
2645 string_append (result, "__complex");
2653 /* Now pick off the fundamental type. There can be only one. */
2662 APPEND_BLANK (result);
2663 string_append (result, "void");
2667 APPEND_BLANK (result);
2668 string_append (result, "long long");
2672 APPEND_BLANK (result);
2673 string_append (result, "long");
2677 APPEND_BLANK (result);
2678 string_append (result, "int");
2682 APPEND_BLANK (result);
2683 string_append (result, "short");
2687 APPEND_BLANK (result);
2688 string_append (result, "bool");
2692 APPEND_BLANK (result);
2693 string_append (result, "char");
2697 APPEND_BLANK (result);
2698 string_append (result, "wchar_t");
2702 APPEND_BLANK (result);
2703 string_append (result, "long double");
2707 APPEND_BLANK (result);
2708 string_append (result, "double");
2712 APPEND_BLANK (result);
2713 string_append (result, "float");
2717 if (!isdigit (**mangled))
2723 /* An explicit type, such as "6mytype" or "7integer" */
2734 APPEND_BLANK (result);
2735 if (!demangle_class_name (work, mangled, result)) {
2741 success = demangle_template(work,mangled, result, 0, 1);
2751 /* `result' will be initialized in do_type; it will be freed on failure */
2754 do_arg (work, mangled, result)
2755 struct work_stuff *work;
2756 const char **mangled;
2759 const char *start = *mangled;
2761 if (!do_type (work, mangled, result))
2767 remember_type (work, start, *mangled - start);
2773 remember_type (work, start, len)
2774 struct work_stuff *work;
2780 if (work -> ntypes >= work -> typevec_size)
2782 if (work -> typevec_size == 0)
2784 work -> typevec_size = 3;
2786 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2790 work -> typevec_size *= 2;
2792 = (char **) xrealloc ((char *)work -> typevec,
2793 sizeof (char *) * work -> typevec_size);
2796 tem = xmalloc (len + 1);
2797 memcpy (tem, start, len);
2799 work -> typevec[work -> ntypes++] = tem;
2802 /* Forget the remembered types, but not the type vector itself. */
2806 struct work_stuff *work;
2810 while (work -> ntypes > 0)
2812 i = --(work -> ntypes);
2813 if (work -> typevec[i] != NULL)
2815 free (work -> typevec[i]);
2816 work -> typevec[i] = NULL;
2821 /* Process the argument list part of the signature, after any class spec
2822 has been consumed, as well as the first 'F' character (if any). For
2825 "__als__3fooRT0" => process "RT0"
2826 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2828 DECLP must be already initialised, usually non-empty. It won't be freed
2831 Note that g++ differs significantly from ARM and lucid style mangling
2832 with regards to references to previously seen types. For example, given
2833 the source fragment:
2837 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2840 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2841 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2843 g++ produces the names:
2848 while lcc (and presumably other ARM style compilers as well) produces:
2850 foo__FiR3fooT1T2T1T2
2851 __ct__3fooFiR3fooT1T2T1T2
2853 Note that g++ bases it's type numbers starting at zero and counts all
2854 previously seen types, while lucid/ARM bases it's type numbers starting
2855 at one and only considers types after it has seen the 'F' character
2856 indicating the start of the function args. For lucid/ARM style, we
2857 account for this difference by discarding any previously seen types when
2858 we see the 'F' character, and subtracting one from the type number
2864 demangle_args (work, mangled, declp)
2865 struct work_stuff *work;
2866 const char **mangled;
2876 if (PRINT_ARG_TYPES)
2878 string_append (declp, "(");
2879 if (**mangled == '\0')
2881 string_append (declp, "void");
2885 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2887 if ((**mangled == 'N') || (**mangled == 'T'))
2889 temptype = *(*mangled)++;
2891 if (temptype == 'N')
2893 if (!get_count (mangled, &r))
2902 if (ARM_DEMANGLING && work -> ntypes >= 10)
2904 /* If we have 10 or more types we might have more than a 1 digit
2905 index so we'll have to consume the whole count here. This
2906 will lose if the next thing is a type name preceded by a
2907 count but it's impossible to demangle that case properly
2908 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2909 Pc, ...)" or "(..., type12, char *, ...)" */
2910 if ((t = consume_count(mangled)) == 0)
2917 if (!get_count (mangled, &t))
2922 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2926 /* Validate the type index. Protect against illegal indices from
2927 malformed type strings. */
2928 if ((t < 0) || (t >= work -> ntypes))
2934 tem = work -> typevec[t];
2935 if (need_comma && PRINT_ARG_TYPES)
2937 string_append (declp, ", ");
2939 if (!do_arg (work, &tem, &arg))
2943 if (PRINT_ARG_TYPES)
2945 string_appends (declp, &arg);
2947 string_delete (&arg);
2953 if (need_comma & PRINT_ARG_TYPES)
2955 string_append (declp, ", ");
2957 if (!do_arg (work, mangled, &arg))
2961 if (PRINT_ARG_TYPES)
2963 string_appends (declp, &arg);
2965 string_delete (&arg);
2970 if (**mangled == 'e')
2973 if (PRINT_ARG_TYPES)
2977 string_append (declp, ",");
2979 string_append (declp, "...");
2983 if (PRINT_ARG_TYPES)
2985 string_append (declp, ")");
2991 demangle_function_name (work, mangled, declp, scan)
2992 struct work_stuff *work;
2993 const char **mangled;
3001 string_appendn (declp, (*mangled), scan - (*mangled));
3002 string_need (declp, 1);
3003 *(declp -> p) = '\0';
3005 /* Consume the function name, including the "__" separating the name
3006 from the signature. We are guaranteed that SCAN points to the
3009 (*mangled) = scan + 2;
3011 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3014 /* See if we have an ARM style constructor or destructor operator.
3015 If so, then just record it, clear the decl, and return.
3016 We can't build the actual constructor/destructor decl until later,
3017 when we recover the class name from the signature. */
3019 if (strcmp (declp -> b, "__ct") == 0)
3021 work -> constructor += 1;
3022 string_clear (declp);
3025 else if (strcmp (declp -> b, "__dt") == 0)
3027 work -> destructor += 1;
3028 string_clear (declp);
3033 if (declp->p - declp->b >= 3
3034 && declp->b[0] == 'o'
3035 && declp->b[1] == 'p'
3036 && strchr (cplus_markers, declp->b[2]) != NULL)
3038 /* see if it's an assignment expression */
3039 if (declp->p - declp->b >= 10 /* op$assign_ */
3040 && memcmp (declp->b + 3, "assign_", 7) == 0)
3042 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3044 int len = declp->p - declp->b - 10;
3045 if (strlen (optable[i].in) == len
3046 && memcmp (optable[i].in, declp->b + 10, len) == 0)
3048 string_clear (declp);
3049 string_append (declp, "operator");
3050 string_append (declp, optable[i].out);
3051 string_append (declp, "=");
3058 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3060 int len = declp->p - declp->b - 3;
3061 if (strlen (optable[i].in) == len
3062 && memcmp (optable[i].in, declp->b + 3, len) == 0)
3064 string_clear (declp);
3065 string_append (declp, "operator");
3066 string_append (declp, optable[i].out);
3072 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
3073 && strchr (cplus_markers, declp->b[4]) != NULL)
3075 /* type conversion operator */
3077 if (do_type (work, &tem, &type))
3079 string_clear (declp);
3080 string_append (declp, "operator ");
3081 string_appends (declp, &type);
3082 string_delete (&type);
3085 else if (declp->b[0] == '_' && declp->b[1] == '_'
3086 && declp->b[2] == 'o' && declp->b[3] == 'p')
3089 /* type conversion operator. */
3091 if (do_type (work, &tem, &type))
3093 string_clear (declp);
3094 string_append (declp, "operator ");
3095 string_appends (declp, &type);
3096 string_delete (&type);
3099 else if (declp->b[0] == '_' && declp->b[1] == '_'
3100 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
3101 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
3103 if (declp->b[4] == '\0')
3106 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3108 if (strlen (optable[i].in) == 2
3109 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
3111 string_clear (declp);
3112 string_append (declp, "operator");
3113 string_append (declp, optable[i].out);
3120 if (declp->b[2] == 'a' && declp->b[5] == '\0')
3123 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3125 if (strlen (optable[i].in) == 3
3126 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
3128 string_clear (declp);
3129 string_append (declp, "operator");
3130 string_append (declp, optable[i].out);
3139 /* a mini string-handling package */
3154 s->p = s->b = xmalloc (n);
3157 else if (s->e - s->p < n)
3162 s->b = xrealloc (s->b, n);
3175 s->b = s->e = s->p = NULL;
3183 s->b = s->p = s->e = NULL;
3199 return (s->b == s->p);
3205 string_append (p, s)
3210 if (s == NULL || *s == '\0')
3214 memcpy (p->p, s, n);
3219 string_appends (p, s)
3228 memcpy (p->p, s->b, n);
3234 string_appendn (p, s, n)
3242 memcpy (p->p, s, n);
3248 string_prepend (p, s)
3252 if (s != NULL && *s != '\0')
3254 string_prependn (p, s, strlen (s));
3259 string_prepends (p, s)
3264 string_prependn (p, s->b, s->p - s->b);
3269 string_prependn (p, s, n)
3279 for (q = p->p - 1; q >= p->b; q--)
3283 memcpy (p->b, s, n);
3288 /* To generate a standalone demangler program for testing purposes,
3289 just compile and link this file with -DMAIN and libiberty.a. When
3290 run, it demangles each command line arg, or each stdin string, and
3291 prints the result on stdout. */
3297 static char *program_name;
3298 static char *program_version = VERSION;
3299 static int flags = DMGL_PARAMS | DMGL_ANSI;
3301 static void demangle_it PARAMS ((char *));
3302 static void usage PARAMS ((FILE *, int));
3303 static void fatal PARAMS ((char *));
3306 demangle_it (mangled_name)
3311 result = cplus_demangle (mangled_name, flags);
3314 printf ("%s\n", mangled_name);
3318 printf ("%s\n", result);
3324 usage (stream, status)
3329 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3330 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3331 [--help] [--version] [arg...]\n",
3336 #define MBUF_SIZE 512
3337 char mbuffer[MBUF_SIZE];
3339 /* Defined in the automatically-generated underscore.c. */
3340 extern int prepends_underscore;
3342 int strip_underscore = 0;
3344 static struct option long_options[] = {
3345 {"strip-underscores", no_argument, 0, '_'},
3346 {"format", required_argument, 0, 's'},
3347 {"help", no_argument, 0, 'h'},
3348 {"java", no_argument, 0, 'j'},
3349 {"no-strip-underscores", no_argument, 0, 'n'},
3350 {"version", no_argument, 0, 'v'},
3351 {0, no_argument, 0, 0}
3354 /* More 'friendly' abort that prints the line and file.
3355 config.h can #define abort fancy_abort if you like that sort of thing. */
3360 fatal ("Internal gcc abort.");
3371 program_name = argv[0];
3373 strip_underscore = prepends_underscore;
3375 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3385 strip_underscore = 0;
3388 printf ("GNU %s version %s\n", program_name, program_version);
3391 strip_underscore = 1;
3397 if (strcmp (optarg, "gnu") == 0)
3399 current_demangling_style = gnu_demangling;
3401 else if (strcmp (optarg, "lucid") == 0)
3403 current_demangling_style = lucid_demangling;
3405 else if (strcmp (optarg, "arm") == 0)
3407 current_demangling_style = arm_demangling;
3411 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3412 program_name, optarg);
3421 for ( ; optind < argc; optind++)
3423 demangle_it (argv[optind]);
3432 /* Try to read a label. */
3433 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3435 if (i >= MBUF_SIZE-1)
3444 if (mbuffer[0] == '.')
3446 if (strip_underscore && mbuffer[skip_first] == '_')
3454 result = cplus_demangle (mbuffer + skip_first, flags);
3457 if (mbuffer[0] == '.')
3459 fputs (result, stdout);
3463 fputs (mbuffer, stdout);
3480 fprintf (stderr, "%s: %s\n", program_name, str);
3491 register char *value = (char *) malloc (size);
3493 fatal ("virtual memory exhausted");
3498 xrealloc (ptr, size)
3502 register char *value = (char *) realloc (ptr, size);
3504 fatal ("virtual memory exhausted");