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);
1698 n = strcspn (*mangled, cplus_markers);
1700 string_appendn (declp, *mangled, n);
1704 if (success && ((p == NULL) || (p == *mangled)))
1708 string_append (declp,
1709 (work -> options & DMGL_JAVA) ? "." : "::");
1720 string_append (declp, " virtual table");
1722 else if ((*mangled)[0] == '_'
1723 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1724 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1726 /* static data member, "_3foo$varname" for example */
1731 success = demangle_qualified (work, mangled, declp, 0, 1);
1734 success = demangle_template (work, mangled, declp, 0, 1);
1737 n = consume_count (mangled);
1738 string_appendn (declp, *mangled, n);
1741 if (success && (p == *mangled))
1743 /* Consumed everything up to the cplus_marker, append the
1746 string_append (declp, (work -> options & DMGL_JAVA) ? "." : "::");
1747 n = strlen (*mangled);
1748 string_appendn (declp, *mangled, n);
1756 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1758 int delta = ((*mangled) += 8, consume_count (mangled));
1759 char *method = cplus_demangle (++*mangled, work->options);
1763 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1764 string_append (declp, buf);
1765 string_append (declp, method);
1767 n = strlen (*mangled);
1775 else if (strncmp (*mangled, "__t", 3) == 0
1776 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
1778 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
1783 success = demangle_qualified (work, mangled, declp, 0, 1);
1786 success = demangle_template (work, mangled, declp, 0, 1);
1789 success = demangle_fund_type (work, mangled, declp);
1792 if (success && **mangled != '\0')
1795 string_append (declp, p);
1808 arm_special -- special handling of ARM/lucid mangled strings
1813 arm_special (struct work_stuff *work, const char **mangled,
1819 Process some special ARM style mangling forms that don't fit
1820 the normal pattern. For example:
1822 __vtbl__3foo (foo virtual table)
1823 __vtbl__3foo__3bar (bar::foo virtual table)
1828 arm_special (work, mangled, declp)
1829 struct work_stuff *work;
1830 const char **mangled;
1837 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1839 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1840 and create the decl. Note that we consume the entire mangled
1841 input string, which means that demangle_signature has no work
1843 scan = *mangled + ARM_VTABLE_STRLEN;
1844 while (*scan != '\0') /* first check it can be demangled */
1846 n = consume_count (&scan);
1849 return (0); /* no good */
1852 if (scan[0] == '_' && scan[1] == '_')
1857 (*mangled) += ARM_VTABLE_STRLEN;
1858 while (**mangled != '\0')
1860 n = consume_count (mangled);
1861 string_prependn (declp, *mangled, n);
1863 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1865 string_prepend (declp, "::");
1869 string_append (declp, " virtual table");
1882 demangle_qualified -- demangle 'Q' qualified name strings
1887 demangle_qualified (struct work_stuff *, const char *mangled,
1888 string *result, int isfuncname, int append);
1892 Demangle a qualified name, such as "Q25Outer5Inner" which is
1893 the mangled form of "Outer::Inner". The demangled output is
1894 prepended or appended to the result string according to the
1895 state of the append flag.
1897 If isfuncname is nonzero, then the qualified name we are building
1898 is going to be used as a member function name, so if it is a
1899 constructor or destructor function, append an appropriate
1900 constructor or destructor name. I.E. for the above example,
1901 the result for use as a constructor is "Outer::Inner::Inner"
1902 and the result for use as a destructor is "Outer::Inner::~Inner".
1906 Numeric conversion is ASCII dependent (FIXME).
1911 demangle_qualified (work, mangled, result, isfuncname, append)
1912 struct work_stuff *work;
1913 const char **mangled;
1925 string_init (&temp);
1926 switch ((*mangled)[1])
1929 /* GNU mangled name with more than 9 classes. The count is preceded
1930 by an underscore (to distinguish it from the <= 9 case) and followed
1931 by an underscore. */
1933 qualifiers = atoi (p);
1934 if (!isdigit (*p) || *p == '0')
1937 /* Skip the digits. */
1938 while (isdigit (*p))
1956 /* The count is in a single digit. */
1957 num[0] = (*mangled)[1];
1959 qualifiers = atoi (num);
1961 /* If there is an underscore after the digit, skip it. This is
1962 said to be for ARM-qualified names, but the ARM makes no
1963 mention of such an underscore. Perhaps cfront uses one. */
1964 if ((*mangled)[2] == '_')
1979 /* Pick off the names and collect them in the temp buffer in the order
1980 in which they are found, separated by '::'. */
1982 while (qualifiers-- > 0)
1984 if (*mangled[0] == '_')
1985 *mangled = *mangled + 1;
1986 if (*mangled[0] == 't')
1988 success = demangle_template(work, mangled, &temp, 0, 1);
1989 if (!success) break;
1991 else if (*mangled[0] == 'X')
1993 success = do_type (work, mangled, &temp);
1994 if (!success) break;
1998 namelength = consume_count (mangled);
1999 if (strlen (*mangled) < namelength)
2001 /* Simple sanity check failed */
2005 string_appendn (&temp, *mangled, namelength);
2006 *mangled += namelength;
2010 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2014 /* If we are using the result as a function name, we need to append
2015 the appropriate '::' separated constructor or destructor name.
2016 We do this here because this is the most convenient place, where
2017 we already have a pointer to the name and the length of the name. */
2019 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
2021 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2022 if (work -> destructor & 1)
2024 string_append (&temp, "~");
2026 string_appendn (&temp, (*mangled) - namelength, namelength);
2029 /* Now either prepend the temp buffer to the result, or append it,
2030 depending upon the state of the append flag. */
2034 string_appends (result, &temp);
2038 if (!STRING_EMPTY (result))
2040 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
2042 string_prepends (result, &temp);
2045 string_delete (&temp);
2053 get_count -- convert an ascii count to integer, consuming tokens
2058 get_count (const char **type, int *count)
2062 Return 0 if no conversion is performed, 1 if a string is converted.
2066 get_count (type, count)
2073 if (!isdigit (**type))
2079 *count = **type - '0';
2081 if (isdigit (**type))
2091 while (isdigit (*p));
2102 /* result will be initialised here; it will be freed on failure */
2105 do_type (work, mangled, result)
2106 struct work_stuff *work;
2107 const char **mangled;
2114 const char *remembered_type;
2118 string_init (&decl);
2119 string_init (result);
2123 while (success && !done)
2129 /* A pointer type */
2133 if (! (work -> options & DMGL_JAVA))
2134 string_prepend (&decl, "*");
2137 /* A reference type */
2140 string_prepend (&decl, "&");
2146 const char *p = ++(*mangled);
2148 string_prepend (&decl, "(");
2149 string_append (&decl, ")[");
2150 /* Copy anything up until the next underscore (the size of the
2152 while (**mangled && **mangled != '_')
2154 if (**mangled == '_')
2156 string_appendn (&decl, p, *mangled - p);
2157 string_append (&decl, "]");
2165 /* A back reference to a previously seen type */
2168 if (!get_count (mangled, &n) || n >= work -> ntypes)
2174 remembered_type = work -> typevec[n];
2175 mangled = &remembered_type;
2182 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2184 string_prepend (&decl, "(");
2185 string_append (&decl, ")");
2187 /* After picking off the function args, we expect to either find the
2188 function return type (preceded by an '_') or the end of the
2190 if (!demangle_args (work, mangled, &decl)
2191 || (**mangled != '_' && **mangled != '\0'))
2195 if (success && (**mangled == '_'))
2207 member = **mangled == 'M';
2209 if (!isdigit (**mangled) && **mangled != 't')
2215 string_append (&decl, ")");
2216 string_prepend (&decl, (work -> options & DMGL_JAVA) ? "." : "::");
2217 if (isdigit (**mangled))
2219 n = consume_count (mangled);
2220 if (strlen (*mangled) < n)
2225 string_prependn (&decl, *mangled, n);
2231 string_init (&temp);
2232 success = demangle_template (work, mangled, &temp, NULL, 1);
2235 string_prependn (&decl, temp.b, temp.p - temp.b);
2236 string_clear (&temp);
2241 string_prepend (&decl, "(");
2244 if (**mangled == 'C')
2249 if (**mangled == 'V')
2254 if (*(*mangled)++ != 'F')
2260 if ((member && !demangle_args (work, mangled, &decl))
2261 || **mangled != '_')
2267 if (! PRINT_ANSI_QUALIFIERS)
2273 APPEND_BLANK (&decl);
2274 string_append (&decl, "const");
2278 APPEND_BLANK (&decl);
2279 string_append (&decl, "volatile");
2290 if ((*mangled)[1] == 'P')
2293 if (PRINT_ANSI_QUALIFIERS)
2295 if (!STRING_EMPTY (&decl))
2297 string_prepend (&decl, " ");
2299 string_prepend (&decl, "const");
2315 /* A qualified name, such as "Outer::Inner". */
2317 success = demangle_qualified (work, mangled, result, 0, 1);
2322 /* A template parm. We substitute the corresponding argument. */
2328 idx = consume_count_with_underscores (mangled);
2331 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2332 || consume_count_with_underscores (mangled) == -1)
2338 if (work->tmpl_argvec)
2339 string_append (result, work->tmpl_argvec[idx]);
2343 sprintf(buf, "T%d", idx);
2344 string_append (result, buf);
2352 success = demangle_fund_type (work, mangled, result);
2358 if (!STRING_EMPTY (&decl))
2360 string_append (result, " ");
2361 string_appends (result, &decl);
2366 string_delete (result);
2368 string_delete (&decl);
2372 /* Given a pointer to a type string that represents a fundamental type
2373 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2374 string in which the demangled output is being built in RESULT, and
2375 the WORK structure, decode the types and add them to the result.
2380 "Sl" => "signed long"
2381 "CUs" => "const unsigned short"
2386 demangle_fund_type (work, mangled, result)
2387 struct work_stuff *work;
2388 const char **mangled;
2394 /* First pick off any type qualifiers. There can be more than one. */
2402 if (PRINT_ANSI_QUALIFIERS)
2404 APPEND_BLANK (result);
2405 string_append (result, "const");
2410 APPEND_BLANK (result);
2411 string_append (result, "unsigned");
2413 case 'S': /* signed char only */
2415 APPEND_BLANK (result);
2416 string_append (result, "signed");
2420 if (PRINT_ANSI_QUALIFIERS)
2422 APPEND_BLANK (result);
2423 string_append (result, "volatile");
2428 APPEND_BLANK (result);
2429 string_append (result, "__complex");
2437 /* Now pick off the fundamental type. There can be only one. */
2446 APPEND_BLANK (result);
2447 string_append (result, "void");
2451 APPEND_BLANK (result);
2452 string_append (result, "long long");
2456 APPEND_BLANK (result);
2457 string_append (result, "long");
2461 APPEND_BLANK (result);
2462 string_append (result, "int");
2466 APPEND_BLANK (result);
2467 string_append (result, "short");
2471 APPEND_BLANK (result);
2472 string_append (result, "bool");
2476 APPEND_BLANK (result);
2477 string_append (result, "char");
2481 APPEND_BLANK (result);
2482 string_append (result, "wchar_t");
2486 APPEND_BLANK (result);
2487 string_append (result, "long double");
2491 APPEND_BLANK (result);
2492 string_append (result, "double");
2496 APPEND_BLANK (result);
2497 string_append (result, "float");
2501 if (!isdigit (**mangled))
2507 /* An explicit type, such as "6mytype" or "7integer" */
2518 APPEND_BLANK (result);
2519 if (!demangle_class_name (work, mangled, result)) {
2525 success = demangle_template(work,mangled, result, 0, 1);
2535 /* `result' will be initialized in do_type; it will be freed on failure */
2538 do_arg (work, mangled, result)
2539 struct work_stuff *work;
2540 const char **mangled;
2543 const char *start = *mangled;
2545 if (!do_type (work, mangled, result))
2551 remember_type (work, start, *mangled - start);
2557 remember_type (work, start, len)
2558 struct work_stuff *work;
2564 if (work -> ntypes >= work -> typevec_size)
2566 if (work -> typevec_size == 0)
2568 work -> typevec_size = 3;
2570 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2574 work -> typevec_size *= 2;
2576 = (char **) xrealloc ((char *)work -> typevec,
2577 sizeof (char *) * work -> typevec_size);
2580 tem = xmalloc (len + 1);
2581 memcpy (tem, start, len);
2583 work -> typevec[work -> ntypes++] = tem;
2586 /* Forget the remembered types, but not the type vector itself. */
2590 struct work_stuff *work;
2594 while (work -> ntypes > 0)
2596 i = --(work -> ntypes);
2597 if (work -> typevec[i] != NULL)
2599 free (work -> typevec[i]);
2600 work -> typevec[i] = NULL;
2605 /* Process the argument list part of the signature, after any class spec
2606 has been consumed, as well as the first 'F' character (if any). For
2609 "__als__3fooRT0" => process "RT0"
2610 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2612 DECLP must be already initialised, usually non-empty. It won't be freed
2615 Note that g++ differs significantly from ARM and lucid style mangling
2616 with regards to references to previously seen types. For example, given
2617 the source fragment:
2621 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2624 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2625 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2627 g++ produces the names:
2632 while lcc (and presumably other ARM style compilers as well) produces:
2634 foo__FiR3fooT1T2T1T2
2635 __ct__3fooFiR3fooT1T2T1T2
2637 Note that g++ bases it's type numbers starting at zero and counts all
2638 previously seen types, while lucid/ARM bases it's type numbers starting
2639 at one and only considers types after it has seen the 'F' character
2640 indicating the start of the function args. For lucid/ARM style, we
2641 account for this difference by discarding any previously seen types when
2642 we see the 'F' character, and subtracting one from the type number
2648 demangle_args (work, mangled, declp)
2649 struct work_stuff *work;
2650 const char **mangled;
2660 if (PRINT_ARG_TYPES)
2662 string_append (declp, "(");
2663 if (**mangled == '\0')
2665 string_append (declp, "void");
2669 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2671 if ((**mangled == 'N') || (**mangled == 'T'))
2673 temptype = *(*mangled)++;
2675 if (temptype == 'N')
2677 if (!get_count (mangled, &r))
2686 if (ARM_DEMANGLING && work -> ntypes >= 10)
2688 /* If we have 10 or more types we might have more than a 1 digit
2689 index so we'll have to consume the whole count here. This
2690 will lose if the next thing is a type name preceded by a
2691 count but it's impossible to demangle that case properly
2692 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2693 Pc, ...)" or "(..., type12, char *, ...)" */
2694 if ((t = consume_count(mangled)) == 0)
2701 if (!get_count (mangled, &t))
2706 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2710 /* Validate the type index. Protect against illegal indices from
2711 malformed type strings. */
2712 if ((t < 0) || (t >= work -> ntypes))
2718 tem = work -> typevec[t];
2719 if (need_comma && PRINT_ARG_TYPES)
2721 string_append (declp, ", ");
2723 if (!do_arg (work, &tem, &arg))
2727 if (PRINT_ARG_TYPES)
2729 string_appends (declp, &arg);
2731 string_delete (&arg);
2737 if (need_comma & PRINT_ARG_TYPES)
2739 string_append (declp, ", ");
2741 if (!do_arg (work, mangled, &arg))
2745 if (PRINT_ARG_TYPES)
2747 string_appends (declp, &arg);
2749 string_delete (&arg);
2754 if (**mangled == 'e')
2757 if (PRINT_ARG_TYPES)
2761 string_append (declp, ",");
2763 string_append (declp, "...");
2767 if (PRINT_ARG_TYPES)
2769 string_append (declp, ")");
2775 demangle_function_name (work, mangled, declp, scan)
2776 struct work_stuff *work;
2777 const char **mangled;
2786 string_appendn (declp, (*mangled), scan - (*mangled));
2787 string_need (declp, 1);
2788 *(declp -> p) = '\0';
2790 /* Consume the function name, including the "__" separating the name
2791 from the signature. We are guaranteed that SCAN points to the
2794 (*mangled) = scan + 2;
2796 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2799 /* See if we have an ARM style constructor or destructor operator.
2800 If so, then just record it, clear the decl, and return.
2801 We can't build the actual constructor/destructor decl until later,
2802 when we recover the class name from the signature. */
2804 if (strcmp (declp -> b, "__ct") == 0)
2806 work -> constructor += 1;
2807 string_clear (declp);
2810 else if (strcmp (declp -> b, "__dt") == 0)
2812 work -> destructor += 1;
2813 string_clear (declp);
2818 if (declp->p - declp->b >= 3
2819 && declp->b[0] == 'o'
2820 && declp->b[1] == 'p'
2821 && strchr (cplus_markers, declp->b[2]) != NULL)
2823 /* see if it's an assignment expression */
2824 if (declp->p - declp->b >= 10 /* op$assign_ */
2825 && memcmp (declp->b + 3, "assign_", 7) == 0)
2827 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2829 len = declp->p - declp->b - 10;
2830 if (strlen (optable[i].in) == len
2831 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2833 string_clear (declp);
2834 string_append (declp, "operator");
2835 string_append (declp, optable[i].out);
2836 string_append (declp, "=");
2843 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2845 int len = declp->p - declp->b - 3;
2846 if (strlen (optable[i].in) == len
2847 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2849 string_clear (declp);
2850 string_append (declp, "operator");
2851 string_append (declp, optable[i].out);
2857 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2858 && strchr (cplus_markers, declp->b[4]) != NULL)
2860 /* type conversion operator */
2862 if (do_type (work, &tem, &type))
2864 string_clear (declp);
2865 string_append (declp, "operator ");
2866 string_appends (declp, &type);
2867 string_delete (&type);
2870 else if (declp->b[0] == '_' && declp->b[1] == '_'
2871 && declp->b[2] == 'o' && declp->b[3] == 'p')
2874 /* type conversion operator. */
2876 if (do_type (work, &tem, &type))
2878 string_clear (declp);
2879 string_append (declp, "operator ");
2880 string_appends (declp, &type);
2881 string_delete (&type);
2884 else if (declp->b[0] == '_' && declp->b[1] == '_'
2885 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2886 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2888 if (declp->b[4] == '\0')
2891 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2893 if (strlen (optable[i].in) == 2
2894 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2896 string_clear (declp);
2897 string_append (declp, "operator");
2898 string_append (declp, optable[i].out);
2905 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2908 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2910 if (strlen (optable[i].in) == 3
2911 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2913 string_clear (declp);
2914 string_append (declp, "operator");
2915 string_append (declp, optable[i].out);
2924 /* a mini string-handling package */
2939 s->p = s->b = xmalloc (n);
2942 else if (s->e - s->p < n)
2947 s->b = xrealloc (s->b, n);
2960 s->b = s->e = s->p = NULL;
2968 s->b = s->p = s->e = NULL;
2984 return (s->b == s->p);
2990 string_append (p, s)
2995 if (s == NULL || *s == '\0')
2999 memcpy (p->p, s, n);
3004 string_appends (p, s)
3013 memcpy (p->p, s->b, n);
3019 string_appendn (p, s, n)
3027 memcpy (p->p, s, n);
3033 string_prepend (p, s)
3037 if (s != NULL && *s != '\0')
3039 string_prependn (p, s, strlen (s));
3044 string_prepends (p, s)
3049 string_prependn (p, s->b, s->p - s->b);
3054 string_prependn (p, s, n)
3064 for (q = p->p - 1; q >= p->b; q--)
3068 memcpy (p->b, s, n);
3073 /* To generate a standalone demangler program for testing purposes,
3074 just compile and link this file with -DMAIN and libiberty.a. When
3075 run, it demangles each command line arg, or each stdin string, and
3076 prints the result on stdout. */
3082 static char *program_name;
3083 static char *program_version = VERSION;
3084 static int flags = DMGL_PARAMS | DMGL_ANSI;
3086 static void demangle_it PARAMS ((char *));
3087 static void usage PARAMS ((FILE *, int));
3088 static void fatal PARAMS ((char *));
3091 demangle_it (mangled_name)
3096 result = cplus_demangle (mangled_name, flags);
3099 printf ("%s\n", mangled_name);
3103 printf ("%s\n", result);
3109 usage (stream, status)
3114 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3115 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3116 [--help] [--version] [arg...]\n",
3121 #define MBUF_SIZE 512
3122 char mbuffer[MBUF_SIZE];
3124 /* Defined in the automatically-generated underscore.c. */
3125 extern int prepends_underscore;
3127 int strip_underscore = 0;
3129 static struct option long_options[] = {
3130 {"strip-underscores", no_argument, 0, '_'},
3131 {"format", required_argument, 0, 's'},
3132 {"help", no_argument, 0, 'h'},
3133 {"java", no_argument, 0, 'j'},
3134 {"no-strip-underscores", no_argument, 0, 'n'},
3135 {"version", no_argument, 0, 'v'},
3136 {0, no_argument, 0, 0}
3147 program_name = argv[0];
3149 strip_underscore = prepends_underscore;
3151 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3161 strip_underscore = 0;
3164 printf ("GNU %s version %s\n", program_name, program_version);
3167 strip_underscore = 1;
3173 if (strcmp (optarg, "gnu") == 0)
3175 current_demangling_style = gnu_demangling;
3177 else if (strcmp (optarg, "lucid") == 0)
3179 current_demangling_style = lucid_demangling;
3181 else if (strcmp (optarg, "arm") == 0)
3183 current_demangling_style = arm_demangling;
3187 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3188 program_name, optarg);
3197 for ( ; optind < argc; optind++)
3199 demangle_it (argv[optind]);
3208 /* Try to read a label. */
3209 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3211 if (i >= MBUF_SIZE-1)
3220 if (mbuffer[0] == '.')
3222 if (strip_underscore && mbuffer[skip_first] == '_')
3230 result = cplus_demangle (mbuffer + skip_first, flags);
3233 if (mbuffer[0] == '.')
3235 fputs (result, stdout);
3239 fputs (mbuffer, stdout);
3256 fprintf (stderr, "%s: %s\n", program_name, str);
3267 register char *value = (char *) malloc (size);
3269 fatal ("virtual memory exhausted");
3274 xrealloc (ptr, size)
3278 register char *value = (char *) realloc (ptr, size);
3280 fatal ("virtual memory exhausted");