1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 This file is part of the libiberty library.
7 Libiberty is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 Libiberty is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with libiberty; see the file COPYING.LIB. If
19 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
24 This file imports xmalloc and xrealloc, which are like malloc and
25 realloc except that they generate a fatal error if there is no
28 /* This file lives in both GCC and libiberty. When making changes, please
29 try not to break either. */
36 #undef CURRENT_DEMANGLING_STYLE
37 #define CURRENT_DEMANGLING_STYLE work->options
39 extern char *xmalloc PARAMS((unsigned));
40 extern char *xrealloc PARAMS((char *, unsigned));
42 static const char *mystrstr PARAMS ((const char *, const char *));
48 register const char *p = s1;
49 register int len = strlen (s2);
51 for (; (p = strchr (p, *s2)) != 0; p++)
53 if (strncmp (p, s2, len) == 0)
61 /* In order to allow a single demangler executable to demangle strings
62 using various common values of CPLUS_MARKER, as well as any specific
63 one set at compile time, we maintain a string containing all the
64 commonly used ones, and check to see if the marker we are looking for
65 is in that string. CPLUS_MARKER is usually '$' on systems where the
66 assembler can deal with that. Where the assembler can't, it's usually
67 '.' (but on many systems '.' is used for other things). We put the
68 current defined CPLUS_MARKER first (which defaults to '$'), followed
69 by the next most common value, followed by an explicit '$' in case
70 the value of CPLUS_MARKER is not '$'.
72 We could avoid this if we could just get g++ to tell us what the actual
73 cplus marker character is as part of the debug information, perhaps by
74 ensuring that it is the character that terminates the gcc<n>_compiled
75 marker symbol (FIXME). */
77 #if !defined (CPLUS_MARKER)
78 #define CPLUS_MARKER '$'
81 enum demangling_styles current_demangling_style = gnu_demangling;
83 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
86 set_cplus_marker_for_demangling (ch)
89 cplus_markers[0] = ch;
92 /* Stuff that is shared between sub-routines.
93 Using a shared structure allows cplus_demangle to be reentrant. */
103 int static_type; /* A static member function */
104 int const_type; /* A const member function */
105 char **tmpl_argvec; /* Template function arguments. */
106 int ntmpl_args; /* The number of template function arguments. */
109 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
110 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
112 static const struct optable
118 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
119 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
120 {"new", " new", 0}, /* old (1.91, and 1.x) */
121 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
122 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
123 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
124 {"as", "=", DMGL_ANSI}, /* ansi */
125 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
126 {"eq", "==", DMGL_ANSI}, /* old, ansi */
127 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
128 {"gt", ">", DMGL_ANSI}, /* old, ansi */
129 {"le", "<=", DMGL_ANSI}, /* old, ansi */
130 {"lt", "<", DMGL_ANSI}, /* old, ansi */
131 {"plus", "+", 0}, /* old */
132 {"pl", "+", DMGL_ANSI}, /* ansi */
133 {"apl", "+=", DMGL_ANSI}, /* ansi */
134 {"minus", "-", 0}, /* old */
135 {"mi", "-", DMGL_ANSI}, /* ansi */
136 {"ami", "-=", DMGL_ANSI}, /* ansi */
137 {"mult", "*", 0}, /* old */
138 {"ml", "*", DMGL_ANSI}, /* ansi */
139 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
140 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
141 {"convert", "+", 0}, /* old (unary +) */
142 {"negate", "-", 0}, /* old (unary -) */
143 {"trunc_mod", "%", 0}, /* old */
144 {"md", "%", DMGL_ANSI}, /* ansi */
145 {"amd", "%=", DMGL_ANSI}, /* ansi */
146 {"trunc_div", "/", 0}, /* old */
147 {"dv", "/", DMGL_ANSI}, /* ansi */
148 {"adv", "/=", DMGL_ANSI}, /* ansi */
149 {"truth_andif", "&&", 0}, /* old */
150 {"aa", "&&", DMGL_ANSI}, /* ansi */
151 {"truth_orif", "||", 0}, /* old */
152 {"oo", "||", DMGL_ANSI}, /* ansi */
153 {"truth_not", "!", 0}, /* old */
154 {"nt", "!", DMGL_ANSI}, /* ansi */
155 {"postincrement","++", 0}, /* old */
156 {"pp", "++", DMGL_ANSI}, /* ansi */
157 {"postdecrement","--", 0}, /* old */
158 {"mm", "--", DMGL_ANSI}, /* ansi */
159 {"bit_ior", "|", 0}, /* old */
160 {"or", "|", DMGL_ANSI}, /* ansi */
161 {"aor", "|=", DMGL_ANSI}, /* ansi */
162 {"bit_xor", "^", 0}, /* old */
163 {"er", "^", DMGL_ANSI}, /* ansi */
164 {"aer", "^=", DMGL_ANSI}, /* ansi */
165 {"bit_and", "&", 0}, /* old */
166 {"ad", "&", DMGL_ANSI}, /* ansi */
167 {"aad", "&=", DMGL_ANSI}, /* ansi */
168 {"bit_not", "~", 0}, /* old */
169 {"co", "~", DMGL_ANSI}, /* ansi */
170 {"call", "()", 0}, /* old */
171 {"cl", "()", DMGL_ANSI}, /* ansi */
172 {"alshift", "<<", 0}, /* old */
173 {"ls", "<<", DMGL_ANSI}, /* ansi */
174 {"als", "<<=", DMGL_ANSI}, /* ansi */
175 {"arshift", ">>", 0}, /* old */
176 {"rs", ">>", DMGL_ANSI}, /* ansi */
177 {"ars", ">>=", DMGL_ANSI}, /* ansi */
178 {"component", "->", 0}, /* old */
179 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
180 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
181 {"indirect", "*", 0}, /* old */
182 {"method_call", "->()", 0}, /* old */
183 {"addr", "&", 0}, /* old (unary &) */
184 {"array", "[]", 0}, /* old */
185 {"vc", "[]", DMGL_ANSI}, /* ansi */
186 {"compound", ", ", 0}, /* old */
187 {"cm", ", ", DMGL_ANSI}, /* ansi */
188 {"cond", "?:", 0}, /* old */
189 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
190 {"max", ">?", 0}, /* old */
191 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
192 {"min", "<?", 0}, /* old */
193 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
194 {"nop", "", 0}, /* old (for operator=) */
195 {"rm", "->*", DMGL_ANSI} /* ansi */
199 typedef struct string /* Beware: these aren't required to be */
200 { /* '\0' terminated. */
201 char *b; /* pointer to start of string */
202 char *p; /* pointer after last character */
203 char *e; /* pointer after end of allocated space */
206 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
207 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
208 string_prepend(str, " ");}
209 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
210 string_append(str, " ");}
212 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
213 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
215 /* Prototypes for local functions */
218 mop_up PARAMS ((struct work_stuff *, string *, int));
222 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
226 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
230 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
234 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
237 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
240 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
244 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
247 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
250 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
253 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
256 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
259 arm_special PARAMS ((struct work_stuff *, const char **, string *));
262 string_need PARAMS ((string *, int));
265 string_delete PARAMS ((string *));
268 string_init PARAMS ((string *));
271 string_clear PARAMS ((string *));
275 string_empty PARAMS ((string *));
279 string_append PARAMS ((string *, const char *));
282 string_appends PARAMS ((string *, string *));
285 string_appendn PARAMS ((string *, const char *, int));
288 string_prepend PARAMS ((string *, const char *));
291 string_prependn PARAMS ((string *, const char *, int));
294 get_count PARAMS ((const char **, int *));
297 consume_count PARAMS ((const char **));
300 consume_count_with_underscores PARAMS ((const char**));
303 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
306 do_type PARAMS ((struct work_stuff *, const char **, string *));
309 do_arg PARAMS ((struct work_stuff *, const char **, string *));
312 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
316 remember_type PARAMS ((struct work_stuff *, const char *, int));
319 forget_types PARAMS ((struct work_stuff *));
322 string_prepends PARAMS ((string *, string *));
324 /* Translate count to integer, consuming tokens in the process.
325 Conversion terminates on the first non-digit character.
326 Trying to consume something that isn't a count results in
327 no consumption of input and a return of 0. */
335 while (isdigit (**type))
338 count += **type - '0';
345 /* Like consume_count, but for counts that are preceeded and followed
346 by '_' if they are greater than 10. Also, -1 is returned for
347 failure, since 0 can be a valid value. */
350 consume_count_with_underscores (mangled)
351 const char **mangled;
355 if (**mangled == '_')
358 if (!isdigit (**mangled))
361 idx = consume_count (mangled);
362 if (**mangled != '_')
363 /* The trailing underscore was missing. */
370 if (**mangled < '0' || **mangled > '9')
373 idx = **mangled - '0';
381 cplus_demangle_opname (opname, result, options)
386 int len, i, len1, ret;
388 struct work_stuff work[1];
391 len = strlen(opname);
394 work->options = options;
396 if (opname[0] == '_' && opname[1] == '_'
397 && opname[2] == 'o' && opname[3] == 'p')
400 /* type conversion operator. */
402 if (do_type (work, &tem, &type))
404 strcat (result, "operator ");
405 strncat (result, type.b, type.p - type.b);
406 string_delete (&type);
410 else if (opname[0] == '_' && opname[1] == '_'
411 && opname[2] >= 'a' && opname[2] <= 'z'
412 && opname[3] >= 'a' && opname[3] <= 'z')
414 if (opname[4] == '\0')
417 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
419 if (strlen (optable[i].in) == 2
420 && memcmp (optable[i].in, opname + 2, 2) == 0)
422 strcat (result, "operator");
423 strcat (result, optable[i].out);
431 if (opname[2] == 'a' && opname[5] == '\0')
434 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
436 if (strlen (optable[i].in) == 3
437 && memcmp (optable[i].in, opname + 2, 3) == 0)
439 strcat (result, "operator");
440 strcat (result, optable[i].out);
451 && strchr (cplus_markers, opname[2]) != NULL)
453 /* see if it's an assignment expression */
454 if (len >= 10 /* op$assign_ */
455 && memcmp (opname + 3, "assign_", 7) == 0)
457 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
460 if (strlen (optable[i].in) == len1
461 && memcmp (optable[i].in, opname + 10, len1) == 0)
463 strcat (result, "operator");
464 strcat (result, optable[i].out);
465 strcat (result, "=");
473 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
476 if (strlen (optable[i].in) == len1
477 && memcmp (optable[i].in, opname + 3, len1) == 0)
479 strcat (result, "operator");
480 strcat (result, optable[i].out);
487 else if (len >= 5 && memcmp (opname, "type", 4) == 0
488 && strchr (cplus_markers, opname[4]) != NULL)
490 /* type conversion operator */
492 if (do_type (work, &tem, &type))
494 strcat (result, "operator ");
495 strncat (result, type.b, type.p - type.b);
496 string_delete (&type);
503 /* Takes operator name as e.g. "++" and returns mangled
504 operator name (e.g. "postincrement_expr"), or NULL if not found.
506 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
507 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
510 cplus_mangle_opname (opname, options)
517 len = strlen (opname);
518 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
520 if (strlen (optable[i].out) == len
521 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
522 && memcmp (optable[i].out, opname, len) == 0)
523 return optable[i].in;
528 /* char *cplus_demangle (const char *mangled, int options)
530 If MANGLED is a mangled function name produced by GNU C++, then
531 a pointer to a malloced string giving a C++ representation
532 of the name will be returned; otherwise NULL will be returned.
533 It is the caller's responsibility to free the string which
536 The OPTIONS arg may contain one or more of the following bits:
538 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
540 DMGL_PARAMS Function parameters are included.
544 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
545 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
546 cplus_demangle ("foo__1Ai", 0) => "A::foo"
548 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
549 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
550 cplus_demangle ("foo__1Afe", 0) => "A::foo"
552 Note that any leading underscores, or other such characters prepended by
553 the compilation system, are presumed to have already been stripped from
557 cplus_demangle (mangled, options)
563 struct work_stuff work[1];
564 char *demangled = NULL;
566 if ((mangled != NULL) && (*mangled != '\0'))
568 memset ((char *) work, 0, sizeof (work));
569 work -> options = options;
570 if ((work->options & DMGL_STYLE_MASK) == 0)
571 work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
575 /* First check to see if gnu style demangling is active and if the
576 string to be demangled contains a CPLUS_MARKER. If so, attempt to
577 recognize one of the gnu special forms rather than looking for a
578 standard prefix. In particular, don't worry about whether there
579 is a "__" string in the mangled string. Consider "_$_5__foo" for
582 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
584 success = gnu_special (work, &mangled, &decl);
588 success = demangle_prefix (work, &mangled, &decl);
590 if (success && (*mangled != '\0'))
592 success = demangle_signature (work, &mangled, &decl);
594 if (work->constructor == 2)
596 string_prepend(&decl, "global constructors keyed to ");
597 work->constructor = 0;
599 else if (work->destructor == 2)
601 string_prepend(&decl, "global destructors keyed to ");
602 work->destructor = 0;
604 demangled = mop_up (work, &decl, success);
610 mop_up (work, declp, success)
611 struct work_stuff *work;
615 char *demangled = NULL;
617 /* Discard the remembered types, if any. */
620 if (work -> typevec != NULL)
622 free ((char *) work -> typevec);
624 if (work->tmpl_argvec)
628 for (i = 0; i < work->ntmpl_args; i++)
629 if (work->tmpl_argvec[i])
630 free ((char*) work->tmpl_argvec[i]);
632 free ((char*) work->tmpl_argvec);
635 /* If demangling was successful, ensure that the demangled string is null
636 terminated and return it. Otherwise, free the demangling decl. */
640 string_delete (declp);
644 string_appendn (declp, "", 1);
645 demangled = declp -> b;
654 demangle_signature -- demangle the signature part of a mangled name
659 demangle_signature (struct work_stuff *work, const char **mangled,
664 Consume and demangle the signature portion of the mangled name.
666 DECLP is the string where demangled output is being built. At
667 entry it contains the demangled root name from the mangled name
668 prefix. I.E. either a demangled operator name or the root function
669 name. In some special cases, it may contain nothing.
671 *MANGLED points to the current unconsumed location in the mangled
672 name. As tokens are consumed and demangling is performed, the
673 pointer is updated to continuously point at the next token to
676 Demangling GNU style mangled names is nasty because there is no
677 explicit token that marks the start of the outermost function
681 demangle_signature (work, mangled, declp)
682 struct work_stuff *work;
683 const char **mangled;
689 int expect_return_type = 0;
690 const char *oldmangled = NULL;
694 while (success && (**mangled != '\0'))
699 oldmangled = *mangled;
700 success = demangle_qualified (work, mangled, declp, 1, 0);
703 remember_type (work, oldmangled, *mangled - oldmangled);
705 if (AUTO_DEMANGLING || GNU_DEMANGLING)
713 /* Static member function */
714 if (oldmangled == NULL)
716 oldmangled = *mangled;
719 work -> static_type = 1;
723 /* a const member function */
724 if (oldmangled == NULL)
726 oldmangled = *mangled;
729 work -> const_type = 1;
732 case '0': case '1': case '2': case '3': case '4':
733 case '5': case '6': case '7': case '8': case '9':
734 if (oldmangled == NULL)
736 oldmangled = *mangled;
738 success = demangle_class (work, mangled, declp);
741 remember_type (work, oldmangled, *mangled - oldmangled);
743 if (AUTO_DEMANGLING || GNU_DEMANGLING)
752 /* ARM style demangling includes a specific 'F' character after
753 the class name. For GNU style, it is just implied. So we can
754 safely just consume any 'F' at this point and be compatible
755 with either style. */
761 /* For lucid/ARM style we have to forget any types we might
762 have remembered up to this point, since they were not argument
763 types. GNU style considers all types seen as available for
764 back references. See comment in demangle_args() */
766 if (LUCID_DEMANGLING || ARM_DEMANGLING)
770 success = demangle_args (work, mangled, declp);
775 string_init(&trawname);
777 if (oldmangled == NULL)
779 oldmangled = *mangled;
781 success = demangle_template (work, mangled, &tname, &trawname, 1);
784 remember_type (work, oldmangled, *mangled - oldmangled);
786 string_append(&tname, (work -> options & DMGL_JAVA) ? "." : "::");
787 string_prepends(declp, &tname);
788 if (work -> destructor & 1)
790 string_prepend (&trawname, "~");
791 string_appends (declp, &trawname);
792 work->destructor -= 1;
794 if ((work->constructor & 1) || (work->destructor & 1))
796 string_appends (declp, &trawname);
797 work->constructor -= 1;
799 string_delete(&trawname);
800 string_delete(&tname);
806 if (GNU_DEMANGLING && expect_return_type)
808 /* Read the return type. */
810 string_init (&return_type);
813 success = do_type (work, mangled, &return_type);
814 APPEND_BLANK (&return_type);
816 string_prepends (declp, &return_type);
817 string_delete (&return_type);
821 /* At the outermost level, we cannot have a return type specified,
822 so if we run into another '_' at this point we are dealing with
823 a mangled name that is either bogus, or has been mangled by
824 some algorithm we don't know how to deal with. So just
825 reject the entire demangling. */
832 /* A G++ template function. Read the template arguments. */
833 success = demangle_template (work, mangled, declp, 0, 0);
834 if (!(work->constructor & 1))
835 expect_return_type = 1;
844 if (AUTO_DEMANGLING || GNU_DEMANGLING)
846 /* Assume we have stumbled onto the first outermost function
847 argument token, and start processing args. */
849 success = demangle_args (work, mangled, declp);
853 /* Non-GNU demanglers use a specific token to mark the start
854 of the outermost function argument tokens. Typically 'F',
855 for ARM-demangling, for example. So if we find something
856 we are not prepared for, it must be an error. */
862 if (AUTO_DEMANGLING || GNU_DEMANGLING)
865 if (success && expect_func)
868 success = demangle_args (work, mangled, declp);
869 /* Since template include the mangling of their return types,
870 we must set expect_func to 0 so that we don't try do
871 demangle more arguments the next time we get here. */
876 if (success && !func_done)
878 if (AUTO_DEMANGLING || GNU_DEMANGLING)
880 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
881 bar__3fooi is 'foo::bar(int)'. We get here when we find the
882 first case, and need to ensure that the '(void)' gets added to
883 the current declp. Note that with ARM, the first case
884 represents the name of a static data member 'foo::bar',
885 which is in the current declp, so we leave it alone. */
886 success = demangle_args (work, mangled, declp);
889 if (success && work -> static_type && PRINT_ARG_TYPES)
891 string_append (declp, " static");
893 if (success && work -> const_type && PRINT_ARG_TYPES)
895 string_append (declp, " const");
903 demangle_method_args (work, mangled, declp)
904 struct work_stuff *work;
905 const char **mangled;
910 if (work -> static_type)
912 string_append (declp, *mangled + 1);
913 *mangled += strlen (*mangled);
918 success = demangle_args (work, mangled, declp);
926 demangle_template (work, mangled, tname, trawname, is_type)
927 struct work_stuff *work;
928 const char **mangled;
946 int is_java_array = 0;
953 /* get template name */
954 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
959 string_appendn (trawname, *mangled, r);
960 is_java_array = (work -> options & DMGL_JAVA)
961 && strncmp (*mangled, "JArray1Z", 8) == 0;
964 string_appendn (tname, *mangled, r);
969 string_append (tname, "<");
970 /* get size of template parameter list */
971 if (!get_count (mangled, &r))
977 /* Create an array for saving the template argument values. */
978 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
979 work->ntmpl_args = r;
980 for (i = 0; i < r; i++)
981 work->tmpl_argvec[i] = 0;
983 for (i = 0; i < r; i++)
987 string_append (tname, ", ");
989 /* Z for type parameters */
990 if (**mangled == 'Z')
993 /* temp is initialized in do_type */
994 success = do_type (work, mangled, &temp);
997 string_appends (tname, &temp);
1001 /* Save the template argument. */
1002 int len = temp.p - temp.b;
1003 work->tmpl_argvec[i] = xmalloc (len + 1);
1004 memcpy (work->tmpl_argvec[i], temp.b, len);
1005 work->tmpl_argvec[i][len] = '\0';
1008 string_delete(&temp);
1019 /* otherwise, value parameter */
1027 /* temp is initialized in do_type */
1028 success = do_type (work, mangled, &temp);
1032 string_appends (s, &temp);
1035 string_delete(&temp);
1041 string_append (s, "=");
1052 while (*old_p && !done)
1059 done = is_pointer = 1;
1061 case 'C': /* const */
1062 case 'S': /* explicitly signed [char] */
1063 case 'U': /* unsigned */
1064 case 'V': /* volatile */
1065 case 'F': /* function */
1066 case 'M': /* member function */
1068 case 'J': /* complex */
1071 case 'Q': /* qualified name */
1072 done = is_integral = 1;
1074 case 'T': /* remembered type */
1077 case 'v': /* void */
1080 case 'x': /* long long */
1081 case 'l': /* long */
1083 case 's': /* short */
1084 case 'w': /* wchar_t */
1085 done = is_integral = 1;
1087 case 'b': /* bool */
1090 case 'c': /* char */
1093 case 'r': /* long double */
1094 case 'd': /* double */
1095 case 'f': /* float */
1099 /* it's probably user defined type, let's assume
1100 it's integral, it seems hard to figure out
1101 what it really is */
1102 done = is_integral = 1;
1105 if (**mangled == 'Y')
1107 /* The next argument is a template parameter. */
1111 idx = consume_count_with_underscores (mangled);
1113 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1114 || consume_count_with_underscores (mangled) == -1)
1121 if (work->tmpl_argvec)
1122 string_append (s, work->tmpl_argvec[idx]);
1126 sprintf(buf, "T%d", idx);
1127 string_append (s, buf);
1130 else if (is_integral)
1132 if (**mangled == 'm')
1134 string_appendn (s, "-", 1);
1137 while (isdigit (**mangled))
1139 string_appendn (s, *mangled, 1);
1147 if (**mangled == 'm')
1149 string_appendn (s, "-", 1);
1152 string_appendn (s, "'", 1);
1153 val = consume_count(mangled);
1163 string_appendn (s, &tmp[0], 1);
1164 string_appendn (s, "'", 1);
1168 int val = consume_count (mangled);
1170 string_appendn (s, "false", 5);
1172 string_appendn (s, "true", 4);
1178 if (**mangled == 'm')
1180 string_appendn (s, "-", 1);
1183 while (isdigit (**mangled))
1185 string_appendn (s, *mangled, 1);
1188 if (**mangled == '.') /* fraction */
1190 string_appendn (s, ".", 1);
1192 while (isdigit (**mangled))
1194 string_appendn (s, *mangled, 1);
1198 if (**mangled == 'e') /* exponent */
1200 string_appendn (s, "e", 1);
1202 while (isdigit (**mangled))
1204 string_appendn (s, *mangled, 1);
1209 else if (is_pointer)
1211 symbol_len = consume_count (mangled);
1212 if (symbol_len == 0)
1219 if (symbol_len == 0)
1220 string_appendn (s, "0", 1);
1223 char *p = xmalloc (symbol_len + 1), *q;
1224 strncpy (p, *mangled, symbol_len);
1225 p [symbol_len] = '\0';
1226 q = cplus_demangle (p, work->options);
1227 string_appendn (s, "&", 1);
1230 string_append (s, q);
1234 string_append (s, p);
1237 *mangled += symbol_len;
1241 int len = s->p - s->b;
1242 work->tmpl_argvec[i] = xmalloc (len + 1);
1243 memcpy (work->tmpl_argvec[i], s->b, len);
1244 work->tmpl_argvec[i][len] = '\0';
1246 string_appends (tname, s);
1254 string_append (tname, "[]");
1258 if (tname->p[-1] == '>')
1259 string_append (tname, " ");
1260 string_append (tname, ">");
1264 if (work -> static_type)
1266 string_append (declp, *mangled + 1);
1267 *mangled += strlen (*mangled);
1272 success = demangle_args (work, mangled, declp);
1280 arm_pt (work, mangled, n, anchor, args)
1281 struct work_stuff *work;
1282 const char *mangled;
1284 const char **anchor, **args;
1287 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1290 *args = *anchor + 6;
1291 len = consume_count (args);
1292 if (*args + len == mangled + n && **args == '_')
1302 demangle_arm_pt (work, mangled, n, declp)
1303 struct work_stuff *work;
1304 const char **mangled;
1310 const char *e = *mangled + n;
1313 if (arm_pt (work, *mangled, n, &p, &args))
1317 string_appendn (declp, *mangled, p - *mangled);
1318 string_append (declp, "<");
1319 /* should do error checking here */
1321 string_clear (&arg);
1322 do_type (work, &args, &arg);
1323 string_appends (declp, &arg);
1324 string_append (declp, ",");
1326 string_delete (&arg);
1328 string_append (declp, ">");
1332 string_appendn (declp, *mangled, n);
1338 demangle_class_name (work, mangled, declp)
1339 struct work_stuff *work;
1340 const char **mangled;
1346 n = consume_count (mangled);
1347 if (strlen (*mangled) >= n)
1349 demangle_arm_pt (work, mangled, n, declp);
1360 demangle_class -- demangle a mangled class sequence
1365 demangle_class (struct work_stuff *work, const char **mangled,
1370 DECLP points to the buffer into which demangling is being done.
1372 *MANGLED points to the current token to be demangled. On input,
1373 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1374 On exit, it points to the next token after the mangled class on
1375 success, or the first unconsumed token on failure.
1377 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1378 we are demangling a constructor or destructor. In this case
1379 we prepend "class::class" or "class::~class" to DECLP.
1381 Otherwise, we prepend "class::" to the current DECLP.
1383 Reset the constructor/destructor flags once they have been
1384 "consumed". This allows demangle_class to be called later during
1385 the same demangling, to do normal class demangling.
1387 Returns 1 if demangling is successful, 0 otherwise.
1392 demangle_class (work, mangled, declp)
1393 struct work_stuff *work;
1394 const char **mangled;
1400 string_init (&class_name);
1401 if (demangle_class_name (work, mangled, &class_name))
1403 if ((work->constructor & 1) || (work->destructor & 1))
1405 string_prepends (declp, &class_name);
1406 if (work -> destructor & 1)
1408 string_prepend (declp, "~");
1409 work -> destructor -= 1;
1413 work -> constructor -= 1;
1416 string_prepend (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1417 string_prepends (declp, &class_name);
1420 string_delete (&class_name);
1428 demangle_prefix -- consume the mangled name prefix and find signature
1433 demangle_prefix (struct work_stuff *work, const char **mangled,
1438 Consume and demangle the prefix of the mangled name.
1440 DECLP points to the string buffer into which demangled output is
1441 placed. On entry, the buffer is empty. On exit it contains
1442 the root function name, the demangled operator name, or in some
1443 special cases either nothing or the completely demangled result.
1445 MANGLED points to the current pointer into the mangled name. As each
1446 token of the mangled name is consumed, it is updated. Upon entry
1447 the current mangled name pointer points to the first character of
1448 the mangled name. Upon exit, it should point to the first character
1449 of the signature if demangling was successful, or to the first
1450 unconsumed character if demangling of the prefix was unsuccessful.
1452 Returns 1 on success, 0 otherwise.
1456 demangle_prefix (work, mangled, declp)
1457 struct work_stuff *work;
1458 const char **mangled;
1465 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1467 char *marker = strchr (cplus_markers, (*mangled)[8]);
1468 if (marker != NULL && *marker == (*mangled)[10])
1470 if ((*mangled)[9] == 'D')
1472 /* it's a GNU global destructor to be executed at program exit */
1474 work->destructor = 2;
1475 if (gnu_special (work, mangled, declp))
1478 else if ((*mangled)[9] == 'I')
1480 /* it's a GNU global constructor to be executed at program init */
1482 work->constructor = 2;
1483 if (gnu_special (work, mangled, declp))
1488 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1490 /* it's a ARM global destructor to be executed at program exit */
1492 work->destructor = 2;
1494 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1496 /* it's a ARM global constructor to be executed at program initial */
1498 work->constructor = 2;
1501 /* This block of code is a reduction in strength time optimization
1503 scan = mystrstr (*mangled, "__"); */
1509 scan = strchr (scan, '_');
1510 } while (scan != NULL && *++scan != '_');
1512 if (scan != NULL) --scan;
1517 /* We found a sequence of two or more '_', ensure that we start at
1518 the last pair in the sequence. */
1519 i = strspn (scan, "_");
1530 else if (work -> static_type)
1532 if (!isdigit (scan[0]) && (scan[0] != 't'))
1537 else if ((scan == *mangled)
1538 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
1539 || (scan[2] == 'H')))
1541 /* The ARM says nothing about the mangling of local variables.
1542 But cfront mangles local variables by prepending __<nesting_level>
1543 to them. As an extension to ARM demangling we handle this case. */
1544 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1546 *mangled = scan + 2;
1547 consume_count (mangled);
1548 string_append (declp, *mangled);
1549 *mangled += strlen (*mangled);
1554 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1555 names like __Q2_3foo3bar for nested type names. So don't accept
1556 this style of constructor for cfront demangling. A GNU
1557 style member-template constructor starts with 'H'. */
1558 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1559 work -> constructor += 1;
1560 *mangled = scan + 2;
1563 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1565 /* Mangled name starts with "__". Skip over any leading '_' characters,
1566 then find the next "__" that separates the prefix from the signature.
1568 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1569 || (arm_special (work, mangled, declp) == 0))
1571 while (*scan == '_')
1575 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1577 /* No separator (I.E. "__not_mangled"), or empty signature
1578 (I.E. "__not_mangled_either__") */
1583 demangle_function_name (work, mangled, declp, scan);
1587 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1589 /* Cfront-style parameterized type. Handled later as a signature. */
1593 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1595 else if (*(scan + 2) != '\0')
1597 /* Mangled name does not start with "__" but does have one somewhere
1598 in there with non empty stuff after it. Looks like a global
1600 demangle_function_name (work, mangled, declp, scan);
1604 /* Doesn't look like a mangled name */
1608 if (!success && (work->constructor == 2 || work->destructor == 2))
1610 string_append (declp, *mangled);
1611 *mangled += strlen (*mangled);
1621 gnu_special -- special handling of gnu mangled strings
1626 gnu_special (struct work_stuff *work, const char **mangled,
1632 Process some special GNU style mangling forms that don't fit
1633 the normal pattern. For example:
1635 _$_3foo (destructor for class foo)
1636 _vt$foo (foo virtual table)
1637 _vt$foo$bar (foo::bar virtual table)
1638 __vt_foo (foo virtual table, new style with thunks)
1639 _3foo$varname (static data member)
1640 _Q22rs2tu$vw (static data member)
1641 __t6vector1Zii (constructor with template)
1642 __thunk_4__$_7ostream (virtual function thunk)
1646 gnu_special (work, mangled, declp)
1647 struct work_stuff *work;
1648 const char **mangled;
1655 if ((*mangled)[0] == '_'
1656 && strchr (cplus_markers, (*mangled)[1]) != NULL
1657 && (*mangled)[2] == '_')
1659 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1661 work -> destructor += 1;
1663 else if ((*mangled)[0] == '_'
1664 && (((*mangled)[1] == '_'
1665 && (*mangled)[2] == 'v'
1666 && (*mangled)[3] == 't'
1667 && (*mangled)[4] == '_')
1668 || ((*mangled)[1] == 'v'
1669 && (*mangled)[2] == 't'
1670 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1672 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1673 and create the decl. Note that we consume the entire mangled
1674 input string, which means that demangle_signature has no work
1676 if ((*mangled)[2] == 'v')
1677 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1679 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1680 while (**mangled != '\0')
1682 p = strpbrk (*mangled, cplus_markers);
1686 success = demangle_qualified (work, mangled, declp, 0, 1);
1689 success = demangle_template (work, mangled, declp, 0, 1);
1692 if (isdigit(*mangled[0]))
1694 n = consume_count(mangled);
1695 /* We may be seeing a too-large size, or else a
1696 ".<digits>" indicating a static local symbol. In
1697 any case, declare victory and move on; *don't* try
1698 to use n to allocate. */
1699 if (n >= strlen (*mangled))
1707 n = strcspn (*mangled, cplus_markers);
1709 string_appendn (declp, *mangled, n);
1713 if (success && ((p == NULL) || (p == *mangled)))
1717 string_append (declp,
1718 (work -> options & DMGL_JAVA) ? "." : "::");
1729 string_append (declp, " virtual table");
1731 else if ((*mangled)[0] == '_'
1732 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1733 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1735 /* static data member, "_3foo$varname" for example */
1740 success = demangle_qualified (work, mangled, declp, 0, 1);
1743 success = demangle_template (work, mangled, declp, 0, 1);
1746 n = consume_count (mangled);
1747 string_appendn (declp, *mangled, n);
1750 if (success && (p == *mangled))
1752 /* Consumed everything up to the cplus_marker, append the
1755 string_append (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1756 n = strlen (*mangled);
1757 string_appendn (declp, *mangled, n);
1765 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1767 int delta = ((*mangled) += 8, consume_count (mangled));
1768 char *method = cplus_demangle (++*mangled, work->options);
1772 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1773 string_append (declp, buf);
1774 string_append (declp, method);
1776 n = strlen (*mangled);
1784 else if (strncmp (*mangled, "__t", 3) == 0
1785 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
1787 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
1792 success = demangle_qualified (work, mangled, declp, 0, 1);
1795 success = demangle_template (work, mangled, declp, 0, 1);
1798 success = demangle_fund_type (work, mangled, declp);
1801 if (success && **mangled != '\0')
1804 string_append (declp, p);
1817 arm_special -- special handling of ARM/lucid mangled strings
1822 arm_special (struct work_stuff *work, const char **mangled,
1828 Process some special ARM style mangling forms that don't fit
1829 the normal pattern. For example:
1831 __vtbl__3foo (foo virtual table)
1832 __vtbl__3foo__3bar (bar::foo virtual table)
1837 arm_special (work, mangled, declp)
1838 struct work_stuff *work;
1839 const char **mangled;
1846 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1848 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1849 and create the decl. Note that we consume the entire mangled
1850 input string, which means that demangle_signature has no work
1852 scan = *mangled + ARM_VTABLE_STRLEN;
1853 while (*scan != '\0') /* first check it can be demangled */
1855 n = consume_count (&scan);
1858 return (0); /* no good */
1861 if (scan[0] == '_' && scan[1] == '_')
1866 (*mangled) += ARM_VTABLE_STRLEN;
1867 while (**mangled != '\0')
1869 n = consume_count (mangled);
1870 string_prependn (declp, *mangled, n);
1872 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1874 string_prepend (declp, "::");
1878 string_append (declp, " virtual table");
1891 demangle_qualified -- demangle 'Q' qualified name strings
1896 demangle_qualified (struct work_stuff *, const char *mangled,
1897 string *result, int isfuncname, int append);
1901 Demangle a qualified name, such as "Q25Outer5Inner" which is
1902 the mangled form of "Outer::Inner". The demangled output is
1903 prepended or appended to the result string according to the
1904 state of the append flag.
1906 If isfuncname is nonzero, then the qualified name we are building
1907 is going to be used as a member function name, so if it is a
1908 constructor or destructor function, append an appropriate
1909 constructor or destructor name. I.E. for the above example,
1910 the result for use as a constructor is "Outer::Inner::Inner"
1911 and the result for use as a destructor is "Outer::Inner::~Inner".
1915 Numeric conversion is ASCII dependent (FIXME).
1920 demangle_qualified (work, mangled, result, isfuncname, append)
1921 struct work_stuff *work;
1922 const char **mangled;
1934 string_init (&temp);
1935 switch ((*mangled)[1])
1938 /* GNU mangled name with more than 9 classes. The count is preceded
1939 by an underscore (to distinguish it from the <= 9 case) and followed
1940 by an underscore. */
1942 qualifiers = atoi (p);
1943 if (!isdigit (*p) || *p == '0')
1946 /* Skip the digits. */
1947 while (isdigit (*p))
1965 /* The count is in a single digit. */
1966 num[0] = (*mangled)[1];
1968 qualifiers = atoi (num);
1970 /* If there is an underscore after the digit, skip it. This is
1971 said to be for ARM-qualified names, but the ARM makes no
1972 mention of such an underscore. Perhaps cfront uses one. */
1973 if ((*mangled)[2] == '_')
1988 /* Pick off the names and collect them in the temp buffer in the order
1989 in which they are found, separated by '::'. */
1991 while (qualifiers-- > 0)
1993 if (*mangled[0] == '_')
1994 *mangled = *mangled + 1;
1995 if (*mangled[0] == 't')
1997 success = demangle_template(work, mangled, &temp, 0, 1);
1998 if (!success) break;
2000 else if (*mangled[0] == 'X')
2002 success = do_type (work, mangled, &temp);
2003 if (!success) break;
2007 namelength = consume_count (mangled);
2008 if (strlen (*mangled) < namelength)
2010 /* Simple sanity check failed */
2014 string_appendn (&temp, *mangled, namelength);
2015 *mangled += namelength;
2019 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2023 /* If we are using the result as a function name, we need to append
2024 the appropriate '::' separated constructor or destructor name.
2025 We do this here because this is the most convenient place, where
2026 we already have a pointer to the name and the length of the name. */
2028 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
2030 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2031 if (work -> destructor & 1)
2033 string_append (&temp, "~");
2035 string_appendn (&temp, (*mangled) - namelength, namelength);
2038 /* Now either prepend the temp buffer to the result, or append it,
2039 depending upon the state of the append flag. */
2043 string_appends (result, &temp);
2047 if (!STRING_EMPTY (result))
2049 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2051 string_prepends (result, &temp);
2054 string_delete (&temp);
2062 get_count -- convert an ascii count to integer, consuming tokens
2067 get_count (const char **type, int *count)
2071 Return 0 if no conversion is performed, 1 if a string is converted.
2075 get_count (type, count)
2082 if (!isdigit (**type))
2088 *count = **type - '0';
2090 if (isdigit (**type))
2100 while (isdigit (*p));
2111 /* result will be initialised here; it will be freed on failure */
2114 do_type (work, mangled, result)
2115 struct work_stuff *work;
2116 const char **mangled;
2123 const char *remembered_type;
2127 string_init (&decl);
2128 string_init (result);
2132 while (success && !done)
2138 /* A pointer type */
2142 if (! (work -> options & DMGL_JAVA))
2143 string_prepend (&decl, "*");
2146 /* A reference type */
2149 string_prepend (&decl, "&");
2155 const char *p = ++(*mangled);
2157 string_prepend (&decl, "(");
2158 string_append (&decl, ")[");
2159 /* Copy anything up until the next underscore (the size of the
2161 while (**mangled && **mangled != '_')
2163 if (**mangled == '_')
2165 string_appendn (&decl, p, *mangled - p);
2166 string_append (&decl, "]");
2174 /* A back reference to a previously seen type */
2177 if (!get_count (mangled, &n) || n >= work -> ntypes)
2183 remembered_type = work -> typevec[n];
2184 mangled = &remembered_type;
2191 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2193 string_prepend (&decl, "(");
2194 string_append (&decl, ")");
2196 /* After picking off the function args, we expect to either find the
2197 function return type (preceded by an '_') or the end of the
2199 if (!demangle_args (work, mangled, &decl)
2200 || (**mangled != '_' && **mangled != '\0'))
2204 if (success && (**mangled == '_'))
2216 member = **mangled == 'M';
2218 if (!isdigit (**mangled) && **mangled != 't')
2224 string_append (&decl, ")");
2225 string_prepend (&decl, (work -> options & DMGL_JAVA) ? "." : "::");
2226 if (isdigit (**mangled))
2228 n = consume_count (mangled);
2229 if (strlen (*mangled) < n)
2234 string_prependn (&decl, *mangled, n);
2240 string_init (&temp);
2241 success = demangle_template (work, mangled, &temp, NULL, 1);
2244 string_prependn (&decl, temp.b, temp.p - temp.b);
2245 string_clear (&temp);
2250 string_prepend (&decl, "(");
2253 if (**mangled == 'C')
2258 if (**mangled == 'V')
2263 if (*(*mangled)++ != 'F')
2269 if ((member && !demangle_args (work, mangled, &decl))
2270 || **mangled != '_')
2276 if (! PRINT_ANSI_QUALIFIERS)
2282 APPEND_BLANK (&decl);
2283 string_append (&decl, "const");
2287 APPEND_BLANK (&decl);
2288 string_append (&decl, "volatile");
2299 if ((*mangled)[1] == 'P')
2302 if (PRINT_ANSI_QUALIFIERS)
2304 if (!STRING_EMPTY (&decl))
2306 string_prepend (&decl, " ");
2308 string_prepend (&decl, "const");
2324 /* A qualified name, such as "Outer::Inner". */
2326 success = demangle_qualified (work, mangled, result, 0, 1);
2331 /* A template parm. We substitute the corresponding argument. */
2337 idx = consume_count_with_underscores (mangled);
2340 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2341 || consume_count_with_underscores (mangled) == -1)
2347 if (work->tmpl_argvec)
2348 string_append (result, work->tmpl_argvec[idx]);
2352 sprintf(buf, "T%d", idx);
2353 string_append (result, buf);
2361 success = demangle_fund_type (work, mangled, result);
2367 if (!STRING_EMPTY (&decl))
2369 string_append (result, " ");
2370 string_appends (result, &decl);
2375 string_delete (result);
2377 string_delete (&decl);
2381 /* Given a pointer to a type string that represents a fundamental type
2382 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2383 string in which the demangled output is being built in RESULT, and
2384 the WORK structure, decode the types and add them to the result.
2389 "Sl" => "signed long"
2390 "CUs" => "const unsigned short"
2395 demangle_fund_type (work, mangled, result)
2396 struct work_stuff *work;
2397 const char **mangled;
2403 /* First pick off any type qualifiers. There can be more than one. */
2411 if (PRINT_ANSI_QUALIFIERS)
2413 APPEND_BLANK (result);
2414 string_append (result, "const");
2419 APPEND_BLANK (result);
2420 string_append (result, "unsigned");
2422 case 'S': /* signed char only */
2424 APPEND_BLANK (result);
2425 string_append (result, "signed");
2429 if (PRINT_ANSI_QUALIFIERS)
2431 APPEND_BLANK (result);
2432 string_append (result, "volatile");
2437 APPEND_BLANK (result);
2438 string_append (result, "__complex");
2446 /* Now pick off the fundamental type. There can be only one. */
2455 APPEND_BLANK (result);
2456 string_append (result, "void");
2460 APPEND_BLANK (result);
2461 string_append (result, "long long");
2465 APPEND_BLANK (result);
2466 string_append (result, "long");
2470 APPEND_BLANK (result);
2471 string_append (result, "int");
2475 APPEND_BLANK (result);
2476 string_append (result, "short");
2480 APPEND_BLANK (result);
2481 string_append (result, "bool");
2485 APPEND_BLANK (result);
2486 string_append (result, "char");
2490 APPEND_BLANK (result);
2491 string_append (result, "wchar_t");
2495 APPEND_BLANK (result);
2496 string_append (result, "long double");
2500 APPEND_BLANK (result);
2501 string_append (result, "double");
2505 APPEND_BLANK (result);
2506 string_append (result, "float");
2510 if (!isdigit (**mangled))
2516 /* An explicit type, such as "6mytype" or "7integer" */
2527 APPEND_BLANK (result);
2528 if (!demangle_class_name (work, mangled, result)) {
2534 success = demangle_template(work,mangled, result, 0, 1);
2544 /* `result' will be initialized in do_type; it will be freed on failure */
2547 do_arg (work, mangled, result)
2548 struct work_stuff *work;
2549 const char **mangled;
2552 const char *start = *mangled;
2554 if (!do_type (work, mangled, result))
2560 remember_type (work, start, *mangled - start);
2566 remember_type (work, start, len)
2567 struct work_stuff *work;
2573 if (work -> ntypes >= work -> typevec_size)
2575 if (work -> typevec_size == 0)
2577 work -> typevec_size = 3;
2579 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2583 work -> typevec_size *= 2;
2585 = (char **) xrealloc ((char *)work -> typevec,
2586 sizeof (char *) * work -> typevec_size);
2589 tem = xmalloc (len + 1);
2590 memcpy (tem, start, len);
2592 work -> typevec[work -> ntypes++] = tem;
2595 /* Forget the remembered types, but not the type vector itself. */
2599 struct work_stuff *work;
2603 while (work -> ntypes > 0)
2605 i = --(work -> ntypes);
2606 if (work -> typevec[i] != NULL)
2608 free (work -> typevec[i]);
2609 work -> typevec[i] = NULL;
2614 /* Process the argument list part of the signature, after any class spec
2615 has been consumed, as well as the first 'F' character (if any). For
2618 "__als__3fooRT0" => process "RT0"
2619 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2621 DECLP must be already initialised, usually non-empty. It won't be freed
2624 Note that g++ differs significantly from ARM and lucid style mangling
2625 with regards to references to previously seen types. For example, given
2626 the source fragment:
2630 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2633 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2634 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2636 g++ produces the names:
2641 while lcc (and presumably other ARM style compilers as well) produces:
2643 foo__FiR3fooT1T2T1T2
2644 __ct__3fooFiR3fooT1T2T1T2
2646 Note that g++ bases it's type numbers starting at zero and counts all
2647 previously seen types, while lucid/ARM bases it's type numbers starting
2648 at one and only considers types after it has seen the 'F' character
2649 indicating the start of the function args. For lucid/ARM style, we
2650 account for this difference by discarding any previously seen types when
2651 we see the 'F' character, and subtracting one from the type number
2657 demangle_args (work, mangled, declp)
2658 struct work_stuff *work;
2659 const char **mangled;
2669 if (PRINT_ARG_TYPES)
2671 string_append (declp, "(");
2672 if (**mangled == '\0')
2674 string_append (declp, "void");
2678 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2680 if ((**mangled == 'N') || (**mangled == 'T'))
2682 temptype = *(*mangled)++;
2684 if (temptype == 'N')
2686 if (!get_count (mangled, &r))
2695 if (ARM_DEMANGLING && work -> ntypes >= 10)
2697 /* If we have 10 or more types we might have more than a 1 digit
2698 index so we'll have to consume the whole count here. This
2699 will lose if the next thing is a type name preceded by a
2700 count but it's impossible to demangle that case properly
2701 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2702 Pc, ...)" or "(..., type12, char *, ...)" */
2703 if ((t = consume_count(mangled)) == 0)
2710 if (!get_count (mangled, &t))
2715 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2719 /* Validate the type index. Protect against illegal indices from
2720 malformed type strings. */
2721 if ((t < 0) || (t >= work -> ntypes))
2727 tem = work -> typevec[t];
2728 if (need_comma && PRINT_ARG_TYPES)
2730 string_append (declp, ", ");
2732 if (!do_arg (work, &tem, &arg))
2736 if (PRINT_ARG_TYPES)
2738 string_appends (declp, &arg);
2740 string_delete (&arg);
2746 if (need_comma & PRINT_ARG_TYPES)
2748 string_append (declp, ", ");
2750 if (!do_arg (work, mangled, &arg))
2754 if (PRINT_ARG_TYPES)
2756 string_appends (declp, &arg);
2758 string_delete (&arg);
2763 if (**mangled == 'e')
2766 if (PRINT_ARG_TYPES)
2770 string_append (declp, ",");
2772 string_append (declp, "...");
2776 if (PRINT_ARG_TYPES)
2778 string_append (declp, ")");
2784 demangle_function_name (work, mangled, declp, scan)
2785 struct work_stuff *work;
2786 const char **mangled;
2795 string_appendn (declp, (*mangled), scan - (*mangled));
2796 string_need (declp, 1);
2797 *(declp -> p) = '\0';
2799 /* Consume the function name, including the "__" separating the name
2800 from the signature. We are guaranteed that SCAN points to the
2803 (*mangled) = scan + 2;
2805 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2808 /* See if we have an ARM style constructor or destructor operator.
2809 If so, then just record it, clear the decl, and return.
2810 We can't build the actual constructor/destructor decl until later,
2811 when we recover the class name from the signature. */
2813 if (strcmp (declp -> b, "__ct") == 0)
2815 work -> constructor += 1;
2816 string_clear (declp);
2819 else if (strcmp (declp -> b, "__dt") == 0)
2821 work -> destructor += 1;
2822 string_clear (declp);
2827 if (declp->p - declp->b >= 3
2828 && declp->b[0] == 'o'
2829 && declp->b[1] == 'p'
2830 && strchr (cplus_markers, declp->b[2]) != NULL)
2832 /* see if it's an assignment expression */
2833 if (declp->p - declp->b >= 10 /* op$assign_ */
2834 && memcmp (declp->b + 3, "assign_", 7) == 0)
2836 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2838 len = declp->p - declp->b - 10;
2839 if (strlen (optable[i].in) == len
2840 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2842 string_clear (declp);
2843 string_append (declp, "operator");
2844 string_append (declp, optable[i].out);
2845 string_append (declp, "=");
2852 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2854 int len = declp->p - declp->b - 3;
2855 if (strlen (optable[i].in) == len
2856 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2858 string_clear (declp);
2859 string_append (declp, "operator");
2860 string_append (declp, optable[i].out);
2866 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2867 && strchr (cplus_markers, declp->b[4]) != NULL)
2869 /* type conversion operator */
2871 if (do_type (work, &tem, &type))
2873 string_clear (declp);
2874 string_append (declp, "operator ");
2875 string_appends (declp, &type);
2876 string_delete (&type);
2879 else if (declp->b[0] == '_' && declp->b[1] == '_'
2880 && declp->b[2] == 'o' && declp->b[3] == 'p')
2883 /* type conversion operator. */
2885 if (do_type (work, &tem, &type))
2887 string_clear (declp);
2888 string_append (declp, "operator ");
2889 string_appends (declp, &type);
2890 string_delete (&type);
2893 else if (declp->b[0] == '_' && declp->b[1] == '_'
2894 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2895 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2897 if (declp->b[4] == '\0')
2900 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2902 if (strlen (optable[i].in) == 2
2903 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2905 string_clear (declp);
2906 string_append (declp, "operator");
2907 string_append (declp, optable[i].out);
2914 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2917 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2919 if (strlen (optable[i].in) == 3
2920 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2922 string_clear (declp);
2923 string_append (declp, "operator");
2924 string_append (declp, optable[i].out);
2933 /* a mini string-handling package */
2948 s->p = s->b = xmalloc (n);
2951 else if (s->e - s->p < n)
2956 s->b = xrealloc (s->b, n);
2969 s->b = s->e = s->p = NULL;
2977 s->b = s->p = s->e = NULL;
2993 return (s->b == s->p);
2999 string_append (p, s)
3004 if (s == NULL || *s == '\0')
3008 memcpy (p->p, s, n);
3013 string_appends (p, s)
3022 memcpy (p->p, s->b, n);
3028 string_appendn (p, s, n)
3036 memcpy (p->p, s, n);
3042 string_prepend (p, s)
3046 if (s != NULL && *s != '\0')
3048 string_prependn (p, s, strlen (s));
3053 string_prepends (p, s)
3058 string_prependn (p, s->b, s->p - s->b);
3063 string_prependn (p, s, n)
3073 for (q = p->p - 1; q >= p->b; q--)
3077 memcpy (p->b, s, n);
3082 /* To generate a standalone demangler program for testing purposes,
3083 just compile and link this file with -DMAIN and libiberty.a. When
3084 run, it demangles each command line arg, or each stdin string, and
3085 prints the result on stdout. */
3091 static char *program_name;
3092 static char *program_version = VERSION;
3093 static int flags = DMGL_PARAMS | DMGL_ANSI;
3095 static void demangle_it PARAMS ((char *));
3096 static void usage PARAMS ((FILE *, int));
3097 static void fatal PARAMS ((char *));
3100 demangle_it (mangled_name)
3105 result = cplus_demangle (mangled_name, flags);
3108 printf ("%s\n", mangled_name);
3112 printf ("%s\n", result);
3118 usage (stream, status)
3123 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3124 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3125 [--help] [--version] [arg...]\n",
3130 #define MBUF_SIZE 512
3131 char mbuffer[MBUF_SIZE];
3133 /* Defined in the automatically-generated underscore.c. */
3134 extern int prepends_underscore;
3136 int strip_underscore = 0;
3138 static struct option long_options[] = {
3139 {"strip-underscores", no_argument, 0, '_'},
3140 {"format", required_argument, 0, 's'},
3141 {"help", no_argument, 0, 'h'},
3142 {"java", no_argument, 0, 'j'},
3143 {"no-strip-underscores", no_argument, 0, 'n'},
3144 {"version", no_argument, 0, 'v'},
3145 {0, no_argument, 0, 0}
3156 program_name = argv[0];
3158 strip_underscore = prepends_underscore;
3160 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3170 strip_underscore = 0;
3173 printf ("GNU %s version %s\n", program_name, program_version);
3176 strip_underscore = 1;
3182 if (strcmp (optarg, "gnu") == 0)
3184 current_demangling_style = gnu_demangling;
3186 else if (strcmp (optarg, "lucid") == 0)
3188 current_demangling_style = lucid_demangling;
3190 else if (strcmp (optarg, "arm") == 0)
3192 current_demangling_style = arm_demangling;
3196 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3197 program_name, optarg);
3206 for ( ; optind < argc; optind++)
3208 demangle_it (argv[optind]);
3217 /* Try to read a label. */
3218 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3220 if (i >= MBUF_SIZE-1)
3229 if (mbuffer[0] == '.')
3231 if (strip_underscore && mbuffer[skip_first] == '_')
3239 result = cplus_demangle (mbuffer + skip_first, flags);
3242 if (mbuffer[0] == '.')
3244 fputs (result, stdout);
3248 fputs (mbuffer, stdout);
3265 fprintf (stderr, "%s: %s\n", program_name, str);
3276 register char *value = (char *) malloc (size);
3278 fatal ("virtual memory exhausted");
3283 xrealloc (ptr, size)
3287 register char *value = (char *) realloc (ptr, size);
3289 fatal ("virtual memory exhausted");