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. */
36 #include <sys/types.h>
48 #undef CURRENT_DEMANGLING_STYLE
49 #define CURRENT_DEMANGLING_STYLE work->options
51 extern char *xmalloc PARAMS((unsigned));
52 extern char *xrealloc PARAMS((char *, unsigned));
54 static const char *mystrstr PARAMS ((const char *, const char *));
60 register const char *p = s1;
61 register int len = strlen (s2);
63 for (; (p = strchr (p, *s2)) != 0; p++)
65 if (strncmp (p, s2, len) == 0)
73 /* In order to allow a single demangler executable to demangle strings
74 using various common values of CPLUS_MARKER, as well as any specific
75 one set at compile time, we maintain a string containing all the
76 commonly used ones, and check to see if the marker we are looking for
77 is in that string. CPLUS_MARKER is usually '$' on systems where the
78 assembler can deal with that. Where the assembler can't, it's usually
79 '.' (but on many systems '.' is used for other things). We put the
80 current defined CPLUS_MARKER first (which defaults to '$'), followed
81 by the next most common value, followed by an explicit '$' in case
82 the value of CPLUS_MARKER is not '$'.
84 We could avoid this if we could just get g++ to tell us what the actual
85 cplus marker character is as part of the debug information, perhaps by
86 ensuring that it is the character that terminates the gcc<n>_compiled
87 marker symbol (FIXME). */
89 #if !defined (CPLUS_MARKER)
90 #define CPLUS_MARKER '$'
93 enum demangling_styles current_demangling_style = gnu_demangling;
95 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
98 set_cplus_marker_for_demangling (ch)
101 cplus_markers[0] = ch;
104 typedef struct string /* Beware: these aren't required to be */
105 { /* '\0' terminated. */
106 char *b; /* pointer to start of string */
107 char *p; /* pointer after last character */
108 char *e; /* pointer after end of allocated space */
111 /* Stuff that is shared between sub-routines.
112 Using a shared structure allows cplus_demangle to be reentrant. */
128 int static_type; /* A static member function */
129 int type_quals; /* The type qualifiers. */
130 int dllimported; /* Symbol imported from a PE DLL */
131 char **tmpl_argvec; /* Template function arguments. */
132 int ntmpl_args; /* The number of template function arguments. */
133 int forgetting_types; /* Nonzero if we are not remembering the types
135 string* previous_argument; /* The last function argument demangled. */
136 int nrepeats; /* The number of times to repeat the previous
140 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
141 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
143 static const struct optable
149 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
150 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
151 {"new", " new", 0}, /* old (1.91, and 1.x) */
152 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
153 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
154 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
155 {"as", "=", DMGL_ANSI}, /* ansi */
156 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
157 {"eq", "==", DMGL_ANSI}, /* old, ansi */
158 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
159 {"gt", ">", DMGL_ANSI}, /* old, ansi */
160 {"le", "<=", DMGL_ANSI}, /* old, ansi */
161 {"lt", "<", DMGL_ANSI}, /* old, ansi */
162 {"plus", "+", 0}, /* old */
163 {"pl", "+", DMGL_ANSI}, /* ansi */
164 {"apl", "+=", DMGL_ANSI}, /* ansi */
165 {"minus", "-", 0}, /* old */
166 {"mi", "-", DMGL_ANSI}, /* ansi */
167 {"ami", "-=", DMGL_ANSI}, /* ansi */
168 {"mult", "*", 0}, /* old */
169 {"ml", "*", DMGL_ANSI}, /* ansi */
170 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
171 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
172 {"convert", "+", 0}, /* old (unary +) */
173 {"negate", "-", 0}, /* old (unary -) */
174 {"trunc_mod", "%", 0}, /* old */
175 {"md", "%", DMGL_ANSI}, /* ansi */
176 {"amd", "%=", DMGL_ANSI}, /* ansi */
177 {"trunc_div", "/", 0}, /* old */
178 {"dv", "/", DMGL_ANSI}, /* ansi */
179 {"adv", "/=", DMGL_ANSI}, /* ansi */
180 {"truth_andif", "&&", 0}, /* old */
181 {"aa", "&&", DMGL_ANSI}, /* ansi */
182 {"truth_orif", "||", 0}, /* old */
183 {"oo", "||", DMGL_ANSI}, /* ansi */
184 {"truth_not", "!", 0}, /* old */
185 {"nt", "!", DMGL_ANSI}, /* ansi */
186 {"postincrement","++", 0}, /* old */
187 {"pp", "++", DMGL_ANSI}, /* ansi */
188 {"postdecrement","--", 0}, /* old */
189 {"mm", "--", DMGL_ANSI}, /* ansi */
190 {"bit_ior", "|", 0}, /* old */
191 {"or", "|", DMGL_ANSI}, /* ansi */
192 {"aor", "|=", DMGL_ANSI}, /* ansi */
193 {"bit_xor", "^", 0}, /* old */
194 {"er", "^", DMGL_ANSI}, /* ansi */
195 {"aer", "^=", DMGL_ANSI}, /* ansi */
196 {"bit_and", "&", 0}, /* old */
197 {"ad", "&", DMGL_ANSI}, /* ansi */
198 {"aad", "&=", DMGL_ANSI}, /* ansi */
199 {"bit_not", "~", 0}, /* old */
200 {"co", "~", DMGL_ANSI}, /* ansi */
201 {"call", "()", 0}, /* old */
202 {"cl", "()", DMGL_ANSI}, /* ansi */
203 {"alshift", "<<", 0}, /* old */
204 {"ls", "<<", DMGL_ANSI}, /* ansi */
205 {"als", "<<=", DMGL_ANSI}, /* ansi */
206 {"arshift", ">>", 0}, /* old */
207 {"rs", ">>", DMGL_ANSI}, /* ansi */
208 {"ars", ">>=", DMGL_ANSI}, /* ansi */
209 {"component", "->", 0}, /* old */
210 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
211 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
212 {"indirect", "*", 0}, /* old */
213 {"method_call", "->()", 0}, /* old */
214 {"addr", "&", 0}, /* old (unary &) */
215 {"array", "[]", 0}, /* old */
216 {"vc", "[]", DMGL_ANSI}, /* ansi */
217 {"compound", ", ", 0}, /* old */
218 {"cm", ", ", DMGL_ANSI}, /* ansi */
219 {"cond", "?:", 0}, /* old */
220 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
221 {"max", ">?", 0}, /* old */
222 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
223 {"min", "<?", 0}, /* old */
224 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
225 {"nop", "", 0}, /* old (for operator=) */
226 {"rm", "->*", DMGL_ANSI}, /* ansi */
227 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
230 /* These values are used to indicate the various type varieties.
231 They are all non-zero so that they can be used as `success'
233 typedef enum type_kind_t
244 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
245 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
246 string_prepend(str, " ");}
247 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
248 string_append(str, " ");}
249 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
251 /* The scope separator appropriate for the language being demangled. */
252 #define SCOPE_STRING(work) "::"
254 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
255 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
257 /* Prototypes for local functions */
260 mop_up PARAMS ((struct work_stuff *, string *, int));
263 squangle_mop_up PARAMS ((struct work_stuff *));
267 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
271 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
274 demangle_template_template_parm PARAMS ((struct work_stuff *work,
275 const char **, string *));
278 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
279 string *, int, int));
282 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
286 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
289 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
292 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
296 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
299 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
302 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
305 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
308 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
311 arm_special PARAMS ((const char **, string *));
314 string_need PARAMS ((string *, int));
317 string_delete PARAMS ((string *));
320 string_init PARAMS ((string *));
323 string_clear PARAMS ((string *));
327 string_empty PARAMS ((string *));
331 string_append PARAMS ((string *, const char *));
334 string_appends PARAMS ((string *, string *));
337 string_appendn PARAMS ((string *, const char *, int));
340 string_prepend PARAMS ((string *, const char *));
343 string_prependn PARAMS ((string *, const char *, int));
346 get_count PARAMS ((const char **, int *));
349 consume_count PARAMS ((const char **));
352 consume_count_with_underscores PARAMS ((const char**));
355 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
358 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
361 do_type PARAMS ((struct work_stuff *, const char **, string *));
364 do_arg PARAMS ((struct work_stuff *, const char **, string *));
367 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
371 remember_type PARAMS ((struct work_stuff *, const char *, int));
374 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
377 register_Btype PARAMS ((struct work_stuff *));
380 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
383 forget_types PARAMS ((struct work_stuff *));
386 forget_B_and_K_types PARAMS ((struct work_stuff *));
389 string_prepends PARAMS ((string *, string *));
392 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
393 string*, type_kind_t));
395 /* There is a TYPE_QUAL value for each type qualifier. They can be
396 combined by bitwise-or to form the complete set of qualifiers for a
399 #define TYPE_UNQUALIFIED 0x0
400 #define TYPE_QUAL_CONST 0x1
401 #define TYPE_QUAL_VOLATILE 0x2
402 #define TYPE_QUAL_RESTRICT 0x4
405 code_for_qualifier PARAMS ((char));
408 qualifier_string PARAMS ((int));
411 demangle_qualifier PARAMS ((char));
413 /* Translate count to integer, consuming tokens in the process.
414 Conversion terminates on the first non-digit character.
415 Trying to consume something that isn't a count results in
416 no consumption of input and a return of 0. */
424 while (isdigit ((unsigned char)**type))
427 count += **type - '0';
434 /* Like consume_count, but for counts that are preceded and followed
435 by '_' if they are greater than 10. Also, -1 is returned for
436 failure, since 0 can be a valid value. */
439 consume_count_with_underscores (mangled)
440 const char **mangled;
444 if (**mangled == '_')
447 if (!isdigit ((unsigned char)**mangled))
450 idx = consume_count (mangled);
451 if (**mangled != '_')
452 /* The trailing underscore was missing. */
459 if (**mangled < '0' || **mangled > '9')
462 idx = **mangled - '0';
469 /* C is the code for a type-qualifier. Return the TYPE_QUAL
470 corresponding to this qualifier. */
473 code_for_qualifier (c)
479 return TYPE_QUAL_CONST;
482 return TYPE_QUAL_VOLATILE;
485 return TYPE_QUAL_RESTRICT;
491 /* C was an invalid qualifier. */
495 /* Return the string corresponding to the qualifiers given by
499 qualifier_string (type_quals)
504 case TYPE_UNQUALIFIED:
507 case TYPE_QUAL_CONST:
510 case TYPE_QUAL_VOLATILE:
513 case TYPE_QUAL_RESTRICT:
516 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
517 return "const volatile";
519 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
520 return "const __restrict";
522 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
523 return "volatile __restrict";
525 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
526 return "const volatile __restrict";
532 /* TYPE_QUALS was an invalid qualifier set. */
536 /* C is the code for a type-qualifier. Return the string
537 corresponding to this qualifier. This function should only be
538 called with a valid qualifier code. */
541 demangle_qualifier (c)
544 return qualifier_string (code_for_qualifier (c));
548 cplus_demangle_opname (opname, result, options)
555 struct work_stuff work[1];
558 len = strlen(opname);
561 memset ((char *) work, 0, sizeof (work));
562 work->options = options;
564 if (opname[0] == '_' && opname[1] == '_'
565 && opname[2] == 'o' && opname[3] == 'p')
568 /* type conversion operator. */
570 if (do_type (work, &tem, &type))
572 strcat (result, "operator ");
573 strncat (result, type.b, type.p - type.b);
574 string_delete (&type);
578 else if (opname[0] == '_' && opname[1] == '_'
579 && opname[2] >= 'a' && opname[2] <= 'z'
580 && opname[3] >= 'a' && opname[3] <= 'z')
582 if (opname[4] == '\0')
586 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
588 if (strlen (optable[i].in) == 2
589 && memcmp (optable[i].in, opname + 2, 2) == 0)
591 strcat (result, "operator");
592 strcat (result, optable[i].out);
600 if (opname[2] == 'a' && opname[5] == '\0')
604 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
606 if (strlen (optable[i].in) == 3
607 && memcmp (optable[i].in, opname + 2, 3) == 0)
609 strcat (result, "operator");
610 strcat (result, optable[i].out);
621 && strchr (cplus_markers, opname[2]) != NULL)
623 /* see if it's an assignment expression */
624 if (len >= 10 /* op$assign_ */
625 && memcmp (opname + 3, "assign_", 7) == 0)
628 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
631 if ((int) strlen (optable[i].in) == len1
632 && memcmp (optable[i].in, opname + 10, len1) == 0)
634 strcat (result, "operator");
635 strcat (result, optable[i].out);
636 strcat (result, "=");
645 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
648 if ((int) strlen (optable[i].in) == len1
649 && memcmp (optable[i].in, opname + 3, len1) == 0)
651 strcat (result, "operator");
652 strcat (result, optable[i].out);
659 else if (len >= 5 && memcmp (opname, "type", 4) == 0
660 && strchr (cplus_markers, opname[4]) != NULL)
662 /* type conversion operator */
664 if (do_type (work, &tem, &type))
666 strcat (result, "operator ");
667 strncat (result, type.b, type.p - type.b);
668 string_delete (&type);
672 squangle_mop_up (work);
676 /* Takes operator name as e.g. "++" and returns mangled
677 operator name (e.g. "postincrement_expr"), or NULL if not found.
679 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
680 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
683 cplus_mangle_opname (opname, options)
690 len = strlen (opname);
691 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
693 if ((int) strlen (optable[i].out) == len
694 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
695 && memcmp (optable[i].out, opname, len) == 0)
696 return optable[i].in;
701 /* char *cplus_demangle (const char *mangled, int options)
703 If MANGLED is a mangled function name produced by GNU C++, then
704 a pointer to a malloced string giving a C++ representation
705 of the name will be returned; otherwise NULL will be returned.
706 It is the caller's responsibility to free the string which
709 The OPTIONS arg may contain one or more of the following bits:
711 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
713 DMGL_PARAMS Function parameters are included.
717 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
718 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
719 cplus_demangle ("foo__1Ai", 0) => "A::foo"
721 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
722 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
723 cplus_demangle ("foo__1Afe", 0) => "A::foo"
725 Note that any leading underscores, or other such characters prepended by
726 the compilation system, are presumed to have already been stripped from
730 cplus_demangle (mangled, options)
735 struct work_stuff work[1];
736 memset ((char *) work, 0, sizeof (work));
737 work -> options = options;
738 if ((work -> options & DMGL_STYLE_MASK) == 0)
739 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
741 ret = internal_cplus_demangle (work, mangled);
742 squangle_mop_up (work);
747 /* This function performs most of what cplus_demangle use to do, but
748 to be able to demangle a name with a B, K or n code, we need to
749 have a longer term memory of what types have been seen. The original
750 now intializes and cleans up the squangle code info, while internal
751 calls go directly to this routine to avoid resetting that info. */
754 internal_cplus_demangle (work, mangled)
755 struct work_stuff *work;
761 char *demangled = NULL;
763 s1 = work->constructor;
764 s2 = work->destructor;
765 s3 = work->static_type;
766 s4 = work->type_quals;
767 work->constructor = work->destructor = 0;
768 work->type_quals = TYPE_UNQUALIFIED;
769 work->dllimported = 0;
771 if ((mangled != NULL) && (*mangled != '\0'))
775 /* First check to see if gnu style demangling is active and if the
776 string to be demangled contains a CPLUS_MARKER. If so, attempt to
777 recognize one of the gnu special forms rather than looking for a
778 standard prefix. In particular, don't worry about whether there
779 is a "__" string in the mangled string. Consider "_$_5__foo" for
782 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
784 success = gnu_special (work, &mangled, &decl);
788 success = demangle_prefix (work, &mangled, &decl);
790 if (success && (*mangled != '\0'))
792 success = demangle_signature (work, &mangled, &decl);
794 if (work->constructor == 2)
796 string_prepend (&decl, "global constructors keyed to ");
797 work->constructor = 0;
799 else if (work->destructor == 2)
801 string_prepend (&decl, "global destructors keyed to ");
802 work->destructor = 0;
804 else if (work->dllimported == 1)
806 string_prepend (&decl, "import stub for ");
807 work->dllimported = 0;
809 demangled = mop_up (work, &decl, success);
811 work->constructor = s1;
812 work->destructor = s2;
813 work->static_type = s3;
814 work->type_quals = s4;
819 /* Clear out and squangling related storage */
821 squangle_mop_up (work)
822 struct work_stuff *work;
824 /* clean up the B and K type mangling types. */
825 forget_B_and_K_types (work);
826 if (work -> btypevec != NULL)
828 free ((char *) work -> btypevec);
830 if (work -> ktypevec != NULL)
832 free ((char *) work -> ktypevec);
836 /* Clear out any mangled storage */
839 mop_up (work, declp, success)
840 struct work_stuff *work;
844 char *demangled = NULL;
846 /* Discard the remembered types, if any. */
849 if (work -> typevec != NULL)
851 free ((char *) work -> typevec);
852 work -> typevec = NULL;
854 if (work->tmpl_argvec)
858 for (i = 0; i < work->ntmpl_args; i++)
859 if (work->tmpl_argvec[i])
860 free ((char*) work->tmpl_argvec[i]);
862 free ((char*) work->tmpl_argvec);
863 work->tmpl_argvec = NULL;
865 if (work->previous_argument)
867 string_delete (work->previous_argument);
868 free ((char*) work->previous_argument);
871 /* If demangling was successful, ensure that the demangled string is null
872 terminated and return it. Otherwise, free the demangling decl. */
876 string_delete (declp);
880 string_appendn (declp, "", 1);
881 demangled = declp -> b;
890 demangle_signature -- demangle the signature part of a mangled name
895 demangle_signature (struct work_stuff *work, const char **mangled,
900 Consume and demangle the signature portion of the mangled name.
902 DECLP is the string where demangled output is being built. At
903 entry it contains the demangled root name from the mangled name
904 prefix. I.E. either a demangled operator name or the root function
905 name. In some special cases, it may contain nothing.
907 *MANGLED points to the current unconsumed location in the mangled
908 name. As tokens are consumed and demangling is performed, the
909 pointer is updated to continuously point at the next token to
912 Demangling GNU style mangled names is nasty because there is no
913 explicit token that marks the start of the outermost function
917 demangle_signature (work, mangled, declp)
918 struct work_stuff *work;
919 const char **mangled;
925 int expect_return_type = 0;
926 const char *oldmangled = NULL;
930 while (success && (**mangled != '\0'))
935 oldmangled = *mangled;
936 success = demangle_qualified (work, mangled, declp, 1, 0);
938 remember_type (work, oldmangled, *mangled - oldmangled);
939 if (AUTO_DEMANGLING || GNU_DEMANGLING)
945 oldmangled = *mangled;
946 success = demangle_qualified (work, mangled, declp, 1, 0);
947 if (AUTO_DEMANGLING || GNU_DEMANGLING)
955 /* Static member function */
956 if (oldmangled == NULL)
958 oldmangled = *mangled;
961 work -> static_type = 1;
967 work->type_quals |= code_for_qualifier (**mangled);
969 /* a qualified member function */
970 if (oldmangled == NULL)
971 oldmangled = *mangled;
975 case '0': case '1': case '2': case '3': case '4':
976 case '5': case '6': case '7': case '8': case '9':
977 if (oldmangled == NULL)
979 oldmangled = *mangled;
981 success = demangle_class (work, mangled, declp);
984 remember_type (work, oldmangled, *mangled - oldmangled);
986 if (AUTO_DEMANGLING || GNU_DEMANGLING)
996 success = do_type (work, mangled, &s);
999 string_append (&s, SCOPE_STRING (work));
1000 string_prepends (declp, &s);
1009 /* ARM style demangling includes a specific 'F' character after
1010 the class name. For GNU style, it is just implied. So we can
1011 safely just consume any 'F' at this point and be compatible
1012 with either style. */
1018 /* For lucid/ARM style we have to forget any types we might
1019 have remembered up to this point, since they were not argument
1020 types. GNU style considers all types seen as available for
1021 back references. See comment in demangle_args() */
1023 if (LUCID_DEMANGLING || ARM_DEMANGLING)
1025 forget_types (work);
1027 success = demangle_args (work, mangled, declp);
1032 string_init(&trawname);
1033 string_init(&tname);
1034 if (oldmangled == NULL)
1036 oldmangled = *mangled;
1038 success = demangle_template (work, mangled, &tname,
1042 remember_type (work, oldmangled, *mangled - oldmangled);
1044 string_append (&tname, SCOPE_STRING (work));
1046 string_prepends(declp, &tname);
1047 if (work -> destructor & 1)
1049 string_prepend (&trawname, "~");
1050 string_appends (declp, &trawname);
1051 work->destructor -= 1;
1053 if ((work->constructor & 1) || (work->destructor & 1))
1055 string_appends (declp, &trawname);
1056 work->constructor -= 1;
1058 string_delete(&trawname);
1059 string_delete(&tname);
1065 if (GNU_DEMANGLING && expect_return_type)
1067 /* Read the return type. */
1069 string_init (&return_type);
1072 success = do_type (work, mangled, &return_type);
1073 APPEND_BLANK (&return_type);
1075 string_prepends (declp, &return_type);
1076 string_delete (&return_type);
1080 /* At the outermost level, we cannot have a return type specified,
1081 so if we run into another '_' at this point we are dealing with
1082 a mangled name that is either bogus, or has been mangled by
1083 some algorithm we don't know how to deal with. So just
1084 reject the entire demangling. */
1091 /* A G++ template function. Read the template arguments. */
1092 success = demangle_template (work, mangled, declp, 0, 0,
1094 if (!(work->constructor & 1))
1095 expect_return_type = 1;
1104 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1106 /* Assume we have stumbled onto the first outermost function
1107 argument token, and start processing args. */
1109 success = demangle_args (work, mangled, declp);
1113 /* Non-GNU demanglers use a specific token to mark the start
1114 of the outermost function argument tokens. Typically 'F',
1115 for ARM-demangling, for example. So if we find something
1116 we are not prepared for, it must be an error. */
1122 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1125 if (success && expect_func)
1128 success = demangle_args (work, mangled, declp);
1129 /* Since template include the mangling of their return types,
1130 we must set expect_func to 0 so that we don't try do
1131 demangle more arguments the next time we get here. */
1136 if (success && !func_done)
1138 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1140 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1141 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1142 first case, and need to ensure that the '(void)' gets added to
1143 the current declp. Note that with ARM, the first case
1144 represents the name of a static data member 'foo::bar',
1145 which is in the current declp, so we leave it alone. */
1146 success = demangle_args (work, mangled, declp);
1149 if (success && PRINT_ARG_TYPES)
1151 if (work->static_type)
1152 string_append (declp, " static");
1153 if (work->type_quals != TYPE_UNQUALIFIED)
1155 APPEND_BLANK (declp);
1156 string_append (declp, qualifier_string (work->type_quals));
1166 demangle_method_args (work, mangled, declp)
1167 struct work_stuff *work;
1168 const char **mangled;
1173 if (work -> static_type)
1175 string_append (declp, *mangled + 1);
1176 *mangled += strlen (*mangled);
1181 success = demangle_args (work, mangled, declp);
1189 demangle_template_template_parm (work, mangled, tname)
1190 struct work_stuff *work;
1191 const char **mangled;
1200 string_append (tname, "template <");
1201 /* get size of template parameter list */
1202 if (get_count (mangled, &r))
1204 for (i = 0; i < r; i++)
1208 string_append (tname, ", ");
1211 /* Z for type parameters */
1212 if (**mangled == 'Z')
1215 string_append (tname, "class");
1217 /* z for template parameters */
1218 else if (**mangled == 'z')
1222 demangle_template_template_parm (work, mangled, tname);
1230 /* temp is initialized in do_type */
1231 success = do_type (work, mangled, &temp);
1234 string_appends (tname, &temp);
1236 string_delete(&temp);
1246 if (tname->p[-1] == '>')
1247 string_append (tname, " ");
1248 string_append (tname, "> class");
1253 demangle_integral_value (work, mangled, s)
1254 struct work_stuff *work;
1255 const char** mangled;
1260 if (**mangled == 'E')
1262 int need_operator = 0;
1265 string_appendn (s, "(", 1);
1267 while (success && **mangled != 'W' && **mangled != '\0')
1276 len = strlen (*mangled);
1279 i < sizeof (optable) / sizeof (optable [0]);
1282 size_t l = strlen (optable[i].in);
1285 && memcmp (optable[i].in, *mangled, l) == 0)
1287 string_appendn (s, " ", 1);
1288 string_append (s, optable[i].out);
1289 string_appendn (s, " ", 1);
1302 success = demangle_template_value_parm (work, mangled, s,
1306 if (**mangled != 'W')
1310 string_appendn (s, ")", 1);
1314 else if (**mangled == 'Q' || **mangled == 'K')
1315 success = demangle_qualified (work, mangled, s, 0, 1);
1320 if (**mangled == 'm')
1322 string_appendn (s, "-", 1);
1325 while (isdigit ((unsigned char)**mangled))
1327 string_appendn (s, *mangled, 1);
1337 demangle_template_value_parm (work, mangled, s, tk)
1338 struct work_stuff *work;
1339 const char **mangled;
1345 if (**mangled == 'Y')
1347 /* The next argument is a template parameter. */
1351 idx = consume_count_with_underscores (mangled);
1353 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1354 || consume_count_with_underscores (mangled) == -1)
1356 if (work->tmpl_argvec)
1357 string_append (s, work->tmpl_argvec[idx]);
1361 sprintf(buf, "T%d", idx);
1362 string_append (s, buf);
1365 else if (tk == tk_integral)
1366 success = demangle_integral_value (work, mangled, s);
1367 else if (tk == tk_char)
1371 if (**mangled == 'm')
1373 string_appendn (s, "-", 1);
1376 string_appendn (s, "'", 1);
1377 val = consume_count(mangled);
1382 string_appendn (s, &tmp[0], 1);
1383 string_appendn (s, "'", 1);
1385 else if (tk == tk_bool)
1387 int val = consume_count (mangled);
1389 string_appendn (s, "false", 5);
1391 string_appendn (s, "true", 4);
1395 else if (tk == tk_real)
1397 if (**mangled == 'm')
1399 string_appendn (s, "-", 1);
1402 while (isdigit ((unsigned char)**mangled))
1404 string_appendn (s, *mangled, 1);
1407 if (**mangled == '.') /* fraction */
1409 string_appendn (s, ".", 1);
1411 while (isdigit ((unsigned char)**mangled))
1413 string_appendn (s, *mangled, 1);
1417 if (**mangled == 'e') /* exponent */
1419 string_appendn (s, "e", 1);
1421 while (isdigit ((unsigned char)**mangled))
1423 string_appendn (s, *mangled, 1);
1428 else if (tk == tk_pointer || tk == tk_reference)
1430 int symbol_len = consume_count (mangled);
1431 if (symbol_len == 0)
1433 if (symbol_len == 0)
1434 string_appendn (s, "0", 1);
1437 char *p = xmalloc (symbol_len + 1), *q;
1438 strncpy (p, *mangled, symbol_len);
1439 p [symbol_len] = '\0';
1440 /* We use cplus_demangle here, rather than
1441 internal_cplus_demangle, because the name of the entity
1442 mangled here does not make use of any of the squangling
1443 or type-code information we have built up thus far; it is
1444 mangled independently. */
1445 q = cplus_demangle (p, work->options);
1446 if (tk == tk_pointer)
1447 string_appendn (s, "&", 1);
1448 /* FIXME: Pointer-to-member constants should get a
1449 qualifying class name here. */
1452 string_append (s, q);
1456 string_append (s, p);
1459 *mangled += symbol_len;
1465 /* Demangle the template name in MANGLED. The full name of the
1466 template (e.g., S<int>) is placed in TNAME. The name without the
1467 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1468 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1469 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1470 the tmeplate is remembered in the list of back-referenceable
1474 demangle_template (work, mangled, tname, trawname, is_type, remember)
1475 struct work_stuff *work;
1476 const char **mangled;
1494 bindex = register_Btype (work);
1496 /* get template name */
1497 if (**mangled == 'z')
1503 idx = consume_count_with_underscores (mangled);
1505 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1506 || consume_count_with_underscores (mangled) == -1)
1509 if (work->tmpl_argvec)
1511 string_append (tname, work->tmpl_argvec[idx]);
1513 string_append (trawname, work->tmpl_argvec[idx]);
1518 sprintf(buf, "T%d", idx);
1519 string_append (tname, buf);
1521 string_append (trawname, buf);
1526 if ((r = consume_count (mangled)) == 0
1527 || (int) strlen (*mangled) < r)
1531 string_appendn (tname, *mangled, r);
1533 string_appendn (trawname, *mangled, r);
1537 string_append (tname, "<");
1538 /* get size of template parameter list */
1539 if (!get_count (mangled, &r))
1545 /* Create an array for saving the template argument values. */
1546 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1547 work->ntmpl_args = r;
1548 for (i = 0; i < r; i++)
1549 work->tmpl_argvec[i] = 0;
1551 for (i = 0; i < r; i++)
1555 string_append (tname, ", ");
1557 /* Z for type parameters */
1558 if (**mangled == 'Z')
1561 /* temp is initialized in do_type */
1562 success = do_type (work, mangled, &temp);
1565 string_appends (tname, &temp);
1569 /* Save the template argument. */
1570 int len = temp.p - temp.b;
1571 work->tmpl_argvec[i] = xmalloc (len + 1);
1572 memcpy (work->tmpl_argvec[i], temp.b, len);
1573 work->tmpl_argvec[i][len] = '\0';
1576 string_delete(&temp);
1582 /* z for template parameters */
1583 else if (**mangled == 'z')
1587 success = demangle_template_template_parm (work, mangled, tname);
1590 && (r2 = consume_count (mangled)) > 0
1591 && (int) strlen (*mangled) >= r2)
1593 string_append (tname, " ");
1594 string_appendn (tname, *mangled, r2);
1597 /* Save the template argument. */
1599 work->tmpl_argvec[i] = xmalloc (len + 1);
1600 memcpy (work->tmpl_argvec[i], *mangled, len);
1601 work->tmpl_argvec[i][len] = '\0';
1615 /* otherwise, value parameter */
1617 /* temp is initialized in do_type */
1618 success = do_type (work, mangled, &temp);
1619 string_delete(&temp);
1631 success = demangle_template_value_parm (work, mangled, s,
1632 (type_kind_t) success);
1644 int len = s->p - s->b;
1645 work->tmpl_argvec[i] = xmalloc (len + 1);
1646 memcpy (work->tmpl_argvec[i], s->b, len);
1647 work->tmpl_argvec[i][len] = '\0';
1649 string_appends (tname, s);
1656 if (tname->p[-1] == '>')
1657 string_append (tname, " ");
1658 string_append (tname, ">");
1661 if (is_type && remember)
1662 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1665 if (work -> static_type)
1667 string_append (declp, *mangled + 1);
1668 *mangled += strlen (*mangled);
1673 success = demangle_args (work, mangled, declp);
1681 arm_pt (work, mangled, n, anchor, args)
1682 struct work_stuff *work;
1683 const char *mangled;
1685 const char **anchor, **args;
1688 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__")))
1691 *args = *anchor + 6;
1692 len = consume_count (args);
1693 if (*args + len == mangled + n && **args == '_')
1703 demangle_arm_pt (work, mangled, n, declp)
1704 struct work_stuff *work;
1705 const char **mangled;
1711 const char *e = *mangled + n;
1714 if (arm_pt (work, *mangled, n, &p, &args))
1718 string_appendn (declp, *mangled, p - *mangled);
1719 string_append (declp, "<");
1720 /* should do error checking here */
1722 string_clear (&arg);
1723 do_type (work, &args, &arg);
1724 string_appends (declp, &arg);
1725 string_append (declp, ",");
1727 string_delete (&arg);
1729 string_append (declp, ">");
1731 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1732 && (*mangled)[9] == 'N'
1733 && (*mangled)[8] == (*mangled)[10]
1734 && strchr (cplus_markers, (*mangled)[8]))
1736 /* A member of the anonymous namespace. */
1737 string_append (declp, "{anonymous}");
1741 string_appendn (declp, *mangled, n);
1747 demangle_class_name (work, mangled, declp)
1748 struct work_stuff *work;
1749 const char **mangled;
1755 n = consume_count (mangled);
1756 if ((int) strlen (*mangled) >= n)
1758 demangle_arm_pt (work, mangled, n, declp);
1769 demangle_class -- demangle a mangled class sequence
1774 demangle_class (struct work_stuff *work, const char **mangled,
1779 DECLP points to the buffer into which demangling is being done.
1781 *MANGLED points to the current token to be demangled. On input,
1782 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1783 On exit, it points to the next token after the mangled class on
1784 success, or the first unconsumed token on failure.
1786 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1787 we are demangling a constructor or destructor. In this case
1788 we prepend "class::class" or "class::~class" to DECLP.
1790 Otherwise, we prepend "class::" to the current DECLP.
1792 Reset the constructor/destructor flags once they have been
1793 "consumed". This allows demangle_class to be called later during
1794 the same demangling, to do normal class demangling.
1796 Returns 1 if demangling is successful, 0 otherwise.
1801 demangle_class (work, mangled, declp)
1802 struct work_stuff *work;
1803 const char **mangled;
1810 string_init (&class_name);
1811 btype = register_Btype (work);
1812 if (demangle_class_name (work, mangled, &class_name))
1814 if ((work->constructor & 1) || (work->destructor & 1))
1816 string_prepends (declp, &class_name);
1817 if (work -> destructor & 1)
1819 string_prepend (declp, "~");
1820 work -> destructor -= 1;
1824 work -> constructor -= 1;
1827 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
1828 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
1829 string_prepend (declp, SCOPE_STRING (work));
1830 string_prepends (declp, &class_name);
1833 string_delete (&class_name);
1841 demangle_prefix -- consume the mangled name prefix and find signature
1846 demangle_prefix (struct work_stuff *work, const char **mangled,
1851 Consume and demangle the prefix of the mangled name.
1853 DECLP points to the string buffer into which demangled output is
1854 placed. On entry, the buffer is empty. On exit it contains
1855 the root function name, the demangled operator name, or in some
1856 special cases either nothing or the completely demangled result.
1858 MANGLED points to the current pointer into the mangled name. As each
1859 token of the mangled name is consumed, it is updated. Upon entry
1860 the current mangled name pointer points to the first character of
1861 the mangled name. Upon exit, it should point to the first character
1862 of the signature if demangling was successful, or to the first
1863 unconsumed character if demangling of the prefix was unsuccessful.
1865 Returns 1 on success, 0 otherwise.
1869 demangle_prefix (work, mangled, declp)
1870 struct work_stuff *work;
1871 const char **mangled;
1878 if (strlen(*mangled) > 6
1879 && (strncmp(*mangled, "_imp__", 6) == 0
1880 || strncmp(*mangled, "__imp_", 6) == 0))
1882 /* it's a symbol imported from a PE dynamic library. Check for both
1883 new style prefix _imp__ and legacy __imp_ used by older versions
1886 work->dllimported = 1;
1888 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
1890 char *marker = strchr (cplus_markers, (*mangled)[8]);
1891 if (marker != NULL && *marker == (*mangled)[10])
1893 if ((*mangled)[9] == 'D')
1895 /* it's a GNU global destructor to be executed at program exit */
1897 work->destructor = 2;
1898 if (gnu_special (work, mangled, declp))
1901 else if ((*mangled)[9] == 'I')
1903 /* it's a GNU global constructor to be executed at program init */
1905 work->constructor = 2;
1906 if (gnu_special (work, mangled, declp))
1911 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0)
1913 /* it's a ARM global destructor to be executed at program exit */
1915 work->destructor = 2;
1917 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0)
1919 /* it's a ARM global constructor to be executed at program initial */
1921 work->constructor = 2;
1924 /* This block of code is a reduction in strength time optimization
1926 scan = mystrstr (*mangled, "__"); */
1932 scan = strchr (scan, '_');
1933 } while (scan != NULL && *++scan != '_');
1935 if (scan != NULL) --scan;
1940 /* We found a sequence of two or more '_', ensure that we start at
1941 the last pair in the sequence. */
1942 i = strspn (scan, "_");
1953 else if (work -> static_type)
1955 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
1960 else if ((scan == *mangled)
1961 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
1962 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
1964 /* The ARM says nothing about the mangling of local variables.
1965 But cfront mangles local variables by prepending __<nesting_level>
1966 to them. As an extension to ARM demangling we handle this case. */
1967 if ((LUCID_DEMANGLING || ARM_DEMANGLING)
1968 && isdigit ((unsigned char)scan[2]))
1970 *mangled = scan + 2;
1971 consume_count (mangled);
1972 string_append (declp, *mangled);
1973 *mangled += strlen (*mangled);
1978 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
1979 names like __Q2_3foo3bar for nested type names. So don't accept
1980 this style of constructor for cfront demangling. A GNU
1981 style member-template constructor starts with 'H'. */
1982 if (!(LUCID_DEMANGLING || ARM_DEMANGLING))
1983 work -> constructor += 1;
1984 *mangled = scan + 2;
1987 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
1988 && (scan[2] != 't'))
1990 /* Mangled name starts with "__". Skip over any leading '_' characters,
1991 then find the next "__" that separates the prefix from the signature.
1993 if (!(ARM_DEMANGLING || LUCID_DEMANGLING)
1994 || (arm_special (mangled, declp) == 0))
1996 while (*scan == '_')
2000 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2002 /* No separator (I.E. "__not_mangled"), or empty signature
2003 (I.E. "__not_mangled_either__") */
2008 demangle_function_name (work, mangled, declp, scan);
2012 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2014 /* Cfront-style parameterized type. Handled later as a signature. */
2018 demangle_arm_pt (work, mangled, strlen (*mangled), declp);
2020 else if (*(scan + 2) != '\0')
2022 /* Mangled name does not start with "__" but does have one somewhere
2023 in there with non empty stuff after it. Looks like a global
2025 demangle_function_name (work, mangled, declp, scan);
2029 /* Doesn't look like a mangled name */
2033 if (!success && (work->constructor == 2 || work->destructor == 2))
2035 string_append (declp, *mangled);
2036 *mangled += strlen (*mangled);
2046 gnu_special -- special handling of gnu mangled strings
2051 gnu_special (struct work_stuff *work, const char **mangled,
2057 Process some special GNU style mangling forms that don't fit
2058 the normal pattern. For example:
2060 _$_3foo (destructor for class foo)
2061 _vt$foo (foo virtual table)
2062 _vt$foo$bar (foo::bar virtual table)
2063 __vt_foo (foo virtual table, new style with thunks)
2064 _3foo$varname (static data member)
2065 _Q22rs2tu$vw (static data member)
2066 __t6vector1Zii (constructor with template)
2067 __thunk_4__$_7ostream (virtual function thunk)
2071 gnu_special (work, mangled, declp)
2072 struct work_stuff *work;
2073 const char **mangled;
2080 if ((*mangled)[0] == '_'
2081 && strchr (cplus_markers, (*mangled)[1]) != NULL
2082 && (*mangled)[2] == '_')
2084 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2086 work -> destructor += 1;
2088 else if ((*mangled)[0] == '_'
2089 && (((*mangled)[1] == '_'
2090 && (*mangled)[2] == 'v'
2091 && (*mangled)[3] == 't'
2092 && (*mangled)[4] == '_')
2093 || ((*mangled)[1] == 'v'
2094 && (*mangled)[2] == 't'
2095 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2097 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2098 and create the decl. Note that we consume the entire mangled
2099 input string, which means that demangle_signature has no work
2101 if ((*mangled)[2] == 'v')
2102 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2104 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2105 while (**mangled != '\0')
2111 success = demangle_qualified (work, mangled, declp, 0, 1);
2114 success = demangle_template (work, mangled, declp, 0, 1,
2118 if (isdigit((unsigned char)*mangled[0]))
2120 n = consume_count(mangled);
2121 /* We may be seeing a too-large size, or else a
2122 ".<digits>" indicating a static local symbol. In
2123 any case, declare victory and move on; *don't* try
2124 to use n to allocate. */
2125 if (n > (int) strlen (*mangled))
2133 n = strcspn (*mangled, cplus_markers);
2135 string_appendn (declp, *mangled, n);
2139 p = strpbrk (*mangled, cplus_markers);
2140 if (success && ((p == NULL) || (p == *mangled)))
2144 string_append (declp, SCOPE_STRING (work));
2155 string_append (declp, " virtual table");
2157 else if ((*mangled)[0] == '_'
2158 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2159 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2161 /* static data member, "_3foo$varname" for example */
2167 success = demangle_qualified (work, mangled, declp, 0, 1);
2170 success = demangle_template (work, mangled, declp, 0, 1, 1);
2173 n = consume_count (mangled);
2174 string_appendn (declp, *mangled, n);
2177 if (success && (p == *mangled))
2179 /* Consumed everything up to the cplus_marker, append the
2182 string_append (declp, SCOPE_STRING (work));
2183 n = strlen (*mangled);
2184 string_appendn (declp, *mangled, n);
2192 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2194 int delta = ((*mangled) += 8, consume_count (mangled));
2195 char *method = internal_cplus_demangle (work, ++*mangled);
2199 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2200 string_append (declp, buf);
2201 string_append (declp, method);
2203 n = strlen (*mangled);
2211 else if (strncmp (*mangled, "__t", 3) == 0
2212 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2214 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2220 success = demangle_qualified (work, mangled, declp, 0, 1);
2223 success = demangle_template (work, mangled, declp, 0, 1, 1);
2226 success = demangle_fund_type (work, mangled, declp);
2229 if (success && **mangled != '\0')
2232 string_append (declp, p);
2245 arm_special -- special handling of ARM/lucid mangled strings
2250 arm_special (const char **mangled,
2256 Process some special ARM style mangling forms that don't fit
2257 the normal pattern. For example:
2259 __vtbl__3foo (foo virtual table)
2260 __vtbl__3foo__3bar (bar::foo virtual table)
2265 arm_special (mangled, declp)
2266 const char **mangled;
2273 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2275 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2276 and create the decl. Note that we consume the entire mangled
2277 input string, which means that demangle_signature has no work
2279 scan = *mangled + ARM_VTABLE_STRLEN;
2280 while (*scan != '\0') /* first check it can be demangled */
2282 n = consume_count (&scan);
2285 return (0); /* no good */
2288 if (scan[0] == '_' && scan[1] == '_')
2293 (*mangled) += ARM_VTABLE_STRLEN;
2294 while (**mangled != '\0')
2296 n = consume_count (mangled);
2297 string_prependn (declp, *mangled, n);
2299 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2301 string_prepend (declp, "::");
2305 string_append (declp, " virtual table");
2318 demangle_qualified -- demangle 'Q' qualified name strings
2323 demangle_qualified (struct work_stuff *, const char *mangled,
2324 string *result, int isfuncname, int append);
2328 Demangle a qualified name, such as "Q25Outer5Inner" which is
2329 the mangled form of "Outer::Inner". The demangled output is
2330 prepended or appended to the result string according to the
2331 state of the append flag.
2333 If isfuncname is nonzero, then the qualified name we are building
2334 is going to be used as a member function name, so if it is a
2335 constructor or destructor function, append an appropriate
2336 constructor or destructor name. I.E. for the above example,
2337 the result for use as a constructor is "Outer::Inner::Inner"
2338 and the result for use as a destructor is "Outer::Inner::~Inner".
2342 Numeric conversion is ASCII dependent (FIXME).
2347 demangle_qualified (work, mangled, result, isfuncname, append)
2348 struct work_stuff *work;
2349 const char **mangled;
2360 int bindex = register_Btype (work);
2362 /* We only make use of ISFUNCNAME if the entity is a constructor or
2364 isfuncname = (isfuncname
2365 && ((work->constructor & 1) || (work->destructor & 1)));
2367 string_init (&temp);
2368 string_init (&last_name);
2370 if ((*mangled)[0] == 'K')
2372 /* Squangling qualified name reuse */
2375 idx = consume_count_with_underscores (mangled);
2376 if (idx == -1 || idx >= work -> numk)
2379 string_append (&temp, work -> ktypevec[idx]);
2382 switch ((*mangled)[1])
2385 /* GNU mangled name with more than 9 classes. The count is preceded
2386 by an underscore (to distinguish it from the <= 9 case) and followed
2387 by an underscore. */
2389 qualifiers = atoi (p);
2390 if (!isdigit ((unsigned char)*p) || *p == '0')
2393 /* Skip the digits. */
2394 while (isdigit ((unsigned char)*p))
2412 /* The count is in a single digit. */
2413 num[0] = (*mangled)[1];
2415 qualifiers = atoi (num);
2417 /* If there is an underscore after the digit, skip it. This is
2418 said to be for ARM-qualified names, but the ARM makes no
2419 mention of such an underscore. Perhaps cfront uses one. */
2420 if ((*mangled)[2] == '_')
2435 /* Pick off the names and collect them in the temp buffer in the order
2436 in which they are found, separated by '::'. */
2438 while (qualifiers-- > 0)
2441 string_clear (&last_name);
2443 if (*mangled[0] == '_')
2446 if (*mangled[0] == 't')
2448 /* Here we always append to TEMP since we will want to use
2449 the template name without the template parameters as a
2450 constructor or destructor name. The appropriate
2451 (parameter-less) value is returned by demangle_template
2452 in LAST_NAME. We do not remember the template type here,
2453 in order to match the G++ mangling algorithm. */
2454 success = demangle_template(work, mangled, &temp,
2459 else if (*mangled[0] == 'K')
2463 idx = consume_count_with_underscores (mangled);
2464 if (idx == -1 || idx >= work->numk)
2467 string_append (&temp, work->ktypevec[idx]);
2470 if (!success) break;
2474 success = do_type (work, mangled, &last_name);
2477 string_appends (&temp, &last_name);
2481 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2484 string_append (&temp, SCOPE_STRING (work));
2487 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2489 /* If we are using the result as a function name, we need to append
2490 the appropriate '::' separated constructor or destructor name.
2491 We do this here because this is the most convenient place, where
2492 we already have a pointer to the name and the length of the name. */
2496 string_append (&temp, SCOPE_STRING (work));
2497 if (work -> destructor & 1)
2498 string_append (&temp, "~");
2499 string_appends (&temp, &last_name);
2502 /* Now either prepend the temp buffer to the result, or append it,
2503 depending upon the state of the append flag. */
2506 string_appends (result, &temp);
2509 if (!STRING_EMPTY (result))
2510 string_append (&temp, SCOPE_STRING (work));
2511 string_prepends (result, &temp);
2514 string_delete (&last_name);
2515 string_delete (&temp);
2523 get_count -- convert an ascii count to integer, consuming tokens
2528 get_count (const char **type, int *count)
2532 Return 0 if no conversion is performed, 1 if a string is converted.
2536 get_count (type, count)
2543 if (!isdigit ((unsigned char)**type))
2549 *count = **type - '0';
2551 if (isdigit ((unsigned char)**type))
2561 while (isdigit ((unsigned char)*p));
2572 /* RESULT will be initialised here; it will be freed on failure. The
2573 value returned is really a type_kind_t. */
2576 do_type (work, mangled, result)
2577 struct work_stuff *work;
2578 const char **mangled;
2585 const char *remembered_type;
2588 type_kind_t tk = tk_none;
2590 string_init (&btype);
2591 string_init (&decl);
2592 string_init (result);
2596 while (success && !done)
2602 /* A pointer type */
2606 string_prepend (&decl, "*");
2611 /* A reference type */
2614 string_prepend (&decl, "&");
2623 if (!STRING_EMPTY (&decl)
2624 && (decl.b[0] == '*' || decl.b[0] == '&'))
2626 string_prepend (&decl, "(");
2627 string_append (&decl, ")");
2629 string_append (&decl, "[");
2630 if (**mangled != '_')
2631 success = demangle_template_value_parm (work, mangled, &decl,
2633 if (**mangled == '_')
2635 string_append (&decl, "]");
2639 /* A back reference to a previously seen type */
2642 if (!get_count (mangled, &n) || n >= work -> ntypes)
2648 remembered_type = work -> typevec[n];
2649 mangled = &remembered_type;
2656 if (!STRING_EMPTY (&decl)
2657 && (decl.b[0] == '*' || decl.b[0] == '&'))
2659 string_prepend (&decl, "(");
2660 string_append (&decl, ")");
2662 /* After picking off the function args, we expect to either find the
2663 function return type (preceded by an '_') or the end of the
2665 if (!demangle_nested_args (work, mangled, &decl)
2666 || (**mangled != '_' && **mangled != '\0'))
2671 if (success && (**mangled == '_'))
2678 type_quals = TYPE_UNQUALIFIED;
2680 member = **mangled == 'M';
2682 if (!isdigit ((unsigned char)**mangled) && **mangled != 't')
2688 string_append (&decl, ")");
2689 string_prepend (&decl, SCOPE_STRING (work));
2690 if (isdigit ((unsigned char)**mangled))
2692 n = consume_count (mangled);
2693 if ((int) strlen (*mangled) < n)
2698 string_prependn (&decl, *mangled, n);
2704 string_init (&temp);
2705 success = demangle_template (work, mangled, &temp,
2709 string_prependn (&decl, temp.b, temp.p - temp.b);
2710 string_clear (&temp);
2715 string_prepend (&decl, "(");
2723 type_quals |= code_for_qualifier (**mangled);
2731 if (*(*mangled)++ != 'F')
2737 if ((member && !demangle_nested_args (work, mangled, &decl))
2738 || **mangled != '_')
2744 if (! PRINT_ANSI_QUALIFIERS)
2748 if (type_quals != TYPE_UNQUALIFIED)
2750 APPEND_BLANK (&decl);
2751 string_append (&decl, qualifier_string (type_quals));
2762 if (PRINT_ANSI_QUALIFIERS)
2764 if (!STRING_EMPTY (&decl))
2765 string_prepend (&decl, " ");
2767 string_prepend (&decl, demangle_qualifier (**mangled));
2782 if (success) switch (**mangled)
2784 /* A qualified name, such as "Outer::Inner". */
2788 success = demangle_qualified (work, mangled, result, 0, 1);
2792 /* A back reference to a previously seen squangled type */
2795 if (!get_count (mangled, &n) || n >= work -> numb)
2798 string_append (result, work->btypevec[n]);
2803 /* A template parm. We substitute the corresponding argument. */
2808 idx = consume_count_with_underscores (mangled);
2811 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2812 || consume_count_with_underscores (mangled) == -1)
2818 if (work->tmpl_argvec)
2819 string_append (result, work->tmpl_argvec[idx]);
2823 sprintf(buf, "T%d", idx);
2824 string_append (result, buf);
2832 success = demangle_fund_type (work, mangled, result);
2834 tk = (type_kind_t) success;
2840 if (!STRING_EMPTY (&decl))
2842 string_append (result, " ");
2843 string_appends (result, &decl);
2847 string_delete (result);
2848 string_delete (&decl);
2851 /* Assume an integral type, if we're not sure. */
2852 return (int) ((tk == tk_none) ? tk_integral : tk);
2857 /* Given a pointer to a type string that represents a fundamental type
2858 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
2859 string in which the demangled output is being built in RESULT, and
2860 the WORK structure, decode the types and add them to the result.
2865 "Sl" => "signed long"
2866 "CUs" => "const unsigned short"
2868 The value returned is really a type_kind_t. */
2871 demangle_fund_type (work, mangled, result)
2872 struct work_stuff *work;
2873 const char **mangled;
2879 type_kind_t tk = tk_integral;
2881 string_init (&btype);
2883 /* First pick off any type qualifiers. There can be more than one. */
2893 if (PRINT_ANSI_QUALIFIERS)
2895 APPEND_BLANK (result);
2896 string_append (result, demangle_qualifier (**mangled));
2901 APPEND_BLANK (result);
2902 string_append (result, "unsigned");
2904 case 'S': /* signed char only */
2906 APPEND_BLANK (result);
2907 string_append (result, "signed");
2911 APPEND_BLANK (result);
2912 string_append (result, "__complex");
2920 /* Now pick off the fundamental type. There can be only one. */
2929 APPEND_BLANK (result);
2930 string_append (result, "void");
2934 APPEND_BLANK (result);
2935 string_append (result, "long long");
2939 APPEND_BLANK (result);
2940 string_append (result, "long");
2944 APPEND_BLANK (result);
2945 string_append (result, "int");
2949 APPEND_BLANK (result);
2950 string_append (result, "short");
2954 APPEND_BLANK (result);
2955 string_append (result, "bool");
2960 APPEND_BLANK (result);
2961 string_append (result, "char");
2966 APPEND_BLANK (result);
2967 string_append (result, "wchar_t");
2972 APPEND_BLANK (result);
2973 string_append (result, "long double");
2978 APPEND_BLANK (result);
2979 string_append (result, "double");
2984 APPEND_BLANK (result);
2985 string_append (result, "float");
2990 if (!isdigit ((unsigned char)**mangled))
2996 /* An explicit type, such as "6mytype" or "7integer" */
3008 int bindex = register_Btype (work);
3010 string_init (&btype);
3011 if (demangle_class_name (work, mangled, &btype)) {
3012 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3013 APPEND_BLANK (result);
3014 string_appends (result, &btype);
3018 string_delete (&btype);
3023 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3024 string_appends (result, &btype);
3032 return success ? ((int) tk) : 0;
3035 /* Demangle the next argument, given by MANGLED into RESULT, which
3036 *should be an uninitialized* string. It will be initialized here,
3037 and free'd should anything go wrong. */
3040 do_arg (work, mangled, result)
3041 struct work_stuff *work;
3042 const char **mangled;
3045 /* Remember where we started so that we can record the type, for
3046 non-squangling type remembering. */
3047 const char *start = *mangled;
3049 string_init (result);
3051 if (work->nrepeats > 0)
3055 if (work->previous_argument == 0)
3058 /* We want to reissue the previous type in this argument list. */
3059 string_appends (result, work->previous_argument);
3063 if (**mangled == 'n')
3065 /* A squangling-style repeat. */
3067 work->nrepeats = consume_count(mangled);
3069 if (work->nrepeats == 0)
3070 /* This was not a repeat count after all. */
3073 if (work->nrepeats > 9)
3075 if (**mangled != '_')
3076 /* The repeat count should be followed by an '_' in this
3083 /* Now, the repeat is all set up. */
3084 return do_arg (work, mangled, result);
3087 /* Save the result in WORK->previous_argument so that we can find it
3088 if it's repeated. Note that saving START is not good enough: we
3089 do not want to add additional types to the back-referenceable
3090 type vector when processing a repeated type. */
3091 if (work->previous_argument)
3092 string_clear (work->previous_argument);
3095 work->previous_argument = (string*) xmalloc (sizeof (string));
3096 string_init (work->previous_argument);
3099 if (!do_type (work, mangled, work->previous_argument))
3102 string_appends (result, work->previous_argument);
3104 remember_type (work, start, *mangled - start);
3109 remember_type (work, start, len)
3110 struct work_stuff *work;
3116 if (work->forgetting_types)
3119 if (work -> ntypes >= work -> typevec_size)
3121 if (work -> typevec_size == 0)
3123 work -> typevec_size = 3;
3125 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3129 work -> typevec_size *= 2;
3131 = (char **) xrealloc ((char *)work -> typevec,
3132 sizeof (char *) * work -> typevec_size);
3135 tem = xmalloc (len + 1);
3136 memcpy (tem, start, len);
3138 work -> typevec[work -> ntypes++] = tem;
3142 /* Remember a K type class qualifier. */
3144 remember_Ktype (work, start, len)
3145 struct work_stuff *work;
3151 if (work -> numk >= work -> ksize)
3153 if (work -> ksize == 0)
3157 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3163 = (char **) xrealloc ((char *)work -> ktypevec,
3164 sizeof (char *) * work -> ksize);
3167 tem = xmalloc (len + 1);
3168 memcpy (tem, start, len);
3170 work -> ktypevec[work -> numk++] = tem;
3173 /* Register a B code, and get an index for it. B codes are registered
3174 as they are seen, rather than as they are completed, so map<temp<char> >
3175 registers map<temp<char> > as B0, and temp<char> as B1 */
3178 register_Btype (work)
3179 struct work_stuff *work;
3183 if (work -> numb >= work -> bsize)
3185 if (work -> bsize == 0)
3189 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3195 = (char **) xrealloc ((char *)work -> btypevec,
3196 sizeof (char *) * work -> bsize);
3199 ret = work -> numb++;
3200 work -> btypevec[ret] = NULL;
3204 /* Store a value into a previously registered B code type. */
3207 remember_Btype (work, start, len, index)
3208 struct work_stuff *work;
3214 tem = xmalloc (len + 1);
3215 memcpy (tem, start, len);
3217 work -> btypevec[index] = tem;
3220 /* Lose all the info related to B and K type codes. */
3222 forget_B_and_K_types (work)
3223 struct work_stuff *work;
3227 while (work -> numk > 0)
3229 i = --(work -> numk);
3230 if (work -> ktypevec[i] != NULL)
3232 free (work -> ktypevec[i]);
3233 work -> ktypevec[i] = NULL;
3237 while (work -> numb > 0)
3239 i = --(work -> numb);
3240 if (work -> btypevec[i] != NULL)
3242 free (work -> btypevec[i]);
3243 work -> btypevec[i] = NULL;
3247 /* Forget the remembered types, but not the type vector itself. */
3251 struct work_stuff *work;
3255 while (work -> ntypes > 0)
3257 i = --(work -> ntypes);
3258 if (work -> typevec[i] != NULL)
3260 free (work -> typevec[i]);
3261 work -> typevec[i] = NULL;
3266 /* Process the argument list part of the signature, after any class spec
3267 has been consumed, as well as the first 'F' character (if any). For
3270 "__als__3fooRT0" => process "RT0"
3271 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3273 DECLP must be already initialised, usually non-empty. It won't be freed
3276 Note that g++ differs significantly from ARM and lucid style mangling
3277 with regards to references to previously seen types. For example, given
3278 the source fragment:
3282 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3285 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3286 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3288 g++ produces the names:
3293 while lcc (and presumably other ARM style compilers as well) produces:
3295 foo__FiR3fooT1T2T1T2
3296 __ct__3fooFiR3fooT1T2T1T2
3298 Note that g++ bases its type numbers starting at zero and counts all
3299 previously seen types, while lucid/ARM bases its type numbers starting
3300 at one and only considers types after it has seen the 'F' character
3301 indicating the start of the function args. For lucid/ARM style, we
3302 account for this difference by discarding any previously seen types when
3303 we see the 'F' character, and subtracting one from the type number
3309 demangle_args (work, mangled, declp)
3310 struct work_stuff *work;
3311 const char **mangled;
3321 if (PRINT_ARG_TYPES)
3323 string_append (declp, "(");
3324 if (**mangled == '\0')
3326 string_append (declp, "void");
3330 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3331 || work->nrepeats > 0)
3333 if ((**mangled == 'N') || (**mangled == 'T'))
3335 temptype = *(*mangled)++;
3337 if (temptype == 'N')
3339 if (!get_count (mangled, &r))
3348 if (ARM_DEMANGLING && work -> ntypes >= 10)
3350 /* If we have 10 or more types we might have more than a 1 digit
3351 index so we'll have to consume the whole count here. This
3352 will lose if the next thing is a type name preceded by a
3353 count but it's impossible to demangle that case properly
3354 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3355 Pc, ...)" or "(..., type12, char *, ...)" */
3356 if ((t = consume_count(mangled)) == 0)
3363 if (!get_count (mangled, &t))
3368 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3372 /* Validate the type index. Protect against illegal indices from
3373 malformed type strings. */
3374 if ((t < 0) || (t >= work -> ntypes))
3378 while (work->nrepeats > 0 || --r >= 0)
3380 tem = work -> typevec[t];
3381 if (need_comma && PRINT_ARG_TYPES)
3383 string_append (declp, ", ");
3385 if (!do_arg (work, &tem, &arg))
3389 if (PRINT_ARG_TYPES)
3391 string_appends (declp, &arg);
3393 string_delete (&arg);
3399 if (need_comma && PRINT_ARG_TYPES)
3400 string_append (declp, ", ");
3401 if (!do_arg (work, mangled, &arg))
3403 if (PRINT_ARG_TYPES)
3404 string_appends (declp, &arg);
3405 string_delete (&arg);
3410 if (**mangled == 'e')
3413 if (PRINT_ARG_TYPES)
3417 string_append (declp, ",");
3419 string_append (declp, "...");
3423 if (PRINT_ARG_TYPES)
3425 string_append (declp, ")");
3430 /* Like demangle_args, but for demangling the argument lists of function
3431 and method pointers or references, not top-level declarations. */
3434 demangle_nested_args (work, mangled, declp)
3435 struct work_stuff *work;
3436 const char **mangled;
3439 string* saved_previous_argument;
3443 /* The G++ name-mangling algorithm does not remember types on nested
3444 argument lists, unless -fsquangling is used, and in that case the
3445 type vector updated by remember_type is not used. So, we turn
3446 off remembering of types here. */
3447 ++work->forgetting_types;
3449 /* For the repeat codes used with -fsquangling, we must keep track of
3450 the last argument. */
3451 saved_previous_argument = work->previous_argument;
3452 saved_nrepeats = work->nrepeats;
3453 work->previous_argument = 0;
3456 /* Actually demangle the arguments. */
3457 result = demangle_args (work, mangled, declp);
3459 /* Restore the previous_argument field. */
3460 if (work->previous_argument)
3461 string_delete (work->previous_argument);
3462 work->previous_argument = saved_previous_argument;
3463 work->nrepeats = saved_nrepeats;
3469 demangle_function_name (work, mangled, declp, scan)
3470 struct work_stuff *work;
3471 const char **mangled;
3479 string_appendn (declp, (*mangled), scan - (*mangled));
3480 string_need (declp, 1);
3481 *(declp -> p) = '\0';
3483 /* Consume the function name, including the "__" separating the name
3484 from the signature. We are guaranteed that SCAN points to the
3487 (*mangled) = scan + 2;
3489 if (LUCID_DEMANGLING || ARM_DEMANGLING)
3492 /* See if we have an ARM style constructor or destructor operator.
3493 If so, then just record it, clear the decl, and return.
3494 We can't build the actual constructor/destructor decl until later,
3495 when we recover the class name from the signature. */
3497 if (strcmp (declp -> b, "__ct") == 0)
3499 work -> constructor += 1;
3500 string_clear (declp);
3503 else if (strcmp (declp -> b, "__dt") == 0)
3505 work -> destructor += 1;
3506 string_clear (declp);
3511 if (declp->p - declp->b >= 3
3512 && declp->b[0] == 'o'
3513 && declp->b[1] == 'p'
3514 && strchr (cplus_markers, declp->b[2]) != NULL)
3516 /* see if it's an assignment expression */
3517 if (declp->p - declp->b >= 10 /* op$assign_ */
3518 && memcmp (declp->b + 3, "assign_", 7) == 0)
3520 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3522 int len = declp->p - declp->b - 10;
3523 if ((int) strlen (optable[i].in) == len
3524 && memcmp (optable[i].in, declp->b + 10, len) == 0)
3526 string_clear (declp);
3527 string_append (declp, "operator");
3528 string_append (declp, optable[i].out);
3529 string_append (declp, "=");
3536 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3538 int len = declp->p - declp->b - 3;
3539 if ((int) strlen (optable[i].in) == len
3540 && memcmp (optable[i].in, declp->b + 3, len) == 0)
3542 string_clear (declp);
3543 string_append (declp, "operator");
3544 string_append (declp, optable[i].out);
3550 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
3551 && strchr (cplus_markers, declp->b[4]) != NULL)
3553 /* type conversion operator */
3555 if (do_type (work, &tem, &type))
3557 string_clear (declp);
3558 string_append (declp, "operator ");
3559 string_appends (declp, &type);
3560 string_delete (&type);
3563 else if (declp->b[0] == '_' && declp->b[1] == '_'
3564 && declp->b[2] == 'o' && declp->b[3] == 'p')
3567 /* type conversion operator. */
3569 if (do_type (work, &tem, &type))
3571 string_clear (declp);
3572 string_append (declp, "operator ");
3573 string_appends (declp, &type);
3574 string_delete (&type);
3577 else if (declp->b[0] == '_' && declp->b[1] == '_'
3578 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
3579 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
3581 if (declp->b[4] == '\0')
3584 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3586 if (strlen (optable[i].in) == 2
3587 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
3589 string_clear (declp);
3590 string_append (declp, "operator");
3591 string_append (declp, optable[i].out);
3598 if (declp->b[2] == 'a' && declp->b[5] == '\0')
3601 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3603 if (strlen (optable[i].in) == 3
3604 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
3606 string_clear (declp);
3607 string_append (declp, "operator");
3608 string_append (declp, optable[i].out);
3617 /* a mini string-handling package */
3632 s->p = s->b = xmalloc (n);
3635 else if (s->e - s->p < n)
3640 s->b = xrealloc (s->b, n);
3653 s->b = s->e = s->p = NULL;
3661 s->b = s->p = s->e = NULL;
3677 return (s->b == s->p);
3683 string_append (p, s)
3688 if (s == NULL || *s == '\0')
3692 memcpy (p->p, s, n);
3697 string_appends (p, s)
3706 memcpy (p->p, s->b, n);
3712 string_appendn (p, s, n)
3720 memcpy (p->p, s, n);
3726 string_prepend (p, s)
3730 if (s != NULL && *s != '\0')
3732 string_prependn (p, s, strlen (s));
3737 string_prepends (p, s)
3742 string_prependn (p, s->b, s->p - s->b);
3747 string_prependn (p, s, n)
3757 for (q = p->p - 1; q >= p->b; q--)
3761 memcpy (p->b, s, n);
3766 /* To generate a standalone demangler program for testing purposes,
3767 just compile and link this file with -DMAIN and libiberty.a. When
3768 run, it demangles each command line arg, or each stdin string, and
3769 prints the result on stdout. */
3775 static char *program_name;
3776 static char *program_version = VERSION;
3777 static int flags = DMGL_PARAMS | DMGL_ANSI;
3779 static void demangle_it PARAMS ((char *));
3780 static void usage PARAMS ((FILE *, int));
3781 static void fatal PARAMS ((char *));
3784 demangle_it (mangled_name)
3789 result = cplus_demangle (mangled_name, flags);
3792 printf ("%s\n", mangled_name);
3796 printf ("%s\n", result);
3802 usage (stream, status)
3807 Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\
3808 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\
3809 [--help] [--version] [arg...]\n",
3814 #define MBUF_SIZE 32767
3815 char mbuffer[MBUF_SIZE];
3817 /* Defined in the automatically-generated underscore.c. */
3818 extern int prepends_underscore;
3820 int strip_underscore = 0;
3822 static struct option long_options[] = {
3823 {"strip-underscores", no_argument, 0, '_'},
3824 {"format", required_argument, 0, 's'},
3825 {"help", no_argument, 0, 'h'},
3826 {"no-strip-underscores", no_argument, 0, 'n'},
3827 {"version", no_argument, 0, 'v'},
3828 {0, no_argument, 0, 0}
3831 /* More 'friendly' abort that prints the line and file.
3832 config.h can #define abort fancy_abort if you like that sort of thing. */
3837 fatal ("Internal gcc abort.");
3848 program_name = argv[0];
3850 strip_underscore = prepends_underscore;
3852 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
3862 strip_underscore = 0;
3865 printf ("GNU %s version %s\n", program_name, program_version);
3868 strip_underscore = 1;
3871 if (strcmp (optarg, "gnu") == 0)
3873 current_demangling_style = gnu_demangling;
3875 else if (strcmp (optarg, "lucid") == 0)
3877 current_demangling_style = lucid_demangling;
3879 else if (strcmp (optarg, "arm") == 0)
3881 current_demangling_style = arm_demangling;
3885 fprintf (stderr, "%s: unknown demangling style `%s'\n",
3886 program_name, optarg);
3895 for ( ; optind < argc; optind++)
3897 demangle_it (argv[optind]);
3906 /* Try to read a label. */
3907 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.'))
3909 if (i >= MBUF_SIZE-1)
3918 if (mbuffer[0] == '.')
3920 if (strip_underscore && mbuffer[skip_first] == '_')
3928 result = cplus_demangle (mbuffer + skip_first, flags);
3931 if (mbuffer[0] == '.')
3933 fputs (result, stdout);
3937 fputs (mbuffer, stdout);
3954 fprintf (stderr, "%s: %s\n", program_name, str);
3962 register char *value = (char *) malloc (size);
3964 fatal ("virtual memory exhausted");
3969 xrealloc (ptr, size)
3973 register char *value = (char *) realloc (ptr, size);
3975 fatal ("virtual memory exhausted");