1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995 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 ((char *)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 */
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 if (!get_count (mangled, &symbol_len))
1063 string_appendn (tname, *mangled, symbol_len);
1064 *mangled += symbol_len;
1069 if (tname->p[-1] == '>')
1070 string_append (tname, " ");
1071 string_append (tname, ">");
1074 if (work -> static_type)
1076 string_append (declp, *mangled + 1);
1077 *mangled += strlen (*mangled);
1082 success = demangle_args (work, mangled, declp);
1090 arm_pt (work, mangled, n, anchor, args)
1091 struct work_stuff *work;
1092 const char *mangled;
1094 const char **anchor, **args;
1097 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1100 *args = *anchor + 6;
1101 len = consume_count (args);
1102 if (*args + len == mangled + n && **args == '_')
1112 demangle_arm_pt (work, mangled, n, declp)
1113 struct work_stuff *work;
1114 const char **mangled;
1120 const char *e = *mangled + n;
1123 if (arm_pt (work, *mangled, n, &p, &args))
1127 string_appendn (declp, *mangled, p - *mangled);
1128 string_append (declp, "<");
1129 /* should do error checking here */
1131 string_clear (&arg);
1132 do_type (work, &args, &arg);
1133 string_appends (declp, &arg);
1134 string_append (declp, ",");
1136 string_delete (&arg);
1138 string_append (declp, ">");
1142 string_appendn (declp, *mangled, n);
1148 demangle_class_name (work, mangled, declp)
1149 struct work_stuff *work;
1150 const char **mangled;
1156 n = consume_count (mangled);
1157 if (strlen (*mangled) >= n)
1159 demangle_arm_pt (work, mangled, n, declp);
1170 demangle_class -- demangle a mangled class sequence
1175 demangle_class (struct work_stuff *work, const char **mangled,
1180 DECLP points to the buffer into which demangling is being done.
1182 *MANGLED points to the current token to be demangled. On input,
1183 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1184 On exit, it points to the next token after the mangled class on
1185 success, or the first unconsumed token on failure.
1187 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1188 we are demangling a constructor or destructor. In this case
1189 we prepend "class::class" or "class::~class" to DECLP.
1191 Otherwise, we prepend "class::" to the current DECLP.
1193 Reset the constructor/destructor flags once they have been
1194 "consumed". This allows demangle_class to be called later during
1195 the same demangling, to do normal class demangling.
1197 Returns 1 if demangling is successful, 0 otherwise.
1202 demangle_class (work, mangled, declp)
1203 struct work_stuff *work;
1204 const char **mangled;
1210 string_init (&class_name);
1211 if (demangle_class_name (work, mangled, &class_name))
1213 if ((work->constructor & 1) || (work->destructor & 1))
1215 string_prepends (declp, &class_name);
1216 if (work -> destructor & 1)
1218 string_prepend (declp, "~");
1219 work -> destructor -= 1;
1223 work -> constructor -= 1;
1226 string_prepend (declp, "::");
1227 string_prepends (declp, &class_name);
1230 string_delete (&class_name);
1238 demangle_prefix -- consume the mangled name prefix and find signature
1243 demangle_prefix (struct work_stuff *work, const char **mangled,
1248 Consume and demangle the prefix of the mangled name.
1250 DECLP points to the string buffer into which demangled output is
1251 placed. On entry, the buffer is empty. On exit it contains
1252 the root function name, the demangled operator name, or in some
1253 special cases either nothing or the completely demangled result.
1255 MANGLED points to the current pointer into the mangled name. As each
1256 token of the mangled name is consumed, it is updated. Upon entry
1257 the current mangled name pointer points to the first character of
1258 the mangled name. Upon exit, it should point to the first character
1259 of the signature if demangling was successful, or to the first
1260 unconsumed character if demangling of the prefix was unsuccessful.
1262 Returns 1 on success, 0 otherwise.
1266 demangle_prefix (work, mangled, declp)
1267 struct work_stuff *work;
1268 const char **mangled;
1275 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1277 char *marker = strchr (cplus_markers, (*mangled)[8]);
1278 if (marker != NULL && *marker == (*mangled)[10])
1280 if ((*mangled)[9] == 'D')
1282 /* it's a GNU global destructor to be executed at program exit */
1284 work->destructor = 2;
1285 if (gnu_special (work, mangled, declp))
1288 else if ((*mangled)[9] == 'I')
1290 /* it's a GNU global constructor to be executed at program init */
1292 work->constructor = 2;
1293 if (gnu_special (work, mangled, declp))
1298 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1300 /* it's a ARM global destructor to be executed at program exit */
1302 work->destructor = 2;
1304 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1306 /* it's a ARM global constructor to be executed at program initial */
1308 work->constructor = 2;
1311 /* This block of code is a reduction in strength time optimization
1313 scan = mystrstr (*mangled, "__"); */
1319 scan = strchr (scan, '_');
1320 } while (scan != NULL && *++scan != '_');
1322 if (scan != NULL) --scan;
1327 /* We found a sequence of two or more '_', ensure that we start at
1328 the last pair in the sequence. */
1329 i = strspn (scan, "_");
1340 else if (work -> static_type)
1342 if (!isdigit (scan[0]) && (scan[0] != 't'))
1347 else if ((scan == *mangled) &&
1348 (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')))
1350 /* The ARM says nothing about the mangling of local variables.
1351 But cfront mangles local variables by prepending __<nesting_level>
1352 to them. As an extension to ARM demangling we handle this case. */
1353 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1355 *mangled = scan + 2;
1356 consume_count (mangled);
1357 string_append (declp, *mangled);
1358 *mangled += strlen (*mangled);
1363 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1364 names like __Q2_3foo3bar for nested type names. So don't accept
1365 this style of constructor for cfront demangling. */
1366 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1367 work -> constructor += 1;
1368 *mangled = scan + 2;
1371 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1373 /* Mangled name starts with "__". Skip over any leading '_' characters,
1374 then find the next "__" that separates the prefix from the signature.
1376 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1377 || (arm_special (work, mangled, declp) == 0))
1379 while (*scan == '_')
1383 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1385 /* No separator (I.E. "__not_mangled"), or empty signature
1386 (I.E. "__not_mangled_either__") */
1391 demangle_function_name (work, mangled, declp, scan);
1395 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1397 /* Cfront-style parameterized type. Handled later as a signature. */
1401 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1403 else if (*(scan + 2) != '\0')
1405 /* Mangled name does not start with "__" but does have one somewhere
1406 in there with non empty stuff after it. Looks like a global
1408 demangle_function_name (work, mangled, declp, scan);
1412 /* Doesn't look like a mangled name */
1416 if (!success && (work->constructor == 2 || work->destructor == 2))
1418 string_append (declp, *mangled);
1419 *mangled += strlen (*mangled);
1429 gnu_special -- special handling of gnu mangled strings
1434 gnu_special (struct work_stuff *work, const char **mangled,
1440 Process some special GNU style mangling forms that don't fit
1441 the normal pattern. For example:
1443 _$_3foo (destructor for class foo)
1444 _vt$foo (foo virtual table)
1445 _vt$foo$bar (foo::bar virtual table)
1446 __vt_foo (foo virtual table, new style with thunks)
1447 _3foo$varname (static data member)
1448 _Q22rs2tu$vw (static data member)
1449 __t6vector1Zii (constructor with template)
1450 __thunk_4__$_7ostream (virtual function thunk)
1454 gnu_special (work, mangled, declp)
1455 struct work_stuff *work;
1456 const char **mangled;
1463 if ((*mangled)[0] == '_'
1464 && strchr (cplus_markers, (*mangled)[1]) != NULL
1465 && (*mangled)[2] == '_')
1467 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1469 work -> destructor += 1;
1471 else if ((*mangled)[0] == '_'
1472 && (((*mangled)[1] == '_'
1473 && (*mangled)[2] == 'v'
1474 && (*mangled)[3] == 't'
1475 && (*mangled)[4] == '_')
1476 || ((*mangled)[1] == 'v'
1477 && (*mangled)[2] == 't'
1478 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1480 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1481 and create the decl. Note that we consume the entire mangled
1482 input string, which means that demangle_signature has no work
1484 if ((*mangled)[2] == 'v')
1485 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1487 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1488 while (**mangled != '\0')
1490 p = strpbrk (*mangled, cplus_markers);
1494 success = demangle_qualified (work, mangled, declp, 0, 1);
1497 success = demangle_template (work, mangled, declp, 0);
1500 if (isdigit(*mangled[0]))
1502 n = consume_count(mangled);
1506 n = strcspn (*mangled, cplus_markers);
1508 string_appendn (declp, *mangled, n);
1512 if (success && ((p == NULL) || (p == *mangled)))
1516 string_append (declp, "::");
1527 string_append (declp, " virtual table");
1529 else if ((*mangled)[0] == '_'
1530 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1531 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1533 /* static data member, "_3foo$varname" for example */
1538 success = demangle_qualified (work, mangled, declp, 0, 1);
1541 success = demangle_template (work, mangled, declp, 0);
1544 n = consume_count (mangled);
1545 string_appendn (declp, *mangled, n);
1548 if (success && (p == *mangled))
1550 /* Consumed everything up to the cplus_marker, append the
1553 string_append (declp, "::");
1554 n = strlen (*mangled);
1555 string_appendn (declp, *mangled, n);
1563 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1565 int delta = ((*mangled) += 8, consume_count (mangled));
1566 char *method = cplus_demangle (++*mangled, work->options);
1570 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1571 string_append (declp, buf);
1572 string_append (declp, method);
1574 n = strlen (*mangled);
1593 arm_special -- special handling of ARM/lucid mangled strings
1598 arm_special (struct work_stuff *work, const char **mangled,
1604 Process some special ARM style mangling forms that don't fit
1605 the normal pattern. For example:
1607 __vtbl__3foo (foo virtual table)
1608 __vtbl__3foo__3bar (bar::foo virtual table)
1613 arm_special (work, mangled, declp)
1614 struct work_stuff *work;
1615 const char **mangled;
1622 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1624 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1625 and create the decl. Note that we consume the entire mangled
1626 input string, which means that demangle_signature has no work
1628 scan = *mangled + ARM_VTABLE_STRLEN;
1629 while (*scan != '\0') /* first check it can be demangled */
1631 n = consume_count (&scan);
1634 return (0); /* no good */
1637 if (scan[0] == '_' && scan[1] == '_')
1642 (*mangled) += ARM_VTABLE_STRLEN;
1643 while (**mangled != '\0')
1645 n = consume_count (mangled);
1646 string_prependn (declp, *mangled, n);
1648 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1650 string_prepend (declp, "::");
1654 string_append (declp, " virtual table");
1667 demangle_qualified -- demangle 'Q' qualified name strings
1672 demangle_qualified (struct work_stuff *, const char *mangled,
1673 string *result, int isfuncname, int append);
1677 Demangle a qualified name, such as "Q25Outer5Inner" which is
1678 the mangled form of "Outer::Inner". The demangled output is
1679 prepended or appended to the result string according to the
1680 state of the append flag.
1682 If isfuncname is nonzero, then the qualified name we are building
1683 is going to be used as a member function name, so if it is a
1684 constructor or destructor function, append an appropriate
1685 constructor or destructor name. I.E. for the above example,
1686 the result for use as a constructor is "Outer::Inner::Inner"
1687 and the result for use as a destructor is "Outer::Inner::~Inner".
1691 Numeric conversion is ASCII dependent (FIXME).
1696 demangle_qualified (work, mangled, result, isfuncname, append)
1697 struct work_stuff *work;
1698 const char **mangled;
1710 string_init (&temp);
1711 switch ((*mangled)[1])
1714 /* GNU mangled name with more than 9 classes. The count is preceded
1715 by an underscore (to distinguish it from the <= 9 case) and followed
1716 by an underscore. */
1718 qualifiers = atoi (p);
1719 if (!isdigit (*p) || *p == '0')
1722 /* Skip the digits. */
1723 while (isdigit (*p))
1741 /* The count is in a single digit. */
1742 num[0] = (*mangled)[1];
1744 qualifiers = atoi (num);
1746 /* If there is an underscore after the digit, skip it. This is
1747 said to be for ARM-qualified names, but the ARM makes no
1748 mention of such an underscore. Perhaps cfront uses one. */
1749 if ((*mangled)[2] == '_')
1764 /* Pick off the names and collect them in the temp buffer in the order
1765 in which they are found, separated by '::'. */
1767 while (qualifiers-- > 0)
1769 if (*mangled[0] == '_')
1770 *mangled = *mangled + 1;
1771 if (*mangled[0] == 't')
1773 success = demangle_template(work, mangled, &temp, 0);
1774 if (!success) break;
1778 namelength = consume_count (mangled);
1779 if (strlen (*mangled) < namelength)
1781 /* Simple sanity check failed */
1785 string_appendn (&temp, *mangled, namelength);
1786 *mangled += namelength;
1790 string_appendn (&temp, "::", 2);
1794 /* If we are using the result as a function name, we need to append
1795 the appropriate '::' separated constructor or destructor name.
1796 We do this here because this is the most convenient place, where
1797 we already have a pointer to the name and the length of the name. */
1799 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
1801 string_appendn (&temp, "::", 2);
1802 if (work -> destructor & 1)
1804 string_append (&temp, "~");
1806 string_appendn (&temp, (*mangled) - namelength, namelength);
1809 /* Now either prepend the temp buffer to the result, or append it,
1810 depending upon the state of the append flag. */
1814 string_appends (result, &temp);
1818 if (!STRING_EMPTY (result))
1820 string_appendn (&temp, "::", 2);
1822 string_prepends (result, &temp);
1825 string_delete (&temp);
1833 get_count -- convert an ascii count to integer, consuming tokens
1838 get_count (const char **type, int *count)
1842 Return 0 if no conversion is performed, 1 if a string is converted.
1846 get_count (type, count)
1853 if (!isdigit (**type))
1859 *count = **type - '0';
1861 if (isdigit (**type))
1871 while (isdigit (*p));
1882 /* result will be initialised here; it will be freed on failure */
1885 do_type (work, mangled, result)
1886 struct work_stuff *work;
1887 const char **mangled;
1894 const char *remembered_type;
1898 string_init (&decl);
1899 string_init (result);
1903 while (success && !done)
1909 /* A pointer type */
1913 string_prepend (&decl, "*");
1916 /* A reference type */
1919 string_prepend (&decl, "&");
1925 const char *p = ++(*mangled);
1927 string_prepend (&decl, "(");
1928 string_append (&decl, ")[");
1929 /* Copy anything up until the next underscore (the size of the
1931 while (**mangled && **mangled != '_')
1933 if (**mangled == '_')
1935 string_appendn (&decl, p, *mangled - p);
1936 string_append (&decl, "]");
1944 /* A back reference to a previously seen type */
1947 if (!get_count (mangled, &n) || n >= work -> ntypes)
1953 remembered_type = work -> typevec[n];
1954 mangled = &remembered_type;
1961 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
1963 string_prepend (&decl, "(");
1964 string_append (&decl, ")");
1966 /* After picking off the function args, we expect to either find the
1967 function return type (preceded by an '_') or the end of the
1969 if (!demangle_args (work, mangled, &decl)
1970 || (**mangled != '_' && **mangled != '\0'))
1974 if (success && (**mangled == '_'))
1986 member = **mangled == 'M';
1988 if (!isdigit (**mangled))
1993 n = consume_count (mangled);
1994 if (strlen (*mangled) < n)
1999 string_append (&decl, ")");
2000 string_prepend (&decl, "::");
2001 string_prependn (&decl, *mangled, n);
2002 string_prepend (&decl, "(");
2006 if (**mangled == 'C')
2011 if (**mangled == 'V')
2016 if (*(*mangled)++ != 'F')
2022 if ((member && !demangle_args (work, mangled, &decl))
2023 || **mangled != '_')
2029 if (! PRINT_ANSI_QUALIFIERS)
2035 APPEND_BLANK (&decl);
2036 string_append (&decl, "const");
2040 APPEND_BLANK (&decl);
2041 string_append (&decl, "volatile");
2052 if ((*mangled)[1] == 'P')
2055 if (PRINT_ANSI_QUALIFIERS)
2057 if (!STRING_EMPTY (&decl))
2059 string_prepend (&decl, " ");
2061 string_prepend (&decl, "const");
2077 /* A qualified name, such as "Outer::Inner". */
2079 success = demangle_qualified (work, mangled, result, 0, 1);
2083 success = demangle_fund_type (work, mangled, result);
2089 if (!STRING_EMPTY (&decl))
2091 string_append (result, " ");
2092 string_appends (result, &decl);
2097 string_delete (result);
2099 string_delete (&decl);
2103 /* Given a pointer to a type string that represents a fundamental type
2104 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2105 string in which the demangled output is being built in RESULT, and
2106 the WORK structure, decode the types and add them to the result.
2111 "Sl" => "signed long"
2112 "CUs" => "const unsigned short"
2117 demangle_fund_type (work, mangled, result)
2118 struct work_stuff *work;
2119 const char **mangled;
2125 /* First pick off any type qualifiers. There can be more than one. */
2133 if (PRINT_ANSI_QUALIFIERS)
2135 APPEND_BLANK (result);
2136 string_append (result, "const");
2141 APPEND_BLANK (result);
2142 string_append (result, "unsigned");
2144 case 'S': /* signed char only */
2146 APPEND_BLANK (result);
2147 string_append (result, "signed");
2151 if (PRINT_ANSI_QUALIFIERS)
2153 APPEND_BLANK (result);
2154 string_append (result, "volatile");
2163 /* Now pick off the fundamental type. There can be only one. */
2172 APPEND_BLANK (result);
2173 string_append (result, "void");
2177 APPEND_BLANK (result);
2178 string_append (result, "long long");
2182 APPEND_BLANK (result);
2183 string_append (result, "long");
2187 APPEND_BLANK (result);
2188 string_append (result, "int");
2192 APPEND_BLANK (result);
2193 string_append (result, "short");
2197 APPEND_BLANK (result);
2198 string_append (result, "bool");
2202 APPEND_BLANK (result);
2203 string_append (result, "char");
2207 APPEND_BLANK (result);
2208 string_append (result, "wchar_t");
2212 APPEND_BLANK (result);
2213 string_append (result, "long double");
2217 APPEND_BLANK (result);
2218 string_append (result, "double");
2222 APPEND_BLANK (result);
2223 string_append (result, "float");
2227 if (!isdigit (**mangled))
2233 /* An explicit type, such as "6mytype" or "7integer" */
2244 APPEND_BLANK (result);
2245 if (!demangle_class_name (work, mangled, result)) {
2251 success = demangle_template(work,mangled, result, 0);
2261 /* `result' will be initialized in do_type; it will be freed on failure */
2264 do_arg (work, mangled, result)
2265 struct work_stuff *work;
2266 const char **mangled;
2269 const char *start = *mangled;
2271 if (!do_type (work, mangled, result))
2277 remember_type (work, start, *mangled - start);
2283 remember_type (work, start, len)
2284 struct work_stuff *work;
2290 if (work -> ntypes >= work -> typevec_size)
2292 if (work -> typevec_size == 0)
2294 work -> typevec_size = 3;
2296 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2300 work -> typevec_size *= 2;
2302 (char **) xrealloc ((char *)work -> typevec,
2303 sizeof (char *) * work -> typevec_size);
2306 tem = xmalloc (len + 1);
2307 memcpy (tem, start, len);
2309 work -> typevec[work -> ntypes++] = tem;
2312 /* Forget the remembered types, but not the type vector itself. */
2316 struct work_stuff *work;
2320 while (work -> ntypes > 0)
2322 i = --(work -> ntypes);
2323 if (work -> typevec[i] != NULL)
2325 free (work -> typevec[i]);
2326 work -> typevec[i] = NULL;
2331 /* Process the argument list part of the signature, after any class spec
2332 has been consumed, as well as the first 'F' character (if any). For
2335 "__als__3fooRT0" => process "RT0"
2336 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2338 DECLP must be already initialised, usually non-empty. It won't be freed
2341 Note that g++ differs significantly from ARM and lucid style mangling
2342 with regards to references to previously seen types. For example, given
2343 the source fragment:
2347 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2350 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2351 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2353 g++ produces the names:
2358 while lcc (and presumably other ARM style compilers as well) produces:
2360 foo__FiR3fooT1T2T1T2
2361 __ct__3fooFiR3fooT1T2T1T2
2363 Note that g++ bases it's type numbers starting at zero and counts all
2364 previously seen types, while lucid/ARM bases it's type numbers starting
2365 at one and only considers types after it has seen the 'F' character
2366 indicating the start of the function args. For lucid/ARM style, we
2367 account for this difference by discarding any previously seen types when
2368 we see the 'F' character, and subtracting one from the type number
2374 demangle_args (work, mangled, declp)
2375 struct work_stuff *work;
2376 const char **mangled;
2386 if (PRINT_ARG_TYPES)
2388 string_append (declp, "(");
2389 if (**mangled == '\0')
2391 string_append (declp, "void");
2395 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2397 if ((**mangled == 'N') || (**mangled == 'T'))
2399 temptype = *(*mangled)++;
2401 if (temptype == 'N')
2403 if (!get_count (mangled, &r))
2412 if (ARM_DEMANGLING && work -> ntypes >= 10)
2414 /* If we have 10 or more types we might have more than a 1 digit
2415 index so we'll have to consume the whole count here. This
2416 will lose if the next thing is a type name preceded by a
2417 count but it's impossible to demangle that case properly
2418 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2419 Pc, ...)" or "(..., type12, char *, ...)" */
2420 if ((t = consume_count(mangled)) == 0)
2427 if (!get_count (mangled, &t))
2432 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2436 /* Validate the type index. Protect against illegal indices from
2437 malformed type strings. */
2438 if ((t < 0) || (t >= work -> ntypes))
2444 tem = work -> typevec[t];
2445 if (need_comma && PRINT_ARG_TYPES)
2447 string_append (declp, ", ");
2449 if (!do_arg (work, &tem, &arg))
2453 if (PRINT_ARG_TYPES)
2455 string_appends (declp, &arg);
2457 string_delete (&arg);
2463 if (need_comma & PRINT_ARG_TYPES)
2465 string_append (declp, ", ");
2467 if (!do_arg (work, mangled, &arg))
2471 if (PRINT_ARG_TYPES)
2473 string_appends (declp, &arg);
2475 string_delete (&arg);
2480 if (**mangled == 'e')
2483 if (PRINT_ARG_TYPES)
2487 string_append (declp, ",");
2489 string_append (declp, "...");
2493 if (PRINT_ARG_TYPES)
2495 string_append (declp, ")");
2501 demangle_function_name (work, mangled, declp, scan)
2502 struct work_stuff *work;
2503 const char **mangled;
2512 string_appendn (declp, (*mangled), scan - (*mangled));
2513 string_need (declp, 1);
2514 *(declp -> p) = '\0';
2516 /* Consume the function name, including the "__" separating the name
2517 from the signature. We are guaranteed that SCAN points to the
2520 (*mangled) = scan + 2;
2522 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2525 /* See if we have an ARM style constructor or destructor operator.
2526 If so, then just record it, clear the decl, and return.
2527 We can't build the actual constructor/destructor decl until later,
2528 when we recover the class name from the signature. */
2530 if (strcmp (declp -> b, "__ct") == 0)
2532 work -> constructor += 1;
2533 string_clear (declp);
2536 else if (strcmp (declp -> b, "__dt") == 0)
2538 work -> destructor += 1;
2539 string_clear (declp);
2544 if (declp->p - declp->b >= 3
2545 && declp->b[0] == 'o'
2546 && declp->b[1] == 'p'
2547 && strchr (cplus_markers, declp->b[2]) != NULL)
2549 /* see if it's an assignment expression */
2550 if (declp->p - declp->b >= 10 /* op$assign_ */
2551 && memcmp (declp->b + 3, "assign_", 7) == 0)
2553 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2555 len = declp->p - declp->b - 10;
2556 if (strlen (optable[i].in) == len
2557 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2559 string_clear (declp);
2560 string_append (declp, "operator");
2561 string_append (declp, optable[i].out);
2562 string_append (declp, "=");
2569 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2571 int len = declp->p - declp->b - 3;
2572 if (strlen (optable[i].in) == len
2573 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2575 string_clear (declp);
2576 string_append (declp, "operator");
2577 string_append (declp, optable[i].out);
2583 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2584 && strchr (cplus_markers, declp->b[4]) != NULL)
2586 /* type conversion operator */
2588 if (do_type (work, &tem, &type))
2590 string_clear (declp);
2591 string_append (declp, "operator ");
2592 string_appends (declp, &type);
2593 string_delete (&type);
2596 else if (declp->b[0] == '_' && declp->b[1] == '_'
2597 && declp->b[2] == 'o' && declp->b[3] == 'p')
2600 /* type conversion operator. */
2602 if (do_type (work, &tem, &type))
2604 string_clear (declp);
2605 string_append (declp, "operator ");
2606 string_appends (declp, &type);
2607 string_delete (&type);
2610 else if (declp->b[0] == '_' && declp->b[1] == '_'
2611 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2612 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2614 if (declp->b[4] == '\0')
2617 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2619 if (strlen (optable[i].in) == 2
2620 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2622 string_clear (declp);
2623 string_append (declp, "operator");
2624 string_append (declp, optable[i].out);
2631 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2634 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2636 if (strlen (optable[i].in) == 3
2637 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2639 string_clear (declp);
2640 string_append (declp, "operator");
2641 string_append (declp, optable[i].out);
2650 /* a mini string-handling package */
2665 s->p = s->b = xmalloc (n);
2668 else if (s->e - s->p < n)
2673 s->b = xrealloc (s->b, n);
2686 s->b = s->e = s->p = NULL;
2694 s->b = s->p = s->e = NULL;
2710 return (s->b == s->p);
2716 string_append (p, s)
2721 if (s == NULL || *s == '\0')
2725 memcpy (p->p, s, n);
2730 string_appends (p, s)
2739 memcpy (p->p, s->b, n);
2745 string_appendn (p, s, n)
2753 memcpy (p->p, s, n);
2759 string_prepend (p, s)
2763 if (s != NULL && *s != '\0')
2765 string_prependn (p, s, strlen (s));
2770 string_prepends (p, s)
2775 string_prependn (p, s->b, s->p - s->b);
2780 string_prependn (p, s, n)
2790 for (q = p->p - 1; q >= p->b; q--)
2794 memcpy (p->b, s, n);
2799 /* To generate a standalone demangler program for testing purposes,
2800 just compile and link this file with -DMAIN and libiberty.a. When
2801 run, it demangles each command line arg, or each stdin string, and
2802 prints the result on stdout. */
2807 demangle_it (mangled_name)
2812 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2815 printf ("%s\n", mangled_name);
2819 printf ("%s\n", result);
2826 static char *program_name;
2827 static char *program_version = VERSION;
2830 usage (stream, status)
2835 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
2836 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
2837 [--help] [--version] [arg...]\n",
2842 #define MBUF_SIZE 512
2843 char mbuffer[MBUF_SIZE];
2845 /* Defined in the automatically-generated underscore.c. */
2846 extern int prepends_underscore;
2848 int strip_underscore = 0;
2850 static struct option long_options[] = {
2851 {"strip-underscores", no_argument, 0, '_'},
2852 {"format", required_argument, 0, 's'},
2853 {"help", no_argument, 0, 'h'},
2854 {"no-strip-underscores", no_argument, 0, 'n'},
2855 {"version", no_argument, 0, 'v'},
2856 {0, no_argument, 0, 0}
2867 program_name = argv[0];
2869 strip_underscore = prepends_underscore;
2871 while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
2881 strip_underscore = 0;
2884 printf ("GNU %s version %s\n", program_name, program_version);
2887 strip_underscore = 1;
2890 if (strcmp (optarg, "gnu") == 0)
2892 current_demangling_style = gnu_demangling;
2894 else if (strcmp (optarg, "lucid") == 0)
2896 current_demangling_style = lucid_demangling;
2898 else if (strcmp (optarg, "arm") == 0)
2900 current_demangling_style = arm_demangling;
2904 fprintf (stderr, "%s: unknown demangling style `%s'\n",
2905 program_name, optarg);
2914 for ( ; optind < argc; optind++)
2916 demangle_it (argv[optind]);
2925 /* Try to read a label. */
2926 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
2928 if (i >= MBUF_SIZE-1)
2937 if (mbuffer[0] == '.')
2939 if (strip_underscore && mbuffer[skip_first] == '_')
2947 result = cplus_demangle (mbuffer + skip_first,
2948 DMGL_PARAMS | DMGL_ANSI);
2951 if (mbuffer[0] == '.')
2953 fputs (result, stdout);
2957 fputs (mbuffer, stdout);
2974 fprintf (stderr, "%s: %s\n", program_name, str);
2985 register char *value = (char *) malloc (size);
2987 fatal ("virtual memory exhausted");
2992 xrealloc (ptr, size)
2996 register char *value = (char *) realloc (ptr, size);
2998 fatal ("virtual memory exhausted");