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 */
107 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
108 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
110 static const struct optable
116 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
117 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
118 {"new", " new", 0}, /* old (1.91, and 1.x) */
119 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
120 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
121 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
122 {"as", "=", DMGL_ANSI}, /* ansi */
123 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
124 {"eq", "==", DMGL_ANSI}, /* old, ansi */
125 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
126 {"gt", ">", DMGL_ANSI}, /* old, ansi */
127 {"le", "<=", DMGL_ANSI}, /* old, ansi */
128 {"lt", "<", DMGL_ANSI}, /* old, ansi */
129 {"plus", "+", 0}, /* old */
130 {"pl", "+", DMGL_ANSI}, /* ansi */
131 {"apl", "+=", DMGL_ANSI}, /* ansi */
132 {"minus", "-", 0}, /* old */
133 {"mi", "-", DMGL_ANSI}, /* ansi */
134 {"ami", "-=", DMGL_ANSI}, /* ansi */
135 {"mult", "*", 0}, /* old */
136 {"ml", "*", DMGL_ANSI}, /* ansi */
137 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
138 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
139 {"convert", "+", 0}, /* old (unary +) */
140 {"negate", "-", 0}, /* old (unary -) */
141 {"trunc_mod", "%", 0}, /* old */
142 {"md", "%", DMGL_ANSI}, /* ansi */
143 {"amd", "%=", DMGL_ANSI}, /* ansi */
144 {"trunc_div", "/", 0}, /* old */
145 {"dv", "/", DMGL_ANSI}, /* ansi */
146 {"adv", "/=", DMGL_ANSI}, /* ansi */
147 {"truth_andif", "&&", 0}, /* old */
148 {"aa", "&&", DMGL_ANSI}, /* ansi */
149 {"truth_orif", "||", 0}, /* old */
150 {"oo", "||", DMGL_ANSI}, /* ansi */
151 {"truth_not", "!", 0}, /* old */
152 {"nt", "!", DMGL_ANSI}, /* ansi */
153 {"postincrement","++", 0}, /* old */
154 {"pp", "++", DMGL_ANSI}, /* ansi */
155 {"postdecrement","--", 0}, /* old */
156 {"mm", "--", DMGL_ANSI}, /* ansi */
157 {"bit_ior", "|", 0}, /* old */
158 {"or", "|", DMGL_ANSI}, /* ansi */
159 {"aor", "|=", DMGL_ANSI}, /* ansi */
160 {"bit_xor", "^", 0}, /* old */
161 {"er", "^", DMGL_ANSI}, /* ansi */
162 {"aer", "^=", DMGL_ANSI}, /* ansi */
163 {"bit_and", "&", 0}, /* old */
164 {"ad", "&", DMGL_ANSI}, /* ansi */
165 {"aad", "&=", DMGL_ANSI}, /* ansi */
166 {"bit_not", "~", 0}, /* old */
167 {"co", "~", DMGL_ANSI}, /* ansi */
168 {"call", "()", 0}, /* old */
169 {"cl", "()", DMGL_ANSI}, /* ansi */
170 {"alshift", "<<", 0}, /* old */
171 {"ls", "<<", DMGL_ANSI}, /* ansi */
172 {"als", "<<=", DMGL_ANSI}, /* ansi */
173 {"arshift", ">>", 0}, /* old */
174 {"rs", ">>", DMGL_ANSI}, /* ansi */
175 {"ars", ">>=", DMGL_ANSI}, /* ansi */
176 {"component", "->", 0}, /* old */
177 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
178 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
179 {"indirect", "*", 0}, /* old */
180 {"method_call", "->()", 0}, /* old */
181 {"addr", "&", 0}, /* old (unary &) */
182 {"array", "[]", 0}, /* old */
183 {"vc", "[]", DMGL_ANSI}, /* ansi */
184 {"compound", ", ", 0}, /* old */
185 {"cm", ", ", DMGL_ANSI}, /* ansi */
186 {"cond", "?:", 0}, /* old */
187 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
188 {"max", ">?", 0}, /* old */
189 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
190 {"min", "<?", 0}, /* old */
191 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
192 {"nop", "", 0}, /* old (for operator=) */
193 {"rm", "->*", DMGL_ANSI} /* ansi */
197 typedef struct string /* Beware: these aren't required to be */
198 { /* '\0' terminated. */
199 char *b; /* pointer to start of string */
200 char *p; /* pointer after last character */
201 char *e; /* pointer after end of allocated space */
204 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
205 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
206 string_prepend(str, " ");}
207 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
208 string_append(str, " ");}
210 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
211 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
213 /* Prototypes for local functions */
216 mop_up PARAMS ((struct work_stuff *, string *, int));
220 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
224 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
228 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
232 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
235 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
238 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
242 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
245 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
248 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
251 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
254 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
257 arm_special PARAMS ((struct work_stuff *, const char **, string *));
260 string_need PARAMS ((string *, int));
263 string_delete PARAMS ((string *));
266 string_init PARAMS ((string *));
269 string_clear PARAMS ((string *));
273 string_empty PARAMS ((string *));
277 string_append PARAMS ((string *, const char *));
280 string_appends PARAMS ((string *, string *));
283 string_appendn PARAMS ((string *, const char *, int));
286 string_prepend PARAMS ((string *, const char *));
289 string_prependn PARAMS ((string *, const char *, int));
292 get_count PARAMS ((const char **, int *));
295 consume_count PARAMS ((const char **));
298 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
301 do_type PARAMS ((struct work_stuff *, const char **, string *));
304 do_arg PARAMS ((struct work_stuff *, const char **, string *));
307 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
311 remember_type PARAMS ((struct work_stuff *, const char *, int));
314 forget_types PARAMS ((struct work_stuff *));
317 string_prepends PARAMS ((string *, string *));
319 /* Translate count to integer, consuming tokens in the process.
320 Conversion terminates on the first non-digit character.
321 Trying to consume something that isn't a count results in
322 no consumption of input and a return of 0. */
330 while (isdigit (**type))
333 count += **type - '0';
340 cplus_demangle_opname (opname, result, options)
345 int len, i, len1, ret;
347 struct work_stuff work[1];
350 len = strlen(opname);
353 work->options = options;
355 if (opname[0] == '_' && opname[1] == '_'
356 && opname[2] == 'o' && opname[3] == 'p')
359 /* type conversion operator. */
361 if (do_type (work, &tem, &type))
363 strcat (result, "operator ");
364 strncat (result, type.b, type.p - type.b);
365 string_delete (&type);
369 else if (opname[0] == '_' && opname[1] == '_'
370 && opname[2] >= 'a' && opname[2] <= 'z'
371 && opname[3] >= 'a' && opname[3] <= 'z')
373 if (opname[4] == '\0')
376 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
378 if (strlen (optable[i].in) == 2
379 && memcmp (optable[i].in, opname + 2, 2) == 0)
381 strcat (result, "operator");
382 strcat (result, optable[i].out);
390 if (opname[2] == 'a' && opname[5] == '\0')
393 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
395 if (strlen (optable[i].in) == 3
396 && memcmp (optable[i].in, opname + 2, 3) == 0)
398 strcat (result, "operator");
399 strcat (result, optable[i].out);
410 && strchr (cplus_markers, opname[2]) != NULL)
412 /* see if it's an assignment expression */
413 if (len >= 10 /* op$assign_ */
414 && memcmp (opname + 3, "assign_", 7) == 0)
416 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
419 if (strlen (optable[i].in) == len1
420 && memcmp (optable[i].in, opname + 10, len1) == 0)
422 strcat (result, "operator");
423 strcat (result, optable[i].out);
424 strcat (result, "=");
432 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
435 if (strlen (optable[i].in) == len1
436 && memcmp (optable[i].in, opname + 3, len1) == 0)
438 strcat (result, "operator");
439 strcat (result, optable[i].out);
446 else if (len >= 5 && memcmp (opname, "type", 4) == 0
447 && strchr (cplus_markers, opname[4]) != NULL)
449 /* type conversion operator */
451 if (do_type (work, &tem, &type))
453 strcat (result, "operator ");
454 strncat (result, type.b, type.p - type.b);
455 string_delete (&type);
462 /* Takes operator name as e.g. "++" and returns mangled
463 operator name (e.g. "postincrement_expr"), or NULL if not found.
465 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
466 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
469 cplus_mangle_opname (opname, options)
476 len = strlen (opname);
477 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
479 if (strlen (optable[i].out) == len
480 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
481 && memcmp (optable[i].out, opname, len) == 0)
482 return optable[i].in;
487 /* char *cplus_demangle (const char *mangled, int options)
489 If MANGLED is a mangled function name produced by GNU C++, then
490 a pointer to a malloced string giving a C++ representation
491 of the name will be returned; otherwise NULL will be returned.
492 It is the caller's responsibility to free the string which
495 The OPTIONS arg may contain one or more of the following bits:
497 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
499 DMGL_PARAMS Function parameters are included.
503 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
504 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
505 cplus_demangle ("foo__1Ai", 0) => "A::foo"
507 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
508 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
509 cplus_demangle ("foo__1Afe", 0) => "A::foo"
511 Note that any leading underscores, or other such characters prepended by
512 the compilation system, are presumed to have already been stripped from
516 cplus_demangle (mangled, options)
522 struct work_stuff work[1];
523 char *demangled = NULL;
525 if ((mangled != NULL) && (*mangled != '\0'))
527 memset ((char *) work, 0, sizeof (work));
528 work -> options = options;
529 if ((work->options & DMGL_STYLE_MASK) == 0)
530 work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
534 /* First check to see if gnu style demangling is active and if the
535 string to be demangled contains a CPLUS_MARKER. If so, attempt to
536 recognize one of the gnu special forms rather than looking for a
537 standard prefix. In particular, don't worry about whether there
538 is a "__" string in the mangled string. Consider "_$_5__foo" for
541 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
543 success = gnu_special (work, &mangled, &decl);
547 success = demangle_prefix (work, &mangled, &decl);
549 if (success && (*mangled != '\0'))
551 success = demangle_signature (work, &mangled, &decl);
553 if (work->constructor == 2)
555 string_prepend(&decl, "global constructors keyed to ");
556 work->constructor = 0;
558 else if (work->destructor == 2)
560 string_prepend(&decl, "global destructors keyed to ");
561 work->destructor = 0;
563 demangled = mop_up (work, &decl, success);
569 mop_up (work, declp, success)
570 struct work_stuff *work;
574 char *demangled = NULL;
576 /* Discard the remembered types, if any. */
579 if (work -> typevec != NULL)
581 free ((char *) work -> typevec);
584 /* If demangling was successful, ensure that the demangled string is null
585 terminated and return it. Otherwise, free the demangling decl. */
589 string_delete (declp);
593 string_appendn (declp, "", 1);
594 demangled = declp -> b;
603 demangle_signature -- demangle the signature part of a mangled name
608 demangle_signature (struct work_stuff *work, const char **mangled,
613 Consume and demangle the signature portion of the mangled name.
615 DECLP is the string where demangled output is being built. At
616 entry it contains the demangled root name from the mangled name
617 prefix. I.E. either a demangled operator name or the root function
618 name. In some special cases, it may contain nothing.
620 *MANGLED points to the current unconsumed location in the mangled
621 name. As tokens are consumed and demangling is performed, the
622 pointer is updated to continuously point at the next token to
625 Demangling GNU style mangled names is nasty because there is no
626 explicit token that marks the start of the outermost function
630 demangle_signature (work, mangled, declp)
631 struct work_stuff *work;
632 const char **mangled;
638 const char *oldmangled = NULL;
642 while (success && (**mangled != '\0'))
647 oldmangled = *mangled;
648 success = demangle_qualified (work, mangled, declp, 1, 0);
651 remember_type (work, oldmangled, *mangled - oldmangled);
653 if (AUTO_DEMANGLING || GNU_DEMANGLING)
661 /* Static member function */
662 if (oldmangled == NULL)
664 oldmangled = *mangled;
667 work -> static_type = 1;
671 /* a const member function */
672 if (oldmangled == NULL)
674 oldmangled = *mangled;
677 work -> const_type = 1;
680 case '0': case '1': case '2': case '3': case '4':
681 case '5': case '6': case '7': case '8': case '9':
682 if (oldmangled == NULL)
684 oldmangled = *mangled;
686 success = demangle_class (work, mangled, declp);
689 remember_type (work, oldmangled, *mangled - oldmangled);
691 if (AUTO_DEMANGLING || GNU_DEMANGLING)
700 /* ARM style demangling includes a specific 'F' character after
701 the class name. For GNU style, it is just implied. So we can
702 safely just consume any 'F' at this point and be compatible
703 with either style. */
709 /* For lucid/ARM style we have to forget any types we might
710 have remembered up to this point, since they were not argument
711 types. GNU style considers all types seen as available for
712 back references. See comment in demangle_args() */
714 if (LUCID_DEMANGLING || ARM_DEMANGLING)
718 success = demangle_args (work, mangled, declp);
723 string_init(&trawname);
725 if (oldmangled == NULL)
727 oldmangled = *mangled;
729 success = demangle_template (work, mangled, &tname, &trawname);
732 remember_type (work, oldmangled, *mangled - oldmangled);
734 string_append(&tname, "::");
735 string_prepends(declp, &tname);
736 if (work -> destructor & 1)
738 string_prepend (&trawname, "~");
739 string_appends (declp, &trawname);
740 work->destructor -= 1;
742 if ((work->constructor & 1) || (work->destructor & 1))
744 string_appends (declp, &trawname);
745 work->constructor -= 1;
747 string_delete(&trawname);
748 string_delete(&tname);
754 /* At the outermost level, we cannot have a return type specified,
755 so if we run into another '_' at this point we are dealing with
756 a mangled name that is either bogus, or has been mangled by
757 some algorithm we don't know how to deal with. So just
758 reject the entire demangling. */
763 if (AUTO_DEMANGLING || GNU_DEMANGLING)
765 /* Assume we have stumbled onto the first outermost function
766 argument token, and start processing args. */
768 success = demangle_args (work, mangled, declp);
772 /* Non-GNU demanglers use a specific token to mark the start
773 of the outermost function argument tokens. Typically 'F',
774 for ARM-demangling, for example. So if we find something
775 we are not prepared for, it must be an error. */
781 if (AUTO_DEMANGLING || GNU_DEMANGLING)
784 if (success && expect_func)
787 success = demangle_args (work, mangled, declp);
791 if (success && !func_done)
793 if (AUTO_DEMANGLING || GNU_DEMANGLING)
795 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
796 bar__3fooi is 'foo::bar(int)'. We get here when we find the
797 first case, and need to ensure that the '(void)' gets added to
798 the current declp. Note that with ARM, the first case
799 represents the name of a static data member 'foo::bar',
800 which is in the current declp, so we leave it alone. */
801 success = demangle_args (work, mangled, declp);
804 if (success && work -> static_type && PRINT_ARG_TYPES)
806 string_append (declp, " static");
808 if (success && work -> const_type && PRINT_ARG_TYPES)
810 string_append (declp, " const");
818 demangle_method_args (work, mangled, declp)
819 struct work_stuff *work;
820 const char **mangled;
825 if (work -> static_type)
827 string_append (declp, *mangled + 1);
828 *mangled += strlen (*mangled);
833 success = demangle_args (work, mangled, declp);
841 demangle_template (work, mangled, tname, trawname)
842 struct work_stuff *work;
843 const char **mangled;
864 /* get template name */
865 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
870 string_appendn (trawname, *mangled, r);
871 string_appendn (tname, *mangled, r);
873 string_append (tname, "<");
874 /* get size of template parameter list */
875 if (!get_count (mangled, &r))
879 for (i = 0; i < r; i++)
883 string_append (tname, ", ");
885 /* Z for type parameters */
886 if (**mangled == 'Z')
889 /* temp is initialized in do_type */
890 success = do_type (work, mangled, &temp);
893 string_appends (tname, &temp);
895 string_delete(&temp);
903 /* otherwise, value parameter */
911 /* temp is initialized in do_type */
912 success = do_type (work, mangled, &temp);
916 string_appends (tname, &temp);
919 string_delete(&temp);
925 string_append (tname, "=");
927 while (*old_p && !done)
934 done = is_pointer = 1;
936 case 'C': /* const */
937 case 'S': /* explicitly signed [char] */
938 case 'U': /* unsigned */
939 case 'V': /* volatile */
940 case 'F': /* function */
941 case 'M': /* member function */
945 case 'Q': /* qualified name */
946 done = is_integral = 1;
948 case 'T': /* remembered type */
954 case 'x': /* long long */
957 case 's': /* short */
958 case 'w': /* wchar_t */
959 done = is_integral = 1;
967 case 'r': /* long double */
968 case 'd': /* double */
969 case 'f': /* float */
973 /* it's probably user defined type, let's assume
974 it's integral, it seems hard to figure out
976 done = is_integral = 1;
981 if (**mangled == 'm')
983 string_appendn (tname, "-", 1);
986 while (isdigit (**mangled))
988 string_appendn (tname, *mangled, 1);
996 if (**mangled == 'm')
998 string_appendn (tname, "-", 1);
1001 string_appendn (tname, "'", 1);
1002 val = consume_count(mangled);
1010 string_appendn (tname, &tmp[0], 1);
1011 string_appendn (tname, "'", 1);
1015 int val = consume_count (mangled);
1017 string_appendn (tname, "false", 5);
1019 string_appendn (tname, "true", 4);
1025 if (**mangled == 'm')
1027 string_appendn (tname, "-", 1);
1030 while (isdigit (**mangled))
1032 string_appendn (tname, *mangled, 1);
1035 if (**mangled == '.') /* fraction */
1037 string_appendn (tname, ".", 1);
1039 while (isdigit (**mangled))
1041 string_appendn (tname, *mangled, 1);
1045 if (**mangled == 'e') /* exponent */
1047 string_appendn (tname, "e", 1);
1049 while (isdigit (**mangled))
1051 string_appendn (tname, *mangled, 1);
1056 else if (is_pointer)
1058 symbol_len = consume_count (mangled);
1059 if (symbol_len == 0)
1064 if (symbol_len == 0)
1065 string_appendn (tname, "0", 1);
1068 char *p = xmalloc (symbol_len + 1), *q;
1069 strncpy (p, *mangled, symbol_len);
1070 p [symbol_len] = '\0';
1071 q = cplus_demangle (p, work->options);
1072 string_appendn (tname, "&", 1);
1075 string_append (tname, q);
1079 string_append (tname, p);
1082 *mangled += symbol_len;
1087 if (tname->p[-1] == '>')
1088 string_append (tname, " ");
1089 string_append (tname, ">");
1092 if (work -> static_type)
1094 string_append (declp, *mangled + 1);
1095 *mangled += strlen (*mangled);
1100 success = demangle_args (work, mangled, declp);
1108 arm_pt (work, mangled, n, anchor, args)
1109 struct work_stuff *work;
1110 const char *mangled;
1112 const char **anchor, **args;
1115 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1118 *args = *anchor + 6;
1119 len = consume_count (args);
1120 if (*args + len == mangled + n && **args == '_')
1130 demangle_arm_pt (work, mangled, n, declp)
1131 struct work_stuff *work;
1132 const char **mangled;
1138 const char *e = *mangled + n;
1141 if (arm_pt (work, *mangled, n, &p, &args))
1145 string_appendn (declp, *mangled, p - *mangled);
1146 string_append (declp, "<");
1147 /* should do error checking here */
1149 string_clear (&arg);
1150 do_type (work, &args, &arg);
1151 string_appends (declp, &arg);
1152 string_append (declp, ",");
1154 string_delete (&arg);
1156 string_append (declp, ">");
1160 string_appendn (declp, *mangled, n);
1166 demangle_class_name (work, mangled, declp)
1167 struct work_stuff *work;
1168 const char **mangled;
1174 n = consume_count (mangled);
1175 if (strlen (*mangled) >= n)
1177 demangle_arm_pt (work, mangled, n, declp);
1188 demangle_class -- demangle a mangled class sequence
1193 demangle_class (struct work_stuff *work, const char **mangled,
1198 DECLP points to the buffer into which demangling is being done.
1200 *MANGLED points to the current token to be demangled. On input,
1201 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1202 On exit, it points to the next token after the mangled class on
1203 success, or the first unconsumed token on failure.
1205 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1206 we are demangling a constructor or destructor. In this case
1207 we prepend "class::class" or "class::~class" to DECLP.
1209 Otherwise, we prepend "class::" to the current DECLP.
1211 Reset the constructor/destructor flags once they have been
1212 "consumed". This allows demangle_class to be called later during
1213 the same demangling, to do normal class demangling.
1215 Returns 1 if demangling is successful, 0 otherwise.
1220 demangle_class (work, mangled, declp)
1221 struct work_stuff *work;
1222 const char **mangled;
1228 string_init (&class_name);
1229 if (demangle_class_name (work, mangled, &class_name))
1231 if ((work->constructor & 1) || (work->destructor & 1))
1233 string_prepends (declp, &class_name);
1234 if (work -> destructor & 1)
1236 string_prepend (declp, "~");
1237 work -> destructor -= 1;
1241 work -> constructor -= 1;
1244 string_prepend (declp, "::");
1245 string_prepends (declp, &class_name);
1248 string_delete (&class_name);
1256 demangle_prefix -- consume the mangled name prefix and find signature
1261 demangle_prefix (struct work_stuff *work, const char **mangled,
1266 Consume and demangle the prefix of the mangled name.
1268 DECLP points to the string buffer into which demangled output is
1269 placed. On entry, the buffer is empty. On exit it contains
1270 the root function name, the demangled operator name, or in some
1271 special cases either nothing or the completely demangled result.
1273 MANGLED points to the current pointer into the mangled name. As each
1274 token of the mangled name is consumed, it is updated. Upon entry
1275 the current mangled name pointer points to the first character of
1276 the mangled name. Upon exit, it should point to the first character
1277 of the signature if demangling was successful, or to the first
1278 unconsumed character if demangling of the prefix was unsuccessful.
1280 Returns 1 on success, 0 otherwise.
1284 demangle_prefix (work, mangled, declp)
1285 struct work_stuff *work;
1286 const char **mangled;
1293 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1295 char *marker = strchr (cplus_markers, (*mangled)[8]);
1296 if (marker != NULL && *marker == (*mangled)[10])
1298 if ((*mangled)[9] == 'D')
1300 /* it's a GNU global destructor to be executed at program exit */
1302 work->destructor = 2;
1303 if (gnu_special (work, mangled, declp))
1306 else if ((*mangled)[9] == 'I')
1308 /* it's a GNU global constructor to be executed at program init */
1310 work->constructor = 2;
1311 if (gnu_special (work, mangled, declp))
1316 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1318 /* it's a ARM global destructor to be executed at program exit */
1320 work->destructor = 2;
1322 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1324 /* it's a ARM global constructor to be executed at program initial */
1326 work->constructor = 2;
1329 /* This block of code is a reduction in strength time optimization
1331 scan = mystrstr (*mangled, "__"); */
1337 scan = strchr (scan, '_');
1338 } while (scan != NULL && *++scan != '_');
1340 if (scan != NULL) --scan;
1345 /* We found a sequence of two or more '_', ensure that we start at
1346 the last pair in the sequence. */
1347 i = strspn (scan, "_");
1358 else if (work -> static_type)
1360 if (!isdigit (scan[0]) && (scan[0] != 't'))
1365 else if ((scan == *mangled) &&
1366 (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')))
1368 /* The ARM says nothing about the mangling of local variables.
1369 But cfront mangles local variables by prepending __<nesting_level>
1370 to them. As an extension to ARM demangling we handle this case. */
1371 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1373 *mangled = scan + 2;
1374 consume_count (mangled);
1375 string_append (declp, *mangled);
1376 *mangled += strlen (*mangled);
1381 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1382 names like __Q2_3foo3bar for nested type names. So don't accept
1383 this style of constructor for cfront demangling. */
1384 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1385 work -> constructor += 1;
1386 *mangled = scan + 2;
1389 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1391 /* Mangled name starts with "__". Skip over any leading '_' characters,
1392 then find the next "__" that separates the prefix from the signature.
1394 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1395 || (arm_special (work, mangled, declp) == 0))
1397 while (*scan == '_')
1401 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1403 /* No separator (I.E. "__not_mangled"), or empty signature
1404 (I.E. "__not_mangled_either__") */
1409 demangle_function_name (work, mangled, declp, scan);
1413 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1415 /* Cfront-style parameterized type. Handled later as a signature. */
1419 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1421 else if (*(scan + 2) != '\0')
1423 /* Mangled name does not start with "__" but does have one somewhere
1424 in there with non empty stuff after it. Looks like a global
1426 demangle_function_name (work, mangled, declp, scan);
1430 /* Doesn't look like a mangled name */
1434 if (!success && (work->constructor == 2 || work->destructor == 2))
1436 string_append (declp, *mangled);
1437 *mangled += strlen (*mangled);
1447 gnu_special -- special handling of gnu mangled strings
1452 gnu_special (struct work_stuff *work, const char **mangled,
1458 Process some special GNU style mangling forms that don't fit
1459 the normal pattern. For example:
1461 _$_3foo (destructor for class foo)
1462 _vt$foo (foo virtual table)
1463 _vt$foo$bar (foo::bar virtual table)
1464 __vt_foo (foo virtual table, new style with thunks)
1465 _3foo$varname (static data member)
1466 _Q22rs2tu$vw (static data member)
1467 __t6vector1Zii (constructor with template)
1468 __thunk_4__$_7ostream (virtual function thunk)
1472 gnu_special (work, mangled, declp)
1473 struct work_stuff *work;
1474 const char **mangled;
1481 if ((*mangled)[0] == '_'
1482 && strchr (cplus_markers, (*mangled)[1]) != NULL
1483 && (*mangled)[2] == '_')
1485 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1487 work -> destructor += 1;
1489 else if ((*mangled)[0] == '_'
1490 && (((*mangled)[1] == '_'
1491 && (*mangled)[2] == 'v'
1492 && (*mangled)[3] == 't'
1493 && (*mangled)[4] == '_')
1494 || ((*mangled)[1] == 'v'
1495 && (*mangled)[2] == 't'
1496 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1498 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1499 and create the decl. Note that we consume the entire mangled
1500 input string, which means that demangle_signature has no work
1502 if ((*mangled)[2] == 'v')
1503 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1505 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1506 while (**mangled != '\0')
1508 p = strpbrk (*mangled, cplus_markers);
1512 success = demangle_qualified (work, mangled, declp, 0, 1);
1515 success = demangle_template (work, mangled, declp, 0);
1518 if (isdigit(*mangled[0]))
1520 n = consume_count(mangled);
1524 n = strcspn (*mangled, cplus_markers);
1526 string_appendn (declp, *mangled, n);
1530 if (success && ((p == NULL) || (p == *mangled)))
1534 string_append (declp, "::");
1545 string_append (declp, " virtual table");
1547 else if ((*mangled)[0] == '_'
1548 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1549 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1551 /* static data member, "_3foo$varname" for example */
1556 success = demangle_qualified (work, mangled, declp, 0, 1);
1559 success = demangle_template (work, mangled, declp, 0);
1562 n = consume_count (mangled);
1563 string_appendn (declp, *mangled, n);
1566 if (success && (p == *mangled))
1568 /* Consumed everything up to the cplus_marker, append the
1571 string_append (declp, "::");
1572 n = strlen (*mangled);
1573 string_appendn (declp, *mangled, n);
1581 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1583 int delta = ((*mangled) += 8, consume_count (mangled));
1584 char *method = cplus_demangle (++*mangled, work->options);
1588 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1589 string_append (declp, buf);
1590 string_append (declp, method);
1592 n = strlen (*mangled);
1600 else if (strncmp (*mangled, "__t", 3) == 0
1601 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
1603 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
1608 success = demangle_qualified (work, mangled, declp, 0, 1);
1611 success = demangle_template (work, mangled, declp, 0);
1614 success = demangle_fund_type (work, mangled, declp);
1617 if (success && **mangled != '\0')
1620 string_append (declp, p);
1633 arm_special -- special handling of ARM/lucid mangled strings
1638 arm_special (struct work_stuff *work, const char **mangled,
1644 Process some special ARM style mangling forms that don't fit
1645 the normal pattern. For example:
1647 __vtbl__3foo (foo virtual table)
1648 __vtbl__3foo__3bar (bar::foo virtual table)
1653 arm_special (work, mangled, declp)
1654 struct work_stuff *work;
1655 const char **mangled;
1662 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1664 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1665 and create the decl. Note that we consume the entire mangled
1666 input string, which means that demangle_signature has no work
1668 scan = *mangled + ARM_VTABLE_STRLEN;
1669 while (*scan != '\0') /* first check it can be demangled */
1671 n = consume_count (&scan);
1674 return (0); /* no good */
1677 if (scan[0] == '_' && scan[1] == '_')
1682 (*mangled) += ARM_VTABLE_STRLEN;
1683 while (**mangled != '\0')
1685 n = consume_count (mangled);
1686 string_prependn (declp, *mangled, n);
1688 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1690 string_prepend (declp, "::");
1694 string_append (declp, " virtual table");
1707 demangle_qualified -- demangle 'Q' qualified name strings
1712 demangle_qualified (struct work_stuff *, const char *mangled,
1713 string *result, int isfuncname, int append);
1717 Demangle a qualified name, such as "Q25Outer5Inner" which is
1718 the mangled form of "Outer::Inner". The demangled output is
1719 prepended or appended to the result string according to the
1720 state of the append flag.
1722 If isfuncname is nonzero, then the qualified name we are building
1723 is going to be used as a member function name, so if it is a
1724 constructor or destructor function, append an appropriate
1725 constructor or destructor name. I.E. for the above example,
1726 the result for use as a constructor is "Outer::Inner::Inner"
1727 and the result for use as a destructor is "Outer::Inner::~Inner".
1731 Numeric conversion is ASCII dependent (FIXME).
1736 demangle_qualified (work, mangled, result, isfuncname, append)
1737 struct work_stuff *work;
1738 const char **mangled;
1750 string_init (&temp);
1751 switch ((*mangled)[1])
1754 /* GNU mangled name with more than 9 classes. The count is preceded
1755 by an underscore (to distinguish it from the <= 9 case) and followed
1756 by an underscore. */
1758 qualifiers = atoi (p);
1759 if (!isdigit (*p) || *p == '0')
1762 /* Skip the digits. */
1763 while (isdigit (*p))
1781 /* The count is in a single digit. */
1782 num[0] = (*mangled)[1];
1784 qualifiers = atoi (num);
1786 /* If there is an underscore after the digit, skip it. This is
1787 said to be for ARM-qualified names, but the ARM makes no
1788 mention of such an underscore. Perhaps cfront uses one. */
1789 if ((*mangled)[2] == '_')
1804 /* Pick off the names and collect them in the temp buffer in the order
1805 in which they are found, separated by '::'. */
1807 while (qualifiers-- > 0)
1809 if (*mangled[0] == '_')
1810 *mangled = *mangled + 1;
1811 if (*mangled[0] == 't')
1813 success = demangle_template(work, mangled, &temp, 0);
1814 if (!success) break;
1818 namelength = consume_count (mangled);
1819 if (strlen (*mangled) < namelength)
1821 /* Simple sanity check failed */
1825 string_appendn (&temp, *mangled, namelength);
1826 *mangled += namelength;
1830 string_appendn (&temp, "::", 2);
1834 /* If we are using the result as a function name, we need to append
1835 the appropriate '::' separated constructor or destructor name.
1836 We do this here because this is the most convenient place, where
1837 we already have a pointer to the name and the length of the name. */
1839 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
1841 string_appendn (&temp, "::", 2);
1842 if (work -> destructor & 1)
1844 string_append (&temp, "~");
1846 string_appendn (&temp, (*mangled) - namelength, namelength);
1849 /* Now either prepend the temp buffer to the result, or append it,
1850 depending upon the state of the append flag. */
1854 string_appends (result, &temp);
1858 if (!STRING_EMPTY (result))
1860 string_appendn (&temp, "::", 2);
1862 string_prepends (result, &temp);
1865 string_delete (&temp);
1873 get_count -- convert an ascii count to integer, consuming tokens
1878 get_count (const char **type, int *count)
1882 Return 0 if no conversion is performed, 1 if a string is converted.
1886 get_count (type, count)
1893 if (!isdigit (**type))
1899 *count = **type - '0';
1901 if (isdigit (**type))
1911 while (isdigit (*p));
1922 /* result will be initialised here; it will be freed on failure */
1925 do_type (work, mangled, result)
1926 struct work_stuff *work;
1927 const char **mangled;
1934 const char *remembered_type;
1938 string_init (&decl);
1939 string_init (result);
1943 while (success && !done)
1949 /* A pointer type */
1953 string_prepend (&decl, "*");
1956 /* A reference type */
1959 string_prepend (&decl, "&");
1965 const char *p = ++(*mangled);
1967 string_prepend (&decl, "(");
1968 string_append (&decl, ")[");
1969 /* Copy anything up until the next underscore (the size of the
1971 while (**mangled && **mangled != '_')
1973 if (**mangled == '_')
1975 string_appendn (&decl, p, *mangled - p);
1976 string_append (&decl, "]");
1984 /* A back reference to a previously seen type */
1987 if (!get_count (mangled, &n) || n >= work -> ntypes)
1993 remembered_type = work -> typevec[n];
1994 mangled = &remembered_type;
2001 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2003 string_prepend (&decl, "(");
2004 string_append (&decl, ")");
2006 /* After picking off the function args, we expect to either find the
2007 function return type (preceded by an '_') or the end of the
2009 if (!demangle_args (work, mangled, &decl)
2010 || (**mangled != '_' && **mangled != '\0'))
2014 if (success && (**mangled == '_'))
2026 member = **mangled == 'M';
2028 if (!isdigit (**mangled) && **mangled != 't')
2034 string_append (&decl, ")");
2035 string_prepend (&decl, "::");
2036 if (isdigit (**mangled))
2038 n = consume_count (mangled);
2039 if (strlen (*mangled) < n)
2044 string_prependn (&decl, *mangled, n);
2050 string_init (&temp);
2051 success = demangle_template (work, mangled, &temp, NULL);
2054 string_prependn (&decl, temp.b, temp.p - temp.b);
2055 string_clear (&temp);
2060 string_prepend (&decl, "(");
2063 if (**mangled == 'C')
2068 if (**mangled == 'V')
2073 if (*(*mangled)++ != 'F')
2079 if ((member && !demangle_args (work, mangled, &decl))
2080 || **mangled != '_')
2086 if (! PRINT_ANSI_QUALIFIERS)
2092 APPEND_BLANK (&decl);
2093 string_append (&decl, "const");
2097 APPEND_BLANK (&decl);
2098 string_append (&decl, "volatile");
2109 if ((*mangled)[1] == 'P')
2112 if (PRINT_ANSI_QUALIFIERS)
2114 if (!STRING_EMPTY (&decl))
2116 string_prepend (&decl, " ");
2118 string_prepend (&decl, "const");
2134 /* A qualified name, such as "Outer::Inner". */
2136 success = demangle_qualified (work, mangled, result, 0, 1);
2140 success = demangle_fund_type (work, mangled, result);
2146 if (!STRING_EMPTY (&decl))
2148 string_append (result, " ");
2149 string_appends (result, &decl);
2154 string_delete (result);
2156 string_delete (&decl);
2160 /* Given a pointer to a type string that represents a fundamental type
2161 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2162 string in which the demangled output is being built in RESULT, and
2163 the WORK structure, decode the types and add them to the result.
2168 "Sl" => "signed long"
2169 "CUs" => "const unsigned short"
2174 demangle_fund_type (work, mangled, result)
2175 struct work_stuff *work;
2176 const char **mangled;
2182 /* First pick off any type qualifiers. There can be more than one. */
2190 if (PRINT_ANSI_QUALIFIERS)
2192 APPEND_BLANK (result);
2193 string_append (result, "const");
2198 APPEND_BLANK (result);
2199 string_append (result, "unsigned");
2201 case 'S': /* signed char only */
2203 APPEND_BLANK (result);
2204 string_append (result, "signed");
2208 if (PRINT_ANSI_QUALIFIERS)
2210 APPEND_BLANK (result);
2211 string_append (result, "volatile");
2220 /* Now pick off the fundamental type. There can be only one. */
2229 APPEND_BLANK (result);
2230 string_append (result, "void");
2234 APPEND_BLANK (result);
2235 string_append (result, "long long");
2239 APPEND_BLANK (result);
2240 string_append (result, "long");
2244 APPEND_BLANK (result);
2245 string_append (result, "int");
2249 APPEND_BLANK (result);
2250 string_append (result, "short");
2254 APPEND_BLANK (result);
2255 string_append (result, "bool");
2259 APPEND_BLANK (result);
2260 string_append (result, "char");
2264 APPEND_BLANK (result);
2265 string_append (result, "wchar_t");
2269 APPEND_BLANK (result);
2270 string_append (result, "long double");
2274 APPEND_BLANK (result);
2275 string_append (result, "double");
2279 APPEND_BLANK (result);
2280 string_append (result, "float");
2284 if (!isdigit (**mangled))
2290 /* An explicit type, such as "6mytype" or "7integer" */
2301 APPEND_BLANK (result);
2302 if (!demangle_class_name (work, mangled, result)) {
2308 success = demangle_template(work,mangled, result, 0);
2318 /* `result' will be initialized in do_type; it will be freed on failure */
2321 do_arg (work, mangled, result)
2322 struct work_stuff *work;
2323 const char **mangled;
2326 const char *start = *mangled;
2328 if (!do_type (work, mangled, result))
2334 remember_type (work, start, *mangled - start);
2340 remember_type (work, start, len)
2341 struct work_stuff *work;
2347 if (work -> ntypes >= work -> typevec_size)
2349 if (work -> typevec_size == 0)
2351 work -> typevec_size = 3;
2353 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2357 work -> typevec_size *= 2;
2359 (char **) xrealloc ((char *)work -> typevec,
2360 sizeof (char *) * work -> typevec_size);
2363 tem = xmalloc (len + 1);
2364 memcpy (tem, start, len);
2366 work -> typevec[work -> ntypes++] = tem;
2369 /* Forget the remembered types, but not the type vector itself. */
2373 struct work_stuff *work;
2377 while (work -> ntypes > 0)
2379 i = --(work -> ntypes);
2380 if (work -> typevec[i] != NULL)
2382 free (work -> typevec[i]);
2383 work -> typevec[i] = NULL;
2388 /* Process the argument list part of the signature, after any class spec
2389 has been consumed, as well as the first 'F' character (if any). For
2392 "__als__3fooRT0" => process "RT0"
2393 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2395 DECLP must be already initialised, usually non-empty. It won't be freed
2398 Note that g++ differs significantly from ARM and lucid style mangling
2399 with regards to references to previously seen types. For example, given
2400 the source fragment:
2404 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2407 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2408 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2410 g++ produces the names:
2415 while lcc (and presumably other ARM style compilers as well) produces:
2417 foo__FiR3fooT1T2T1T2
2418 __ct__3fooFiR3fooT1T2T1T2
2420 Note that g++ bases it's type numbers starting at zero and counts all
2421 previously seen types, while lucid/ARM bases it's type numbers starting
2422 at one and only considers types after it has seen the 'F' character
2423 indicating the start of the function args. For lucid/ARM style, we
2424 account for this difference by discarding any previously seen types when
2425 we see the 'F' character, and subtracting one from the type number
2431 demangle_args (work, mangled, declp)
2432 struct work_stuff *work;
2433 const char **mangled;
2443 if (PRINT_ARG_TYPES)
2445 string_append (declp, "(");
2446 if (**mangled == '\0')
2448 string_append (declp, "void");
2452 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2454 if ((**mangled == 'N') || (**mangled == 'T'))
2456 temptype = *(*mangled)++;
2458 if (temptype == 'N')
2460 if (!get_count (mangled, &r))
2469 if (ARM_DEMANGLING && work -> ntypes >= 10)
2471 /* If we have 10 or more types we might have more than a 1 digit
2472 index so we'll have to consume the whole count here. This
2473 will lose if the next thing is a type name preceded by a
2474 count but it's impossible to demangle that case properly
2475 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2476 Pc, ...)" or "(..., type12, char *, ...)" */
2477 if ((t = consume_count(mangled)) == 0)
2484 if (!get_count (mangled, &t))
2489 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2493 /* Validate the type index. Protect against illegal indices from
2494 malformed type strings. */
2495 if ((t < 0) || (t >= work -> ntypes))
2501 tem = work -> typevec[t];
2502 if (need_comma && PRINT_ARG_TYPES)
2504 string_append (declp, ", ");
2506 if (!do_arg (work, &tem, &arg))
2510 if (PRINT_ARG_TYPES)
2512 string_appends (declp, &arg);
2514 string_delete (&arg);
2520 if (need_comma & PRINT_ARG_TYPES)
2522 string_append (declp, ", ");
2524 if (!do_arg (work, mangled, &arg))
2528 if (PRINT_ARG_TYPES)
2530 string_appends (declp, &arg);
2532 string_delete (&arg);
2537 if (**mangled == 'e')
2540 if (PRINT_ARG_TYPES)
2544 string_append (declp, ",");
2546 string_append (declp, "...");
2550 if (PRINT_ARG_TYPES)
2552 string_append (declp, ")");
2558 demangle_function_name (work, mangled, declp, scan)
2559 struct work_stuff *work;
2560 const char **mangled;
2569 string_appendn (declp, (*mangled), scan - (*mangled));
2570 string_need (declp, 1);
2571 *(declp -> p) = '\0';
2573 /* Consume the function name, including the "__" separating the name
2574 from the signature. We are guaranteed that SCAN points to the
2577 (*mangled) = scan + 2;
2579 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2582 /* See if we have an ARM style constructor or destructor operator.
2583 If so, then just record it, clear the decl, and return.
2584 We can't build the actual constructor/destructor decl until later,
2585 when we recover the class name from the signature. */
2587 if (strcmp (declp -> b, "__ct") == 0)
2589 work -> constructor += 1;
2590 string_clear (declp);
2593 else if (strcmp (declp -> b, "__dt") == 0)
2595 work -> destructor += 1;
2596 string_clear (declp);
2601 if (declp->p - declp->b >= 3
2602 && declp->b[0] == 'o'
2603 && declp->b[1] == 'p'
2604 && strchr (cplus_markers, declp->b[2]) != NULL)
2606 /* see if it's an assignment expression */
2607 if (declp->p - declp->b >= 10 /* op$assign_ */
2608 && memcmp (declp->b + 3, "assign_", 7) == 0)
2610 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2612 len = declp->p - declp->b - 10;
2613 if (strlen (optable[i].in) == len
2614 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2616 string_clear (declp);
2617 string_append (declp, "operator");
2618 string_append (declp, optable[i].out);
2619 string_append (declp, "=");
2626 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2628 int len = declp->p - declp->b - 3;
2629 if (strlen (optable[i].in) == len
2630 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2632 string_clear (declp);
2633 string_append (declp, "operator");
2634 string_append (declp, optable[i].out);
2640 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2641 && strchr (cplus_markers, declp->b[4]) != NULL)
2643 /* type conversion operator */
2645 if (do_type (work, &tem, &type))
2647 string_clear (declp);
2648 string_append (declp, "operator ");
2649 string_appends (declp, &type);
2650 string_delete (&type);
2653 else if (declp->b[0] == '_' && declp->b[1] == '_'
2654 && declp->b[2] == 'o' && declp->b[3] == 'p')
2657 /* type conversion operator. */
2659 if (do_type (work, &tem, &type))
2661 string_clear (declp);
2662 string_append (declp, "operator ");
2663 string_appends (declp, &type);
2664 string_delete (&type);
2667 else if (declp->b[0] == '_' && declp->b[1] == '_'
2668 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2669 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2671 if (declp->b[4] == '\0')
2674 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2676 if (strlen (optable[i].in) == 2
2677 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2679 string_clear (declp);
2680 string_append (declp, "operator");
2681 string_append (declp, optable[i].out);
2688 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2691 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2693 if (strlen (optable[i].in) == 3
2694 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2696 string_clear (declp);
2697 string_append (declp, "operator");
2698 string_append (declp, optable[i].out);
2707 /* a mini string-handling package */
2722 s->p = s->b = xmalloc (n);
2725 else if (s->e - s->p < n)
2730 s->b = xrealloc (s->b, n);
2743 s->b = s->e = s->p = NULL;
2751 s->b = s->p = s->e = NULL;
2767 return (s->b == s->p);
2773 string_append (p, s)
2778 if (s == NULL || *s == '\0')
2782 memcpy (p->p, s, n);
2787 string_appends (p, s)
2796 memcpy (p->p, s->b, n);
2802 string_appendn (p, s, n)
2810 memcpy (p->p, s, n);
2816 string_prepend (p, s)
2820 if (s != NULL && *s != '\0')
2822 string_prependn (p, s, strlen (s));
2827 string_prepends (p, s)
2832 string_prependn (p, s->b, s->p - s->b);
2837 string_prependn (p, s, n)
2847 for (q = p->p - 1; q >= p->b; q--)
2851 memcpy (p->b, s, n);
2856 /* To generate a standalone demangler program for testing purposes,
2857 just compile and link this file with -DMAIN and libiberty.a. When
2858 run, it demangles each command line arg, or each stdin string, and
2859 prints the result on stdout. */
2864 demangle_it (mangled_name)
2869 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2872 printf ("%s\n", mangled_name);
2876 printf ("%s\n", result);
2883 static char *program_name;
2884 static char *program_version = VERSION;
2887 usage (stream, status)
2892 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
2893 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
2894 [--help] [--version] [arg...]\n",
2899 #define MBUF_SIZE 512
2900 char mbuffer[MBUF_SIZE];
2902 /* Defined in the automatically-generated underscore.c. */
2903 extern int prepends_underscore;
2905 int strip_underscore = 0;
2907 static struct option long_options[] = {
2908 {"strip-underscores", no_argument, 0, '_'},
2909 {"format", required_argument, 0, 's'},
2910 {"help", no_argument, 0, 'h'},
2911 {"no-strip-underscores", no_argument, 0, 'n'},
2912 {"version", no_argument, 0, 'v'},
2913 {0, no_argument, 0, 0}
2924 program_name = argv[0];
2926 strip_underscore = prepends_underscore;
2928 while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
2938 strip_underscore = 0;
2941 printf ("GNU %s version %s\n", program_name, program_version);
2944 strip_underscore = 1;
2947 if (strcmp (optarg, "gnu") == 0)
2949 current_demangling_style = gnu_demangling;
2951 else if (strcmp (optarg, "lucid") == 0)
2953 current_demangling_style = lucid_demangling;
2955 else if (strcmp (optarg, "arm") == 0)
2957 current_demangling_style = arm_demangling;
2961 fprintf (stderr, "%s: unknown demangling style `%s'\n",
2962 program_name, optarg);
2971 for ( ; optind < argc; optind++)
2973 demangle_it (argv[optind]);
2982 /* Try to read a label. */
2983 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
2985 if (i >= MBUF_SIZE-1)
2994 if (mbuffer[0] == '.')
2996 if (strip_underscore && mbuffer[skip_first] == '_')
3004 result = cplus_demangle (mbuffer + skip_first,
3005 DMGL_PARAMS | DMGL_ANSI);
3008 if (mbuffer[0] == '.')
3010 fputs (result, stdout);
3014 fputs (mbuffer, stdout);
3031 fprintf (stderr, "%s: %s\n", program_name, str);
3042 register char *value = (char *) malloc (size);
3044 fatal ("virtual memory exhausted");
3049 xrealloc (ptr, size)
3053 register char *value = (char *) realloc (ptr, size);
3055 fatal ("virtual memory exhausted");