1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 This file is part of the libiberty library.
7 Libiberty is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 Libiberty is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with libiberty; see the file COPYING.LIB. If
19 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
24 This file imports xmalloc and xrealloc, which are like malloc and
25 realloc except that they generate a fatal error if there is no
28 /* This file lives in both GCC and libiberty. When making changes, please
29 try not to break either. */
32 #include <sys/types.h>
41 #undef CURRENT_DEMANGLING_STYLE
42 #define CURRENT_DEMANGLING_STYLE work->options
44 extern char *xmalloc PARAMS((unsigned));
45 extern char *xrealloc PARAMS((char *, unsigned));
47 static const char *mystrstr PARAMS ((const char *, const char *));
53 register const char *p = s1;
54 register int len = strlen (s2);
56 for (; (p = strchr (p, *s2)) != 0; p++)
58 if (strncmp (p, s2, len) == 0)
66 /* In order to allow a single demangler executable to demangle strings
67 using various common values of CPLUS_MARKER, as well as any specific
68 one set at compile time, we maintain a string containing all the
69 commonly used ones, and check to see if the marker we are looking for
70 is in that string. CPLUS_MARKER is usually '$' on systems where the
71 assembler can deal with that. Where the assembler can't, it's usually
72 '.' (but on many systems '.' is used for other things). We put the
73 current defined CPLUS_MARKER first (which defaults to '$'), followed
74 by the next most common value, followed by an explicit '$' in case
75 the value of CPLUS_MARKER is not '$'.
77 We could avoid this if we could just get g++ to tell us what the actual
78 cplus marker character is as part of the debug information, perhaps by
79 ensuring that it is the character that terminates the gcc<n>_compiled
80 marker symbol (FIXME). */
82 #if !defined (CPLUS_MARKER)
83 #define CPLUS_MARKER '$'
86 enum demangling_styles current_demangling_style = gnu_demangling;
88 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
91 set_cplus_marker_for_demangling (ch)
94 cplus_markers[0] = ch;
97 /* Stuff that is shared between sub-routines.
98 Using a shared structure allows cplus_demangle to be reentrant. */
114 int static_type; /* A static member function */
115 int const_type; /* A const member function */
116 char **tmpl_argvec; /* Template function arguments. */
117 int ntmpl_args; /* The number of template function arguments. */
120 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
121 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
123 static const struct optable
129 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
130 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
131 {"new", " new", 0}, /* old (1.91, and 1.x) */
132 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
133 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
134 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
135 {"as", "=", DMGL_ANSI}, /* ansi */
136 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
137 {"eq", "==", DMGL_ANSI}, /* old, ansi */
138 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
139 {"gt", ">", DMGL_ANSI}, /* old, ansi */
140 {"le", "<=", DMGL_ANSI}, /* old, ansi */
141 {"lt", "<", DMGL_ANSI}, /* old, ansi */
142 {"plus", "+", 0}, /* old */
143 {"pl", "+", DMGL_ANSI}, /* ansi */
144 {"apl", "+=", DMGL_ANSI}, /* ansi */
145 {"minus", "-", 0}, /* old */
146 {"mi", "-", DMGL_ANSI}, /* ansi */
147 {"ami", "-=", DMGL_ANSI}, /* ansi */
148 {"mult", "*", 0}, /* old */
149 {"ml", "*", DMGL_ANSI}, /* ansi */
150 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
151 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
152 {"convert", "+", 0}, /* old (unary +) */
153 {"negate", "-", 0}, /* old (unary -) */
154 {"trunc_mod", "%", 0}, /* old */
155 {"md", "%", DMGL_ANSI}, /* ansi */
156 {"amd", "%=", DMGL_ANSI}, /* ansi */
157 {"trunc_div", "/", 0}, /* old */
158 {"dv", "/", DMGL_ANSI}, /* ansi */
159 {"adv", "/=", DMGL_ANSI}, /* ansi */
160 {"truth_andif", "&&", 0}, /* old */
161 {"aa", "&&", DMGL_ANSI}, /* ansi */
162 {"truth_orif", "||", 0}, /* old */
163 {"oo", "||", DMGL_ANSI}, /* ansi */
164 {"truth_not", "!", 0}, /* old */
165 {"nt", "!", DMGL_ANSI}, /* ansi */
166 {"postincrement","++", 0}, /* old */
167 {"pp", "++", DMGL_ANSI}, /* ansi */
168 {"postdecrement","--", 0}, /* old */
169 {"mm", "--", DMGL_ANSI}, /* ansi */
170 {"bit_ior", "|", 0}, /* old */
171 {"or", "|", DMGL_ANSI}, /* ansi */
172 {"aor", "|=", DMGL_ANSI}, /* ansi */
173 {"bit_xor", "^", 0}, /* old */
174 {"er", "^", DMGL_ANSI}, /* ansi */
175 {"aer", "^=", DMGL_ANSI}, /* ansi */
176 {"bit_and", "&", 0}, /* old */
177 {"ad", "&", DMGL_ANSI}, /* ansi */
178 {"aad", "&=", DMGL_ANSI}, /* ansi */
179 {"bit_not", "~", 0}, /* old */
180 {"co", "~", DMGL_ANSI}, /* ansi */
181 {"call", "()", 0}, /* old */
182 {"cl", "()", DMGL_ANSI}, /* ansi */
183 {"alshift", "<<", 0}, /* old */
184 {"ls", "<<", DMGL_ANSI}, /* ansi */
185 {"als", "<<=", DMGL_ANSI}, /* ansi */
186 {"arshift", ">>", 0}, /* old */
187 {"rs", ">>", DMGL_ANSI}, /* ansi */
188 {"ars", ">>=", DMGL_ANSI}, /* ansi */
189 {"component", "->", 0}, /* old */
190 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
191 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
192 {"indirect", "*", 0}, /* old */
193 {"method_call", "->()", 0}, /* old */
194 {"addr", "&", 0}, /* old (unary &) */
195 {"array", "[]", 0}, /* old */
196 {"vc", "[]", DMGL_ANSI}, /* ansi */
197 {"compound", ", ", 0}, /* old */
198 {"cm", ", ", DMGL_ANSI}, /* ansi */
199 {"cond", "?:", 0}, /* old */
200 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
201 {"max", ">?", 0}, /* old */
202 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
203 {"min", "<?", 0}, /* old */
204 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
205 {"nop", "", 0}, /* old (for operator=) */
206 {"rm", "->*", DMGL_ANSI}, /* ansi */
207 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
211 typedef struct string /* Beware: these aren't required to be */
212 { /* '\0' terminated. */
213 char *b; /* pointer to start of string */
214 char *p; /* pointer after last character */
215 char *e; /* pointer after end of allocated space */
218 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
219 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
220 string_prepend(str, " ");}
221 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
222 string_append(str, " ");}
223 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
225 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
226 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
228 /* Prototypes for local functions */
231 mop_up PARAMS ((struct work_stuff *, string *, int));
234 squangle_mop_up PARAMS ((struct work_stuff *));
238 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
242 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
245 demangle_template_template_parm PARAMS ((struct work_stuff *work,
246 const char **, string *));
249 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
253 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
257 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
260 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
263 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
267 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
270 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
273 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
276 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
279 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
282 arm_special PARAMS ((const char **, string *));
285 string_need PARAMS ((string *, int));
288 string_delete PARAMS ((string *));
291 string_init PARAMS ((string *));
294 string_clear PARAMS ((string *));
298 string_empty PARAMS ((string *));
302 string_append PARAMS ((string *, const char *));
305 string_appends PARAMS ((string *, string *));
308 string_appendn PARAMS ((string *, const char *, int));
311 string_prepend PARAMS ((string *, const char *));
314 string_prependn PARAMS ((string *, const char *, int));
317 get_count PARAMS ((const char **, int *));
320 consume_count PARAMS ((const char **));
323 consume_count_with_underscores PARAMS ((const char**));
326 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
329 do_type PARAMS ((struct work_stuff *, const char **, string *));
332 do_arg PARAMS ((struct work_stuff *, const char **, string *));
335 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
339 remember_type PARAMS ((struct work_stuff *, const char *, int));
342 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
345 register_Btype PARAMS ((struct work_stuff *));
348 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
351 forget_types PARAMS ((struct work_stuff *));
354 forget_B_and_K_types PARAMS ((struct work_stuff *));
357 string_prepends PARAMS ((string *, string *));
360 demangle_template_value_parm PARAMS ((struct work_stuff*,
361 const char**, string*));
363 /* Translate count to integer, consuming tokens in the process.
364 Conversion terminates on the first non-digit character.
365 Trying to consume something that isn't a count results in
366 no consumption of input and a return of 0. */
374 while (isdigit (**type))
377 count += **type - '0';
384 /* Like consume_count, but for counts that are preceded 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)
427 struct work_stuff work[1];
430 len = strlen(opname);
433 memset ((char *) work, 0, sizeof (work));
434 work->options = options;
436 if (opname[0] == '_' && opname[1] == '_'
437 && opname[2] == 'o' && opname[3] == 'p')
440 /* type conversion operator. */
442 if (do_type (work, &tem, &type))
444 strcat (result, "operator ");
445 strncat (result, type.b, type.p - type.b);
446 string_delete (&type);
450 else if (opname[0] == '_' && opname[1] == '_'
451 && opname[2] >= 'a' && opname[2] <= 'z'
452 && opname[3] >= 'a' && opname[3] <= 'z')
454 if (opname[4] == '\0')
458 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
460 if (strlen (optable[i].in) == 2
461 && memcmp (optable[i].in, opname + 2, 2) == 0)
463 strcat (result, "operator");
464 strcat (result, optable[i].out);
472 if (opname[2] == 'a' && opname[5] == '\0')
476 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
478 if (strlen (optable[i].in) == 3
479 && memcmp (optable[i].in, opname + 2, 3) == 0)
481 strcat (result, "operator");
482 strcat (result, optable[i].out);
493 && strchr (cplus_markers, opname[2]) != NULL)
495 /* see if it's an assignment expression */
496 if (len >= 10 /* op$assign_ */
497 && memcmp (opname + 3, "assign_", 7) == 0)
500 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
503 if (strlen (optable[i].in) == len1
504 && memcmp (optable[i].in, opname + 10, len1) == 0)
506 strcat (result, "operator");
507 strcat (result, optable[i].out);
508 strcat (result, "=");
517 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
520 if (strlen (optable[i].in) == len1
521 && memcmp (optable[i].in, opname + 3, len1) == 0)
523 strcat (result, "operator");
524 strcat (result, optable[i].out);
531 else if (len >= 5 && memcmp (opname, "type", 4) == 0
532 && strchr (cplus_markers, opname[4]) != NULL)
534 /* type conversion operator */
536 if (do_type (work, &tem, &type))
538 strcat (result, "operator ");
539 strncat (result, type.b, type.p - type.b);
540 string_delete (&type);
544 squangle_mop_up (work);
548 /* Takes operator name as e.g. "++" and returns mangled
549 operator name (e.g. "postincrement_expr"), or NULL if not found.
551 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
552 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
555 cplus_mangle_opname (opname, options)
562 len = strlen (opname);
563 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
565 if (strlen (optable[i].out) == len
566 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
567 && memcmp (optable[i].out, opname, len) == 0)
568 return optable[i].in;
573 /* char *cplus_demangle (const char *mangled, int options)
575 If MANGLED is a mangled function name produced by GNU C++, then
576 a pointer to a malloced string giving a C++ representation
577 of the name will be returned; otherwise NULL will be returned.
578 It is the caller's responsibility to free the string which
581 The OPTIONS arg may contain one or more of the following bits:
583 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
585 DMGL_PARAMS Function parameters are included.
589 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
590 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
591 cplus_demangle ("foo__1Ai", 0) => "A::foo"
593 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
594 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
595 cplus_demangle ("foo__1Afe", 0) => "A::foo"
597 Note that any leading underscores, or other such characters prepended by
598 the compilation system, are presumed to have already been stripped from
602 cplus_demangle (mangled, options)
607 struct work_stuff work[1];
608 memset ((char *) work, 0, sizeof (work));
609 work -> options = options;
610 if ((work -> options & DMGL_STYLE_MASK) == 0)
611 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
613 ret = internal_cplus_demangle (work, mangled);
614 squangle_mop_up (work);
619 /* This function performs most of what cplus_demangle use to do, but
620 to be able to demangle a name with a B, K or n code, we need to
621 have a longer term memory of what types have been seen. The original
622 now intializes and cleans up the squangle code info, while internal
623 calls go directly to this routine to avoid resetting that info. */
626 internal_cplus_demangle (work, mangled)
627 struct work_stuff *work;
633 char *demangled = NULL;
635 s1 = work->constructor;
636 s2 = work->destructor;
637 s3 = work->static_type;
638 s4 = work->const_type;
639 work->constructor = work->destructor = 0;
640 work->static_type = work->const_type = 0;
642 if ((mangled != NULL) && (*mangled != '\0'))
646 /* First check to see if gnu style demangling is active and if the
647 string to be demangled contains a CPLUS_MARKER. If so, attempt to
648 recognize one of the gnu special forms rather than looking for a
649 standard prefix. In particular, don't worry about whether there
650 is a "__" string in the mangled string. Consider "_$_5__foo" for
653 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
655 success = gnu_special (work, &mangled, &decl);
659 success = demangle_prefix (work, &mangled, &decl);
661 if (success && (*mangled != '\0'))
663 success = demangle_signature (work, &mangled, &decl);
665 if (work->constructor == 2)
667 string_prepend (&decl, "global constructors keyed to ");
668 work->constructor = 0;
670 else if (work->destructor == 2)
672 string_prepend (&decl, "global destructors keyed to ");
673 work->destructor = 0;
675 demangled = mop_up (work, &decl, success);
677 work->constructor = s1;
678 work->destructor = s2;
679 work->static_type = s3;
680 work->const_type = s4;
685 /* Clear out and squangling related storage */
687 squangle_mop_up (work)
688 struct work_stuff *work;
690 /* clean up the B and K type mangling types. */
691 forget_B_and_K_types (work);
692 if (work -> btypevec != NULL)
694 free ((char *) work -> btypevec);
696 if (work -> ktypevec != NULL)
698 free ((char *) work -> ktypevec);
702 /* Clear out any mangled storage */
705 mop_up (work, declp, success)
706 struct work_stuff *work;
710 char *demangled = NULL;
712 /* Discard the remembered types, if any. */
715 if (work -> typevec != NULL)
717 free ((char *) work -> typevec);
718 work -> typevec = NULL;
720 if (work->tmpl_argvec)
724 for (i = 0; i < work->ntmpl_args; i++)
725 if (work->tmpl_argvec[i])
726 free ((char*) work->tmpl_argvec[i]);
728 free ((char*) work->tmpl_argvec);
729 work->tmpl_argvec = NULL;
732 /* If demangling was successful, ensure that the demangled string is null
733 terminated and return it. Otherwise, free the demangling decl. */
737 string_delete (declp);
741 string_appendn (declp, "", 1);
742 demangled = declp -> b;
751 demangle_signature -- demangle the signature part of a mangled name
756 demangle_signature (struct work_stuff *work, const char **mangled,
761 Consume and demangle the signature portion of the mangled name.
763 DECLP is the string where demangled output is being built. At
764 entry it contains the demangled root name from the mangled name
765 prefix. I.E. either a demangled operator name or the root function
766 name. In some special cases, it may contain nothing.
768 *MANGLED points to the current unconsumed location in the mangled
769 name. As tokens are consumed and demangling is performed, the
770 pointer is updated to continuously point at the next token to
773 Demangling GNU style mangled names is nasty because there is no
774 explicit token that marks the start of the outermost function
778 demangle_signature (work, mangled, declp)
779 struct work_stuff *work;
780 const char **mangled;
786 int expect_return_type = 0;
787 const char *oldmangled = NULL;
791 while (success && (**mangled != '\0'))
796 oldmangled = *mangled;
797 success = demangle_qualified (work, mangled, declp, 1, 0);
800 remember_type (work, oldmangled, *mangled - oldmangled);
802 if (AUTO_DEMANGLING || GNU_DEMANGLING)
810 oldmangled = *mangled;
811 success = demangle_qualified (work, mangled, declp, 1, 0);
812 if (AUTO_DEMANGLING || GNU_DEMANGLING)
820 /* Static member function */
821 if (oldmangled == NULL)
823 oldmangled = *mangled;
826 work -> static_type = 1;
830 /* a const member function */
831 if (oldmangled == NULL)
833 oldmangled = *mangled;
836 work -> const_type = 1;
839 case '0': case '1': case '2': case '3': case '4':
840 case '5': case '6': case '7': case '8': case '9':
841 if (oldmangled == NULL)
843 oldmangled = *mangled;
845 success = demangle_class (work, mangled, declp);
848 remember_type (work, oldmangled, *mangled - oldmangled);
850 if (AUTO_DEMANGLING || GNU_DEMANGLING)
859 /* ARM style demangling includes a specific 'F' character after
860 the class name. For GNU style, it is just implied. So we can
861 safely just consume any 'F' at this point and be compatible
862 with either style. */
868 /* For lucid/ARM style we have to forget any types we might
869 have remembered up to this point, since they were not argument
870 types. GNU style considers all types seen as available for
871 back references. See comment in demangle_args() */
873 if (LUCID_DEMANGLING || ARM_DEMANGLING)
877 success = demangle_args (work, mangled, declp);
882 string_init(&trawname);
884 if (oldmangled == NULL)
886 oldmangled = *mangled;
888 success = demangle_template (work, mangled, &tname, &trawname, 1);
891 remember_type (work, oldmangled, *mangled - oldmangled);
893 string_append (&tname, "::");
895 string_prepends(declp, &tname);
896 if (work -> destructor & 1)
898 string_prepend (&trawname, "~");
899 string_appends (declp, &trawname);
900 work->destructor -= 1;
902 if ((work->constructor & 1) || (work->destructor & 1))
904 string_appends (declp, &trawname);
905 work->constructor -= 1;
907 string_delete(&trawname);
908 string_delete(&tname);
914 if (GNU_DEMANGLING && expect_return_type)
916 /* Read the return type. */
918 string_init (&return_type);
921 success = do_type (work, mangled, &return_type);
922 APPEND_BLANK (&return_type);
924 string_prepends (declp, &return_type);
925 string_delete (&return_type);
929 /* At the outermost level, we cannot have a return type specified,
930 so if we run into another '_' at this point we are dealing with
931 a mangled name that is either bogus, or has been mangled by
932 some algorithm we don't know how to deal with. So just
933 reject the entire demangling. */
940 /* A G++ template function. Read the template arguments. */
941 success = demangle_template (work, mangled, declp, 0, 0);
942 if (!(work->constructor & 1))
943 expect_return_type = 1;
952 if (AUTO_DEMANGLING || GNU_DEMANGLING)
954 /* Assume we have stumbled onto the first outermost function
955 argument token, and start processing args. */
957 success = demangle_args (work, mangled, declp);
961 /* Non-GNU demanglers use a specific token to mark the start
962 of the outermost function argument tokens. Typically 'F',
963 for ARM-demangling, for example. So if we find something
964 we are not prepared for, it must be an error. */
970 if (AUTO_DEMANGLING || GNU_DEMANGLING)
973 if (success && expect_func)
976 success = demangle_args (work, mangled, declp);
977 /* Since template include the mangling of their return types,
978 we must set expect_func to 0 so that we don't try do
979 demangle more arguments the next time we get here. */
984 if (success && !func_done)
986 if (AUTO_DEMANGLING || GNU_DEMANGLING)
988 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
989 bar__3fooi is 'foo::bar(int)'. We get here when we find the
990 first case, and need to ensure that the '(void)' gets added to
991 the current declp. Note that with ARM, the first case
992 represents the name of a static data member 'foo::bar',
993 which is in the current declp, so we leave it alone. */
994 success = demangle_args (work, mangled, declp);
997 if (success && work -> static_type && PRINT_ARG_TYPES)
999 string_append (declp, " static");
1001 if (success && work -> const_type && PRINT_ARG_TYPES)
1003 string_append (declp, " const");
1011 demangle_method_args (work, mangled, declp)
1012 struct work_stuff *work;
1013 const char **mangled;
1018 if (work -> static_type)
1020 string_append (declp, *mangled + 1);
1021 *mangled += strlen (*mangled);
1026 success = demangle_args (work, mangled, declp);
1034 demangle_template_template_parm (work, mangled, tname)
1035 struct work_stuff *work;
1036 const char **mangled;
1045 string_append (tname, "template <");
1046 /* get size of template parameter list */
1047 if (get_count (mangled, &r))
1049 for (i = 0; i < r; i++)
1053 string_append (tname, ", ");
1056 /* Z for type parameters */
1057 if (**mangled == 'Z')
1060 string_append (tname, "class");
1062 /* z for template parameters */
1063 else if (**mangled == 'z')
1067 demangle_template_template_parm (work, mangled, tname);
1075 /* temp is initialized in do_type */
1076 success = do_type (work, mangled, &temp);
1079 string_appends (tname, &temp);
1081 string_delete(&temp);
1091 if (tname->p[-1] == '>')
1092 string_append (tname, " ");
1093 string_append (tname, "> class");
1098 demangle_integral_value (work, mangled, s)
1099 struct work_stuff *work;
1100 const char** mangled;
1105 if (**mangled == 'E')
1107 int need_operator = 0;
1110 string_appendn (s, "(", 1);
1112 while (success && **mangled != 'W' && **mangled != '\0')
1121 len = strlen (*mangled);
1124 i < sizeof (optable) / sizeof (optable [0]);
1127 size_t l = strlen (optable[i].in);
1130 && memcmp (optable[i].in, *mangled, l) == 0)
1132 string_appendn (s, " ", 1);
1133 string_append (s, optable[i].out);
1134 string_appendn (s, " ", 1);
1147 success = demangle_template_value_parm (work, mangled, s);
1150 if (**mangled != 'W')
1154 string_appendn (s, ")", 1);
1158 else if (**mangled == 'Q' || **mangled == 'K')
1159 success = demangle_qualified (work, mangled, s, 0, 1);
1164 if (**mangled == 'm')
1166 string_appendn (s, "-", 1);
1169 while (isdigit (**mangled))
1171 string_appendn (s, *mangled, 1);
1181 demangle_template_value_parm (work, mangled, s)
1182 struct work_stuff *work;
1183 const char **mangled;
1186 const char *old_p = *mangled;
1189 int is_integral = 0;
1195 while (*old_p && !done)
1202 done = is_pointer = 1;
1204 case 'C': /* const */
1205 case 'S': /* explicitly signed [char] */
1206 case 'U': /* unsigned */
1207 case 'V': /* volatile */
1208 case 'F': /* function */
1209 case 'M': /* member function */
1211 case 'J': /* complex */
1214 case 'E': /* expression */
1215 case 'Q': /* qualified name */
1216 case 'K': /* qualified name */
1217 done = is_integral = 1;
1219 case 'B': /* squangled name */
1220 done = is_integral = 1;
1222 case 'T': /* remembered type */
1225 case 'v': /* void */
1228 case 'x': /* long long */
1229 case 'l': /* long */
1231 case 's': /* short */
1232 case 'w': /* wchar_t */
1233 done = is_integral = 1;
1235 case 'b': /* bool */
1238 case 'c': /* char */
1241 case 'r': /* long double */
1242 case 'd': /* double */
1243 case 'f': /* float */
1247 /* it's probably user defined type, let's assume
1248 it's integral, it seems hard to figure out
1249 what it really is */
1250 done = is_integral = 1;
1253 if (**mangled == 'Y')
1255 /* The next argument is a template parameter. */
1259 idx = consume_count_with_underscores (mangled);
1261 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1262 || consume_count_with_underscores (mangled) == -1)
1264 if (work->tmpl_argvec)
1265 string_append (s, work->tmpl_argvec[idx]);
1269 sprintf(buf, "T%d", idx);
1270 string_append (s, buf);
1273 else if (is_integral)
1274 success = demangle_integral_value (work, mangled, s);
1279 if (**mangled == 'm')
1281 string_appendn (s, "-", 1);
1284 string_appendn (s, "'", 1);
1285 val = consume_count(mangled);
1290 string_appendn (s, &tmp[0], 1);
1291 string_appendn (s, "'", 1);
1295 int val = consume_count (mangled);
1297 string_appendn (s, "false", 5);
1299 string_appendn (s, "true", 4);
1305 if (**mangled == 'm')
1307 string_appendn (s, "-", 1);
1310 while (isdigit (**mangled))
1312 string_appendn (s, *mangled, 1);
1315 if (**mangled == '.') /* fraction */
1317 string_appendn (s, ".", 1);
1319 while (isdigit (**mangled))
1321 string_appendn (s, *mangled, 1);
1325 if (**mangled == 'e') /* exponent */
1327 string_appendn (s, "e", 1);
1329 while (isdigit (**mangled))
1331 string_appendn (s, *mangled, 1);
1336 else if (is_pointer)
1338 int symbol_len = consume_count (mangled);
1339 if (symbol_len == 0)
1341 if (symbol_len == 0)
1342 string_appendn (s, "0", 1);
1345 char *p = xmalloc (symbol_len + 1), *q;
1346 strncpy (p, *mangled, symbol_len);
1347 p [symbol_len] = '\0';
1348 q = internal_cplus_demangle (work, p);
1349 string_appendn (s, "&", 1);
1352 string_append (s, q);
1356 string_append (s, p);
1359 *mangled += symbol_len;
1366 demangle_template (work, mangled, tname, trawname, is_type)
1367 struct work_stuff *work;
1368 const char **mangled;
1384 /* get template name */
1385 if (**mangled == 'z')
1391 idx = consume_count_with_underscores (mangled);
1393 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1394 || consume_count_with_underscores (mangled) == -1)
1398 if (work->tmpl_argvec)
1400 string_append (tname, work->tmpl_argvec[idx]);
1402 string_append (trawname, work->tmpl_argvec[idx]);
1407 sprintf(buf, "T%d", idx);
1408 string_append (tname, buf);
1410 string_append (trawname, work->tmpl_argvec[idx]);
1415 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
1420 string_appendn (trawname, *mangled, r);
1421 string_appendn (tname, *mangled, r);
1425 string_append (tname, "<");
1426 /* get size of template parameter list */
1427 if (!get_count (mangled, &r))
1433 /* Create an array for saving the template argument values. */
1434 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1435 work->ntmpl_args = r;
1436 for (i = 0; i < r; i++)
1437 work->tmpl_argvec[i] = 0;
1439 for (i = 0; i < r; i++)
1443 string_append (tname, ", ");
1445 /* Z for type parameters */
1446 if (**mangled == 'Z')
1449 /* temp is initialized in do_type */
1450 success = do_type (work, mangled, &temp);
1453 string_appends (tname, &temp);
1457 /* Save the template argument. */
1458 int len = temp.p - temp.b;
1459 work->tmpl_argvec[i] = xmalloc (len + 1);
1460 memcpy (work->tmpl_argvec[i], temp.b, len);
1461 work->tmpl_argvec[i][len] = '\0';
1464 string_delete(&temp);
1470 /* z for template parameters */
1471 else if (**mangled == 'z')
1475 success = demangle_template_template_parm (work, mangled, tname);
1478 && (r2 = consume_count (mangled)) > 0 && strlen (*mangled) >= r2)
1480 string_append (tname, " ");
1481 string_appendn (tname, *mangled, r2);
1484 /* Save the template argument. */
1486 work->tmpl_argvec[i] = xmalloc (len + 1);
1487 memcpy (work->tmpl_argvec[i], *mangled, len);
1488 work->tmpl_argvec[i][len] = '\0';
1502 /* otherwise, value parameter */
1504 /* temp is initialized in do_type */
1505 success = do_type (work, mangled, &temp);
1509 string_appends (s, &temp);
1512 string_delete(&temp);
1518 string_append (s, "=");
1529 success = demangle_template_value_parm (work, mangled, s);
1541 int len = s->p - s->b;
1542 work->tmpl_argvec[i] = xmalloc (len + 1);
1543 memcpy (work->tmpl_argvec[i], s->b, len);
1544 work->tmpl_argvec[i][len] = '\0';
1546 string_appends (tname, s);
1553 if (tname->p[-1] == '>')
1554 string_append (tname, " ");
1555 string_append (tname, ">");
1559 if (work -> static_type)
1561 string_append (declp, *mangled + 1);
1562 *mangled += strlen (*mangled);
1567 success = demangle_args (work, mangled, declp);
1575 arm_pt (work, mangled, n, anchor, args)
1576 struct work_stuff *work;
1577 const char *mangled;
1579 const char **anchor, **args;
1582 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1585 *args = *anchor + 6;
1586 len = consume_count (args);
1587 if (*args + len == mangled + n && **args == '_')
1597 demangle_arm_pt (work, mangled, n, declp)
1598 struct work_stuff *work;
1599 const char **mangled;
1605 const char *e = *mangled + n;
1608 if (arm_pt (work, *mangled, n, &p, &args))
1612 string_appendn (declp, *mangled, p - *mangled);
1613 string_append (declp, "<");
1614 /* should do error checking here */
1616 string_clear (&arg);
1617 do_type (work, &args, &arg);
1618 string_appends (declp, &arg);
1619 string_append (declp, ",");
1621 string_delete (&arg);
1623 string_append (declp, ">");
1627 string_appendn (declp, *mangled, n);
1633 demangle_class_name (work, mangled, declp)
1634 struct work_stuff *work;
1635 const char **mangled;
1641 n = consume_count (mangled);
1642 if (strlen (*mangled) >= n)
1644 demangle_arm_pt (work, mangled, n, declp);
1655 demangle_class -- demangle a mangled class sequence
1660 demangle_class (struct work_stuff *work, const char **mangled,
1665 DECLP points to the buffer into which demangling is being done.
1667 *MANGLED points to the current token to be demangled. On input,
1668 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1669 On exit, it points to the next token after the mangled class on
1670 success, or the first unconsumed token on failure.
1672 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1673 we are demangling a constructor or destructor. In this case
1674 we prepend "class::class" or "class::~class" to DECLP.
1676 Otherwise, we prepend "class::" to the current DECLP.
1678 Reset the constructor/destructor flags once they have been
1679 "consumed". This allows demangle_class to be called later during
1680 the same demangling, to do normal class demangling.
1682 Returns 1 if demangling is successful, 0 otherwise.
1687 demangle_class (work, mangled, declp)
1688 struct work_stuff *work;
1689 const char **mangled;
1696 string_init (&class_name);
1697 btype = register_Btype (work);
1698 if (demangle_class_name (work, mangled, &class_name))
1700 if ((work->constructor & 1) || (work->destructor & 1))
1702 string_prepends (declp, &class_name);
1703 if (work -> destructor & 1)
1705 string_prepend (declp, "~");
1706 work -> destructor -= 1;
1710 work -> constructor -= 1;
1713 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
1714 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
1715 string_prepend (declp, "::");
1716 string_prepends (declp, &class_name);
1719 string_delete (&class_name);
1727 demangle_prefix -- consume the mangled name prefix and find signature
1732 demangle_prefix (struct work_stuff *work, const char **mangled,
1737 Consume and demangle the prefix of the mangled name.
1739 DECLP points to the string buffer into which demangled output is
1740 placed. On entry, the buffer is empty. On exit it contains
1741 the root function name, the demangled operator name, or in some
1742 special cases either nothing or the completely demangled result.
1744 MANGLED points to the current pointer into the mangled name. As each
1745 token of the mangled name is consumed, it is updated. Upon entry
1746 the current mangled name pointer points to the first character of
1747 the mangled name. Upon exit, it should point to the first character
1748 of the signature if demangling was successful, or to the first
1749 unconsumed character if demangling of the prefix was unsuccessful.
1751 Returns 1 on success, 0 otherwise.
1755 demangle_prefix (work, mangled, declp)
1756 struct work_stuff *work;
1757 const char **mangled;
1764 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1766 char *marker = strchr (cplus_markers, (*mangled)[8]);
1767 if (marker != NULL && *marker == (*mangled)[10])
1769 if ((*mangled)[9] == 'D')
1771 /* it's a GNU global destructor to be executed at program exit */
1773 work->destructor = 2;
1774 if (gnu_special (work, mangled, declp))
1777 else if ((*mangled)[9] == 'I')
1779 /* it's a GNU global constructor to be executed at program init */
1781 work->constructor = 2;
1782 if (gnu_special (work, mangled, declp))
1787 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1789 /* it's a ARM global destructor to be executed at program exit */
1791 work->destructor = 2;
1793 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1795 /* it's a ARM global constructor to be executed at program initial */
1797 work->constructor = 2;
1800 /* This block of code is a reduction in strength time optimization
1802 scan = mystrstr (*mangled, "__"); */
1808 scan = strchr (scan, '_');
1809 } while (scan != NULL && *++scan != '_');
1811 if (scan != NULL) --scan;
1816 /* We found a sequence of two or more '_', ensure that we start at
1817 the last pair in the sequence. */
1818 i = strspn (scan, "_");
1829 else if (work -> static_type)
1831 if (!isdigit (scan[0]) && (scan[0] != 't'))
1836 else if ((scan == *mangled)
1837 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
1838 || (scan[2] == 'K') || (scan[2] == 'H')))
1840 /* The ARM says nothing about the mangling of local variables.
1841 But cfront mangles local variables by prepending __<nesting_level>
1842 to them. As an extension to ARM demangling we handle this case. */
1843 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1845 *mangled = scan + 2;
1846 consume_count (mangled);
1847 string_append (declp, *mangled);
1848 *mangled += strlen (*mangled);
1853 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1854 names like __Q2_3foo3bar for nested type names. So don't accept
1855 this style of constructor for cfront demangling. A GNU
1856 style member-template constructor starts with 'H'. */
1857 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1858 work -> constructor += 1;
1859 *mangled = scan + 2;
1862 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1864 /* Mangled name starts with "__". Skip over any leading '_' characters,
1865 then find the next "__" that separates the prefix from the signature.
1867 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1868 || (arm_special (mangled, declp) == 0))
1870 while (*scan == '_')
1874 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1876 /* No separator (I.E. "__not_mangled"), or empty signature
1877 (I.E. "__not_mangled_either__") */
1882 demangle_function_name (work, mangled, declp, scan);
1886 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1888 /* Cfront-style parameterized type. Handled later as a signature. */
1892 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1894 else if (*(scan + 2) != '\0')
1896 /* Mangled name does not start with "__" but does have one somewhere
1897 in there with non empty stuff after it. Looks like a global
1899 demangle_function_name (work, mangled, declp, scan);
1903 /* Doesn't look like a mangled name */
1907 if (!success && (work->constructor == 2 || work->destructor == 2))
1909 string_append (declp, *mangled);
1910 *mangled += strlen (*mangled);
1920 gnu_special -- special handling of gnu mangled strings
1925 gnu_special (struct work_stuff *work, const char **mangled,
1931 Process some special GNU style mangling forms that don't fit
1932 the normal pattern. For example:
1934 _$_3foo (destructor for class foo)
1935 _vt$foo (foo virtual table)
1936 _vt$foo$bar (foo::bar virtual table)
1937 __vt_foo (foo virtual table, new style with thunks)
1938 _3foo$varname (static data member)
1939 _Q22rs2tu$vw (static data member)
1940 __t6vector1Zii (constructor with template)
1941 __thunk_4__$_7ostream (virtual function thunk)
1945 gnu_special (work, mangled, declp)
1946 struct work_stuff *work;
1947 const char **mangled;
1954 if ((*mangled)[0] == '_'
1955 && strchr (cplus_markers, (*mangled)[1]) != NULL
1956 && (*mangled)[2] == '_')
1958 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1960 work -> destructor += 1;
1962 else if ((*mangled)[0] == '_'
1963 && (((*mangled)[1] == '_'
1964 && (*mangled)[2] == 'v'
1965 && (*mangled)[3] == 't'
1966 && (*mangled)[4] == '_')
1967 || ((*mangled)[1] == 'v'
1968 && (*mangled)[2] == 't'
1969 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1971 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1972 and create the decl. Note that we consume the entire mangled
1973 input string, which means that demangle_signature has no work
1975 if ((*mangled)[2] == 'v')
1976 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1978 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1979 while (**mangled != '\0')
1981 p = strpbrk (*mangled, cplus_markers);
1986 success = demangle_qualified (work, mangled, declp, 0, 1);
1989 success = demangle_template (work, mangled, declp, 0, 1);
1992 if (isdigit(*mangled[0]))
1994 n = consume_count(mangled);
1995 /* We may be seeing a too-large size, or else a
1996 ".<digits>" indicating a static local symbol. In
1997 any case, declare victory and move on; *don't* try
1998 to use n to allocate. */
1999 if (n > strlen (*mangled))
2007 n = strcspn (*mangled, cplus_markers);
2009 string_appendn (declp, *mangled, n);
2013 if (success && ((p == NULL) || (p == *mangled)))
2017 string_append (declp, "::");
2028 string_append (declp, " virtual table");
2030 else if ((*mangled)[0] == '_'
2031 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2032 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2034 /* static data member, "_3foo$varname" for example */
2040 success = demangle_qualified (work, mangled, declp, 0, 1);
2043 success = demangle_template (work, mangled, declp, 0, 1);
2046 n = consume_count (mangled);
2047 string_appendn (declp, *mangled, n);
2050 if (success && (p == *mangled))
2052 /* Consumed everything up to the cplus_marker, append the
2055 string_append (declp, "::");
2056 n = strlen (*mangled);
2057 string_appendn (declp, *mangled, n);
2065 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2067 int delta = ((*mangled) += 8, consume_count (mangled));
2068 char *method = internal_cplus_demangle (work, ++*mangled);
2072 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2073 string_append (declp, buf);
2074 string_append (declp, method);
2076 n = strlen (*mangled);
2084 else if (strncmp (*mangled, "__t", 3) == 0
2085 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2087 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2093 success = demangle_qualified (work, mangled, declp, 0, 1);
2096 success = demangle_template (work, mangled, declp, 0, 1);
2099 success = demangle_fund_type (work, mangled, declp);
2102 if (success && **mangled != '\0')
2105 string_append (declp, p);
2118 arm_special -- special handling of ARM/lucid mangled strings
2123 arm_special (const char **mangled,
2129 Process some special ARM style mangling forms that don't fit
2130 the normal pattern. For example:
2132 __vtbl__3foo (foo virtual table)
2133 __vtbl__3foo__3bar (bar::foo virtual table)
2138 arm_special (mangled, declp)
2139 const char **mangled;
2146 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2148 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2149 and create the decl. Note that we consume the entire mangled
2150 input string, which means that demangle_signature has no work
2152 scan = *mangled + ARM_VTABLE_STRLEN;
2153 while (*scan != '\0') /* first check it can be demangled */
2155 n = consume_count (&scan);
2158 return (0); /* no good */
2161 if (scan[0] == '_' && scan[1] == '_')
2166 (*mangled) += ARM_VTABLE_STRLEN;
2167 while (**mangled != '\0')
2169 n = consume_count (mangled);
2170 string_prependn (declp, *mangled, n);
2172 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2174 string_prepend (declp, "::");
2178 string_append (declp, " virtual table");
2191 demangle_qualified -- demangle 'Q' qualified name strings
2196 demangle_qualified (struct work_stuff *, const char *mangled,
2197 string *result, int isfuncname, int append);
2201 Demangle a qualified name, such as "Q25Outer5Inner" which is
2202 the mangled form of "Outer::Inner". The demangled output is
2203 prepended or appended to the result string according to the
2204 state of the append flag.
2206 If isfuncname is nonzero, then the qualified name we are building
2207 is going to be used as a member function name, so if it is a
2208 constructor or destructor function, append an appropriate
2209 constructor or destructor name. I.E. for the above example,
2210 the result for use as a constructor is "Outer::Inner::Inner"
2211 and the result for use as a destructor is "Outer::Inner::~Inner".
2215 Numeric conversion is ASCII dependent (FIXME).
2220 demangle_qualified (work, mangled, result, isfuncname, append)
2221 struct work_stuff *work;
2222 const char **mangled;
2234 string_init (&temp);
2236 if ((*mangled)[0] == 'K')
2238 /* Squangling qualified name reuse */
2241 idx = consume_count_with_underscores (mangled);
2242 if (idx == -1 || idx > work -> numk)
2245 string_append (&temp, work -> ktypevec[idx]);
2248 switch ((*mangled)[1])
2251 /* GNU mangled name with more than 9 classes. The count is preceded
2252 by an underscore (to distinguish it from the <= 9 case) and followed
2253 by an underscore. */
2255 qualifiers = atoi (p);
2256 if (!isdigit (*p) || *p == '0')
2259 /* Skip the digits. */
2260 while (isdigit (*p))
2278 /* The count is in a single digit. */
2279 num[0] = (*mangled)[1];
2281 qualifiers = atoi (num);
2283 /* If there is an underscore after the digit, skip it. This is
2284 said to be for ARM-qualified names, but the ARM makes no
2285 mention of such an underscore. Perhaps cfront uses one. */
2286 if ((*mangled)[2] == '_')
2301 /* Pick off the names and collect them in the temp buffer in the order
2302 in which they are found, separated by '::'. */
2304 while (qualifiers-- > 0)
2307 if (*mangled[0] == '_')
2308 *mangled = *mangled + 1;
2309 if (*mangled[0] == 't')
2311 success = demangle_template(work, mangled, &temp, 0, 1);
2312 if (!success) break;
2314 else if (*mangled[0] == 'X')
2316 success = do_type (work, mangled, &temp);
2317 if (!success) break;
2319 else if (*mangled[0] == 'K')
2323 idx = consume_count_with_underscores (mangled);
2324 if (idx == -1 || idx > work->numk)
2327 string_append (&temp, work->ktypevec[idx]);
2330 if (!success) break;
2334 namelength = consume_count (mangled);
2335 if (strlen (*mangled) < namelength)
2337 /* Simple sanity check failed */
2341 string_appendn (&temp, *mangled, namelength);
2342 *mangled += namelength;
2347 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2352 string_append (&temp, "::");
2356 /* If we are using the result as a function name, we need to append
2357 the appropriate '::' separated constructor or destructor name.
2358 We do this here because this is the most convenient place, where
2359 we already have a pointer to the name and the length of the name. */
2361 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
2363 string_append (&temp, "::");
2364 if (work -> destructor & 1)
2366 string_append (&temp, "~");
2368 string_appendn (&temp, (*mangled) - namelength, namelength);
2371 /* Now either prepend the temp buffer to the result, or append it,
2372 depending upon the state of the append flag. */
2376 string_appends (result, &temp);
2380 if (!STRING_EMPTY (result))
2382 string_append (&temp, "::");
2384 string_prepends (result, &temp);
2387 string_delete (&temp);
2395 get_count -- convert an ascii count to integer, consuming tokens
2400 get_count (const char **type, int *count)
2404 Return 0 if no conversion is performed, 1 if a string is converted.
2408 get_count (type, count)
2415 if (!isdigit (**type))
2421 *count = **type - '0';
2423 if (isdigit (**type))
2433 while (isdigit (*p));
2444 /* result will be initialised here; it will be freed on failure */
2447 do_type (work, mangled, result)
2448 struct work_stuff *work;
2449 const char **mangled;
2456 const char *remembered_type;
2461 string_init (&btype);
2462 string_init (&decl);
2463 string_init (result);
2467 while (success && !done)
2473 /* A pointer type */
2477 string_prepend (&decl, "*");
2480 /* A reference type */
2483 string_prepend (&decl, "&");
2489 const char *p = ++(*mangled);
2491 string_prepend (&decl, "(");
2492 string_append (&decl, ")[");
2493 /* Copy anything up until the next underscore (the size of the
2495 while (**mangled && **mangled != '_')
2497 if (**mangled == '_')
2499 string_appendn (&decl, p, *mangled - p);
2500 string_append (&decl, "]");
2508 /* A back reference to a previously seen type */
2511 if (!get_count (mangled, &n) || n >= work -> ntypes)
2517 remembered_type = work -> typevec[n];
2518 mangled = &remembered_type;
2525 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2527 string_prepend (&decl, "(");
2528 string_append (&decl, ")");
2530 /* After picking off the function args, we expect to either find the
2531 function return type (preceded by an '_') or the end of the
2533 if (!demangle_args (work, mangled, &decl)
2534 || (**mangled != '_' && **mangled != '\0'))
2538 if (success && (**mangled == '_'))
2550 member = **mangled == 'M';
2552 if (!isdigit (**mangled) && **mangled != 't')
2558 string_append (&decl, ")");
2559 string_prepend (&decl, "::");
2560 if (isdigit (**mangled))
2562 n = consume_count (mangled);
2563 if (strlen (*mangled) < n)
2568 string_prependn (&decl, *mangled, n);
2574 string_init (&temp);
2575 success = demangle_template (work, mangled, &temp, NULL, 1);
2578 string_prependn (&decl, temp.b, temp.p - temp.b);
2579 string_clear (&temp);
2584 string_prepend (&decl, "(");
2587 if (**mangled == 'C')
2592 if (**mangled == 'V')
2597 if (*(*mangled)++ != 'F')
2603 if ((member && !demangle_args (work, mangled, &decl))
2604 || **mangled != '_')
2610 if (! PRINT_ANSI_QUALIFIERS)
2616 APPEND_BLANK (&decl);
2617 string_append (&decl, "const");
2621 APPEND_BLANK (&decl);
2622 string_append (&decl, "volatile");
2633 if ((*mangled)[1] == 'P')
2636 if (PRINT_ANSI_QUALIFIERS)
2638 if (!STRING_EMPTY (&decl))
2640 string_prepend (&decl, " ");
2642 string_prepend (&decl, "const");
2658 /* A qualified name, such as "Outer::Inner". */
2662 int btype = register_Btype (work);
2663 success = demangle_qualified (work, mangled, result, 0, 1);
2664 remember_Btype (work, result->b, LEN_STRING (result), btype);
2669 /* A back reference to a previously seen squangled type */
2672 if (!get_count (mangled, &n) || n >= work -> numb)
2676 string_append (result, work->btypevec[n]);
2682 /* A template parm. We substitute the corresponding argument. */
2687 idx = consume_count_with_underscores (mangled);
2690 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2691 || consume_count_with_underscores (mangled) == -1)
2697 if (work->tmpl_argvec)
2698 string_append (result, work->tmpl_argvec[idx]);
2702 sprintf(buf, "T%d", idx);
2703 string_append (result, buf);
2711 success = demangle_fund_type (work, mangled, result);
2717 if (!STRING_EMPTY (&decl))
2719 string_append (result, " ");
2720 string_appends (result, &decl);
2725 string_delete (result);
2727 string_delete (&decl);
2731 /* Given a pointer to a type string that represents a fundamental type
2732 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2733 string in which the demangled output is being built in RESULT, and
2734 the WORK structure, decode the types and add them to the result.
2739 "Sl" => "signed long"
2740 "CUs" => "const unsigned short"
2745 demangle_fund_type (work, mangled, result)
2746 struct work_stuff *work;
2747 const char **mangled;
2753 string_init (&btype);
2755 /* First pick off any type qualifiers. There can be more than one. */
2763 if (PRINT_ANSI_QUALIFIERS)
2765 APPEND_BLANK (result);
2766 string_append (result, "const");
2771 APPEND_BLANK (result);
2772 string_append (result, "unsigned");
2774 case 'S': /* signed char only */
2776 APPEND_BLANK (result);
2777 string_append (result, "signed");
2781 if (PRINT_ANSI_QUALIFIERS)
2783 APPEND_BLANK (result);
2784 string_append (result, "volatile");
2789 APPEND_BLANK (result);
2790 string_append (result, "__complex");
2798 /* Now pick off the fundamental type. There can be only one. */
2807 APPEND_BLANK (result);
2808 string_append (result, "void");
2812 APPEND_BLANK (result);
2813 string_append (result, "long long");
2817 APPEND_BLANK (result);
2818 string_append (result, "long");
2822 APPEND_BLANK (result);
2823 string_append (result, "int");
2827 APPEND_BLANK (result);
2828 string_append (result, "short");
2832 APPEND_BLANK (result);
2833 string_append (result, "bool");
2837 APPEND_BLANK (result);
2838 string_append (result, "char");
2842 APPEND_BLANK (result);
2843 string_append (result, "wchar_t");
2847 APPEND_BLANK (result);
2848 string_append (result, "long double");
2852 APPEND_BLANK (result);
2853 string_append (result, "double");
2857 APPEND_BLANK (result);
2858 string_append (result, "float");
2862 if (!isdigit (**mangled))
2868 /* An explicit type, such as "6mytype" or "7integer" */
2880 int bindex = register_Btype (work);
2882 string_init (&btype);
2883 if (demangle_class_name (work, mangled, &btype)) {
2884 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
2885 APPEND_BLANK (result);
2886 string_appends (result, &btype);
2890 string_delete (&btype);
2895 int bindex= register_Btype (work);
2896 success = demangle_template (work, mangled, &btype, 0, 1);
2897 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
2898 string_appends (result, &btype);
2909 /* `result' will be initialized in do_type; it will be freed on failure */
2912 do_arg (work, mangled, result)
2913 struct work_stuff *work;
2914 const char **mangled;
2917 const char *start = *mangled;
2919 if (!do_type (work, mangled, result))
2925 remember_type (work, start, *mangled - start);
2931 remember_type (work, start, len)
2932 struct work_stuff *work;
2938 if (work -> ntypes >= work -> typevec_size)
2940 if (work -> typevec_size == 0)
2942 work -> typevec_size = 3;
2944 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2948 work -> typevec_size *= 2;
2950 = (char **) xrealloc ((char *)work -> typevec,
2951 sizeof (char *) * work -> typevec_size);
2954 tem = xmalloc (len + 1);
2955 memcpy (tem, start, len);
2957 work -> typevec[work -> ntypes++] = tem;
2961 /* Remember a K type class qualifier. */
2963 remember_Ktype (work, start, len)
2964 struct work_stuff *work;
2970 if (work -> numk >= work -> ksize)
2972 if (work -> ksize == 0)
2976 = (char **) xmalloc (sizeof (char *) * work -> ksize);
2982 = (char **) xrealloc ((char *)work -> ktypevec,
2983 sizeof (char *) * work -> ksize);
2986 tem = xmalloc (len + 1);
2987 memcpy (tem, start, len);
2989 work -> ktypevec[work -> numk++] = tem;
2992 /* Register a B code, and get an index for it. B codes are registered
2993 as they are seen, rather than as they are completed, so map<temp<char> >
2994 registers map<temp<char> > as B0, and temp<char> as B1 */
2997 register_Btype (work)
2998 struct work_stuff *work;
3002 if (work -> numb >= work -> bsize)
3004 if (work -> bsize == 0)
3008 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3014 = (char **) xrealloc ((char *)work -> btypevec,
3015 sizeof (char *) * work -> bsize);
3018 ret = work -> numb++;
3019 work -> btypevec[ret] = NULL;
3023 /* Store a value into a previously registered B code type. */
3026 remember_Btype (work, start, len, index)
3027 struct work_stuff *work;
3033 tem = xmalloc (len + 1);
3034 memcpy (tem, start, len);
3036 work -> btypevec[index] = tem;
3039 /* Lose all the info related to B and K type codes. */
3041 forget_B_and_K_types (work)
3042 struct work_stuff *work;
3046 while (work -> numk > 0)
3048 i = --(work -> numk);
3049 if (work -> ktypevec[i] != NULL)
3051 free (work -> ktypevec[i]);
3052 work -> ktypevec[i] = NULL;
3056 while (work -> numb > 0)
3058 i = --(work -> numb);
3059 if (work -> btypevec[i] != NULL)
3061 free (work -> btypevec[i]);
3062 work -> btypevec[i] = NULL;
3066 /* Forget the remembered types, but not the type vector itself. */
3070 struct work_stuff *work;
3074 while (work -> ntypes > 0)
3076 i = --(work -> ntypes);
3077 if (work -> typevec[i] != NULL)
3079 free (work -> typevec[i]);
3080 work -> typevec[i] = NULL;
3085 /* Process the argument list part of the signature, after any class spec
3086 has been consumed, as well as the first 'F' character (if any). For
3089 "__als__3fooRT0" => process "RT0"
3090 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3092 DECLP must be already initialised, usually non-empty. It won't be freed
3095 Note that g++ differs significantly from ARM and lucid style mangling
3096 with regards to references to previously seen types. For example, given
3097 the source fragment:
3101 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3104 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3105 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3107 g++ produces the names:
3112 while lcc (and presumably other ARM style compilers as well) produces:
3114 foo__FiR3fooT1T2T1T2
3115 __ct__3fooFiR3fooT1T2T1T2
3117 Note that g++ bases it's type numbers starting at zero and counts all
3118 previously seen types, while lucid/ARM bases it's type numbers starting
3119 at one and only considers types after it has seen the 'F' character
3120 indicating the start of the function args. For lucid/ARM style, we
3121 account for this difference by discarding any previously seen types when
3122 we see the 'F' character, and subtracting one from the type number
3128 demangle_args (work, mangled, declp)
3129 struct work_stuff *work;
3130 const char **mangled;
3140 if (PRINT_ARG_TYPES)
3142 string_append (declp, "(");
3143 if (**mangled == '\0')
3145 string_append (declp, "void");
3149 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3151 if ((**mangled == 'N') || (**mangled == 'T'))
3153 temptype = *(*mangled)++;
3155 if (temptype == 'N')
3157 if (!get_count (mangled, &r))
3166 if (ARM_DEMANGLING && work -> ntypes >= 10)
3168 /* If we have 10 or more types we might have more than a 1 digit
3169 index so we'll have to consume the whole count here. This
3170 will lose if the next thing is a type name preceded by a
3171 count but it's impossible to demangle that case properly
3172 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3173 Pc, ...)" or "(..., type12, char *, ...)" */
3174 if ((t = consume_count(mangled)) == 0)
3181 if (!get_count (mangled, &t))
3186 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3190 /* Validate the type index. Protect against illegal indices from
3191 malformed type strings. */
3192 if ((t < 0) || (t >= work -> ntypes))
3198 tem = work -> typevec[t];
3199 if (need_comma && PRINT_ARG_TYPES)
3201 string_append (declp, ", ");
3203 if (!do_arg (work, &tem, &arg))
3207 if (PRINT_ARG_TYPES)
3209 string_appends (declp, &arg);
3211 string_delete (&arg);
3217 if (need_comma & PRINT_ARG_TYPES)
3219 string_append (declp, ", ");
3221 if (!do_arg (work, mangled, &arg))
3225 if (PRINT_ARG_TYPES)
3227 string_appends (declp, &arg);
3229 string_delete (&arg);
3234 if (**mangled == 'e')
3237 if (PRINT_ARG_TYPES)
3241 string_append (declp, ",");
3243 string_append (declp, "...");
3247 if (PRINT_ARG_TYPES)
3249 string_append (declp, ")");
3255 demangle_function_name (work, mangled, declp, scan)
3256 struct work_stuff *work;
3257 const char **mangled;
3265 string_appendn (declp, (*mangled), scan - (*mangled));
3266 string_need (declp, 1);
3267 *(declp -> p) = '\0';
3269 /* Consume the function name, including the "__" separating the name
3270 from the signature. We are guaranteed that SCAN points to the
3273 (*mangled) = scan + 2;
3275 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3278 /* See if we have an ARM style constructor or destructor operator.
3279 If so, then just record it, clear the decl, and return.
3280 We can't build the actual constructor/destructor decl until later,
3281 when we recover the class name from the signature. */
3283 if (strcmp (declp -> b, "__ct") == 0)
3285 work -> constructor += 1;
3286 string_clear (declp);
3289 else if (strcmp (declp -> b, "__dt") == 0)
3291 work -> destructor += 1;
3292 string_clear (declp);
3297 if (declp->p - declp->b >= 3
3298 && declp->b[0] == 'o'
3299 && declp->b[1] == 'p'
3300 && strchr (cplus_markers, declp->b[2]) != NULL)
3302 /* see if it's an assignment expression */
3303 if (declp->p - declp->b >= 10 /* op$assign_ */
3304 && memcmp (declp->b + 3, "assign_", 7) == 0)
3306 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3308 int len = declp->p - declp->b - 10;
3309 if (strlen (optable[i].in) == len
3310 && memcmp (optable[i].in, declp->b + 10, len) == 0)
3312 string_clear (declp);
3313 string_append (declp, "operator");
3314 string_append (declp, optable[i].out);
3315 string_append (declp, "=");
3322 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3324 int len = declp->p - declp->b - 3;
3325 if (strlen (optable[i].in) == len
3326 && memcmp (optable[i].in, declp->b + 3, len) == 0)
3328 string_clear (declp);
3329 string_append (declp, "operator");
3330 string_append (declp, optable[i].out);
3336 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
3337 && strchr (cplus_markers, declp->b[4]) != NULL)
3339 /* type conversion operator */
3341 if (do_type (work, &tem, &type))
3343 string_clear (declp);
3344 string_append (declp, "operator ");
3345 string_appends (declp, &type);
3346 string_delete (&type);
3349 else if (declp->b[0] == '_' && declp->b[1] == '_'
3350 && declp->b[2] == 'o' && declp->b[3] == 'p')
3353 /* type conversion operator. */
3355 if (do_type (work, &tem, &type))
3357 string_clear (declp);
3358 string_append (declp, "operator ");
3359 string_appends (declp, &type);
3360 string_delete (&type);
3363 else if (declp->b[0] == '_' && declp->b[1] == '_'
3364 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
3365 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
3367 if (declp->b[4] == '\0')
3370 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3372 if (strlen (optable[i].in) == 2
3373 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
3375 string_clear (declp);
3376 string_append (declp, "operator");
3377 string_append (declp, optable[i].out);
3384 if (declp->b[2] == 'a' && declp->b[5] == '\0')
3387 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3389 if (strlen (optable[i].in) == 3
3390 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
3392 string_clear (declp);
3393 string_append (declp, "operator");
3394 string_append (declp, optable[i].out);
3403 /* a mini string-handling package */
3418 s->p = s->b = xmalloc (n);
3421 else if (s->e - s->p < n)
3426 s->b = xrealloc (s->b, n);
3439 s->b = s->e = s->p = NULL;
3447 s->b = s->p = s->e = NULL;
3463 return (s->b == s->p);
3469 string_append (p, s)
3474 if (s == NULL || *s == '\0')
3478 memcpy (p->p, s, n);
3483 string_appends (p, s)
3492 memcpy (p->p, s->b, n);
3498 string_appendn (p, s, n)
3506 memcpy (p->p, s, n);
3512 string_prepend (p, s)
3516 if (s != NULL && *s != '\0')
3518 string_prependn (p, s, strlen (s));
3523 string_prepends (p, s)
3528 string_prependn (p, s->b, s->p - s->b);
3533 string_prependn (p, s, n)
3543 for (q = p->p - 1; q >= p->b; q--)
3547 memcpy (p->b, s, n);
3552 /* To generate a standalone demangler program for testing purposes,
3553 just compile and link this file with -DMAIN and libiberty.a. When
3554 run, it demangles each command line arg, or each stdin string, and
3555 prints the result on stdout. */
3561 static char *program_name;
3562 static char *program_version = VERSION;
3563 static int flags = DMGL_PARAMS | DMGL_ANSI;
3565 static void demangle_it PARAMS ((char *));
3566 static void usage PARAMS ((FILE *, int));
3567 static void fatal PARAMS ((char *));
3570 demangle_it (mangled_name)
3575 result = cplus_demangle (mangled_name, flags);
3578 printf ("%s\n", mangled_name);
3582 printf ("%s\n", result);
3588 usage (stream, status)
3593 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3594 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3595 [--help] [--version] [arg...]\n",
3600 #define MBUF_SIZE 512
3601 char mbuffer[MBUF_SIZE];
3603 /* Defined in the automatically-generated underscore.c. */
3604 extern int prepends_underscore;
3606 int strip_underscore = 0;
3608 static struct option long_options[] = {
3609 {"strip-underscores", no_argument, 0, '_'},
3610 {"format", required_argument, 0, 's'},
3611 {"help", no_argument, 0, 'h'},
3612 {"no-strip-underscores", no_argument, 0, 'n'},
3613 {"version", no_argument, 0, 'v'},
3614 {0, no_argument, 0, 0}
3617 /* More 'friendly' abort that prints the line and file.
3618 config.h can #define abort fancy_abort if you like that sort of thing. */
3623 fatal ("Internal gcc abort.");
3634 program_name = argv[0];
3636 strip_underscore = prepends_underscore;
3638 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3648 strip_underscore = 0;
3651 printf ("GNU %s version %s\n", program_name, program_version);
3654 strip_underscore = 1;
3657 if (strcmp (optarg, "gnu") == 0)
3659 current_demangling_style = gnu_demangling;
3661 else if (strcmp (optarg, "lucid") == 0)
3663 current_demangling_style = lucid_demangling;
3665 else if (strcmp (optarg, "arm") == 0)
3667 current_demangling_style = arm_demangling;
3671 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3672 program_name, optarg);
3681 for ( ; optind < argc; optind++)
3683 demangle_it (argv[optind]);
3692 /* Try to read a label. */
3693 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3695 if (i >= MBUF_SIZE-1)
3704 if (mbuffer[0] == '.')
3706 if (strip_underscore && mbuffer[skip_first] == '_')
3714 result = cplus_demangle (mbuffer + skip_first, flags);
3717 if (mbuffer[0] == '.')
3719 fputs (result, stdout);
3723 fputs (mbuffer, stdout);
3740 fprintf (stderr, "%s: %s\n", program_name, str);
3751 register char *value = (char *) malloc (size);
3753 fatal ("virtual memory exhausted");
3758 xrealloc (ptr, size)
3762 register char *value = (char *) realloc (ptr, size);
3764 fatal ("virtual memory exhausted");