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. */
40 #undef CURRENT_DEMANGLING_STYLE
41 #define CURRENT_DEMANGLING_STYLE work->options
43 extern char *xmalloc PARAMS((unsigned));
44 extern char *xrealloc PARAMS((char *, unsigned));
46 static const char *mystrstr PARAMS ((const char *, const char *));
52 register const char *p = s1;
53 register int len = strlen (s2);
55 for (; (p = strchr (p, *s2)) != 0; p++)
57 if (strncmp (p, s2, len) == 0)
65 /* In order to allow a single demangler executable to demangle strings
66 using various common values of CPLUS_MARKER, as well as any specific
67 one set at compile time, we maintain a string containing all the
68 commonly used ones, and check to see if the marker we are looking for
69 is in that string. CPLUS_MARKER is usually '$' on systems where the
70 assembler can deal with that. Where the assembler can't, it's usually
71 '.' (but on many systems '.' is used for other things). We put the
72 current defined CPLUS_MARKER first (which defaults to '$'), followed
73 by the next most common value, followed by an explicit '$' in case
74 the value of CPLUS_MARKER is not '$'.
76 We could avoid this if we could just get g++ to tell us what the actual
77 cplus marker character is as part of the debug information, perhaps by
78 ensuring that it is the character that terminates the gcc<n>_compiled
79 marker symbol (FIXME). */
81 #if !defined (CPLUS_MARKER)
82 #define CPLUS_MARKER '$'
85 enum demangling_styles current_demangling_style = gnu_demangling;
87 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
90 set_cplus_marker_for_demangling (ch)
93 cplus_markers[0] = ch;
96 /* Stuff that is shared between sub-routines.
97 Using a shared structure allows cplus_demangle to be reentrant. */
107 int static_type; /* A static member function */
108 int const_type; /* A const member function */
109 char **tmpl_argvec; /* Template function arguments. */
110 int ntmpl_args; /* The number of template function arguments. */
113 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
114 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
116 static const struct optable
122 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
123 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
124 {"new", " new", 0}, /* old (1.91, and 1.x) */
125 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
126 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
127 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
128 {"as", "=", DMGL_ANSI}, /* ansi */
129 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
130 {"eq", "==", DMGL_ANSI}, /* old, ansi */
131 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
132 {"gt", ">", DMGL_ANSI}, /* old, ansi */
133 {"le", "<=", DMGL_ANSI}, /* old, ansi */
134 {"lt", "<", DMGL_ANSI}, /* old, ansi */
135 {"plus", "+", 0}, /* old */
136 {"pl", "+", DMGL_ANSI}, /* ansi */
137 {"apl", "+=", DMGL_ANSI}, /* ansi */
138 {"minus", "-", 0}, /* old */
139 {"mi", "-", DMGL_ANSI}, /* ansi */
140 {"ami", "-=", DMGL_ANSI}, /* ansi */
141 {"mult", "*", 0}, /* old */
142 {"ml", "*", DMGL_ANSI}, /* ansi */
143 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
144 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
145 {"convert", "+", 0}, /* old (unary +) */
146 {"negate", "-", 0}, /* old (unary -) */
147 {"trunc_mod", "%", 0}, /* old */
148 {"md", "%", DMGL_ANSI}, /* ansi */
149 {"amd", "%=", DMGL_ANSI}, /* ansi */
150 {"trunc_div", "/", 0}, /* old */
151 {"dv", "/", DMGL_ANSI}, /* ansi */
152 {"adv", "/=", DMGL_ANSI}, /* ansi */
153 {"truth_andif", "&&", 0}, /* old */
154 {"aa", "&&", DMGL_ANSI}, /* ansi */
155 {"truth_orif", "||", 0}, /* old */
156 {"oo", "||", DMGL_ANSI}, /* ansi */
157 {"truth_not", "!", 0}, /* old */
158 {"nt", "!", DMGL_ANSI}, /* ansi */
159 {"postincrement","++", 0}, /* old */
160 {"pp", "++", DMGL_ANSI}, /* ansi */
161 {"postdecrement","--", 0}, /* old */
162 {"mm", "--", DMGL_ANSI}, /* ansi */
163 {"bit_ior", "|", 0}, /* old */
164 {"or", "|", DMGL_ANSI}, /* ansi */
165 {"aor", "|=", DMGL_ANSI}, /* ansi */
166 {"bit_xor", "^", 0}, /* old */
167 {"er", "^", DMGL_ANSI}, /* ansi */
168 {"aer", "^=", DMGL_ANSI}, /* ansi */
169 {"bit_and", "&", 0}, /* old */
170 {"ad", "&", DMGL_ANSI}, /* ansi */
171 {"aad", "&=", DMGL_ANSI}, /* ansi */
172 {"bit_not", "~", 0}, /* old */
173 {"co", "~", DMGL_ANSI}, /* ansi */
174 {"call", "()", 0}, /* old */
175 {"cl", "()", DMGL_ANSI}, /* ansi */
176 {"alshift", "<<", 0}, /* old */
177 {"ls", "<<", DMGL_ANSI}, /* ansi */
178 {"als", "<<=", DMGL_ANSI}, /* ansi */
179 {"arshift", ">>", 0}, /* old */
180 {"rs", ">>", DMGL_ANSI}, /* ansi */
181 {"ars", ">>=", DMGL_ANSI}, /* ansi */
182 {"component", "->", 0}, /* old */
183 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
184 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
185 {"indirect", "*", 0}, /* old */
186 {"method_call", "->()", 0}, /* old */
187 {"addr", "&", 0}, /* old (unary &) */
188 {"array", "[]", 0}, /* old */
189 {"vc", "[]", DMGL_ANSI}, /* ansi */
190 {"compound", ", ", 0}, /* old */
191 {"cm", ", ", DMGL_ANSI}, /* ansi */
192 {"cond", "?:", 0}, /* old */
193 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
194 {"max", ">?", 0}, /* old */
195 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
196 {"min", "<?", 0}, /* old */
197 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
198 {"nop", "", 0}, /* old (for operator=) */
199 {"rm", "->*", DMGL_ANSI} /* ansi */
203 typedef struct string /* Beware: these aren't required to be */
204 { /* '\0' terminated. */
205 char *b; /* pointer to start of string */
206 char *p; /* pointer after last character */
207 char *e; /* pointer after end of allocated space */
210 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
211 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
212 string_prepend(str, " ");}
213 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
214 string_append(str, " ");}
216 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
217 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
219 /* Prototypes for local functions */
222 mop_up PARAMS ((struct work_stuff *, string *, int));
226 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
230 demangle_template_template_parm PARAMS ((struct work_stuff *work,
231 const char **, string *));
234 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
238 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
242 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
245 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
248 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
252 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
255 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
258 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
261 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
264 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
267 arm_special PARAMS ((struct work_stuff *, const char **, string *));
270 string_need PARAMS ((string *, int));
273 string_delete PARAMS ((string *));
276 string_init PARAMS ((string *));
279 string_clear PARAMS ((string *));
283 string_empty PARAMS ((string *));
287 string_append PARAMS ((string *, const char *));
290 string_appends PARAMS ((string *, string *));
293 string_appendn PARAMS ((string *, const char *, int));
296 string_prepend PARAMS ((string *, const char *));
299 string_prependn PARAMS ((string *, const char *, int));
302 get_count PARAMS ((const char **, int *));
305 consume_count PARAMS ((const char **));
308 consume_count_with_underscores PARAMS ((const char**));
311 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
314 do_type PARAMS ((struct work_stuff *, const char **, string *));
317 do_arg PARAMS ((struct work_stuff *, const char **, string *));
320 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
324 remember_type PARAMS ((struct work_stuff *, const char *, int));
327 forget_types PARAMS ((struct work_stuff *));
330 string_prepends PARAMS ((string *, string *));
332 /* Translate count to integer, consuming tokens in the process.
333 Conversion terminates on the first non-digit character.
334 Trying to consume something that isn't a count results in
335 no consumption of input and a return of 0. */
343 while (isdigit (**type))
346 count += **type - '0';
353 /* Like consume_count, but for counts that are preceded and followed
354 by '_' if they are greater than 10. Also, -1 is returned for
355 failure, since 0 can be a valid value. */
358 consume_count_with_underscores (mangled)
359 const char **mangled;
363 if (**mangled == '_')
366 if (!isdigit (**mangled))
369 idx = consume_count (mangled);
370 if (**mangled != '_')
371 /* The trailing underscore was missing. */
378 if (**mangled < '0' || **mangled > '9')
381 idx = **mangled - '0';
389 cplus_demangle_opname (opname, result, options)
394 int len, i, len1, ret;
396 struct work_stuff work[1];
399 len = strlen(opname);
402 work->options = options;
404 if (opname[0] == '_' && opname[1] == '_'
405 && opname[2] == 'o' && opname[3] == 'p')
408 /* type conversion operator. */
410 if (do_type (work, &tem, &type))
412 strcat (result, "operator ");
413 strncat (result, type.b, type.p - type.b);
414 string_delete (&type);
418 else if (opname[0] == '_' && opname[1] == '_'
419 && opname[2] >= 'a' && opname[2] <= 'z'
420 && opname[3] >= 'a' && opname[3] <= 'z')
422 if (opname[4] == '\0')
425 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
427 if (strlen (optable[i].in) == 2
428 && memcmp (optable[i].in, opname + 2, 2) == 0)
430 strcat (result, "operator");
431 strcat (result, optable[i].out);
439 if (opname[2] == 'a' && opname[5] == '\0')
442 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
444 if (strlen (optable[i].in) == 3
445 && memcmp (optable[i].in, opname + 2, 3) == 0)
447 strcat (result, "operator");
448 strcat (result, optable[i].out);
459 && strchr (cplus_markers, opname[2]) != NULL)
461 /* see if it's an assignment expression */
462 if (len >= 10 /* op$assign_ */
463 && memcmp (opname + 3, "assign_", 7) == 0)
465 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
468 if (strlen (optable[i].in) == len1
469 && memcmp (optable[i].in, opname + 10, len1) == 0)
471 strcat (result, "operator");
472 strcat (result, optable[i].out);
473 strcat (result, "=");
481 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
484 if (strlen (optable[i].in) == len1
485 && memcmp (optable[i].in, opname + 3, len1) == 0)
487 strcat (result, "operator");
488 strcat (result, optable[i].out);
495 else if (len >= 5 && memcmp (opname, "type", 4) == 0
496 && strchr (cplus_markers, opname[4]) != NULL)
498 /* type conversion operator */
500 if (do_type (work, &tem, &type))
502 strcat (result, "operator ");
503 strncat (result, type.b, type.p - type.b);
504 string_delete (&type);
511 /* Takes operator name as e.g. "++" and returns mangled
512 operator name (e.g. "postincrement_expr"), or NULL if not found.
514 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
515 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
518 cplus_mangle_opname (opname, options)
525 len = strlen (opname);
526 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
528 if (strlen (optable[i].out) == len
529 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
530 && memcmp (optable[i].out, opname, len) == 0)
531 return optable[i].in;
536 /* char *cplus_demangle (const char *mangled, int options)
538 If MANGLED is a mangled function name produced by GNU C++, then
539 a pointer to a malloced string giving a C++ representation
540 of the name will be returned; otherwise NULL will be returned.
541 It is the caller's responsibility to free the string which
544 The OPTIONS arg may contain one or more of the following bits:
546 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
548 DMGL_PARAMS Function parameters are included.
552 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
553 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
554 cplus_demangle ("foo__1Ai", 0) => "A::foo"
556 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
557 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
558 cplus_demangle ("foo__1Afe", 0) => "A::foo"
560 Note that any leading underscores, or other such characters prepended by
561 the compilation system, are presumed to have already been stripped from
565 cplus_demangle (mangled, options)
571 struct work_stuff work[1];
572 char *demangled = NULL;
574 if ((mangled != NULL) && (*mangled != '\0'))
576 memset ((char *) work, 0, sizeof (work));
577 work -> options = options;
578 if ((work->options & DMGL_STYLE_MASK) == 0)
579 work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
583 /* First check to see if gnu style demangling is active and if the
584 string to be demangled contains a CPLUS_MARKER. If so, attempt to
585 recognize one of the gnu special forms rather than looking for a
586 standard prefix. In particular, don't worry about whether there
587 is a "__" string in the mangled string. Consider "_$_5__foo" for
590 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
592 success = gnu_special (work, &mangled, &decl);
596 success = demangle_prefix (work, &mangled, &decl);
598 if (success && (*mangled != '\0'))
600 success = demangle_signature (work, &mangled, &decl);
602 if (work->constructor == 2)
604 string_prepend(&decl, "global constructors keyed to ");
605 work->constructor = 0;
607 else if (work->destructor == 2)
609 string_prepend(&decl, "global destructors keyed to ");
610 work->destructor = 0;
612 demangled = mop_up (work, &decl, success);
618 mop_up (work, declp, success)
619 struct work_stuff *work;
623 char *demangled = NULL;
625 /* Discard the remembered types, if any. */
628 if (work -> typevec != NULL)
630 free ((char *) work -> typevec);
632 if (work->tmpl_argvec)
636 for (i = 0; i < work->ntmpl_args; i++)
637 if (work->tmpl_argvec[i])
638 free ((char*) work->tmpl_argvec[i]);
640 free ((char*) work->tmpl_argvec);
643 /* If demangling was successful, ensure that the demangled string is null
644 terminated and return it. Otherwise, free the demangling decl. */
648 string_delete (declp);
652 string_appendn (declp, "", 1);
653 demangled = declp -> b;
662 demangle_signature -- demangle the signature part of a mangled name
667 demangle_signature (struct work_stuff *work, const char **mangled,
672 Consume and demangle the signature portion of the mangled name.
674 DECLP is the string where demangled output is being built. At
675 entry it contains the demangled root name from the mangled name
676 prefix. I.E. either a demangled operator name or the root function
677 name. In some special cases, it may contain nothing.
679 *MANGLED points to the current unconsumed location in the mangled
680 name. As tokens are consumed and demangling is performed, the
681 pointer is updated to continuously point at the next token to
684 Demangling GNU style mangled names is nasty because there is no
685 explicit token that marks the start of the outermost function
689 demangle_signature (work, mangled, declp)
690 struct work_stuff *work;
691 const char **mangled;
697 int expect_return_type = 0;
698 const char *oldmangled = NULL;
702 while (success && (**mangled != '\0'))
707 oldmangled = *mangled;
708 success = demangle_qualified (work, mangled, declp, 1, 0);
711 remember_type (work, oldmangled, *mangled - oldmangled);
713 if (AUTO_DEMANGLING || GNU_DEMANGLING)
721 /* Static member function */
722 if (oldmangled == NULL)
724 oldmangled = *mangled;
727 work -> static_type = 1;
731 /* a const member function */
732 if (oldmangled == NULL)
734 oldmangled = *mangled;
737 work -> const_type = 1;
740 case '0': case '1': case '2': case '3': case '4':
741 case '5': case '6': case '7': case '8': case '9':
742 if (oldmangled == NULL)
744 oldmangled = *mangled;
746 success = demangle_class (work, mangled, declp);
749 remember_type (work, oldmangled, *mangled - oldmangled);
751 if (AUTO_DEMANGLING || GNU_DEMANGLING)
760 /* ARM style demangling includes a specific 'F' character after
761 the class name. For GNU style, it is just implied. So we can
762 safely just consume any 'F' at this point and be compatible
763 with either style. */
769 /* For lucid/ARM style we have to forget any types we might
770 have remembered up to this point, since they were not argument
771 types. GNU style considers all types seen as available for
772 back references. See comment in demangle_args() */
774 if (LUCID_DEMANGLING || ARM_DEMANGLING)
778 success = demangle_args (work, mangled, declp);
783 string_init(&trawname);
785 if (oldmangled == NULL)
787 oldmangled = *mangled;
789 success = demangle_template (work, mangled, &tname, &trawname, 1);
792 remember_type (work, oldmangled, *mangled - oldmangled);
794 string_append(&tname, (work -> options & DMGL_JAVA) ? "." : "::");
795 string_prepends(declp, &tname);
796 if (work -> destructor & 1)
798 string_prepend (&trawname, "~");
799 string_appends (declp, &trawname);
800 work->destructor -= 1;
802 if ((work->constructor & 1) || (work->destructor & 1))
804 string_appends (declp, &trawname);
805 work->constructor -= 1;
807 string_delete(&trawname);
808 string_delete(&tname);
814 if (GNU_DEMANGLING && expect_return_type)
816 /* Read the return type. */
818 string_init (&return_type);
821 success = do_type (work, mangled, &return_type);
822 APPEND_BLANK (&return_type);
824 string_prepends (declp, &return_type);
825 string_delete (&return_type);
829 /* At the outermost level, we cannot have a return type specified,
830 so if we run into another '_' at this point we are dealing with
831 a mangled name that is either bogus, or has been mangled by
832 some algorithm we don't know how to deal with. So just
833 reject the entire demangling. */
840 /* A G++ template function. Read the template arguments. */
841 success = demangle_template (work, mangled, declp, 0, 0);
842 if (!(work->constructor & 1))
843 expect_return_type = 1;
852 if (AUTO_DEMANGLING || GNU_DEMANGLING)
854 /* Assume we have stumbled onto the first outermost function
855 argument token, and start processing args. */
857 success = demangle_args (work, mangled, declp);
861 /* Non-GNU demanglers use a specific token to mark the start
862 of the outermost function argument tokens. Typically 'F',
863 for ARM-demangling, for example. So if we find something
864 we are not prepared for, it must be an error. */
870 if (AUTO_DEMANGLING || GNU_DEMANGLING)
873 if (success && expect_func)
876 success = demangle_args (work, mangled, declp);
877 /* Since template include the mangling of their return types,
878 we must set expect_func to 0 so that we don't try do
879 demangle more arguments the next time we get here. */
884 if (success && !func_done)
886 if (AUTO_DEMANGLING || GNU_DEMANGLING)
888 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
889 bar__3fooi is 'foo::bar(int)'. We get here when we find the
890 first case, and need to ensure that the '(void)' gets added to
891 the current declp. Note that with ARM, the first case
892 represents the name of a static data member 'foo::bar',
893 which is in the current declp, so we leave it alone. */
894 success = demangle_args (work, mangled, declp);
897 if (success && work -> static_type && PRINT_ARG_TYPES)
899 string_append (declp, " static");
901 if (success && work -> const_type && PRINT_ARG_TYPES)
903 string_append (declp, " const");
911 demangle_method_args (work, mangled, declp)
912 struct work_stuff *work;
913 const char **mangled;
918 if (work -> static_type)
920 string_append (declp, *mangled + 1);
921 *mangled += strlen (*mangled);
926 success = demangle_args (work, mangled, declp);
934 demangle_template_template_parm (work, mangled, tname)
935 struct work_stuff *work;
936 const char **mangled;
945 string_append (tname, "template <");
946 /* get size of template parameter list */
947 if (get_count (mangled, &r))
949 for (i = 0; i < r; i++)
953 string_append (tname, ", ");
956 /* Z for type parameters */
957 if (**mangled == 'Z')
960 string_append (tname, "class");
962 /* z for template parameters */
963 else if (**mangled == 'z')
967 demangle_template_template_parm (work, mangled, tname);
975 /* temp is initialized in do_type */
976 success = do_type (work, mangled, &temp);
979 string_appends (tname, &temp);
981 string_delete(&temp);
991 if (tname->p[-1] == '>')
992 string_append (tname, " ");
993 string_append (tname, "> class");
998 demangle_template (work, mangled, tname, trawname, is_type)
999 struct work_stuff *work;
1000 const char **mangled;
1018 int is_java_array = 0;
1025 /* get template name */
1026 if (**mangled == 'z')
1032 idx = consume_count_with_underscores (mangled);
1034 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1035 || consume_count_with_underscores (mangled) == -1)
1039 if (work->tmpl_argvec)
1041 string_append (tname, work->tmpl_argvec[idx]);
1043 string_append (trawname, work->tmpl_argvec[idx]);
1048 sprintf(buf, "T%d", idx);
1049 string_append (tname, buf);
1051 string_append (trawname, work->tmpl_argvec[idx]);
1056 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
1061 string_appendn (trawname, *mangled, r);
1062 is_java_array = (work -> options & DMGL_JAVA)
1063 && strncmp (*mangled, "JArray1Z", 8) == 0;
1064 if (! is_java_array)
1066 string_appendn (tname, *mangled, r);
1072 string_append (tname, "<");
1073 /* get size of template parameter list */
1074 if (!get_count (mangled, &r))
1080 /* Create an array for saving the template argument values. */
1081 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1082 work->ntmpl_args = r;
1083 for (i = 0; i < r; i++)
1084 work->tmpl_argvec[i] = 0;
1086 for (i = 0; i < r; i++)
1090 string_append (tname, ", ");
1092 /* Z for type parameters */
1093 if (**mangled == 'Z')
1096 /* temp is initialized in do_type */
1097 success = do_type (work, mangled, &temp);
1100 string_appends (tname, &temp);
1104 /* Save the template argument. */
1105 int len = temp.p - temp.b;
1106 work->tmpl_argvec[i] = xmalloc (len + 1);
1107 memcpy (work->tmpl_argvec[i], temp.b, len);
1108 work->tmpl_argvec[i][len] = '\0';
1111 string_delete(&temp);
1117 /* z for template parameters */
1118 else if (**mangled == 'z')
1122 success = demangle_template_template_parm (work, mangled, tname);
1125 && (r2 = consume_count (mangled)) > 0 && strlen (*mangled) >= r2)
1127 string_append (tname, " ");
1128 string_appendn (tname, *mangled, r2);
1131 /* Save the template argument. */
1133 work->tmpl_argvec[i] = xmalloc (len + 1);
1134 memcpy (work->tmpl_argvec[i], *mangled, len);
1135 work->tmpl_argvec[i][len] = '\0';
1149 /* otherwise, value parameter */
1157 /* temp is initialized in do_type */
1158 success = do_type (work, mangled, &temp);
1162 string_appends (s, &temp);
1165 string_delete(&temp);
1171 string_append (s, "=");
1182 while (*old_p && !done)
1189 done = is_pointer = 1;
1191 case 'C': /* const */
1192 case 'S': /* explicitly signed [char] */
1193 case 'U': /* unsigned */
1194 case 'V': /* volatile */
1195 case 'F': /* function */
1196 case 'M': /* member function */
1198 case 'J': /* complex */
1201 case 'Q': /* qualified name */
1202 done = is_integral = 1;
1204 case 'T': /* remembered type */
1207 case 'v': /* void */
1210 case 'x': /* long long */
1211 case 'l': /* long */
1213 case 's': /* short */
1214 case 'w': /* wchar_t */
1215 done = is_integral = 1;
1217 case 'b': /* bool */
1220 case 'c': /* char */
1223 case 'r': /* long double */
1224 case 'd': /* double */
1225 case 'f': /* float */
1229 /* it's probably user defined type, let's assume
1230 it's integral, it seems hard to figure out
1231 what it really is */
1232 done = is_integral = 1;
1235 if (**mangled == 'Y')
1237 /* The next argument is a template parameter. */
1241 idx = consume_count_with_underscores (mangled);
1243 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1244 || consume_count_with_underscores (mangled) == -1)
1251 if (work->tmpl_argvec)
1252 string_append (s, work->tmpl_argvec[idx]);
1256 sprintf(buf, "T%d", idx);
1257 string_append (s, buf);
1260 else if (is_integral)
1262 if (**mangled == 'm')
1264 string_appendn (s, "-", 1);
1267 while (isdigit (**mangled))
1269 string_appendn (s, *mangled, 1);
1277 if (**mangled == 'm')
1279 string_appendn (s, "-", 1);
1282 string_appendn (s, "'", 1);
1283 val = consume_count(mangled);
1293 string_appendn (s, &tmp[0], 1);
1294 string_appendn (s, "'", 1);
1298 int val = consume_count (mangled);
1300 string_appendn (s, "false", 5);
1302 string_appendn (s, "true", 4);
1308 if (**mangled == 'm')
1310 string_appendn (s, "-", 1);
1313 while (isdigit (**mangled))
1315 string_appendn (s, *mangled, 1);
1318 if (**mangled == '.') /* fraction */
1320 string_appendn (s, ".", 1);
1322 while (isdigit (**mangled))
1324 string_appendn (s, *mangled, 1);
1328 if (**mangled == 'e') /* exponent */
1330 string_appendn (s, "e", 1);
1332 while (isdigit (**mangled))
1334 string_appendn (s, *mangled, 1);
1339 else if (is_pointer)
1341 symbol_len = consume_count (mangled);
1342 if (symbol_len == 0)
1349 if (symbol_len == 0)
1350 string_appendn (s, "0", 1);
1353 char *p = xmalloc (symbol_len + 1), *q;
1354 strncpy (p, *mangled, symbol_len);
1355 p [symbol_len] = '\0';
1356 q = cplus_demangle (p, work->options);
1357 string_appendn (s, "&", 1);
1360 string_append (s, q);
1364 string_append (s, p);
1367 *mangled += symbol_len;
1371 int len = s->p - s->b;
1372 work->tmpl_argvec[i] = xmalloc (len + 1);
1373 memcpy (work->tmpl_argvec[i], s->b, len);
1374 work->tmpl_argvec[i][len] = '\0';
1376 string_appends (tname, s);
1384 string_append (tname, "[]");
1388 if (tname->p[-1] == '>')
1389 string_append (tname, " ");
1390 string_append (tname, ">");
1394 if (work -> static_type)
1396 string_append (declp, *mangled + 1);
1397 *mangled += strlen (*mangled);
1402 success = demangle_args (work, mangled, declp);
1410 arm_pt (work, mangled, n, anchor, args)
1411 struct work_stuff *work;
1412 const char *mangled;
1414 const char **anchor, **args;
1417 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1420 *args = *anchor + 6;
1421 len = consume_count (args);
1422 if (*args + len == mangled + n && **args == '_')
1432 demangle_arm_pt (work, mangled, n, declp)
1433 struct work_stuff *work;
1434 const char **mangled;
1440 const char *e = *mangled + n;
1443 if (arm_pt (work, *mangled, n, &p, &args))
1447 string_appendn (declp, *mangled, p - *mangled);
1448 string_append (declp, "<");
1449 /* should do error checking here */
1451 string_clear (&arg);
1452 do_type (work, &args, &arg);
1453 string_appends (declp, &arg);
1454 string_append (declp, ",");
1456 string_delete (&arg);
1458 string_append (declp, ">");
1462 string_appendn (declp, *mangled, n);
1468 demangle_class_name (work, mangled, declp)
1469 struct work_stuff *work;
1470 const char **mangled;
1476 n = consume_count (mangled);
1477 if (strlen (*mangled) >= n)
1479 demangle_arm_pt (work, mangled, n, declp);
1490 demangle_class -- demangle a mangled class sequence
1495 demangle_class (struct work_stuff *work, const char **mangled,
1500 DECLP points to the buffer into which demangling is being done.
1502 *MANGLED points to the current token to be demangled. On input,
1503 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1504 On exit, it points to the next token after the mangled class on
1505 success, or the first unconsumed token on failure.
1507 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1508 we are demangling a constructor or destructor. In this case
1509 we prepend "class::class" or "class::~class" to DECLP.
1511 Otherwise, we prepend "class::" to the current DECLP.
1513 Reset the constructor/destructor flags once they have been
1514 "consumed". This allows demangle_class to be called later during
1515 the same demangling, to do normal class demangling.
1517 Returns 1 if demangling is successful, 0 otherwise.
1522 demangle_class (work, mangled, declp)
1523 struct work_stuff *work;
1524 const char **mangled;
1530 string_init (&class_name);
1531 if (demangle_class_name (work, mangled, &class_name))
1533 if ((work->constructor & 1) || (work->destructor & 1))
1535 string_prepends (declp, &class_name);
1536 if (work -> destructor & 1)
1538 string_prepend (declp, "~");
1539 work -> destructor -= 1;
1543 work -> constructor -= 1;
1546 string_prepend (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1547 string_prepends (declp, &class_name);
1550 string_delete (&class_name);
1558 demangle_prefix -- consume the mangled name prefix and find signature
1563 demangle_prefix (struct work_stuff *work, const char **mangled,
1568 Consume and demangle the prefix of the mangled name.
1570 DECLP points to the string buffer into which demangled output is
1571 placed. On entry, the buffer is empty. On exit it contains
1572 the root function name, the demangled operator name, or in some
1573 special cases either nothing or the completely demangled result.
1575 MANGLED points to the current pointer into the mangled name. As each
1576 token of the mangled name is consumed, it is updated. Upon entry
1577 the current mangled name pointer points to the first character of
1578 the mangled name. Upon exit, it should point to the first character
1579 of the signature if demangling was successful, or to the first
1580 unconsumed character if demangling of the prefix was unsuccessful.
1582 Returns 1 on success, 0 otherwise.
1586 demangle_prefix (work, mangled, declp)
1587 struct work_stuff *work;
1588 const char **mangled;
1595 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1597 char *marker = strchr (cplus_markers, (*mangled)[8]);
1598 if (marker != NULL && *marker == (*mangled)[10])
1600 if ((*mangled)[9] == 'D')
1602 /* it's a GNU global destructor to be executed at program exit */
1604 work->destructor = 2;
1605 if (gnu_special (work, mangled, declp))
1608 else if ((*mangled)[9] == 'I')
1610 /* it's a GNU global constructor to be executed at program init */
1612 work->constructor = 2;
1613 if (gnu_special (work, mangled, declp))
1618 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1620 /* it's a ARM global destructor to be executed at program exit */
1622 work->destructor = 2;
1624 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1626 /* it's a ARM global constructor to be executed at program initial */
1628 work->constructor = 2;
1631 /* This block of code is a reduction in strength time optimization
1633 scan = mystrstr (*mangled, "__"); */
1639 scan = strchr (scan, '_');
1640 } while (scan != NULL && *++scan != '_');
1642 if (scan != NULL) --scan;
1647 /* We found a sequence of two or more '_', ensure that we start at
1648 the last pair in the sequence. */
1649 i = strspn (scan, "_");
1660 else if (work -> static_type)
1662 if (!isdigit (scan[0]) && (scan[0] != 't'))
1667 else if ((scan == *mangled)
1668 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
1669 || (scan[2] == 'H')))
1671 /* The ARM says nothing about the mangling of local variables.
1672 But cfront mangles local variables by prepending __<nesting_level>
1673 to them. As an extension to ARM demangling we handle this case. */
1674 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1676 *mangled = scan + 2;
1677 consume_count (mangled);
1678 string_append (declp, *mangled);
1679 *mangled += strlen (*mangled);
1684 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1685 names like __Q2_3foo3bar for nested type names. So don't accept
1686 this style of constructor for cfront demangling. A GNU
1687 style member-template constructor starts with 'H'. */
1688 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1689 work -> constructor += 1;
1690 *mangled = scan + 2;
1693 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1695 /* Mangled name starts with "__". Skip over any leading '_' characters,
1696 then find the next "__" that separates the prefix from the signature.
1698 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1699 || (arm_special (work, mangled, declp) == 0))
1701 while (*scan == '_')
1705 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1707 /* No separator (I.E. "__not_mangled"), or empty signature
1708 (I.E. "__not_mangled_either__") */
1713 demangle_function_name (work, mangled, declp, scan);
1717 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1719 /* Cfront-style parameterized type. Handled later as a signature. */
1723 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1725 else if (*(scan + 2) != '\0')
1727 /* Mangled name does not start with "__" but does have one somewhere
1728 in there with non empty stuff after it. Looks like a global
1730 demangle_function_name (work, mangled, declp, scan);
1734 /* Doesn't look like a mangled name */
1738 if (!success && (work->constructor == 2 || work->destructor == 2))
1740 string_append (declp, *mangled);
1741 *mangled += strlen (*mangled);
1751 gnu_special -- special handling of gnu mangled strings
1756 gnu_special (struct work_stuff *work, const char **mangled,
1762 Process some special GNU style mangling forms that don't fit
1763 the normal pattern. For example:
1765 _$_3foo (destructor for class foo)
1766 _vt$foo (foo virtual table)
1767 _vt$foo$bar (foo::bar virtual table)
1768 __vt_foo (foo virtual table, new style with thunks)
1769 _3foo$varname (static data member)
1770 _Q22rs2tu$vw (static data member)
1771 __t6vector1Zii (constructor with template)
1772 __thunk_4__$_7ostream (virtual function thunk)
1776 gnu_special (work, mangled, declp)
1777 struct work_stuff *work;
1778 const char **mangled;
1785 if ((*mangled)[0] == '_'
1786 && strchr (cplus_markers, (*mangled)[1]) != NULL
1787 && (*mangled)[2] == '_')
1789 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1791 work -> destructor += 1;
1793 else if ((*mangled)[0] == '_'
1794 && (((*mangled)[1] == '_'
1795 && (*mangled)[2] == 'v'
1796 && (*mangled)[3] == 't'
1797 && (*mangled)[4] == '_')
1798 || ((*mangled)[1] == 'v'
1799 && (*mangled)[2] == 't'
1800 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1802 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1803 and create the decl. Note that we consume the entire mangled
1804 input string, which means that demangle_signature has no work
1806 if ((*mangled)[2] == 'v')
1807 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1809 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1810 while (**mangled != '\0')
1812 p = strpbrk (*mangled, cplus_markers);
1816 success = demangle_qualified (work, mangled, declp, 0, 1);
1819 success = demangle_template (work, mangled, declp, 0, 1);
1822 if (isdigit(*mangled[0]))
1824 n = consume_count(mangled);
1828 n = strcspn (*mangled, cplus_markers);
1830 string_appendn (declp, *mangled, n);
1834 if (success && ((p == NULL) || (p == *mangled)))
1838 string_append (declp,
1839 (work -> options & DMGL_JAVA) ? "." : "::");
1850 string_append (declp, " virtual table");
1852 else if ((*mangled)[0] == '_'
1853 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1854 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1856 /* static data member, "_3foo$varname" for example */
1861 success = demangle_qualified (work, mangled, declp, 0, 1);
1864 success = demangle_template (work, mangled, declp, 0, 1);
1867 n = consume_count (mangled);
1868 string_appendn (declp, *mangled, n);
1871 if (success && (p == *mangled))
1873 /* Consumed everything up to the cplus_marker, append the
1876 string_append (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1877 n = strlen (*mangled);
1878 string_appendn (declp, *mangled, n);
1886 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1888 int delta = ((*mangled) += 8, consume_count (mangled));
1889 char *method = cplus_demangle (++*mangled, work->options);
1893 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1894 string_append (declp, buf);
1895 string_append (declp, method);
1897 n = strlen (*mangled);
1905 else if (strncmp (*mangled, "__t", 3) == 0
1906 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
1908 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
1913 success = demangle_qualified (work, mangled, declp, 0, 1);
1916 success = demangle_template (work, mangled, declp, 0, 1);
1919 success = demangle_fund_type (work, mangled, declp);
1922 if (success && **mangled != '\0')
1925 string_append (declp, p);
1938 arm_special -- special handling of ARM/lucid mangled strings
1943 arm_special (struct work_stuff *work, const char **mangled,
1949 Process some special ARM style mangling forms that don't fit
1950 the normal pattern. For example:
1952 __vtbl__3foo (foo virtual table)
1953 __vtbl__3foo__3bar (bar::foo virtual table)
1958 arm_special (work, mangled, declp)
1959 struct work_stuff *work;
1960 const char **mangled;
1967 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1969 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1970 and create the decl. Note that we consume the entire mangled
1971 input string, which means that demangle_signature has no work
1973 scan = *mangled + ARM_VTABLE_STRLEN;
1974 while (*scan != '\0') /* first check it can be demangled */
1976 n = consume_count (&scan);
1979 return (0); /* no good */
1982 if (scan[0] == '_' && scan[1] == '_')
1987 (*mangled) += ARM_VTABLE_STRLEN;
1988 while (**mangled != '\0')
1990 n = consume_count (mangled);
1991 string_prependn (declp, *mangled, n);
1993 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1995 string_prepend (declp, "::");
1999 string_append (declp, " virtual table");
2012 demangle_qualified -- demangle 'Q' qualified name strings
2017 demangle_qualified (struct work_stuff *, const char *mangled,
2018 string *result, int isfuncname, int append);
2022 Demangle a qualified name, such as "Q25Outer5Inner" which is
2023 the mangled form of "Outer::Inner". The demangled output is
2024 prepended or appended to the result string according to the
2025 state of the append flag.
2027 If isfuncname is nonzero, then the qualified name we are building
2028 is going to be used as a member function name, so if it is a
2029 constructor or destructor function, append an appropriate
2030 constructor or destructor name. I.E. for the above example,
2031 the result for use as a constructor is "Outer::Inner::Inner"
2032 and the result for use as a destructor is "Outer::Inner::~Inner".
2036 Numeric conversion is ASCII dependent (FIXME).
2041 demangle_qualified (work, mangled, result, isfuncname, append)
2042 struct work_stuff *work;
2043 const char **mangled;
2055 string_init (&temp);
2056 switch ((*mangled)[1])
2059 /* GNU mangled name with more than 9 classes. The count is preceded
2060 by an underscore (to distinguish it from the <= 9 case) and followed
2061 by an underscore. */
2063 qualifiers = atoi (p);
2064 if (!isdigit (*p) || *p == '0')
2067 /* Skip the digits. */
2068 while (isdigit (*p))
2086 /* The count is in a single digit. */
2087 num[0] = (*mangled)[1];
2089 qualifiers = atoi (num);
2091 /* If there is an underscore after the digit, skip it. This is
2092 said to be for ARM-qualified names, but the ARM makes no
2093 mention of such an underscore. Perhaps cfront uses one. */
2094 if ((*mangled)[2] == '_')
2109 /* Pick off the names and collect them in the temp buffer in the order
2110 in which they are found, separated by '::'. */
2112 while (qualifiers-- > 0)
2114 if (*mangled[0] == '_')
2115 *mangled = *mangled + 1;
2116 if (*mangled[0] == 't')
2118 success = demangle_template(work, mangled, &temp, 0, 1);
2119 if (!success) break;
2121 else if (*mangled[0] == 'X')
2123 success = do_type (work, mangled, &temp);
2124 if (!success) break;
2128 namelength = consume_count (mangled);
2129 if (strlen (*mangled) < namelength)
2131 /* Simple sanity check failed */
2135 string_appendn (&temp, *mangled, namelength);
2136 *mangled += namelength;
2140 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2144 /* If we are using the result as a function name, we need to append
2145 the appropriate '::' separated constructor or destructor name.
2146 We do this here because this is the most convenient place, where
2147 we already have a pointer to the name and the length of the name. */
2149 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
2151 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2152 if (work -> destructor & 1)
2154 string_append (&temp, "~");
2156 string_appendn (&temp, (*mangled) - namelength, namelength);
2159 /* Now either prepend the temp buffer to the result, or append it,
2160 depending upon the state of the append flag. */
2164 string_appends (result, &temp);
2168 if (!STRING_EMPTY (result))
2170 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2172 string_prepends (result, &temp);
2175 string_delete (&temp);
2183 get_count -- convert an ascii count to integer, consuming tokens
2188 get_count (const char **type, int *count)
2192 Return 0 if no conversion is performed, 1 if a string is converted.
2196 get_count (type, count)
2203 if (!isdigit (**type))
2209 *count = **type - '0';
2211 if (isdigit (**type))
2221 while (isdigit (*p));
2232 /* result will be initialised here; it will be freed on failure */
2235 do_type (work, mangled, result)
2236 struct work_stuff *work;
2237 const char **mangled;
2244 const char *remembered_type;
2248 string_init (&decl);
2249 string_init (result);
2253 while (success && !done)
2259 /* A pointer type */
2263 if (! (work -> options & DMGL_JAVA))
2264 string_prepend (&decl, "*");
2267 /* A reference type */
2270 string_prepend (&decl, "&");
2276 const char *p = ++(*mangled);
2278 string_prepend (&decl, "(");
2279 string_append (&decl, ")[");
2280 /* Copy anything up until the next underscore (the size of the
2282 while (**mangled && **mangled != '_')
2284 if (**mangled == '_')
2286 string_appendn (&decl, p, *mangled - p);
2287 string_append (&decl, "]");
2295 /* A back reference to a previously seen type */
2298 if (!get_count (mangled, &n) || n >= work -> ntypes)
2304 remembered_type = work -> typevec[n];
2305 mangled = &remembered_type;
2312 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2314 string_prepend (&decl, "(");
2315 string_append (&decl, ")");
2317 /* After picking off the function args, we expect to either find the
2318 function return type (preceded by an '_') or the end of the
2320 if (!demangle_args (work, mangled, &decl)
2321 || (**mangled != '_' && **mangled != '\0'))
2325 if (success && (**mangled == '_'))
2337 member = **mangled == 'M';
2339 if (!isdigit (**mangled) && **mangled != 't')
2345 string_append (&decl, ")");
2346 string_prepend (&decl, (work -> options & DMGL_JAVA) ? "." : "::");
2347 if (isdigit (**mangled))
2349 n = consume_count (mangled);
2350 if (strlen (*mangled) < n)
2355 string_prependn (&decl, *mangled, n);
2361 string_init (&temp);
2362 success = demangle_template (work, mangled, &temp, NULL, 1);
2365 string_prependn (&decl, temp.b, temp.p - temp.b);
2366 string_clear (&temp);
2371 string_prepend (&decl, "(");
2374 if (**mangled == 'C')
2379 if (**mangled == 'V')
2384 if (*(*mangled)++ != 'F')
2390 if ((member && !demangle_args (work, mangled, &decl))
2391 || **mangled != '_')
2397 if (! PRINT_ANSI_QUALIFIERS)
2403 APPEND_BLANK (&decl);
2404 string_append (&decl, "const");
2408 APPEND_BLANK (&decl);
2409 string_append (&decl, "volatile");
2420 if ((*mangled)[1] == 'P')
2423 if (PRINT_ANSI_QUALIFIERS)
2425 if (!STRING_EMPTY (&decl))
2427 string_prepend (&decl, " ");
2429 string_prepend (&decl, "const");
2445 /* A qualified name, such as "Outer::Inner". */
2447 success = demangle_qualified (work, mangled, result, 0, 1);
2452 /* A template parm. We substitute the corresponding argument. */
2457 idx = consume_count_with_underscores (mangled);
2460 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2461 || consume_count_with_underscores (mangled) == -1)
2467 if (work->tmpl_argvec)
2468 string_append (result, work->tmpl_argvec[idx]);
2472 sprintf(buf, "T%d", idx);
2473 string_append (result, buf);
2481 success = demangle_fund_type (work, mangled, result);
2487 if (!STRING_EMPTY (&decl))
2489 string_append (result, " ");
2490 string_appends (result, &decl);
2495 string_delete (result);
2497 string_delete (&decl);
2501 /* Given a pointer to a type string that represents a fundamental type
2502 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2503 string in which the demangled output is being built in RESULT, and
2504 the WORK structure, decode the types and add them to the result.
2509 "Sl" => "signed long"
2510 "CUs" => "const unsigned short"
2515 demangle_fund_type (work, mangled, result)
2516 struct work_stuff *work;
2517 const char **mangled;
2523 /* First pick off any type qualifiers. There can be more than one. */
2531 if (PRINT_ANSI_QUALIFIERS)
2533 APPEND_BLANK (result);
2534 string_append (result, "const");
2539 APPEND_BLANK (result);
2540 string_append (result, "unsigned");
2542 case 'S': /* signed char only */
2544 APPEND_BLANK (result);
2545 string_append (result, "signed");
2549 if (PRINT_ANSI_QUALIFIERS)
2551 APPEND_BLANK (result);
2552 string_append (result, "volatile");
2557 APPEND_BLANK (result);
2558 string_append (result, "__complex");
2566 /* Now pick off the fundamental type. There can be only one. */
2575 APPEND_BLANK (result);
2576 string_append (result, "void");
2580 APPEND_BLANK (result);
2581 string_append (result, "long long");
2585 APPEND_BLANK (result);
2586 string_append (result, "long");
2590 APPEND_BLANK (result);
2591 string_append (result, "int");
2595 APPEND_BLANK (result);
2596 string_append (result, "short");
2600 APPEND_BLANK (result);
2601 string_append (result, "bool");
2605 APPEND_BLANK (result);
2606 string_append (result, "char");
2610 APPEND_BLANK (result);
2611 string_append (result, "wchar_t");
2615 APPEND_BLANK (result);
2616 string_append (result, "long double");
2620 APPEND_BLANK (result);
2621 string_append (result, "double");
2625 APPEND_BLANK (result);
2626 string_append (result, "float");
2630 if (!isdigit (**mangled))
2636 /* An explicit type, such as "6mytype" or "7integer" */
2647 APPEND_BLANK (result);
2648 if (!demangle_class_name (work, mangled, result)) {
2654 success = demangle_template(work,mangled, result, 0, 1);
2664 /* `result' will be initialized in do_type; it will be freed on failure */
2667 do_arg (work, mangled, result)
2668 struct work_stuff *work;
2669 const char **mangled;
2672 const char *start = *mangled;
2674 if (!do_type (work, mangled, result))
2680 remember_type (work, start, *mangled - start);
2686 remember_type (work, start, len)
2687 struct work_stuff *work;
2693 if (work -> ntypes >= work -> typevec_size)
2695 if (work -> typevec_size == 0)
2697 work -> typevec_size = 3;
2699 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2703 work -> typevec_size *= 2;
2705 = (char **) xrealloc ((char *)work -> typevec,
2706 sizeof (char *) * work -> typevec_size);
2709 tem = xmalloc (len + 1);
2710 memcpy (tem, start, len);
2712 work -> typevec[work -> ntypes++] = tem;
2715 /* Forget the remembered types, but not the type vector itself. */
2719 struct work_stuff *work;
2723 while (work -> ntypes > 0)
2725 i = --(work -> ntypes);
2726 if (work -> typevec[i] != NULL)
2728 free (work -> typevec[i]);
2729 work -> typevec[i] = NULL;
2734 /* Process the argument list part of the signature, after any class spec
2735 has been consumed, as well as the first 'F' character (if any). For
2738 "__als__3fooRT0" => process "RT0"
2739 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2741 DECLP must be already initialised, usually non-empty. It won't be freed
2744 Note that g++ differs significantly from ARM and lucid style mangling
2745 with regards to references to previously seen types. For example, given
2746 the source fragment:
2750 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2753 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2754 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2756 g++ produces the names:
2761 while lcc (and presumably other ARM style compilers as well) produces:
2763 foo__FiR3fooT1T2T1T2
2764 __ct__3fooFiR3fooT1T2T1T2
2766 Note that g++ bases it's type numbers starting at zero and counts all
2767 previously seen types, while lucid/ARM bases it's type numbers starting
2768 at one and only considers types after it has seen the 'F' character
2769 indicating the start of the function args. For lucid/ARM style, we
2770 account for this difference by discarding any previously seen types when
2771 we see the 'F' character, and subtracting one from the type number
2777 demangle_args (work, mangled, declp)
2778 struct work_stuff *work;
2779 const char **mangled;
2789 if (PRINT_ARG_TYPES)
2791 string_append (declp, "(");
2792 if (**mangled == '\0')
2794 string_append (declp, "void");
2798 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2800 if ((**mangled == 'N') || (**mangled == 'T'))
2802 temptype = *(*mangled)++;
2804 if (temptype == 'N')
2806 if (!get_count (mangled, &r))
2815 if (ARM_DEMANGLING && work -> ntypes >= 10)
2817 /* If we have 10 or more types we might have more than a 1 digit
2818 index so we'll have to consume the whole count here. This
2819 will lose if the next thing is a type name preceded by a
2820 count but it's impossible to demangle that case properly
2821 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2822 Pc, ...)" or "(..., type12, char *, ...)" */
2823 if ((t = consume_count(mangled)) == 0)
2830 if (!get_count (mangled, &t))
2835 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2839 /* Validate the type index. Protect against illegal indices from
2840 malformed type strings. */
2841 if ((t < 0) || (t >= work -> ntypes))
2847 tem = work -> typevec[t];
2848 if (need_comma && PRINT_ARG_TYPES)
2850 string_append (declp, ", ");
2852 if (!do_arg (work, &tem, &arg))
2856 if (PRINT_ARG_TYPES)
2858 string_appends (declp, &arg);
2860 string_delete (&arg);
2866 if (need_comma & PRINT_ARG_TYPES)
2868 string_append (declp, ", ");
2870 if (!do_arg (work, mangled, &arg))
2874 if (PRINT_ARG_TYPES)
2876 string_appends (declp, &arg);
2878 string_delete (&arg);
2883 if (**mangled == 'e')
2886 if (PRINT_ARG_TYPES)
2890 string_append (declp, ",");
2892 string_append (declp, "...");
2896 if (PRINT_ARG_TYPES)
2898 string_append (declp, ")");
2904 demangle_function_name (work, mangled, declp, scan)
2905 struct work_stuff *work;
2906 const char **mangled;
2915 string_appendn (declp, (*mangled), scan - (*mangled));
2916 string_need (declp, 1);
2917 *(declp -> p) = '\0';
2919 /* Consume the function name, including the "__" separating the name
2920 from the signature. We are guaranteed that SCAN points to the
2923 (*mangled) = scan + 2;
2925 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2928 /* See if we have an ARM style constructor or destructor operator.
2929 If so, then just record it, clear the decl, and return.
2930 We can't build the actual constructor/destructor decl until later,
2931 when we recover the class name from the signature. */
2933 if (strcmp (declp -> b, "__ct") == 0)
2935 work -> constructor += 1;
2936 string_clear (declp);
2939 else if (strcmp (declp -> b, "__dt") == 0)
2941 work -> destructor += 1;
2942 string_clear (declp);
2947 if (declp->p - declp->b >= 3
2948 && declp->b[0] == 'o'
2949 && declp->b[1] == 'p'
2950 && strchr (cplus_markers, declp->b[2]) != NULL)
2952 /* see if it's an assignment expression */
2953 if (declp->p - declp->b >= 10 /* op$assign_ */
2954 && memcmp (declp->b + 3, "assign_", 7) == 0)
2956 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2958 len = declp->p - declp->b - 10;
2959 if (strlen (optable[i].in) == len
2960 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2962 string_clear (declp);
2963 string_append (declp, "operator");
2964 string_append (declp, optable[i].out);
2965 string_append (declp, "=");
2972 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2974 int len = declp->p - declp->b - 3;
2975 if (strlen (optable[i].in) == len
2976 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2978 string_clear (declp);
2979 string_append (declp, "operator");
2980 string_append (declp, optable[i].out);
2986 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2987 && strchr (cplus_markers, declp->b[4]) != NULL)
2989 /* type conversion operator */
2991 if (do_type (work, &tem, &type))
2993 string_clear (declp);
2994 string_append (declp, "operator ");
2995 string_appends (declp, &type);
2996 string_delete (&type);
2999 else if (declp->b[0] == '_' && declp->b[1] == '_'
3000 && declp->b[2] == 'o' && declp->b[3] == 'p')
3003 /* type conversion operator. */
3005 if (do_type (work, &tem, &type))
3007 string_clear (declp);
3008 string_append (declp, "operator ");
3009 string_appends (declp, &type);
3010 string_delete (&type);
3013 else if (declp->b[0] == '_' && declp->b[1] == '_'
3014 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
3015 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
3017 if (declp->b[4] == '\0')
3020 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3022 if (strlen (optable[i].in) == 2
3023 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
3025 string_clear (declp);
3026 string_append (declp, "operator");
3027 string_append (declp, optable[i].out);
3034 if (declp->b[2] == 'a' && declp->b[5] == '\0')
3037 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3039 if (strlen (optable[i].in) == 3
3040 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
3042 string_clear (declp);
3043 string_append (declp, "operator");
3044 string_append (declp, optable[i].out);
3053 /* a mini string-handling package */
3068 s->p = s->b = xmalloc (n);
3071 else if (s->e - s->p < n)
3076 s->b = xrealloc (s->b, n);
3089 s->b = s->e = s->p = NULL;
3097 s->b = s->p = s->e = NULL;
3113 return (s->b == s->p);
3119 string_append (p, s)
3124 if (s == NULL || *s == '\0')
3128 memcpy (p->p, s, n);
3133 string_appends (p, s)
3142 memcpy (p->p, s->b, n);
3148 string_appendn (p, s, n)
3156 memcpy (p->p, s, n);
3162 string_prepend (p, s)
3166 if (s != NULL && *s != '\0')
3168 string_prependn (p, s, strlen (s));
3173 string_prepends (p, s)
3178 string_prependn (p, s->b, s->p - s->b);
3183 string_prependn (p, s, n)
3193 for (q = p->p - 1; q >= p->b; q--)
3197 memcpy (p->b, s, n);
3202 /* To generate a standalone demangler program for testing purposes,
3203 just compile and link this file with -DMAIN and libiberty.a. When
3204 run, it demangles each command line arg, or each stdin string, and
3205 prints the result on stdout. */
3211 static char *program_name;
3212 static char *program_version = VERSION;
3213 static int flags = DMGL_PARAMS | DMGL_ANSI;
3215 static void demangle_it PARAMS ((char *));
3216 static void usage PARAMS ((FILE *, int));
3217 static void fatal PARAMS ((char *));
3220 demangle_it (mangled_name)
3225 result = cplus_demangle (mangled_name, flags);
3228 printf ("%s\n", mangled_name);
3232 printf ("%s\n", result);
3238 usage (stream, status)
3243 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3244 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3245 [--help] [--version] [arg...]\n",
3250 #define MBUF_SIZE 512
3251 char mbuffer[MBUF_SIZE];
3253 /* Defined in the automatically-generated underscore.c. */
3254 extern int prepends_underscore;
3256 int strip_underscore = 0;
3258 static struct option long_options[] = {
3259 {"strip-underscores", no_argument, 0, '_'},
3260 {"format", required_argument, 0, 's'},
3261 {"help", no_argument, 0, 'h'},
3262 {"java", no_argument, 0, 'j'},
3263 {"no-strip-underscores", no_argument, 0, 'n'},
3264 {"version", no_argument, 0, 'v'},
3265 {0, no_argument, 0, 0}
3268 /* More 'friendly' abort that prints the line and file.
3269 config.h can #define abort fancy_abort if you like that sort of thing. */
3274 fatal ("Internal gcc abort.");
3285 program_name = argv[0];
3287 strip_underscore = prepends_underscore;
3289 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3299 strip_underscore = 0;
3302 printf ("GNU %s version %s\n", program_name, program_version);
3305 strip_underscore = 1;
3311 if (strcmp (optarg, "gnu") == 0)
3313 current_demangling_style = gnu_demangling;
3315 else if (strcmp (optarg, "lucid") == 0)
3317 current_demangling_style = lucid_demangling;
3319 else if (strcmp (optarg, "arm") == 0)
3321 current_demangling_style = arm_demangling;
3325 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3326 program_name, optarg);
3335 for ( ; optind < argc; optind++)
3337 demangle_it (argv[optind]);
3346 /* Try to read a label. */
3347 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3349 if (i >= MBUF_SIZE-1)
3358 if (mbuffer[0] == '.')
3360 if (strip_underscore && mbuffer[skip_first] == '_')
3368 result = cplus_demangle (mbuffer + skip_first, flags);
3371 if (mbuffer[0] == '.')
3373 fputs (result, stdout);
3377 fputs (mbuffer, stdout);
3394 fprintf (stderr, "%s: %s\n", program_name, str);
3405 register char *value = (char *) malloc (size);
3407 fatal ("virtual memory exhausted");
3412 xrealloc (ptr, size)
3416 register char *value = (char *) realloc (ptr, size);
3418 fatal ("virtual memory exhausted");