1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996 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
33 #undef CURRENT_DEMANGLING_STYLE
34 #define CURRENT_DEMANGLING_STYLE work->options
36 extern char *xmalloc PARAMS((unsigned));
37 extern char *xrealloc PARAMS((char *, unsigned));
43 register char *p = s1;
44 register int len = strlen (s2);
46 for (; (p = strchr (p, *s2)) != 0; p++)
48 if (strncmp (p, s2, len) == 0)
56 /* In order to allow a single demangler executable to demangle strings
57 using various common values of CPLUS_MARKER, as well as any specific
58 one set at compile time, we maintain a string containing all the
59 commonly used ones, and check to see if the marker we are looking for
60 is in that string. CPLUS_MARKER is usually '$' on systems where the
61 assembler can deal with that. Where the assembler can't, it's usually
62 '.' (but on many systems '.' is used for other things). We put the
63 current defined CPLUS_MARKER first (which defaults to '$'), followed
64 by the next most common value, followed by an explicit '$' in case
65 the value of CPLUS_MARKER is not '$'.
67 We could avoid this if we could just get g++ to tell us what the actual
68 cplus marker character is as part of the debug information, perhaps by
69 ensuring that it is the character that terminates the gcc<n>_compiled
70 marker symbol (FIXME). */
72 #if !defined (CPLUS_MARKER)
73 #define CPLUS_MARKER '$'
76 enum demangling_styles current_demangling_style = gnu_demangling;
78 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
81 set_cplus_marker_for_demangling (ch)
84 cplus_markers[0] = ch;
87 /* Stuff that is shared between sub-routines.
88 * Using a shared structure allows cplus_demangle to be reentrant. */
98 int static_type; /* A static member function */
99 int const_type; /* A const member function */
102 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
103 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
105 static const struct optable
111 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
112 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
113 {"new", " new", 0}, /* old (1.91, and 1.x) */
114 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
115 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
116 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
117 {"as", "=", DMGL_ANSI}, /* ansi */
118 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
119 {"eq", "==", DMGL_ANSI}, /* old, ansi */
120 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
121 {"gt", ">", DMGL_ANSI}, /* old, ansi */
122 {"le", "<=", DMGL_ANSI}, /* old, ansi */
123 {"lt", "<", DMGL_ANSI}, /* old, ansi */
124 {"plus", "+", 0}, /* old */
125 {"pl", "+", DMGL_ANSI}, /* ansi */
126 {"apl", "+=", DMGL_ANSI}, /* ansi */
127 {"minus", "-", 0}, /* old */
128 {"mi", "-", DMGL_ANSI}, /* ansi */
129 {"ami", "-=", DMGL_ANSI}, /* ansi */
130 {"mult", "*", 0}, /* old */
131 {"ml", "*", DMGL_ANSI}, /* ansi */
132 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
133 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
134 {"convert", "+", 0}, /* old (unary +) */
135 {"negate", "-", 0}, /* old (unary -) */
136 {"trunc_mod", "%", 0}, /* old */
137 {"md", "%", DMGL_ANSI}, /* ansi */
138 {"amd", "%=", DMGL_ANSI}, /* ansi */
139 {"trunc_div", "/", 0}, /* old */
140 {"dv", "/", DMGL_ANSI}, /* ansi */
141 {"adv", "/=", DMGL_ANSI}, /* ansi */
142 {"truth_andif", "&&", 0}, /* old */
143 {"aa", "&&", DMGL_ANSI}, /* ansi */
144 {"truth_orif", "||", 0}, /* old */
145 {"oo", "||", DMGL_ANSI}, /* ansi */
146 {"truth_not", "!", 0}, /* old */
147 {"nt", "!", DMGL_ANSI}, /* ansi */
148 {"postincrement","++", 0}, /* old */
149 {"pp", "++", DMGL_ANSI}, /* ansi */
150 {"postdecrement","--", 0}, /* old */
151 {"mm", "--", DMGL_ANSI}, /* ansi */
152 {"bit_ior", "|", 0}, /* old */
153 {"or", "|", DMGL_ANSI}, /* ansi */
154 {"aor", "|=", DMGL_ANSI}, /* ansi */
155 {"bit_xor", "^", 0}, /* old */
156 {"er", "^", DMGL_ANSI}, /* ansi */
157 {"aer", "^=", DMGL_ANSI}, /* ansi */
158 {"bit_and", "&", 0}, /* old */
159 {"ad", "&", DMGL_ANSI}, /* ansi */
160 {"aad", "&=", DMGL_ANSI}, /* ansi */
161 {"bit_not", "~", 0}, /* old */
162 {"co", "~", DMGL_ANSI}, /* ansi */
163 {"call", "()", 0}, /* old */
164 {"cl", "()", DMGL_ANSI}, /* ansi */
165 {"alshift", "<<", 0}, /* old */
166 {"ls", "<<", DMGL_ANSI}, /* ansi */
167 {"als", "<<=", DMGL_ANSI}, /* ansi */
168 {"arshift", ">>", 0}, /* old */
169 {"rs", ">>", DMGL_ANSI}, /* ansi */
170 {"ars", ">>=", DMGL_ANSI}, /* ansi */
171 {"component", "->", 0}, /* old */
172 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
173 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
174 {"indirect", "*", 0}, /* old */
175 {"method_call", "->()", 0}, /* old */
176 {"addr", "&", 0}, /* old (unary &) */
177 {"array", "[]", 0}, /* old */
178 {"vc", "[]", DMGL_ANSI}, /* ansi */
179 {"compound", ", ", 0}, /* old */
180 {"cm", ", ", DMGL_ANSI}, /* ansi */
181 {"cond", "?:", 0}, /* old */
182 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
183 {"max", ">?", 0}, /* old */
184 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
185 {"min", "<?", 0}, /* old */
186 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
187 {"nop", "", 0}, /* old (for operator=) */
188 {"rm", "->*", DMGL_ANSI} /* ansi */
192 typedef struct string /* Beware: these aren't required to be */
193 { /* '\0' terminated. */
194 char *b; /* pointer to start of string */
195 char *p; /* pointer after last character */
196 char *e; /* pointer after end of allocated space */
199 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
200 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
201 string_prepend(str, " ");}
202 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
203 string_append(str, " ");}
205 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
206 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
208 /* Prototypes for local functions */
211 mop_up PARAMS ((struct work_stuff *, string *, int));
215 demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
219 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
223 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
227 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
230 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
233 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
236 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
239 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
242 arm_special PARAMS ((struct work_stuff *, const char **, string *));
245 string_need PARAMS ((string *, int));
248 string_delete PARAMS ((string *));
251 string_init PARAMS ((string *));
254 string_clear PARAMS ((string *));
258 string_empty PARAMS ((string *));
262 string_append PARAMS ((string *, const char *));
265 string_appends PARAMS ((string *, string *));
268 string_appendn PARAMS ((string *, const char *, int));
271 string_prepend PARAMS ((string *, const char *));
274 string_prependn PARAMS ((string *, const char *, int));
277 get_count PARAMS ((const char **, int *));
280 consume_count PARAMS ((const char **));
283 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
286 do_type PARAMS ((struct work_stuff *, const char **, string *));
289 do_arg PARAMS ((struct work_stuff *, const char **, string *));
292 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
296 remember_type PARAMS ((struct work_stuff *, const char *, int));
299 forget_types PARAMS ((struct work_stuff *));
302 string_prepends PARAMS ((string *, string *));
304 /* Translate count to integer, consuming tokens in the process.
305 Conversion terminates on the first non-digit character.
306 Trying to consume something that isn't a count results in
307 no consumption of input and a return of 0. */
315 while (isdigit (**type))
318 count += **type - '0';
325 cplus_demangle_opname (opname, result, options)
330 int len, i, len1, ret;
332 struct work_stuff work[1];
335 len = strlen(opname);
338 work->options = options;
340 if (opname[0] == '_' && opname[1] == '_'
341 && opname[2] == 'o' && opname[3] == 'p')
344 /* type conversion operator. */
346 if (do_type (work, &tem, &type))
348 strcat (result, "operator ");
349 strncat (result, type.b, type.p - type.b);
350 string_delete (&type);
354 else if (opname[0] == '_' && opname[1] == '_'
355 && opname[2] >= 'a' && opname[2] <= 'z'
356 && opname[3] >= 'a' && opname[3] <= 'z')
358 if (opname[4] == '\0')
361 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
363 if (strlen (optable[i].in) == 2
364 && memcmp (optable[i].in, opname + 2, 2) == 0)
366 strcat (result, "operator");
367 strcat (result, optable[i].out);
375 if (opname[2] == 'a' && opname[5] == '\0')
378 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
380 if (strlen (optable[i].in) == 3
381 && memcmp (optable[i].in, opname + 2, 3) == 0)
383 strcat (result, "operator");
384 strcat (result, optable[i].out);
395 && strchr (cplus_markers, opname[2]) != NULL)
397 /* see if it's an assignment expression */
398 if (len >= 10 /* op$assign_ */
399 && memcmp (opname + 3, "assign_", 7) == 0)
401 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
404 if (strlen (optable[i].in) == len1
405 && memcmp (optable[i].in, opname + 10, len1) == 0)
407 strcat (result, "operator");
408 strcat (result, optable[i].out);
409 strcat (result, "=");
417 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
420 if (strlen (optable[i].in) == len1
421 && memcmp (optable[i].in, opname + 3, len1) == 0)
423 strcat (result, "operator");
424 strcat (result, optable[i].out);
431 else if (len >= 5 && memcmp (opname, "type", 4) == 0
432 && strchr (cplus_markers, opname[4]) != NULL)
434 /* type conversion operator */
436 if (do_type (work, &tem, &type))
438 strcat (result, "operator ");
439 strncat (result, type.b, type.p - type.b);
440 string_delete (&type);
447 /* Takes operator name as e.g. "++" and returns mangled
448 operator name (e.g. "postincrement_expr"), or NULL if not found.
450 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
451 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
454 cplus_mangle_opname (opname, options)
461 len = strlen (opname);
462 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
464 if (strlen (optable[i].out) == len
465 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
466 && memcmp (optable[i].out, opname, len) == 0)
467 return optable[i].in;
472 /* check to see whether MANGLED can match TEXT in the first TEXT_LEN
475 int cplus_match (mangled, text, text_len)
480 if (strncmp (mangled, text, text_len) != 0) {
481 return(0); /* cannot match either */
483 return(1); /* matches mangled, may match demangled */
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
631 demangle_signature (work, mangled, declp)
632 struct work_stuff *work;
633 const char **mangled;
639 const char *oldmangled = NULL;
643 while (success && (**mangled != '\0'))
648 oldmangled = *mangled;
649 success = demangle_qualified (work, mangled, declp, 1, 0);
652 remember_type (work, oldmangled, *mangled - oldmangled);
654 if (AUTO_DEMANGLING || GNU_DEMANGLING)
662 /* Static member function */
663 if (oldmangled == NULL)
665 oldmangled = *mangled;
668 work -> static_type = 1;
672 /* a const member function */
673 if (oldmangled == NULL)
675 oldmangled = *mangled;
678 work -> const_type = 1;
681 case '0': case '1': case '2': case '3': case '4':
682 case '5': case '6': case '7': case '8': case '9':
683 if (oldmangled == NULL)
685 oldmangled = *mangled;
687 success = demangle_class (work, mangled, declp);
690 remember_type (work, oldmangled, *mangled - oldmangled);
692 if (AUTO_DEMANGLING || GNU_DEMANGLING)
701 /* ARM style demangling includes a specific 'F' character after
702 the class name. For GNU style, it is just implied. So we can
703 safely just consume any 'F' at this point and be compatible
704 with either style. */
710 /* For lucid/ARM style we have to forget any types we might
711 have remembered up to this point, since they were not argument
712 types. GNU style considers all types seen as available for
713 back references. See comment in demangle_args() */
715 if (LUCID_DEMANGLING || ARM_DEMANGLING)
719 success = demangle_args (work, mangled, declp);
724 string_init(&trawname);
726 if (oldmangled == NULL)
728 oldmangled = *mangled;
730 success = demangle_template (work, mangled, &tname, &trawname);
733 remember_type (work, oldmangled, *mangled - oldmangled);
735 string_append(&tname, "::");
736 string_prepends(declp, &tname);
737 if (work -> destructor & 1)
739 string_prepend (&trawname, "~");
740 string_appends (declp, &trawname);
741 work->destructor -= 1;
743 if ((work->constructor & 1) || (work->destructor & 1))
745 string_appends (declp, &trawname);
746 work->constructor -= 1;
748 string_delete(&trawname);
749 string_delete(&tname);
755 /* At the outermost level, we cannot have a return type specified,
756 so if we run into another '_' at this point we are dealing with
757 a mangled name that is either bogus, or has been mangled by
758 some algorithm we don't know how to deal with. So just
759 reject the entire demangling. */
764 if (AUTO_DEMANGLING || GNU_DEMANGLING)
766 /* Assume we have stumbled onto the first outermost function
767 argument token, and start processing args. */
769 success = demangle_args (work, mangled, declp);
773 /* Non-GNU demanglers use a specific token to mark the start
774 of the outermost function argument tokens. Typically 'F',
775 for ARM-demangling, for example. So if we find something
776 we are not prepared for, it must be an error. */
782 if (AUTO_DEMANGLING || GNU_DEMANGLING)
785 if (success && expect_func)
788 success = demangle_args (work, mangled, declp);
792 if (success && !func_done)
794 if (AUTO_DEMANGLING || GNU_DEMANGLING)
796 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
797 bar__3fooi is 'foo::bar(int)'. We get here when we find the
798 first case, and need to ensure that the '(void)' gets added to
799 the current declp. Note that with ARM, the first case
800 represents the name of a static data member 'foo::bar',
801 which is in the current declp, so we leave it alone. */
802 success = demangle_args (work, mangled, declp);
805 if (success && work -> static_type && PRINT_ARG_TYPES)
807 string_append (declp, " static");
809 if (success && work -> const_type && PRINT_ARG_TYPES)
811 string_append (declp, " const");
819 demangle_method_args (work, mangled, declp)
820 struct work_stuff *work;
821 const char **mangled;
826 if (work -> static_type)
828 string_append (declp, *mangled + 1);
829 *mangled += strlen (*mangled);
834 success = demangle_args (work, mangled, declp);
842 demangle_template (work, mangled, tname, trawname)
843 struct work_stuff *work;
844 const char **mangled;
865 /* get template name */
866 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
871 string_appendn (trawname, *mangled, r);
872 string_appendn (tname, *mangled, r);
874 string_append (tname, "<");
875 /* get size of template parameter list */
876 if (!get_count (mangled, &r))
880 for (i = 0; i < r; i++)
884 string_append (tname, ", ");
886 /* Z for type parameters */
887 if (**mangled == 'Z')
890 /* temp is initialized in do_type */
891 success = do_type (work, mangled, &temp);
894 string_appends (tname, &temp);
896 string_delete(&temp);
904 /* otherwise, value parameter */
912 /* temp is initialized in do_type */
913 success = do_type (work, mangled, &temp);
917 string_appends (tname, &temp);
920 string_delete(&temp);
926 string_append (tname, "=");
928 while (*old_p && !done)
935 done = is_pointer = 1;
937 case 'C': /* const */
938 case 'S': /* explicitly signed [char] */
939 case 'U': /* unsigned */
940 case 'V': /* volatile */
941 case 'F': /* function */
942 case 'M': /* member function */
946 case 'Q': /* qualified name */
947 done = is_integral = 1;
949 case 'T': /* remembered type */
955 case 'x': /* long long */
958 case 's': /* short */
959 case 'w': /* wchar_t */
960 done = is_integral = 1;
968 case 'r': /* long double */
969 case 'd': /* double */
970 case 'f': /* float */
974 /* it's probably user defined type, let's assume
975 it's integral, it seems hard to figure out
977 done = is_integral = 1;
982 if (**mangled == 'm')
984 string_appendn (tname, "-", 1);
987 while (isdigit (**mangled))
989 string_appendn (tname, *mangled, 1);
997 if (**mangled == 'm')
999 string_appendn (tname, "-", 1);
1002 string_appendn (tname, "'", 1);
1003 val = consume_count(mangled);
1011 string_appendn (tname, &tmp[0], 1);
1012 string_appendn (tname, "'", 1);
1016 int val = consume_count (mangled);
1018 string_appendn (tname, "false", 5);
1020 string_appendn (tname, "true", 4);
1026 if (**mangled == 'm')
1028 string_appendn (tname, "-", 1);
1031 while (isdigit (**mangled))
1033 string_appendn (tname, *mangled, 1);
1036 if (**mangled == '.') /* fraction */
1038 string_appendn (tname, ".", 1);
1040 while (isdigit (**mangled))
1042 string_appendn (tname, *mangled, 1);
1046 if (**mangled == 'e') /* exponent */
1048 string_appendn (tname, "e", 1);
1050 while (isdigit (**mangled))
1052 string_appendn (tname, *mangled, 1);
1057 else if (is_pointer)
1059 if (!get_count (mangled, &symbol_len))
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);
1611 arm_special -- special handling of ARM/lucid mangled strings
1616 arm_special (struct work_stuff *work, const char **mangled,
1622 Process some special ARM style mangling forms that don't fit
1623 the normal pattern. For example:
1625 __vtbl__3foo (foo virtual table)
1626 __vtbl__3foo__3bar (bar::foo virtual table)
1631 arm_special (work, mangled, declp)
1632 struct work_stuff *work;
1633 const char **mangled;
1640 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1642 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1643 and create the decl. Note that we consume the entire mangled
1644 input string, which means that demangle_signature has no work
1646 scan = *mangled + ARM_VTABLE_STRLEN;
1647 while (*scan != '\0') /* first check it can be demangled */
1649 n = consume_count (&scan);
1652 return (0); /* no good */
1655 if (scan[0] == '_' && scan[1] == '_')
1660 (*mangled) += ARM_VTABLE_STRLEN;
1661 while (**mangled != '\0')
1663 n = consume_count (mangled);
1664 string_prependn (declp, *mangled, n);
1666 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1668 string_prepend (declp, "::");
1672 string_append (declp, " virtual table");
1685 demangle_qualified -- demangle 'Q' qualified name strings
1690 demangle_qualified (struct work_stuff *, const char *mangled,
1691 string *result, int isfuncname, int append);
1695 Demangle a qualified name, such as "Q25Outer5Inner" which is
1696 the mangled form of "Outer::Inner". The demangled output is
1697 prepended or appended to the result string according to the
1698 state of the append flag.
1700 If isfuncname is nonzero, then the qualified name we are building
1701 is going to be used as a member function name, so if it is a
1702 constructor or destructor function, append an appropriate
1703 constructor or destructor name. I.E. for the above example,
1704 the result for use as a constructor is "Outer::Inner::Inner"
1705 and the result for use as a destructor is "Outer::Inner::~Inner".
1709 Numeric conversion is ASCII dependent (FIXME).
1714 demangle_qualified (work, mangled, result, isfuncname, append)
1715 struct work_stuff *work;
1716 const char **mangled;
1728 string_init (&temp);
1729 switch ((*mangled)[1])
1732 /* GNU mangled name with more than 9 classes. The count is preceded
1733 by an underscore (to distinguish it from the <= 9 case) and followed
1734 by an underscore. */
1736 qualifiers = atoi (p);
1737 if (!isdigit (*p) || *p == '0')
1740 /* Skip the digits. */
1741 while (isdigit (*p))
1759 /* The count is in a single digit. */
1760 num[0] = (*mangled)[1];
1762 qualifiers = atoi (num);
1764 /* If there is an underscore after the digit, skip it. This is
1765 said to be for ARM-qualified names, but the ARM makes no
1766 mention of such an underscore. Perhaps cfront uses one. */
1767 if ((*mangled)[2] == '_')
1782 /* Pick off the names and collect them in the temp buffer in the order
1783 in which they are found, separated by '::'. */
1785 while (qualifiers-- > 0)
1787 if (*mangled[0] == '_')
1788 *mangled = *mangled + 1;
1789 if (*mangled[0] == 't')
1791 success = demangle_template(work, mangled, &temp, 0);
1792 if (!success) break;
1796 namelength = consume_count (mangled);
1797 if (strlen (*mangled) < namelength)
1799 /* Simple sanity check failed */
1803 string_appendn (&temp, *mangled, namelength);
1804 *mangled += namelength;
1808 string_appendn (&temp, "::", 2);
1812 /* If we are using the result as a function name, we need to append
1813 the appropriate '::' separated constructor or destructor name.
1814 We do this here because this is the most convenient place, where
1815 we already have a pointer to the name and the length of the name. */
1817 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
1819 string_appendn (&temp, "::", 2);
1820 if (work -> destructor & 1)
1822 string_append (&temp, "~");
1824 string_appendn (&temp, (*mangled) - namelength, namelength);
1827 /* Now either prepend the temp buffer to the result, or append it,
1828 depending upon the state of the append flag. */
1832 string_appends (result, &temp);
1836 if (!STRING_EMPTY (result))
1838 string_appendn (&temp, "::", 2);
1840 string_prepends (result, &temp);
1843 string_delete (&temp);
1851 get_count -- convert an ascii count to integer, consuming tokens
1856 get_count (const char **type, int *count)
1860 Return 0 if no conversion is performed, 1 if a string is converted.
1864 get_count (type, count)
1871 if (!isdigit (**type))
1877 *count = **type - '0';
1879 if (isdigit (**type))
1889 while (isdigit (*p));
1900 /* result will be initialised here; it will be freed on failure */
1903 do_type (work, mangled, result)
1904 struct work_stuff *work;
1905 const char **mangled;
1912 const char *remembered_type;
1916 string_init (&decl);
1917 string_init (result);
1921 while (success && !done)
1927 /* A pointer type */
1931 string_prepend (&decl, "*");
1934 /* A reference type */
1937 string_prepend (&decl, "&");
1943 const char *p = ++(*mangled);
1945 string_prepend (&decl, "(");
1946 string_append (&decl, ")[");
1947 /* Copy anything up until the next underscore (the size of the
1949 while (**mangled && **mangled != '_')
1951 if (**mangled == '_')
1953 string_appendn (&decl, p, *mangled - p);
1954 string_append (&decl, "]");
1962 /* A back reference to a previously seen type */
1965 if (!get_count (mangled, &n) || n >= work -> ntypes)
1971 remembered_type = work -> typevec[n];
1972 mangled = &remembered_type;
1979 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
1981 string_prepend (&decl, "(");
1982 string_append (&decl, ")");
1984 /* After picking off the function args, we expect to either find the
1985 function return type (preceded by an '_') or the end of the
1987 if (!demangle_args (work, mangled, &decl)
1988 || (**mangled != '_' && **mangled != '\0'))
1992 if (success && (**mangled == '_'))
2004 member = **mangled == 'M';
2006 if (!isdigit (**mangled))
2011 n = consume_count (mangled);
2012 if (strlen (*mangled) < n)
2017 string_append (&decl, ")");
2018 string_prepend (&decl, "::");
2019 string_prependn (&decl, *mangled, n);
2020 string_prepend (&decl, "(");
2024 if (**mangled == 'C')
2029 if (**mangled == 'V')
2034 if (*(*mangled)++ != 'F')
2040 if ((member && !demangle_args (work, mangled, &decl))
2041 || **mangled != '_')
2047 if (! PRINT_ANSI_QUALIFIERS)
2053 APPEND_BLANK (&decl);
2054 string_append (&decl, "const");
2058 APPEND_BLANK (&decl);
2059 string_append (&decl, "volatile");
2070 if ((*mangled)[1] == 'P')
2073 if (PRINT_ANSI_QUALIFIERS)
2075 if (!STRING_EMPTY (&decl))
2077 string_prepend (&decl, " ");
2079 string_prepend (&decl, "const");
2095 /* A qualified name, such as "Outer::Inner". */
2097 success = demangle_qualified (work, mangled, result, 0, 1);
2101 success = demangle_fund_type (work, mangled, result);
2107 if (!STRING_EMPTY (&decl))
2109 string_append (result, " ");
2110 string_appends (result, &decl);
2115 string_delete (result);
2117 string_delete (&decl);
2121 /* Given a pointer to a type string that represents a fundamental type
2122 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2123 string in which the demangled output is being built in RESULT, and
2124 the WORK structure, decode the types and add them to the result.
2129 "Sl" => "signed long"
2130 "CUs" => "const unsigned short"
2135 demangle_fund_type (work, mangled, result)
2136 struct work_stuff *work;
2137 const char **mangled;
2143 /* First pick off any type qualifiers. There can be more than one. */
2151 if (PRINT_ANSI_QUALIFIERS)
2153 APPEND_BLANK (result);
2154 string_append (result, "const");
2159 APPEND_BLANK (result);
2160 string_append (result, "unsigned");
2162 case 'S': /* signed char only */
2164 APPEND_BLANK (result);
2165 string_append (result, "signed");
2169 if (PRINT_ANSI_QUALIFIERS)
2171 APPEND_BLANK (result);
2172 string_append (result, "volatile");
2181 /* Now pick off the fundamental type. There can be only one. */
2190 APPEND_BLANK (result);
2191 string_append (result, "void");
2195 APPEND_BLANK (result);
2196 string_append (result, "long long");
2200 APPEND_BLANK (result);
2201 string_append (result, "long");
2205 APPEND_BLANK (result);
2206 string_append (result, "int");
2210 APPEND_BLANK (result);
2211 string_append (result, "short");
2215 APPEND_BLANK (result);
2216 string_append (result, "bool");
2220 APPEND_BLANK (result);
2221 string_append (result, "char");
2225 APPEND_BLANK (result);
2226 string_append (result, "wchar_t");
2230 APPEND_BLANK (result);
2231 string_append (result, "long double");
2235 APPEND_BLANK (result);
2236 string_append (result, "double");
2240 APPEND_BLANK (result);
2241 string_append (result, "float");
2245 if (!isdigit (**mangled))
2251 /* An explicit type, such as "6mytype" or "7integer" */
2262 APPEND_BLANK (result);
2263 if (!demangle_class_name (work, mangled, result)) {
2269 success = demangle_template(work,mangled, result, 0);
2279 /* `result' will be initialized in do_type; it will be freed on failure */
2282 do_arg (work, mangled, result)
2283 struct work_stuff *work;
2284 const char **mangled;
2287 const char *start = *mangled;
2289 if (!do_type (work, mangled, result))
2295 remember_type (work, start, *mangled - start);
2301 remember_type (work, start, len)
2302 struct work_stuff *work;
2308 if (work -> ntypes >= work -> typevec_size)
2310 if (work -> typevec_size == 0)
2312 work -> typevec_size = 3;
2314 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2318 work -> typevec_size *= 2;
2320 (char **) xrealloc ((char *)work -> typevec,
2321 sizeof (char *) * work -> typevec_size);
2324 tem = xmalloc (len + 1);
2325 memcpy (tem, start, len);
2327 work -> typevec[work -> ntypes++] = tem;
2330 /* Forget the remembered types, but not the type vector itself. */
2334 struct work_stuff *work;
2338 while (work -> ntypes > 0)
2340 i = --(work -> ntypes);
2341 if (work -> typevec[i] != NULL)
2343 free (work -> typevec[i]);
2344 work -> typevec[i] = NULL;
2349 /* Process the argument list part of the signature, after any class spec
2350 has been consumed, as well as the first 'F' character (if any). For
2353 "__als__3fooRT0" => process "RT0"
2354 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2356 DECLP must be already initialised, usually non-empty. It won't be freed
2359 Note that g++ differs significantly from ARM and lucid style mangling
2360 with regards to references to previously seen types. For example, given
2361 the source fragment:
2365 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2368 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2369 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2371 g++ produces the names:
2376 while lcc (and presumably other ARM style compilers as well) produces:
2378 foo__FiR3fooT1T2T1T2
2379 __ct__3fooFiR3fooT1T2T1T2
2381 Note that g++ bases it's type numbers starting at zero and counts all
2382 previously seen types, while lucid/ARM bases it's type numbers starting
2383 at one and only considers types after it has seen the 'F' character
2384 indicating the start of the function args. For lucid/ARM style, we
2385 account for this difference by discarding any previously seen types when
2386 we see the 'F' character, and subtracting one from the type number
2392 demangle_args (work, mangled, declp)
2393 struct work_stuff *work;
2394 const char **mangled;
2404 if (PRINT_ARG_TYPES)
2406 string_append (declp, "(");
2407 if (**mangled == '\0')
2409 string_append (declp, "void");
2413 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2415 if ((**mangled == 'N') || (**mangled == 'T'))
2417 temptype = *(*mangled)++;
2419 if (temptype == 'N')
2421 if (!get_count (mangled, &r))
2430 if (ARM_DEMANGLING && work -> ntypes >= 10)
2432 /* If we have 10 or more types we might have more than a 1 digit
2433 index so we'll have to consume the whole count here. This
2434 will lose if the next thing is a type name preceded by a
2435 count but it's impossible to demangle that case properly
2436 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2437 Pc, ...)" or "(..., type12, char *, ...)" */
2438 if ((t = consume_count(mangled)) == 0)
2445 if (!get_count (mangled, &t))
2450 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2454 /* Validate the type index. Protect against illegal indices from
2455 malformed type strings. */
2456 if ((t < 0) || (t >= work -> ntypes))
2462 tem = work -> typevec[t];
2463 if (need_comma && PRINT_ARG_TYPES)
2465 string_append (declp, ", ");
2467 if (!do_arg (work, &tem, &arg))
2471 if (PRINT_ARG_TYPES)
2473 string_appends (declp, &arg);
2475 string_delete (&arg);
2481 if (need_comma & PRINT_ARG_TYPES)
2483 string_append (declp, ", ");
2485 if (!do_arg (work, mangled, &arg))
2489 if (PRINT_ARG_TYPES)
2491 string_appends (declp, &arg);
2493 string_delete (&arg);
2498 if (**mangled == 'e')
2501 if (PRINT_ARG_TYPES)
2505 string_append (declp, ",");
2507 string_append (declp, "...");
2511 if (PRINT_ARG_TYPES)
2513 string_append (declp, ")");
2519 demangle_function_name (work, mangled, declp, scan)
2520 struct work_stuff *work;
2521 const char **mangled;
2530 string_appendn (declp, (*mangled), scan - (*mangled));
2531 string_need (declp, 1);
2532 *(declp -> p) = '\0';
2534 /* Consume the function name, including the "__" separating the name
2535 from the signature. We are guaranteed that SCAN points to the
2538 (*mangled) = scan + 2;
2540 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2543 /* See if we have an ARM style constructor or destructor operator.
2544 If so, then just record it, clear the decl, and return.
2545 We can't build the actual constructor/destructor decl until later,
2546 when we recover the class name from the signature. */
2548 if (strcmp (declp -> b, "__ct") == 0)
2550 work -> constructor += 1;
2551 string_clear (declp);
2554 else if (strcmp (declp -> b, "__dt") == 0)
2556 work -> destructor += 1;
2557 string_clear (declp);
2562 if (declp->p - declp->b >= 3
2563 && declp->b[0] == 'o'
2564 && declp->b[1] == 'p'
2565 && strchr (cplus_markers, declp->b[2]) != NULL)
2567 /* see if it's an assignment expression */
2568 if (declp->p - declp->b >= 10 /* op$assign_ */
2569 && memcmp (declp->b + 3, "assign_", 7) == 0)
2571 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2573 len = declp->p - declp->b - 10;
2574 if (strlen (optable[i].in) == len
2575 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2577 string_clear (declp);
2578 string_append (declp, "operator");
2579 string_append (declp, optable[i].out);
2580 string_append (declp, "=");
2587 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2589 int len = declp->p - declp->b - 3;
2590 if (strlen (optable[i].in) == len
2591 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2593 string_clear (declp);
2594 string_append (declp, "operator");
2595 string_append (declp, optable[i].out);
2601 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2602 && strchr (cplus_markers, declp->b[4]) != NULL)
2604 /* type conversion operator */
2606 if (do_type (work, &tem, &type))
2608 string_clear (declp);
2609 string_append (declp, "operator ");
2610 string_appends (declp, &type);
2611 string_delete (&type);
2614 else if (declp->b[0] == '_' && declp->b[1] == '_'
2615 && declp->b[2] == 'o' && declp->b[3] == 'p')
2618 /* type conversion operator. */
2620 if (do_type (work, &tem, &type))
2622 string_clear (declp);
2623 string_append (declp, "operator ");
2624 string_appends (declp, &type);
2625 string_delete (&type);
2628 else if (declp->b[0] == '_' && declp->b[1] == '_'
2629 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2630 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2632 if (declp->b[4] == '\0')
2635 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2637 if (strlen (optable[i].in) == 2
2638 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2640 string_clear (declp);
2641 string_append (declp, "operator");
2642 string_append (declp, optable[i].out);
2649 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2652 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2654 if (strlen (optable[i].in) == 3
2655 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2657 string_clear (declp);
2658 string_append (declp, "operator");
2659 string_append (declp, optable[i].out);
2668 /* a mini string-handling package */
2683 s->p = s->b = xmalloc (n);
2686 else if (s->e - s->p < n)
2691 s->b = xrealloc (s->b, n);
2704 s->b = s->e = s->p = NULL;
2712 s->b = s->p = s->e = NULL;
2728 return (s->b == s->p);
2734 string_append (p, s)
2739 if (s == NULL || *s == '\0')
2743 memcpy (p->p, s, n);
2748 string_appends (p, s)
2757 memcpy (p->p, s->b, n);
2763 string_appendn (p, s, n)
2771 memcpy (p->p, s, n);
2777 string_prepend (p, s)
2781 if (s != NULL && *s != '\0')
2783 string_prependn (p, s, strlen (s));
2788 string_prepends (p, s)
2793 string_prependn (p, s->b, s->p - s->b);
2798 string_prependn (p, s, n)
2808 for (q = p->p - 1; q >= p->b; q--)
2812 memcpy (p->b, s, n);
2817 /* To generate a standalone demangler program for testing purposes,
2818 just compile and link this file with -DMAIN and libiberty.a. When
2819 run, it demangles each command line arg, or each stdin string, and
2820 prints the result on stdout. */
2825 demangle_it (mangled_name)
2830 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2833 printf ("%s\n", mangled_name);
2837 printf ("%s\n", result);
2844 static char *program_name;
2845 static char *program_version = VERSION;
2848 usage (stream, status)
2853 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
2854 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
2855 [--help] [--version] [arg...]\n",
2860 #define MBUF_SIZE 512
2861 char mbuffer[MBUF_SIZE];
2863 /* Defined in the automatically-generated underscore.c. */
2864 extern int prepends_underscore;
2866 int strip_underscore = 0;
2868 static struct option long_options[] = {
2869 {"strip-underscores", no_argument, 0, '_'},
2870 {"format", required_argument, 0, 's'},
2871 {"help", no_argument, 0, 'h'},
2872 {"no-strip-underscores", no_argument, 0, 'n'},
2873 {"version", no_argument, 0, 'v'},
2874 {0, no_argument, 0, 0}
2885 program_name = argv[0];
2887 strip_underscore = prepends_underscore;
2889 while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
2899 strip_underscore = 0;
2902 printf ("GNU %s version %s\n", program_name, program_version);
2905 strip_underscore = 1;
2908 if (strcmp (optarg, "gnu") == 0)
2910 current_demangling_style = gnu_demangling;
2912 else if (strcmp (optarg, "lucid") == 0)
2914 current_demangling_style = lucid_demangling;
2916 else if (strcmp (optarg, "arm") == 0)
2918 current_demangling_style = arm_demangling;
2922 fprintf (stderr, "%s: unknown demangling style `%s'\n",
2923 program_name, optarg);
2932 for ( ; optind < argc; optind++)
2934 demangle_it (argv[optind]);
2943 /* Try to read a label. */
2944 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
2946 if (i >= MBUF_SIZE-1)
2955 if (mbuffer[0] == '.')
2957 if (strip_underscore && mbuffer[skip_first] == '_')
2965 result = cplus_demangle (mbuffer + skip_first,
2966 DMGL_PARAMS | DMGL_ANSI);
2969 if (mbuffer[0] == '.')
2971 fputs (result, stdout);
2975 fputs (mbuffer, stdout);
2992 fprintf (stderr, "%s: %s\n", program_name, str);
3003 register char *value = (char *) malloc (size);
3005 fatal ("virtual memory exhausted");
3010 xrealloc (ptr, size)
3014 register char *value = (char *) realloc (ptr, size);
3016 fatal ("virtual memory exhausted");