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. */
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));
42 static const char *mystrstr PARAMS ((const char *, const char *));
48 register const char *p = s1;
49 register int len = strlen (s2);
51 for (; (p = strchr (p, *s2)) != 0; p++)
53 if (strncmp (p, s2, len) == 0)
61 /* In order to allow a single demangler executable to demangle strings
62 using various common values of CPLUS_MARKER, as well as any specific
63 one set at compile time, we maintain a string containing all the
64 commonly used ones, and check to see if the marker we are looking for
65 is in that string. CPLUS_MARKER is usually '$' on systems where the
66 assembler can deal with that. Where the assembler can't, it's usually
67 '.' (but on many systems '.' is used for other things). We put the
68 current defined CPLUS_MARKER first (which defaults to '$'), followed
69 by the next most common value, followed by an explicit '$' in case
70 the value of CPLUS_MARKER is not '$'.
72 We could avoid this if we could just get g++ to tell us what the actual
73 cplus marker character is as part of the debug information, perhaps by
74 ensuring that it is the character that terminates the gcc<n>_compiled
75 marker symbol (FIXME). */
77 #if !defined (CPLUS_MARKER)
78 #define CPLUS_MARKER '$'
81 enum demangling_styles current_demangling_style = gnu_demangling;
83 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
86 set_cplus_marker_for_demangling (ch)
89 cplus_markers[0] = ch;
92 /* Stuff that is shared between sub-routines.
93 Using a shared structure allows cplus_demangle to be reentrant. */
103 int static_type; /* A static member function */
104 int const_type; /* A const member function */
105 char **tmpl_argvec; /* Template function arguments. */
106 int ntmpl_args; /* The number of template function arguments. */
109 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
110 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
112 static const struct optable
118 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
119 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
120 {"new", " new", 0}, /* old (1.91, and 1.x) */
121 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
122 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
123 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
124 {"as", "=", DMGL_ANSI}, /* ansi */
125 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
126 {"eq", "==", DMGL_ANSI}, /* old, ansi */
127 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
128 {"gt", ">", DMGL_ANSI}, /* old, ansi */
129 {"le", "<=", DMGL_ANSI}, /* old, ansi */
130 {"lt", "<", DMGL_ANSI}, /* old, ansi */
131 {"plus", "+", 0}, /* old */
132 {"pl", "+", DMGL_ANSI}, /* ansi */
133 {"apl", "+=", DMGL_ANSI}, /* ansi */
134 {"minus", "-", 0}, /* old */
135 {"mi", "-", DMGL_ANSI}, /* ansi */
136 {"ami", "-=", DMGL_ANSI}, /* ansi */
137 {"mult", "*", 0}, /* old */
138 {"ml", "*", DMGL_ANSI}, /* ansi */
139 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
140 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
141 {"convert", "+", 0}, /* old (unary +) */
142 {"negate", "-", 0}, /* old (unary -) */
143 {"trunc_mod", "%", 0}, /* old */
144 {"md", "%", DMGL_ANSI}, /* ansi */
145 {"amd", "%=", DMGL_ANSI}, /* ansi */
146 {"trunc_div", "/", 0}, /* old */
147 {"dv", "/", DMGL_ANSI}, /* ansi */
148 {"adv", "/=", DMGL_ANSI}, /* ansi */
149 {"truth_andif", "&&", 0}, /* old */
150 {"aa", "&&", DMGL_ANSI}, /* ansi */
151 {"truth_orif", "||", 0}, /* old */
152 {"oo", "||", DMGL_ANSI}, /* ansi */
153 {"truth_not", "!", 0}, /* old */
154 {"nt", "!", DMGL_ANSI}, /* ansi */
155 {"postincrement","++", 0}, /* old */
156 {"pp", "++", DMGL_ANSI}, /* ansi */
157 {"postdecrement","--", 0}, /* old */
158 {"mm", "--", DMGL_ANSI}, /* ansi */
159 {"bit_ior", "|", 0}, /* old */
160 {"or", "|", DMGL_ANSI}, /* ansi */
161 {"aor", "|=", DMGL_ANSI}, /* ansi */
162 {"bit_xor", "^", 0}, /* old */
163 {"er", "^", DMGL_ANSI}, /* ansi */
164 {"aer", "^=", DMGL_ANSI}, /* ansi */
165 {"bit_and", "&", 0}, /* old */
166 {"ad", "&", DMGL_ANSI}, /* ansi */
167 {"aad", "&=", DMGL_ANSI}, /* ansi */
168 {"bit_not", "~", 0}, /* old */
169 {"co", "~", DMGL_ANSI}, /* ansi */
170 {"call", "()", 0}, /* old */
171 {"cl", "()", DMGL_ANSI}, /* ansi */
172 {"alshift", "<<", 0}, /* old */
173 {"ls", "<<", DMGL_ANSI}, /* ansi */
174 {"als", "<<=", DMGL_ANSI}, /* ansi */
175 {"arshift", ">>", 0}, /* old */
176 {"rs", ">>", DMGL_ANSI}, /* ansi */
177 {"ars", ">>=", DMGL_ANSI}, /* ansi */
178 {"component", "->", 0}, /* old */
179 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
180 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
181 {"indirect", "*", 0}, /* old */
182 {"method_call", "->()", 0}, /* old */
183 {"addr", "&", 0}, /* old (unary &) */
184 {"array", "[]", 0}, /* old */
185 {"vc", "[]", DMGL_ANSI}, /* ansi */
186 {"compound", ", ", 0}, /* old */
187 {"cm", ", ", DMGL_ANSI}, /* ansi */
188 {"cond", "?:", 0}, /* old */
189 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
190 {"max", ">?", 0}, /* old */
191 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
192 {"min", "<?", 0}, /* old */
193 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
194 {"nop", "", 0}, /* old (for operator=) */
195 {"rm", "->*", DMGL_ANSI} /* ansi */
199 typedef struct string /* Beware: these aren't required to be */
200 { /* '\0' terminated. */
201 char *b; /* pointer to start of string */
202 char *p; /* pointer after last character */
203 char *e; /* pointer after end of allocated space */
206 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
207 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
208 string_prepend(str, " ");}
209 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
210 string_append(str, " ");}
212 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
213 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
215 /* Prototypes for local functions */
218 mop_up PARAMS ((struct work_stuff *, string *, int));
222 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
226 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
230 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
234 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
237 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
240 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
244 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
247 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
250 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
253 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
256 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
259 arm_special PARAMS ((struct work_stuff *, const char **, string *));
262 string_need PARAMS ((string *, int));
265 string_delete PARAMS ((string *));
268 string_init PARAMS ((string *));
271 string_clear PARAMS ((string *));
275 string_empty PARAMS ((string *));
279 string_append PARAMS ((string *, const char *));
282 string_appends PARAMS ((string *, string *));
285 string_appendn PARAMS ((string *, const char *, int));
288 string_prepend PARAMS ((string *, const char *));
291 string_prependn PARAMS ((string *, const char *, int));
294 get_count PARAMS ((const char **, int *));
297 consume_count_with_underscores PARAMS ((const char**));
300 consume_count PARAMS ((const char **));
303 consume_count_with_underscores PARAMS ((const char**));
306 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
309 do_type PARAMS ((struct work_stuff *, const char **, string *));
312 do_arg PARAMS ((struct work_stuff *, const char **, string *));
315 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
319 remember_type PARAMS ((struct work_stuff *, const char *, int));
322 forget_types PARAMS ((struct work_stuff *));
325 string_prepends PARAMS ((string *, string *));
327 /* Translate count to integer, consuming tokens in the process.
328 Conversion terminates on the first non-digit character.
329 Trying to consume something that isn't a count results in
330 no consumption of input and a return of 0. */
338 while (isdigit (**type))
341 count += **type - '0';
348 /* Like consume_count, but for counts that are preceeded and followed
349 by '_' if they are greater than 10. Also, -1 is returned for
350 failure, since 0 can be a valid value. */
353 consume_count_with_underscores (mangled)
354 const char **mangled;
358 if (**mangled == '_')
361 if (!isdigit (**mangled))
364 idx = consume_count (mangled);
365 if (**mangled != '_')
366 /* The trailing underscore was missing. */
373 if (**mangled < '0' || **mangled > '9')
376 idx = **mangled - '0';
384 /* Like consume_count, but for counts that are preceeded and followed
385 by '_' if they are greater than 10. Also, -1 is returned for
386 failure, since 0 can be a valid value. */
389 consume_count_with_underscores (mangled)
390 const char **mangled;
394 if (**mangled == '_')
397 if (!isdigit (**mangled))
400 idx = consume_count (mangled);
401 if (**mangled != '_')
402 /* The trailing underscore was missing. */
409 if (**mangled < '0' || **mangled > '9')
412 idx = **mangled - '0';
420 cplus_demangle_opname (opname, result, options)
425 int len, i, len1, ret;
427 struct work_stuff work[1];
430 len = strlen(opname);
433 work->options = options;
435 if (opname[0] == '_' && opname[1] == '_'
436 && opname[2] == 'o' && opname[3] == 'p')
439 /* type conversion operator. */
441 if (do_type (work, &tem, &type))
443 strcat (result, "operator ");
444 strncat (result, type.b, type.p - type.b);
445 string_delete (&type);
449 else if (opname[0] == '_' && opname[1] == '_'
450 && opname[2] >= 'a' && opname[2] <= 'z'
451 && opname[3] >= 'a' && opname[3] <= 'z')
453 if (opname[4] == '\0')
456 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
458 if (strlen (optable[i].in) == 2
459 && memcmp (optable[i].in, opname + 2, 2) == 0)
461 strcat (result, "operator");
462 strcat (result, optable[i].out);
470 if (opname[2] == 'a' && opname[5] == '\0')
473 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
475 if (strlen (optable[i].in) == 3
476 && memcmp (optable[i].in, opname + 2, 3) == 0)
478 strcat (result, "operator");
479 strcat (result, optable[i].out);
490 && strchr (cplus_markers, opname[2]) != NULL)
492 /* see if it's an assignment expression */
493 if (len >= 10 /* op$assign_ */
494 && memcmp (opname + 3, "assign_", 7) == 0)
496 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
499 if (strlen (optable[i].in) == len1
500 && memcmp (optable[i].in, opname + 10, len1) == 0)
502 strcat (result, "operator");
503 strcat (result, optable[i].out);
504 strcat (result, "=");
512 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
515 if (strlen (optable[i].in) == len1
516 && memcmp (optable[i].in, opname + 3, len1) == 0)
518 strcat (result, "operator");
519 strcat (result, optable[i].out);
526 else if (len >= 5 && memcmp (opname, "type", 4) == 0
527 && strchr (cplus_markers, opname[4]) != NULL)
529 /* type conversion operator */
531 if (do_type (work, &tem, &type))
533 strcat (result, "operator ");
534 strncat (result, type.b, type.p - type.b);
535 string_delete (&type);
542 /* Takes operator name as e.g. "++" and returns mangled
543 operator name (e.g. "postincrement_expr"), or NULL if not found.
545 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
546 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
549 cplus_mangle_opname (opname, options)
556 len = strlen (opname);
557 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
559 if (strlen (optable[i].out) == len
560 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
561 && memcmp (optable[i].out, opname, len) == 0)
562 return optable[i].in;
567 /* char *cplus_demangle (const char *mangled, int options)
569 If MANGLED is a mangled function name produced by GNU C++, then
570 a pointer to a malloced string giving a C++ representation
571 of the name will be returned; otherwise NULL will be returned.
572 It is the caller's responsibility to free the string which
575 The OPTIONS arg may contain one or more of the following bits:
577 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
579 DMGL_PARAMS Function parameters are included.
583 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
584 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
585 cplus_demangle ("foo__1Ai", 0) => "A::foo"
587 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
588 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
589 cplus_demangle ("foo__1Afe", 0) => "A::foo"
591 Note that any leading underscores, or other such characters prepended by
592 the compilation system, are presumed to have already been stripped from
596 cplus_demangle (mangled, options)
602 struct work_stuff work[1];
603 char *demangled = NULL;
605 if ((mangled != NULL) && (*mangled != '\0'))
607 memset ((char *) work, 0, sizeof (work));
608 work -> options = options;
609 if ((work->options & DMGL_STYLE_MASK) == 0)
610 work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
614 /* First check to see if gnu style demangling is active and if the
615 string to be demangled contains a CPLUS_MARKER. If so, attempt to
616 recognize one of the gnu special forms rather than looking for a
617 standard prefix. In particular, don't worry about whether there
618 is a "__" string in the mangled string. Consider "_$_5__foo" for
621 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
623 success = gnu_special (work, &mangled, &decl);
627 success = demangle_prefix (work, &mangled, &decl);
629 if (success && (*mangled != '\0'))
631 success = demangle_signature (work, &mangled, &decl);
633 if (work->constructor == 2)
635 string_prepend(&decl, "global constructors keyed to ");
636 work->constructor = 0;
638 else if (work->destructor == 2)
640 string_prepend(&decl, "global destructors keyed to ");
641 work->destructor = 0;
643 demangled = mop_up (work, &decl, success);
649 mop_up (work, declp, success)
650 struct work_stuff *work;
654 char *demangled = NULL;
656 /* Discard the remembered types, if any. */
659 if (work -> typevec != NULL)
661 free ((char *) work -> typevec);
663 if (work->tmpl_argvec)
667 for (i = 0; i < work->ntmpl_args; i++)
668 if (work->tmpl_argvec[i])
669 free ((char*) work->tmpl_argvec[i]);
671 free ((char*) work->tmpl_argvec);
674 /* If demangling was successful, ensure that the demangled string is null
675 terminated and return it. Otherwise, free the demangling decl. */
679 string_delete (declp);
683 string_appendn (declp, "", 1);
684 demangled = declp -> b;
693 demangle_signature -- demangle the signature part of a mangled name
698 demangle_signature (struct work_stuff *work, const char **mangled,
703 Consume and demangle the signature portion of the mangled name.
705 DECLP is the string where demangled output is being built. At
706 entry it contains the demangled root name from the mangled name
707 prefix. I.E. either a demangled operator name or the root function
708 name. In some special cases, it may contain nothing.
710 *MANGLED points to the current unconsumed location in the mangled
711 name. As tokens are consumed and demangling is performed, the
712 pointer is updated to continuously point at the next token to
715 Demangling GNU style mangled names is nasty because there is no
716 explicit token that marks the start of the outermost function
720 demangle_signature (work, mangled, declp)
721 struct work_stuff *work;
722 const char **mangled;
728 int expect_return_type = 0;
729 const char *oldmangled = NULL;
733 while (success && (**mangled != '\0'))
738 oldmangled = *mangled;
739 success = demangle_qualified (work, mangled, declp, 1, 0);
742 remember_type (work, oldmangled, *mangled - oldmangled);
744 if (AUTO_DEMANGLING || GNU_DEMANGLING)
752 /* Static member function */
753 if (oldmangled == NULL)
755 oldmangled = *mangled;
758 work -> static_type = 1;
762 /* a const member function */
763 if (oldmangled == NULL)
765 oldmangled = *mangled;
768 work -> const_type = 1;
771 case '0': case '1': case '2': case '3': case '4':
772 case '5': case '6': case '7': case '8': case '9':
773 if (oldmangled == NULL)
775 oldmangled = *mangled;
777 success = demangle_class (work, mangled, declp);
780 remember_type (work, oldmangled, *mangled - oldmangled);
782 if (AUTO_DEMANGLING || GNU_DEMANGLING)
791 /* ARM style demangling includes a specific 'F' character after
792 the class name. For GNU style, it is just implied. So we can
793 safely just consume any 'F' at this point and be compatible
794 with either style. */
800 /* For lucid/ARM style we have to forget any types we might
801 have remembered up to this point, since they were not argument
802 types. GNU style considers all types seen as available for
803 back references. See comment in demangle_args() */
805 if (LUCID_DEMANGLING || ARM_DEMANGLING)
809 success = demangle_args (work, mangled, declp);
814 string_init(&trawname);
816 if (oldmangled == NULL)
818 oldmangled = *mangled;
820 success = demangle_template (work, mangled, &tname, &trawname, 1);
823 remember_type (work, oldmangled, *mangled - oldmangled);
825 string_append(&tname, (work -> options & DMGL_JAVA) ? "." : "::");
826 string_prepends(declp, &tname);
827 if (work -> destructor & 1)
829 string_prepend (&trawname, "~");
830 string_appends (declp, &trawname);
831 work->destructor -= 1;
833 if ((work->constructor & 1) || (work->destructor & 1))
835 string_appends (declp, &trawname);
836 work->constructor -= 1;
838 string_delete(&trawname);
839 string_delete(&tname);
845 if (GNU_DEMANGLING && expect_return_type)
847 /* Read the return type. */
849 string_init (&return_type);
852 success = do_type (work, mangled, &return_type);
853 APPEND_BLANK (&return_type);
855 string_prepends (declp, &return_type);
856 string_delete (&return_type);
860 /* At the outermost level, we cannot have a return type specified,
861 so if we run into another '_' at this point we are dealing with
862 a mangled name that is either bogus, or has been mangled by
863 some algorithm we don't know how to deal with. So just
864 reject the entire demangling. */
871 /* A G++ template function. Read the template arguments. */
872 success = demangle_template (work, mangled, declp, 0, 0);
873 if (!(work->constructor & 1))
874 expect_return_type = 1;
883 if (AUTO_DEMANGLING || GNU_DEMANGLING)
885 /* Assume we have stumbled onto the first outermost function
886 argument token, and start processing args. */
888 success = demangle_args (work, mangled, declp);
892 /* Non-GNU demanglers use a specific token to mark the start
893 of the outermost function argument tokens. Typically 'F',
894 for ARM-demangling, for example. So if we find something
895 we are not prepared for, it must be an error. */
901 if (AUTO_DEMANGLING || GNU_DEMANGLING)
904 if (success && expect_func)
907 success = demangle_args (work, mangled, declp);
908 /* Since template include the mangling of their return types,
909 we must set expect_func to 0 so that we don't try do
910 demangle more arguments the next time we get here. */
915 if (success && !func_done)
917 if (AUTO_DEMANGLING || GNU_DEMANGLING)
919 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
920 bar__3fooi is 'foo::bar(int)'. We get here when we find the
921 first case, and need to ensure that the '(void)' gets added to
922 the current declp. Note that with ARM, the first case
923 represents the name of a static data member 'foo::bar',
924 which is in the current declp, so we leave it alone. */
925 success = demangle_args (work, mangled, declp);
928 if (success && work -> static_type && PRINT_ARG_TYPES)
930 string_append (declp, " static");
932 if (success && work -> const_type && PRINT_ARG_TYPES)
934 string_append (declp, " const");
942 demangle_method_args (work, mangled, declp)
943 struct work_stuff *work;
944 const char **mangled;
949 if (work -> static_type)
951 string_append (declp, *mangled + 1);
952 *mangled += strlen (*mangled);
957 success = demangle_args (work, mangled, declp);
965 demangle_template (work, mangled, tname, trawname, is_type)
966 struct work_stuff *work;
967 const char **mangled;
985 int is_java_array = 0;
992 /* get template name */
993 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
998 string_appendn (trawname, *mangled, r);
999 is_java_array = (work -> options & DMGL_JAVA)
1000 && strncmp (*mangled, "JArray1Z", 8) == 0;
1001 if (! is_java_array)
1003 string_appendn (tname, *mangled, r);
1008 string_append (tname, "<");
1009 /* get size of template parameter list */
1010 if (!get_count (mangled, &r))
1016 /* Create an array for saving the template argument values. */
1017 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1018 work->ntmpl_args = r;
1019 for (i = 0; i < r; i++)
1020 work->tmpl_argvec[i] = 0;
1022 for (i = 0; i < r; i++)
1026 string_append (tname, ", ");
1028 /* Z for type parameters */
1029 if (**mangled == 'Z')
1032 /* temp is initialized in do_type */
1033 success = do_type (work, mangled, &temp);
1036 string_appends (tname, &temp);
1040 /* Save the template argument. */
1041 int len = temp.p - temp.b;
1042 work->tmpl_argvec[i] = xmalloc (len + 1);
1043 memcpy (work->tmpl_argvec[i], temp.b, len);
1044 work->tmpl_argvec[i][len] = '\0';
1047 string_delete(&temp);
1058 /* otherwise, value parameter */
1066 /* temp is initialized in do_type */
1067 success = do_type (work, mangled, &temp);
1071 string_appends (s, &temp);
1074 string_delete(&temp);
1080 string_append (s, "=");
1091 while (*old_p && !done)
1098 done = is_pointer = 1;
1100 case 'C': /* const */
1101 case 'S': /* explicitly signed [char] */
1102 case 'U': /* unsigned */
1103 case 'V': /* volatile */
1104 case 'F': /* function */
1105 case 'M': /* member function */
1107 case 'J': /* complex */
1110 case 'Q': /* qualified name */
1111 done = is_integral = 1;
1113 case 'T': /* remembered type */
1116 case 'v': /* void */
1119 case 'x': /* long long */
1120 case 'l': /* long */
1122 case 's': /* short */
1123 case 'w': /* wchar_t */
1124 done = is_integral = 1;
1126 case 'b': /* bool */
1129 case 'c': /* char */
1132 case 'r': /* long double */
1133 case 'd': /* double */
1134 case 'f': /* float */
1138 /* it's probably user defined type, let's assume
1139 it's integral, it seems hard to figure out
1140 what it really is */
1141 done = is_integral = 1;
1144 if (**mangled == 'Y')
1146 /* The next argument is a template parameter. */
1150 idx = consume_count_with_underscores (mangled);
1152 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1153 || consume_count_with_underscores (mangled) == -1)
1160 if (work->tmpl_argvec)
1161 string_append (s, work->tmpl_argvec[idx]);
1165 sprintf(buf, "T%d", idx);
1166 string_append (s, buf);
1169 else if (is_integral)
1171 if (**mangled == 'm')
1173 string_appendn (s, "-", 1);
1176 while (isdigit (**mangled))
1178 string_appendn (s, *mangled, 1);
1186 if (**mangled == 'm')
1188 string_appendn (s, "-", 1);
1191 string_appendn (s, "'", 1);
1192 val = consume_count(mangled);
1202 string_appendn (s, &tmp[0], 1);
1203 string_appendn (s, "'", 1);
1207 int val = consume_count (mangled);
1209 string_appendn (s, "false", 5);
1211 string_appendn (s, "true", 4);
1217 if (**mangled == 'm')
1219 string_appendn (s, "-", 1);
1222 while (isdigit (**mangled))
1224 string_appendn (s, *mangled, 1);
1227 if (**mangled == '.') /* fraction */
1229 string_appendn (s, ".", 1);
1231 while (isdigit (**mangled))
1233 string_appendn (s, *mangled, 1);
1237 if (**mangled == 'e') /* exponent */
1239 string_appendn (s, "e", 1);
1241 while (isdigit (**mangled))
1243 string_appendn (s, *mangled, 1);
1248 else if (is_pointer)
1250 symbol_len = consume_count (mangled);
1251 if (symbol_len == 0)
1258 if (symbol_len == 0)
1259 string_appendn (s, "0", 1);
1262 char *p = xmalloc (symbol_len + 1), *q;
1263 strncpy (p, *mangled, symbol_len);
1264 p [symbol_len] = '\0';
1265 q = cplus_demangle (p, work->options);
1266 string_appendn (s, "&", 1);
1269 string_append (s, q);
1273 string_append (s, p);
1276 *mangled += symbol_len;
1280 int len = s->p - s->b;
1281 work->tmpl_argvec[i] = xmalloc (len + 1);
1282 memcpy (work->tmpl_argvec[i], s->b, len);
1283 work->tmpl_argvec[i][len] = '\0';
1285 string_appends (tname, s);
1293 string_append (tname, "[]");
1297 if (tname->p[-1] == '>')
1298 string_append (tname, " ");
1299 string_append (tname, ">");
1303 if (work -> static_type)
1305 string_append (declp, *mangled + 1);
1306 *mangled += strlen (*mangled);
1311 success = demangle_args (work, mangled, declp);
1319 arm_pt (work, mangled, n, anchor, args)
1320 struct work_stuff *work;
1321 const char *mangled;
1323 const char **anchor, **args;
1326 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1329 *args = *anchor + 6;
1330 len = consume_count (args);
1331 if (*args + len == mangled + n && **args == '_')
1341 demangle_arm_pt (work, mangled, n, declp)
1342 struct work_stuff *work;
1343 const char **mangled;
1349 const char *e = *mangled + n;
1352 if (arm_pt (work, *mangled, n, &p, &args))
1356 string_appendn (declp, *mangled, p - *mangled);
1357 string_append (declp, "<");
1358 /* should do error checking here */
1360 string_clear (&arg);
1361 do_type (work, &args, &arg);
1362 string_appends (declp, &arg);
1363 string_append (declp, ",");
1365 string_delete (&arg);
1367 string_append (declp, ">");
1371 string_appendn (declp, *mangled, n);
1377 demangle_class_name (work, mangled, declp)
1378 struct work_stuff *work;
1379 const char **mangled;
1385 n = consume_count (mangled);
1386 if (strlen (*mangled) >= n)
1388 demangle_arm_pt (work, mangled, n, declp);
1399 demangle_class -- demangle a mangled class sequence
1404 demangle_class (struct work_stuff *work, const char **mangled,
1409 DECLP points to the buffer into which demangling is being done.
1411 *MANGLED points to the current token to be demangled. On input,
1412 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1413 On exit, it points to the next token after the mangled class on
1414 success, or the first unconsumed token on failure.
1416 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1417 we are demangling a constructor or destructor. In this case
1418 we prepend "class::class" or "class::~class" to DECLP.
1420 Otherwise, we prepend "class::" to the current DECLP.
1422 Reset the constructor/destructor flags once they have been
1423 "consumed". This allows demangle_class to be called later during
1424 the same demangling, to do normal class demangling.
1426 Returns 1 if demangling is successful, 0 otherwise.
1431 demangle_class (work, mangled, declp)
1432 struct work_stuff *work;
1433 const char **mangled;
1439 string_init (&class_name);
1440 if (demangle_class_name (work, mangled, &class_name))
1442 if ((work->constructor & 1) || (work->destructor & 1))
1444 string_prepends (declp, &class_name);
1445 if (work -> destructor & 1)
1447 string_prepend (declp, "~");
1448 work -> destructor -= 1;
1452 work -> constructor -= 1;
1455 string_prepend (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1456 string_prepends (declp, &class_name);
1459 string_delete (&class_name);
1467 demangle_prefix -- consume the mangled name prefix and find signature
1472 demangle_prefix (struct work_stuff *work, const char **mangled,
1477 Consume and demangle the prefix of the mangled name.
1479 DECLP points to the string buffer into which demangled output is
1480 placed. On entry, the buffer is empty. On exit it contains
1481 the root function name, the demangled operator name, or in some
1482 special cases either nothing or the completely demangled result.
1484 MANGLED points to the current pointer into the mangled name. As each
1485 token of the mangled name is consumed, it is updated. Upon entry
1486 the current mangled name pointer points to the first character of
1487 the mangled name. Upon exit, it should point to the first character
1488 of the signature if demangling was successful, or to the first
1489 unconsumed character if demangling of the prefix was unsuccessful.
1491 Returns 1 on success, 0 otherwise.
1495 demangle_prefix (work, mangled, declp)
1496 struct work_stuff *work;
1497 const char **mangled;
1504 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1506 char *marker = strchr (cplus_markers, (*mangled)[8]);
1507 if (marker != NULL && *marker == (*mangled)[10])
1509 if ((*mangled)[9] == 'D')
1511 /* it's a GNU global destructor to be executed at program exit */
1513 work->destructor = 2;
1514 if (gnu_special (work, mangled, declp))
1517 else if ((*mangled)[9] == 'I')
1519 /* it's a GNU global constructor to be executed at program init */
1521 work->constructor = 2;
1522 if (gnu_special (work, mangled, declp))
1527 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1529 /* it's a ARM global destructor to be executed at program exit */
1531 work->destructor = 2;
1533 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1535 /* it's a ARM global constructor to be executed at program initial */
1537 work->constructor = 2;
1540 /* This block of code is a reduction in strength time optimization
1542 scan = mystrstr (*mangled, "__"); */
1548 scan = strchr (scan, '_');
1549 } while (scan != NULL && *++scan != '_');
1551 if (scan != NULL) --scan;
1556 /* We found a sequence of two or more '_', ensure that we start at
1557 the last pair in the sequence. */
1558 i = strspn (scan, "_");
1569 else if (work -> static_type)
1571 if (!isdigit (scan[0]) && (scan[0] != 't'))
1576 else if ((scan == *mangled)
1577 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
1578 || (scan[2] == 'H')))
1580 /* The ARM says nothing about the mangling of local variables.
1581 But cfront mangles local variables by prepending __<nesting_level>
1582 to them. As an extension to ARM demangling we handle this case. */
1583 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1585 *mangled = scan + 2;
1586 consume_count (mangled);
1587 string_append (declp, *mangled);
1588 *mangled += strlen (*mangled);
1593 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1594 names like __Q2_3foo3bar for nested type names. So don't accept
1595 this style of constructor for cfront demangling. A GNU
1596 style member-template constructor starts with 'H'. */
1597 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1598 work -> constructor += 1;
1599 *mangled = scan + 2;
1602 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1604 /* Mangled name starts with "__". Skip over any leading '_' characters,
1605 then find the next "__" that separates the prefix from the signature.
1607 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1608 || (arm_special (work, mangled, declp) == 0))
1610 while (*scan == '_')
1614 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1616 /* No separator (I.E. "__not_mangled"), or empty signature
1617 (I.E. "__not_mangled_either__") */
1622 demangle_function_name (work, mangled, declp, scan);
1626 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1628 /* Cfront-style parameterized type. Handled later as a signature. */
1632 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1634 else if (*(scan + 2) != '\0')
1636 /* Mangled name does not start with "__" but does have one somewhere
1637 in there with non empty stuff after it. Looks like a global
1639 demangle_function_name (work, mangled, declp, scan);
1643 /* Doesn't look like a mangled name */
1647 if (!success && (work->constructor == 2 || work->destructor == 2))
1649 string_append (declp, *mangled);
1650 *mangled += strlen (*mangled);
1660 gnu_special -- special handling of gnu mangled strings
1665 gnu_special (struct work_stuff *work, const char **mangled,
1671 Process some special GNU style mangling forms that don't fit
1672 the normal pattern. For example:
1674 _$_3foo (destructor for class foo)
1675 _vt$foo (foo virtual table)
1676 _vt$foo$bar (foo::bar virtual table)
1677 __vt_foo (foo virtual table, new style with thunks)
1678 _3foo$varname (static data member)
1679 _Q22rs2tu$vw (static data member)
1680 __t6vector1Zii (constructor with template)
1681 __thunk_4__$_7ostream (virtual function thunk)
1685 gnu_special (work, mangled, declp)
1686 struct work_stuff *work;
1687 const char **mangled;
1694 if ((*mangled)[0] == '_'
1695 && strchr (cplus_markers, (*mangled)[1]) != NULL
1696 && (*mangled)[2] == '_')
1698 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1700 work -> destructor += 1;
1702 else if ((*mangled)[0] == '_'
1703 && (((*mangled)[1] == '_'
1704 && (*mangled)[2] == 'v'
1705 && (*mangled)[3] == 't'
1706 && (*mangled)[4] == '_')
1707 || ((*mangled)[1] == 'v'
1708 && (*mangled)[2] == 't'
1709 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1711 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1712 and create the decl. Note that we consume the entire mangled
1713 input string, which means that demangle_signature has no work
1715 if ((*mangled)[2] == 'v')
1716 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1718 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1719 while (**mangled != '\0')
1721 p = strpbrk (*mangled, cplus_markers);
1725 success = demangle_qualified (work, mangled, declp, 0, 1);
1728 success = demangle_template (work, mangled, declp, 0, 1);
1731 if (isdigit(*mangled[0]))
1733 n = consume_count(mangled);
1737 n = strcspn (*mangled, cplus_markers);
1739 string_appendn (declp, *mangled, n);
1743 if (success && ((p == NULL) || (p == *mangled)))
1747 string_append (declp,
1748 (work -> options & DMGL_JAVA) ? "." : "::");
1759 string_append (declp, " virtual table");
1761 else if ((*mangled)[0] == '_'
1762 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1763 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1765 /* static data member, "_3foo$varname" for example */
1770 success = demangle_qualified (work, mangled, declp, 0, 1);
1773 success = demangle_template (work, mangled, declp, 0, 1);
1776 n = consume_count (mangled);
1777 string_appendn (declp, *mangled, n);
1780 if (success && (p == *mangled))
1782 /* Consumed everything up to the cplus_marker, append the
1785 string_append (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1786 n = strlen (*mangled);
1787 string_appendn (declp, *mangled, n);
1795 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1797 int delta = ((*mangled) += 8, consume_count (mangled));
1798 char *method = cplus_demangle (++*mangled, work->options);
1802 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1803 string_append (declp, buf);
1804 string_append (declp, method);
1806 n = strlen (*mangled);
1814 else if (strncmp (*mangled, "__t", 3) == 0
1815 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
1817 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
1822 success = demangle_qualified (work, mangled, declp, 0, 1);
1825 success = demangle_template (work, mangled, declp, 0, 1);
1828 success = demangle_fund_type (work, mangled, declp);
1831 if (success && **mangled != '\0')
1834 string_append (declp, p);
1847 arm_special -- special handling of ARM/lucid mangled strings
1852 arm_special (struct work_stuff *work, const char **mangled,
1858 Process some special ARM style mangling forms that don't fit
1859 the normal pattern. For example:
1861 __vtbl__3foo (foo virtual table)
1862 __vtbl__3foo__3bar (bar::foo virtual table)
1867 arm_special (work, mangled, declp)
1868 struct work_stuff *work;
1869 const char **mangled;
1876 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1878 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1879 and create the decl. Note that we consume the entire mangled
1880 input string, which means that demangle_signature has no work
1882 scan = *mangled + ARM_VTABLE_STRLEN;
1883 while (*scan != '\0') /* first check it can be demangled */
1885 n = consume_count (&scan);
1888 return (0); /* no good */
1891 if (scan[0] == '_' && scan[1] == '_')
1896 (*mangled) += ARM_VTABLE_STRLEN;
1897 while (**mangled != '\0')
1899 n = consume_count (mangled);
1900 string_prependn (declp, *mangled, n);
1902 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1904 string_prepend (declp, "::");
1908 string_append (declp, " virtual table");
1921 demangle_qualified -- demangle 'Q' qualified name strings
1926 demangle_qualified (struct work_stuff *, const char *mangled,
1927 string *result, int isfuncname, int append);
1931 Demangle a qualified name, such as "Q25Outer5Inner" which is
1932 the mangled form of "Outer::Inner". The demangled output is
1933 prepended or appended to the result string according to the
1934 state of the append flag.
1936 If isfuncname is nonzero, then the qualified name we are building
1937 is going to be used as a member function name, so if it is a
1938 constructor or destructor function, append an appropriate
1939 constructor or destructor name. I.E. for the above example,
1940 the result for use as a constructor is "Outer::Inner::Inner"
1941 and the result for use as a destructor is "Outer::Inner::~Inner".
1945 Numeric conversion is ASCII dependent (FIXME).
1950 demangle_qualified (work, mangled, result, isfuncname, append)
1951 struct work_stuff *work;
1952 const char **mangled;
1964 string_init (&temp);
1965 switch ((*mangled)[1])
1968 /* GNU mangled name with more than 9 classes. The count is preceded
1969 by an underscore (to distinguish it from the <= 9 case) and followed
1970 by an underscore. */
1972 qualifiers = atoi (p);
1973 if (!isdigit (*p) || *p == '0')
1976 /* Skip the digits. */
1977 while (isdigit (*p))
1995 /* The count is in a single digit. */
1996 num[0] = (*mangled)[1];
1998 qualifiers = atoi (num);
2000 /* If there is an underscore after the digit, skip it. This is
2001 said to be for ARM-qualified names, but the ARM makes no
2002 mention of such an underscore. Perhaps cfront uses one. */
2003 if ((*mangled)[2] == '_')
2018 /* Pick off the names and collect them in the temp buffer in the order
2019 in which they are found, separated by '::'. */
2021 while (qualifiers-- > 0)
2023 if (*mangled[0] == '_')
2024 *mangled = *mangled + 1;
2025 if (*mangled[0] == 't')
2027 success = demangle_template(work, mangled, &temp, 0, 1);
2028 if (!success) break;
2030 else if (*mangled[0] == 'X')
2032 success = do_type (work, mangled, &temp);
2033 if (!success) break;
2037 namelength = consume_count (mangled);
2038 if (strlen (*mangled) < namelength)
2040 /* Simple sanity check failed */
2044 string_appendn (&temp, *mangled, namelength);
2045 *mangled += namelength;
2049 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2053 /* If we are using the result as a function name, we need to append
2054 the appropriate '::' separated constructor or destructor name.
2055 We do this here because this is the most convenient place, where
2056 we already have a pointer to the name and the length of the name. */
2058 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
2060 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2061 if (work -> destructor & 1)
2063 string_append (&temp, "~");
2065 string_appendn (&temp, (*mangled) - namelength, namelength);
2068 /* Now either prepend the temp buffer to the result, or append it,
2069 depending upon the state of the append flag. */
2073 string_appends (result, &temp);
2077 if (!STRING_EMPTY (result))
2079 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2081 string_prepends (result, &temp);
2084 string_delete (&temp);
2092 get_count -- convert an ascii count to integer, consuming tokens
2097 get_count (const char **type, int *count)
2101 Return 0 if no conversion is performed, 1 if a string is converted.
2105 get_count (type, count)
2112 if (!isdigit (**type))
2118 *count = **type - '0';
2120 if (isdigit (**type))
2130 while (isdigit (*p));
2141 /* result will be initialised here; it will be freed on failure */
2144 do_type (work, mangled, result)
2145 struct work_stuff *work;
2146 const char **mangled;
2153 const char *remembered_type;
2157 string_init (&decl);
2158 string_init (result);
2162 while (success && !done)
2168 /* A pointer type */
2172 if (! (work -> options & DMGL_JAVA))
2173 string_prepend (&decl, "*");
2176 /* A reference type */
2179 string_prepend (&decl, "&");
2185 const char *p = ++(*mangled);
2187 string_prepend (&decl, "(");
2188 string_append (&decl, ")[");
2189 /* Copy anything up until the next underscore (the size of the
2191 while (**mangled && **mangled != '_')
2193 if (**mangled == '_')
2195 string_appendn (&decl, p, *mangled - p);
2196 string_append (&decl, "]");
2204 /* A back reference to a previously seen type */
2207 if (!get_count (mangled, &n) || n >= work -> ntypes)
2213 remembered_type = work -> typevec[n];
2214 mangled = &remembered_type;
2221 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2223 string_prepend (&decl, "(");
2224 string_append (&decl, ")");
2226 /* After picking off the function args, we expect to either find the
2227 function return type (preceded by an '_') or the end of the
2229 if (!demangle_args (work, mangled, &decl)
2230 || (**mangled != '_' && **mangled != '\0'))
2234 if (success && (**mangled == '_'))
2246 member = **mangled == 'M';
2248 if (!isdigit (**mangled) && **mangled != 't')
2254 string_append (&decl, ")");
2255 string_prepend (&decl, (work -> options & DMGL_JAVA) ? "." : "::");
2256 if (isdigit (**mangled))
2258 n = consume_count (mangled);
2259 if (strlen (*mangled) < n)
2264 string_prependn (&decl, *mangled, n);
2270 string_init (&temp);
2271 success = demangle_template (work, mangled, &temp, NULL, 1);
2274 string_prependn (&decl, temp.b, temp.p - temp.b);
2275 string_clear (&temp);
2280 string_prepend (&decl, "(");
2283 if (**mangled == 'C')
2288 if (**mangled == 'V')
2293 if (*(*mangled)++ != 'F')
2299 if ((member && !demangle_args (work, mangled, &decl))
2300 || **mangled != '_')
2306 if (! PRINT_ANSI_QUALIFIERS)
2312 APPEND_BLANK (&decl);
2313 string_append (&decl, "const");
2317 APPEND_BLANK (&decl);
2318 string_append (&decl, "volatile");
2329 if ((*mangled)[1] == 'P')
2332 if (PRINT_ANSI_QUALIFIERS)
2334 if (!STRING_EMPTY (&decl))
2336 string_prepend (&decl, " ");
2338 string_prepend (&decl, "const");
2354 /* A qualified name, such as "Outer::Inner". */
2356 success = demangle_qualified (work, mangled, result, 0, 1);
2361 /* A template parm. We substitute the corresponding argument. */
2367 idx = consume_count_with_underscores (mangled);
2370 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2371 || consume_count_with_underscores (mangled) == -1)
2377 if (work->tmpl_argvec)
2378 string_append (result, work->tmpl_argvec[idx]);
2382 sprintf(buf, "T%d", idx);
2383 string_append (result, buf);
2392 /* A template parm. We substitute the corresponding argument. */
2398 idx = consume_count_with_underscores (mangled);
2401 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2402 || consume_count_with_underscores (mangled) == -1)
2408 if (work->tmpl_argvec)
2409 string_append (result, work->tmpl_argvec[idx]);
2413 sprintf(buf, "T%d", idx);
2414 string_append (result, buf);
2422 success = demangle_fund_type (work, mangled, result);
2428 if (!STRING_EMPTY (&decl))
2430 string_append (result, " ");
2431 string_appends (result, &decl);
2436 string_delete (result);
2438 string_delete (&decl);
2442 /* Given a pointer to a type string that represents a fundamental type
2443 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2444 string in which the demangled output is being built in RESULT, and
2445 the WORK structure, decode the types and add them to the result.
2450 "Sl" => "signed long"
2451 "CUs" => "const unsigned short"
2456 demangle_fund_type (work, mangled, result)
2457 struct work_stuff *work;
2458 const char **mangled;
2464 /* First pick off any type qualifiers. There can be more than one. */
2472 if (PRINT_ANSI_QUALIFIERS)
2474 APPEND_BLANK (result);
2475 string_append (result, "const");
2480 APPEND_BLANK (result);
2481 string_append (result, "unsigned");
2483 case 'S': /* signed char only */
2485 APPEND_BLANK (result);
2486 string_append (result, "signed");
2490 if (PRINT_ANSI_QUALIFIERS)
2492 APPEND_BLANK (result);
2493 string_append (result, "volatile");
2498 APPEND_BLANK (result);
2499 string_append (result, "__complex");
2507 /* Now pick off the fundamental type. There can be only one. */
2516 APPEND_BLANK (result);
2517 string_append (result, "void");
2521 APPEND_BLANK (result);
2522 string_append (result, "long long");
2526 APPEND_BLANK (result);
2527 string_append (result, "long");
2531 APPEND_BLANK (result);
2532 string_append (result, "int");
2536 APPEND_BLANK (result);
2537 string_append (result, "short");
2541 APPEND_BLANK (result);
2542 string_append (result, "bool");
2546 APPEND_BLANK (result);
2547 string_append (result, "char");
2551 APPEND_BLANK (result);
2552 string_append (result, "wchar_t");
2556 APPEND_BLANK (result);
2557 string_append (result, "long double");
2561 APPEND_BLANK (result);
2562 string_append (result, "double");
2566 APPEND_BLANK (result);
2567 string_append (result, "float");
2571 if (!isdigit (**mangled))
2577 /* An explicit type, such as "6mytype" or "7integer" */
2588 APPEND_BLANK (result);
2589 if (!demangle_class_name (work, mangled, result)) {
2595 success = demangle_template(work,mangled, result, 0, 1);
2605 /* `result' will be initialized in do_type; it will be freed on failure */
2608 do_arg (work, mangled, result)
2609 struct work_stuff *work;
2610 const char **mangled;
2613 const char *start = *mangled;
2615 if (!do_type (work, mangled, result))
2621 remember_type (work, start, *mangled - start);
2627 remember_type (work, start, len)
2628 struct work_stuff *work;
2634 if (work -> ntypes >= work -> typevec_size)
2636 if (work -> typevec_size == 0)
2638 work -> typevec_size = 3;
2640 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2644 work -> typevec_size *= 2;
2646 = (char **) xrealloc ((char *)work -> typevec,
2647 sizeof (char *) * work -> typevec_size);
2650 tem = xmalloc (len + 1);
2651 memcpy (tem, start, len);
2653 work -> typevec[work -> ntypes++] = tem;
2656 /* Forget the remembered types, but not the type vector itself. */
2660 struct work_stuff *work;
2664 while (work -> ntypes > 0)
2666 i = --(work -> ntypes);
2667 if (work -> typevec[i] != NULL)
2669 free (work -> typevec[i]);
2670 work -> typevec[i] = NULL;
2675 /* Process the argument list part of the signature, after any class spec
2676 has been consumed, as well as the first 'F' character (if any). For
2679 "__als__3fooRT0" => process "RT0"
2680 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2682 DECLP must be already initialised, usually non-empty. It won't be freed
2685 Note that g++ differs significantly from ARM and lucid style mangling
2686 with regards to references to previously seen types. For example, given
2687 the source fragment:
2691 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2694 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2695 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2697 g++ produces the names:
2702 while lcc (and presumably other ARM style compilers as well) produces:
2704 foo__FiR3fooT1T2T1T2
2705 __ct__3fooFiR3fooT1T2T1T2
2707 Note that g++ bases it's type numbers starting at zero and counts all
2708 previously seen types, while lucid/ARM bases it's type numbers starting
2709 at one and only considers types after it has seen the 'F' character
2710 indicating the start of the function args. For lucid/ARM style, we
2711 account for this difference by discarding any previously seen types when
2712 we see the 'F' character, and subtracting one from the type number
2718 demangle_args (work, mangled, declp)
2719 struct work_stuff *work;
2720 const char **mangled;
2730 if (PRINT_ARG_TYPES)
2732 string_append (declp, "(");
2733 if (**mangled == '\0')
2735 string_append (declp, "void");
2739 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2741 if ((**mangled == 'N') || (**mangled == 'T'))
2743 temptype = *(*mangled)++;
2745 if (temptype == 'N')
2747 if (!get_count (mangled, &r))
2756 if (ARM_DEMANGLING && work -> ntypes >= 10)
2758 /* If we have 10 or more types we might have more than a 1 digit
2759 index so we'll have to consume the whole count here. This
2760 will lose if the next thing is a type name preceded by a
2761 count but it's impossible to demangle that case properly
2762 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2763 Pc, ...)" or "(..., type12, char *, ...)" */
2764 if ((t = consume_count(mangled)) == 0)
2771 if (!get_count (mangled, &t))
2776 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2780 /* Validate the type index. Protect against illegal indices from
2781 malformed type strings. */
2782 if ((t < 0) || (t >= work -> ntypes))
2788 tem = work -> typevec[t];
2789 if (need_comma && PRINT_ARG_TYPES)
2791 string_append (declp, ", ");
2793 if (!do_arg (work, &tem, &arg))
2797 if (PRINT_ARG_TYPES)
2799 string_appends (declp, &arg);
2801 string_delete (&arg);
2807 if (need_comma & PRINT_ARG_TYPES)
2809 string_append (declp, ", ");
2811 if (!do_arg (work, mangled, &arg))
2815 if (PRINT_ARG_TYPES)
2817 string_appends (declp, &arg);
2819 string_delete (&arg);
2824 if (**mangled == 'e')
2827 if (PRINT_ARG_TYPES)
2831 string_append (declp, ",");
2833 string_append (declp, "...");
2837 if (PRINT_ARG_TYPES)
2839 string_append (declp, ")");
2845 demangle_function_name (work, mangled, declp, scan)
2846 struct work_stuff *work;
2847 const char **mangled;
2856 string_appendn (declp, (*mangled), scan - (*mangled));
2857 string_need (declp, 1);
2858 *(declp -> p) = '\0';
2860 /* Consume the function name, including the "__" separating the name
2861 from the signature. We are guaranteed that SCAN points to the
2864 (*mangled) = scan + 2;
2866 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2869 /* See if we have an ARM style constructor or destructor operator.
2870 If so, then just record it, clear the decl, and return.
2871 We can't build the actual constructor/destructor decl until later,
2872 when we recover the class name from the signature. */
2874 if (strcmp (declp -> b, "__ct") == 0)
2876 work -> constructor += 1;
2877 string_clear (declp);
2880 else if (strcmp (declp -> b, "__dt") == 0)
2882 work -> destructor += 1;
2883 string_clear (declp);
2888 if (declp->p - declp->b >= 3
2889 && declp->b[0] == 'o'
2890 && declp->b[1] == 'p'
2891 && strchr (cplus_markers, declp->b[2]) != NULL)
2893 /* see if it's an assignment expression */
2894 if (declp->p - declp->b >= 10 /* op$assign_ */
2895 && memcmp (declp->b + 3, "assign_", 7) == 0)
2897 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2899 len = declp->p - declp->b - 10;
2900 if (strlen (optable[i].in) == len
2901 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2903 string_clear (declp);
2904 string_append (declp, "operator");
2905 string_append (declp, optable[i].out);
2906 string_append (declp, "=");
2913 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2915 int len = declp->p - declp->b - 3;
2916 if (strlen (optable[i].in) == len
2917 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2919 string_clear (declp);
2920 string_append (declp, "operator");
2921 string_append (declp, optable[i].out);
2927 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2928 && strchr (cplus_markers, declp->b[4]) != NULL)
2930 /* type conversion operator */
2932 if (do_type (work, &tem, &type))
2934 string_clear (declp);
2935 string_append (declp, "operator ");
2936 string_appends (declp, &type);
2937 string_delete (&type);
2940 else if (declp->b[0] == '_' && declp->b[1] == '_'
2941 && declp->b[2] == 'o' && declp->b[3] == 'p')
2944 /* type conversion operator. */
2946 if (do_type (work, &tem, &type))
2948 string_clear (declp);
2949 string_append (declp, "operator ");
2950 string_appends (declp, &type);
2951 string_delete (&type);
2954 else if (declp->b[0] == '_' && declp->b[1] == '_'
2955 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2956 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2958 if (declp->b[4] == '\0')
2961 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2963 if (strlen (optable[i].in) == 2
2964 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2966 string_clear (declp);
2967 string_append (declp, "operator");
2968 string_append (declp, optable[i].out);
2975 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2978 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2980 if (strlen (optable[i].in) == 3
2981 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2983 string_clear (declp);
2984 string_append (declp, "operator");
2985 string_append (declp, optable[i].out);
2994 /* a mini string-handling package */
3009 s->p = s->b = xmalloc (n);
3012 else if (s->e - s->p < n)
3017 s->b = xrealloc (s->b, n);
3030 s->b = s->e = s->p = NULL;
3038 s->b = s->p = s->e = NULL;
3054 return (s->b == s->p);
3060 string_append (p, s)
3065 if (s == NULL || *s == '\0')
3069 memcpy (p->p, s, n);
3074 string_appends (p, s)
3083 memcpy (p->p, s->b, n);
3089 string_appendn (p, s, n)
3097 memcpy (p->p, s, n);
3103 string_prepend (p, s)
3107 if (s != NULL && *s != '\0')
3109 string_prependn (p, s, strlen (s));
3114 string_prepends (p, s)
3119 string_prependn (p, s->b, s->p - s->b);
3124 string_prependn (p, s, n)
3134 for (q = p->p - 1; q >= p->b; q--)
3138 memcpy (p->b, s, n);
3143 /* To generate a standalone demangler program for testing purposes,
3144 just compile and link this file with -DMAIN and libiberty.a. When
3145 run, it demangles each command line arg, or each stdin string, and
3146 prints the result on stdout. */
3152 static char *program_name;
3153 static char *program_version = VERSION;
3154 static int flags = DMGL_PARAMS | DMGL_ANSI;
3156 static void demangle_it PARAMS ((char *));
3157 static void usage PARAMS ((FILE *, int));
3158 static void fatal PARAMS ((char *));
3161 demangle_it (mangled_name)
3166 result = cplus_demangle (mangled_name, flags);
3169 printf ("%s\n", mangled_name);
3173 printf ("%s\n", result);
3179 usage (stream, status)
3184 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3185 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3186 [--help] [--version] [arg...]\n",
3191 #define MBUF_SIZE 512
3192 char mbuffer[MBUF_SIZE];
3194 /* Defined in the automatically-generated underscore.c. */
3195 extern int prepends_underscore;
3197 int strip_underscore = 0;
3199 static struct option long_options[] = {
3200 {"strip-underscores", no_argument, 0, '_'},
3201 {"format", required_argument, 0, 's'},
3202 {"help", no_argument, 0, 'h'},
3203 {"java", no_argument, 0, 'j'},
3204 {"no-strip-underscores", no_argument, 0, 'n'},
3205 {"version", no_argument, 0, 'v'},
3206 {0, no_argument, 0, 0}
3217 program_name = argv[0];
3219 strip_underscore = prepends_underscore;
3221 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3231 strip_underscore = 0;
3234 printf ("GNU %s version %s\n", program_name, program_version);
3237 strip_underscore = 1;
3243 if (strcmp (optarg, "gnu") == 0)
3245 current_demangling_style = gnu_demangling;
3247 else if (strcmp (optarg, "lucid") == 0)
3249 current_demangling_style = lucid_demangling;
3251 else if (strcmp (optarg, "arm") == 0)
3253 current_demangling_style = arm_demangling;
3257 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3258 program_name, optarg);
3267 for ( ; optind < argc; optind++)
3269 demangle_it (argv[optind]);
3278 /* Try to read a label. */
3279 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3281 if (i >= MBUF_SIZE-1)
3290 if (mbuffer[0] == '.')
3292 if (strip_underscore && mbuffer[skip_first] == '_')
3300 result = cplus_demangle (mbuffer + skip_first, flags);
3303 if (mbuffer[0] == '.')
3305 fputs (result, stdout);
3309 fputs (mbuffer, stdout);
3326 fprintf (stderr, "%s: %s\n", program_name, str);
3337 register char *value = (char *) malloc (size);
3339 fatal ("virtual memory exhausted");
3344 xrealloc (ptr, size)
3348 register char *value = (char *) realloc (ptr, size);
3350 fatal ("virtual memory exhausted");