1 /* Demangler for GNU C++
2 Copyright 1989, 91, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 This file is part of the libiberty library.
7 Libiberty is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 Libiberty is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with libiberty; see the file COPYING.LIB. If
19 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
24 This file imports xmalloc and xrealloc, which are like malloc and
25 realloc except that they generate a fatal error if there is no
28 /* This file lives in both GCC and libiberty. When making changes, please
29 try not to break either. */
32 #include <sys/types.h>
41 #undef CURRENT_DEMANGLING_STYLE
42 #define CURRENT_DEMANGLING_STYLE work->options
44 extern char *xmalloc PARAMS((unsigned));
45 extern char *xrealloc PARAMS((char *, unsigned));
47 static const char *mystrstr PARAMS ((const char *, const char *));
53 register const char *p = s1;
54 register int len = strlen (s2);
56 for (; (p = strchr (p, *s2)) != 0; p++)
58 if (strncmp (p, s2, len) == 0)
66 /* In order to allow a single demangler executable to demangle strings
67 using various common values of CPLUS_MARKER, as well as any specific
68 one set at compile time, we maintain a string containing all the
69 commonly used ones, and check to see if the marker we are looking for
70 is in that string. CPLUS_MARKER is usually '$' on systems where the
71 assembler can deal with that. Where the assembler can't, it's usually
72 '.' (but on many systems '.' is used for other things). We put the
73 current defined CPLUS_MARKER first (which defaults to '$'), followed
74 by the next most common value, followed by an explicit '$' in case
75 the value of CPLUS_MARKER is not '$'.
77 We could avoid this if we could just get g++ to tell us what the actual
78 cplus marker character is as part of the debug information, perhaps by
79 ensuring that it is the character that terminates the gcc<n>_compiled
80 marker symbol (FIXME). */
82 #if !defined (CPLUS_MARKER)
83 #define CPLUS_MARKER '$'
86 enum demangling_styles current_demangling_style = gnu_demangling;
88 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
91 set_cplus_marker_for_demangling (ch)
94 cplus_markers[0] = ch;
97 typedef struct string /* Beware: these aren't required to be */
98 { /* '\0' terminated. */
99 char *b; /* pointer to start of string */
100 char *p; /* pointer after last character */
101 char *e; /* pointer after end of allocated space */
104 /* Stuff that is shared between sub-routines.
105 Using a shared structure allows cplus_demangle to be reentrant. */
121 int static_type; /* A static member function */
122 int const_type; /* A const member function */
123 int volatile_type; /* A volatile member function */
124 char **tmpl_argvec; /* Template function arguments. */
125 int ntmpl_args; /* The number of template function arguments. */
126 int forgetting_types; /* Nonzero if we are not remembering the types
128 string* previous_argument; /* The last function argument demangled. */
129 int nrepeats; /* The number of times to repeat the previous
133 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
134 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
136 static const struct optable
142 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
143 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
144 {"new", " new", 0}, /* old (1.91, and 1.x) */
145 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
146 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
147 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
148 {"as", "=", DMGL_ANSI}, /* ansi */
149 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
150 {"eq", "==", DMGL_ANSI}, /* old, ansi */
151 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
152 {"gt", ">", DMGL_ANSI}, /* old, ansi */
153 {"le", "<=", DMGL_ANSI}, /* old, ansi */
154 {"lt", "<", DMGL_ANSI}, /* old, ansi */
155 {"plus", "+", 0}, /* old */
156 {"pl", "+", DMGL_ANSI}, /* ansi */
157 {"apl", "+=", DMGL_ANSI}, /* ansi */
158 {"minus", "-", 0}, /* old */
159 {"mi", "-", DMGL_ANSI}, /* ansi */
160 {"ami", "-=", DMGL_ANSI}, /* ansi */
161 {"mult", "*", 0}, /* old */
162 {"ml", "*", DMGL_ANSI}, /* ansi */
163 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
164 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
165 {"convert", "+", 0}, /* old (unary +) */
166 {"negate", "-", 0}, /* old (unary -) */
167 {"trunc_mod", "%", 0}, /* old */
168 {"md", "%", DMGL_ANSI}, /* ansi */
169 {"amd", "%=", DMGL_ANSI}, /* ansi */
170 {"trunc_div", "/", 0}, /* old */
171 {"dv", "/", DMGL_ANSI}, /* ansi */
172 {"adv", "/=", DMGL_ANSI}, /* ansi */
173 {"truth_andif", "&&", 0}, /* old */
174 {"aa", "&&", DMGL_ANSI}, /* ansi */
175 {"truth_orif", "||", 0}, /* old */
176 {"oo", "||", DMGL_ANSI}, /* ansi */
177 {"truth_not", "!", 0}, /* old */
178 {"nt", "!", DMGL_ANSI}, /* ansi */
179 {"postincrement","++", 0}, /* old */
180 {"pp", "++", DMGL_ANSI}, /* ansi */
181 {"postdecrement","--", 0}, /* old */
182 {"mm", "--", DMGL_ANSI}, /* ansi */
183 {"bit_ior", "|", 0}, /* old */
184 {"or", "|", DMGL_ANSI}, /* ansi */
185 {"aor", "|=", DMGL_ANSI}, /* ansi */
186 {"bit_xor", "^", 0}, /* old */
187 {"er", "^", DMGL_ANSI}, /* ansi */
188 {"aer", "^=", DMGL_ANSI}, /* ansi */
189 {"bit_and", "&", 0}, /* old */
190 {"ad", "&", DMGL_ANSI}, /* ansi */
191 {"aad", "&=", DMGL_ANSI}, /* ansi */
192 {"bit_not", "~", 0}, /* old */
193 {"co", "~", DMGL_ANSI}, /* ansi */
194 {"call", "()", 0}, /* old */
195 {"cl", "()", DMGL_ANSI}, /* ansi */
196 {"alshift", "<<", 0}, /* old */
197 {"ls", "<<", DMGL_ANSI}, /* ansi */
198 {"als", "<<=", DMGL_ANSI}, /* ansi */
199 {"arshift", ">>", 0}, /* old */
200 {"rs", ">>", DMGL_ANSI}, /* ansi */
201 {"ars", ">>=", DMGL_ANSI}, /* ansi */
202 {"component", "->", 0}, /* old */
203 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
204 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
205 {"indirect", "*", 0}, /* old */
206 {"method_call", "->()", 0}, /* old */
207 {"addr", "&", 0}, /* old (unary &) */
208 {"array", "[]", 0}, /* old */
209 {"vc", "[]", DMGL_ANSI}, /* ansi */
210 {"compound", ", ", 0}, /* old */
211 {"cm", ", ", DMGL_ANSI}, /* ansi */
212 {"cond", "?:", 0}, /* old */
213 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
214 {"max", ">?", 0}, /* old */
215 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
216 {"min", "<?", 0}, /* old */
217 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
218 {"nop", "", 0}, /* old (for operator=) */
219 {"rm", "->*", DMGL_ANSI}, /* ansi */
220 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
223 /* These values are used to indicate the various type varieties.
224 They are all non-zero so that they can be used as `success'
226 typedef enum type_kind_t
236 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
237 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
238 string_prepend(str, " ");}
239 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
240 string_append(str, " ");}
241 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
243 /* The scope separator appropriate for the language being demangled. */
244 #define SCOPE_STRING(work) "::"
246 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
247 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
249 /* Prototypes for local functions */
252 mop_up PARAMS ((struct work_stuff *, string *, int));
255 squangle_mop_up PARAMS ((struct work_stuff *));
259 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
263 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
266 demangle_template_template_parm PARAMS ((struct work_stuff *work,
267 const char **, string *));
270 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
271 string *, int, int));
274 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
278 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
281 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
284 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
288 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
291 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
294 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
297 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
300 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
303 arm_special PARAMS ((const char **, string *));
306 string_need PARAMS ((string *, int));
309 string_delete PARAMS ((string *));
312 string_init PARAMS ((string *));
315 string_clear PARAMS ((string *));
319 string_empty PARAMS ((string *));
323 string_append PARAMS ((string *, const char *));
326 string_appends PARAMS ((string *, string *));
329 string_appendn PARAMS ((string *, const char *, int));
332 string_prepend PARAMS ((string *, const char *));
335 string_prependn PARAMS ((string *, const char *, int));
338 get_count PARAMS ((const char **, int *));
341 consume_count PARAMS ((const char **));
344 consume_count_with_underscores PARAMS ((const char**));
347 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
350 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
353 do_type PARAMS ((struct work_stuff *, const char **, string *));
356 do_arg PARAMS ((struct work_stuff *, const char **, string *));
359 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
363 remember_type PARAMS ((struct work_stuff *, const char *, int));
366 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
369 register_Btype PARAMS ((struct work_stuff *));
372 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
375 forget_types PARAMS ((struct work_stuff *));
378 forget_B_and_K_types PARAMS ((struct work_stuff *));
381 string_prepends PARAMS ((string *, string *));
384 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
385 string*, type_kind_t));
387 /* Translate count to integer, consuming tokens in the process.
388 Conversion terminates on the first non-digit character.
389 Trying to consume something that isn't a count results in
390 no consumption of input and a return of 0. */
398 while (isdigit (**type))
401 count += **type - '0';
408 /* Like consume_count, but for counts that are preceded and followed
409 by '_' if they are greater than 10. Also, -1 is returned for
410 failure, since 0 can be a valid value. */
413 consume_count_with_underscores (mangled)
414 const char **mangled;
418 if (**mangled == '_')
421 if (!isdigit (**mangled))
424 idx = consume_count (mangled);
425 if (**mangled != '_')
426 /* The trailing underscore was missing. */
433 if (**mangled < '0' || **mangled > '9')
436 idx = **mangled - '0';
444 cplus_demangle_opname (opname, result, options)
451 struct work_stuff work[1];
454 len = strlen(opname);
457 memset ((char *) work, 0, sizeof (work));
458 work->options = options;
460 if (opname[0] == '_' && opname[1] == '_'
461 && opname[2] == 'o' && opname[3] == 'p')
464 /* type conversion operator. */
466 if (do_type (work, &tem, &type))
468 strcat (result, "operator ");
469 strncat (result, type.b, type.p - type.b);
470 string_delete (&type);
474 else if (opname[0] == '_' && opname[1] == '_'
475 && opname[2] >= 'a' && opname[2] <= 'z'
476 && opname[3] >= 'a' && opname[3] <= 'z')
478 if (opname[4] == '\0')
482 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
484 if (strlen (optable[i].in) == 2
485 && memcmp (optable[i].in, opname + 2, 2) == 0)
487 strcat (result, "operator");
488 strcat (result, optable[i].out);
496 if (opname[2] == 'a' && opname[5] == '\0')
500 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
502 if (strlen (optable[i].in) == 3
503 && memcmp (optable[i].in, opname + 2, 3) == 0)
505 strcat (result, "operator");
506 strcat (result, optable[i].out);
517 && strchr (cplus_markers, opname[2]) != NULL)
519 /* see if it's an assignment expression */
520 if (len >= 10 /* op$assign_ */
521 && memcmp (opname + 3, "assign_", 7) == 0)
524 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
527 if (strlen (optable[i].in) == len1
528 && memcmp (optable[i].in, opname + 10, len1) == 0)
530 strcat (result, "operator");
531 strcat (result, optable[i].out);
532 strcat (result, "=");
541 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
544 if (strlen (optable[i].in) == len1
545 && memcmp (optable[i].in, opname + 3, len1) == 0)
547 strcat (result, "operator");
548 strcat (result, optable[i].out);
555 else if (len >= 5 && memcmp (opname, "type", 4) == 0
556 && strchr (cplus_markers, opname[4]) != NULL)
558 /* type conversion operator */
560 if (do_type (work, &tem, &type))
562 strcat (result, "operator ");
563 strncat (result, type.b, type.p - type.b);
564 string_delete (&type);
568 squangle_mop_up (work);
572 /* Takes operator name as e.g. "++" and returns mangled
573 operator name (e.g. "postincrement_expr"), or NULL if not found.
575 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
576 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
579 cplus_mangle_opname (opname, options)
586 len = strlen (opname);
587 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
589 if (strlen (optable[i].out) == len
590 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
591 && memcmp (optable[i].out, opname, len) == 0)
592 return optable[i].in;
597 /* char *cplus_demangle (const char *mangled, int options)
599 If MANGLED is a mangled function name produced by GNU C++, then
600 a pointer to a malloced string giving a C++ representation
601 of the name will be returned; otherwise NULL will be returned.
602 It is the caller's responsibility to free the string which
605 The OPTIONS arg may contain one or more of the following bits:
607 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
609 DMGL_PARAMS Function parameters are included.
613 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
614 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
615 cplus_demangle ("foo__1Ai", 0) => "A::foo"
617 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
618 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
619 cplus_demangle ("foo__1Afe", 0) => "A::foo"
621 Note that any leading underscores, or other such characters prepended by
622 the compilation system, are presumed to have already been stripped from
626 cplus_demangle (mangled, options)
631 struct work_stuff work[1];
632 memset ((char *) work, 0, sizeof (work));
633 work -> options = options;
634 if ((work -> options & DMGL_STYLE_MASK) == 0)
635 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
637 ret = internal_cplus_demangle (work, mangled);
638 squangle_mop_up (work);
643 /* This function performs most of what cplus_demangle use to do, but
644 to be able to demangle a name with a B, K or n code, we need to
645 have a longer term memory of what types have been seen. The original
646 now intializes and cleans up the squangle code info, while internal
647 calls go directly to this routine to avoid resetting that info. */
650 internal_cplus_demangle (work, mangled)
651 struct work_stuff *work;
657 char *demangled = NULL;
659 int saved_volatile_type;
660 s1 = work->constructor;
661 s2 = work->destructor;
662 s3 = work->static_type;
663 s4 = work->const_type;
664 saved_volatile_type = work->volatile_type;
665 work->constructor = work->destructor = 0;
666 work->static_type = work->const_type = 0;
667 work->volatile_type = 0;
669 if ((mangled != NULL) && (*mangled != '\0'))
673 /* First check to see if gnu style demangling is active and if the
674 string to be demangled contains a CPLUS_MARKER. If so, attempt to
675 recognize one of the gnu special forms rather than looking for a
676 standard prefix. In particular, don't worry about whether there
677 is a "__" string in the mangled string. Consider "_$_5__foo" for
680 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
682 success = gnu_special (work, &mangled, &decl);
686 success = demangle_prefix (work, &mangled, &decl);
688 if (success && (*mangled != '\0'))
690 success = demangle_signature (work, &mangled, &decl);
692 if (work->constructor == 2)
694 string_prepend (&decl, "global constructors keyed to ");
695 work->constructor = 0;
697 else if (work->destructor == 2)
699 string_prepend (&decl, "global destructors keyed to ");
700 work->destructor = 0;
702 demangled = mop_up (work, &decl, success);
704 work->constructor = s1;
705 work->destructor = s2;
706 work->static_type = s3;
707 work->const_type = s4;
708 work->volatile_type = saved_volatile_type;
713 /* Clear out and squangling related storage */
715 squangle_mop_up (work)
716 struct work_stuff *work;
718 /* clean up the B and K type mangling types. */
719 forget_B_and_K_types (work);
720 if (work -> btypevec != NULL)
722 free ((char *) work -> btypevec);
724 if (work -> ktypevec != NULL)
726 free ((char *) work -> ktypevec);
730 /* Clear out any mangled storage */
733 mop_up (work, declp, success)
734 struct work_stuff *work;
738 char *demangled = NULL;
740 /* Discard the remembered types, if any. */
743 if (work -> typevec != NULL)
745 free ((char *) work -> typevec);
746 work -> typevec = NULL;
748 if (work->tmpl_argvec)
752 for (i = 0; i < work->ntmpl_args; i++)
753 if (work->tmpl_argvec[i])
754 free ((char*) work->tmpl_argvec[i]);
756 free ((char*) work->tmpl_argvec);
757 work->tmpl_argvec = NULL;
759 if (work->previous_argument)
761 string_delete (work->previous_argument);
762 free ((char*) work->previous_argument);
765 /* If demangling was successful, ensure that the demangled string is null
766 terminated and return it. Otherwise, free the demangling decl. */
770 string_delete (declp);
774 string_appendn (declp, "", 1);
775 demangled = declp -> b;
784 demangle_signature -- demangle the signature part of a mangled name
789 demangle_signature (struct work_stuff *work, const char **mangled,
794 Consume and demangle the signature portion of the mangled name.
796 DECLP is the string where demangled output is being built. At
797 entry it contains the demangled root name from the mangled name
798 prefix. I.E. either a demangled operator name or the root function
799 name. In some special cases, it may contain nothing.
801 *MANGLED points to the current unconsumed location in the mangled
802 name. As tokens are consumed and demangling is performed, the
803 pointer is updated to continuously point at the next token to
806 Demangling GNU style mangled names is nasty because there is no
807 explicit token that marks the start of the outermost function
811 demangle_signature (work, mangled, declp)
812 struct work_stuff *work;
813 const char **mangled;
819 int expect_return_type = 0;
820 const char *oldmangled = NULL;
824 while (success && (**mangled != '\0'))
829 oldmangled = *mangled;
830 success = demangle_qualified (work, mangled, declp, 1, 0);
832 remember_type (work, oldmangled, *mangled - oldmangled);
833 if (AUTO_DEMANGLING || GNU_DEMANGLING)
839 oldmangled = *mangled;
840 success = demangle_qualified (work, mangled, declp, 1, 0);
841 if (AUTO_DEMANGLING || GNU_DEMANGLING)
849 /* Static member function */
850 if (oldmangled == NULL)
852 oldmangled = *mangled;
855 work -> static_type = 1;
860 if (**mangled == 'C')
861 work -> const_type = 1;
863 work->volatile_type = 1;
865 /* a qualified member function */
866 if (oldmangled == NULL)
867 oldmangled = *mangled;
871 case '0': case '1': case '2': case '3': case '4':
872 case '5': case '6': case '7': case '8': case '9':
873 if (oldmangled == NULL)
875 oldmangled = *mangled;
877 success = demangle_class (work, mangled, declp);
880 remember_type (work, oldmangled, *mangled - oldmangled);
882 if (AUTO_DEMANGLING || GNU_DEMANGLING)
892 success = do_type (work, mangled, &s);
895 string_append (&s, SCOPE_STRING (work));
896 string_prepends (declp, &s);
905 /* ARM style demangling includes a specific 'F' character after
906 the class name. For GNU style, it is just implied. So we can
907 safely just consume any 'F' at this point and be compatible
908 with either style. */
914 /* For lucid/ARM style we have to forget any types we might
915 have remembered up to this point, since they were not argument
916 types. GNU style considers all types seen as available for
917 back references. See comment in demangle_args() */
919 if (LUCID_DEMANGLING || ARM_DEMANGLING)
923 success = demangle_args (work, mangled, declp);
928 string_init(&trawname);
930 if (oldmangled == NULL)
932 oldmangled = *mangled;
934 success = demangle_template (work, mangled, &tname,
938 remember_type (work, oldmangled, *mangled - oldmangled);
940 string_append (&tname, SCOPE_STRING (work));
942 string_prepends(declp, &tname);
943 if (work -> destructor & 1)
945 string_prepend (&trawname, "~");
946 string_appends (declp, &trawname);
947 work->destructor -= 1;
949 if ((work->constructor & 1) || (work->destructor & 1))
951 string_appends (declp, &trawname);
952 work->constructor -= 1;
954 string_delete(&trawname);
955 string_delete(&tname);
961 if (GNU_DEMANGLING && expect_return_type)
963 /* Read the return type. */
965 string_init (&return_type);
968 success = do_type (work, mangled, &return_type);
969 APPEND_BLANK (&return_type);
971 string_prepends (declp, &return_type);
972 string_delete (&return_type);
976 /* At the outermost level, we cannot have a return type specified,
977 so if we run into another '_' at this point we are dealing with
978 a mangled name that is either bogus, or has been mangled by
979 some algorithm we don't know how to deal with. So just
980 reject the entire demangling. */
987 /* A G++ template function. Read the template arguments. */
988 success = demangle_template (work, mangled, declp, 0, 0,
990 if (!(work->constructor & 1))
991 expect_return_type = 1;
1000 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1002 /* Assume we have stumbled onto the first outermost function
1003 argument token, and start processing args. */
1005 success = demangle_args (work, mangled, declp);
1009 /* Non-GNU demanglers use a specific token to mark the start
1010 of the outermost function argument tokens. Typically 'F',
1011 for ARM-demangling, for example. So if we find something
1012 we are not prepared for, it must be an error. */
1018 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1021 if (success && expect_func)
1024 success = demangle_args (work, mangled, declp);
1025 /* Since template include the mangling of their return types,
1026 we must set expect_func to 0 so that we don't try do
1027 demangle more arguments the next time we get here. */
1032 if (success && !func_done)
1034 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1036 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1037 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1038 first case, and need to ensure that the '(void)' gets added to
1039 the current declp. Note that with ARM, the first case
1040 represents the name of a static data member 'foo::bar',
1041 which is in the current declp, so we leave it alone. */
1042 success = demangle_args (work, mangled, declp);
1045 if (success && work -> static_type && PRINT_ARG_TYPES)
1046 string_append (declp, " static");
1047 if (success && work -> const_type && PRINT_ARG_TYPES)
1048 string_append (declp, " const");
1049 else if (success && work->volatile_type && PRINT_ARG_TYPES)
1050 string_append (declp, " volatile");
1058 demangle_method_args (work, mangled, declp)
1059 struct work_stuff *work;
1060 const char **mangled;
1065 if (work -> static_type)
1067 string_append (declp, *mangled + 1);
1068 *mangled += strlen (*mangled);
1073 success = demangle_args (work, mangled, declp);
1081 demangle_template_template_parm (work, mangled, tname)
1082 struct work_stuff *work;
1083 const char **mangled;
1092 string_append (tname, "template <");
1093 /* get size of template parameter list */
1094 if (get_count (mangled, &r))
1096 for (i = 0; i < r; i++)
1100 string_append (tname, ", ");
1103 /* Z for type parameters */
1104 if (**mangled == 'Z')
1107 string_append (tname, "class");
1109 /* z for template parameters */
1110 else if (**mangled == 'z')
1114 demangle_template_template_parm (work, mangled, tname);
1122 /* temp is initialized in do_type */
1123 success = do_type (work, mangled, &temp);
1126 string_appends (tname, &temp);
1128 string_delete(&temp);
1138 if (tname->p[-1] == '>')
1139 string_append (tname, " ");
1140 string_append (tname, "> class");
1145 demangle_integral_value (work, mangled, s)
1146 struct work_stuff *work;
1147 const char** mangled;
1152 if (**mangled == 'E')
1154 int need_operator = 0;
1157 string_appendn (s, "(", 1);
1159 while (success && **mangled != 'W' && **mangled != '\0')
1168 len = strlen (*mangled);
1171 i < sizeof (optable) / sizeof (optable [0]);
1174 size_t l = strlen (optable[i].in);
1177 && memcmp (optable[i].in, *mangled, l) == 0)
1179 string_appendn (s, " ", 1);
1180 string_append (s, optable[i].out);
1181 string_appendn (s, " ", 1);
1194 success = demangle_template_value_parm (work, mangled, s,
1198 if (**mangled != 'W')
1202 string_appendn (s, ")", 1);
1206 else if (**mangled == 'Q' || **mangled == 'K')
1207 success = demangle_qualified (work, mangled, s, 0, 1);
1212 if (**mangled == 'm')
1214 string_appendn (s, "-", 1);
1217 while (isdigit (**mangled))
1219 string_appendn (s, *mangled, 1);
1229 demangle_template_value_parm (work, mangled, s, tk)
1230 struct work_stuff *work;
1231 const char **mangled;
1237 if (**mangled == 'Y')
1239 /* The next argument is a template parameter. */
1243 idx = consume_count_with_underscores (mangled);
1245 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1246 || consume_count_with_underscores (mangled) == -1)
1248 if (work->tmpl_argvec)
1249 string_append (s, work->tmpl_argvec[idx]);
1253 sprintf(buf, "T%d", idx);
1254 string_append (s, buf);
1257 else if (tk == tk_integral)
1258 success = demangle_integral_value (work, mangled, s);
1259 else if (tk == tk_char)
1263 if (**mangled == 'm')
1265 string_appendn (s, "-", 1);
1268 string_appendn (s, "'", 1);
1269 val = consume_count(mangled);
1274 string_appendn (s, &tmp[0], 1);
1275 string_appendn (s, "'", 1);
1277 else if (tk == tk_bool)
1279 int val = consume_count (mangled);
1281 string_appendn (s, "false", 5);
1283 string_appendn (s, "true", 4);
1287 else if (tk == tk_real)
1289 if (**mangled == 'm')
1291 string_appendn (s, "-", 1);
1294 while (isdigit (**mangled))
1296 string_appendn (s, *mangled, 1);
1299 if (**mangled == '.') /* fraction */
1301 string_appendn (s, ".", 1);
1303 while (isdigit (**mangled))
1305 string_appendn (s, *mangled, 1);
1309 if (**mangled == 'e') /* exponent */
1311 string_appendn (s, "e", 1);
1313 while (isdigit (**mangled))
1315 string_appendn (s, *mangled, 1);
1320 else if (tk == tk_pointer)
1322 int symbol_len = consume_count (mangled);
1323 if (symbol_len == 0)
1325 if (symbol_len == 0)
1326 string_appendn (s, "0", 1);
1329 char *p = xmalloc (symbol_len + 1), *q;
1330 strncpy (p, *mangled, symbol_len);
1331 p [symbol_len] = '\0';
1332 q = internal_cplus_demangle (work, p);
1333 string_appendn (s, "&", 1);
1336 string_append (s, q);
1340 string_append (s, p);
1343 *mangled += symbol_len;
1349 /* Demangle the template name in MANGLED. The full name of the
1350 template (e.g., S<int>) is placed in TNAME. The name without the
1351 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1352 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1353 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1354 the tmeplate is remembered in the list of back-referenceable
1358 demangle_template (work, mangled, tname, trawname, is_type, remember)
1359 struct work_stuff *work;
1360 const char **mangled;
1378 bindex = register_Btype (work);
1380 /* get template name */
1381 if (**mangled == 'z')
1387 idx = consume_count_with_underscores (mangled);
1389 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1390 || consume_count_with_underscores (mangled) == -1)
1393 if (work->tmpl_argvec)
1395 string_append (tname, work->tmpl_argvec[idx]);
1397 string_append (trawname, work->tmpl_argvec[idx]);
1402 sprintf(buf, "T%d", idx);
1403 string_append (tname, buf);
1405 string_append (trawname, buf);
1410 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
1414 string_appendn (tname, *mangled, r);
1416 string_appendn (trawname, *mangled, r);
1420 string_append (tname, "<");
1421 /* get size of template parameter list */
1422 if (!get_count (mangled, &r))
1428 /* Create an array for saving the template argument values. */
1429 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1430 work->ntmpl_args = r;
1431 for (i = 0; i < r; i++)
1432 work->tmpl_argvec[i] = 0;
1434 for (i = 0; i < r; i++)
1438 string_append (tname, ", ");
1440 /* Z for type parameters */
1441 if (**mangled == 'Z')
1444 /* temp is initialized in do_type */
1445 success = do_type (work, mangled, &temp);
1448 string_appends (tname, &temp);
1452 /* Save the template argument. */
1453 int len = temp.p - temp.b;
1454 work->tmpl_argvec[i] = xmalloc (len + 1);
1455 memcpy (work->tmpl_argvec[i], temp.b, len);
1456 work->tmpl_argvec[i][len] = '\0';
1459 string_delete(&temp);
1465 /* z for template parameters */
1466 else if (**mangled == 'z')
1470 success = demangle_template_template_parm (work, mangled, tname);
1473 && (r2 = consume_count (mangled)) > 0 && strlen (*mangled) >= r2)
1475 string_append (tname, " ");
1476 string_appendn (tname, *mangled, r2);
1479 /* Save the template argument. */
1481 work->tmpl_argvec[i] = xmalloc (len + 1);
1482 memcpy (work->tmpl_argvec[i], *mangled, len);
1483 work->tmpl_argvec[i][len] = '\0';
1496 const char* start_of_value_parm = *mangled;
1498 /* otherwise, value parameter */
1500 /* temp is initialized in do_type */
1501 success = do_type (work, mangled, &temp);
1502 string_delete(&temp);
1514 success = demangle_template_value_parm (work, mangled, s,
1515 (type_kind_t) success);
1527 int len = s->p - s->b;
1528 work->tmpl_argvec[i] = xmalloc (len + 1);
1529 memcpy (work->tmpl_argvec[i], s->b, len);
1530 work->tmpl_argvec[i][len] = '\0';
1532 string_appends (tname, s);
1539 if (tname->p[-1] == '>')
1540 string_append (tname, " ");
1541 string_append (tname, ">");
1544 if (is_type && remember)
1545 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1548 if (work -> static_type)
1550 string_append (declp, *mangled + 1);
1551 *mangled += strlen (*mangled);
1556 success = demangle_args (work, mangled, declp);
1564 arm_pt (work, mangled, n, anchor, args)
1565 struct work_stuff *work;
1566 const char *mangled;
1568 const char **anchor, **args;
1571 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1574 *args = *anchor + 6;
1575 len = consume_count (args);
1576 if (*args + len == mangled + n && **args == '_')
1586 demangle_arm_pt (work, mangled, n, declp)
1587 struct work_stuff *work;
1588 const char **mangled;
1594 const char *e = *mangled + n;
1597 if (arm_pt (work, *mangled, n, &p, &args))
1601 string_appendn (declp, *mangled, p - *mangled);
1602 string_append (declp, "<");
1603 /* should do error checking here */
1605 string_clear (&arg);
1606 do_type (work, &args, &arg);
1607 string_appends (declp, &arg);
1608 string_append (declp, ",");
1610 string_delete (&arg);
1612 string_append (declp, ">");
1616 string_appendn (declp, *mangled, n);
1622 demangle_class_name (work, mangled, declp)
1623 struct work_stuff *work;
1624 const char **mangled;
1630 n = consume_count (mangled);
1631 if (strlen (*mangled) >= n)
1633 demangle_arm_pt (work, mangled, n, declp);
1644 demangle_class -- demangle a mangled class sequence
1649 demangle_class (struct work_stuff *work, const char **mangled,
1654 DECLP points to the buffer into which demangling is being done.
1656 *MANGLED points to the current token to be demangled. On input,
1657 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1658 On exit, it points to the next token after the mangled class on
1659 success, or the first unconsumed token on failure.
1661 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1662 we are demangling a constructor or destructor. In this case
1663 we prepend "class::class" or "class::~class" to DECLP.
1665 Otherwise, we prepend "class::" to the current DECLP.
1667 Reset the constructor/destructor flags once they have been
1668 "consumed". This allows demangle_class to be called later during
1669 the same demangling, to do normal class demangling.
1671 Returns 1 if demangling is successful, 0 otherwise.
1676 demangle_class (work, mangled, declp)
1677 struct work_stuff *work;
1678 const char **mangled;
1685 string_init (&class_name);
1686 btype = register_Btype (work);
1687 if (demangle_class_name (work, mangled, &class_name))
1689 if ((work->constructor & 1) || (work->destructor & 1))
1691 string_prepends (declp, &class_name);
1692 if (work -> destructor & 1)
1694 string_prepend (declp, "~");
1695 work -> destructor -= 1;
1699 work -> constructor -= 1;
1702 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
1703 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
1704 string_prepend (declp, SCOPE_STRING (work));
1705 string_prepends (declp, &class_name);
1708 string_delete (&class_name);
1716 demangle_prefix -- consume the mangled name prefix and find signature
1721 demangle_prefix (struct work_stuff *work, const char **mangled,
1726 Consume and demangle the prefix of the mangled name.
1728 DECLP points to the string buffer into which demangled output is
1729 placed. On entry, the buffer is empty. On exit it contains
1730 the root function name, the demangled operator name, or in some
1731 special cases either nothing or the completely demangled result.
1733 MANGLED points to the current pointer into the mangled name. As each
1734 token of the mangled name is consumed, it is updated. Upon entry
1735 the current mangled name pointer points to the first character of
1736 the mangled name. Upon exit, it should point to the first character
1737 of the signature if demangling was successful, or to the first
1738 unconsumed character if demangling of the prefix was unsuccessful.
1740 Returns 1 on success, 0 otherwise.
1744 demangle_prefix (work, mangled, declp)
1745 struct work_stuff *work;
1746 const char **mangled;
1753 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1755 char *marker = strchr (cplus_markers, (*mangled)[8]);
1756 if (marker != NULL && *marker == (*mangled)[10])
1758 if ((*mangled)[9] == 'D')
1760 /* it's a GNU global destructor to be executed at program exit */
1762 work->destructor = 2;
1763 if (gnu_special (work, mangled, declp))
1766 else if ((*mangled)[9] == 'I')
1768 /* it's a GNU global constructor to be executed at program init */
1770 work->constructor = 2;
1771 if (gnu_special (work, mangled, declp))
1776 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1778 /* it's a ARM global destructor to be executed at program exit */
1780 work->destructor = 2;
1782 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1784 /* it's a ARM global constructor to be executed at program initial */
1786 work->constructor = 2;
1789 /* This block of code is a reduction in strength time optimization
1791 scan = mystrstr (*mangled, "__"); */
1797 scan = strchr (scan, '_');
1798 } while (scan != NULL && *++scan != '_');
1800 if (scan != NULL) --scan;
1805 /* We found a sequence of two or more '_', ensure that we start at
1806 the last pair in the sequence. */
1807 i = strspn (scan, "_");
1818 else if (work -> static_type)
1820 if (!isdigit (scan[0]) && (scan[0] != 't'))
1825 else if ((scan == *mangled)
1826 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
1827 || (scan[2] == 'K') || (scan[2] == 'H')))
1829 /* The ARM says nothing about the mangling of local variables.
1830 But cfront mangles local variables by prepending __<nesting_level>
1831 to them. As an extension to ARM demangling we handle this case. */
1832 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2]))
1834 *mangled = scan + 2;
1835 consume_count (mangled);
1836 string_append (declp, *mangled);
1837 *mangled += strlen (*mangled);
1842 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1843 names like __Q2_3foo3bar for nested type names. So don't accept
1844 this style of constructor for cfront demangling. A GNU
1845 style member-template constructor starts with 'H'. */
1846 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1847 work -> constructor += 1;
1848 *mangled = scan + 2;
1851 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
1853 /* Mangled name starts with "__". Skip over any leading '_' characters,
1854 then find the next "__" that separates the prefix from the signature.
1856 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1857 || (arm_special (mangled, declp) == 0))
1859 while (*scan == '_')
1863 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
1865 /* No separator (I.E. "__not_mangled"), or empty signature
1866 (I.E. "__not_mangled_either__") */
1871 demangle_function_name (work, mangled, declp, scan);
1875 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
1877 /* Cfront-style parameterized type. Handled later as a signature. */
1881 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
1883 else if (*(scan + 2) != '\0')
1885 /* Mangled name does not start with "__" but does have one somewhere
1886 in there with non empty stuff after it. Looks like a global
1888 demangle_function_name (work, mangled, declp, scan);
1892 /* Doesn't look like a mangled name */
1896 if (!success && (work->constructor == 2 || work->destructor == 2))
1898 string_append (declp, *mangled);
1899 *mangled += strlen (*mangled);
1909 gnu_special -- special handling of gnu mangled strings
1914 gnu_special (struct work_stuff *work, const char **mangled,
1920 Process some special GNU style mangling forms that don't fit
1921 the normal pattern. For example:
1923 _$_3foo (destructor for class foo)
1924 _vt$foo (foo virtual table)
1925 _vt$foo$bar (foo::bar virtual table)
1926 __vt_foo (foo virtual table, new style with thunks)
1927 _3foo$varname (static data member)
1928 _Q22rs2tu$vw (static data member)
1929 __t6vector1Zii (constructor with template)
1930 __thunk_4__$_7ostream (virtual function thunk)
1934 gnu_special (work, mangled, declp)
1935 struct work_stuff *work;
1936 const char **mangled;
1943 if ((*mangled)[0] == '_'
1944 && strchr (cplus_markers, (*mangled)[1]) != NULL
1945 && (*mangled)[2] == '_')
1947 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
1949 work -> destructor += 1;
1951 else if ((*mangled)[0] == '_'
1952 && (((*mangled)[1] == '_'
1953 && (*mangled)[2] == 'v'
1954 && (*mangled)[3] == 't'
1955 && (*mangled)[4] == '_')
1956 || ((*mangled)[1] == 'v'
1957 && (*mangled)[2] == 't'
1958 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
1960 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
1961 and create the decl. Note that we consume the entire mangled
1962 input string, which means that demangle_signature has no work
1964 if ((*mangled)[2] == 'v')
1965 (*mangled) += 5; /* New style, with thunks: "__vt_" */
1967 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
1968 while (**mangled != '\0')
1970 p = strpbrk (*mangled, cplus_markers);
1975 success = demangle_qualified (work, mangled, declp, 0, 1);
1978 success = demangle_template (work, mangled, declp, 0, 1,
1982 if (isdigit(*mangled[0]))
1984 n = consume_count(mangled);
1985 /* We may be seeing a too-large size, or else a
1986 ".<digits>" indicating a static local symbol. In
1987 any case, declare victory and move on; *don't* try
1988 to use n to allocate. */
1989 if (n > strlen (*mangled))
1997 n = strcspn (*mangled, cplus_markers);
1999 string_appendn (declp, *mangled, n);
2003 if (success && ((p == NULL) || (p == *mangled)))
2007 string_append (declp, SCOPE_STRING (work));
2018 string_append (declp, " virtual table");
2020 else if ((*mangled)[0] == '_'
2021 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2022 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2024 /* static data member, "_3foo$varname" for example */
2030 success = demangle_qualified (work, mangled, declp, 0, 1);
2033 success = demangle_template (work, mangled, declp, 0, 1, 1);
2036 n = consume_count (mangled);
2037 string_appendn (declp, *mangled, n);
2040 if (success && (p == *mangled))
2042 /* Consumed everything up to the cplus_marker, append the
2045 string_append (declp, SCOPE_STRING (work));
2046 n = strlen (*mangled);
2047 string_appendn (declp, *mangled, n);
2055 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2057 int delta = ((*mangled) += 8, consume_count (mangled));
2058 char *method = internal_cplus_demangle (work, ++*mangled);
2062 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2063 string_append (declp, buf);
2064 string_append (declp, method);
2066 n = strlen (*mangled);
2074 else if (strncmp (*mangled, "__t", 3) == 0
2075 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2077 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2083 success = demangle_qualified (work, mangled, declp, 0, 1);
2086 success = demangle_template (work, mangled, declp, 0, 1, 1);
2089 success = demangle_fund_type (work, mangled, declp);
2092 if (success && **mangled != '\0')
2095 string_append (declp, p);
2108 arm_special -- special handling of ARM/lucid mangled strings
2113 arm_special (const char **mangled,
2119 Process some special ARM style mangling forms that don't fit
2120 the normal pattern. For example:
2122 __vtbl__3foo (foo virtual table)
2123 __vtbl__3foo__3bar (bar::foo virtual table)
2128 arm_special (mangled, declp)
2129 const char **mangled;
2136 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2138 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2139 and create the decl. Note that we consume the entire mangled
2140 input string, which means that demangle_signature has no work
2142 scan = *mangled + ARM_VTABLE_STRLEN;
2143 while (*scan != '\0') /* first check it can be demangled */
2145 n = consume_count (&scan);
2148 return (0); /* no good */
2151 if (scan[0] == '_' && scan[1] == '_')
2156 (*mangled) += ARM_VTABLE_STRLEN;
2157 while (**mangled != '\0')
2159 n = consume_count (mangled);
2160 string_prependn (declp, *mangled, n);
2162 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2164 string_prepend (declp, "::");
2168 string_append (declp, " virtual table");
2181 demangle_qualified -- demangle 'Q' qualified name strings
2186 demangle_qualified (struct work_stuff *, const char *mangled,
2187 string *result, int isfuncname, int append);
2191 Demangle a qualified name, such as "Q25Outer5Inner" which is
2192 the mangled form of "Outer::Inner". The demangled output is
2193 prepended or appended to the result string according to the
2194 state of the append flag.
2196 If isfuncname is nonzero, then the qualified name we are building
2197 is going to be used as a member function name, so if it is a
2198 constructor or destructor function, append an appropriate
2199 constructor or destructor name. I.E. for the above example,
2200 the result for use as a constructor is "Outer::Inner::Inner"
2201 and the result for use as a destructor is "Outer::Inner::~Inner".
2205 Numeric conversion is ASCII dependent (FIXME).
2210 demangle_qualified (work, mangled, result, isfuncname, append)
2211 struct work_stuff *work;
2212 const char **mangled;
2223 int bindex = register_Btype (work);
2225 /* We only make use of ISFUNCNAME if the entity is a constructor or
2227 isfuncname = (isfuncname
2228 && ((work->constructor & 1) || (work->destructor & 1)));
2230 string_init (&temp);
2231 string_init (&last_name);
2233 if ((*mangled)[0] == 'K')
2235 /* Squangling qualified name reuse */
2238 idx = consume_count_with_underscores (mangled);
2239 if (idx == -1 || idx > work -> numk)
2242 string_append (&temp, work -> ktypevec[idx]);
2245 switch ((*mangled)[1])
2248 /* GNU mangled name with more than 9 classes. The count is preceded
2249 by an underscore (to distinguish it from the <= 9 case) and followed
2250 by an underscore. */
2252 qualifiers = atoi (p);
2253 if (!isdigit (*p) || *p == '0')
2256 /* Skip the digits. */
2257 while (isdigit (*p))
2275 /* The count is in a single digit. */
2276 num[0] = (*mangled)[1];
2278 qualifiers = atoi (num);
2280 /* If there is an underscore after the digit, skip it. This is
2281 said to be for ARM-qualified names, but the ARM makes no
2282 mention of such an underscore. Perhaps cfront uses one. */
2283 if ((*mangled)[2] == '_')
2298 /* Pick off the names and collect them in the temp buffer in the order
2299 in which they are found, separated by '::'. */
2301 while (qualifiers-- > 0)
2304 string_clear (&last_name);
2306 if (*mangled[0] == '_')
2309 if (*mangled[0] == 't')
2311 /* Here we always append to TEMP since we will want to use
2312 the template name without the template parameters as a
2313 constructor or destructor name. The appropriate
2314 (parameter-less) value is returned by demangle_template
2315 in LAST_NAME. We do not remember the template type here,
2316 in order to match the G++ mangling algorithm. */
2317 success = demangle_template(work, mangled, &temp,
2322 else if (*mangled[0] == 'K')
2326 idx = consume_count_with_underscores (mangled);
2327 if (idx == -1 || idx > work->numk)
2330 string_append (&temp, work->ktypevec[idx]);
2333 if (!success) break;
2337 success = do_type (work, mangled, &last_name);
2340 string_appends (&temp, &last_name);
2344 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2347 string_append (&temp, SCOPE_STRING (work));
2350 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2352 /* If we are using the result as a function name, we need to append
2353 the appropriate '::' separated constructor or destructor name.
2354 We do this here because this is the most convenient place, where
2355 we already have a pointer to the name and the length of the name. */
2359 string_append (&temp, SCOPE_STRING (work));
2360 if (work -> destructor & 1)
2361 string_append (&temp, "~");
2362 string_appends (&temp, &last_name);
2365 /* Now either prepend the temp buffer to the result, or append it,
2366 depending upon the state of the append flag. */
2369 string_appends (result, &temp);
2372 if (!STRING_EMPTY (result))
2373 string_append (&temp, SCOPE_STRING (work));
2374 string_prepends (result, &temp);
2377 string_delete (&last_name);
2378 string_delete (&temp);
2386 get_count -- convert an ascii count to integer, consuming tokens
2391 get_count (const char **type, int *count)
2395 Return 0 if no conversion is performed, 1 if a string is converted.
2399 get_count (type, count)
2406 if (!isdigit (**type))
2412 *count = **type - '0';
2414 if (isdigit (**type))
2424 while (isdigit (*p));
2435 /* RESULT will be initialised here; it will be freed on failure. The
2436 value returned is really a type_kind_t. */
2439 do_type (work, mangled, result)
2440 struct work_stuff *work;
2441 const char **mangled;
2448 const char *remembered_type;
2452 type_kind_t tk = tk_none;
2454 string_init (&btype);
2455 string_init (&decl);
2456 string_init (result);
2460 while (success && !done)
2466 /* A pointer type */
2470 string_prepend (&decl, "*");
2475 /* A reference type */
2478 string_prepend (&decl, "&");
2487 string_prepend (&decl, "(");
2488 string_append (&decl, ")[");
2489 success = demangle_template_value_parm (work, mangled, &decl,
2491 if (**mangled == '_')
2493 string_append (&decl, "]");
2497 /* A back reference to a previously seen type */
2500 if (!get_count (mangled, &n) || n >= work -> ntypes)
2506 remembered_type = work -> typevec[n];
2507 mangled = &remembered_type;
2514 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
2516 string_prepend (&decl, "(");
2517 string_append (&decl, ")");
2519 /* After picking off the function args, we expect to either find the
2520 function return type (preceded by an '_') or the end of the
2522 if (!demangle_nested_args (work, mangled, &decl)
2523 || (**mangled != '_' && **mangled != '\0'))
2528 if (success && (**mangled == '_'))
2538 member = **mangled == 'M';
2540 if (!isdigit (**mangled) && **mangled != 't')
2546 string_append (&decl, ")");
2547 string_prepend (&decl, SCOPE_STRING (work));
2548 if (isdigit (**mangled))
2550 n = consume_count (mangled);
2551 if (strlen (*mangled) < n)
2556 string_prependn (&decl, *mangled, n);
2562 string_init (&temp);
2563 success = demangle_template (work, mangled, &temp,
2567 string_prependn (&decl, temp.b, temp.p - temp.b);
2568 string_clear (&temp);
2573 string_prepend (&decl, "(");
2576 if (**mangled == 'C')
2581 if (**mangled == 'V')
2586 if (*(*mangled)++ != 'F')
2592 if ((member && !demangle_nested_args (work, mangled, &decl))
2593 || **mangled != '_')
2599 if (! PRINT_ANSI_QUALIFIERS)
2605 APPEND_BLANK (&decl);
2606 string_append (&decl, "const");
2610 APPEND_BLANK (&decl);
2611 string_append (&decl, "volatile");
2622 if ((*mangled)[1] == 'P')
2625 if (PRINT_ANSI_QUALIFIERS)
2627 if (!STRING_EMPTY (&decl))
2629 string_prepend (&decl, " ");
2631 string_prepend (&decl,
2632 (**mangled) == 'C' ? "const" : "volatile");
2649 /* A qualified name, such as "Outer::Inner". */
2653 success = demangle_qualified (work, mangled, result, 0, 1);
2657 /* A back reference to a previously seen squangled type */
2660 if (!get_count (mangled, &n) || n >= work -> numb)
2663 string_append (result, work->btypevec[n]);
2668 /* A template parm. We substitute the corresponding argument. */
2673 idx = consume_count_with_underscores (mangled);
2676 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2677 || consume_count_with_underscores (mangled) == -1)
2683 if (work->tmpl_argvec)
2684 string_append (result, work->tmpl_argvec[idx]);
2688 sprintf(buf, "T%d", idx);
2689 string_append (result, buf);
2697 success = demangle_fund_type (work, mangled, result);
2699 tk = (type_kind_t) success;
2705 if (!STRING_EMPTY (&decl))
2707 string_append (result, " ");
2708 string_appends (result, &decl);
2712 string_delete (result);
2713 string_delete (&decl);
2716 /* Assume an integral type, if we're not sure. */
2717 return (int) ((tk == tk_none) ? tk_integral : tk);
2722 /* Given a pointer to a type string that represents a fundamental type
2723 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2724 string in which the demangled output is being built in RESULT, and
2725 the WORK structure, decode the types and add them to the result.
2730 "Sl" => "signed long"
2731 "CUs" => "const unsigned short"
2733 The value returned is really a type_kind_t. */
2736 demangle_fund_type (work, mangled, result)
2737 struct work_stuff *work;
2738 const char **mangled;
2744 type_kind_t tk = tk_integral;
2746 string_init (&btype);
2748 /* First pick off any type qualifiers. There can be more than one. */
2756 if (PRINT_ANSI_QUALIFIERS)
2758 APPEND_BLANK (result);
2759 string_append (result, "const");
2764 APPEND_BLANK (result);
2765 string_append (result, "unsigned");
2767 case 'S': /* signed char only */
2769 APPEND_BLANK (result);
2770 string_append (result, "signed");
2774 if (PRINT_ANSI_QUALIFIERS)
2776 APPEND_BLANK (result);
2777 string_append (result, "volatile");
2782 APPEND_BLANK (result);
2783 string_append (result, "__complex");
2791 /* Now pick off the fundamental type. There can be only one. */
2800 APPEND_BLANK (result);
2801 string_append (result, "void");
2805 APPEND_BLANK (result);
2806 string_append (result, "long long");
2810 APPEND_BLANK (result);
2811 string_append (result, "long");
2815 APPEND_BLANK (result);
2816 string_append (result, "int");
2820 APPEND_BLANK (result);
2821 string_append (result, "short");
2825 APPEND_BLANK (result);
2826 string_append (result, "bool");
2831 APPEND_BLANK (result);
2832 string_append (result, "char");
2837 APPEND_BLANK (result);
2838 string_append (result, "wchar_t");
2843 APPEND_BLANK (result);
2844 string_append (result, "long double");
2849 APPEND_BLANK (result);
2850 string_append (result, "double");
2855 APPEND_BLANK (result);
2856 string_append (result, "float");
2861 if (!isdigit (**mangled))
2867 /* An explicit type, such as "6mytype" or "7integer" */
2879 int bindex = register_Btype (work);
2881 string_init (&btype);
2882 if (demangle_class_name (work, mangled, &btype)) {
2883 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
2884 APPEND_BLANK (result);
2885 string_appends (result, &btype);
2889 string_delete (&btype);
2894 success = demangle_template (work, mangled, &btype, 0, 1, 1);
2895 string_appends (result, &btype);
2903 return success ? ((int) tk) : 0;
2906 /* Demangle the next argument, given by MANGLED into RESULT, which
2907 *should be an uninitialized* string. It will be initialized here,
2908 and free'd should anything go wrong. */
2911 do_arg (work, mangled, result)
2912 struct work_stuff *work;
2913 const char **mangled;
2916 /* Remember where we started so that we can record the type, for
2917 non-squangling type remembering. */
2918 const char *start = *mangled;
2920 string_init (result);
2922 if (work->nrepeats > 0)
2926 if (work->previous_argument == 0)
2929 /* We want to reissue the previous type in this argument list. */
2930 string_appends (result, work->previous_argument);
2934 if (**mangled == 'n')
2936 /* A squangling-style repeat. */
2938 work->nrepeats = consume_count(mangled);
2940 if (work->nrepeats == 0)
2941 /* This was not a repeat count after all. */
2944 if (work->nrepeats > 9)
2946 if (**mangled != '_')
2947 /* The repeat count should be followed by an '_' in this
2954 /* Now, the repeat is all set up. */
2955 return do_arg (work, mangled, result);
2958 /* Save the result in WORK->previous_argument so that we can find it
2959 if it's repeated. Note that saving START is not good enough: we
2960 do not want to add additional types to the back-referenceable
2961 type vector when processing a repeated type. */
2962 if (work->previous_argument)
2963 string_clear (work->previous_argument);
2966 work->previous_argument = (string*) xmalloc (sizeof (string));
2967 string_init (work->previous_argument);
2970 if (!do_type (work, mangled, work->previous_argument))
2973 string_appends (result, work->previous_argument);
2975 remember_type (work, start, *mangled - start);
2980 remember_type (work, start, len)
2981 struct work_stuff *work;
2987 if (work->forgetting_types)
2990 if (work -> ntypes >= work -> typevec_size)
2992 if (work -> typevec_size == 0)
2994 work -> typevec_size = 3;
2996 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3000 work -> typevec_size *= 2;
3002 = (char **) xrealloc ((char *)work -> typevec,
3003 sizeof (char *) * work -> typevec_size);
3006 tem = xmalloc (len + 1);
3007 memcpy (tem, start, len);
3009 work -> typevec[work -> ntypes++] = tem;
3013 /* Remember a K type class qualifier. */
3015 remember_Ktype (work, start, len)
3016 struct work_stuff *work;
3022 if (work -> numk >= work -> ksize)
3024 if (work -> ksize == 0)
3028 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3034 = (char **) xrealloc ((char *)work -> ktypevec,
3035 sizeof (char *) * work -> ksize);
3038 tem = xmalloc (len + 1);
3039 memcpy (tem, start, len);
3041 work -> ktypevec[work -> numk++] = tem;
3044 /* Register a B code, and get an index for it. B codes are registered
3045 as they are seen, rather than as they are completed, so map<temp<char> >
3046 registers map<temp<char> > as B0, and temp<char> as B1 */
3049 register_Btype (work)
3050 struct work_stuff *work;
3054 if (work -> numb >= work -> bsize)
3056 if (work -> bsize == 0)
3060 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3066 = (char **) xrealloc ((char *)work -> btypevec,
3067 sizeof (char *) * work -> bsize);
3070 ret = work -> numb++;
3071 work -> btypevec[ret] = NULL;
3075 /* Store a value into a previously registered B code type. */
3078 remember_Btype (work, start, len, index)
3079 struct work_stuff *work;
3085 tem = xmalloc (len + 1);
3086 memcpy (tem, start, len);
3088 work -> btypevec[index] = tem;
3091 /* Lose all the info related to B and K type codes. */
3093 forget_B_and_K_types (work)
3094 struct work_stuff *work;
3098 while (work -> numk > 0)
3100 i = --(work -> numk);
3101 if (work -> ktypevec[i] != NULL)
3103 free (work -> ktypevec[i]);
3104 work -> ktypevec[i] = NULL;
3108 while (work -> numb > 0)
3110 i = --(work -> numb);
3111 if (work -> btypevec[i] != NULL)
3113 free (work -> btypevec[i]);
3114 work -> btypevec[i] = NULL;
3118 /* Forget the remembered types, but not the type vector itself. */
3122 struct work_stuff *work;
3126 while (work -> ntypes > 0)
3128 i = --(work -> ntypes);
3129 if (work -> typevec[i] != NULL)
3131 free (work -> typevec[i]);
3132 work -> typevec[i] = NULL;
3137 /* Process the argument list part of the signature, after any class spec
3138 has been consumed, as well as the first 'F' character (if any). For
3141 "__als__3fooRT0" => process "RT0"
3142 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3144 DECLP must be already initialised, usually non-empty. It won't be freed
3147 Note that g++ differs significantly from ARM and lucid style mangling
3148 with regards to references to previously seen types. For example, given
3149 the source fragment:
3153 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3156 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3157 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3159 g++ produces the names:
3164 while lcc (and presumably other ARM style compilers as well) produces:
3166 foo__FiR3fooT1T2T1T2
3167 __ct__3fooFiR3fooT1T2T1T2
3169 Note that g++ bases its type numbers starting at zero and counts all
3170 previously seen types, while lucid/ARM bases its type numbers starting
3171 at one and only considers types after it has seen the 'F' character
3172 indicating the start of the function args. For lucid/ARM style, we
3173 account for this difference by discarding any previously seen types when
3174 we see the 'F' character, and subtracting one from the type number
3180 demangle_args (work, mangled, declp)
3181 struct work_stuff *work;
3182 const char **mangled;
3192 if (PRINT_ARG_TYPES)
3194 string_append (declp, "(");
3195 if (**mangled == '\0')
3197 string_append (declp, "void");
3201 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3202 || work->nrepeats > 0)
3204 if ((**mangled == 'N') || (**mangled == 'T'))
3206 temptype = *(*mangled)++;
3208 if (temptype == 'N')
3210 if (!get_count (mangled, &r))
3219 if (ARM_DEMANGLING && work -> ntypes >= 10)
3221 /* If we have 10 or more types we might have more than a 1 digit
3222 index so we'll have to consume the whole count here. This
3223 will lose if the next thing is a type name preceded by a
3224 count but it's impossible to demangle that case properly
3225 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3226 Pc, ...)" or "(..., type12, char *, ...)" */
3227 if ((t = consume_count(mangled)) == 0)
3234 if (!get_count (mangled, &t))
3239 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3243 /* Validate the type index. Protect against illegal indices from
3244 malformed type strings. */
3245 if ((t < 0) || (t >= work -> ntypes))
3249 while (work->nrepeats > 0 || --r >= 0)
3251 tem = work -> typevec[t];
3252 if (need_comma && PRINT_ARG_TYPES)
3254 string_append (declp, ", ");
3256 if (!do_arg (work, &tem, &arg))
3260 if (PRINT_ARG_TYPES)
3262 string_appends (declp, &arg);
3264 string_delete (&arg);
3270 if (need_comma && PRINT_ARG_TYPES)
3271 string_append (declp, ", ");
3272 if (!do_arg (work, mangled, &arg))
3274 if (PRINT_ARG_TYPES)
3275 string_appends (declp, &arg);
3276 string_delete (&arg);
3281 if (**mangled == 'e')
3284 if (PRINT_ARG_TYPES)
3288 string_append (declp, ",");
3290 string_append (declp, "...");
3294 if (PRINT_ARG_TYPES)
3296 string_append (declp, ")");
3301 /* Like demangle_args, but for demangling the argument lists of function
3302 and method pointers or references, not top-level declarations. */
3305 demangle_nested_args (work, mangled, declp)
3306 struct work_stuff *work;
3307 const char **mangled;
3310 string* saved_previous_argument;
3314 /* The G++ name-mangling algorithm does not remember types on nested
3315 argument lists, unless -fsquangling is used, and in that case the
3316 type vector updated by remember_type is not used. So, we turn
3317 off remembering of types here. */
3318 ++work->forgetting_types;
3320 /* For the repeat codes used with -fsquangling, we must keep track of
3321 the last argument. */
3322 saved_previous_argument = work->previous_argument;
3323 saved_nrepeats = work->nrepeats;
3324 work->previous_argument = 0;
3327 /* Actually demangle the arguments. */
3328 result = demangle_args (work, mangled, declp);
3330 /* Restore the previous_argument field. */
3331 if (work->previous_argument)
3332 string_delete (work->previous_argument);
3333 work->previous_argument = saved_previous_argument;
3334 work->nrepeats = saved_nrepeats;
3340 demangle_function_name (work, mangled, declp, scan)
3341 struct work_stuff *work;
3342 const char **mangled;
3350 string_appendn (declp, (*mangled), scan - (*mangled));
3351 string_need (declp, 1);
3352 *(declp -> p) = '\0';
3354 /* Consume the function name, including the "__" separating the name
3355 from the signature. We are guaranteed that SCAN points to the
3358 (*mangled) = scan + 2;
3360 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3363 /* See if we have an ARM style constructor or destructor operator.
3364 If so, then just record it, clear the decl, and return.
3365 We can't build the actual constructor/destructor decl until later,
3366 when we recover the class name from the signature. */
3368 if (strcmp (declp -> b, "__ct") == 0)
3370 work -> constructor += 1;
3371 string_clear (declp);
3374 else if (strcmp (declp -> b, "__dt") == 0)
3376 work -> destructor += 1;
3377 string_clear (declp);
3382 if (declp->p - declp->b >= 3
3383 && declp->b[0] == 'o'
3384 && declp->b[1] == 'p'
3385 && strchr (cplus_markers, declp->b[2]) != NULL)
3387 /* see if it's an assignment expression */
3388 if (declp->p - declp->b >= 10 /* op$assign_ */
3389 && memcmp (declp->b + 3, "assign_", 7) == 0)
3391 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3393 int len = declp->p - declp->b - 10;
3394 if (strlen (optable[i].in) == len
3395 && memcmp (optable[i].in, declp->b + 10, len) == 0)
3397 string_clear (declp);
3398 string_append (declp, "operator");
3399 string_append (declp, optable[i].out);
3400 string_append (declp, "=");
3407 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3409 int len = declp->p - declp->b - 3;
3410 if (strlen (optable[i].in) == len
3411 && memcmp (optable[i].in, declp->b + 3, len) == 0)
3413 string_clear (declp);
3414 string_append (declp, "operator");
3415 string_append (declp, optable[i].out);
3421 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
3422 && strchr (cplus_markers, declp->b[4]) != NULL)
3424 /* type conversion operator */
3426 if (do_type (work, &tem, &type))
3428 string_clear (declp);
3429 string_append (declp, "operator ");
3430 string_appends (declp, &type);
3431 string_delete (&type);
3434 else if (declp->b[0] == '_' && declp->b[1] == '_'
3435 && declp->b[2] == 'o' && declp->b[3] == 'p')
3438 /* type conversion operator. */
3440 if (do_type (work, &tem, &type))
3442 string_clear (declp);
3443 string_append (declp, "operator ");
3444 string_appends (declp, &type);
3445 string_delete (&type);
3448 else if (declp->b[0] == '_' && declp->b[1] == '_'
3449 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
3450 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
3452 if (declp->b[4] == '\0')
3455 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3457 if (strlen (optable[i].in) == 2
3458 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
3460 string_clear (declp);
3461 string_append (declp, "operator");
3462 string_append (declp, optable[i].out);
3469 if (declp->b[2] == 'a' && declp->b[5] == '\0')
3472 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3474 if (strlen (optable[i].in) == 3
3475 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
3477 string_clear (declp);
3478 string_append (declp, "operator");
3479 string_append (declp, optable[i].out);
3488 /* a mini string-handling package */
3503 s->p = s->b = xmalloc (n);
3506 else if (s->e - s->p < n)
3511 s->b = xrealloc (s->b, n);
3524 s->b = s->e = s->p = NULL;
3532 s->b = s->p = s->e = NULL;
3548 return (s->b == s->p);
3554 string_append (p, s)
3559 if (s == NULL || *s == '\0')
3563 memcpy (p->p, s, n);
3568 string_appends (p, s)
3577 memcpy (p->p, s->b, n);
3583 string_appendn (p, s, n)
3591 memcpy (p->p, s, n);
3597 string_prepend (p, s)
3601 if (s != NULL && *s != '\0')
3603 string_prependn (p, s, strlen (s));
3608 string_prepends (p, s)
3613 string_prependn (p, s->b, s->p - s->b);
3618 string_prependn (p, s, n)
3628 for (q = p->p - 1; q >= p->b; q--)
3632 memcpy (p->b, s, n);
3637 /* To generate a standalone demangler program for testing purposes,
3638 just compile and link this file with -DMAIN and libiberty.a. When
3639 run, it demangles each command line arg, or each stdin string, and
3640 prints the result on stdout. */
3646 static char *program_name;
3647 static char *program_version = VERSION;
3648 static int flags = DMGL_PARAMS | DMGL_ANSI;
3650 static void demangle_it PARAMS ((char *));
3651 static void usage PARAMS ((FILE *, int));
3652 static void fatal PARAMS ((char *));
3655 demangle_it (mangled_name)
3660 result = cplus_demangle (mangled_name, flags);
3663 printf ("%s\n", mangled_name);
3667 printf ("%s\n", result);
3673 usage (stream, status)
3678 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3679 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3680 [--help] [--version] [arg...]\n",
3685 #define MBUF_SIZE 32767
3686 char mbuffer[MBUF_SIZE];
3688 /* Defined in the automatically-generated underscore.c. */
3689 extern int prepends_underscore;
3691 int strip_underscore = 0;
3693 static struct option long_options[] = {
3694 {"strip-underscores", no_argument, 0, '_'},
3695 {"format", required_argument, 0, 's'},
3696 {"help", no_argument, 0, 'h'},
3697 {"no-strip-underscores", no_argument, 0, 'n'},
3698 {"version", no_argument, 0, 'v'},
3699 {0, no_argument, 0, 0}
3702 /* More 'friendly' abort that prints the line and file.
3703 config.h can #define abort fancy_abort if you like that sort of thing. */
3708 fatal ("Internal gcc abort.");
3719 program_name = argv[0];
3721 strip_underscore = prepends_underscore;
3723 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3733 strip_underscore = 0;
3736 printf ("GNU %s version %s\n", program_name, program_version);
3739 strip_underscore = 1;
3742 if (strcmp (optarg, "gnu") == 0)
3744 current_demangling_style = gnu_demangling;
3746 else if (strcmp (optarg, "lucid") == 0)
3748 current_demangling_style = lucid_demangling;
3750 else if (strcmp (optarg, "arm") == 0)
3752 current_demangling_style = arm_demangling;
3756 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3757 program_name, optarg);
3766 for ( ; optind < argc; optind++)
3768 demangle_it (argv[optind]);
3777 /* Try to read a label. */
3778 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3780 if (i >= MBUF_SIZE-1)
3789 if (mbuffer[0] == '.')
3791 if (strip_underscore && mbuffer[skip_first] == '_')
3799 result = cplus_demangle (mbuffer + skip_first, flags);
3802 if (mbuffer[0] == '.')
3804 fputs (result, stdout);
3808 fputs (mbuffer, stdout);
3825 fprintf (stderr, "%s: %s\n", program_name, str);
3836 register char *value = (char *) malloc (size);
3838 fatal ("virtual memory exhausted");
3843 xrealloc (ptr, size)
3847 register char *value = (char *) realloc (ptr, size);
3849 fatal ("virtual memory exhausted");