1 /* Demangler for GNU C++
2 Copyright 1989, 91, 94, 95, 96, 97, 98, 1999 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
5 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
7 This file is part of the libiberty library.
8 Libiberty is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 Libiberty is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public
19 License along with libiberty; see the file COPYING.LIB. If
20 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
25 This file imports xmalloc and xrealloc, which are like malloc and
26 realloc except that they generate a fatal error if there is no
29 /* This file lives in both GCC and libiberty. When making changes, please
30 try not to break either. */
37 #include <sys/types.h>
49 #undef CURRENT_DEMANGLING_STYLE
50 #define CURRENT_DEMANGLING_STYLE work->options
52 #include "libiberty.h"
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' };
97 static char char_str[2] = { '\000', '\000' };
100 set_cplus_marker_for_demangling (ch)
103 cplus_markers[0] = ch;
106 typedef struct string /* Beware: these aren't required to be */
107 { /* '\0' terminated. */
108 char *b; /* pointer to start of string */
109 char *p; /* pointer after last character */
110 char *e; /* pointer after end of allocated space */
113 /* Stuff that is shared between sub-routines.
114 Using a shared structure allows cplus_demangle to be reentrant. */
130 int static_type; /* A static member function */
131 int temp_start; /* index in demangled to start of template args */
132 int type_quals; /* The type qualifiers. */
133 int dllimported; /* Symbol imported from a PE DLL */
134 char **tmpl_argvec; /* Template function arguments. */
135 int ntmpl_args; /* The number of template function arguments. */
136 int forgetting_types; /* Nonzero if we are not remembering the types
138 string* previous_argument; /* The last function argument demangled. */
139 int nrepeats; /* The number of times to repeat the previous
143 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
144 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
146 static const struct optable
152 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
153 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
154 {"new", " new", 0}, /* old (1.91, and 1.x) */
155 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
156 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
157 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
158 {"as", "=", DMGL_ANSI}, /* ansi */
159 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
160 {"eq", "==", DMGL_ANSI}, /* old, ansi */
161 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
162 {"gt", ">", DMGL_ANSI}, /* old, ansi */
163 {"le", "<=", DMGL_ANSI}, /* old, ansi */
164 {"lt", "<", DMGL_ANSI}, /* old, ansi */
165 {"plus", "+", 0}, /* old */
166 {"pl", "+", DMGL_ANSI}, /* ansi */
167 {"apl", "+=", DMGL_ANSI}, /* ansi */
168 {"minus", "-", 0}, /* old */
169 {"mi", "-", DMGL_ANSI}, /* ansi */
170 {"ami", "-=", DMGL_ANSI}, /* ansi */
171 {"mult", "*", 0}, /* old */
172 {"ml", "*", DMGL_ANSI}, /* ansi */
173 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
174 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
175 {"convert", "+", 0}, /* old (unary +) */
176 {"negate", "-", 0}, /* old (unary -) */
177 {"trunc_mod", "%", 0}, /* old */
178 {"md", "%", DMGL_ANSI}, /* ansi */
179 {"amd", "%=", DMGL_ANSI}, /* ansi */
180 {"trunc_div", "/", 0}, /* old */
181 {"dv", "/", DMGL_ANSI}, /* ansi */
182 {"adv", "/=", DMGL_ANSI}, /* ansi */
183 {"truth_andif", "&&", 0}, /* old */
184 {"aa", "&&", DMGL_ANSI}, /* ansi */
185 {"truth_orif", "||", 0}, /* old */
186 {"oo", "||", DMGL_ANSI}, /* ansi */
187 {"truth_not", "!", 0}, /* old */
188 {"nt", "!", DMGL_ANSI}, /* ansi */
189 {"postincrement","++", 0}, /* old */
190 {"pp", "++", DMGL_ANSI}, /* ansi */
191 {"postdecrement","--", 0}, /* old */
192 {"mm", "--", DMGL_ANSI}, /* ansi */
193 {"bit_ior", "|", 0}, /* old */
194 {"or", "|", DMGL_ANSI}, /* ansi */
195 {"aor", "|=", DMGL_ANSI}, /* ansi */
196 {"bit_xor", "^", 0}, /* old */
197 {"er", "^", DMGL_ANSI}, /* ansi */
198 {"aer", "^=", DMGL_ANSI}, /* ansi */
199 {"bit_and", "&", 0}, /* old */
200 {"ad", "&", DMGL_ANSI}, /* ansi */
201 {"aad", "&=", DMGL_ANSI}, /* ansi */
202 {"bit_not", "~", 0}, /* old */
203 {"co", "~", DMGL_ANSI}, /* ansi */
204 {"call", "()", 0}, /* old */
205 {"cl", "()", DMGL_ANSI}, /* ansi */
206 {"alshift", "<<", 0}, /* old */
207 {"ls", "<<", DMGL_ANSI}, /* ansi */
208 {"als", "<<=", DMGL_ANSI}, /* ansi */
209 {"arshift", ">>", 0}, /* old */
210 {"rs", ">>", DMGL_ANSI}, /* ansi */
211 {"ars", ">>=", DMGL_ANSI}, /* ansi */
212 {"component", "->", 0}, /* old */
213 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
214 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
215 {"indirect", "*", 0}, /* old */
216 {"method_call", "->()", 0}, /* old */
217 {"addr", "&", 0}, /* old (unary &) */
218 {"array", "[]", 0}, /* old */
219 {"vc", "[]", DMGL_ANSI}, /* ansi */
220 {"compound", ", ", 0}, /* old */
221 {"cm", ", ", DMGL_ANSI}, /* ansi */
222 {"cond", "?:", 0}, /* old */
223 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
224 {"max", ">?", 0}, /* old */
225 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
226 {"min", "<?", 0}, /* old */
227 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
228 {"nop", "", 0}, /* old (for operator=) */
229 {"rm", "->*", DMGL_ANSI}, /* ansi */
230 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
233 /* These values are used to indicate the various type varieties.
234 They are all non-zero so that they can be used as `success'
236 typedef enum type_kind_t
247 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
248 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
249 string_prepend(str, " ");}
250 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
251 string_append(str, " ");}
252 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
254 /* The scope separator appropriate for the language being demangled. */
256 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
258 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
259 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
261 /* Prototypes for local functions */
264 mop_up PARAMS ((struct work_stuff *, string *, int));
267 squangle_mop_up PARAMS ((struct work_stuff *));
271 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
275 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
278 demangle_template_template_parm PARAMS ((struct work_stuff *work,
279 const char **, string *));
282 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
283 string *, int, int));
286 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
290 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
293 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
297 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
300 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
303 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
306 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
309 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
312 arm_special PARAMS ((const char **, string *));
315 string_need PARAMS ((string *, int));
318 string_delete PARAMS ((string *));
321 string_init PARAMS ((string *));
324 string_clear PARAMS ((string *));
328 string_empty PARAMS ((string *));
332 string_append PARAMS ((string *, const char *));
335 string_appends PARAMS ((string *, string *));
338 string_appendn PARAMS ((string *, const char *, int));
341 string_prepend PARAMS ((string *, const char *));
344 string_prependn PARAMS ((string *, const char *, int));
347 get_count PARAMS ((const char **, int *));
350 consume_count PARAMS ((const char **));
353 consume_count_with_underscores PARAMS ((const char**));
356 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
359 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
362 do_type PARAMS ((struct work_stuff *, const char **, string *));
365 do_arg PARAMS ((struct work_stuff *, const char **, string *));
368 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
372 remember_type PARAMS ((struct work_stuff *, const char *, int));
375 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
378 register_Btype PARAMS ((struct work_stuff *));
381 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
384 forget_types PARAMS ((struct work_stuff *));
387 forget_B_and_K_types PARAMS ((struct work_stuff *));
390 string_prepends PARAMS ((string *, string *));
393 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
394 string*, type_kind_t));
397 do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
400 do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
403 snarf_numeric_literal PARAMS ((const char **, string *));
405 /* There is a TYPE_QUAL value for each type qualifier. They can be
406 combined by bitwise-or to form the complete set of qualifiers for a
409 #define TYPE_UNQUALIFIED 0x0
410 #define TYPE_QUAL_CONST 0x1
411 #define TYPE_QUAL_VOLATILE 0x2
412 #define TYPE_QUAL_RESTRICT 0x4
415 code_for_qualifier PARAMS ((int));
418 qualifier_string PARAMS ((int));
421 demangle_qualifier PARAMS ((int));
423 /* Translate count to integer, consuming tokens in the process.
424 Conversion terminates on the first non-digit character.
426 Trying to consume something that isn't a count results in no
427 consumption of input and a return of -1.
429 Overflow consumes the rest of the digits, and returns -1. */
437 if (! isdigit ((unsigned char)**type))
440 while (isdigit ((unsigned char)**type))
444 /* Check for overflow.
445 We assume that count is represented using two's-complement;
446 no power of two is divisible by ten, so if an overflow occurs
447 when multiplying by ten, the result will not be a multiple of
449 if ((count % 10) != 0)
451 while (isdigit ((unsigned char) **type))
456 count += **type - '0';
464 /* Like consume_count, but for counts that are preceded and followed
465 by '_' if they are greater than 10. Also, -1 is returned for
466 failure, since 0 can be a valid value. */
469 consume_count_with_underscores (mangled)
470 const char **mangled;
474 if (**mangled == '_')
477 if (!isdigit ((unsigned char)**mangled))
480 idx = consume_count (mangled);
481 if (**mangled != '_')
482 /* The trailing underscore was missing. */
489 if (**mangled < '0' || **mangled > '9')
492 idx = **mangled - '0';
499 /* C is the code for a type-qualifier. Return the TYPE_QUAL
500 corresponding to this qualifier. */
503 code_for_qualifier (c)
509 return TYPE_QUAL_CONST;
512 return TYPE_QUAL_VOLATILE;
515 return TYPE_QUAL_RESTRICT;
521 /* C was an invalid qualifier. */
525 /* Return the string corresponding to the qualifiers given by
529 qualifier_string (type_quals)
534 case TYPE_UNQUALIFIED:
537 case TYPE_QUAL_CONST:
540 case TYPE_QUAL_VOLATILE:
543 case TYPE_QUAL_RESTRICT:
546 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
547 return "const volatile";
549 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
550 return "const __restrict";
552 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
553 return "volatile __restrict";
555 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
556 return "const volatile __restrict";
562 /* TYPE_QUALS was an invalid qualifier set. */
566 /* C is the code for a type-qualifier. Return the string
567 corresponding to this qualifier. This function should only be
568 called with a valid qualifier code. */
571 demangle_qualifier (c)
574 return qualifier_string (code_for_qualifier (c));
578 cplus_demangle_opname (opname, result, options)
585 struct work_stuff work[1];
588 len = strlen(opname);
591 memset ((char *) work, 0, sizeof (work));
592 work->options = options;
594 if (opname[0] == '_' && opname[1] == '_'
595 && opname[2] == 'o' && opname[3] == 'p')
598 /* type conversion operator. */
600 if (do_type (work, &tem, &type))
602 strcat (result, "operator ");
603 strncat (result, type.b, type.p - type.b);
604 string_delete (&type);
608 else if (opname[0] == '_' && opname[1] == '_'
609 && opname[2] >= 'a' && opname[2] <= 'z'
610 && opname[3] >= 'a' && opname[3] <= 'z')
612 if (opname[4] == '\0')
616 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
618 if (strlen (optable[i].in) == 2
619 && memcmp (optable[i].in, opname + 2, 2) == 0)
621 strcat (result, "operator");
622 strcat (result, optable[i].out);
630 if (opname[2] == 'a' && opname[5] == '\0')
634 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
636 if (strlen (optable[i].in) == 3
637 && memcmp (optable[i].in, opname + 2, 3) == 0)
639 strcat (result, "operator");
640 strcat (result, optable[i].out);
651 && strchr (cplus_markers, opname[2]) != NULL)
653 /* see if it's an assignment expression */
654 if (len >= 10 /* op$assign_ */
655 && memcmp (opname + 3, "assign_", 7) == 0)
658 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
661 if ((int) strlen (optable[i].in) == len1
662 && memcmp (optable[i].in, opname + 10, len1) == 0)
664 strcat (result, "operator");
665 strcat (result, optable[i].out);
666 strcat (result, "=");
675 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
678 if ((int) strlen (optable[i].in) == len1
679 && memcmp (optable[i].in, opname + 3, len1) == 0)
681 strcat (result, "operator");
682 strcat (result, optable[i].out);
689 else if (len >= 5 && memcmp (opname, "type", 4) == 0
690 && strchr (cplus_markers, opname[4]) != NULL)
692 /* type conversion operator */
694 if (do_type (work, &tem, &type))
696 strcat (result, "operator ");
697 strncat (result, type.b, type.p - type.b);
698 string_delete (&type);
702 squangle_mop_up (work);
706 /* Takes operator name as e.g. "++" and returns mangled
707 operator name (e.g. "postincrement_expr"), or NULL if not found.
709 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
710 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
713 cplus_mangle_opname (opname, options)
720 len = strlen (opname);
721 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
723 if ((int) strlen (optable[i].out) == len
724 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
725 && memcmp (optable[i].out, opname, len) == 0)
726 return optable[i].in;
731 /* char *cplus_demangle (const char *mangled, int options)
733 If MANGLED is a mangled function name produced by GNU C++, then
734 a pointer to a malloced string giving a C++ representation
735 of the name will be returned; otherwise NULL will be returned.
736 It is the caller's responsibility to free the string which
739 The OPTIONS arg may contain one or more of the following bits:
741 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
743 DMGL_PARAMS Function parameters are included.
747 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
748 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
749 cplus_demangle ("foo__1Ai", 0) => "A::foo"
751 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
752 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
753 cplus_demangle ("foo__1Afe", 0) => "A::foo"
755 Note that any leading underscores, or other such characters prepended by
756 the compilation system, are presumed to have already been stripped from
760 cplus_demangle (mangled, options)
765 struct work_stuff work[1];
766 memset ((char *) work, 0, sizeof (work));
767 work -> options = options;
768 if ((work -> options & DMGL_STYLE_MASK) == 0)
769 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
771 ret = internal_cplus_demangle (work, mangled);
772 squangle_mop_up (work);
777 /* This function performs most of what cplus_demangle use to do, but
778 to be able to demangle a name with a B, K or n code, we need to
779 have a longer term memory of what types have been seen. The original
780 now intializes and cleans up the squangle code info, while internal
781 calls go directly to this routine to avoid resetting that info. */
784 internal_cplus_demangle (work, mangled)
785 struct work_stuff *work;
791 char *demangled = NULL;
793 s1 = work->constructor;
794 s2 = work->destructor;
795 s3 = work->static_type;
796 s4 = work->type_quals;
797 work->constructor = work->destructor = 0;
798 work->type_quals = TYPE_UNQUALIFIED;
799 work->dllimported = 0;
801 if ((mangled != NULL) && (*mangled != '\0'))
805 /* First check to see if gnu style demangling is active and if the
806 string to be demangled contains a CPLUS_MARKER. If so, attempt to
807 recognize one of the gnu special forms rather than looking for a
808 standard prefix. In particular, don't worry about whether there
809 is a "__" string in the mangled string. Consider "_$_5__foo" for
812 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
814 success = gnu_special (work, &mangled, &decl);
818 success = demangle_prefix (work, &mangled, &decl);
820 if (success && (*mangled != '\0'))
822 success = demangle_signature (work, &mangled, &decl);
824 if (work->constructor == 2)
826 string_prepend (&decl, "global constructors keyed to ");
827 work->constructor = 0;
829 else if (work->destructor == 2)
831 string_prepend (&decl, "global destructors keyed to ");
832 work->destructor = 0;
834 else if (work->dllimported == 1)
836 string_prepend (&decl, "import stub for ");
837 work->dllimported = 0;
839 demangled = mop_up (work, &decl, success);
841 work->constructor = s1;
842 work->destructor = s2;
843 work->static_type = s3;
844 work->type_quals = s4;
849 /* Clear out and squangling related storage */
851 squangle_mop_up (work)
852 struct work_stuff *work;
854 /* clean up the B and K type mangling types. */
855 forget_B_and_K_types (work);
856 if (work -> btypevec != NULL)
858 free ((char *) work -> btypevec);
860 if (work -> ktypevec != NULL)
862 free ((char *) work -> ktypevec);
866 /* Clear out any mangled storage */
869 mop_up (work, declp, success)
870 struct work_stuff *work;
874 char *demangled = NULL;
876 /* Discard the remembered types, if any. */
879 if (work -> typevec != NULL)
881 free ((char *) work -> typevec);
882 work -> typevec = NULL;
884 if (work->tmpl_argvec)
888 for (i = 0; i < work->ntmpl_args; i++)
889 if (work->tmpl_argvec[i])
890 free ((char*) work->tmpl_argvec[i]);
892 free ((char*) work->tmpl_argvec);
893 work->tmpl_argvec = NULL;
895 if (work->previous_argument)
897 string_delete (work->previous_argument);
898 free ((char*) work->previous_argument);
899 work->previous_argument = NULL;
902 /* If demangling was successful, ensure that the demangled string is null
903 terminated and return it. Otherwise, free the demangling decl. */
907 string_delete (declp);
911 string_appendn (declp, "", 1);
912 demangled = declp -> b;
921 demangle_signature -- demangle the signature part of a mangled name
926 demangle_signature (struct work_stuff *work, const char **mangled,
931 Consume and demangle the signature portion of the mangled name.
933 DECLP is the string where demangled output is being built. At
934 entry it contains the demangled root name from the mangled name
935 prefix. I.E. either a demangled operator name or the root function
936 name. In some special cases, it may contain nothing.
938 *MANGLED points to the current unconsumed location in the mangled
939 name. As tokens are consumed and demangling is performed, the
940 pointer is updated to continuously point at the next token to
943 Demangling GNU style mangled names is nasty because there is no
944 explicit token that marks the start of the outermost function
948 demangle_signature (work, mangled, declp)
949 struct work_stuff *work;
950 const char **mangled;
956 int expect_return_type = 0;
957 const char *oldmangled = NULL;
961 while (success && (**mangled != '\0'))
966 oldmangled = *mangled;
967 success = demangle_qualified (work, mangled, declp, 1, 0);
969 remember_type (work, oldmangled, *mangled - oldmangled);
970 if (AUTO_DEMANGLING || GNU_DEMANGLING)
976 oldmangled = *mangled;
977 success = demangle_qualified (work, mangled, declp, 1, 0);
978 if (AUTO_DEMANGLING || GNU_DEMANGLING)
986 /* Static member function */
987 if (oldmangled == NULL)
989 oldmangled = *mangled;
992 work -> static_type = 1;
998 work->type_quals |= code_for_qualifier (**mangled);
1000 /* a qualified member function */
1001 if (oldmangled == NULL)
1002 oldmangled = *mangled;
1007 /* Local class name follows after "Lnnn_" */
1010 while (**mangled && (**mangled != '_'))
1021 case '0': case '1': case '2': case '3': case '4':
1022 case '5': case '6': case '7': case '8': case '9':
1023 if (oldmangled == NULL)
1025 oldmangled = *mangled;
1027 work->temp_start = -1; /* uppermost call to demangle_class */
1028 success = demangle_class (work, mangled, declp);
1031 remember_type (work, oldmangled, *mangled - oldmangled);
1033 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1035 /* EDG and others will have the "F", so we let the loop cycle
1036 if we are looking at one. */
1037 if (**mangled != 'F')
1046 success = do_type (work, mangled, &s);
1049 string_append (&s, SCOPE_STRING (work));
1050 string_prepends (declp, &s);
1059 /* ARM/HP style demangling includes a specific 'F' character after
1060 the class name. For GNU style, it is just implied. So we can
1061 safely just consume any 'F' at this point and be compatible
1062 with either style. */
1068 /* For lucid/ARM/HP style we have to forget any types we might
1069 have remembered up to this point, since they were not argument
1070 types. GNU style considers all types seen as available for
1071 back references. See comment in demangle_args() */
1073 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1075 forget_types (work);
1077 success = demangle_args (work, mangled, declp);
1078 /* After picking off the function args, we expect to either
1079 find the function return type (preceded by an '_') or the
1080 end of the string. */
1081 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1084 /* At this level, we do not care about the return type. */
1085 success = do_type (work, mangled, &tname);
1086 string_delete (&tname);
1093 string_init(&trawname);
1094 string_init(&tname);
1095 if (oldmangled == NULL)
1097 oldmangled = *mangled;
1099 success = demangle_template (work, mangled, &tname,
1103 remember_type (work, oldmangled, *mangled - oldmangled);
1105 string_append (&tname, SCOPE_STRING (work));
1107 string_prepends(declp, &tname);
1108 if (work -> destructor & 1)
1110 string_prepend (&trawname, "~");
1111 string_appends (declp, &trawname);
1112 work->destructor -= 1;
1114 if ((work->constructor & 1) || (work->destructor & 1))
1116 string_appends (declp, &trawname);
1117 work->constructor -= 1;
1119 string_delete(&trawname);
1120 string_delete(&tname);
1126 if (GNU_DEMANGLING && expect_return_type)
1128 /* Read the return type. */
1130 string_init (&return_type);
1133 success = do_type (work, mangled, &return_type);
1134 APPEND_BLANK (&return_type);
1136 string_prepends (declp, &return_type);
1137 string_delete (&return_type);
1141 /* At the outermost level, we cannot have a return type specified,
1142 so if we run into another '_' at this point we are dealing with
1143 a mangled name that is either bogus, or has been mangled by
1144 some algorithm we don't know how to deal with. So just
1145 reject the entire demangling. */
1146 /* However, "_nnn" is an expected suffix for alternate entry point
1147 numbered nnn for a function, with HP aCC, so skip over that
1148 without reporting failure. pai/1997-09-04 */
1152 while (**mangled && isdigit ((unsigned char)**mangled))
1162 /* A G++ template function. Read the template arguments. */
1163 success = demangle_template (work, mangled, declp, 0, 0,
1165 if (!(work->constructor & 1))
1166 expect_return_type = 1;
1175 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1177 /* Assume we have stumbled onto the first outermost function
1178 argument token, and start processing args. */
1180 success = demangle_args (work, mangled, declp);
1184 /* Non-GNU demanglers use a specific token to mark the start
1185 of the outermost function argument tokens. Typically 'F',
1186 for ARM/HP-demangling, for example. So if we find something
1187 we are not prepared for, it must be an error. */
1193 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1196 if (success && expect_func)
1199 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1201 forget_types (work);
1203 success = demangle_args (work, mangled, declp);
1204 /* Since template include the mangling of their return types,
1205 we must set expect_func to 0 so that we don't try do
1206 demangle more arguments the next time we get here. */
1211 if (success && !func_done)
1213 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1215 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1216 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1217 first case, and need to ensure that the '(void)' gets added to
1218 the current declp. Note that with ARM/HP, the first case
1219 represents the name of a static data member 'foo::bar',
1220 which is in the current declp, so we leave it alone. */
1221 success = demangle_args (work, mangled, declp);
1224 if (success && PRINT_ARG_TYPES)
1226 if (work->static_type)
1227 string_append (declp, " static");
1228 if (work->type_quals != TYPE_UNQUALIFIED)
1230 APPEND_BLANK (declp);
1231 string_append (declp, qualifier_string (work->type_quals));
1241 demangle_method_args (work, mangled, declp)
1242 struct work_stuff *work;
1243 const char **mangled;
1248 if (work -> static_type)
1250 string_append (declp, *mangled + 1);
1251 *mangled += strlen (*mangled);
1256 success = demangle_args (work, mangled, declp);
1264 demangle_template_template_parm (work, mangled, tname)
1265 struct work_stuff *work;
1266 const char **mangled;
1275 string_append (tname, "template <");
1276 /* get size of template parameter list */
1277 if (get_count (mangled, &r))
1279 for (i = 0; i < r; i++)
1283 string_append (tname, ", ");
1286 /* Z for type parameters */
1287 if (**mangled == 'Z')
1290 string_append (tname, "class");
1292 /* z for template parameters */
1293 else if (**mangled == 'z')
1297 demangle_template_template_parm (work, mangled, tname);
1305 /* temp is initialized in do_type */
1306 success = do_type (work, mangled, &temp);
1309 string_appends (tname, &temp);
1311 string_delete(&temp);
1321 if (tname->p[-1] == '>')
1322 string_append (tname, " ");
1323 string_append (tname, "> class");
1328 demangle_integral_value (work, mangled, s)
1329 struct work_stuff *work;
1330 const char** mangled;
1335 if (**mangled == 'E')
1337 int need_operator = 0;
1340 string_appendn (s, "(", 1);
1342 while (success && **mangled != 'W' && **mangled != '\0')
1351 len = strlen (*mangled);
1354 i < sizeof (optable) / sizeof (optable [0]);
1357 size_t l = strlen (optable[i].in);
1360 && memcmp (optable[i].in, *mangled, l) == 0)
1362 string_appendn (s, " ", 1);
1363 string_append (s, optable[i].out);
1364 string_appendn (s, " ", 1);
1377 success = demangle_template_value_parm (work, mangled, s,
1381 if (**mangled != 'W')
1385 string_appendn (s, ")", 1);
1389 else if (**mangled == 'Q' || **mangled == 'K')
1390 success = demangle_qualified (work, mangled, s, 0, 1);
1395 if (**mangled == 'm')
1397 string_appendn (s, "-", 1);
1400 while (isdigit ((unsigned char)**mangled))
1402 string_appendn (s, *mangled, 1);
1412 demangle_template_value_parm (work, mangled, s, tk)
1413 struct work_stuff *work;
1414 const char **mangled;
1420 if (**mangled == 'Y')
1422 /* The next argument is a template parameter. */
1426 idx = consume_count_with_underscores (mangled);
1428 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1429 || consume_count_with_underscores (mangled) == -1)
1431 if (work->tmpl_argvec)
1432 string_append (s, work->tmpl_argvec[idx]);
1436 sprintf(buf, "T%d", idx);
1437 string_append (s, buf);
1440 else if (tk == tk_integral)
1441 success = demangle_integral_value (work, mangled, s);
1442 else if (tk == tk_char)
1446 if (**mangled == 'm')
1448 string_appendn (s, "-", 1);
1451 string_appendn (s, "'", 1);
1452 val = consume_count(mangled);
1459 string_appendn (s, &tmp[0], 1);
1460 string_appendn (s, "'", 1);
1463 else if (tk == tk_bool)
1465 int val = consume_count (mangled);
1467 string_appendn (s, "false", 5);
1469 string_appendn (s, "true", 4);
1473 else if (tk == tk_real)
1475 if (**mangled == 'm')
1477 string_appendn (s, "-", 1);
1480 while (isdigit ((unsigned char)**mangled))
1482 string_appendn (s, *mangled, 1);
1485 if (**mangled == '.') /* fraction */
1487 string_appendn (s, ".", 1);
1489 while (isdigit ((unsigned char)**mangled))
1491 string_appendn (s, *mangled, 1);
1495 if (**mangled == 'e') /* exponent */
1497 string_appendn (s, "e", 1);
1499 while (isdigit ((unsigned char)**mangled))
1501 string_appendn (s, *mangled, 1);
1506 else if (tk == tk_pointer || tk == tk_reference)
1508 int symbol_len = consume_count (mangled);
1509 if (symbol_len == -1)
1511 if (symbol_len == 0)
1512 string_appendn (s, "0", 1);
1515 char *p = xmalloc (symbol_len + 1), *q;
1516 strncpy (p, *mangled, symbol_len);
1517 p [symbol_len] = '\0';
1518 /* We use cplus_demangle here, rather than
1519 internal_cplus_demangle, because the name of the entity
1520 mangled here does not make use of any of the squangling
1521 or type-code information we have built up thus far; it is
1522 mangled independently. */
1523 q = cplus_demangle (p, work->options);
1524 if (tk == tk_pointer)
1525 string_appendn (s, "&", 1);
1526 /* FIXME: Pointer-to-member constants should get a
1527 qualifying class name here. */
1530 string_append (s, q);
1534 string_append (s, p);
1537 *mangled += symbol_len;
1543 /* Demangle the template name in MANGLED. The full name of the
1544 template (e.g., S<int>) is placed in TNAME. The name without the
1545 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1546 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1547 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1548 the tmeplate is remembered in the list of back-referenceable
1552 demangle_template (work, mangled, tname, trawname, is_type, remember)
1553 struct work_stuff *work;
1554 const char **mangled;
1565 int is_java_array = 0;
1573 bindex = register_Btype (work);
1575 /* get template name */
1576 if (**mangled == 'z')
1582 idx = consume_count_with_underscores (mangled);
1584 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1585 || consume_count_with_underscores (mangled) == -1)
1588 if (work->tmpl_argvec)
1590 string_append (tname, work->tmpl_argvec[idx]);
1592 string_append (trawname, work->tmpl_argvec[idx]);
1597 sprintf(buf, "T%d", idx);
1598 string_append (tname, buf);
1600 string_append (trawname, buf);
1605 if ((r = consume_count (mangled)) <= 0
1606 || (int) strlen (*mangled) < r)
1610 is_java_array = (work -> options & DMGL_JAVA)
1611 && strncmp (*mangled, "JArray1Z", 8) == 0;
1612 if (! is_java_array)
1614 string_appendn (tname, *mangled, r);
1617 string_appendn (trawname, *mangled, r);
1622 string_append (tname, "<");
1623 /* get size of template parameter list */
1624 if (!get_count (mangled, &r))
1630 /* Create an array for saving the template argument values. */
1631 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1632 work->ntmpl_args = r;
1633 for (i = 0; i < r; i++)
1634 work->tmpl_argvec[i] = 0;
1636 for (i = 0; i < r; i++)
1640 string_append (tname, ", ");
1642 /* Z for type parameters */
1643 if (**mangled == 'Z')
1646 /* temp is initialized in do_type */
1647 success = do_type (work, mangled, &temp);
1650 string_appends (tname, &temp);
1654 /* Save the template argument. */
1655 int len = temp.p - temp.b;
1656 work->tmpl_argvec[i] = xmalloc (len + 1);
1657 memcpy (work->tmpl_argvec[i], temp.b, len);
1658 work->tmpl_argvec[i][len] = '\0';
1661 string_delete(&temp);
1667 /* z for template parameters */
1668 else if (**mangled == 'z')
1672 success = demangle_template_template_parm (work, mangled, tname);
1675 && (r2 = consume_count (mangled)) > 0
1676 && (int) strlen (*mangled) >= r2)
1678 string_append (tname, " ");
1679 string_appendn (tname, *mangled, r2);
1682 /* Save the template argument. */
1684 work->tmpl_argvec[i] = xmalloc (len + 1);
1685 memcpy (work->tmpl_argvec[i], *mangled, len);
1686 work->tmpl_argvec[i][len] = '\0';
1700 /* otherwise, value parameter */
1702 /* temp is initialized in do_type */
1703 success = do_type (work, mangled, &temp);
1704 string_delete(&temp);
1716 success = demangle_template_value_parm (work, mangled, s,
1717 (type_kind_t) success);
1729 int len = s->p - s->b;
1730 work->tmpl_argvec[i] = xmalloc (len + 1);
1731 memcpy (work->tmpl_argvec[i], s->b, len);
1732 work->tmpl_argvec[i][len] = '\0';
1734 string_appends (tname, s);
1742 string_append (tname, "[]");
1746 if (tname->p[-1] == '>')
1747 string_append (tname, " ");
1748 string_append (tname, ">");
1751 if (is_type && remember)
1752 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1755 if (work -> static_type)
1757 string_append (declp, *mangled + 1);
1758 *mangled += strlen (*mangled);
1763 success = demangle_args (work, mangled, declp);
1771 arm_pt (work, mangled, n, anchor, args)
1772 struct work_stuff *work;
1773 const char *mangled;
1775 const char **anchor, **args;
1777 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1778 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1779 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
1782 *args = *anchor + 6;
1783 len = consume_count (args);
1786 if (*args + len == mangled + n && **args == '_')
1792 if (AUTO_DEMANGLING || EDG_DEMANGLING)
1794 if ((*anchor = mystrstr (mangled, "__tm__"))
1795 || (*anchor = mystrstr (mangled, "__ps__"))
1796 || (*anchor = mystrstr (mangled, "__pt__")))
1799 *args = *anchor + 6;
1800 len = consume_count (args);
1803 if (*args + len == mangled + n && **args == '_')
1809 else if ((*anchor = mystrstr (mangled, "__S")))
1812 *args = *anchor + 3;
1813 len = consume_count (args);
1816 if (*args + len == mangled + n && **args == '_')
1828 demangle_arm_hp_template (work, mangled, n, declp)
1829 struct work_stuff *work;
1830 const char **mangled;
1836 const char *e = *mangled + n;
1839 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1841 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
1843 char *start_spec_args = NULL;
1845 /* First check for and omit template specialization pseudo-arguments,
1846 such as in "Spec<#1,#1.*>" */
1847 start_spec_args = strchr (*mangled, '<');
1848 if (start_spec_args && (start_spec_args - *mangled < n))
1849 string_appendn (declp, *mangled, start_spec_args - *mangled);
1851 string_appendn (declp, *mangled, n);
1852 (*mangled) += n + 1;
1854 if (work->temp_start == -1) /* non-recursive call */
1855 work->temp_start = declp->p - declp->b;
1856 string_append (declp, "<");
1859 string_clear (&arg);
1863 /* 'T' signals a type parameter */
1865 if (!do_type (work, mangled, &arg))
1866 goto hpacc_template_args_done;
1871 /* 'U' or 'S' signals an integral value */
1872 if (!do_hpacc_template_const_value (work, mangled, &arg))
1873 goto hpacc_template_args_done;
1877 /* 'A' signals a named constant expression (literal) */
1878 if (!do_hpacc_template_literal (work, mangled, &arg))
1879 goto hpacc_template_args_done;
1883 /* Today, 1997-09-03, we have only the above types
1884 of template parameters */
1885 /* FIXME: maybe this should fail and return null */
1886 goto hpacc_template_args_done;
1888 string_appends (declp, &arg);
1889 /* Check if we're at the end of template args.
1890 0 if at end of static member of template class,
1891 _ if done with template args for a function */
1892 if ((**mangled == '\000') || (**mangled == '_'))
1895 string_append (declp, ",");
1897 hpacc_template_args_done:
1898 string_append (declp, ">");
1899 string_delete (&arg);
1900 if (**mangled == '_')
1904 /* ARM template? (Also handles HP cfront extensions) */
1905 else if (arm_pt (work, *mangled, n, &p, &args))
1910 string_appendn (declp, *mangled, p - *mangled);
1911 if (work->temp_start == -1) /* non-recursive call */
1912 work->temp_start = declp->p - declp->b;
1913 string_append (declp, "<");
1914 /* should do error checking here */
1916 string_clear (&arg);
1918 /* Check for type or literal here */
1921 /* HP cfront extensions to ARM for template args */
1922 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1923 /* FIXME: We handle only numeric literals for HP cfront */
1925 /* A typed constant value follows */
1927 if (!do_type (work, &args, &type_str))
1928 goto cfront_template_args_done;
1929 string_append (&arg, "(");
1930 string_appends (&arg, &type_str);
1931 string_append (&arg, ")");
1933 goto cfront_template_args_done;
1935 /* Now snarf a literal value following 'L' */
1936 if (!snarf_numeric_literal (&args, &arg))
1937 goto cfront_template_args_done;
1941 /* Snarf a literal following 'L' */
1943 if (!snarf_numeric_literal (&args, &arg))
1944 goto cfront_template_args_done;
1947 /* Not handling other HP cfront stuff */
1948 if (!do_type (work, &args, &arg))
1949 goto cfront_template_args_done;
1951 string_appends (declp, &arg);
1952 string_append (declp, ",");
1954 cfront_template_args_done:
1955 string_delete (&arg);
1957 --declp->p; /* remove extra comma */
1958 string_append (declp, ">");
1960 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1961 && (*mangled)[9] == 'N'
1962 && (*mangled)[8] == (*mangled)[10]
1963 && strchr (cplus_markers, (*mangled)[8]))
1965 /* A member of the anonymous namespace. */
1966 string_append (declp, "{anonymous}");
1970 if (work->temp_start == -1) /* non-recursive call only */
1971 work->temp_start = 0; /* disable in recursive calls */
1972 string_appendn (declp, *mangled, n);
1977 /* Extract a class name, possibly a template with arguments, from the
1978 mangled string; qualifiers, local class indicators, etc. have
1979 already been dealt with */
1982 demangle_class_name (work, mangled, declp)
1983 struct work_stuff *work;
1984 const char **mangled;
1990 n = consume_count (mangled);
1993 if ((int) strlen (*mangled) >= n)
1995 demangle_arm_hp_template (work, mangled, n, declp);
2006 demangle_class -- demangle a mangled class sequence
2011 demangle_class (struct work_stuff *work, const char **mangled,
2016 DECLP points to the buffer into which demangling is being done.
2018 *MANGLED points to the current token to be demangled. On input,
2019 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2020 On exit, it points to the next token after the mangled class on
2021 success, or the first unconsumed token on failure.
2023 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2024 we are demangling a constructor or destructor. In this case
2025 we prepend "class::class" or "class::~class" to DECLP.
2027 Otherwise, we prepend "class::" to the current DECLP.
2029 Reset the constructor/destructor flags once they have been
2030 "consumed". This allows demangle_class to be called later during
2031 the same demangling, to do normal class demangling.
2033 Returns 1 if demangling is successful, 0 otherwise.
2038 demangle_class (work, mangled, declp)
2039 struct work_stuff *work;
2040 const char **mangled;
2046 char *save_class_name_end = 0;
2048 string_init (&class_name);
2049 btype = register_Btype (work);
2050 if (demangle_class_name (work, mangled, &class_name))
2052 save_class_name_end = class_name.p;
2053 if ((work->constructor & 1) || (work->destructor & 1))
2055 /* adjust so we don't include template args */
2056 if (work->temp_start && (work->temp_start != -1))
2058 class_name.p = class_name.b + work->temp_start;
2060 string_prepends (declp, &class_name);
2061 if (work -> destructor & 1)
2063 string_prepend (declp, "~");
2064 work -> destructor -= 1;
2068 work -> constructor -= 1;
2071 class_name.p = save_class_name_end;
2072 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2073 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2074 string_prepend (declp, SCOPE_STRING (work));
2075 string_prepends (declp, &class_name);
2078 string_delete (&class_name);
2086 demangle_prefix -- consume the mangled name prefix and find signature
2091 demangle_prefix (struct work_stuff *work, const char **mangled,
2096 Consume and demangle the prefix of the mangled name.
2098 DECLP points to the string buffer into which demangled output is
2099 placed. On entry, the buffer is empty. On exit it contains
2100 the root function name, the demangled operator name, or in some
2101 special cases either nothing or the completely demangled result.
2103 MANGLED points to the current pointer into the mangled name. As each
2104 token of the mangled name is consumed, it is updated. Upon entry
2105 the current mangled name pointer points to the first character of
2106 the mangled name. Upon exit, it should point to the first character
2107 of the signature if demangling was successful, or to the first
2108 unconsumed character if demangling of the prefix was unsuccessful.
2110 Returns 1 on success, 0 otherwise.
2114 demangle_prefix (work, mangled, declp)
2115 struct work_stuff *work;
2116 const char **mangled;
2123 if (strlen(*mangled) > 6
2124 && (strncmp(*mangled, "_imp__", 6) == 0
2125 || strncmp(*mangled, "__imp_", 6) == 0))
2127 /* it's a symbol imported from a PE dynamic library. Check for both
2128 new style prefix _imp__ and legacy __imp_ used by older versions
2131 work->dllimported = 1;
2133 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2135 char *marker = strchr (cplus_markers, (*mangled)[8]);
2136 if (marker != NULL && *marker == (*mangled)[10])
2138 if ((*mangled)[9] == 'D')
2140 /* it's a GNU global destructor to be executed at program exit */
2142 work->destructor = 2;
2143 if (gnu_special (work, mangled, declp))
2146 else if ((*mangled)[9] == 'I')
2148 /* it's a GNU global constructor to be executed at program init */
2150 work->constructor = 2;
2151 if (gnu_special (work, mangled, declp))
2156 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2158 /* it's a ARM global destructor to be executed at program exit */
2160 work->destructor = 2;
2162 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2164 /* it's a ARM global constructor to be executed at program initial */
2166 work->constructor = 2;
2169 /* This block of code is a reduction in strength time optimization
2171 scan = mystrstr (*mangled, "__"); */
2177 scan = strchr (scan, '_');
2178 } while (scan != NULL && *++scan != '_');
2180 if (scan != NULL) --scan;
2185 /* We found a sequence of two or more '_', ensure that we start at
2186 the last pair in the sequence. */
2187 i = strspn (scan, "_");
2198 else if (work -> static_type)
2200 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
2205 else if ((scan == *mangled)
2206 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
2207 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2209 /* The ARM says nothing about the mangling of local variables.
2210 But cfront mangles local variables by prepending __<nesting_level>
2211 to them. As an extension to ARM demangling we handle this case. */
2212 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2213 && isdigit ((unsigned char)scan[2]))
2215 *mangled = scan + 2;
2216 consume_count (mangled);
2217 string_append (declp, *mangled);
2218 *mangled += strlen (*mangled);
2223 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2224 names like __Q2_3foo3bar for nested type names. So don't accept
2225 this style of constructor for cfront demangling. A GNU
2226 style member-template constructor starts with 'H'. */
2227 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2228 work -> constructor += 1;
2229 *mangled = scan + 2;
2232 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2234 /* Cfront-style parameterized type. Handled later as a signature. */
2238 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2240 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2241 || (scan[2] == 'p' && scan[3] == 's')
2242 || (scan[2] == 'p' && scan[3] == 't')))
2244 /* EDG-style parameterized type. Handled later as a signature. */
2248 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2250 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
2251 && (scan[2] != 't'))
2253 /* Mangled name starts with "__". Skip over any leading '_' characters,
2254 then find the next "__" that separates the prefix from the signature.
2256 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2257 || (arm_special (mangled, declp) == 0))
2259 while (*scan == '_')
2263 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2265 /* No separator (I.E. "__not_mangled"), or empty signature
2266 (I.E. "__not_mangled_either__") */
2273 /* Look for the LAST occurrence of __, allowing names to
2274 have the '__' sequence embedded in them. */
2275 if (!(ARM_DEMANGLING || HP_DEMANGLING))
2277 while ((tmp = mystrstr (scan + 2, "__")) != NULL)
2280 if (*(scan + 2) == '\0')
2283 demangle_function_name (work, mangled, declp, scan);
2287 else if (*(scan + 2) != '\0')
2289 /* Mangled name does not start with "__" but does have one somewhere
2290 in there with non empty stuff after it. Looks like a global
2292 demangle_function_name (work, mangled, declp, scan);
2296 /* Doesn't look like a mangled name */
2300 if (!success && (work->constructor == 2 || work->destructor == 2))
2302 string_append (declp, *mangled);
2303 *mangled += strlen (*mangled);
2313 gnu_special -- special handling of gnu mangled strings
2318 gnu_special (struct work_stuff *work, const char **mangled,
2324 Process some special GNU style mangling forms that don't fit
2325 the normal pattern. For example:
2327 _$_3foo (destructor for class foo)
2328 _vt$foo (foo virtual table)
2329 _vt$foo$bar (foo::bar virtual table)
2330 __vt_foo (foo virtual table, new style with thunks)
2331 _3foo$varname (static data member)
2332 _Q22rs2tu$vw (static data member)
2333 __t6vector1Zii (constructor with template)
2334 __thunk_4__$_7ostream (virtual function thunk)
2338 gnu_special (work, mangled, declp)
2339 struct work_stuff *work;
2340 const char **mangled;
2347 if ((*mangled)[0] == '_'
2348 && strchr (cplus_markers, (*mangled)[1]) != NULL
2349 && (*mangled)[2] == '_')
2351 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2353 work -> destructor += 1;
2355 else if ((*mangled)[0] == '_'
2356 && (((*mangled)[1] == '_'
2357 && (*mangled)[2] == 'v'
2358 && (*mangled)[3] == 't'
2359 && (*mangled)[4] == '_')
2360 || ((*mangled)[1] == 'v'
2361 && (*mangled)[2] == 't'
2362 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2364 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2365 and create the decl. Note that we consume the entire mangled
2366 input string, which means that demangle_signature has no work
2368 if ((*mangled)[2] == 'v')
2369 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2371 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2372 while (**mangled != '\0')
2378 success = demangle_qualified (work, mangled, declp, 0, 1);
2381 success = demangle_template (work, mangled, declp, 0, 1,
2385 if (isdigit((unsigned char)*mangled[0]))
2387 n = consume_count(mangled);
2388 /* We may be seeing a too-large size, or else a
2389 ".<digits>" indicating a static local symbol. In
2390 any case, declare victory and move on; *don't* try
2391 to use n to allocate. */
2392 if (n > (int) strlen (*mangled))
2400 n = strcspn (*mangled, cplus_markers);
2402 string_appendn (declp, *mangled, n);
2406 p = strpbrk (*mangled, cplus_markers);
2407 if (success && ((p == NULL) || (p == *mangled)))
2411 string_append (declp, SCOPE_STRING (work));
2422 string_append (declp, " virtual table");
2424 else if ((*mangled)[0] == '_'
2425 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2426 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2428 /* static data member, "_3foo$varname" for example */
2434 success = demangle_qualified (work, mangled, declp, 0, 1);
2437 success = demangle_template (work, mangled, declp, 0, 1, 1);
2440 n = consume_count (mangled);
2441 if (n < 0 || n > strlen (*mangled))
2446 string_appendn (declp, *mangled, n);
2449 if (success && (p == *mangled))
2451 /* Consumed everything up to the cplus_marker, append the
2454 string_append (declp, SCOPE_STRING (work));
2455 n = strlen (*mangled);
2456 string_appendn (declp, *mangled, n);
2464 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2469 delta = consume_count (mangled);
2474 char *method = internal_cplus_demangle (work, ++*mangled);
2479 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2480 string_append (declp, buf);
2481 string_append (declp, method);
2483 n = strlen (*mangled);
2492 else if (strncmp (*mangled, "__t", 3) == 0
2493 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2495 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2501 success = demangle_qualified (work, mangled, declp, 0, 1);
2504 success = demangle_template (work, mangled, declp, 0, 1, 1);
2507 success = demangle_fund_type (work, mangled, declp);
2510 if (success && **mangled != '\0')
2513 string_append (declp, p);
2523 recursively_demangle(work, mangled, result, namelength)
2524 struct work_stuff *work;
2525 const char **mangled;
2529 char * recurse = (char *)NULL;
2530 char * recurse_dem = (char *)NULL;
2532 recurse = (char *) xmalloc (namelength + 1);
2533 memcpy (recurse, *mangled, namelength);
2534 recurse[namelength] = '\000';
2536 recurse_dem = cplus_demangle (recurse, work->options);
2540 string_append (result, recurse_dem);
2545 string_appendn (result, *mangled, namelength);
2548 *mangled += namelength;
2555 arm_special -- special handling of ARM/lucid mangled strings
2560 arm_special (const char **mangled,
2566 Process some special ARM style mangling forms that don't fit
2567 the normal pattern. For example:
2569 __vtbl__3foo (foo virtual table)
2570 __vtbl__3foo__3bar (bar::foo virtual table)
2575 arm_special (mangled, declp)
2576 const char **mangled;
2583 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2585 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2586 and create the decl. Note that we consume the entire mangled
2587 input string, which means that demangle_signature has no work
2589 scan = *mangled + ARM_VTABLE_STRLEN;
2590 while (*scan != '\0') /* first check it can be demangled */
2592 n = consume_count (&scan);
2595 return (0); /* no good */
2598 if (scan[0] == '_' && scan[1] == '_')
2603 (*mangled) += ARM_VTABLE_STRLEN;
2604 while (**mangled != '\0')
2606 n = consume_count (mangled);
2608 || n > strlen (*mangled))
2610 string_prependn (declp, *mangled, n);
2612 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2614 string_prepend (declp, "::");
2618 string_append (declp, " virtual table");
2631 demangle_qualified -- demangle 'Q' qualified name strings
2636 demangle_qualified (struct work_stuff *, const char *mangled,
2637 string *result, int isfuncname, int append);
2641 Demangle a qualified name, such as "Q25Outer5Inner" which is
2642 the mangled form of "Outer::Inner". The demangled output is
2643 prepended or appended to the result string according to the
2644 state of the append flag.
2646 If isfuncname is nonzero, then the qualified name we are building
2647 is going to be used as a member function name, so if it is a
2648 constructor or destructor function, append an appropriate
2649 constructor or destructor name. I.E. for the above example,
2650 the result for use as a constructor is "Outer::Inner::Inner"
2651 and the result for use as a destructor is "Outer::Inner::~Inner".
2655 Numeric conversion is ASCII dependent (FIXME).
2660 demangle_qualified (work, mangled, result, isfuncname, append)
2661 struct work_stuff *work;
2662 const char **mangled;
2673 int bindex = register_Btype (work);
2675 /* We only make use of ISFUNCNAME if the entity is a constructor or
2677 isfuncname = (isfuncname
2678 && ((work->constructor & 1) || (work->destructor & 1)));
2680 string_init (&temp);
2681 string_init (&last_name);
2683 if ((*mangled)[0] == 'K')
2685 /* Squangling qualified name reuse */
2688 idx = consume_count_with_underscores (mangled);
2689 if (idx == -1 || idx >= work -> numk)
2692 string_append (&temp, work -> ktypevec[idx]);
2695 switch ((*mangled)[1])
2698 /* GNU mangled name with more than 9 classes. The count is preceded
2699 by an underscore (to distinguish it from the <= 9 case) and followed
2700 by an underscore. */
2702 qualifiers = atoi (p);
2703 if (!isdigit ((unsigned char)*p) || *p == '0')
2706 /* Skip the digits. */
2707 while (isdigit ((unsigned char)*p))
2725 /* The count is in a single digit. */
2726 num[0] = (*mangled)[1];
2728 qualifiers = atoi (num);
2730 /* If there is an underscore after the digit, skip it. This is
2731 said to be for ARM-qualified names, but the ARM makes no
2732 mention of such an underscore. Perhaps cfront uses one. */
2733 if ((*mangled)[2] == '_')
2748 /* Pick off the names and collect them in the temp buffer in the order
2749 in which they are found, separated by '::'. */
2751 while (qualifiers-- > 0)
2754 string_clear (&last_name);
2756 if (*mangled[0] == '_')
2759 if (*mangled[0] == 't')
2761 /* Here we always append to TEMP since we will want to use
2762 the template name without the template parameters as a
2763 constructor or destructor name. The appropriate
2764 (parameter-less) value is returned by demangle_template
2765 in LAST_NAME. We do not remember the template type here,
2766 in order to match the G++ mangling algorithm. */
2767 success = demangle_template(work, mangled, &temp,
2772 else if (*mangled[0] == 'K')
2776 idx = consume_count_with_underscores (mangled);
2777 if (idx == -1 || idx >= work->numk)
2780 string_append (&temp, work->ktypevec[idx]);
2783 if (!success) break;
2790 /* Now recursively demangle the qualifier
2791 * This is necessary to deal with templates in
2792 * mangling styles like EDG */
2793 namelength = consume_count (mangled);
2794 if (namelength == -1)
2799 recursively_demangle(work, mangled, &temp, namelength);
2803 success = do_type (work, mangled, &last_name);
2806 string_appends (&temp, &last_name);
2811 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2814 string_append (&temp, SCOPE_STRING (work));
2817 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2819 /* If we are using the result as a function name, we need to append
2820 the appropriate '::' separated constructor or destructor name.
2821 We do this here because this is the most convenient place, where
2822 we already have a pointer to the name and the length of the name. */
2826 string_append (&temp, SCOPE_STRING (work));
2827 if (work -> destructor & 1)
2828 string_append (&temp, "~");
2829 string_appends (&temp, &last_name);
2832 /* Now either prepend the temp buffer to the result, or append it,
2833 depending upon the state of the append flag. */
2836 string_appends (result, &temp);
2839 if (!STRING_EMPTY (result))
2840 string_append (&temp, SCOPE_STRING (work));
2841 string_prepends (result, &temp);
2844 string_delete (&last_name);
2845 string_delete (&temp);
2853 get_count -- convert an ascii count to integer, consuming tokens
2858 get_count (const char **type, int *count)
2862 Assume that *type points at a count in a mangled name; set
2863 *count to its value, and set *type to the next character after
2864 the count. There are some weird rules in effect here.
2866 If *type does not point at a string of digits, return zero.
2868 If *type points at a string of digits followed by an
2869 underscore, set *count to their value as an integer, advance
2870 *type to point *after the underscore, and return 1.
2872 If *type points at a string of digits not followed by an
2873 underscore, consume only the first digit. Set *count to its
2874 value as an integer, leave *type pointing after that digit,
2877 The excuse for this odd behavior: in the ARM and HP demangling
2878 styles, a type can be followed by a repeat count of the form
2881 `x' is a single digit specifying how many additional copies
2882 of the type to append to the argument list, and
2884 `y' is one or more digits, specifying the zero-based index of
2885 the first repeated argument in the list. Yes, as you're
2886 unmangling the name you can figure this out yourself, but
2889 So, for example, in `bar__3fooFPiN51', the first argument is a
2890 pointer to an integer (`Pi'), and then the next five arguments
2891 are the same (`N5'), and the first repeat is the function's
2892 second argument (`1').
2896 get_count (type, count)
2903 if (!isdigit ((unsigned char)**type))
2909 *count = **type - '0';
2911 if (isdigit ((unsigned char)**type))
2921 while (isdigit ((unsigned char)*p));
2932 /* RESULT will be initialised here; it will be freed on failure. The
2933 value returned is really a type_kind_t. */
2936 do_type (work, mangled, result)
2937 struct work_stuff *work;
2938 const char **mangled;
2945 const char *remembered_type;
2948 type_kind_t tk = tk_none;
2950 string_init (&btype);
2951 string_init (&decl);
2952 string_init (result);
2956 while (success && !done)
2962 /* A pointer type */
2966 if (! (work -> options & DMGL_JAVA))
2967 string_prepend (&decl, "*");
2972 /* A reference type */
2975 string_prepend (&decl, "&");
2984 if (!STRING_EMPTY (&decl)
2985 && (decl.b[0] == '*' || decl.b[0] == '&'))
2987 string_prepend (&decl, "(");
2988 string_append (&decl, ")");
2990 string_append (&decl, "[");
2991 if (**mangled != '_')
2992 success = demangle_template_value_parm (work, mangled, &decl,
2994 if (**mangled == '_')
2996 string_append (&decl, "]");
3000 /* A back reference to a previously seen type */
3003 if (!get_count (mangled, &n) || n >= work -> ntypes)
3009 remembered_type = work -> typevec[n];
3010 mangled = &remembered_type;
3017 if (!STRING_EMPTY (&decl)
3018 && (decl.b[0] == '*' || decl.b[0] == '&'))
3020 string_prepend (&decl, "(");
3021 string_append (&decl, ")");
3023 /* After picking off the function args, we expect to either find the
3024 function return type (preceded by an '_') or the end of the
3026 if (!demangle_nested_args (work, mangled, &decl)
3027 || (**mangled != '_' && **mangled != '\0'))
3032 if (success && (**mangled == '_'))
3039 type_quals = TYPE_UNQUALIFIED;
3041 member = **mangled == 'M';
3043 if (!isdigit ((unsigned char)**mangled) && **mangled != 't')
3049 string_append (&decl, ")");
3050 string_prepend (&decl, SCOPE_STRING (work));
3051 if (isdigit ((unsigned char)**mangled))
3053 n = consume_count (mangled);
3055 || (int) strlen (*mangled) < n)
3060 string_prependn (&decl, *mangled, n);
3066 string_init (&temp);
3067 success = demangle_template (work, mangled, &temp,
3071 string_prependn (&decl, temp.b, temp.p - temp.b);
3072 string_clear (&temp);
3077 string_prepend (&decl, "(");
3085 type_quals |= code_for_qualifier (**mangled);
3093 if (*(*mangled)++ != 'F')
3099 if ((member && !demangle_nested_args (work, mangled, &decl))
3100 || **mangled != '_')
3106 if (! PRINT_ANSI_QUALIFIERS)
3110 if (type_quals != TYPE_UNQUALIFIED)
3112 APPEND_BLANK (&decl);
3113 string_append (&decl, qualifier_string (type_quals));
3124 if (PRINT_ANSI_QUALIFIERS)
3126 if (!STRING_EMPTY (&decl))
3127 string_prepend (&decl, " ");
3129 string_prepend (&decl, demangle_qualifier (**mangled));
3144 if (success) switch (**mangled)
3146 /* A qualified name, such as "Outer::Inner". */
3150 success = demangle_qualified (work, mangled, result, 0, 1);
3154 /* A back reference to a previously seen squangled type */
3157 if (!get_count (mangled, &n) || n >= work -> numb)
3160 string_append (result, work->btypevec[n]);
3165 /* A template parm. We substitute the corresponding argument. */
3170 idx = consume_count_with_underscores (mangled);
3173 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3174 || consume_count_with_underscores (mangled) == -1)
3180 if (work->tmpl_argvec)
3181 string_append (result, work->tmpl_argvec[idx]);
3185 sprintf(buf, "T%d", idx);
3186 string_append (result, buf);
3194 success = demangle_fund_type (work, mangled, result);
3196 tk = (type_kind_t) success;
3202 if (!STRING_EMPTY (&decl))
3204 string_append (result, " ");
3205 string_appends (result, &decl);
3209 string_delete (result);
3210 string_delete (&decl);
3213 /* Assume an integral type, if we're not sure. */
3214 return (int) ((tk == tk_none) ? tk_integral : tk);
3219 /* Given a pointer to a type string that represents a fundamental type
3220 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3221 string in which the demangled output is being built in RESULT, and
3222 the WORK structure, decode the types and add them to the result.
3227 "Sl" => "signed long"
3228 "CUs" => "const unsigned short"
3230 The value returned is really a type_kind_t. */
3233 demangle_fund_type (work, mangled, result)
3234 struct work_stuff *work;
3235 const char **mangled;
3243 type_kind_t tk = tk_integral;
3245 string_init (&btype);
3247 /* First pick off any type qualifiers. There can be more than one. */
3256 if (PRINT_ANSI_QUALIFIERS)
3258 if (!STRING_EMPTY (result))
3259 string_prepend (result, " ");
3260 string_prepend (result, demangle_qualifier (**mangled));
3266 APPEND_BLANK (result);
3267 string_append (result, "unsigned");
3269 case 'S': /* signed char only */
3271 APPEND_BLANK (result);
3272 string_append (result, "signed");
3276 APPEND_BLANK (result);
3277 string_append (result, "__complex");
3285 /* Now pick off the fundamental type. There can be only one. */
3294 APPEND_BLANK (result);
3295 string_append (result, "void");
3299 APPEND_BLANK (result);
3300 string_append (result, "long long");
3304 APPEND_BLANK (result);
3305 string_append (result, "long");
3309 APPEND_BLANK (result);
3310 string_append (result, "int");
3314 APPEND_BLANK (result);
3315 string_append (result, "short");
3319 APPEND_BLANK (result);
3320 string_append (result, "bool");
3325 APPEND_BLANK (result);
3326 string_append (result, "char");
3331 APPEND_BLANK (result);
3332 string_append (result, "wchar_t");
3337 APPEND_BLANK (result);
3338 string_append (result, "long double");
3343 APPEND_BLANK (result);
3344 string_append (result, "double");
3349 APPEND_BLANK (result);
3350 string_append (result, "float");
3355 if (!isdigit ((unsigned char)**mangled))
3362 if (**mangled == '_')
3366 for (i = 0; **mangled != '_'; ++(*mangled), ++i)
3373 strncpy (buf, *mangled, 2);
3376 sscanf (buf, "%x", &dec);
3377 sprintf (buf, "int%i_t", dec);
3378 APPEND_BLANK (result);
3379 string_append (result, buf);
3383 /* An explicit type, such as "6mytype" or "7integer" */
3395 int bindex = register_Btype (work);
3397 string_init (&btype);
3398 if (demangle_class_name (work, mangled, &btype)) {
3399 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3400 APPEND_BLANK (result);
3401 string_appends (result, &btype);
3405 string_delete (&btype);
3410 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3411 string_appends (result, &btype);
3419 return success ? ((int) tk) : 0;
3423 /* Handle a template's value parameter for HP aCC (extension from ARM)
3424 **mangled points to 'S' or 'U' */
3427 do_hpacc_template_const_value (work, mangled, result)
3428 struct work_stuff *work;
3429 const char **mangled;
3434 if (**mangled != 'U' && **mangled != 'S')
3437 unsigned_const = (**mangled == 'U');
3444 string_append (result, "-");
3450 /* special case for -2^31 */
3451 string_append (result, "-2147483648");
3458 /* We have to be looking at an integer now */
3459 if (!(isdigit ((unsigned char)**mangled)))
3462 /* We only deal with integral values for template
3463 parameters -- so it's OK to look only for digits */
3464 while (isdigit ((unsigned char)**mangled))
3466 char_str[0] = **mangled;
3467 string_append (result, char_str);
3472 string_append (result, "U");
3474 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3475 with L or LL suffixes. pai/1997-09-03 */
3477 return 1; /* success */
3480 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3481 **mangled is pointing to the 'A' */
3484 do_hpacc_template_literal (work, mangled, result)
3485 struct work_stuff *work;
3486 const char **mangled;
3489 int literal_len = 0;
3493 if (**mangled != 'A')
3498 literal_len = consume_count (mangled);
3500 if (literal_len <= 0)
3503 /* Literal parameters are names of arrays, functions, etc. and the
3504 canonical representation uses the address operator */
3505 string_append (result, "&");
3507 /* Now recursively demangle the literal name */
3508 recurse = (char *) xmalloc (literal_len + 1);
3509 memcpy (recurse, *mangled, literal_len);
3510 recurse[literal_len] = '\000';
3512 recurse_dem = cplus_demangle (recurse, work->options);
3516 string_append (result, recurse_dem);
3521 string_appendn (result, *mangled, literal_len);
3523 (*mangled) += literal_len;
3530 snarf_numeric_literal (args, arg)
3537 string_append (arg, char_str);
3540 else if (**args == '+')
3543 if (!isdigit ((unsigned char)**args))
3546 while (isdigit ((unsigned char)**args))
3548 char_str[0] = **args;
3549 string_append (arg, char_str);
3556 /* Demangle the next argument, given by MANGLED into RESULT, which
3557 *should be an uninitialized* string. It will be initialized here,
3558 and free'd should anything go wrong. */
3561 do_arg (work, mangled, result)
3562 struct work_stuff *work;
3563 const char **mangled;
3566 /* Remember where we started so that we can record the type, for
3567 non-squangling type remembering. */
3568 const char *start = *mangled;
3570 string_init (result);
3572 if (work->nrepeats > 0)
3576 if (work->previous_argument == 0)
3579 /* We want to reissue the previous type in this argument list. */
3580 string_appends (result, work->previous_argument);
3584 if (**mangled == 'n')
3586 /* A squangling-style repeat. */
3588 work->nrepeats = consume_count(mangled);
3590 if (work->nrepeats <= 0)
3591 /* This was not a repeat count after all. */
3594 if (work->nrepeats > 9)
3596 if (**mangled != '_')
3597 /* The repeat count should be followed by an '_' in this
3604 /* Now, the repeat is all set up. */
3605 return do_arg (work, mangled, result);
3608 /* Save the result in WORK->previous_argument so that we can find it
3609 if it's repeated. Note that saving START is not good enough: we
3610 do not want to add additional types to the back-referenceable
3611 type vector when processing a repeated type. */
3612 if (work->previous_argument)
3613 string_clear (work->previous_argument);
3616 work->previous_argument = (string*) xmalloc (sizeof (string));
3617 string_init (work->previous_argument);
3620 if (!do_type (work, mangled, work->previous_argument))
3623 string_appends (result, work->previous_argument);
3625 remember_type (work, start, *mangled - start);
3630 remember_type (work, start, len)
3631 struct work_stuff *work;
3637 if (work->forgetting_types)
3640 if (work -> ntypes >= work -> typevec_size)
3642 if (work -> typevec_size == 0)
3644 work -> typevec_size = 3;
3646 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3650 work -> typevec_size *= 2;
3652 = (char **) xrealloc ((char *)work -> typevec,
3653 sizeof (char *) * work -> typevec_size);
3656 tem = xmalloc (len + 1);
3657 memcpy (tem, start, len);
3659 work -> typevec[work -> ntypes++] = tem;
3663 /* Remember a K type class qualifier. */
3665 remember_Ktype (work, start, len)
3666 struct work_stuff *work;
3672 if (work -> numk >= work -> ksize)
3674 if (work -> ksize == 0)
3678 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3684 = (char **) xrealloc ((char *)work -> ktypevec,
3685 sizeof (char *) * work -> ksize);
3688 tem = xmalloc (len + 1);
3689 memcpy (tem, start, len);
3691 work -> ktypevec[work -> numk++] = tem;
3694 /* Register a B code, and get an index for it. B codes are registered
3695 as they are seen, rather than as they are completed, so map<temp<char> >
3696 registers map<temp<char> > as B0, and temp<char> as B1 */
3699 register_Btype (work)
3700 struct work_stuff *work;
3704 if (work -> numb >= work -> bsize)
3706 if (work -> bsize == 0)
3710 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3716 = (char **) xrealloc ((char *)work -> btypevec,
3717 sizeof (char *) * work -> bsize);
3720 ret = work -> numb++;
3721 work -> btypevec[ret] = NULL;
3725 /* Store a value into a previously registered B code type. */
3728 remember_Btype (work, start, len, index)
3729 struct work_stuff *work;
3735 tem = xmalloc (len + 1);
3736 memcpy (tem, start, len);
3738 work -> btypevec[index] = tem;
3741 /* Lose all the info related to B and K type codes. */
3743 forget_B_and_K_types (work)
3744 struct work_stuff *work;
3748 while (work -> numk > 0)
3750 i = --(work -> numk);
3751 if (work -> ktypevec[i] != NULL)
3753 free (work -> ktypevec[i]);
3754 work -> ktypevec[i] = NULL;
3758 while (work -> numb > 0)
3760 i = --(work -> numb);
3761 if (work -> btypevec[i] != NULL)
3763 free (work -> btypevec[i]);
3764 work -> btypevec[i] = NULL;
3768 /* Forget the remembered types, but not the type vector itself. */
3772 struct work_stuff *work;
3776 while (work -> ntypes > 0)
3778 i = --(work -> ntypes);
3779 if (work -> typevec[i] != NULL)
3781 free (work -> typevec[i]);
3782 work -> typevec[i] = NULL;
3787 /* Process the argument list part of the signature, after any class spec
3788 has been consumed, as well as the first 'F' character (if any). For
3791 "__als__3fooRT0" => process "RT0"
3792 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3794 DECLP must be already initialised, usually non-empty. It won't be freed
3797 Note that g++ differs significantly from ARM and lucid style mangling
3798 with regards to references to previously seen types. For example, given
3799 the source fragment:
3803 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3806 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3807 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3809 g++ produces the names:
3814 while lcc (and presumably other ARM style compilers as well) produces:
3816 foo__FiR3fooT1T2T1T2
3817 __ct__3fooFiR3fooT1T2T1T2
3819 Note that g++ bases its type numbers starting at zero and counts all
3820 previously seen types, while lucid/ARM bases its type numbers starting
3821 at one and only considers types after it has seen the 'F' character
3822 indicating the start of the function args. For lucid/ARM style, we
3823 account for this difference by discarding any previously seen types when
3824 we see the 'F' character, and subtracting one from the type number
3830 demangle_args (work, mangled, declp)
3831 struct work_stuff *work;
3832 const char **mangled;
3842 if (PRINT_ARG_TYPES)
3844 string_append (declp, "(");
3845 if (**mangled == '\0')
3847 string_append (declp, "void");
3851 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3852 || work->nrepeats > 0)
3854 if ((**mangled == 'N') || (**mangled == 'T'))
3856 temptype = *(*mangled)++;
3858 if (temptype == 'N')
3860 if (!get_count (mangled, &r))
3869 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
3871 /* If we have 10 or more types we might have more than a 1 digit
3872 index so we'll have to consume the whole count here. This
3873 will lose if the next thing is a type name preceded by a
3874 count but it's impossible to demangle that case properly
3875 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3876 Pc, ...)" or "(..., type12, char *, ...)" */
3877 if ((t = consume_count(mangled)) <= 0)
3884 if (!get_count (mangled, &t))
3889 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3893 /* Validate the type index. Protect against illegal indices from
3894 malformed type strings. */
3895 if ((t < 0) || (t >= work -> ntypes))
3899 while (work->nrepeats > 0 || --r >= 0)
3901 tem = work -> typevec[t];
3902 if (need_comma && PRINT_ARG_TYPES)
3904 string_append (declp, ", ");
3906 if (!do_arg (work, &tem, &arg))
3910 if (PRINT_ARG_TYPES)
3912 string_appends (declp, &arg);
3914 string_delete (&arg);
3920 if (need_comma && PRINT_ARG_TYPES)
3921 string_append (declp, ", ");
3922 if (!do_arg (work, mangled, &arg))
3924 if (PRINT_ARG_TYPES)
3925 string_appends (declp, &arg);
3926 string_delete (&arg);
3931 if (**mangled == 'e')
3934 if (PRINT_ARG_TYPES)
3938 string_append (declp, ",");
3940 string_append (declp, "...");
3944 if (PRINT_ARG_TYPES)
3946 string_append (declp, ")");
3951 /* Like demangle_args, but for demangling the argument lists of function
3952 and method pointers or references, not top-level declarations. */
3955 demangle_nested_args (work, mangled, declp)
3956 struct work_stuff *work;
3957 const char **mangled;
3960 string* saved_previous_argument;
3964 /* The G++ name-mangling algorithm does not remember types on nested
3965 argument lists, unless -fsquangling is used, and in that case the
3966 type vector updated by remember_type is not used. So, we turn
3967 off remembering of types here. */
3968 ++work->forgetting_types;
3970 /* For the repeat codes used with -fsquangling, we must keep track of
3971 the last argument. */
3972 saved_previous_argument = work->previous_argument;
3973 saved_nrepeats = work->nrepeats;
3974 work->previous_argument = 0;
3977 /* Actually demangle the arguments. */
3978 result = demangle_args (work, mangled, declp);
3980 /* Restore the previous_argument field. */
3981 if (work->previous_argument)
3982 string_delete (work->previous_argument);
3983 work->previous_argument = saved_previous_argument;
3984 --work->forgetting_types;
3985 work->nrepeats = saved_nrepeats;
3991 demangle_function_name (work, mangled, declp, scan)
3992 struct work_stuff *work;
3993 const char **mangled;
4001 string_appendn (declp, (*mangled), scan - (*mangled));
4002 string_need (declp, 1);
4003 *(declp -> p) = '\0';
4005 /* Consume the function name, including the "__" separating the name
4006 from the signature. We are guaranteed that SCAN points to the
4009 (*mangled) = scan + 2;
4010 /* We may be looking at an instantiation of a template function:
4011 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4012 following _F marks the start of the function arguments. Handle
4013 the template arguments first. */
4015 if (HP_DEMANGLING && (**mangled == 'X'))
4017 demangle_arm_hp_template (work, mangled, 0, declp);
4018 /* This leaves MANGLED pointing to the 'F' marking func args */
4021 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4024 /* See if we have an ARM style constructor or destructor operator.
4025 If so, then just record it, clear the decl, and return.
4026 We can't build the actual constructor/destructor decl until later,
4027 when we recover the class name from the signature. */
4029 if (strcmp (declp -> b, "__ct") == 0)
4031 work -> constructor += 1;
4032 string_clear (declp);
4035 else if (strcmp (declp -> b, "__dt") == 0)
4037 work -> destructor += 1;
4038 string_clear (declp);
4043 if (declp->p - declp->b >= 3
4044 && declp->b[0] == 'o'
4045 && declp->b[1] == 'p'
4046 && strchr (cplus_markers, declp->b[2]) != NULL)
4048 /* see if it's an assignment expression */
4049 if (declp->p - declp->b >= 10 /* op$assign_ */
4050 && memcmp (declp->b + 3, "assign_", 7) == 0)
4052 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4054 int len = declp->p - declp->b - 10;
4055 if ((int) strlen (optable[i].in) == len
4056 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4058 string_clear (declp);
4059 string_append (declp, "operator");
4060 string_append (declp, optable[i].out);
4061 string_append (declp, "=");
4068 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4070 int len = declp->p - declp->b - 3;
4071 if ((int) strlen (optable[i].in) == len
4072 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4074 string_clear (declp);
4075 string_append (declp, "operator");
4076 string_append (declp, optable[i].out);
4082 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4083 && strchr (cplus_markers, declp->b[4]) != NULL)
4085 /* type conversion operator */
4087 if (do_type (work, &tem, &type))
4089 string_clear (declp);
4090 string_append (declp, "operator ");
4091 string_appends (declp, &type);
4092 string_delete (&type);
4095 else if (declp->b[0] == '_' && declp->b[1] == '_'
4096 && declp->b[2] == 'o' && declp->b[3] == 'p')
4099 /* type conversion operator. */
4101 if (do_type (work, &tem, &type))
4103 string_clear (declp);
4104 string_append (declp, "operator ");
4105 string_appends (declp, &type);
4106 string_delete (&type);
4109 else if (declp->b[0] == '_' && declp->b[1] == '_'
4110 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
4111 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
4113 if (declp->b[4] == '\0')
4116 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4118 if (strlen (optable[i].in) == 2
4119 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4121 string_clear (declp);
4122 string_append (declp, "operator");
4123 string_append (declp, optable[i].out);
4130 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4133 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4135 if (strlen (optable[i].in) == 3
4136 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4138 string_clear (declp);
4139 string_append (declp, "operator");
4140 string_append (declp, optable[i].out);
4149 /* a mini string-handling package */
4164 s->p = s->b = xmalloc (n);
4167 else if (s->e - s->p < n)
4172 s->b = xrealloc (s->b, n);
4185 s->b = s->e = s->p = NULL;
4193 s->b = s->p = s->e = NULL;
4209 return (s->b == s->p);
4215 string_append (p, s)
4220 if (s == NULL || *s == '\0')
4224 memcpy (p->p, s, n);
4229 string_appends (p, s)
4238 memcpy (p->p, s->b, n);
4244 string_appendn (p, s, n)
4252 memcpy (p->p, s, n);
4258 string_prepend (p, s)
4262 if (s != NULL && *s != '\0')
4264 string_prependn (p, s, strlen (s));
4269 string_prepends (p, s)
4274 string_prependn (p, s->b, s->p - s->b);
4279 string_prependn (p, s, n)
4289 for (q = p->p - 1; q >= p->b; q--)
4293 memcpy (p->b, s, n);
4298 /* To generate a standalone demangler program for testing purposes,
4299 just compile and link this file with -DMAIN and libiberty.a. When
4300 run, it demangles each command line arg, or each stdin string, and
4301 prints the result on stdout. */
4307 static char *program_name;
4308 static char *program_version = VERSION;
4309 static int flags = DMGL_PARAMS | DMGL_ANSI;
4311 static void demangle_it PARAMS ((char *));
4312 static void usage PARAMS ((FILE *, int));
4313 static void fatal PARAMS ((char *));
4316 demangle_it (mangled_name)
4321 result = cplus_demangle (mangled_name, flags);
4324 printf ("%s\n", mangled_name);
4328 printf ("%s\n", result);
4334 usage (stream, status)
4339 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4340 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4341 [--help] [--version] [arg...]\n",
4346 #define MBUF_SIZE 32767
4347 char mbuffer[MBUF_SIZE];
4349 /* Defined in the automatically-generated underscore.c. */
4350 extern int prepends_underscore;
4352 int strip_underscore = 0;
4354 static struct option long_options[] = {
4355 {"strip-underscores", no_argument, 0, '_'},
4356 {"format", required_argument, 0, 's'},
4357 {"help", no_argument, 0, 'h'},
4358 {"java", no_argument, 0, 'j'},
4359 {"no-strip-underscores", no_argument, 0, 'n'},
4360 {"version", no_argument, 0, 'v'},
4361 {0, no_argument, 0, 0}
4364 /* More 'friendly' abort that prints the line and file.
4365 config.h can #define abort fancy_abort if you like that sort of thing. */
4370 fatal ("Internal gcc abort.");
4381 program_name = argv[0];
4383 strip_underscore = prepends_underscore;
4385 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
4395 strip_underscore = 0;
4398 printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
4401 strip_underscore = 1;
4407 if (strcmp (optarg, "gnu") == 0)
4409 current_demangling_style = gnu_demangling;
4411 else if (strcmp (optarg, "lucid") == 0)
4413 current_demangling_style = lucid_demangling;
4415 else if (strcmp (optarg, "arm") == 0)
4417 current_demangling_style = arm_demangling;
4419 else if (strcmp (optarg, "hp") == 0)
4421 current_demangling_style = hp_demangling;
4423 else if (strcmp (optarg, "edg") == 0)
4425 current_demangling_style = edg_demangling;
4429 fprintf (stderr, "%s: unknown demangling style `%s'\n",
4430 program_name, optarg);
4439 for ( ; optind < argc; optind++)
4441 demangle_it (argv[optind]);
4450 /* Try to read a label. */
4451 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.' ||
4452 c == '<' || c == '>' || c == '#' || c == ',' || c == '*' || c == '&' ||
4453 c == '[' || c == ']' || c == ':' || c == '(' || c == ')'))
4454 /* the ones in the 2nd & 3rd lines were added to handle
4455 HP aCC template specialization manglings */
4457 if (i >= MBUF_SIZE-1)
4466 if (mbuffer[0] == '.')
4468 if (strip_underscore && mbuffer[skip_first] == '_')
4476 result = cplus_demangle (mbuffer + skip_first, flags);
4479 if (mbuffer[0] == '.')
4481 fputs (result, stdout);
4485 fputs (mbuffer, stdout);
4502 fprintf (stderr, "%s: %s\n", program_name, str);
4510 register PTR value = (PTR) malloc (size);
4512 fatal ("virtual memory exhausted");
4517 xrealloc (ptr, size)
4521 register PTR value = (PTR) realloc (ptr, size);
4523 fatal ("virtual memory exhausted");