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.
425 Trying to consume something that isn't a count results in
426 no consumption of input and a return of 0. */
432 unsigned int count = 0;
435 while (isdigit ((unsigned char)**type))
438 count += **type - '0';
439 /* A sanity check. Otherwise a symbol like
440 `_Utf390_1__1_9223372036854775807__9223372036854775'
441 can cause this function to return a negative value.
442 In this case we just consume until the end of the string. */
443 if (count > strlen (*type))
454 /* Like consume_count, but for counts that are preceded and followed
455 by '_' if they are greater than 10. Also, -1 is returned for
456 failure, since 0 can be a valid value. */
459 consume_count_with_underscores (mangled)
460 const char **mangled;
464 if (**mangled == '_')
467 if (!isdigit ((unsigned char)**mangled))
470 idx = consume_count (mangled);
471 if (**mangled != '_')
472 /* The trailing underscore was missing. */
479 if (**mangled < '0' || **mangled > '9')
482 idx = **mangled - '0';
489 /* C is the code for a type-qualifier. Return the TYPE_QUAL
490 corresponding to this qualifier. */
493 code_for_qualifier (c)
499 return TYPE_QUAL_CONST;
502 return TYPE_QUAL_VOLATILE;
505 return TYPE_QUAL_RESTRICT;
511 /* C was an invalid qualifier. */
515 /* Return the string corresponding to the qualifiers given by
519 qualifier_string (type_quals)
524 case TYPE_UNQUALIFIED:
527 case TYPE_QUAL_CONST:
530 case TYPE_QUAL_VOLATILE:
533 case TYPE_QUAL_RESTRICT:
536 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
537 return "const volatile";
539 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
540 return "const __restrict";
542 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
543 return "volatile __restrict";
545 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
546 return "const volatile __restrict";
552 /* TYPE_QUALS was an invalid qualifier set. */
556 /* C is the code for a type-qualifier. Return the string
557 corresponding to this qualifier. This function should only be
558 called with a valid qualifier code. */
561 demangle_qualifier (c)
564 return qualifier_string (code_for_qualifier (c));
568 cplus_demangle_opname (opname, result, options)
575 struct work_stuff work[1];
578 len = strlen(opname);
581 memset ((char *) work, 0, sizeof (work));
582 work->options = options;
584 if (opname[0] == '_' && opname[1] == '_'
585 && opname[2] == 'o' && opname[3] == 'p')
588 /* type conversion operator. */
590 if (do_type (work, &tem, &type))
592 strcat (result, "operator ");
593 strncat (result, type.b, type.p - type.b);
594 string_delete (&type);
598 else if (opname[0] == '_' && opname[1] == '_'
599 && opname[2] >= 'a' && opname[2] <= 'z'
600 && opname[3] >= 'a' && opname[3] <= 'z')
602 if (opname[4] == '\0')
606 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
608 if (strlen (optable[i].in) == 2
609 && memcmp (optable[i].in, opname + 2, 2) == 0)
611 strcat (result, "operator");
612 strcat (result, optable[i].out);
620 if (opname[2] == 'a' && opname[5] == '\0')
624 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
626 if (strlen (optable[i].in) == 3
627 && memcmp (optable[i].in, opname + 2, 3) == 0)
629 strcat (result, "operator");
630 strcat (result, optable[i].out);
641 && strchr (cplus_markers, opname[2]) != NULL)
643 /* see if it's an assignment expression */
644 if (len >= 10 /* op$assign_ */
645 && memcmp (opname + 3, "assign_", 7) == 0)
648 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
651 if ((int) strlen (optable[i].in) == len1
652 && memcmp (optable[i].in, opname + 10, len1) == 0)
654 strcat (result, "operator");
655 strcat (result, optable[i].out);
656 strcat (result, "=");
665 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
668 if ((int) strlen (optable[i].in) == len1
669 && memcmp (optable[i].in, opname + 3, len1) == 0)
671 strcat (result, "operator");
672 strcat (result, optable[i].out);
679 else if (len >= 5 && memcmp (opname, "type", 4) == 0
680 && strchr (cplus_markers, opname[4]) != NULL)
682 /* type conversion operator */
684 if (do_type (work, &tem, &type))
686 strcat (result, "operator ");
687 strncat (result, type.b, type.p - type.b);
688 string_delete (&type);
692 squangle_mop_up (work);
696 /* Takes operator name as e.g. "++" and returns mangled
697 operator name (e.g. "postincrement_expr"), or NULL if not found.
699 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
700 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
703 cplus_mangle_opname (opname, options)
710 len = strlen (opname);
711 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
713 if ((int) strlen (optable[i].out) == len
714 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
715 && memcmp (optable[i].out, opname, len) == 0)
716 return optable[i].in;
721 /* char *cplus_demangle (const char *mangled, int options)
723 If MANGLED is a mangled function name produced by GNU C++, then
724 a pointer to a malloced string giving a C++ representation
725 of the name will be returned; otherwise NULL will be returned.
726 It is the caller's responsibility to free the string which
729 The OPTIONS arg may contain one or more of the following bits:
731 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
733 DMGL_PARAMS Function parameters are included.
737 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
738 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
739 cplus_demangle ("foo__1Ai", 0) => "A::foo"
741 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
742 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
743 cplus_demangle ("foo__1Afe", 0) => "A::foo"
745 Note that any leading underscores, or other such characters prepended by
746 the compilation system, are presumed to have already been stripped from
750 cplus_demangle (mangled, options)
755 struct work_stuff work[1];
756 memset ((char *) work, 0, sizeof (work));
757 work -> options = options;
758 if ((work -> options & DMGL_STYLE_MASK) == 0)
759 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
761 ret = internal_cplus_demangle (work, mangled);
762 squangle_mop_up (work);
767 /* This function performs most of what cplus_demangle use to do, but
768 to be able to demangle a name with a B, K or n code, we need to
769 have a longer term memory of what types have been seen. The original
770 now intializes and cleans up the squangle code info, while internal
771 calls go directly to this routine to avoid resetting that info. */
774 internal_cplus_demangle (work, mangled)
775 struct work_stuff *work;
781 char *demangled = NULL;
783 s1 = work->constructor;
784 s2 = work->destructor;
785 s3 = work->static_type;
786 s4 = work->type_quals;
787 work->constructor = work->destructor = 0;
788 work->type_quals = TYPE_UNQUALIFIED;
789 work->dllimported = 0;
791 if ((mangled != NULL) && (*mangled != '\0'))
795 /* First check to see if gnu style demangling is active and if the
796 string to be demangled contains a CPLUS_MARKER. If so, attempt to
797 recognize one of the gnu special forms rather than looking for a
798 standard prefix. In particular, don't worry about whether there
799 is a "__" string in the mangled string. Consider "_$_5__foo" for
802 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
804 success = gnu_special (work, &mangled, &decl);
808 success = demangle_prefix (work, &mangled, &decl);
810 if (success && (*mangled != '\0'))
812 success = demangle_signature (work, &mangled, &decl);
814 if (work->constructor == 2)
816 string_prepend (&decl, "global constructors keyed to ");
817 work->constructor = 0;
819 else if (work->destructor == 2)
821 string_prepend (&decl, "global destructors keyed to ");
822 work->destructor = 0;
824 else if (work->dllimported == 1)
826 string_prepend (&decl, "import stub for ");
827 work->dllimported = 0;
829 demangled = mop_up (work, &decl, success);
831 work->constructor = s1;
832 work->destructor = s2;
833 work->static_type = s3;
834 work->type_quals = s4;
839 /* Clear out and squangling related storage */
841 squangle_mop_up (work)
842 struct work_stuff *work;
844 /* clean up the B and K type mangling types. */
845 forget_B_and_K_types (work);
846 if (work -> btypevec != NULL)
848 free ((char *) work -> btypevec);
850 if (work -> ktypevec != NULL)
852 free ((char *) work -> ktypevec);
856 /* Clear out any mangled storage */
859 mop_up (work, declp, success)
860 struct work_stuff *work;
864 char *demangled = NULL;
866 /* Discard the remembered types, if any. */
869 if (work -> typevec != NULL)
871 free ((char *) work -> typevec);
872 work -> typevec = NULL;
874 if (work->tmpl_argvec)
878 for (i = 0; i < work->ntmpl_args; i++)
879 if (work->tmpl_argvec[i])
880 free ((char*) work->tmpl_argvec[i]);
882 free ((char*) work->tmpl_argvec);
883 work->tmpl_argvec = NULL;
885 if (work->previous_argument)
887 string_delete (work->previous_argument);
888 free ((char*) work->previous_argument);
889 work->previous_argument = NULL;
892 /* If demangling was successful, ensure that the demangled string is null
893 terminated and return it. Otherwise, free the demangling decl. */
897 string_delete (declp);
901 string_appendn (declp, "", 1);
902 demangled = declp -> b;
911 demangle_signature -- demangle the signature part of a mangled name
916 demangle_signature (struct work_stuff *work, const char **mangled,
921 Consume and demangle the signature portion of the mangled name.
923 DECLP is the string where demangled output is being built. At
924 entry it contains the demangled root name from the mangled name
925 prefix. I.E. either a demangled operator name or the root function
926 name. In some special cases, it may contain nothing.
928 *MANGLED points to the current unconsumed location in the mangled
929 name. As tokens are consumed and demangling is performed, the
930 pointer is updated to continuously point at the next token to
933 Demangling GNU style mangled names is nasty because there is no
934 explicit token that marks the start of the outermost function
938 demangle_signature (work, mangled, declp)
939 struct work_stuff *work;
940 const char **mangled;
946 int expect_return_type = 0;
947 const char *oldmangled = NULL;
951 while (success && (**mangled != '\0'))
956 oldmangled = *mangled;
957 success = demangle_qualified (work, mangled, declp, 1, 0);
959 remember_type (work, oldmangled, *mangled - oldmangled);
960 if (AUTO_DEMANGLING || GNU_DEMANGLING)
966 oldmangled = *mangled;
967 success = demangle_qualified (work, mangled, declp, 1, 0);
968 if (AUTO_DEMANGLING || GNU_DEMANGLING)
976 /* Static member function */
977 if (oldmangled == NULL)
979 oldmangled = *mangled;
982 work -> static_type = 1;
988 work->type_quals |= code_for_qualifier (**mangled);
990 /* a qualified member function */
991 if (oldmangled == NULL)
992 oldmangled = *mangled;
997 /* Local class name follows after "Lnnn_" */
1000 while (**mangled && (**mangled != '_'))
1011 case '0': case '1': case '2': case '3': case '4':
1012 case '5': case '6': case '7': case '8': case '9':
1013 if (oldmangled == NULL)
1015 oldmangled = *mangled;
1017 work->temp_start = -1; /* uppermost call to demangle_class */
1018 success = demangle_class (work, mangled, declp);
1021 remember_type (work, oldmangled, *mangled - oldmangled);
1023 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1025 /* EDG and others will have the "F", so we let the loop cycle
1026 if we are looking at one. */
1027 if (**mangled != 'F')
1036 success = do_type (work, mangled, &s);
1039 string_append (&s, SCOPE_STRING (work));
1040 string_prepends (declp, &s);
1049 /* ARM/HP style demangling includes a specific 'F' character after
1050 the class name. For GNU style, it is just implied. So we can
1051 safely just consume any 'F' at this point and be compatible
1052 with either style. */
1058 /* For lucid/ARM/HP style we have to forget any types we might
1059 have remembered up to this point, since they were not argument
1060 types. GNU style considers all types seen as available for
1061 back references. See comment in demangle_args() */
1063 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1065 forget_types (work);
1067 success = demangle_args (work, mangled, declp);
1068 /* After picking off the function args, we expect to either
1069 find the function return type (preceded by an '_') or the
1070 end of the string. */
1071 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1074 /* At this level, we do not care about the return type. */
1075 success = do_type (work, mangled, &tname);
1076 string_delete (&tname);
1083 string_init(&trawname);
1084 string_init(&tname);
1085 if (oldmangled == NULL)
1087 oldmangled = *mangled;
1089 success = demangle_template (work, mangled, &tname,
1093 remember_type (work, oldmangled, *mangled - oldmangled);
1095 string_append (&tname, SCOPE_STRING (work));
1097 string_prepends(declp, &tname);
1098 if (work -> destructor & 1)
1100 string_prepend (&trawname, "~");
1101 string_appends (declp, &trawname);
1102 work->destructor -= 1;
1104 if ((work->constructor & 1) || (work->destructor & 1))
1106 string_appends (declp, &trawname);
1107 work->constructor -= 1;
1109 string_delete(&trawname);
1110 string_delete(&tname);
1116 if (GNU_DEMANGLING && expect_return_type)
1118 /* Read the return type. */
1120 string_init (&return_type);
1123 success = do_type (work, mangled, &return_type);
1124 APPEND_BLANK (&return_type);
1126 string_prepends (declp, &return_type);
1127 string_delete (&return_type);
1131 /* At the outermost level, we cannot have a return type specified,
1132 so if we run into another '_' at this point we are dealing with
1133 a mangled name that is either bogus, or has been mangled by
1134 some algorithm we don't know how to deal with. So just
1135 reject the entire demangling. */
1136 /* However, "_nnn" is an expected suffix for alternate entry point
1137 numbered nnn for a function, with HP aCC, so skip over that
1138 without reporting failure. pai/1997-09-04 */
1142 while (**mangled && isdigit ((unsigned char)**mangled))
1152 /* A G++ template function. Read the template arguments. */
1153 success = demangle_template (work, mangled, declp, 0, 0,
1155 if (!(work->constructor & 1))
1156 expect_return_type = 1;
1165 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1167 /* Assume we have stumbled onto the first outermost function
1168 argument token, and start processing args. */
1170 success = demangle_args (work, mangled, declp);
1174 /* Non-GNU demanglers use a specific token to mark the start
1175 of the outermost function argument tokens. Typically 'F',
1176 for ARM/HP-demangling, for example. So if we find something
1177 we are not prepared for, it must be an error. */
1183 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1186 if (success && expect_func)
1189 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1191 forget_types (work);
1193 success = demangle_args (work, mangled, declp);
1194 /* Since template include the mangling of their return types,
1195 we must set expect_func to 0 so that we don't try do
1196 demangle more arguments the next time we get here. */
1201 if (success && !func_done)
1203 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1205 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1206 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1207 first case, and need to ensure that the '(void)' gets added to
1208 the current declp. Note that with ARM/HP, the first case
1209 represents the name of a static data member 'foo::bar',
1210 which is in the current declp, so we leave it alone. */
1211 success = demangle_args (work, mangled, declp);
1214 if (success && PRINT_ARG_TYPES)
1216 if (work->static_type)
1217 string_append (declp, " static");
1218 if (work->type_quals != TYPE_UNQUALIFIED)
1220 APPEND_BLANK (declp);
1221 string_append (declp, qualifier_string (work->type_quals));
1231 demangle_method_args (work, mangled, declp)
1232 struct work_stuff *work;
1233 const char **mangled;
1238 if (work -> static_type)
1240 string_append (declp, *mangled + 1);
1241 *mangled += strlen (*mangled);
1246 success = demangle_args (work, mangled, declp);
1254 demangle_template_template_parm (work, mangled, tname)
1255 struct work_stuff *work;
1256 const char **mangled;
1265 string_append (tname, "template <");
1266 /* get size of template parameter list */
1267 if (get_count (mangled, &r))
1269 for (i = 0; i < r; i++)
1273 string_append (tname, ", ");
1276 /* Z for type parameters */
1277 if (**mangled == 'Z')
1280 string_append (tname, "class");
1282 /* z for template parameters */
1283 else if (**mangled == 'z')
1287 demangle_template_template_parm (work, mangled, tname);
1295 /* temp is initialized in do_type */
1296 success = do_type (work, mangled, &temp);
1299 string_appends (tname, &temp);
1301 string_delete(&temp);
1311 if (tname->p[-1] == '>')
1312 string_append (tname, " ");
1313 string_append (tname, "> class");
1318 demangle_integral_value (work, mangled, s)
1319 struct work_stuff *work;
1320 const char** mangled;
1325 if (**mangled == 'E')
1327 int need_operator = 0;
1330 string_appendn (s, "(", 1);
1332 while (success && **mangled != 'W' && **mangled != '\0')
1341 len = strlen (*mangled);
1344 i < sizeof (optable) / sizeof (optable [0]);
1347 size_t l = strlen (optable[i].in);
1350 && memcmp (optable[i].in, *mangled, l) == 0)
1352 string_appendn (s, " ", 1);
1353 string_append (s, optable[i].out);
1354 string_appendn (s, " ", 1);
1367 success = demangle_template_value_parm (work, mangled, s,
1371 if (**mangled != 'W')
1375 string_appendn (s, ")", 1);
1379 else if (**mangled == 'Q' || **mangled == 'K')
1380 success = demangle_qualified (work, mangled, s, 0, 1);
1385 if (**mangled == 'm')
1387 string_appendn (s, "-", 1);
1390 while (isdigit ((unsigned char)**mangled))
1392 string_appendn (s, *mangled, 1);
1402 demangle_template_value_parm (work, mangled, s, tk)
1403 struct work_stuff *work;
1404 const char **mangled;
1410 if (**mangled == 'Y')
1412 /* The next argument is a template parameter. */
1416 idx = consume_count_with_underscores (mangled);
1418 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1419 || consume_count_with_underscores (mangled) == -1)
1421 if (work->tmpl_argvec)
1422 string_append (s, work->tmpl_argvec[idx]);
1426 sprintf(buf, "T%d", idx);
1427 string_append (s, buf);
1430 else if (tk == tk_integral)
1431 success = demangle_integral_value (work, mangled, s);
1432 else if (tk == tk_char)
1436 if (**mangled == 'm')
1438 string_appendn (s, "-", 1);
1441 string_appendn (s, "'", 1);
1442 val = consume_count(mangled);
1447 string_appendn (s, &tmp[0], 1);
1448 string_appendn (s, "'", 1);
1450 else if (tk == tk_bool)
1452 int val = consume_count (mangled);
1454 string_appendn (s, "false", 5);
1456 string_appendn (s, "true", 4);
1460 else if (tk == tk_real)
1462 if (**mangled == 'm')
1464 string_appendn (s, "-", 1);
1467 while (isdigit ((unsigned char)**mangled))
1469 string_appendn (s, *mangled, 1);
1472 if (**mangled == '.') /* fraction */
1474 string_appendn (s, ".", 1);
1476 while (isdigit ((unsigned char)**mangled))
1478 string_appendn (s, *mangled, 1);
1482 if (**mangled == 'e') /* exponent */
1484 string_appendn (s, "e", 1);
1486 while (isdigit ((unsigned char)**mangled))
1488 string_appendn (s, *mangled, 1);
1493 else if (tk == tk_pointer || tk == tk_reference)
1495 int symbol_len = consume_count (mangled);
1496 if (symbol_len == 0)
1498 if (symbol_len == 0)
1499 string_appendn (s, "0", 1);
1502 char *p = xmalloc (symbol_len + 1), *q;
1503 strncpy (p, *mangled, symbol_len);
1504 p [symbol_len] = '\0';
1505 /* We use cplus_demangle here, rather than
1506 internal_cplus_demangle, because the name of the entity
1507 mangled here does not make use of any of the squangling
1508 or type-code information we have built up thus far; it is
1509 mangled independently. */
1510 q = cplus_demangle (p, work->options);
1511 if (tk == tk_pointer)
1512 string_appendn (s, "&", 1);
1513 /* FIXME: Pointer-to-member constants should get a
1514 qualifying class name here. */
1517 string_append (s, q);
1521 string_append (s, p);
1524 *mangled += symbol_len;
1530 /* Demangle the template name in MANGLED. The full name of the
1531 template (e.g., S<int>) is placed in TNAME. The name without the
1532 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1533 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1534 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1535 the tmeplate is remembered in the list of back-referenceable
1539 demangle_template (work, mangled, tname, trawname, is_type, remember)
1540 struct work_stuff *work;
1541 const char **mangled;
1552 int is_java_array = 0;
1560 bindex = register_Btype (work);
1562 /* get template name */
1563 if (**mangled == 'z')
1569 idx = consume_count_with_underscores (mangled);
1571 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1572 || consume_count_with_underscores (mangled) == -1)
1575 if (work->tmpl_argvec)
1577 string_append (tname, work->tmpl_argvec[idx]);
1579 string_append (trawname, work->tmpl_argvec[idx]);
1584 sprintf(buf, "T%d", idx);
1585 string_append (tname, buf);
1587 string_append (trawname, buf);
1592 if ((r = consume_count (mangled)) == 0
1593 || (int) strlen (*mangled) < r)
1597 is_java_array = (work -> options & DMGL_JAVA)
1598 && strncmp (*mangled, "JArray1Z", 8) == 0;
1599 if (! is_java_array)
1601 string_appendn (tname, *mangled, r);
1604 string_appendn (trawname, *mangled, r);
1609 string_append (tname, "<");
1610 /* get size of template parameter list */
1611 if (!get_count (mangled, &r))
1617 /* Create an array for saving the template argument values. */
1618 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1619 work->ntmpl_args = r;
1620 for (i = 0; i < r; i++)
1621 work->tmpl_argvec[i] = 0;
1623 for (i = 0; i < r; i++)
1627 string_append (tname, ", ");
1629 /* Z for type parameters */
1630 if (**mangled == 'Z')
1633 /* temp is initialized in do_type */
1634 success = do_type (work, mangled, &temp);
1637 string_appends (tname, &temp);
1641 /* Save the template argument. */
1642 int len = temp.p - temp.b;
1643 work->tmpl_argvec[i] = xmalloc (len + 1);
1644 memcpy (work->tmpl_argvec[i], temp.b, len);
1645 work->tmpl_argvec[i][len] = '\0';
1648 string_delete(&temp);
1654 /* z for template parameters */
1655 else if (**mangled == 'z')
1659 success = demangle_template_template_parm (work, mangled, tname);
1662 && (r2 = consume_count (mangled)) > 0
1663 && (int) strlen (*mangled) >= r2)
1665 string_append (tname, " ");
1666 string_appendn (tname, *mangled, r2);
1669 /* Save the template argument. */
1671 work->tmpl_argvec[i] = xmalloc (len + 1);
1672 memcpy (work->tmpl_argvec[i], *mangled, len);
1673 work->tmpl_argvec[i][len] = '\0';
1687 /* otherwise, value parameter */
1689 /* temp is initialized in do_type */
1690 success = do_type (work, mangled, &temp);
1691 string_delete(&temp);
1703 success = demangle_template_value_parm (work, mangled, s,
1704 (type_kind_t) success);
1716 int len = s->p - s->b;
1717 work->tmpl_argvec[i] = xmalloc (len + 1);
1718 memcpy (work->tmpl_argvec[i], s->b, len);
1719 work->tmpl_argvec[i][len] = '\0';
1721 string_appends (tname, s);
1729 string_append (tname, "[]");
1733 if (tname->p[-1] == '>')
1734 string_append (tname, " ");
1735 string_append (tname, ">");
1738 if (is_type && remember)
1739 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1742 if (work -> static_type)
1744 string_append (declp, *mangled + 1);
1745 *mangled += strlen (*mangled);
1750 success = demangle_args (work, mangled, declp);
1758 arm_pt (work, mangled, n, anchor, args)
1759 struct work_stuff *work;
1760 const char *mangled;
1762 const char **anchor, **args;
1764 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1765 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1766 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
1769 *args = *anchor + 6;
1770 len = consume_count (args);
1771 if (*args + len == mangled + n && **args == '_')
1777 if (AUTO_DEMANGLING || EDG_DEMANGLING)
1779 if ((*anchor = mystrstr (mangled, "__tm__"))
1780 || (*anchor = mystrstr (mangled, "__ps__"))
1781 || (*anchor = mystrstr (mangled, "__pt__")))
1784 *args = *anchor + 6;
1785 len = consume_count (args);
1786 if (*args + len == mangled + n && **args == '_')
1792 else if ((*anchor = mystrstr (mangled, "__S")))
1795 *args = *anchor + 3;
1796 len = consume_count (args);
1797 if (*args + len == mangled + n && **args == '_')
1809 demangle_arm_hp_template (work, mangled, n, declp)
1810 struct work_stuff *work;
1811 const char **mangled;
1817 const char *e = *mangled + n;
1820 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1822 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
1824 char *start_spec_args = NULL;
1826 /* First check for and omit template specialization pseudo-arguments,
1827 such as in "Spec<#1,#1.*>" */
1828 start_spec_args = strchr (*mangled, '<');
1829 if (start_spec_args && (start_spec_args - *mangled < n))
1830 string_appendn (declp, *mangled, start_spec_args - *mangled);
1832 string_appendn (declp, *mangled, n);
1833 (*mangled) += n + 1;
1835 if (work->temp_start == -1) /* non-recursive call */
1836 work->temp_start = declp->p - declp->b;
1837 string_append (declp, "<");
1840 string_clear (&arg);
1844 /* 'T' signals a type parameter */
1846 if (!do_type (work, mangled, &arg))
1847 goto hpacc_template_args_done;
1852 /* 'U' or 'S' signals an integral value */
1853 if (!do_hpacc_template_const_value (work, mangled, &arg))
1854 goto hpacc_template_args_done;
1858 /* 'A' signals a named constant expression (literal) */
1859 if (!do_hpacc_template_literal (work, mangled, &arg))
1860 goto hpacc_template_args_done;
1864 /* Today, 1997-09-03, we have only the above types
1865 of template parameters */
1866 /* FIXME: maybe this should fail and return null */
1867 goto hpacc_template_args_done;
1869 string_appends (declp, &arg);
1870 /* Check if we're at the end of template args.
1871 0 if at end of static member of template class,
1872 _ if done with template args for a function */
1873 if ((**mangled == '\000') || (**mangled == '_'))
1876 string_append (declp, ",");
1878 hpacc_template_args_done:
1879 string_append (declp, ">");
1880 string_delete (&arg);
1881 if (**mangled == '_')
1885 /* ARM template? (Also handles HP cfront extensions) */
1886 else if (arm_pt (work, *mangled, n, &p, &args))
1891 string_appendn (declp, *mangled, p - *mangled);
1892 if (work->temp_start == -1) /* non-recursive call */
1893 work->temp_start = declp->p - declp->b;
1894 string_append (declp, "<");
1895 /* should do error checking here */
1897 string_clear (&arg);
1899 /* Check for type or literal here */
1902 /* HP cfront extensions to ARM for template args */
1903 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1904 /* FIXME: We handle only numeric literals for HP cfront */
1906 /* A typed constant value follows */
1908 if (!do_type (work, &args, &type_str))
1909 goto cfront_template_args_done;
1910 string_append (&arg, "(");
1911 string_appends (&arg, &type_str);
1912 string_append (&arg, ")");
1914 goto cfront_template_args_done;
1916 /* Now snarf a literal value following 'L' */
1917 if (!snarf_numeric_literal (&args, &arg))
1918 goto cfront_template_args_done;
1922 /* Snarf a literal following 'L' */
1924 if (!snarf_numeric_literal (&args, &arg))
1925 goto cfront_template_args_done;
1928 /* Not handling other HP cfront stuff */
1929 if (!do_type (work, &args, &arg))
1930 goto cfront_template_args_done;
1932 string_appends (declp, &arg);
1933 string_append (declp, ",");
1935 cfront_template_args_done:
1936 string_delete (&arg);
1938 --declp->p; /* remove extra comma */
1939 string_append (declp, ">");
1941 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1942 && (*mangled)[9] == 'N'
1943 && (*mangled)[8] == (*mangled)[10]
1944 && strchr (cplus_markers, (*mangled)[8]))
1946 /* A member of the anonymous namespace. */
1947 string_append (declp, "{anonymous}");
1951 if (work->temp_start == -1) /* non-recursive call only */
1952 work->temp_start = 0; /* disable in recursive calls */
1953 string_appendn (declp, *mangled, n);
1958 /* Extract a class name, possibly a template with arguments, from the
1959 mangled string; qualifiers, local class indicators, etc. have
1960 already been dealt with */
1963 demangle_class_name (work, mangled, declp)
1964 struct work_stuff *work;
1965 const char **mangled;
1971 n = consume_count (mangled);
1974 demangle_arm_hp_template (work, mangled, n, declp);
1985 demangle_class -- demangle a mangled class sequence
1990 demangle_class (struct work_stuff *work, const char **mangled,
1995 DECLP points to the buffer into which demangling is being done.
1997 *MANGLED points to the current token to be demangled. On input,
1998 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1999 On exit, it points to the next token after the mangled class on
2000 success, or the first unconsumed token on failure.
2002 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2003 we are demangling a constructor or destructor. In this case
2004 we prepend "class::class" or "class::~class" to DECLP.
2006 Otherwise, we prepend "class::" to the current DECLP.
2008 Reset the constructor/destructor flags once they have been
2009 "consumed". This allows demangle_class to be called later during
2010 the same demangling, to do normal class demangling.
2012 Returns 1 if demangling is successful, 0 otherwise.
2017 demangle_class (work, mangled, declp)
2018 struct work_stuff *work;
2019 const char **mangled;
2025 char *save_class_name_end = 0;
2027 string_init (&class_name);
2028 btype = register_Btype (work);
2029 if (demangle_class_name (work, mangled, &class_name))
2031 save_class_name_end = class_name.p;
2032 if ((work->constructor & 1) || (work->destructor & 1))
2034 /* adjust so we don't include template args */
2035 if (work->temp_start && (work->temp_start != -1))
2037 class_name.p = class_name.b + work->temp_start;
2039 string_prepends (declp, &class_name);
2040 if (work -> destructor & 1)
2042 string_prepend (declp, "~");
2043 work -> destructor -= 1;
2047 work -> constructor -= 1;
2050 class_name.p = save_class_name_end;
2051 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2052 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2053 string_prepend (declp, SCOPE_STRING (work));
2054 string_prepends (declp, &class_name);
2057 string_delete (&class_name);
2065 demangle_prefix -- consume the mangled name prefix and find signature
2070 demangle_prefix (struct work_stuff *work, const char **mangled,
2075 Consume and demangle the prefix of the mangled name.
2077 DECLP points to the string buffer into which demangled output is
2078 placed. On entry, the buffer is empty. On exit it contains
2079 the root function name, the demangled operator name, or in some
2080 special cases either nothing or the completely demangled result.
2082 MANGLED points to the current pointer into the mangled name. As each
2083 token of the mangled name is consumed, it is updated. Upon entry
2084 the current mangled name pointer points to the first character of
2085 the mangled name. Upon exit, it should point to the first character
2086 of the signature if demangling was successful, or to the first
2087 unconsumed character if demangling of the prefix was unsuccessful.
2089 Returns 1 on success, 0 otherwise.
2093 demangle_prefix (work, mangled, declp)
2094 struct work_stuff *work;
2095 const char **mangled;
2102 if (strlen(*mangled) > 6
2103 && (strncmp(*mangled, "_imp__", 6) == 0
2104 || strncmp(*mangled, "__imp_", 6) == 0))
2106 /* it's a symbol imported from a PE dynamic library. Check for both
2107 new style prefix _imp__ and legacy __imp_ used by older versions
2110 work->dllimported = 1;
2112 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2114 char *marker = strchr (cplus_markers, (*mangled)[8]);
2115 if (marker != NULL && *marker == (*mangled)[10])
2117 if ((*mangled)[9] == 'D')
2119 /* it's a GNU global destructor to be executed at program exit */
2121 work->destructor = 2;
2122 if (gnu_special (work, mangled, declp))
2125 else if ((*mangled)[9] == 'I')
2127 /* it's a GNU global constructor to be executed at program init */
2129 work->constructor = 2;
2130 if (gnu_special (work, mangled, declp))
2135 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2137 /* it's a ARM global destructor to be executed at program exit */
2139 work->destructor = 2;
2141 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2143 /* it's a ARM global constructor to be executed at program initial */
2145 work->constructor = 2;
2148 /* This block of code is a reduction in strength time optimization
2150 scan = mystrstr (*mangled, "__"); */
2156 scan = strchr (scan, '_');
2157 } while (scan != NULL && *++scan != '_');
2159 if (scan != NULL) --scan;
2164 /* We found a sequence of two or more '_', ensure that we start at
2165 the last pair in the sequence. */
2166 i = strspn (scan, "_");
2177 else if (work -> static_type)
2179 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
2184 else if ((scan == *mangled)
2185 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
2186 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2188 /* The ARM says nothing about the mangling of local variables.
2189 But cfront mangles local variables by prepending __<nesting_level>
2190 to them. As an extension to ARM demangling we handle this case. */
2191 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2192 && isdigit ((unsigned char)scan[2]))
2194 *mangled = scan + 2;
2195 consume_count (mangled);
2196 string_append (declp, *mangled);
2197 *mangled += strlen (*mangled);
2202 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2203 names like __Q2_3foo3bar for nested type names. So don't accept
2204 this style of constructor for cfront demangling. A GNU
2205 style member-template constructor starts with 'H'. */
2206 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2207 work -> constructor += 1;
2208 *mangled = scan + 2;
2211 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2213 /* Cfront-style parameterized type. Handled later as a signature. */
2217 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2219 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2220 || (scan[2] == 'p' && scan[3] == 's')
2221 || (scan[2] == 'p' && scan[3] == 't')))
2223 /* EDG-style parameterized type. Handled later as a signature. */
2227 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2229 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
2230 && (scan[2] != 't'))
2232 /* Mangled name starts with "__". Skip over any leading '_' characters,
2233 then find the next "__" that separates the prefix from the signature.
2235 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2236 || (arm_special (mangled, declp) == 0))
2238 while (*scan == '_')
2242 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2244 /* No separator (I.E. "__not_mangled"), or empty signature
2245 (I.E. "__not_mangled_either__") */
2252 /* Look for the LAST occurrence of __, allowing names to
2253 have the '__' sequence embedded in them. */
2254 if (!(ARM_DEMANGLING || HP_DEMANGLING))
2256 while ((tmp = mystrstr (scan + 2, "__")) != NULL)
2259 if (*(scan + 2) == '\0')
2262 demangle_function_name (work, mangled, declp, scan);
2266 else if (*(scan + 2) != '\0')
2268 /* Mangled name does not start with "__" but does have one somewhere
2269 in there with non empty stuff after it. Looks like a global
2271 demangle_function_name (work, mangled, declp, scan);
2275 /* Doesn't look like a mangled name */
2279 if (!success && (work->constructor == 2 || work->destructor == 2))
2281 string_append (declp, *mangled);
2282 *mangled += strlen (*mangled);
2292 gnu_special -- special handling of gnu mangled strings
2297 gnu_special (struct work_stuff *work, const char **mangled,
2303 Process some special GNU style mangling forms that don't fit
2304 the normal pattern. For example:
2306 _$_3foo (destructor for class foo)
2307 _vt$foo (foo virtual table)
2308 _vt$foo$bar (foo::bar virtual table)
2309 __vt_foo (foo virtual table, new style with thunks)
2310 _3foo$varname (static data member)
2311 _Q22rs2tu$vw (static data member)
2312 __t6vector1Zii (constructor with template)
2313 __thunk_4__$_7ostream (virtual function thunk)
2317 gnu_special (work, mangled, declp)
2318 struct work_stuff *work;
2319 const char **mangled;
2326 if ((*mangled)[0] == '_'
2327 && strchr (cplus_markers, (*mangled)[1]) != NULL
2328 && (*mangled)[2] == '_')
2330 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2332 work -> destructor += 1;
2334 else if ((*mangled)[0] == '_'
2335 && (((*mangled)[1] == '_'
2336 && (*mangled)[2] == 'v'
2337 && (*mangled)[3] == 't'
2338 && (*mangled)[4] == '_')
2339 || ((*mangled)[1] == 'v'
2340 && (*mangled)[2] == 't'
2341 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2343 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2344 and create the decl. Note that we consume the entire mangled
2345 input string, which means that demangle_signature has no work
2347 if ((*mangled)[2] == 'v')
2348 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2350 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2351 while (**mangled != '\0')
2357 success = demangle_qualified (work, mangled, declp, 0, 1);
2360 success = demangle_template (work, mangled, declp, 0, 1,
2364 if (isdigit((unsigned char)*mangled[0]))
2366 n = consume_count(mangled);
2367 /* We may be seeing a too-large size, or else a
2368 ".<digits>" indicating a static local symbol. In
2369 any case, declare victory and move on; *don't* try
2370 to use n to allocate. */
2371 if (n > (int) strlen (*mangled))
2379 n = strcspn (*mangled, cplus_markers);
2381 string_appendn (declp, *mangled, n);
2385 p = strpbrk (*mangled, cplus_markers);
2386 if (success && ((p == NULL) || (p == *mangled)))
2390 string_append (declp, SCOPE_STRING (work));
2401 string_append (declp, " virtual table");
2403 else if ((*mangled)[0] == '_'
2404 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2405 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2407 /* static data member, "_3foo$varname" for example */
2413 success = demangle_qualified (work, mangled, declp, 0, 1);
2416 success = demangle_template (work, mangled, declp, 0, 1, 1);
2419 n = consume_count (mangled);
2420 string_appendn (declp, *mangled, n);
2423 if (success && (p == *mangled))
2425 /* Consumed everything up to the cplus_marker, append the
2428 string_append (declp, SCOPE_STRING (work));
2429 n = strlen (*mangled);
2430 string_appendn (declp, *mangled, n);
2438 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2440 int delta = ((*mangled) += 8, consume_count (mangled));
2441 char *method = internal_cplus_demangle (work, ++*mangled);
2445 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2446 string_append (declp, buf);
2447 string_append (declp, method);
2449 n = strlen (*mangled);
2457 else if (strncmp (*mangled, "__t", 3) == 0
2458 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2460 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2466 success = demangle_qualified (work, mangled, declp, 0, 1);
2469 success = demangle_template (work, mangled, declp, 0, 1, 1);
2472 success = demangle_fund_type (work, mangled, declp);
2475 if (success && **mangled != '\0')
2478 string_append (declp, p);
2488 recursively_demangle(work, mangled, result, namelength)
2489 struct work_stuff *work;
2490 const char **mangled;
2494 char * recurse = (char *)NULL;
2495 char * recurse_dem = (char *)NULL;
2497 recurse = (char *) xmalloc (namelength + 1);
2498 memcpy (recurse, *mangled, namelength);
2499 recurse[namelength] = '\000';
2501 recurse_dem = cplus_demangle (recurse, work->options);
2505 string_append (result, recurse_dem);
2510 string_appendn (result, *mangled, namelength);
2513 *mangled += namelength;
2520 arm_special -- special handling of ARM/lucid mangled strings
2525 arm_special (const char **mangled,
2531 Process some special ARM style mangling forms that don't fit
2532 the normal pattern. For example:
2534 __vtbl__3foo (foo virtual table)
2535 __vtbl__3foo__3bar (bar::foo virtual table)
2540 arm_special (mangled, declp)
2541 const char **mangled;
2548 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2550 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2551 and create the decl. Note that we consume the entire mangled
2552 input string, which means that demangle_signature has no work
2554 scan = *mangled + ARM_VTABLE_STRLEN;
2555 while (*scan != '\0') /* first check it can be demangled */
2557 n = consume_count (&scan);
2560 return (0); /* no good */
2563 if (scan[0] == '_' && scan[1] == '_')
2568 (*mangled) += ARM_VTABLE_STRLEN;
2569 while (**mangled != '\0')
2571 n = consume_count (mangled);
2572 string_prependn (declp, *mangled, n);
2574 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2576 string_prepend (declp, "::");
2580 string_append (declp, " virtual table");
2593 demangle_qualified -- demangle 'Q' qualified name strings
2598 demangle_qualified (struct work_stuff *, const char *mangled,
2599 string *result, int isfuncname, int append);
2603 Demangle a qualified name, such as "Q25Outer5Inner" which is
2604 the mangled form of "Outer::Inner". The demangled output is
2605 prepended or appended to the result string according to the
2606 state of the append flag.
2608 If isfuncname is nonzero, then the qualified name we are building
2609 is going to be used as a member function name, so if it is a
2610 constructor or destructor function, append an appropriate
2611 constructor or destructor name. I.E. for the above example,
2612 the result for use as a constructor is "Outer::Inner::Inner"
2613 and the result for use as a destructor is "Outer::Inner::~Inner".
2617 Numeric conversion is ASCII dependent (FIXME).
2622 demangle_qualified (work, mangled, result, isfuncname, append)
2623 struct work_stuff *work;
2624 const char **mangled;
2635 int bindex = register_Btype (work);
2637 /* We only make use of ISFUNCNAME if the entity is a constructor or
2639 isfuncname = (isfuncname
2640 && ((work->constructor & 1) || (work->destructor & 1)));
2642 string_init (&temp);
2643 string_init (&last_name);
2645 if ((*mangled)[0] == 'K')
2647 /* Squangling qualified name reuse */
2650 idx = consume_count_with_underscores (mangled);
2651 if (idx == -1 || idx >= work -> numk)
2654 string_append (&temp, work -> ktypevec[idx]);
2657 switch ((*mangled)[1])
2660 /* GNU mangled name with more than 9 classes. The count is preceded
2661 by an underscore (to distinguish it from the <= 9 case) and followed
2662 by an underscore. */
2664 qualifiers = atoi (p);
2665 if (!isdigit ((unsigned char)*p) || *p == '0')
2668 /* Skip the digits. */
2669 while (isdigit ((unsigned char)*p))
2687 /* The count is in a single digit. */
2688 num[0] = (*mangled)[1];
2690 qualifiers = atoi (num);
2692 /* If there is an underscore after the digit, skip it. This is
2693 said to be for ARM-qualified names, but the ARM makes no
2694 mention of such an underscore. Perhaps cfront uses one. */
2695 if ((*mangled)[2] == '_')
2710 /* Pick off the names and collect them in the temp buffer in the order
2711 in which they are found, separated by '::'. */
2713 while (qualifiers-- > 0)
2716 string_clear (&last_name);
2718 if (*mangled[0] == '_')
2721 if (*mangled[0] == 't')
2723 /* Here we always append to TEMP since we will want to use
2724 the template name without the template parameters as a
2725 constructor or destructor name. The appropriate
2726 (parameter-less) value is returned by demangle_template
2727 in LAST_NAME. We do not remember the template type here,
2728 in order to match the G++ mangling algorithm. */
2729 success = demangle_template(work, mangled, &temp,
2734 else if (*mangled[0] == 'K')
2738 idx = consume_count_with_underscores (mangled);
2739 if (idx == -1 || idx >= work->numk)
2742 string_append (&temp, work->ktypevec[idx]);
2745 if (!success) break;
2752 /* Now recursively demangle the qualifier
2753 * This is necessary to deal with templates in
2754 * mangling styles like EDG */
2755 namelength = consume_count (mangled);
2756 recursively_demangle(work, mangled, &temp, namelength);
2760 success = do_type (work, mangled, &last_name);
2763 string_appends (&temp, &last_name);
2768 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2771 string_append (&temp, SCOPE_STRING (work));
2774 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2776 /* If we are using the result as a function name, we need to append
2777 the appropriate '::' separated constructor or destructor name.
2778 We do this here because this is the most convenient place, where
2779 we already have a pointer to the name and the length of the name. */
2783 string_append (&temp, SCOPE_STRING (work));
2784 if (work -> destructor & 1)
2785 string_append (&temp, "~");
2786 string_appends (&temp, &last_name);
2789 /* Now either prepend the temp buffer to the result, or append it,
2790 depending upon the state of the append flag. */
2793 string_appends (result, &temp);
2796 if (!STRING_EMPTY (result))
2797 string_append (&temp, SCOPE_STRING (work));
2798 string_prepends (result, &temp);
2801 string_delete (&last_name);
2802 string_delete (&temp);
2810 get_count -- convert an ascii count to integer, consuming tokens
2815 get_count (const char **type, int *count)
2819 Return 0 if no conversion is performed, 1 if a string is converted.
2823 get_count (type, count)
2830 if (!isdigit ((unsigned char)**type))
2836 *count = **type - '0';
2838 if (isdigit ((unsigned char)**type))
2848 while (isdigit ((unsigned char)*p));
2859 /* RESULT will be initialised here; it will be freed on failure. The
2860 value returned is really a type_kind_t. */
2863 do_type (work, mangled, result)
2864 struct work_stuff *work;
2865 const char **mangled;
2872 const char *remembered_type;
2875 type_kind_t tk = tk_none;
2877 string_init (&btype);
2878 string_init (&decl);
2879 string_init (result);
2883 while (success && !done)
2889 /* A pointer type */
2893 if (! (work -> options & DMGL_JAVA))
2894 string_prepend (&decl, "*");
2899 /* A reference type */
2902 string_prepend (&decl, "&");
2911 if (!STRING_EMPTY (&decl)
2912 && (decl.b[0] == '*' || decl.b[0] == '&'))
2914 string_prepend (&decl, "(");
2915 string_append (&decl, ")");
2917 string_append (&decl, "[");
2918 if (**mangled != '_')
2919 success = demangle_template_value_parm (work, mangled, &decl,
2921 if (**mangled == '_')
2923 string_append (&decl, "]");
2927 /* A back reference to a previously seen type */
2930 if (!get_count (mangled, &n) || n >= work -> ntypes)
2936 remembered_type = work -> typevec[n];
2937 mangled = &remembered_type;
2944 if (!STRING_EMPTY (&decl)
2945 && (decl.b[0] == '*' || decl.b[0] == '&'))
2947 string_prepend (&decl, "(");
2948 string_append (&decl, ")");
2950 /* After picking off the function args, we expect to either find the
2951 function return type (preceded by an '_') or the end of the
2953 if (!demangle_nested_args (work, mangled, &decl)
2954 || (**mangled != '_' && **mangled != '\0'))
2959 if (success && (**mangled == '_'))
2966 type_quals = TYPE_UNQUALIFIED;
2968 member = **mangled == 'M';
2970 if (!isdigit ((unsigned char)**mangled) && **mangled != 't')
2976 string_append (&decl, ")");
2977 string_prepend (&decl, SCOPE_STRING (work));
2978 if (isdigit ((unsigned char)**mangled))
2980 n = consume_count (mangled);
2981 if ((int) strlen (*mangled) < n)
2986 string_prependn (&decl, *mangled, n);
2992 string_init (&temp);
2993 success = demangle_template (work, mangled, &temp,
2997 string_prependn (&decl, temp.b, temp.p - temp.b);
2998 string_clear (&temp);
3003 string_prepend (&decl, "(");
3011 type_quals |= code_for_qualifier (**mangled);
3019 if (*(*mangled)++ != 'F')
3025 if ((member && !demangle_nested_args (work, mangled, &decl))
3026 || **mangled != '_')
3032 if (! PRINT_ANSI_QUALIFIERS)
3036 if (type_quals != TYPE_UNQUALIFIED)
3038 APPEND_BLANK (&decl);
3039 string_append (&decl, qualifier_string (type_quals));
3050 if (PRINT_ANSI_QUALIFIERS)
3052 if (!STRING_EMPTY (&decl))
3053 string_prepend (&decl, " ");
3055 string_prepend (&decl, demangle_qualifier (**mangled));
3070 if (success) switch (**mangled)
3072 /* A qualified name, such as "Outer::Inner". */
3076 success = demangle_qualified (work, mangled, result, 0, 1);
3080 /* A back reference to a previously seen squangled type */
3083 if (!get_count (mangled, &n) || n >= work -> numb)
3086 string_append (result, work->btypevec[n]);
3091 /* A template parm. We substitute the corresponding argument. */
3096 idx = consume_count_with_underscores (mangled);
3099 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3100 || consume_count_with_underscores (mangled) == -1)
3106 if (work->tmpl_argvec)
3107 string_append (result, work->tmpl_argvec[idx]);
3111 sprintf(buf, "T%d", idx);
3112 string_append (result, buf);
3120 success = demangle_fund_type (work, mangled, result);
3122 tk = (type_kind_t) success;
3128 if (!STRING_EMPTY (&decl))
3130 string_append (result, " ");
3131 string_appends (result, &decl);
3135 string_delete (result);
3136 string_delete (&decl);
3139 /* Assume an integral type, if we're not sure. */
3140 return (int) ((tk == tk_none) ? tk_integral : tk);
3145 /* Given a pointer to a type string that represents a fundamental type
3146 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3147 string in which the demangled output is being built in RESULT, and
3148 the WORK structure, decode the types and add them to the result.
3153 "Sl" => "signed long"
3154 "CUs" => "const unsigned short"
3156 The value returned is really a type_kind_t. */
3159 demangle_fund_type (work, mangled, result)
3160 struct work_stuff *work;
3161 const char **mangled;
3169 type_kind_t tk = tk_integral;
3171 string_init (&btype);
3173 /* First pick off any type qualifiers. There can be more than one. */
3182 if (PRINT_ANSI_QUALIFIERS)
3184 if (!STRING_EMPTY (result))
3185 string_prepend (result, " ");
3186 string_prepend (result, demangle_qualifier (**mangled));
3192 APPEND_BLANK (result);
3193 string_append (result, "unsigned");
3195 case 'S': /* signed char only */
3197 APPEND_BLANK (result);
3198 string_append (result, "signed");
3202 APPEND_BLANK (result);
3203 string_append (result, "__complex");
3211 /* Now pick off the fundamental type. There can be only one. */
3220 APPEND_BLANK (result);
3221 string_append (result, "void");
3225 APPEND_BLANK (result);
3226 string_append (result, "long long");
3230 APPEND_BLANK (result);
3231 string_append (result, "long");
3235 APPEND_BLANK (result);
3236 string_append (result, "int");
3240 APPEND_BLANK (result);
3241 string_append (result, "short");
3245 APPEND_BLANK (result);
3246 string_append (result, "bool");
3251 APPEND_BLANK (result);
3252 string_append (result, "char");
3257 APPEND_BLANK (result);
3258 string_append (result, "wchar_t");
3263 APPEND_BLANK (result);
3264 string_append (result, "long double");
3269 APPEND_BLANK (result);
3270 string_append (result, "double");
3275 APPEND_BLANK (result);
3276 string_append (result, "float");
3281 if (!isdigit ((unsigned char)**mangled))
3288 if (**mangled == '_')
3292 for (i = 0; **mangled != '_'; ++(*mangled), ++i)
3299 strncpy (buf, *mangled, 2);
3302 sscanf (buf, "%x", &dec);
3303 sprintf (buf, "int%i_t", dec);
3304 APPEND_BLANK (result);
3305 string_append (result, buf);
3309 /* An explicit type, such as "6mytype" or "7integer" */
3321 int bindex = register_Btype (work);
3323 string_init (&btype);
3324 if (demangle_class_name (work, mangled, &btype)) {
3325 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3326 APPEND_BLANK (result);
3327 string_appends (result, &btype);
3331 string_delete (&btype);
3336 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3337 string_appends (result, &btype);
3345 return success ? ((int) tk) : 0;
3349 /* Handle a template's value parameter for HP aCC (extension from ARM)
3350 **mangled points to 'S' or 'U' */
3353 do_hpacc_template_const_value (work, mangled, result)
3354 struct work_stuff *work;
3355 const char **mangled;
3360 if (**mangled != 'U' && **mangled != 'S')
3363 unsigned_const = (**mangled == 'U');
3370 string_append (result, "-");
3376 /* special case for -2^31 */
3377 string_append (result, "-2147483648");
3384 /* We have to be looking at an integer now */
3385 if (!(isdigit ((unsigned char)**mangled)))
3388 /* We only deal with integral values for template
3389 parameters -- so it's OK to look only for digits */
3390 while (isdigit ((unsigned char)**mangled))
3392 char_str[0] = **mangled;
3393 string_append (result, char_str);
3398 string_append (result, "U");
3400 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3401 with L or LL suffixes. pai/1997-09-03 */
3403 return 1; /* success */
3406 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3407 **mangled is pointing to the 'A' */
3410 do_hpacc_template_literal (work, mangled, result)
3411 struct work_stuff *work;
3412 const char **mangled;
3415 int literal_len = 0;
3419 if (**mangled != 'A')
3424 literal_len = consume_count (mangled);
3429 /* Literal parameters are names of arrays, functions, etc. and the
3430 canonical representation uses the address operator */
3431 string_append (result, "&");
3433 /* Now recursively demangle the literal name */
3434 recurse = (char *) xmalloc (literal_len + 1);
3435 memcpy (recurse, *mangled, literal_len);
3436 recurse[literal_len] = '\000';
3438 recurse_dem = cplus_demangle (recurse, work->options);
3442 string_append (result, recurse_dem);
3447 string_appendn (result, *mangled, literal_len);
3449 (*mangled) += literal_len;
3456 snarf_numeric_literal (args, arg)
3463 string_append (arg, char_str);
3466 else if (**args == '+')
3469 if (!isdigit ((unsigned char)**args))
3472 while (isdigit ((unsigned char)**args))
3474 char_str[0] = **args;
3475 string_append (arg, char_str);
3482 /* Demangle the next argument, given by MANGLED into RESULT, which
3483 *should be an uninitialized* string. It will be initialized here,
3484 and free'd should anything go wrong. */
3487 do_arg (work, mangled, result)
3488 struct work_stuff *work;
3489 const char **mangled;
3492 /* Remember where we started so that we can record the type, for
3493 non-squangling type remembering. */
3494 const char *start = *mangled;
3496 string_init (result);
3498 if (work->nrepeats > 0)
3502 if (work->previous_argument == 0)
3505 /* We want to reissue the previous type in this argument list. */
3506 string_appends (result, work->previous_argument);
3510 if (**mangled == 'n')
3512 /* A squangling-style repeat. */
3514 work->nrepeats = consume_count(mangled);
3516 if (work->nrepeats == 0)
3517 /* This was not a repeat count after all. */
3520 if (work->nrepeats > 9)
3522 if (**mangled != '_')
3523 /* The repeat count should be followed by an '_' in this
3530 /* Now, the repeat is all set up. */
3531 return do_arg (work, mangled, result);
3534 /* Save the result in WORK->previous_argument so that we can find it
3535 if it's repeated. Note that saving START is not good enough: we
3536 do not want to add additional types to the back-referenceable
3537 type vector when processing a repeated type. */
3538 if (work->previous_argument)
3539 string_clear (work->previous_argument);
3542 work->previous_argument = (string*) xmalloc (sizeof (string));
3543 string_init (work->previous_argument);
3546 if (!do_type (work, mangled, work->previous_argument))
3549 string_appends (result, work->previous_argument);
3551 remember_type (work, start, *mangled - start);
3556 remember_type (work, start, len)
3557 struct work_stuff *work;
3563 if (work->forgetting_types)
3566 if (work -> ntypes >= work -> typevec_size)
3568 if (work -> typevec_size == 0)
3570 work -> typevec_size = 3;
3572 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3576 work -> typevec_size *= 2;
3578 = (char **) xrealloc ((char *)work -> typevec,
3579 sizeof (char *) * work -> typevec_size);
3582 tem = xmalloc (len + 1);
3583 memcpy (tem, start, len);
3585 work -> typevec[work -> ntypes++] = tem;
3589 /* Remember a K type class qualifier. */
3591 remember_Ktype (work, start, len)
3592 struct work_stuff *work;
3598 if (work -> numk >= work -> ksize)
3600 if (work -> ksize == 0)
3604 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3610 = (char **) xrealloc ((char *)work -> ktypevec,
3611 sizeof (char *) * work -> ksize);
3614 tem = xmalloc (len + 1);
3615 memcpy (tem, start, len);
3617 work -> ktypevec[work -> numk++] = tem;
3620 /* Register a B code, and get an index for it. B codes are registered
3621 as they are seen, rather than as they are completed, so map<temp<char> >
3622 registers map<temp<char> > as B0, and temp<char> as B1 */
3625 register_Btype (work)
3626 struct work_stuff *work;
3630 if (work -> numb >= work -> bsize)
3632 if (work -> bsize == 0)
3636 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3642 = (char **) xrealloc ((char *)work -> btypevec,
3643 sizeof (char *) * work -> bsize);
3646 ret = work -> numb++;
3647 work -> btypevec[ret] = NULL;
3651 /* Store a value into a previously registered B code type. */
3654 remember_Btype (work, start, len, index)
3655 struct work_stuff *work;
3661 tem = xmalloc (len + 1);
3662 memcpy (tem, start, len);
3664 work -> btypevec[index] = tem;
3667 /* Lose all the info related to B and K type codes. */
3669 forget_B_and_K_types (work)
3670 struct work_stuff *work;
3674 while (work -> numk > 0)
3676 i = --(work -> numk);
3677 if (work -> ktypevec[i] != NULL)
3679 free (work -> ktypevec[i]);
3680 work -> ktypevec[i] = NULL;
3684 while (work -> numb > 0)
3686 i = --(work -> numb);
3687 if (work -> btypevec[i] != NULL)
3689 free (work -> btypevec[i]);
3690 work -> btypevec[i] = NULL;
3694 /* Forget the remembered types, but not the type vector itself. */
3698 struct work_stuff *work;
3702 while (work -> ntypes > 0)
3704 i = --(work -> ntypes);
3705 if (work -> typevec[i] != NULL)
3707 free (work -> typevec[i]);
3708 work -> typevec[i] = NULL;
3713 /* Process the argument list part of the signature, after any class spec
3714 has been consumed, as well as the first 'F' character (if any). For
3717 "__als__3fooRT0" => process "RT0"
3718 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3720 DECLP must be already initialised, usually non-empty. It won't be freed
3723 Note that g++ differs significantly from ARM and lucid style mangling
3724 with regards to references to previously seen types. For example, given
3725 the source fragment:
3729 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3732 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3733 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3735 g++ produces the names:
3740 while lcc (and presumably other ARM style compilers as well) produces:
3742 foo__FiR3fooT1T2T1T2
3743 __ct__3fooFiR3fooT1T2T1T2
3745 Note that g++ bases its type numbers starting at zero and counts all
3746 previously seen types, while lucid/ARM bases its type numbers starting
3747 at one and only considers types after it has seen the 'F' character
3748 indicating the start of the function args. For lucid/ARM style, we
3749 account for this difference by discarding any previously seen types when
3750 we see the 'F' character, and subtracting one from the type number
3756 demangle_args (work, mangled, declp)
3757 struct work_stuff *work;
3758 const char **mangled;
3768 if (PRINT_ARG_TYPES)
3770 string_append (declp, "(");
3771 if (**mangled == '\0')
3773 string_append (declp, "void");
3777 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3778 || work->nrepeats > 0)
3780 if ((**mangled == 'N') || (**mangled == 'T'))
3782 temptype = *(*mangled)++;
3784 if (temptype == 'N')
3786 if (!get_count (mangled, &r))
3795 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
3797 /* If we have 10 or more types we might have more than a 1 digit
3798 index so we'll have to consume the whole count here. This
3799 will lose if the next thing is a type name preceded by a
3800 count but it's impossible to demangle that case properly
3801 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3802 Pc, ...)" or "(..., type12, char *, ...)" */
3803 if ((t = consume_count(mangled)) == 0)
3810 if (!get_count (mangled, &t))
3815 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3819 /* Validate the type index. Protect against illegal indices from
3820 malformed type strings. */
3821 if ((t < 0) || (t >= work -> ntypes))
3825 while (work->nrepeats > 0 || --r >= 0)
3827 tem = work -> typevec[t];
3828 if (need_comma && PRINT_ARG_TYPES)
3830 string_append (declp, ", ");
3832 if (!do_arg (work, &tem, &arg))
3836 if (PRINT_ARG_TYPES)
3838 string_appends (declp, &arg);
3840 string_delete (&arg);
3846 if (need_comma && PRINT_ARG_TYPES)
3847 string_append (declp, ", ");
3848 if (!do_arg (work, mangled, &arg))
3850 if (PRINT_ARG_TYPES)
3851 string_appends (declp, &arg);
3852 string_delete (&arg);
3857 if (**mangled == 'e')
3860 if (PRINT_ARG_TYPES)
3864 string_append (declp, ",");
3866 string_append (declp, "...");
3870 if (PRINT_ARG_TYPES)
3872 string_append (declp, ")");
3877 /* Like demangle_args, but for demangling the argument lists of function
3878 and method pointers or references, not top-level declarations. */
3881 demangle_nested_args (work, mangled, declp)
3882 struct work_stuff *work;
3883 const char **mangled;
3886 string* saved_previous_argument;
3890 /* The G++ name-mangling algorithm does not remember types on nested
3891 argument lists, unless -fsquangling is used, and in that case the
3892 type vector updated by remember_type is not used. So, we turn
3893 off remembering of types here. */
3894 ++work->forgetting_types;
3896 /* For the repeat codes used with -fsquangling, we must keep track of
3897 the last argument. */
3898 saved_previous_argument = work->previous_argument;
3899 saved_nrepeats = work->nrepeats;
3900 work->previous_argument = 0;
3903 /* Actually demangle the arguments. */
3904 result = demangle_args (work, mangled, declp);
3906 /* Restore the previous_argument field. */
3907 if (work->previous_argument)
3908 string_delete (work->previous_argument);
3909 work->previous_argument = saved_previous_argument;
3910 --work->forgetting_types;
3911 work->nrepeats = saved_nrepeats;
3917 demangle_function_name (work, mangled, declp, scan)
3918 struct work_stuff *work;
3919 const char **mangled;
3927 string_appendn (declp, (*mangled), scan - (*mangled));
3928 string_need (declp, 1);
3929 *(declp -> p) = '\0';
3931 /* Consume the function name, including the "__" separating the name
3932 from the signature. We are guaranteed that SCAN points to the
3935 (*mangled) = scan + 2;
3936 /* We may be looking at an instantiation of a template function:
3937 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
3938 following _F marks the start of the function arguments. Handle
3939 the template arguments first. */
3941 if (HP_DEMANGLING && (**mangled == 'X'))
3943 demangle_arm_hp_template (work, mangled, 0, declp);
3944 /* This leaves MANGLED pointing to the 'F' marking func args */
3947 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3950 /* See if we have an ARM style constructor or destructor operator.
3951 If so, then just record it, clear the decl, and return.
3952 We can't build the actual constructor/destructor decl until later,
3953 when we recover the class name from the signature. */
3955 if (strcmp (declp -> b, "__ct") == 0)
3957 work -> constructor += 1;
3958 string_clear (declp);
3961 else if (strcmp (declp -> b, "__dt") == 0)
3963 work -> destructor += 1;
3964 string_clear (declp);
3969 if (declp->p - declp->b >= 3
3970 && declp->b[0] == 'o'
3971 && declp->b[1] == 'p'
3972 && strchr (cplus_markers, declp->b[2]) != NULL)
3974 /* see if it's an assignment expression */
3975 if (declp->p - declp->b >= 10 /* op$assign_ */
3976 && memcmp (declp->b + 3, "assign_", 7) == 0)
3978 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3980 int len = declp->p - declp->b - 10;
3981 if ((int) strlen (optable[i].in) == len
3982 && memcmp (optable[i].in, declp->b + 10, len) == 0)
3984 string_clear (declp);
3985 string_append (declp, "operator");
3986 string_append (declp, optable[i].out);
3987 string_append (declp, "=");
3994 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3996 int len = declp->p - declp->b - 3;
3997 if ((int) strlen (optable[i].in) == len
3998 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4000 string_clear (declp);
4001 string_append (declp, "operator");
4002 string_append (declp, optable[i].out);
4008 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4009 && strchr (cplus_markers, declp->b[4]) != NULL)
4011 /* type conversion operator */
4013 if (do_type (work, &tem, &type))
4015 string_clear (declp);
4016 string_append (declp, "operator ");
4017 string_appends (declp, &type);
4018 string_delete (&type);
4021 else if (declp->b[0] == '_' && declp->b[1] == '_'
4022 && declp->b[2] == 'o' && declp->b[3] == 'p')
4025 /* type conversion operator. */
4027 if (do_type (work, &tem, &type))
4029 string_clear (declp);
4030 string_append (declp, "operator ");
4031 string_appends (declp, &type);
4032 string_delete (&type);
4035 else if (declp->b[0] == '_' && declp->b[1] == '_'
4036 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
4037 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
4039 if (declp->b[4] == '\0')
4042 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4044 if (strlen (optable[i].in) == 2
4045 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4047 string_clear (declp);
4048 string_append (declp, "operator");
4049 string_append (declp, optable[i].out);
4056 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4059 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4061 if (strlen (optable[i].in) == 3
4062 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4064 string_clear (declp);
4065 string_append (declp, "operator");
4066 string_append (declp, optable[i].out);
4075 /* a mini string-handling package */
4090 s->p = s->b = xmalloc (n);
4093 else if (s->e - s->p < n)
4098 s->b = xrealloc (s->b, n);
4111 s->b = s->e = s->p = NULL;
4119 s->b = s->p = s->e = NULL;
4135 return (s->b == s->p);
4141 string_append (p, s)
4146 if (s == NULL || *s == '\0')
4150 memcpy (p->p, s, n);
4155 string_appends (p, s)
4164 memcpy (p->p, s->b, n);
4170 string_appendn (p, s, n)
4178 memcpy (p->p, s, n);
4184 string_prepend (p, s)
4188 if (s != NULL && *s != '\0')
4190 string_prependn (p, s, strlen (s));
4195 string_prepends (p, s)
4200 string_prependn (p, s->b, s->p - s->b);
4205 string_prependn (p, s, n)
4215 for (q = p->p - 1; q >= p->b; q--)
4219 memcpy (p->b, s, n);
4224 /* To generate a standalone demangler program for testing purposes,
4225 just compile and link this file with -DMAIN and libiberty.a. When
4226 run, it demangles each command line arg, or each stdin string, and
4227 prints the result on stdout. */
4233 static char *program_name;
4234 static char *program_version = VERSION;
4235 static int flags = DMGL_PARAMS | DMGL_ANSI;
4237 static void demangle_it PARAMS ((char *));
4238 static void usage PARAMS ((FILE *, int));
4239 static void fatal PARAMS ((char *));
4242 demangle_it (mangled_name)
4247 result = cplus_demangle (mangled_name, flags);
4250 printf ("%s\n", mangled_name);
4254 printf ("%s\n", result);
4260 usage (stream, status)
4265 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4266 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4267 [--help] [--version] [arg...]\n",
4272 #define MBUF_SIZE 32767
4273 char mbuffer[MBUF_SIZE];
4275 /* Defined in the automatically-generated underscore.c. */
4276 extern int prepends_underscore;
4278 int strip_underscore = 0;
4280 static struct option long_options[] = {
4281 {"strip-underscores", no_argument, 0, '_'},
4282 {"format", required_argument, 0, 's'},
4283 {"help", no_argument, 0, 'h'},
4284 {"java", no_argument, 0, 'j'},
4285 {"no-strip-underscores", no_argument, 0, 'n'},
4286 {"version", no_argument, 0, 'v'},
4287 {0, no_argument, 0, 0}
4290 /* More 'friendly' abort that prints the line and file.
4291 config.h can #define abort fancy_abort if you like that sort of thing. */
4296 fatal ("Internal gcc abort.");
4307 program_name = argv[0];
4309 strip_underscore = prepends_underscore;
4311 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
4321 strip_underscore = 0;
4324 printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
4327 strip_underscore = 1;
4333 if (strcmp (optarg, "gnu") == 0)
4335 current_demangling_style = gnu_demangling;
4337 else if (strcmp (optarg, "lucid") == 0)
4339 current_demangling_style = lucid_demangling;
4341 else if (strcmp (optarg, "arm") == 0)
4343 current_demangling_style = arm_demangling;
4345 else if (strcmp (optarg, "hp") == 0)
4347 current_demangling_style = hp_demangling;
4349 else if (strcmp (optarg, "edg") == 0)
4351 current_demangling_style = edg_demangling;
4355 fprintf (stderr, "%s: unknown demangling style `%s'\n",
4356 program_name, optarg);
4365 for ( ; optind < argc; optind++)
4367 demangle_it (argv[optind]);
4376 /* Try to read a label. */
4377 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.' ||
4378 c == '<' || c == '>' || c == '#' || c == ',' || c == '*' || c == '&' ||
4379 c == '[' || c == ']' || c == ':' || c == '(' || c == ')'))
4380 /* the ones in the 2nd & 3rd lines were added to handle
4381 HP aCC template specialization manglings */
4383 if (i >= MBUF_SIZE-1)
4392 if (mbuffer[0] == '.')
4394 if (strip_underscore && mbuffer[skip_first] == '_')
4402 result = cplus_demangle (mbuffer + skip_first, flags);
4405 if (mbuffer[0] == '.')
4407 fputs (result, stdout);
4411 fputs (mbuffer, stdout);
4428 fprintf (stderr, "%s: %s\n", program_name, str);
4436 register PTR value = (PTR) malloc (size);
4438 fatal ("virtual memory exhausted");
4443 xrealloc (ptr, size)
4447 register PTR value = (PTR) realloc (ptr, size);
4449 fatal ("virtual memory exhausted");