1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996 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. */
36 #undef CURRENT_DEMANGLING_STYLE
37 #define CURRENT_DEMANGLING_STYLE work->options
39 extern char *xmalloc PARAMS((unsigned));
40 extern char *xrealloc PARAMS((char *, unsigned));
46 register char *p = s1;
47 register int len = strlen (s2);
49 for (; (p = strchr (p, *s2)) != 0; p++)
51 if (strncmp (p, s2, len) == 0)
59 /* In order to allow a single demangler executable to demangle strings
60 using various common values of CPLUS_MARKER, as well as any specific
61 one set at compile time, we maintain a string containing all the
62 commonly used ones, and check to see if the marker we are looking for
63 is in that string. CPLUS_MARKER is usually '$' on systems where the
64 assembler can deal with that. Where the assembler can't, it's usually
65 '.' (but on many systems '.' is used for other things). We put the
66 current defined CPLUS_MARKER first (which defaults to '$'), followed
67 by the next most common value, followed by an explicit '$' in case
68 the value of CPLUS_MARKER is not '$'.
70 We could avoid this if we could just get g++ to tell us what the actual
71 cplus marker character is as part of the debug information, perhaps by
72 ensuring that it is the character that terminates the gcc<n>_compiled
73 marker symbol (FIXME). */
75 #if !defined (CPLUS_MARKER)
76 #define CPLUS_MARKER '$'
79 enum demangling_styles current_demangling_style = gnu_demangling;
81 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
84 set_cplus_marker_for_demangling (ch)
87 cplus_markers[0] = ch;
90 /* Stuff that is shared between sub-routines.
91 Using a shared structure allows cplus_demangle to be reentrant. */
101 int static_type; /* A static member function */
102 int const_type; /* A const member function */
105 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
106 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
108 static const struct optable
114 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
115 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
116 {"new", " new", 0}, /* old (1.91, and 1.x) */
117 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
118 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
119 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
120 {"as", "=", DMGL_ANSI}, /* ansi */
121 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
122 {"eq", "==", DMGL_ANSI}, /* old, ansi */
123 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
124 {"gt", ">", DMGL_ANSI}, /* old, ansi */
125 {"le", "<=", DMGL_ANSI}, /* old, ansi */
126 {"lt", "<", DMGL_ANSI}, /* old, ansi */
127 {"plus", "+", 0}, /* old */
128 {"pl", "+", DMGL_ANSI}, /* ansi */
129 {"apl", "+=", DMGL_ANSI}, /* ansi */
130 {"minus", "-", 0}, /* old */
131 {"mi", "-", DMGL_ANSI}, /* ansi */
132 {"ami", "-=", DMGL_ANSI}, /* ansi */
133 {"mult", "*", 0}, /* old */
134 {"ml", "*", DMGL_ANSI}, /* ansi */
135 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
136 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
137 {"convert", "+", 0}, /* old (unary +) */
138 {"negate", "-", 0}, /* old (unary -) */
139 {"trunc_mod", "%", 0}, /* old */
140 {"md", "%", DMGL_ANSI}, /* ansi */
141 {"amd", "%=", DMGL_ANSI}, /* ansi */
142 {"trunc_div", "/", 0}, /* old */
143 {"dv", "/", DMGL_ANSI}, /* ansi */
144 {"adv", "/=", DMGL_ANSI}, /* ansi */
145 {"truth_andif", "&&", 0}, /* old */
146 {"aa", "&&", DMGL_ANSI}, /* ansi */
147 {"truth_orif", "||", 0}, /* old */
148 {"oo", "||", DMGL_ANSI}, /* ansi */
149 {"truth_not", "!", 0}, /* old */
150 {"nt", "!", DMGL_ANSI}, /* ansi */
151 {"postincrement","++", 0}, /* old */
152 {"pp", "++", DMGL_ANSI}, /* ansi */
153 {"postdecrement","--", 0}, /* old */
154 {"mm", "--", DMGL_ANSI}, /* ansi */
155 {"bit_ior", "|", 0}, /* old */
156 {"or", "|", DMGL_ANSI}, /* ansi */
157 {"aor", "|=", DMGL_ANSI}, /* ansi */
158 {"bit_xor", "^", 0}, /* old */
159 {"er", "^", DMGL_ANSI}, /* ansi */
160 {"aer", "^=", DMGL_ANSI}, /* ansi */
161 {"bit_and", "&", 0}, /* old */
162 {"ad", "&", DMGL_ANSI}, /* ansi */
163 {"aad", "&=", DMGL_ANSI}, /* ansi */
164 {"bit_not", "~", 0}, /* old */
165 {"co", "~", DMGL_ANSI}, /* ansi */
166 {"call", "()", 0}, /* old */
167 {"cl", "()", DMGL_ANSI}, /* ansi */
168 {"alshift", "<<", 0}, /* old */
169 {"ls", "<<", DMGL_ANSI}, /* ansi */
170 {"als", "<<=", DMGL_ANSI}, /* ansi */
171 {"arshift", ">>", 0}, /* old */
172 {"rs", ">>", DMGL_ANSI}, /* ansi */
173 {"ars", ">>=", DMGL_ANSI}, /* ansi */
174 {"component", "->", 0}, /* old */
175 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
176 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
177 {"indirect", "*", 0}, /* old */
178 {"method_call", "->()", 0}, /* old */
179 {"addr", "&", 0}, /* old (unary &) */
180 {"array", "[]", 0}, /* old */
181 {"vc", "[]", DMGL_ANSI}, /* ansi */
182 {"compound", ", ", 0}, /* old */
183 {"cm", ", ", DMGL_ANSI}, /* ansi */
184 {"cond", "?:", 0}, /* old */
185 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
186 {"max", ">?", 0}, /* old */
187 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
188 {"min", "<?", 0}, /* old */
189 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
190 {"nop", "", 0}, /* old (for operator=) */
191 {"rm", "->*", DMGL_ANSI} /* ansi */
195 typedef struct string /* Beware: these aren't required to be */
196 { /* '\0' terminated. */
197 char *b; /* pointer to start of string */
198 char *p; /* pointer after last character */
199 char *e; /* pointer after end of allocated space */
202 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
203 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
204 string_prepend(str, " ");}
205 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
206 string_append(str, " ");}
208 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
209 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
211 /* Prototypes for local functions */
214 mop_up PARAMS ((struct work_stuff *, string *, int));
218 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
222 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
226 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
230 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
233 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
236 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
239 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
242 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
245 arm_special PARAMS ((struct work_stuff *, const char **, string *));
248 string_need PARAMS ((string *, int));
251 string_delete PARAMS ((string *));
254 string_init PARAMS ((string *));
257 string_clear PARAMS ((string *));
261 string_empty PARAMS ((string *));
265 string_append PARAMS ((string *, const char *));
268 string_appends PARAMS ((string *, string *));
271 string_appendn PARAMS ((string *, const char *, int));
274 string_prepend PARAMS ((string *, const char *));
277 string_prependn PARAMS ((string *, const char *, int));
280 get_count PARAMS ((const char **, int *));
283 consume_count PARAMS ((const char **));
286 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
289 do_type PARAMS ((struct work_stuff *, const char **, string *));
292 do_arg PARAMS ((struct work_stuff *, const char **, string *));
295 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
299 remember_type PARAMS ((struct work_stuff *, const char *, int));
302 forget_types PARAMS ((struct work_stuff *));
305 string_prepends PARAMS ((string *, string *));
307 /* Translate count to integer, consuming tokens in the process.
308 Conversion terminates on the first non-digit character.
309 Trying to consume something that isn't a count results in
310 no consumption of input and a return of 0. */
318 while (isdigit (**type))
321 count += **type - '0';
328 cplus_demangle_opname (opname, result, options)
333 int len, i, len1, ret;
335 struct work_stuff work[1];
338 len = strlen(opname);
341 work->options = options;
343 if (opname[0] == '_' && opname[1] == '_'
344 && opname[2] == 'o' && opname[3] == 'p')
347 /* type conversion operator. */
349 if (do_type (work, &tem, &type))
351 strcat (result, "operator ");
352 strncat (result, type.b, type.p - type.b);
353 string_delete (&type);
357 else if (opname[0] == '_' && opname[1] == '_'
358 && opname[2] >= 'a' && opname[2] <= 'z'
359 && opname[3] >= 'a' && opname[3] <= 'z')
361 if (opname[4] == '\0')
364 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
366 if (strlen (optable[i].in) == 2
367 && memcmp (optable[i].in, opname + 2, 2) == 0)
369 strcat (result, "operator");
370 strcat (result, optable[i].out);
378 if (opname[2] == 'a' && opname[5] == '\0')
381 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
383 if (strlen (optable[i].in) == 3
384 && memcmp (optable[i].in, opname + 2, 3) == 0)
386 strcat (result, "operator");
387 strcat (result, optable[i].out);
398 && strchr (cplus_markers, opname[2]) != NULL)
400 /* see if it's an assignment expression */
401 if (len >= 10 /* op$assign_ */
402 && memcmp (opname + 3, "assign_", 7) == 0)
404 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
407 if (strlen (optable[i].in) == len1
408 && memcmp (optable[i].in, opname + 10, len1) == 0)
410 strcat (result, "operator");
411 strcat (result, optable[i].out);
412 strcat (result, "=");
420 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
423 if (strlen (optable[i].in) == len1
424 && memcmp (optable[i].in, opname + 3, len1) == 0)
426 strcat (result, "operator");
427 strcat (result, optable[i].out);
434 else if (len >= 5 && memcmp (opname, "type", 4) == 0
435 && strchr (cplus_markers, opname[4]) != NULL)
437 /* type conversion operator */
439 if (do_type (work, &tem, &type))
441 strcat (result, "operator ");
442 strncat (result, type.b, type.p - type.b);
443 string_delete (&type);
450 /* Takes operator name as e.g. "++" and returns mangled
451 operator name (e.g. "postincrement_expr"), or NULL if not found.
453 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
454 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
457 cplus_mangle_opname (opname, options)
464 len = strlen (opname);
465 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
467 if (strlen (optable[i].out) == len
468 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
469 && memcmp (optable[i].out, opname, len) == 0)
470 return optable[i].in;
475 /* Check to see whether MANGLED can match TEXT in the first TEXT_LEN
478 int cplus_match (mangled, text, text_len)
483 if (strncmp (mangled, text, text_len) != 0) {
484 return(0); /* cannot match either */
486 return(1); /* matches mangled, may match demangled */
490 /* char *cplus_demangle (const char *mangled, int options)
492 If MANGLED is a mangled function name produced by GNU C++, then
493 a pointer to a malloced string giving a C++ representation
494 of the name will be returned; otherwise NULL will be returned.
495 It is the caller's responsibility to free the string which
498 The OPTIONS arg may contain one or more of the following bits:
500 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
502 DMGL_PARAMS Function parameters are included.
506 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
507 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
508 cplus_demangle ("foo__1Ai", 0) => "A::foo"
510 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
511 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
512 cplus_demangle ("foo__1Afe", 0) => "A::foo"
514 Note that any leading underscores, or other such characters prepended by
515 the compilation system, are presumed to have already been stripped from
519 cplus_demangle (mangled, options)
525 struct work_stuff work[1];
526 char *demangled = NULL;
528 if ((mangled != NULL) && (*mangled != '\0'))
530 memset ((char *) work, 0, sizeof (work));
531 work -> options = options;
532 if ((work->options & DMGL_STYLE_MASK) == 0)
533 work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
537 /* First check to see if gnu style demangling is active and if the
538 string to be demangled contains a CPLUS_MARKER. If so, attempt to
539 recognize one of the gnu special forms rather than looking for a
540 standard prefix. In particular, don't worry about whether there
541 is a "__" string in the mangled string. Consider "_$_5__foo" for
544 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
546 success = gnu_special (work, &mangled, &decl);
550 success = demangle_prefix (work, &mangled, &decl);
552 if (success && (*mangled != '\0'))
554 success = demangle_signature (work, &mangled, &decl);
556 if (work->constructor == 2)
558 string_prepend(&decl, "global constructors keyed to ");
559 work->constructor = 0;
561 else if (work->destructor == 2)
563 string_prepend(&decl, "global destructors keyed to ");
564 work->destructor = 0;
566 demangled = mop_up (work, &decl, success);
572 mop_up (work, declp, success)
573 struct work_stuff *work;
577 char *demangled = NULL;
579 /* Discard the remembered types, if any. */
582 if (work -> typevec != NULL)
584 free ((char *) work -> typevec);
587 /* If demangling was successful, ensure that the demangled string is null
588 terminated and return it. Otherwise, free the demangling decl. */
592 string_delete (declp);
596 string_appendn (declp, "", 1);
597 demangled = declp -> b;
606 demangle_signature -- demangle the signature part of a mangled name
611 demangle_signature (struct work_stuff *work, const char **mangled,
616 Consume and demangle the signature portion of the mangled name.
618 DECLP is the string where demangled output is being built. At
619 entry it contains the demangled root name from the mangled name
620 prefix. I.E. either a demangled operator name or the root function
621 name. In some special cases, it may contain nothing.
623 *MANGLED points to the current unconsumed location in the mangled
624 name. As tokens are consumed and demangling is performed, the
625 pointer is updated to continuously point at the next token to
628 Demangling GNU style mangled names is nasty because there is no
629 explicit token that marks the start of the outermost function
633 demangle_signature (work, mangled, declp)
634 struct work_stuff *work;
635 const char **mangled;
641 const char *oldmangled = NULL;
645 while (success && (**mangled != '\0'))
650 oldmangled = *mangled;
651 success = demangle_qualified (work, mangled, declp, 1, 0);
654 remember_type (work, oldmangled, *mangled - oldmangled);
656 if (AUTO_DEMANGLING || GNU_DEMANGLING)
664 /* Static member function */
665 if (oldmangled == NULL)
667 oldmangled = *mangled;
670 work -> static_type = 1;
674 /* a const member function */
675 if (oldmangled == NULL)
677 oldmangled = *mangled;
680 work -> const_type = 1;
683 case '0': case '1': case '2': case '3': case '4':
684 case '5': case '6': case '7': case '8': case '9':
685 if (oldmangled == NULL)
687 oldmangled = *mangled;
689 success = demangle_class (work, mangled, declp);
692 remember_type (work, oldmangled, *mangled - oldmangled);
694 if (AUTO_DEMANGLING || GNU_DEMANGLING)
703 /* ARM style demangling includes a specific 'F' character after
704 the class name. For GNU style, it is just implied. So we can
705 safely just consume any 'F' at this point and be compatible
706 with either style. */
712 /* For lucid/ARM style we have to forget any types we might
713 have remembered up to this point, since they were not argument
714 types. GNU style considers all types seen as available for
715 back references. See comment in demangle_args() */
717 if (LUCID_DEMANGLING || ARM_DEMANGLING)
721 success = demangle_args (work, mangled, declp);
726 string_init(&trawname);
728 if (oldmangled == NULL)
730 oldmangled = *mangled;
732 success = demangle_template (work, mangled, &tname, &trawname);
735 remember_type (work, oldmangled, *mangled - oldmangled);
737 string_append(&tname, "::");
738 string_prepends(declp, &tname);
739 if (work -> destructor & 1)
741 string_prepend (&trawname, "~");
742 string_appends (declp, &trawname);
743 work->destructor -= 1;
745 if ((work->constructor & 1) || (work->destructor & 1))
747 string_appends (declp, &trawname);
748 work->constructor -= 1;
750 string_delete(&trawname);
751 string_delete(&tname);
757 /* At the outermost level, we cannot have a return type specified,
758 so if we run into another '_' at this point we are dealing with
759 a mangled name that is either bogus, or has been mangled by
760 some algorithm we don't know how to deal with. So just
761 reject the entire demangling. */
766 if (AUTO_DEMANGLING || GNU_DEMANGLING)
768 /* Assume we have stumbled onto the first outermost function
769 argument token, and start processing args. */
771 success = demangle_args (work, mangled, declp);
775 /* Non-GNU demanglers use a specific token to mark the start
776 of the outermost function argument tokens. Typically 'F',
777 for ARM-demangling, for example. So if we find something
778 we are not prepared for, it must be an error. */
784 if (AUTO_DEMANGLING || GNU_DEMANGLING)
787 if (success && expect_func)
790 success = demangle_args (work, mangled, declp);
794 if (success && !func_done)
796 if (AUTO_DEMANGLING || GNU_DEMANGLING)
798 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
799 bar__3fooi is 'foo::bar(int)'. We get here when we find the
800 first case, and need to ensure that the '(void)' gets added to
801 the current declp. Note that with ARM, the first case
802 represents the name of a static data member 'foo::bar',
803 which is in the current declp, so we leave it alone. */
804 success = demangle_args (work, mangled, declp);
807 if (success && work -> static_type && PRINT_ARG_TYPES)
809 string_append (declp, " static");
811 if (success && work -> const_type && PRINT_ARG_TYPES)
813 string_append (declp, " const");
821 demangle_method_args (work, mangled, declp)
822 struct work_stuff *work;
823 const char **mangled;
828 if (work -> static_type)
830 string_append (declp, *mangled + 1);
831 *mangled += strlen (*mangled);
836 success = demangle_args (work, mangled, declp);
844 demangle_template (work, mangled, tname, trawname)
845 struct work_stuff *work;
846 const char **mangled;
867 /* get template name */
868 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
873 string_appendn (trawname, *mangled, r);
874 string_appendn (tname, *mangled, r);
876 string_append (tname, "<");
877 /* get size of template parameter list */
878 if (!get_count (mangled, &r))
882 for (i = 0; i < r; i++)
886 string_append (tname, ", ");
888 /* Z for type parameters */
889 if (**mangled == 'Z')
892 /* temp is initialized in do_type */
893 success = do_type (work, mangled, &temp);
896 string_appends (tname, &temp);
898 string_delete(&temp);
906 /* otherwise, value parameter */
914 /* temp is initialized in do_type */
915 success = do_type (work, mangled, &temp);
919 string_appends (tname, &temp);
922 string_delete(&temp);
928 string_append (tname, "=");
930 while (*old_p && !done)
937 done = is_pointer = 1;
939 case 'C': /* const */
940 case 'S': /* explicitly signed [char] */
941 case 'U': /* unsigned */
942 case 'V': /* volatile */
943 case 'F': /* function */
944 case 'M': /* member function */
948 case 'Q': /* qualified name */
949 done = is_integral = 1;
951 case 'T': /* remembered type */
957 case 'x': /* long long */
960 case 's': /* short */
961 case 'w': /* wchar_t */
962 done = is_integral = 1;
970 case 'r': /* long double */
971 case 'd': /* double */
972 case 'f': /* float */
976 /* it's probably user defined type, let's assume
977 it's integral, it seems hard to figure out
979 done = is_integral = 1;
984 if (**mangled == 'm')
986 string_appendn (tname, "-", 1);
989 while (isdigit (**mangled))
991 string_appendn (tname, *mangled, 1);
999 if (**mangled == 'm')
1001 string_appendn (tname, "-", 1);
1004 string_appendn (tname, "'", 1);
1005 val = consume_count(mangled);
1013 string_appendn (tname, &tmp[0], 1);
1014 string_appendn (tname, "'", 1);
1018 int val = consume_count (mangled);
1020 string_appendn (tname, "false", 5);
1022 string_appendn (tname, "true", 4);
1028 if (**mangled == 'm')
1030 string_appendn (tname, "-", 1);
1033 while (isdigit (**mangled))
1035 string_appendn (tname, *mangled, 1);
1038 if (**mangled == '.') /* fraction */
1040 string_appendn (tname, ".", 1);
1042 while (isdigit (**mangled))
1044 string_appendn (tname, *mangled, 1);
1048 if (**mangled == 'e') /* exponent */
1050 string_appendn (tname, "e", 1);
1052 while (isdigit (**mangled))
1054 string_appendn (tname, *mangled, 1);
1059 else if (is_pointer)
1061 symbol_len = consume_count (mangled);
1062 if (symbol_len == 0)
1067 if (symbol_len == 0)
1068 string_appendn (tname, "0", 1);
1071 char *p = xmalloc (symbol_len + 1), *q;
1072 strncpy (p, *mangled, symbol_len);
1073 p [symbol_len] = '\0';
1074 q = cplus_demangle (p, work->options);
1075 string_appendn (tname, "&", 1);
1078 string_append (tname, q);
1082 string_append (tname, p);
1085 *mangled += symbol_len;
1090 if (tname->p[-1] == '>')
1091 string_append (tname, " ");
1092 string_append (tname, ">");
1095 if (work -> static_type)
1097 string_append (declp, *mangled + 1);
1098 *mangled += strlen (*mangled);
1103 success = demangle_args (work, mangled, declp);
1111 arm_pt (work, mangled, n, anchor, args)
1112 struct work_stuff *work;
1113 const char *mangled;
1115 const char **anchor, **args;
1118 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1121 *args = *anchor + 6;
1122 len = consume_count (args);
1123 if (*args + len == mangled + n && **args == '_')
1133 demangle_arm_pt (work, mangled, n, declp)
1134 struct work_stuff *work;
1135 const char **mangled;
1141 const char *e = *mangled + n;
1144 if (arm_pt (work, *mangled, n, &p, &args))
1148 string_appendn (declp, *mangled, p - *mangled);
1149 string_append (declp, "<");
1150 /* should do error checking here */
1152 string_clear (&arg);
1153 do_type (work, &args, &arg);
1154 string_appends (declp, &arg);
1155 string_append (declp, ",");
1157 string_delete (&arg);
1159 string_append (declp, ">");
1163 string_appendn (declp, *mangled, n);
1169 demangle_class_name (work, mangled, declp)
1170 struct work_stuff *work;
1171 const char **mangled;
1177 n = consume_count (mangled);
1178 if (strlen (*mangled) >= n)
1180 demangle_arm_pt (work, mangled, n, declp);
1191 demangle_class -- demangle a mangled class sequence
1196 demangle_class (struct work_stuff *work, const char **mangled,
1201 DECLP points to the buffer into which demangling is being done.
1203 *MANGLED points to the current token to be demangled. On input,
1204 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1205 On exit, it points to the next token after the mangled class on
1206 success, or the first unconsumed token on failure.
1208 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1209 we are demangling a constructor or destructor. In this case
1210 we prepend "class::class" or "class::~class" to DECLP.
1212 Otherwise, we prepend "class::" to the current DECLP.
1214 Reset the constructor/destructor flags once they have been
1215 "consumed". This allows demangle_class to be called later during
1216 the same demangling, to do normal class demangling.
1218 Returns 1 if demangling is successful, 0 otherwise.
1223 demangle_class (work, mangled, declp)
1224 struct work_stuff *work;
1225 const char **mangled;
1231 string_init (&class_name);
1232 if (demangle_class_name (work, mangled, &class_name))
1234 if ((work->constructor & 1) || (work->destructor & 1))
1236 string_prepends (declp, &class_name);
1237 if (work -> destructor & 1)
1239 string_prepend (declp, "~");
1240 work -> destructor -= 1;
1244 work -> constructor -= 1;
1247 string_prepend (declp, "::");
1248 string_prepends (declp, &class_name);
1251 string_delete (&class_name);
1259 demangle_prefix -- consume the mangled name prefix and find signature
1264 demangle_prefix (struct work_stuff *work, const char **mangled,
1269 Consume and demangle the prefix of the mangled name.
1271 DECLP points to the string buffer into which demangled output is
1272 placed. On entry, the buffer is empty. On exit it contains
1273 the root function name, the demangled operator name, or in some
1274 special cases either nothing or the completely demangled result.
1276 MANGLED points to the current pointer into the mangled name. As each
1277 token of the mangled name is consumed, it is updated. Upon entry
1278 the current mangled name pointer points to the first character of
1279 the mangled name. Upon exit, it should point to the first character
1280 of the signature if demangling was successful, or to the first
1281 unconsumed character if demangling of the prefix was unsuccessful.
1283 Returns 1 on success, 0 otherwise.
1287 demangle_prefix (work, mangled, declp)
1288 struct work_stuff *work;
1289 const char **mangled;
1296 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1298 char *marker = strchr (cplus_markers, (*mangled)[8]);
1299 if (marker != NULL && *marker == (*mangled)[10])
1301 if ((*mangled)[9] == 'D')
1303 /* it's a GNU global destructor to be executed at program exit */
1305 work->destructor = 2;
1306 if (gnu_special (work, mangled, declp))
1309 else if ((*mangled)[9] == 'I')
1311 /* it's a GNU global constructor to be executed at program init */
1313 work->constructor = 2;
1314 if (gnu_special (work, mangled, declp))
1319 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1321 /* it's a ARM global destructor to be executed at program exit */
1323 work->destructor = 2;
1325 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1327 /* it's a ARM global constructor to be executed at program initial */
1329 work->constructor = 2;
1332 /* This block of code is a reduction in strength time optimization
1334 scan = mystrstr (*mangled, "__"); */
1340 scan = strchr (scan, '_');
1341 } while (scan != NULL && *++scan != '_');
1343 if (scan != NULL) --scan;
1348 /* We found a sequence of two or more '_', ensure that we start at
1349 the last pair in the sequence. */
1350 i = strspn (scan, "_");
1361 else if (work -> static_type)
1363 if (!isdigit (scan[0]) && (scan[0] != 't'))
1368 else if ((scan == *mangled) &&
1369 (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')))
1371 /* The ARM says nothing about the mangling of local variables.
1372 But cfront mangles local variables by prepending __<nesting_level>
1373 to them. As an extension to ARM demangling we handle this case. */
1374 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1376 *mangled = scan + 2;
1377 consume_count (mangled);
1378 string_append (declp, *mangled);
1379 *mangled += strlen (*mangled);
1384 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1385 names like __Q2_3foo3bar for nested type names. So don't accept
1386 this style of constructor for cfront demangling. */
1387 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1388 work -> constructor += 1;
1389 *mangled = scan + 2;
1392 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1394 /* Mangled name starts with "__". Skip over any leading '_' characters,
1395 then find the next "__" that separates the prefix from the signature.
1397 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1398 || (arm_special (work, mangled, declp) == 0))
1400 while (*scan == '_')
1404 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1406 /* No separator (I.E. "__not_mangled"), or empty signature
1407 (I.E. "__not_mangled_either__") */
1412 demangle_function_name (work, mangled, declp, scan);
1416 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1418 /* Cfront-style parameterized type. Handled later as a signature. */
1422 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1424 else if (*(scan + 2) != '\0')
1426 /* Mangled name does not start with "__" but does have one somewhere
1427 in there with non empty stuff after it. Looks like a global
1429 demangle_function_name (work, mangled, declp, scan);
1433 /* Doesn't look like a mangled name */
1437 if (!success && (work->constructor == 2 || work->destructor == 2))
1439 string_append (declp, *mangled);
1440 *mangled += strlen (*mangled);
1450 gnu_special -- special handling of gnu mangled strings
1455 gnu_special (struct work_stuff *work, const char **mangled,
1461 Process some special GNU style mangling forms that don't fit
1462 the normal pattern. For example:
1464 _$_3foo (destructor for class foo)
1465 _vt$foo (foo virtual table)
1466 _vt$foo$bar (foo::bar virtual table)
1467 __vt_foo (foo virtual table, new style with thunks)
1468 _3foo$varname (static data member)
1469 _Q22rs2tu$vw (static data member)
1470 __t6vector1Zii (constructor with template)
1471 __thunk_4__$_7ostream (virtual function thunk)
1475 gnu_special (work, mangled, declp)
1476 struct work_stuff *work;
1477 const char **mangled;
1484 if ((*mangled)[0] == '_'
1485 && strchr (cplus_markers, (*mangled)[1]) != NULL
1486 && (*mangled)[2] == '_')
1488 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1490 work -> destructor += 1;
1492 else if ((*mangled)[0] == '_'
1493 && (((*mangled)[1] == '_'
1494 && (*mangled)[2] == 'v'
1495 && (*mangled)[3] == 't'
1496 && (*mangled)[4] == '_')
1497 || ((*mangled)[1] == 'v'
1498 && (*mangled)[2] == 't'
1499 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1501 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1502 and create the decl. Note that we consume the entire mangled
1503 input string, which means that demangle_signature has no work
1505 if ((*mangled)[2] == 'v')
1506 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1508 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1509 while (**mangled != '\0')
1511 p = strpbrk (*mangled, cplus_markers);
1515 success = demangle_qualified (work, mangled, declp, 0, 1);
1518 success = demangle_template (work, mangled, declp, 0);
1521 if (isdigit(*mangled[0]))
1523 n = consume_count(mangled);
1527 n = strcspn (*mangled, cplus_markers);
1529 string_appendn (declp, *mangled, n);
1533 if (success && ((p == NULL) || (p == *mangled)))
1537 string_append (declp, "::");
1548 string_append (declp, " virtual table");
1550 else if ((*mangled)[0] == '_'
1551 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1552 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1554 /* static data member, "_3foo$varname" for example */
1559 success = demangle_qualified (work, mangled, declp, 0, 1);
1562 success = demangle_template (work, mangled, declp, 0);
1565 n = consume_count (mangled);
1566 string_appendn (declp, *mangled, n);
1569 if (success && (p == *mangled))
1571 /* Consumed everything up to the cplus_marker, append the
1574 string_append (declp, "::");
1575 n = strlen (*mangled);
1576 string_appendn (declp, *mangled, n);
1584 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1586 int delta = ((*mangled) += 8, consume_count (mangled));
1587 char *method = cplus_demangle (++*mangled, work->options);
1591 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1592 string_append (declp, buf);
1593 string_append (declp, method);
1595 n = strlen (*mangled);
1603 else if (strncmp (*mangled, "__t", 3) == 0
1604 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
1606 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
1611 success = demangle_qualified (work, mangled, declp, 0, 1);
1614 success = demangle_template (work, mangled, declp, 0);
1617 n = consume_count (mangled);
1618 string_appendn (declp, *mangled, n);
1621 if (success && **mangled != '\0')
1624 string_append (declp, p);
1637 arm_special -- special handling of ARM/lucid mangled strings
1642 arm_special (struct work_stuff *work, const char **mangled,
1648 Process some special ARM style mangling forms that don't fit
1649 the normal pattern. For example:
1651 __vtbl__3foo (foo virtual table)
1652 __vtbl__3foo__3bar (bar::foo virtual table)
1657 arm_special (work, mangled, declp)
1658 struct work_stuff *work;
1659 const char **mangled;
1666 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1668 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1669 and create the decl. Note that we consume the entire mangled
1670 input string, which means that demangle_signature has no work
1672 scan = *mangled + ARM_VTABLE_STRLEN;
1673 while (*scan != '\0') /* first check it can be demangled */
1675 n = consume_count (&scan);
1678 return (0); /* no good */
1681 if (scan[0] == '_' && scan[1] == '_')
1686 (*mangled) += ARM_VTABLE_STRLEN;
1687 while (**mangled != '\0')
1689 n = consume_count (mangled);
1690 string_prependn (declp, *mangled, n);
1692 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1694 string_prepend (declp, "::");
1698 string_append (declp, " virtual table");
1711 demangle_qualified -- demangle 'Q' qualified name strings
1716 demangle_qualified (struct work_stuff *, const char *mangled,
1717 string *result, int isfuncname, int append);
1721 Demangle a qualified name, such as "Q25Outer5Inner" which is
1722 the mangled form of "Outer::Inner". The demangled output is
1723 prepended or appended to the result string according to the
1724 state of the append flag.
1726 If isfuncname is nonzero, then the qualified name we are building
1727 is going to be used as a member function name, so if it is a
1728 constructor or destructor function, append an appropriate
1729 constructor or destructor name. I.E. for the above example,
1730 the result for use as a constructor is "Outer::Inner::Inner"
1731 and the result for use as a destructor is "Outer::Inner::~Inner".
1735 Numeric conversion is ASCII dependent (FIXME).
1740 demangle_qualified (work, mangled, result, isfuncname, append)
1741 struct work_stuff *work;
1742 const char **mangled;
1754 string_init (&temp);
1755 switch ((*mangled)[1])
1758 /* GNU mangled name with more than 9 classes. The count is preceded
1759 by an underscore (to distinguish it from the <= 9 case) and followed
1760 by an underscore. */
1762 qualifiers = atoi (p);
1763 if (!isdigit (*p) || *p == '0')
1766 /* Skip the digits. */
1767 while (isdigit (*p))
1785 /* The count is in a single digit. */
1786 num[0] = (*mangled)[1];
1788 qualifiers = atoi (num);
1790 /* If there is an underscore after the digit, skip it. This is
1791 said to be for ARM-qualified names, but the ARM makes no
1792 mention of such an underscore. Perhaps cfront uses one. */
1793 if ((*mangled)[2] == '_')
1808 /* Pick off the names and collect them in the temp buffer in the order
1809 in which they are found, separated by '::'. */
1811 while (qualifiers-- > 0)
1813 if (*mangled[0] == '_')
1814 *mangled = *mangled + 1;
1815 if (*mangled[0] == 't')
1817 success = demangle_template(work, mangled, &temp, 0);
1818 if (!success) break;
1822 namelength = consume_count (mangled);
1823 if (strlen (*mangled) < namelength)
1825 /* Simple sanity check failed */
1829 string_appendn (&temp, *mangled, namelength);
1830 *mangled += namelength;
1834 string_appendn (&temp, "::", 2);
1838 /* If we are using the result as a function name, we need to append
1839 the appropriate '::' separated constructor or destructor name.
1840 We do this here because this is the most convenient place, where
1841 we already have a pointer to the name and the length of the name. */
1843 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
1845 string_appendn (&temp, "::", 2);
1846 if (work -> destructor & 1)
1848 string_append (&temp, "~");
1850 string_appendn (&temp, (*mangled) - namelength, namelength);
1853 /* Now either prepend the temp buffer to the result, or append it,
1854 depending upon the state of the append flag. */
1858 string_appends (result, &temp);
1862 if (!STRING_EMPTY (result))
1864 string_appendn (&temp, "::", 2);
1866 string_prepends (result, &temp);
1869 string_delete (&temp);
1877 get_count -- convert an ascii count to integer, consuming tokens
1882 get_count (const char **type, int *count)
1886 Return 0 if no conversion is performed, 1 if a string is converted.
1890 get_count (type, count)
1897 if (!isdigit (**type))
1903 *count = **type - '0';
1905 if (isdigit (**type))
1915 while (isdigit (*p));
1926 /* result will be initialised here; it will be freed on failure */
1929 do_type (work, mangled, result)
1930 struct work_stuff *work;
1931 const char **mangled;
1938 const char *remembered_type;
1942 string_init (&decl);
1943 string_init (result);
1947 while (success && !done)
1953 /* A pointer type */
1957 string_prepend (&decl, "*");
1960 /* A reference type */
1963 string_prepend (&decl, "&");
1969 const char *p = ++(*mangled);
1971 string_prepend (&decl, "(");
1972 string_append (&decl, ")[");
1973 /* Copy anything up until the next underscore (the size of the
1975 while (**mangled && **mangled != '_')
1977 if (**mangled == '_')
1979 string_appendn (&decl, p, *mangled - p);
1980 string_append (&decl, "]");
1988 /* A back reference to a previously seen type */
1991 if (!get_count (mangled, &n) || n >= work -> ntypes)
1997 remembered_type = work -> typevec[n];
1998 mangled = &remembered_type;
2005 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2007 string_prepend (&decl, "(");
2008 string_append (&decl, ")");
2010 /* After picking off the function args, we expect to either find the
2011 function return type (preceded by an '_') or the end of the
2013 if (!demangle_args (work, mangled, &decl)
2014 || (**mangled != '_' && **mangled != '\0'))
2018 if (success && (**mangled == '_'))
2030 member = **mangled == 'M';
2032 if (!isdigit (**mangled) && **mangled != 't')
2038 string_append (&decl, ")");
2039 string_prepend (&decl, "::");
2040 if (isdigit (**mangled))
2042 n = consume_count (mangled);
2043 if (strlen (*mangled) < n)
2048 string_prependn (&decl, *mangled, n);
2054 string_init (&temp);
2055 success = demangle_template (work, mangled, &temp, NULL);
2058 string_prependn (&decl, temp.b, temp.p - temp.b);
2059 string_clear (&temp);
2064 string_prepend (&decl, "(");
2067 if (**mangled == 'C')
2072 if (**mangled == 'V')
2077 if (*(*mangled)++ != 'F')
2083 if ((member && !demangle_args (work, mangled, &decl))
2084 || **mangled != '_')
2090 if (! PRINT_ANSI_QUALIFIERS)
2096 APPEND_BLANK (&decl);
2097 string_append (&decl, "const");
2101 APPEND_BLANK (&decl);
2102 string_append (&decl, "volatile");
2113 if ((*mangled)[1] == 'P')
2116 if (PRINT_ANSI_QUALIFIERS)
2118 if (!STRING_EMPTY (&decl))
2120 string_prepend (&decl, " ");
2122 string_prepend (&decl, "const");
2138 /* A qualified name, such as "Outer::Inner". */
2140 success = demangle_qualified (work, mangled, result, 0, 1);
2144 success = demangle_fund_type (work, mangled, result);
2150 if (!STRING_EMPTY (&decl))
2152 string_append (result, " ");
2153 string_appends (result, &decl);
2158 string_delete (result);
2160 string_delete (&decl);
2164 /* Given a pointer to a type string that represents a fundamental type
2165 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2166 string in which the demangled output is being built in RESULT, and
2167 the WORK structure, decode the types and add them to the result.
2172 "Sl" => "signed long"
2173 "CUs" => "const unsigned short"
2178 demangle_fund_type (work, mangled, result)
2179 struct work_stuff *work;
2180 const char **mangled;
2186 /* First pick off any type qualifiers. There can be more than one. */
2194 if (PRINT_ANSI_QUALIFIERS)
2196 APPEND_BLANK (result);
2197 string_append (result, "const");
2202 APPEND_BLANK (result);
2203 string_append (result, "unsigned");
2205 case 'S': /* signed char only */
2207 APPEND_BLANK (result);
2208 string_append (result, "signed");
2212 if (PRINT_ANSI_QUALIFIERS)
2214 APPEND_BLANK (result);
2215 string_append (result, "volatile");
2224 /* Now pick off the fundamental type. There can be only one. */
2233 APPEND_BLANK (result);
2234 string_append (result, "void");
2238 APPEND_BLANK (result);
2239 string_append (result, "long long");
2243 APPEND_BLANK (result);
2244 string_append (result, "long");
2248 APPEND_BLANK (result);
2249 string_append (result, "int");
2253 APPEND_BLANK (result);
2254 string_append (result, "short");
2258 APPEND_BLANK (result);
2259 string_append (result, "bool");
2263 APPEND_BLANK (result);
2264 string_append (result, "char");
2268 APPEND_BLANK (result);
2269 string_append (result, "wchar_t");
2273 APPEND_BLANK (result);
2274 string_append (result, "long double");
2278 APPEND_BLANK (result);
2279 string_append (result, "double");
2283 APPEND_BLANK (result);
2284 string_append (result, "float");
2288 if (!isdigit (**mangled))
2294 /* An explicit type, such as "6mytype" or "7integer" */
2305 APPEND_BLANK (result);
2306 if (!demangle_class_name (work, mangled, result)) {
2312 success = demangle_template(work,mangled, result, 0);
2322 /* `result' will be initialized in do_type; it will be freed on failure */
2325 do_arg (work, mangled, result)
2326 struct work_stuff *work;
2327 const char **mangled;
2330 const char *start = *mangled;
2332 if (!do_type (work, mangled, result))
2338 remember_type (work, start, *mangled - start);
2344 remember_type (work, start, len)
2345 struct work_stuff *work;
2351 if (work -> ntypes >= work -> typevec_size)
2353 if (work -> typevec_size == 0)
2355 work -> typevec_size = 3;
2357 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2361 work -> typevec_size *= 2;
2363 (char **) xrealloc ((char *)work -> typevec,
2364 sizeof (char *) * work -> typevec_size);
2367 tem = xmalloc (len + 1);
2368 memcpy (tem, start, len);
2370 work -> typevec[work -> ntypes++] = tem;
2373 /* Forget the remembered types, but not the type vector itself. */
2377 struct work_stuff *work;
2381 while (work -> ntypes > 0)
2383 i = --(work -> ntypes);
2384 if (work -> typevec[i] != NULL)
2386 free (work -> typevec[i]);
2387 work -> typevec[i] = NULL;
2392 /* Process the argument list part of the signature, after any class spec
2393 has been consumed, as well as the first 'F' character (if any). For
2396 "__als__3fooRT0" => process "RT0"
2397 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2399 DECLP must be already initialised, usually non-empty. It won't be freed
2402 Note that g++ differs significantly from ARM and lucid style mangling
2403 with regards to references to previously seen types. For example, given
2404 the source fragment:
2408 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2411 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2412 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2414 g++ produces the names:
2419 while lcc (and presumably other ARM style compilers as well) produces:
2421 foo__FiR3fooT1T2T1T2
2422 __ct__3fooFiR3fooT1T2T1T2
2424 Note that g++ bases it's type numbers starting at zero and counts all
2425 previously seen types, while lucid/ARM bases it's type numbers starting
2426 at one and only considers types after it has seen the 'F' character
2427 indicating the start of the function args. For lucid/ARM style, we
2428 account for this difference by discarding any previously seen types when
2429 we see the 'F' character, and subtracting one from the type number
2435 demangle_args (work, mangled, declp)
2436 struct work_stuff *work;
2437 const char **mangled;
2447 if (PRINT_ARG_TYPES)
2449 string_append (declp, "(");
2450 if (**mangled == '\0')
2452 string_append (declp, "void");
2456 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2458 if ((**mangled == 'N') || (**mangled == 'T'))
2460 temptype = *(*mangled)++;
2462 if (temptype == 'N')
2464 if (!get_count (mangled, &r))
2473 if (ARM_DEMANGLING && work -> ntypes >= 10)
2475 /* If we have 10 or more types we might have more than a 1 digit
2476 index so we'll have to consume the whole count here. This
2477 will lose if the next thing is a type name preceded by a
2478 count but it's impossible to demangle that case properly
2479 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2480 Pc, ...)" or "(..., type12, char *, ...)" */
2481 if ((t = consume_count(mangled)) == 0)
2488 if (!get_count (mangled, &t))
2493 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2497 /* Validate the type index. Protect against illegal indices from
2498 malformed type strings. */
2499 if ((t < 0) || (t >= work -> ntypes))
2505 tem = work -> typevec[t];
2506 if (need_comma && PRINT_ARG_TYPES)
2508 string_append (declp, ", ");
2510 if (!do_arg (work, &tem, &arg))
2514 if (PRINT_ARG_TYPES)
2516 string_appends (declp, &arg);
2518 string_delete (&arg);
2524 if (need_comma & PRINT_ARG_TYPES)
2526 string_append (declp, ", ");
2528 if (!do_arg (work, mangled, &arg))
2532 if (PRINT_ARG_TYPES)
2534 string_appends (declp, &arg);
2536 string_delete (&arg);
2541 if (**mangled == 'e')
2544 if (PRINT_ARG_TYPES)
2548 string_append (declp, ",");
2550 string_append (declp, "...");
2554 if (PRINT_ARG_TYPES)
2556 string_append (declp, ")");
2562 demangle_function_name (work, mangled, declp, scan)
2563 struct work_stuff *work;
2564 const char **mangled;
2573 string_appendn (declp, (*mangled), scan - (*mangled));
2574 string_need (declp, 1);
2575 *(declp -> p) = '\0';
2577 /* Consume the function name, including the "__" separating the name
2578 from the signature. We are guaranteed that SCAN points to the
2581 (*mangled) = scan + 2;
2583 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2586 /* See if we have an ARM style constructor or destructor operator.
2587 If so, then just record it, clear the decl, and return.
2588 We can't build the actual constructor/destructor decl until later,
2589 when we recover the class name from the signature. */
2591 if (strcmp (declp -> b, "__ct") == 0)
2593 work -> constructor += 1;
2594 string_clear (declp);
2597 else if (strcmp (declp -> b, "__dt") == 0)
2599 work -> destructor += 1;
2600 string_clear (declp);
2605 if (declp->p - declp->b >= 3
2606 && declp->b[0] == 'o'
2607 && declp->b[1] == 'p'
2608 && strchr (cplus_markers, declp->b[2]) != NULL)
2610 /* see if it's an assignment expression */
2611 if (declp->p - declp->b >= 10 /* op$assign_ */
2612 && memcmp (declp->b + 3, "assign_", 7) == 0)
2614 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2616 len = declp->p - declp->b - 10;
2617 if (strlen (optable[i].in) == len
2618 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2620 string_clear (declp);
2621 string_append (declp, "operator");
2622 string_append (declp, optable[i].out);
2623 string_append (declp, "=");
2630 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2632 int len = declp->p - declp->b - 3;
2633 if (strlen (optable[i].in) == len
2634 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2636 string_clear (declp);
2637 string_append (declp, "operator");
2638 string_append (declp, optable[i].out);
2644 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2645 && strchr (cplus_markers, declp->b[4]) != NULL)
2647 /* type conversion operator */
2649 if (do_type (work, &tem, &type))
2651 string_clear (declp);
2652 string_append (declp, "operator ");
2653 string_appends (declp, &type);
2654 string_delete (&type);
2657 else if (declp->b[0] == '_' && declp->b[1] == '_'
2658 && declp->b[2] == 'o' && declp->b[3] == 'p')
2661 /* type conversion operator. */
2663 if (do_type (work, &tem, &type))
2665 string_clear (declp);
2666 string_append (declp, "operator ");
2667 string_appends (declp, &type);
2668 string_delete (&type);
2671 else if (declp->b[0] == '_' && declp->b[1] == '_'
2672 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2673 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2675 if (declp->b[4] == '\0')
2678 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2680 if (strlen (optable[i].in) == 2
2681 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2683 string_clear (declp);
2684 string_append (declp, "operator");
2685 string_append (declp, optable[i].out);
2692 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2695 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2697 if (strlen (optable[i].in) == 3
2698 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2700 string_clear (declp);
2701 string_append (declp, "operator");
2702 string_append (declp, optable[i].out);
2711 /* a mini string-handling package */
2726 s->p = s->b = xmalloc (n);
2729 else if (s->e - s->p < n)
2734 s->b = xrealloc (s->b, n);
2747 s->b = s->e = s->p = NULL;
2755 s->b = s->p = s->e = NULL;
2771 return (s->b == s->p);
2777 string_append (p, s)
2782 if (s == NULL || *s == '\0')
2786 memcpy (p->p, s, n);
2791 string_appends (p, s)
2800 memcpy (p->p, s->b, n);
2806 string_appendn (p, s, n)
2814 memcpy (p->p, s, n);
2820 string_prepend (p, s)
2824 if (s != NULL && *s != '\0')
2826 string_prependn (p, s, strlen (s));
2831 string_prepends (p, s)
2836 string_prependn (p, s->b, s->p - s->b);
2841 string_prependn (p, s, n)
2851 for (q = p->p - 1; q >= p->b; q--)
2855 memcpy (p->b, s, n);
2860 /* To generate a standalone demangler program for testing purposes,
2861 just compile and link this file with -DMAIN and libiberty.a. When
2862 run, it demangles each command line arg, or each stdin string, and
2863 prints the result on stdout. */
2868 demangle_it (mangled_name)
2873 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2876 printf ("%s\n", mangled_name);
2880 printf ("%s\n", result);
2887 static char *program_name;
2888 static char *program_version = VERSION;
2891 usage (stream, status)
2896 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
2897 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
2898 [--help] [--version] [arg...]\n",
2903 #define MBUF_SIZE 512
2904 char mbuffer[MBUF_SIZE];
2906 /* Defined in the automatically-generated underscore.c. */
2907 extern int prepends_underscore;
2909 int strip_underscore = 0;
2911 static struct option long_options[] = {
2912 {"strip-underscores", no_argument, 0, '_'},
2913 {"format", required_argument, 0, 's'},
2914 {"help", no_argument, 0, 'h'},
2915 {"no-strip-underscores", no_argument, 0, 'n'},
2916 {"version", no_argument, 0, 'v'},
2917 {0, no_argument, 0, 0}
2928 program_name = argv[0];
2930 strip_underscore = prepends_underscore;
2932 while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
2942 strip_underscore = 0;
2945 printf ("GNU %s version %s\n", program_name, program_version);
2948 strip_underscore = 1;
2951 if (strcmp (optarg, "gnu") == 0)
2953 current_demangling_style = gnu_demangling;
2955 else if (strcmp (optarg, "lucid") == 0)
2957 current_demangling_style = lucid_demangling;
2959 else if (strcmp (optarg, "arm") == 0)
2961 current_demangling_style = arm_demangling;
2965 fprintf (stderr, "%s: unknown demangling style `%s'\n",
2966 program_name, optarg);
2975 for ( ; optind < argc; optind++)
2977 demangle_it (argv[optind]);
2986 /* Try to read a label. */
2987 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
2989 if (i >= MBUF_SIZE-1)
2998 if (mbuffer[0] == '.')
3000 if (strip_underscore && mbuffer[skip_first] == '_')
3008 result = cplus_demangle (mbuffer + skip_first,
3009 DMGL_PARAMS | DMGL_ANSI);
3012 if (mbuffer[0] == '.')
3014 fputs (result, stdout);
3018 fputs (mbuffer, stdout);
3035 fprintf (stderr, "%s: %s\n", program_name, str);
3046 register char *value = (char *) malloc (size);
3048 fatal ("virtual memory exhausted");
3053 xrealloc (ptr, size)
3057 register char *value = (char *) realloc (ptr, size);
3059 fatal ("virtual memory exhausted");