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
630 demangle_signature (work, mangled, declp)
631 struct work_stuff *work;
632 const char **mangled;
638 const char *oldmangled = NULL;
642 while (success && (**mangled != '\0'))
647 oldmangled = *mangled;
648 success = demangle_qualified (work, mangled, declp, 1, 0);
651 remember_type (work, oldmangled, *mangled - oldmangled);
653 if (AUTO_DEMANGLING || GNU_DEMANGLING)
661 /* Static member function */
662 if (oldmangled == NULL)
664 oldmangled = *mangled;
667 work -> static_type = 1;
671 /* a const member function */
672 if (oldmangled == NULL)
674 oldmangled = *mangled;
677 work -> const_type = 1;
680 case '0': case '1': case '2': case '3': case '4':
681 case '5': case '6': case '7': case '8': case '9':
682 if (oldmangled == NULL)
684 oldmangled = *mangled;
686 success = demangle_class (work, mangled, declp);
689 remember_type (work, oldmangled, *mangled - oldmangled);
691 if (AUTO_DEMANGLING || GNU_DEMANGLING)
700 /* ARM style demangling includes a specific 'F' character after
701 the class name. For GNU style, it is just implied. So we can
702 safely just consume any 'F' at this point and be compatible
703 with either style. */
709 /* For lucid/ARM style we have to forget any types we might
710 have remembered up to this point, since they were not argument
711 types. GNU style considers all types seen as available for
712 back references. See comment in demangle_args() */
714 if (LUCID_DEMANGLING || ARM_DEMANGLING)
718 success = demangle_args (work, mangled, declp);
723 string_init(&trawname);
725 if (oldmangled == NULL)
727 oldmangled = *mangled;
729 success = demangle_template (work, mangled, &tname, &trawname);
732 remember_type (work, oldmangled, *mangled - oldmangled);
734 string_append(&tname, "::");
735 string_prepends(declp, &tname);
736 if (work -> destructor & 1)
738 string_prepend (&trawname, "~");
739 string_appends (declp, &trawname);
740 work->destructor -= 1;
742 if ((work->constructor & 1) || (work->destructor & 1))
744 string_appends (declp, &trawname);
745 work->constructor -= 1;
747 string_delete(&trawname);
748 string_delete(&tname);
754 /* At the outermost level, we cannot have a return type specified,
755 so if we run into another '_' at this point we are dealing with
756 a mangled name that is either bogus, or has been mangled by
757 some algorithm we don't know how to deal with. So just
758 reject the entire demangling. */
763 if (AUTO_DEMANGLING || GNU_DEMANGLING)
765 /* Assume we have stumbled onto the first outermost function
766 argument token, and start processing args. */
768 success = demangle_args (work, mangled, declp);
772 /* Non-GNU demanglers use a specific token to mark the start
773 of the outermost function argument tokens. Typically 'F',
774 for ARM-demangling, for example. So if we find something
775 we are not prepared for, it must be an error. */
781 if (AUTO_DEMANGLING || GNU_DEMANGLING)
784 if (success && expect_func)
787 success = demangle_args (work, mangled, declp);
791 if (success && !func_done)
793 if (AUTO_DEMANGLING || GNU_DEMANGLING)
795 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
796 bar__3fooi is 'foo::bar(int)'. We get here when we find the
797 first case, and need to ensure that the '(void)' gets added to
798 the current declp. Note that with ARM, the first case
799 represents the name of a static data member 'foo::bar',
800 which is in the current declp, so we leave it alone. */
801 success = demangle_args (work, mangled, declp);
804 if (success && work -> static_type && PRINT_ARG_TYPES)
806 string_append (declp, " static");
808 if (success && work -> const_type && PRINT_ARG_TYPES)
810 string_append (declp, " const");
818 demangle_method_args (work, mangled, declp)
819 struct work_stuff *work;
820 const char **mangled;
825 if (work -> static_type)
827 string_append (declp, *mangled + 1);
828 *mangled += strlen (*mangled);
833 success = demangle_args (work, mangled, declp);
841 demangle_template (work, mangled, tname, trawname)
842 struct work_stuff *work;
843 const char **mangled;
864 /* get template name */
865 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
870 string_appendn (trawname, *mangled, r);
871 string_appendn (tname, *mangled, r);
873 string_append (tname, "<");
874 /* get size of template parameter list */
875 if (!get_count (mangled, &r))
879 for (i = 0; i < r; i++)
883 string_append (tname, ", ");
885 /* Z for type parameters */
886 if (**mangled == 'Z')
889 /* temp is initialized in do_type */
890 success = do_type (work, mangled, &temp);
893 string_appends (tname, &temp);
895 string_delete(&temp);
903 /* otherwise, value parameter */
911 /* temp is initialized in do_type */
912 success = do_type (work, mangled, &temp);
916 string_appends (tname, &temp);
919 string_delete(&temp);
925 string_append (tname, "=");
927 while (*old_p && !done)
934 done = is_pointer = 1;
936 case 'C': /* const */
937 case 'S': /* explicitly signed [char] */
938 case 'U': /* unsigned */
939 case 'V': /* volatile */
940 case 'F': /* function */
941 case 'M': /* member function */
945 case 'Q': /* qualified name */
946 done = is_integral = 1;
948 case 'T': /* remembered type */
954 case 'x': /* long long */
957 case 's': /* short */
958 case 'w': /* wchar_t */
959 done = is_integral = 1;
967 case 'r': /* long double */
968 case 'd': /* double */
969 case 'f': /* float */
973 /* it's probably user defined type, let's assume
974 it's integral, it seems hard to figure out
976 done = is_integral = 1;
981 if (**mangled == 'm')
983 string_appendn (tname, "-", 1);
986 while (isdigit (**mangled))
988 string_appendn (tname, *mangled, 1);
996 if (**mangled == 'm')
998 string_appendn (tname, "-", 1);
1001 string_appendn (tname, "'", 1);
1002 val = consume_count(mangled);
1010 string_appendn (tname, &tmp[0], 1);
1011 string_appendn (tname, "'", 1);
1015 int val = consume_count (mangled);
1017 string_appendn (tname, "false", 5);
1019 string_appendn (tname, "true", 4);
1025 if (**mangled == 'm')
1027 string_appendn (tname, "-", 1);
1030 while (isdigit (**mangled))
1032 string_appendn (tname, *mangled, 1);
1035 if (**mangled == '.') /* fraction */
1037 string_appendn (tname, ".", 1);
1039 while (isdigit (**mangled))
1041 string_appendn (tname, *mangled, 1);
1045 if (**mangled == 'e') /* exponent */
1047 string_appendn (tname, "e", 1);
1049 while (isdigit (**mangled))
1051 string_appendn (tname, *mangled, 1);
1056 else if (is_pointer)
1058 if (!get_count (mangled, &symbol_len))
1063 if (symbol_len == 0)
1064 string_appendn (tname, "0", 1);
1067 char *p = xmalloc (symbol_len + 1), *q;
1068 strncpy (p, *mangled, symbol_len);
1069 p [symbol_len] = '\0';
1070 q = cplus_demangle (p, work->options);
1071 string_appendn (tname, "&", 1);
1074 string_append (tname, q);
1078 string_append (tname, p);
1081 *mangled += symbol_len;
1086 if (tname->p[-1] == '>')
1087 string_append (tname, " ");
1088 string_append (tname, ">");
1091 if (work -> static_type)
1093 string_append (declp, *mangled + 1);
1094 *mangled += strlen (*mangled);
1099 success = demangle_args (work, mangled, declp);
1107 arm_pt (work, mangled, n, anchor, args)
1108 struct work_stuff *work;
1109 const char *mangled;
1111 const char **anchor, **args;
1114 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1117 *args = *anchor + 6;
1118 len = consume_count (args);
1119 if (*args + len == mangled + n && **args == '_')
1129 demangle_arm_pt (work, mangled, n, declp)
1130 struct work_stuff *work;
1131 const char **mangled;
1137 const char *e = *mangled + n;
1140 if (arm_pt (work, *mangled, n, &p, &args))
1144 string_appendn (declp, *mangled, p - *mangled);
1145 string_append (declp, "<");
1146 /* should do error checking here */
1148 string_clear (&arg);
1149 do_type (work, &args, &arg);
1150 string_appends (declp, &arg);
1151 string_append (declp, ",");
1153 string_delete (&arg);
1155 string_append (declp, ">");
1159 string_appendn (declp, *mangled, n);
1165 demangle_class_name (work, mangled, declp)
1166 struct work_stuff *work;
1167 const char **mangled;
1173 n = consume_count (mangled);
1174 if (strlen (*mangled) >= n)
1176 demangle_arm_pt (work, mangled, n, declp);
1187 demangle_class -- demangle a mangled class sequence
1192 demangle_class (struct work_stuff *work, const char **mangled,
1197 DECLP points to the buffer into which demangling is being done.
1199 *MANGLED points to the current token to be demangled. On input,
1200 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1201 On exit, it points to the next token after the mangled class on
1202 success, or the first unconsumed token on failure.
1204 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1205 we are demangling a constructor or destructor. In this case
1206 we prepend "class::class" or "class::~class" to DECLP.
1208 Otherwise, we prepend "class::" to the current DECLP.
1210 Reset the constructor/destructor flags once they have been
1211 "consumed". This allows demangle_class to be called later during
1212 the same demangling, to do normal class demangling.
1214 Returns 1 if demangling is successful, 0 otherwise.
1219 demangle_class (work, mangled, declp)
1220 struct work_stuff *work;
1221 const char **mangled;
1227 string_init (&class_name);
1228 if (demangle_class_name (work, mangled, &class_name))
1230 if ((work->constructor & 1) || (work->destructor & 1))
1232 string_prepends (declp, &class_name);
1233 if (work -> destructor & 1)
1235 string_prepend (declp, "~");
1236 work -> destructor -= 1;
1240 work -> constructor -= 1;
1243 string_prepend (declp, "::");
1244 string_prepends (declp, &class_name);
1247 string_delete (&class_name);
1255 demangle_prefix -- consume the mangled name prefix and find signature
1260 demangle_prefix (struct work_stuff *work, const char **mangled,
1265 Consume and demangle the prefix of the mangled name.
1267 DECLP points to the string buffer into which demangled output is
1268 placed. On entry, the buffer is empty. On exit it contains
1269 the root function name, the demangled operator name, or in some
1270 special cases either nothing or the completely demangled result.
1272 MANGLED points to the current pointer into the mangled name. As each
1273 token of the mangled name is consumed, it is updated. Upon entry
1274 the current mangled name pointer points to the first character of
1275 the mangled name. Upon exit, it should point to the first character
1276 of the signature if demangling was successful, or to the first
1277 unconsumed character if demangling of the prefix was unsuccessful.
1279 Returns 1 on success, 0 otherwise.
1283 demangle_prefix (work, mangled, declp)
1284 struct work_stuff *work;
1285 const char **mangled;
1292 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1294 char *marker = strchr (cplus_markers, (*mangled)[8]);
1295 if (marker != NULL && *marker == (*mangled)[10])
1297 if ((*mangled)[9] == 'D')
1299 /* it's a GNU global destructor to be executed at program exit */
1301 work->destructor = 2;
1302 if (gnu_special (work, mangled, declp))
1305 else if ((*mangled)[9] == 'I')
1307 /* it's a GNU global constructor to be executed at program init */
1309 work->constructor = 2;
1310 if (gnu_special (work, mangled, declp))
1315 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1317 /* it's a ARM global destructor to be executed at program exit */
1319 work->destructor = 2;
1321 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1323 /* it's a ARM global constructor to be executed at program initial */
1325 work->constructor = 2;
1328 /* This block of code is a reduction in strength time optimization
1330 scan = mystrstr (*mangled, "__"); */
1336 scan = strchr (scan, '_');
1337 } while (scan != NULL && *++scan != '_');
1339 if (scan != NULL) --scan;
1344 /* We found a sequence of two or more '_', ensure that we start at
1345 the last pair in the sequence. */
1346 i = strspn (scan, "_");
1357 else if (work -> static_type)
1359 if (!isdigit (scan[0]) && (scan[0] != 't'))
1364 else if ((scan == *mangled) &&
1365 (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')))
1367 /* The ARM says nothing about the mangling of local variables.
1368 But cfront mangles local variables by prepending __<nesting_level>
1369 to them. As an extension to ARM demangling we handle this case. */
1370 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1372 *mangled = scan + 2;
1373 consume_count (mangled);
1374 string_append (declp, *mangled);
1375 *mangled += strlen (*mangled);
1380 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1381 names like __Q2_3foo3bar for nested type names. So don't accept
1382 this style of constructor for cfront demangling. */
1383 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1384 work -> constructor += 1;
1385 *mangled = scan + 2;
1388 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1390 /* Mangled name starts with "__". Skip over any leading '_' characters,
1391 then find the next "__" that separates the prefix from the signature.
1393 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1394 || (arm_special (work, mangled, declp) == 0))
1396 while (*scan == '_')
1400 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1402 /* No separator (I.E. "__not_mangled"), or empty signature
1403 (I.E. "__not_mangled_either__") */
1408 demangle_function_name (work, mangled, declp, scan);
1412 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1414 /* Cfront-style parameterized type. Handled later as a signature. */
1418 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1420 else if (*(scan + 2) != '\0')
1422 /* Mangled name does not start with "__" but does have one somewhere
1423 in there with non empty stuff after it. Looks like a global
1425 demangle_function_name (work, mangled, declp, scan);
1429 /* Doesn't look like a mangled name */
1433 if (!success && (work->constructor == 2 || work->destructor == 2))
1435 string_append (declp, *mangled);
1436 *mangled += strlen (*mangled);
1446 gnu_special -- special handling of gnu mangled strings
1451 gnu_special (struct work_stuff *work, const char **mangled,
1457 Process some special GNU style mangling forms that don't fit
1458 the normal pattern. For example:
1460 _$_3foo (destructor for class foo)
1461 _vt$foo (foo virtual table)
1462 _vt$foo$bar (foo::bar virtual table)
1463 __vt_foo (foo virtual table, new style with thunks)
1464 _3foo$varname (static data member)
1465 _Q22rs2tu$vw (static data member)
1466 __t6vector1Zii (constructor with template)
1467 __thunk_4__$_7ostream (virtual function thunk)
1471 gnu_special (work, mangled, declp)
1472 struct work_stuff *work;
1473 const char **mangled;
1480 if ((*mangled)[0] == '_'
1481 && strchr (cplus_markers, (*mangled)[1]) != NULL
1482 && (*mangled)[2] == '_')
1484 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1486 work -> destructor += 1;
1488 else if ((*mangled)[0] == '_'
1489 && (((*mangled)[1] == '_'
1490 && (*mangled)[2] == 'v'
1491 && (*mangled)[3] == 't'
1492 && (*mangled)[4] == '_')
1493 || ((*mangled)[1] == 'v'
1494 && (*mangled)[2] == 't'
1495 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1497 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1498 and create the decl. Note that we consume the entire mangled
1499 input string, which means that demangle_signature has no work
1501 if ((*mangled)[2] == 'v')
1502 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1504 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1505 while (**mangled != '\0')
1507 p = strpbrk (*mangled, cplus_markers);
1511 success = demangle_qualified (work, mangled, declp, 0, 1);
1514 success = demangle_template (work, mangled, declp, 0);
1517 if (isdigit(*mangled[0]))
1519 n = consume_count(mangled);
1523 n = strcspn (*mangled, cplus_markers);
1525 string_appendn (declp, *mangled, n);
1529 if (success && ((p == NULL) || (p == *mangled)))
1533 string_append (declp, "::");
1544 string_append (declp, " virtual table");
1546 else if ((*mangled)[0] == '_'
1547 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
1548 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
1550 /* static data member, "_3foo$varname" for example */
1555 success = demangle_qualified (work, mangled, declp, 0, 1);
1558 success = demangle_template (work, mangled, declp, 0);
1561 n = consume_count (mangled);
1562 string_appendn (declp, *mangled, n);
1565 if (success && (p == *mangled))
1567 /* Consumed everything up to the cplus_marker, append the
1570 string_append (declp, "::");
1571 n = strlen (*mangled);
1572 string_appendn (declp, *mangled, n);
1580 else if (strncmp (*mangled, "__thunk_", 8) == 0)
1582 int delta = ((*mangled) += 8, consume_count (mangled));
1583 char *method = cplus_demangle (++*mangled, work->options);
1587 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
1588 string_append (declp, buf);
1589 string_append (declp, method);
1591 n = strlen (*mangled);
1610 arm_special -- special handling of ARM/lucid mangled strings
1615 arm_special (struct work_stuff *work, const char **mangled,
1621 Process some special ARM style mangling forms that don't fit
1622 the normal pattern. For example:
1624 __vtbl__3foo (foo virtual table)
1625 __vtbl__3foo__3bar (bar::foo virtual table)
1630 arm_special (work, mangled, declp)
1631 struct work_stuff *work;
1632 const char **mangled;
1639 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
1641 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
1642 and create the decl. Note that we consume the entire mangled
1643 input string, which means that demangle_signature has no work
1645 scan = *mangled + ARM_VTABLE_STRLEN;
1646 while (*scan != '\0') /* first check it can be demangled */
1648 n = consume_count (&scan);
1651 return (0); /* no good */
1654 if (scan[0] == '_' && scan[1] == '_')
1659 (*mangled) += ARM_VTABLE_STRLEN;
1660 while (**mangled != '\0')
1662 n = consume_count (mangled);
1663 string_prependn (declp, *mangled, n);
1665 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
1667 string_prepend (declp, "::");
1671 string_append (declp, " virtual table");
1684 demangle_qualified -- demangle 'Q' qualified name strings
1689 demangle_qualified (struct work_stuff *, const char *mangled,
1690 string *result, int isfuncname, int append);
1694 Demangle a qualified name, such as "Q25Outer5Inner" which is
1695 the mangled form of "Outer::Inner". The demangled output is
1696 prepended or appended to the result string according to the
1697 state of the append flag.
1699 If isfuncname is nonzero, then the qualified name we are building
1700 is going to be used as a member function name, so if it is a
1701 constructor or destructor function, append an appropriate
1702 constructor or destructor name. I.E. for the above example,
1703 the result for use as a constructor is "Outer::Inner::Inner"
1704 and the result for use as a destructor is "Outer::Inner::~Inner".
1708 Numeric conversion is ASCII dependent (FIXME).
1713 demangle_qualified (work, mangled, result, isfuncname, append)
1714 struct work_stuff *work;
1715 const char **mangled;
1727 string_init (&temp);
1728 switch ((*mangled)[1])
1731 /* GNU mangled name with more than 9 classes. The count is preceded
1732 by an underscore (to distinguish it from the <= 9 case) and followed
1733 by an underscore. */
1735 qualifiers = atoi (p);
1736 if (!isdigit (*p) || *p == '0')
1739 /* Skip the digits. */
1740 while (isdigit (*p))
1758 /* The count is in a single digit. */
1759 num[0] = (*mangled)[1];
1761 qualifiers = atoi (num);
1763 /* If there is an underscore after the digit, skip it. This is
1764 said to be for ARM-qualified names, but the ARM makes no
1765 mention of such an underscore. Perhaps cfront uses one. */
1766 if ((*mangled)[2] == '_')
1781 /* Pick off the names and collect them in the temp buffer in the order
1782 in which they are found, separated by '::'. */
1784 while (qualifiers-- > 0)
1786 if (*mangled[0] == '_')
1787 *mangled = *mangled + 1;
1788 if (*mangled[0] == 't')
1790 success = demangle_template(work, mangled, &temp, 0);
1791 if (!success) break;
1795 namelength = consume_count (mangled);
1796 if (strlen (*mangled) < namelength)
1798 /* Simple sanity check failed */
1802 string_appendn (&temp, *mangled, namelength);
1803 *mangled += namelength;
1807 string_appendn (&temp, "::", 2);
1811 /* If we are using the result as a function name, we need to append
1812 the appropriate '::' separated constructor or destructor name.
1813 We do this here because this is the most convenient place, where
1814 we already have a pointer to the name and the length of the name. */
1816 if (isfuncname && (work->constructor & 1 || work->destructor & 1))
1818 string_appendn (&temp, "::", 2);
1819 if (work -> destructor & 1)
1821 string_append (&temp, "~");
1823 string_appendn (&temp, (*mangled) - namelength, namelength);
1826 /* Now either prepend the temp buffer to the result, or append it,
1827 depending upon the state of the append flag. */
1831 string_appends (result, &temp);
1835 if (!STRING_EMPTY (result))
1837 string_appendn (&temp, "::", 2);
1839 string_prepends (result, &temp);
1842 string_delete (&temp);
1850 get_count -- convert an ascii count to integer, consuming tokens
1855 get_count (const char **type, int *count)
1859 Return 0 if no conversion is performed, 1 if a string is converted.
1863 get_count (type, count)
1870 if (!isdigit (**type))
1876 *count = **type - '0';
1878 if (isdigit (**type))
1888 while (isdigit (*p));
1899 /* result will be initialised here; it will be freed on failure */
1902 do_type (work, mangled, result)
1903 struct work_stuff *work;
1904 const char **mangled;
1911 const char *remembered_type;
1915 string_init (&decl);
1916 string_init (result);
1920 while (success && !done)
1926 /* A pointer type */
1930 string_prepend (&decl, "*");
1933 /* A reference type */
1936 string_prepend (&decl, "&");
1942 const char *p = ++(*mangled);
1944 string_prepend (&decl, "(");
1945 string_append (&decl, ")[");
1946 /* Copy anything up until the next underscore (the size of the
1948 while (**mangled && **mangled != '_')
1950 if (**mangled == '_')
1952 string_appendn (&decl, p, *mangled - p);
1953 string_append (&decl, "]");
1961 /* A back reference to a previously seen type */
1964 if (!get_count (mangled, &n) || n >= work -> ntypes)
1970 remembered_type = work -> typevec[n];
1971 mangled = &remembered_type;
1978 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
1980 string_prepend (&decl, "(");
1981 string_append (&decl, ")");
1983 /* After picking off the function args, we expect to either find the
1984 function return type (preceded by an '_') or the end of the
1986 if (!demangle_args (work, mangled, &decl)
1987 || (**mangled != '_' && **mangled != '\0'))
1991 if (success && (**mangled == '_'))
2003 member = **mangled == 'M';
2005 if (!isdigit (**mangled))
2010 n = consume_count (mangled);
2011 if (strlen (*mangled) < n)
2016 string_append (&decl, ")");
2017 string_prepend (&decl, "::");
2018 string_prependn (&decl, *mangled, n);
2019 string_prepend (&decl, "(");
2023 if (**mangled == 'C')
2028 if (**mangled == 'V')
2033 if (*(*mangled)++ != 'F')
2039 if ((member && !demangle_args (work, mangled, &decl))
2040 || **mangled != '_')
2046 if (! PRINT_ANSI_QUALIFIERS)
2052 APPEND_BLANK (&decl);
2053 string_append (&decl, "const");
2057 APPEND_BLANK (&decl);
2058 string_append (&decl, "volatile");
2069 if ((*mangled)[1] == 'P')
2072 if (PRINT_ANSI_QUALIFIERS)
2074 if (!STRING_EMPTY (&decl))
2076 string_prepend (&decl, " ");
2078 string_prepend (&decl, "const");
2094 /* A qualified name, such as "Outer::Inner". */
2096 success = demangle_qualified (work, mangled, result, 0, 1);
2100 success = demangle_fund_type (work, mangled, result);
2106 if (!STRING_EMPTY (&decl))
2108 string_append (result, " ");
2109 string_appends (result, &decl);
2114 string_delete (result);
2116 string_delete (&decl);
2120 /* Given a pointer to a type string that represents a fundamental type
2121 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2122 string in which the demangled output is being built in RESULT, and
2123 the WORK structure, decode the types and add them to the result.
2128 "Sl" => "signed long"
2129 "CUs" => "const unsigned short"
2134 demangle_fund_type (work, mangled, result)
2135 struct work_stuff *work;
2136 const char **mangled;
2142 /* First pick off any type qualifiers. There can be more than one. */
2150 if (PRINT_ANSI_QUALIFIERS)
2152 APPEND_BLANK (result);
2153 string_append (result, "const");
2158 APPEND_BLANK (result);
2159 string_append (result, "unsigned");
2161 case 'S': /* signed char only */
2163 APPEND_BLANK (result);
2164 string_append (result, "signed");
2168 if (PRINT_ANSI_QUALIFIERS)
2170 APPEND_BLANK (result);
2171 string_append (result, "volatile");
2180 /* Now pick off the fundamental type. There can be only one. */
2189 APPEND_BLANK (result);
2190 string_append (result, "void");
2194 APPEND_BLANK (result);
2195 string_append (result, "long long");
2199 APPEND_BLANK (result);
2200 string_append (result, "long");
2204 APPEND_BLANK (result);
2205 string_append (result, "int");
2209 APPEND_BLANK (result);
2210 string_append (result, "short");
2214 APPEND_BLANK (result);
2215 string_append (result, "bool");
2219 APPEND_BLANK (result);
2220 string_append (result, "char");
2224 APPEND_BLANK (result);
2225 string_append (result, "wchar_t");
2229 APPEND_BLANK (result);
2230 string_append (result, "long double");
2234 APPEND_BLANK (result);
2235 string_append (result, "double");
2239 APPEND_BLANK (result);
2240 string_append (result, "float");
2244 if (!isdigit (**mangled))
2250 /* An explicit type, such as "6mytype" or "7integer" */
2261 APPEND_BLANK (result);
2262 if (!demangle_class_name (work, mangled, result)) {
2268 success = demangle_template(work,mangled, result, 0);
2278 /* `result' will be initialized in do_type; it will be freed on failure */
2281 do_arg (work, mangled, result)
2282 struct work_stuff *work;
2283 const char **mangled;
2286 const char *start = *mangled;
2288 if (!do_type (work, mangled, result))
2294 remember_type (work, start, *mangled - start);
2300 remember_type (work, start, len)
2301 struct work_stuff *work;
2307 if (work -> ntypes >= work -> typevec_size)
2309 if (work -> typevec_size == 0)
2311 work -> typevec_size = 3;
2313 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
2317 work -> typevec_size *= 2;
2319 (char **) xrealloc ((char *)work -> typevec,
2320 sizeof (char *) * work -> typevec_size);
2323 tem = xmalloc (len + 1);
2324 memcpy (tem, start, len);
2326 work -> typevec[work -> ntypes++] = tem;
2329 /* Forget the remembered types, but not the type vector itself. */
2333 struct work_stuff *work;
2337 while (work -> ntypes > 0)
2339 i = --(work -> ntypes);
2340 if (work -> typevec[i] != NULL)
2342 free (work -> typevec[i]);
2343 work -> typevec[i] = NULL;
2348 /* Process the argument list part of the signature, after any class spec
2349 has been consumed, as well as the first 'F' character (if any). For
2352 "__als__3fooRT0" => process "RT0"
2353 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
2355 DECLP must be already initialised, usually non-empty. It won't be freed
2358 Note that g++ differs significantly from ARM and lucid style mangling
2359 with regards to references to previously seen types. For example, given
2360 the source fragment:
2364 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
2367 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2368 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
2370 g++ produces the names:
2375 while lcc (and presumably other ARM style compilers as well) produces:
2377 foo__FiR3fooT1T2T1T2
2378 __ct__3fooFiR3fooT1T2T1T2
2380 Note that g++ bases it's type numbers starting at zero and counts all
2381 previously seen types, while lucid/ARM bases it's type numbers starting
2382 at one and only considers types after it has seen the 'F' character
2383 indicating the start of the function args. For lucid/ARM style, we
2384 account for this difference by discarding any previously seen types when
2385 we see the 'F' character, and subtracting one from the type number
2391 demangle_args (work, mangled, declp)
2392 struct work_stuff *work;
2393 const char **mangled;
2403 if (PRINT_ARG_TYPES)
2405 string_append (declp, "(");
2406 if (**mangled == '\0')
2408 string_append (declp, "void");
2412 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
2414 if ((**mangled == 'N') || (**mangled == 'T'))
2416 temptype = *(*mangled)++;
2418 if (temptype == 'N')
2420 if (!get_count (mangled, &r))
2429 if (ARM_DEMANGLING && work -> ntypes >= 10)
2431 /* If we have 10 or more types we might have more than a 1 digit
2432 index so we'll have to consume the whole count here. This
2433 will lose if the next thing is a type name preceded by a
2434 count but it's impossible to demangle that case properly
2435 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
2436 Pc, ...)" or "(..., type12, char *, ...)" */
2437 if ((t = consume_count(mangled)) == 0)
2444 if (!get_count (mangled, &t))
2449 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2453 /* Validate the type index. Protect against illegal indices from
2454 malformed type strings. */
2455 if ((t < 0) || (t >= work -> ntypes))
2461 tem = work -> typevec[t];
2462 if (need_comma && PRINT_ARG_TYPES)
2464 string_append (declp, ", ");
2466 if (!do_arg (work, &tem, &arg))
2470 if (PRINT_ARG_TYPES)
2472 string_appends (declp, &arg);
2474 string_delete (&arg);
2480 if (need_comma & PRINT_ARG_TYPES)
2482 string_append (declp, ", ");
2484 if (!do_arg (work, mangled, &arg))
2488 if (PRINT_ARG_TYPES)
2490 string_appends (declp, &arg);
2492 string_delete (&arg);
2497 if (**mangled == 'e')
2500 if (PRINT_ARG_TYPES)
2504 string_append (declp, ",");
2506 string_append (declp, "...");
2510 if (PRINT_ARG_TYPES)
2512 string_append (declp, ")");
2518 demangle_function_name (work, mangled, declp, scan)
2519 struct work_stuff *work;
2520 const char **mangled;
2529 string_appendn (declp, (*mangled), scan - (*mangled));
2530 string_need (declp, 1);
2531 *(declp -> p) = '\0';
2533 /* Consume the function name, including the "__" separating the name
2534 from the signature. We are guaranteed that SCAN points to the
2537 (*mangled) = scan + 2;
2539 if (LUCID_DEMANGLING || ARM_DEMANGLING)
2542 /* See if we have an ARM style constructor or destructor operator.
2543 If so, then just record it, clear the decl, and return.
2544 We can't build the actual constructor/destructor decl until later,
2545 when we recover the class name from the signature. */
2547 if (strcmp (declp -> b, "__ct") == 0)
2549 work -> constructor += 1;
2550 string_clear (declp);
2553 else if (strcmp (declp -> b, "__dt") == 0)
2555 work -> destructor += 1;
2556 string_clear (declp);
2561 if (declp->p - declp->b >= 3
2562 && declp->b[0] == 'o'
2563 && declp->b[1] == 'p'
2564 && strchr (cplus_markers, declp->b[2]) != NULL)
2566 /* see if it's an assignment expression */
2567 if (declp->p - declp->b >= 10 /* op$assign_ */
2568 && memcmp (declp->b + 3, "assign_", 7) == 0)
2570 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2572 len = declp->p - declp->b - 10;
2573 if (strlen (optable[i].in) == len
2574 && memcmp (optable[i].in, declp->b + 10, len) == 0)
2576 string_clear (declp);
2577 string_append (declp, "operator");
2578 string_append (declp, optable[i].out);
2579 string_append (declp, "=");
2586 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2588 int len = declp->p - declp->b - 3;
2589 if (strlen (optable[i].in) == len
2590 && memcmp (optable[i].in, declp->b + 3, len) == 0)
2592 string_clear (declp);
2593 string_append (declp, "operator");
2594 string_append (declp, optable[i].out);
2600 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
2601 && strchr (cplus_markers, declp->b[4]) != NULL)
2603 /* type conversion operator */
2605 if (do_type (work, &tem, &type))
2607 string_clear (declp);
2608 string_append (declp, "operator ");
2609 string_appends (declp, &type);
2610 string_delete (&type);
2613 else if (declp->b[0] == '_' && declp->b[1] == '_'
2614 && declp->b[2] == 'o' && declp->b[3] == 'p')
2617 /* type conversion operator. */
2619 if (do_type (work, &tem, &type))
2621 string_clear (declp);
2622 string_append (declp, "operator ");
2623 string_appends (declp, &type);
2624 string_delete (&type);
2627 else if (declp->b[0] == '_' && declp->b[1] == '_'
2628 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
2629 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
2631 if (declp->b[4] == '\0')
2634 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2636 if (strlen (optable[i].in) == 2
2637 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
2639 string_clear (declp);
2640 string_append (declp, "operator");
2641 string_append (declp, optable[i].out);
2648 if (declp->b[2] == 'a' && declp->b[5] == '\0')
2651 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
2653 if (strlen (optable[i].in) == 3
2654 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
2656 string_clear (declp);
2657 string_append (declp, "operator");
2658 string_append (declp, optable[i].out);
2667 /* a mini string-handling package */
2682 s->p = s->b = xmalloc (n);
2685 else if (s->e - s->p < n)
2690 s->b = xrealloc (s->b, n);
2703 s->b = s->e = s->p = NULL;
2711 s->b = s->p = s->e = NULL;
2727 return (s->b == s->p);
2733 string_append (p, s)
2738 if (s == NULL || *s == '\0')
2742 memcpy (p->p, s, n);
2747 string_appends (p, s)
2756 memcpy (p->p, s->b, n);
2762 string_appendn (p, s, n)
2770 memcpy (p->p, s, n);
2776 string_prepend (p, s)
2780 if (s != NULL && *s != '\0')
2782 string_prependn (p, s, strlen (s));
2787 string_prepends (p, s)
2792 string_prependn (p, s->b, s->p - s->b);
2797 string_prependn (p, s, n)
2807 for (q = p->p - 1; q >= p->b; q--)
2811 memcpy (p->b, s, n);
2816 /* To generate a standalone demangler program for testing purposes,
2817 just compile and link this file with -DMAIN and libiberty.a. When
2818 run, it demangles each command line arg, or each stdin string, and
2819 prints the result on stdout. */
2824 demangle_it (mangled_name)
2829 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
2832 printf ("%s\n", mangled_name);
2836 printf ("%s\n", result);
2843 static char *program_name;
2844 static char *program_version = VERSION;
2847 usage (stream, status)
2852 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
2853 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
2854 [--help] [--version] [arg...]\n",
2859 #define MBUF_SIZE 512
2860 char mbuffer[MBUF_SIZE];
2862 /* Defined in the automatically-generated underscore.c. */
2863 extern int prepends_underscore;
2865 int strip_underscore = 0;
2867 static struct option long_options[] = {
2868 {"strip-underscores", no_argument, 0, '_'},
2869 {"format", required_argument, 0, 's'},
2870 {"help", no_argument, 0, 'h'},
2871 {"no-strip-underscores", no_argument, 0, 'n'},
2872 {"version", no_argument, 0, 'v'},
2873 {0, no_argument, 0, 0}
2884 program_name = argv[0];
2886 strip_underscore = prepends_underscore;
2888 while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
2898 strip_underscore = 0;
2901 printf ("GNU %s version %s\n", program_name, program_version);
2904 strip_underscore = 1;
2907 if (strcmp (optarg, "gnu") == 0)
2909 current_demangling_style = gnu_demangling;
2911 else if (strcmp (optarg, "lucid") == 0)
2913 current_demangling_style = lucid_demangling;
2915 else if (strcmp (optarg, "arm") == 0)
2917 current_demangling_style = arm_demangling;
2921 fprintf (stderr, "%s: unknown demangling style `%s'\n",
2922 program_name, optarg);
2931 for ( ; optind < argc; optind++)
2933 demangle_it (argv[optind]);
2942 /* Try to read a label. */
2943 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
2945 if (i >= MBUF_SIZE-1)
2954 if (mbuffer[0] == '.')
2956 if (strip_underscore && mbuffer[skip_first] == '_')
2964 result = cplus_demangle (mbuffer + skip_first,
2965 DMGL_PARAMS | DMGL_ANSI);
2968 if (mbuffer[0] == '.')
2970 fputs (result, stdout);
2974 fputs (mbuffer, stdout);
2991 fprintf (stderr, "%s: %s\n", program_name, str);
3002 register char *value = (char *) malloc (size);
3004 fatal ("virtual memory exhausted");
3009 xrealloc (ptr, size)
3013 register char *value = (char *) realloc (ptr, size);
3015 fatal ("virtual memory exhausted");