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 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
56 static const char *mystrstr PARAMS ((const char *, const char *));
62 register const char *p = s1;
63 register int len = strlen (s2);
65 for (; (p = strchr (p, *s2)) != 0; p++)
67 if (strncmp (p, s2, len) == 0)
75 /* In order to allow a single demangler executable to demangle strings
76 using various common values of CPLUS_MARKER, as well as any specific
77 one set at compile time, we maintain a string containing all the
78 commonly used ones, and check to see if the marker we are looking for
79 is in that string. CPLUS_MARKER is usually '$' on systems where the
80 assembler can deal with that. Where the assembler can't, it's usually
81 '.' (but on many systems '.' is used for other things). We put the
82 current defined CPLUS_MARKER first (which defaults to '$'), followed
83 by the next most common value, followed by an explicit '$' in case
84 the value of CPLUS_MARKER is not '$'.
86 We could avoid this if we could just get g++ to tell us what the actual
87 cplus marker character is as part of the debug information, perhaps by
88 ensuring that it is the character that terminates the gcc<n>_compiled
89 marker symbol (FIXME). */
91 #if !defined (CPLUS_MARKER)
92 #define CPLUS_MARKER '$'
95 enum demangling_styles current_demangling_style = gnu_demangling;
97 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
99 static char char_str[2] = { '\000', '\000' };
102 set_cplus_marker_for_demangling (ch)
105 cplus_markers[0] = ch;
108 typedef struct string /* Beware: these aren't required to be */
109 { /* '\0' terminated. */
110 char *b; /* pointer to start of string */
111 char *p; /* pointer after last character */
112 char *e; /* pointer after end of allocated space */
115 /* Stuff that is shared between sub-routines.
116 Using a shared structure allows cplus_demangle to be reentrant. */
132 int static_type; /* A static member function */
133 int temp_start; /* index in demangled to start of template args */
134 int type_quals; /* The type qualifiers. */
135 int dllimported; /* Symbol imported from a PE DLL */
136 char **tmpl_argvec; /* Template function arguments. */
137 int ntmpl_args; /* The number of template function arguments. */
138 int forgetting_types; /* Nonzero if we are not remembering the types
140 string* previous_argument; /* The last function argument demangled. */
141 int nrepeats; /* The number of times to repeat the previous
145 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
146 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
148 static const struct optable
154 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
155 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
156 {"new", " new", 0}, /* old (1.91, and 1.x) */
157 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
158 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
159 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
160 {"as", "=", DMGL_ANSI}, /* ansi */
161 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
162 {"eq", "==", DMGL_ANSI}, /* old, ansi */
163 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
164 {"gt", ">", DMGL_ANSI}, /* old, ansi */
165 {"le", "<=", DMGL_ANSI}, /* old, ansi */
166 {"lt", "<", DMGL_ANSI}, /* old, ansi */
167 {"plus", "+", 0}, /* old */
168 {"pl", "+", DMGL_ANSI}, /* ansi */
169 {"apl", "+=", DMGL_ANSI}, /* ansi */
170 {"minus", "-", 0}, /* old */
171 {"mi", "-", DMGL_ANSI}, /* ansi */
172 {"ami", "-=", DMGL_ANSI}, /* ansi */
173 {"mult", "*", 0}, /* old */
174 {"ml", "*", DMGL_ANSI}, /* ansi */
175 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
176 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
177 {"convert", "+", 0}, /* old (unary +) */
178 {"negate", "-", 0}, /* old (unary -) */
179 {"trunc_mod", "%", 0}, /* old */
180 {"md", "%", DMGL_ANSI}, /* ansi */
181 {"amd", "%=", DMGL_ANSI}, /* ansi */
182 {"trunc_div", "/", 0}, /* old */
183 {"dv", "/", DMGL_ANSI}, /* ansi */
184 {"adv", "/=", DMGL_ANSI}, /* ansi */
185 {"truth_andif", "&&", 0}, /* old */
186 {"aa", "&&", DMGL_ANSI}, /* ansi */
187 {"truth_orif", "||", 0}, /* old */
188 {"oo", "||", DMGL_ANSI}, /* ansi */
189 {"truth_not", "!", 0}, /* old */
190 {"nt", "!", DMGL_ANSI}, /* ansi */
191 {"postincrement","++", 0}, /* old */
192 {"pp", "++", DMGL_ANSI}, /* ansi */
193 {"postdecrement","--", 0}, /* old */
194 {"mm", "--", DMGL_ANSI}, /* ansi */
195 {"bit_ior", "|", 0}, /* old */
196 {"or", "|", DMGL_ANSI}, /* ansi */
197 {"aor", "|=", DMGL_ANSI}, /* ansi */
198 {"bit_xor", "^", 0}, /* old */
199 {"er", "^", DMGL_ANSI}, /* ansi */
200 {"aer", "^=", DMGL_ANSI}, /* ansi */
201 {"bit_and", "&", 0}, /* old */
202 {"ad", "&", DMGL_ANSI}, /* ansi */
203 {"aad", "&=", DMGL_ANSI}, /* ansi */
204 {"bit_not", "~", 0}, /* old */
205 {"co", "~", DMGL_ANSI}, /* ansi */
206 {"call", "()", 0}, /* old */
207 {"cl", "()", DMGL_ANSI}, /* ansi */
208 {"alshift", "<<", 0}, /* old */
209 {"ls", "<<", DMGL_ANSI}, /* ansi */
210 {"als", "<<=", DMGL_ANSI}, /* ansi */
211 {"arshift", ">>", 0}, /* old */
212 {"rs", ">>", DMGL_ANSI}, /* ansi */
213 {"ars", ">>=", DMGL_ANSI}, /* ansi */
214 {"component", "->", 0}, /* old */
215 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
216 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
217 {"indirect", "*", 0}, /* old */
218 {"method_call", "->()", 0}, /* old */
219 {"addr", "&", 0}, /* old (unary &) */
220 {"array", "[]", 0}, /* old */
221 {"vc", "[]", DMGL_ANSI}, /* ansi */
222 {"compound", ", ", 0}, /* old */
223 {"cm", ", ", DMGL_ANSI}, /* ansi */
224 {"cond", "?:", 0}, /* old */
225 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
226 {"max", ">?", 0}, /* old */
227 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
228 {"min", "<?", 0}, /* old */
229 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
230 {"nop", "", 0}, /* old (for operator=) */
231 {"rm", "->*", DMGL_ANSI}, /* ansi */
232 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
235 /* These values are used to indicate the various type varieties.
236 They are all non-zero so that they can be used as `success'
238 typedef enum type_kind_t
249 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
250 #define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
251 string_prepend(str, " ");}
252 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
253 string_append(str, " ");}
254 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
256 /* The scope separator appropriate for the language being demangled. */
258 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
260 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
261 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
263 /* Prototypes for local functions */
266 mop_up PARAMS ((struct work_stuff *, string *, int));
269 squangle_mop_up PARAMS ((struct work_stuff *));
273 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
277 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
280 demangle_template_template_parm PARAMS ((struct work_stuff *work,
281 const char **, string *));
284 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
285 string *, int, int));
288 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
292 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
295 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
299 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
302 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
305 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
308 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
311 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
314 arm_special PARAMS ((const char **, string *));
317 string_need PARAMS ((string *, int));
320 string_delete PARAMS ((string *));
323 string_init PARAMS ((string *));
326 string_clear PARAMS ((string *));
330 string_empty PARAMS ((string *));
334 string_append PARAMS ((string *, const char *));
337 string_appends PARAMS ((string *, string *));
340 string_appendn PARAMS ((string *, const char *, int));
343 string_prepend PARAMS ((string *, const char *));
346 string_prependn PARAMS ((string *, const char *, int));
349 get_count PARAMS ((const char **, int *));
352 consume_count PARAMS ((const char **));
355 consume_count_with_underscores PARAMS ((const char**));
358 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
361 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
364 do_type PARAMS ((struct work_stuff *, const char **, string *));
367 do_arg PARAMS ((struct work_stuff *, const char **, string *));
370 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
374 remember_type PARAMS ((struct work_stuff *, const char *, int));
377 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
380 register_Btype PARAMS ((struct work_stuff *));
383 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
386 forget_types PARAMS ((struct work_stuff *));
389 forget_B_and_K_types PARAMS ((struct work_stuff *));
392 string_prepends PARAMS ((string *, string *));
395 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
396 string*, type_kind_t));
399 do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
402 do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
405 snarf_numeric_literal PARAMS ((const char **, string *));
407 /* There is a TYPE_QUAL value for each type qualifier. They can be
408 combined by bitwise-or to form the complete set of qualifiers for a
411 #define TYPE_UNQUALIFIED 0x0
412 #define TYPE_QUAL_CONST 0x1
413 #define TYPE_QUAL_VOLATILE 0x2
414 #define TYPE_QUAL_RESTRICT 0x4
417 code_for_qualifier PARAMS ((int));
420 qualifier_string PARAMS ((int));
423 demangle_qualifier PARAMS ((int));
425 /* Translate count to integer, consuming tokens in the process.
426 Conversion terminates on the first non-digit character.
428 Trying to consume something that isn't a count results in no
429 consumption of input and a return of -1.
431 Overflow consumes the rest of the digits, and returns -1. */
439 if (! isdigit ((unsigned char)**type))
442 while (isdigit ((unsigned char)**type))
446 /* Check for overflow.
447 We assume that count is represented using two's-complement;
448 no power of two is divisible by ten, so if an overflow occurs
449 when multiplying by ten, the result will not be a multiple of
451 if ((count % 10) != 0)
453 while (isdigit ((unsigned char) **type))
458 count += **type - '0';
466 /* Like consume_count, but for counts that are preceded and followed
467 by '_' if they are greater than 10. Also, -1 is returned for
468 failure, since 0 can be a valid value. */
471 consume_count_with_underscores (mangled)
472 const char **mangled;
476 if (**mangled == '_')
479 if (!isdigit ((unsigned char)**mangled))
482 idx = consume_count (mangled);
483 if (**mangled != '_')
484 /* The trailing underscore was missing. */
491 if (**mangled < '0' || **mangled > '9')
494 idx = **mangled - '0';
501 /* C is the code for a type-qualifier. Return the TYPE_QUAL
502 corresponding to this qualifier. */
505 code_for_qualifier (c)
511 return TYPE_QUAL_CONST;
514 return TYPE_QUAL_VOLATILE;
517 return TYPE_QUAL_RESTRICT;
523 /* C was an invalid qualifier. */
527 /* Return the string corresponding to the qualifiers given by
531 qualifier_string (type_quals)
536 case TYPE_UNQUALIFIED:
539 case TYPE_QUAL_CONST:
542 case TYPE_QUAL_VOLATILE:
545 case TYPE_QUAL_RESTRICT:
548 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
549 return "const volatile";
551 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
552 return "const __restrict";
554 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
555 return "volatile __restrict";
557 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
558 return "const volatile __restrict";
564 /* TYPE_QUALS was an invalid qualifier set. */
568 /* C is the code for a type-qualifier. Return the string
569 corresponding to this qualifier. This function should only be
570 called with a valid qualifier code. */
573 demangle_qualifier (c)
576 return qualifier_string (code_for_qualifier (c));
580 cplus_demangle_opname (opname, result, options)
587 struct work_stuff work[1];
590 len = strlen(opname);
593 memset ((char *) work, 0, sizeof (work));
594 work->options = options;
596 if (opname[0] == '_' && opname[1] == '_'
597 && opname[2] == 'o' && opname[3] == 'p')
600 /* type conversion operator. */
602 if (do_type (work, &tem, &type))
604 strcat (result, "operator ");
605 strncat (result, type.b, type.p - type.b);
606 string_delete (&type);
610 else if (opname[0] == '_' && opname[1] == '_'
611 && opname[2] >= 'a' && opname[2] <= 'z'
612 && opname[3] >= 'a' && opname[3] <= 'z')
614 if (opname[4] == '\0')
618 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
620 if (strlen (optable[i].in) == 2
621 && memcmp (optable[i].in, opname + 2, 2) == 0)
623 strcat (result, "operator");
624 strcat (result, optable[i].out);
632 if (opname[2] == 'a' && opname[5] == '\0')
636 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
638 if (strlen (optable[i].in) == 3
639 && memcmp (optable[i].in, opname + 2, 3) == 0)
641 strcat (result, "operator");
642 strcat (result, optable[i].out);
653 && strchr (cplus_markers, opname[2]) != NULL)
655 /* see if it's an assignment expression */
656 if (len >= 10 /* op$assign_ */
657 && memcmp (opname + 3, "assign_", 7) == 0)
660 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
663 if ((int) strlen (optable[i].in) == len1
664 && memcmp (optable[i].in, opname + 10, len1) == 0)
666 strcat (result, "operator");
667 strcat (result, optable[i].out);
668 strcat (result, "=");
677 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
680 if ((int) strlen (optable[i].in) == len1
681 && memcmp (optable[i].in, opname + 3, len1) == 0)
683 strcat (result, "operator");
684 strcat (result, optable[i].out);
691 else if (len >= 5 && memcmp (opname, "type", 4) == 0
692 && strchr (cplus_markers, opname[4]) != NULL)
694 /* type conversion operator */
696 if (do_type (work, &tem, &type))
698 strcat (result, "operator ");
699 strncat (result, type.b, type.p - type.b);
700 string_delete (&type);
704 squangle_mop_up (work);
708 /* Takes operator name as e.g. "++" and returns mangled
709 operator name (e.g. "postincrement_expr"), or NULL if not found.
711 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
712 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
715 cplus_mangle_opname (opname, options)
722 len = strlen (opname);
723 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
725 if ((int) strlen (optable[i].out) == len
726 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
727 && memcmp (optable[i].out, opname, len) == 0)
728 return optable[i].in;
733 /* char *cplus_demangle (const char *mangled, int options)
735 If MANGLED is a mangled function name produced by GNU C++, then
736 a pointer to a malloced string giving a C++ representation
737 of the name will be returned; otherwise NULL will be returned.
738 It is the caller's responsibility to free the string which
741 The OPTIONS arg may contain one or more of the following bits:
743 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
745 DMGL_PARAMS Function parameters are included.
749 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
750 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
751 cplus_demangle ("foo__1Ai", 0) => "A::foo"
753 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
754 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
755 cplus_demangle ("foo__1Afe", 0) => "A::foo"
757 Note that any leading underscores, or other such characters prepended by
758 the compilation system, are presumed to have already been stripped from
762 cplus_demangle (mangled, options)
767 struct work_stuff work[1];
768 memset ((char *) work, 0, sizeof (work));
769 work -> options = options;
770 if ((work -> options & DMGL_STYLE_MASK) == 0)
771 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
773 ret = internal_cplus_demangle (work, mangled);
774 squangle_mop_up (work);
779 /* This function performs most of what cplus_demangle use to do, but
780 to be able to demangle a name with a B, K or n code, we need to
781 have a longer term memory of what types have been seen. The original
782 now intializes and cleans up the squangle code info, while internal
783 calls go directly to this routine to avoid resetting that info. */
786 internal_cplus_demangle (work, mangled)
787 struct work_stuff *work;
793 char *demangled = NULL;
795 s1 = work->constructor;
796 s2 = work->destructor;
797 s3 = work->static_type;
798 s4 = work->type_quals;
799 work->constructor = work->destructor = 0;
800 work->type_quals = TYPE_UNQUALIFIED;
801 work->dllimported = 0;
803 if ((mangled != NULL) && (*mangled != '\0'))
807 /* First check to see if gnu style demangling is active and if the
808 string to be demangled contains a CPLUS_MARKER. If so, attempt to
809 recognize one of the gnu special forms rather than looking for a
810 standard prefix. In particular, don't worry about whether there
811 is a "__" string in the mangled string. Consider "_$_5__foo" for
814 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
816 success = gnu_special (work, &mangled, &decl);
820 success = demangle_prefix (work, &mangled, &decl);
822 if (success && (*mangled != '\0'))
824 success = demangle_signature (work, &mangled, &decl);
826 if (work->constructor == 2)
828 string_prepend (&decl, "global constructors keyed to ");
829 work->constructor = 0;
831 else if (work->destructor == 2)
833 string_prepend (&decl, "global destructors keyed to ");
834 work->destructor = 0;
836 else if (work->dllimported == 1)
838 string_prepend (&decl, "import stub for ");
839 work->dllimported = 0;
841 demangled = mop_up (work, &decl, success);
843 work->constructor = s1;
844 work->destructor = s2;
845 work->static_type = s3;
846 work->type_quals = s4;
851 /* Clear out and squangling related storage */
853 squangle_mop_up (work)
854 struct work_stuff *work;
856 /* clean up the B and K type mangling types. */
857 forget_B_and_K_types (work);
858 if (work -> btypevec != NULL)
860 free ((char *) work -> btypevec);
862 if (work -> ktypevec != NULL)
864 free ((char *) work -> ktypevec);
868 /* Clear out any mangled storage */
871 mop_up (work, declp, success)
872 struct work_stuff *work;
876 char *demangled = NULL;
878 /* Discard the remembered types, if any. */
881 if (work -> typevec != NULL)
883 free ((char *) work -> typevec);
884 work -> typevec = NULL;
885 work -> typevec_size = 0;
887 if (work->tmpl_argvec)
891 for (i = 0; i < work->ntmpl_args; i++)
892 if (work->tmpl_argvec[i])
893 free ((char*) work->tmpl_argvec[i]);
895 free ((char*) work->tmpl_argvec);
896 work->tmpl_argvec = NULL;
898 if (work->previous_argument)
900 string_delete (work->previous_argument);
901 free ((char*) work->previous_argument);
902 work->previous_argument = NULL;
905 /* If demangling was successful, ensure that the demangled string is null
906 terminated and return it. Otherwise, free the demangling decl. */
910 string_delete (declp);
914 string_appendn (declp, "", 1);
915 demangled = declp -> b;
924 demangle_signature -- demangle the signature part of a mangled name
929 demangle_signature (struct work_stuff *work, const char **mangled,
934 Consume and demangle the signature portion of the mangled name.
936 DECLP is the string where demangled output is being built. At
937 entry it contains the demangled root name from the mangled name
938 prefix. I.E. either a demangled operator name or the root function
939 name. In some special cases, it may contain nothing.
941 *MANGLED points to the current unconsumed location in the mangled
942 name. As tokens are consumed and demangling is performed, the
943 pointer is updated to continuously point at the next token to
946 Demangling GNU style mangled names is nasty because there is no
947 explicit token that marks the start of the outermost function
951 demangle_signature (work, mangled, declp)
952 struct work_stuff *work;
953 const char **mangled;
959 int expect_return_type = 0;
960 const char *oldmangled = NULL;
964 while (success && (**mangled != '\0'))
969 oldmangled = *mangled;
970 success = demangle_qualified (work, mangled, declp, 1, 0);
972 remember_type (work, oldmangled, *mangled - oldmangled);
973 if (AUTO_DEMANGLING || GNU_DEMANGLING)
979 oldmangled = *mangled;
980 success = demangle_qualified (work, mangled, declp, 1, 0);
981 if (AUTO_DEMANGLING || GNU_DEMANGLING)
989 /* Static member function */
990 if (oldmangled == NULL)
992 oldmangled = *mangled;
995 work -> static_type = 1;
1001 work->type_quals |= code_for_qualifier (**mangled);
1003 /* a qualified member function */
1004 if (oldmangled == NULL)
1005 oldmangled = *mangled;
1010 /* Local class name follows after "Lnnn_" */
1013 while (**mangled && (**mangled != '_'))
1024 case '0': case '1': case '2': case '3': case '4':
1025 case '5': case '6': case '7': case '8': case '9':
1026 if (oldmangled == NULL)
1028 oldmangled = *mangled;
1030 work->temp_start = -1; /* uppermost call to demangle_class */
1031 success = demangle_class (work, mangled, declp);
1034 remember_type (work, oldmangled, *mangled - oldmangled);
1036 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1038 /* EDG and others will have the "F", so we let the loop cycle
1039 if we are looking at one. */
1040 if (**mangled != 'F')
1049 success = do_type (work, mangled, &s);
1052 string_append (&s, SCOPE_STRING (work));
1053 string_prepends (declp, &s);
1062 /* ARM/HP style demangling includes a specific 'F' character after
1063 the class name. For GNU style, it is just implied. So we can
1064 safely just consume any 'F' at this point and be compatible
1065 with either style. */
1071 /* For lucid/ARM/HP style we have to forget any types we might
1072 have remembered up to this point, since they were not argument
1073 types. GNU style considers all types seen as available for
1074 back references. See comment in demangle_args() */
1076 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1078 forget_types (work);
1080 success = demangle_args (work, mangled, declp);
1081 /* After picking off the function args, we expect to either
1082 find the function return type (preceded by an '_') or the
1083 end of the string. */
1084 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1087 /* At this level, we do not care about the return type. */
1088 success = do_type (work, mangled, &tname);
1089 string_delete (&tname);
1096 string_init(&trawname);
1097 string_init(&tname);
1098 if (oldmangled == NULL)
1100 oldmangled = *mangled;
1102 success = demangle_template (work, mangled, &tname,
1106 remember_type (work, oldmangled, *mangled - oldmangled);
1108 string_append (&tname, SCOPE_STRING (work));
1110 string_prepends(declp, &tname);
1111 if (work -> destructor & 1)
1113 string_prepend (&trawname, "~");
1114 string_appends (declp, &trawname);
1115 work->destructor -= 1;
1117 if ((work->constructor & 1) || (work->destructor & 1))
1119 string_appends (declp, &trawname);
1120 work->constructor -= 1;
1122 string_delete(&trawname);
1123 string_delete(&tname);
1129 if (GNU_DEMANGLING && expect_return_type)
1131 /* Read the return type. */
1133 string_init (&return_type);
1136 success = do_type (work, mangled, &return_type);
1137 APPEND_BLANK (&return_type);
1139 string_prepends (declp, &return_type);
1140 string_delete (&return_type);
1144 /* At the outermost level, we cannot have a return type specified,
1145 so if we run into another '_' at this point we are dealing with
1146 a mangled name that is either bogus, or has been mangled by
1147 some algorithm we don't know how to deal with. So just
1148 reject the entire demangling. */
1149 /* However, "_nnn" is an expected suffix for alternate entry point
1150 numbered nnn for a function, with HP aCC, so skip over that
1151 without reporting failure. pai/1997-09-04 */
1155 while (**mangled && isdigit ((unsigned char)**mangled))
1165 /* A G++ template function. Read the template arguments. */
1166 success = demangle_template (work, mangled, declp, 0, 0,
1168 if (!(work->constructor & 1))
1169 expect_return_type = 1;
1178 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1180 /* Assume we have stumbled onto the first outermost function
1181 argument token, and start processing args. */
1183 success = demangle_args (work, mangled, declp);
1187 /* Non-GNU demanglers use a specific token to mark the start
1188 of the outermost function argument tokens. Typically 'F',
1189 for ARM/HP-demangling, for example. So if we find something
1190 we are not prepared for, it must be an error. */
1196 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1199 if (success && expect_func)
1202 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1204 forget_types (work);
1206 success = demangle_args (work, mangled, declp);
1207 /* Since template include the mangling of their return types,
1208 we must set expect_func to 0 so that we don't try do
1209 demangle more arguments the next time we get here. */
1214 if (success && !func_done)
1216 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1218 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1219 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1220 first case, and need to ensure that the '(void)' gets added to
1221 the current declp. Note that with ARM/HP, the first case
1222 represents the name of a static data member 'foo::bar',
1223 which is in the current declp, so we leave it alone. */
1224 success = demangle_args (work, mangled, declp);
1227 if (success && PRINT_ARG_TYPES)
1229 if (work->static_type)
1230 string_append (declp, " static");
1231 if (work->type_quals != TYPE_UNQUALIFIED)
1233 APPEND_BLANK (declp);
1234 string_append (declp, qualifier_string (work->type_quals));
1244 demangle_method_args (work, mangled, declp)
1245 struct work_stuff *work;
1246 const char **mangled;
1251 if (work -> static_type)
1253 string_append (declp, *mangled + 1);
1254 *mangled += strlen (*mangled);
1259 success = demangle_args (work, mangled, declp);
1267 demangle_template_template_parm (work, mangled, tname)
1268 struct work_stuff *work;
1269 const char **mangled;
1278 string_append (tname, "template <");
1279 /* get size of template parameter list */
1280 if (get_count (mangled, &r))
1282 for (i = 0; i < r; i++)
1286 string_append (tname, ", ");
1289 /* Z for type parameters */
1290 if (**mangled == 'Z')
1293 string_append (tname, "class");
1295 /* z for template parameters */
1296 else if (**mangled == 'z')
1300 demangle_template_template_parm (work, mangled, tname);
1308 /* temp is initialized in do_type */
1309 success = do_type (work, mangled, &temp);
1312 string_appends (tname, &temp);
1314 string_delete(&temp);
1324 if (tname->p[-1] == '>')
1325 string_append (tname, " ");
1326 string_append (tname, "> class");
1331 demangle_integral_value (work, mangled, s)
1332 struct work_stuff *work;
1333 const char** mangled;
1338 if (**mangled == 'E')
1340 int need_operator = 0;
1343 string_appendn (s, "(", 1);
1345 while (success && **mangled != 'W' && **mangled != '\0')
1354 len = strlen (*mangled);
1357 i < sizeof (optable) / sizeof (optable [0]);
1360 size_t l = strlen (optable[i].in);
1363 && memcmp (optable[i].in, *mangled, l) == 0)
1365 string_appendn (s, " ", 1);
1366 string_append (s, optable[i].out);
1367 string_appendn (s, " ", 1);
1380 success = demangle_template_value_parm (work, mangled, s,
1384 if (**mangled != 'W')
1388 string_appendn (s, ")", 1);
1392 else if (**mangled == 'Q' || **mangled == 'K')
1393 success = demangle_qualified (work, mangled, s, 0, 1);
1398 if (**mangled == 'm')
1400 string_appendn (s, "-", 1);
1403 while (isdigit ((unsigned char)**mangled))
1405 string_appendn (s, *mangled, 1);
1415 demangle_template_value_parm (work, mangled, s, tk)
1416 struct work_stuff *work;
1417 const char **mangled;
1423 if (**mangled == 'Y')
1425 /* The next argument is a template parameter. */
1429 idx = consume_count_with_underscores (mangled);
1431 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1432 || consume_count_with_underscores (mangled) == -1)
1434 if (work->tmpl_argvec)
1435 string_append (s, work->tmpl_argvec[idx]);
1439 sprintf(buf, "T%d", idx);
1440 string_append (s, buf);
1443 else if (tk == tk_integral)
1444 success = demangle_integral_value (work, mangled, s);
1445 else if (tk == tk_char)
1449 if (**mangled == 'm')
1451 string_appendn (s, "-", 1);
1454 string_appendn (s, "'", 1);
1455 val = consume_count(mangled);
1462 string_appendn (s, &tmp[0], 1);
1463 string_appendn (s, "'", 1);
1466 else if (tk == tk_bool)
1468 int val = consume_count (mangled);
1470 string_appendn (s, "false", 5);
1472 string_appendn (s, "true", 4);
1476 else if (tk == tk_real)
1478 if (**mangled == 'm')
1480 string_appendn (s, "-", 1);
1483 while (isdigit ((unsigned char)**mangled))
1485 string_appendn (s, *mangled, 1);
1488 if (**mangled == '.') /* fraction */
1490 string_appendn (s, ".", 1);
1492 while (isdigit ((unsigned char)**mangled))
1494 string_appendn (s, *mangled, 1);
1498 if (**mangled == 'e') /* exponent */
1500 string_appendn (s, "e", 1);
1502 while (isdigit ((unsigned char)**mangled))
1504 string_appendn (s, *mangled, 1);
1509 else if (tk == tk_pointer || tk == tk_reference)
1511 if (**mangled == 'Q')
1512 success = demangle_qualified (work, mangled, s,
1517 int symbol_len = consume_count (mangled);
1518 if (symbol_len == -1)
1520 if (symbol_len == 0)
1521 string_appendn (s, "0", 1);
1524 char *p = xmalloc (symbol_len + 1), *q;
1525 strncpy (p, *mangled, symbol_len);
1526 p [symbol_len] = '\0';
1527 /* We use cplus_demangle here, rather than
1528 internal_cplus_demangle, because the name of the entity
1529 mangled here does not make use of any of the squangling
1530 or type-code information we have built up thus far; it is
1531 mangled independently. */
1532 q = cplus_demangle (p, work->options);
1533 if (tk == tk_pointer)
1534 string_appendn (s, "&", 1);
1535 /* FIXME: Pointer-to-member constants should get a
1536 qualifying class name here. */
1539 string_append (s, q);
1543 string_append (s, p);
1546 *mangled += symbol_len;
1553 /* Demangle the template name in MANGLED. The full name of the
1554 template (e.g., S<int>) is placed in TNAME. The name without the
1555 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1556 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1557 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1558 the tmeplate is remembered in the list of back-referenceable
1562 demangle_template (work, mangled, tname, trawname, is_type, remember)
1563 struct work_stuff *work;
1564 const char **mangled;
1575 int is_java_array = 0;
1583 bindex = register_Btype (work);
1585 /* get template name */
1586 if (**mangled == 'z')
1592 idx = consume_count_with_underscores (mangled);
1594 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1595 || consume_count_with_underscores (mangled) == -1)
1598 if (work->tmpl_argvec)
1600 string_append (tname, work->tmpl_argvec[idx]);
1602 string_append (trawname, work->tmpl_argvec[idx]);
1607 sprintf(buf, "T%d", idx);
1608 string_append (tname, buf);
1610 string_append (trawname, buf);
1615 if ((r = consume_count (mangled)) <= 0
1616 || (int) strlen (*mangled) < r)
1620 is_java_array = (work -> options & DMGL_JAVA)
1621 && strncmp (*mangled, "JArray1Z", 8) == 0;
1622 if (! is_java_array)
1624 string_appendn (tname, *mangled, r);
1627 string_appendn (trawname, *mangled, r);
1632 string_append (tname, "<");
1633 /* get size of template parameter list */
1634 if (!get_count (mangled, &r))
1640 /* Create an array for saving the template argument values. */
1641 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1642 work->ntmpl_args = r;
1643 for (i = 0; i < r; i++)
1644 work->tmpl_argvec[i] = 0;
1646 for (i = 0; i < r; i++)
1650 string_append (tname, ", ");
1652 /* Z for type parameters */
1653 if (**mangled == 'Z')
1656 /* temp is initialized in do_type */
1657 success = do_type (work, mangled, &temp);
1660 string_appends (tname, &temp);
1664 /* Save the template argument. */
1665 int len = temp.p - temp.b;
1666 work->tmpl_argvec[i] = xmalloc (len + 1);
1667 memcpy (work->tmpl_argvec[i], temp.b, len);
1668 work->tmpl_argvec[i][len] = '\0';
1671 string_delete(&temp);
1677 /* z for template parameters */
1678 else if (**mangled == 'z')
1682 success = demangle_template_template_parm (work, mangled, tname);
1685 && (r2 = consume_count (mangled)) > 0
1686 && (int) strlen (*mangled) >= r2)
1688 string_append (tname, " ");
1689 string_appendn (tname, *mangled, r2);
1692 /* Save the template argument. */
1694 work->tmpl_argvec[i] = xmalloc (len + 1);
1695 memcpy (work->tmpl_argvec[i], *mangled, len);
1696 work->tmpl_argvec[i][len] = '\0';
1710 /* otherwise, value parameter */
1712 /* temp is initialized in do_type */
1713 success = do_type (work, mangled, &temp);
1714 string_delete(&temp);
1726 success = demangle_template_value_parm (work, mangled, s,
1727 (type_kind_t) success);
1739 int len = s->p - s->b;
1740 work->tmpl_argvec[i] = xmalloc (len + 1);
1741 memcpy (work->tmpl_argvec[i], s->b, len);
1742 work->tmpl_argvec[i][len] = '\0';
1744 string_appends (tname, s);
1752 string_append (tname, "[]");
1756 if (tname->p[-1] == '>')
1757 string_append (tname, " ");
1758 string_append (tname, ">");
1761 if (is_type && remember)
1762 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1765 if (work -> static_type)
1767 string_append (declp, *mangled + 1);
1768 *mangled += strlen (*mangled);
1773 success = demangle_args (work, mangled, declp);
1781 arm_pt (work, mangled, n, anchor, args)
1782 struct work_stuff *work;
1783 const char *mangled;
1785 const char **anchor, **args;
1787 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1788 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1789 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
1792 *args = *anchor + 6;
1793 len = consume_count (args);
1796 if (*args + len == mangled + n && **args == '_')
1802 if (AUTO_DEMANGLING || EDG_DEMANGLING)
1804 if ((*anchor = mystrstr (mangled, "__tm__"))
1805 || (*anchor = mystrstr (mangled, "__ps__"))
1806 || (*anchor = mystrstr (mangled, "__pt__")))
1809 *args = *anchor + 6;
1810 len = consume_count (args);
1813 if (*args + len == mangled + n && **args == '_')
1819 else if ((*anchor = mystrstr (mangled, "__S")))
1822 *args = *anchor + 3;
1823 len = consume_count (args);
1826 if (*args + len == mangled + n && **args == '_')
1838 demangle_arm_hp_template (work, mangled, n, declp)
1839 struct work_stuff *work;
1840 const char **mangled;
1846 const char *e = *mangled + n;
1849 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1851 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
1853 char *start_spec_args = NULL;
1855 /* First check for and omit template specialization pseudo-arguments,
1856 such as in "Spec<#1,#1.*>" */
1857 start_spec_args = strchr (*mangled, '<');
1858 if (start_spec_args && (start_spec_args - *mangled < n))
1859 string_appendn (declp, *mangled, start_spec_args - *mangled);
1861 string_appendn (declp, *mangled, n);
1862 (*mangled) += n + 1;
1864 if (work->temp_start == -1) /* non-recursive call */
1865 work->temp_start = declp->p - declp->b;
1866 string_append (declp, "<");
1869 string_clear (&arg);
1873 /* 'T' signals a type parameter */
1875 if (!do_type (work, mangled, &arg))
1876 goto hpacc_template_args_done;
1881 /* 'U' or 'S' signals an integral value */
1882 if (!do_hpacc_template_const_value (work, mangled, &arg))
1883 goto hpacc_template_args_done;
1887 /* 'A' signals a named constant expression (literal) */
1888 if (!do_hpacc_template_literal (work, mangled, &arg))
1889 goto hpacc_template_args_done;
1893 /* Today, 1997-09-03, we have only the above types
1894 of template parameters */
1895 /* FIXME: maybe this should fail and return null */
1896 goto hpacc_template_args_done;
1898 string_appends (declp, &arg);
1899 /* Check if we're at the end of template args.
1900 0 if at end of static member of template class,
1901 _ if done with template args for a function */
1902 if ((**mangled == '\000') || (**mangled == '_'))
1905 string_append (declp, ",");
1907 hpacc_template_args_done:
1908 string_append (declp, ">");
1909 string_delete (&arg);
1910 if (**mangled == '_')
1914 /* ARM template? (Also handles HP cfront extensions) */
1915 else if (arm_pt (work, *mangled, n, &p, &args))
1920 string_appendn (declp, *mangled, p - *mangled);
1921 if (work->temp_start == -1) /* non-recursive call */
1922 work->temp_start = declp->p - declp->b;
1923 string_append (declp, "<");
1924 /* should do error checking here */
1926 string_clear (&arg);
1928 /* Check for type or literal here */
1931 /* HP cfront extensions to ARM for template args */
1932 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1933 /* FIXME: We handle only numeric literals for HP cfront */
1935 /* A typed constant value follows */
1937 if (!do_type (work, &args, &type_str))
1938 goto cfront_template_args_done;
1939 string_append (&arg, "(");
1940 string_appends (&arg, &type_str);
1941 string_append (&arg, ")");
1943 goto cfront_template_args_done;
1945 /* Now snarf a literal value following 'L' */
1946 if (!snarf_numeric_literal (&args, &arg))
1947 goto cfront_template_args_done;
1951 /* Snarf a literal following 'L' */
1953 if (!snarf_numeric_literal (&args, &arg))
1954 goto cfront_template_args_done;
1957 /* Not handling other HP cfront stuff */
1958 if (!do_type (work, &args, &arg))
1959 goto cfront_template_args_done;
1961 string_appends (declp, &arg);
1962 string_append (declp, ",");
1964 cfront_template_args_done:
1965 string_delete (&arg);
1967 --declp->p; /* remove extra comma */
1968 string_append (declp, ">");
1970 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1971 && (*mangled)[9] == 'N'
1972 && (*mangled)[8] == (*mangled)[10]
1973 && strchr (cplus_markers, (*mangled)[8]))
1975 /* A member of the anonymous namespace. */
1976 string_append (declp, "{anonymous}");
1980 if (work->temp_start == -1) /* non-recursive call only */
1981 work->temp_start = 0; /* disable in recursive calls */
1982 string_appendn (declp, *mangled, n);
1987 /* Extract a class name, possibly a template with arguments, from the
1988 mangled string; qualifiers, local class indicators, etc. have
1989 already been dealt with */
1992 demangle_class_name (work, mangled, declp)
1993 struct work_stuff *work;
1994 const char **mangled;
2000 n = consume_count (mangled);
2003 if ((int) strlen (*mangled) >= n)
2005 demangle_arm_hp_template (work, mangled, n, declp);
2016 demangle_class -- demangle a mangled class sequence
2021 demangle_class (struct work_stuff *work, const char **mangled,
2026 DECLP points to the buffer into which demangling is being done.
2028 *MANGLED points to the current token to be demangled. On input,
2029 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2030 On exit, it points to the next token after the mangled class on
2031 success, or the first unconsumed token on failure.
2033 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2034 we are demangling a constructor or destructor. In this case
2035 we prepend "class::class" or "class::~class" to DECLP.
2037 Otherwise, we prepend "class::" to the current DECLP.
2039 Reset the constructor/destructor flags once they have been
2040 "consumed". This allows demangle_class to be called later during
2041 the same demangling, to do normal class demangling.
2043 Returns 1 if demangling is successful, 0 otherwise.
2048 demangle_class (work, mangled, declp)
2049 struct work_stuff *work;
2050 const char **mangled;
2056 char *save_class_name_end = 0;
2058 string_init (&class_name);
2059 btype = register_Btype (work);
2060 if (demangle_class_name (work, mangled, &class_name))
2062 save_class_name_end = class_name.p;
2063 if ((work->constructor & 1) || (work->destructor & 1))
2065 /* adjust so we don't include template args */
2066 if (work->temp_start && (work->temp_start != -1))
2068 class_name.p = class_name.b + work->temp_start;
2070 string_prepends (declp, &class_name);
2071 if (work -> destructor & 1)
2073 string_prepend (declp, "~");
2074 work -> destructor -= 1;
2078 work -> constructor -= 1;
2081 class_name.p = save_class_name_end;
2082 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2083 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2084 string_prepend (declp, SCOPE_STRING (work));
2085 string_prepends (declp, &class_name);
2088 string_delete (&class_name);
2096 demangle_prefix -- consume the mangled name prefix and find signature
2101 demangle_prefix (struct work_stuff *work, const char **mangled,
2106 Consume and demangle the prefix of the mangled name.
2108 DECLP points to the string buffer into which demangled output is
2109 placed. On entry, the buffer is empty. On exit it contains
2110 the root function name, the demangled operator name, or in some
2111 special cases either nothing or the completely demangled result.
2113 MANGLED points to the current pointer into the mangled name. As each
2114 token of the mangled name is consumed, it is updated. Upon entry
2115 the current mangled name pointer points to the first character of
2116 the mangled name. Upon exit, it should point to the first character
2117 of the signature if demangling was successful, or to the first
2118 unconsumed character if demangling of the prefix was unsuccessful.
2120 Returns 1 on success, 0 otherwise.
2124 demangle_prefix (work, mangled, declp)
2125 struct work_stuff *work;
2126 const char **mangled;
2133 if (strlen(*mangled) > 6
2134 && (strncmp(*mangled, "_imp__", 6) == 0
2135 || strncmp(*mangled, "__imp_", 6) == 0))
2137 /* it's a symbol imported from a PE dynamic library. Check for both
2138 new style prefix _imp__ and legacy __imp_ used by older versions
2141 work->dllimported = 1;
2143 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2145 char *marker = strchr (cplus_markers, (*mangled)[8]);
2146 if (marker != NULL && *marker == (*mangled)[10])
2148 if ((*mangled)[9] == 'D')
2150 /* it's a GNU global destructor to be executed at program exit */
2152 work->destructor = 2;
2153 if (gnu_special (work, mangled, declp))
2156 else if ((*mangled)[9] == 'I')
2158 /* it's a GNU global constructor to be executed at program init */
2160 work->constructor = 2;
2161 if (gnu_special (work, mangled, declp))
2166 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2168 /* it's a ARM global destructor to be executed at program exit */
2170 work->destructor = 2;
2172 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2174 /* it's a ARM global constructor to be executed at program initial */
2176 work->constructor = 2;
2179 /* This block of code is a reduction in strength time optimization
2181 scan = mystrstr (*mangled, "__"); */
2187 scan = strchr (scan, '_');
2188 } while (scan != NULL && *++scan != '_');
2190 if (scan != NULL) --scan;
2195 /* We found a sequence of two or more '_', ensure that we start at
2196 the last pair in the sequence. */
2197 i = strspn (scan, "_");
2208 else if (work -> static_type)
2210 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
2215 else if ((scan == *mangled)
2216 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
2217 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2219 /* The ARM says nothing about the mangling of local variables.
2220 But cfront mangles local variables by prepending __<nesting_level>
2221 to them. As an extension to ARM demangling we handle this case. */
2222 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2223 && isdigit ((unsigned char)scan[2]))
2225 *mangled = scan + 2;
2226 consume_count (mangled);
2227 string_append (declp, *mangled);
2228 *mangled += strlen (*mangled);
2233 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2234 names like __Q2_3foo3bar for nested type names. So don't accept
2235 this style of constructor for cfront demangling. A GNU
2236 style member-template constructor starts with 'H'. */
2237 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2238 work -> constructor += 1;
2239 *mangled = scan + 2;
2242 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2244 /* Cfront-style parameterized type. Handled later as a signature. */
2248 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2250 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2251 || (scan[2] == 'p' && scan[3] == 's')
2252 || (scan[2] == 'p' && scan[3] == 't')))
2254 /* EDG-style parameterized type. Handled later as a signature. */
2258 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2260 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
2261 && (scan[2] != 't'))
2263 /* Mangled name starts with "__". Skip over any leading '_' characters,
2264 then find the next "__" that separates the prefix from the signature.
2266 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2267 || (arm_special (mangled, declp) == 0))
2269 while (*scan == '_')
2273 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2275 /* No separator (I.E. "__not_mangled"), or empty signature
2276 (I.E. "__not_mangled_either__") */
2283 /* Look for the LAST occurrence of __, allowing names to
2284 have the '__' sequence embedded in them. */
2285 if (!(ARM_DEMANGLING || HP_DEMANGLING))
2287 while ((tmp = mystrstr (scan + 2, "__")) != NULL)
2290 if (*(scan + 2) == '\0')
2293 demangle_function_name (work, mangled, declp, scan);
2297 else if (*(scan + 2) != '\0')
2299 /* Mangled name does not start with "__" but does have one somewhere
2300 in there with non empty stuff after it. Looks like a global
2302 demangle_function_name (work, mangled, declp, scan);
2306 /* Doesn't look like a mangled name */
2310 if (!success && (work->constructor == 2 || work->destructor == 2))
2312 string_append (declp, *mangled);
2313 *mangled += strlen (*mangled);
2323 gnu_special -- special handling of gnu mangled strings
2328 gnu_special (struct work_stuff *work, const char **mangled,
2334 Process some special GNU style mangling forms that don't fit
2335 the normal pattern. For example:
2337 _$_3foo (destructor for class foo)
2338 _vt$foo (foo virtual table)
2339 _vt$foo$bar (foo::bar virtual table)
2340 __vt_foo (foo virtual table, new style with thunks)
2341 _3foo$varname (static data member)
2342 _Q22rs2tu$vw (static data member)
2343 __t6vector1Zii (constructor with template)
2344 __thunk_4__$_7ostream (virtual function thunk)
2348 gnu_special (work, mangled, declp)
2349 struct work_stuff *work;
2350 const char **mangled;
2357 if ((*mangled)[0] == '_'
2358 && strchr (cplus_markers, (*mangled)[1]) != NULL
2359 && (*mangled)[2] == '_')
2361 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2363 work -> destructor += 1;
2365 else if ((*mangled)[0] == '_'
2366 && (((*mangled)[1] == '_'
2367 && (*mangled)[2] == 'v'
2368 && (*mangled)[3] == 't'
2369 && (*mangled)[4] == '_')
2370 || ((*mangled)[1] == 'v'
2371 && (*mangled)[2] == 't'
2372 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2374 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2375 and create the decl. Note that we consume the entire mangled
2376 input string, which means that demangle_signature has no work
2378 if ((*mangled)[2] == 'v')
2379 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2381 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2382 while (**mangled != '\0')
2388 success = demangle_qualified (work, mangled, declp, 0, 1);
2391 success = demangle_template (work, mangled, declp, 0, 1,
2395 if (isdigit((unsigned char)*mangled[0]))
2397 n = consume_count(mangled);
2398 /* We may be seeing a too-large size, or else a
2399 ".<digits>" indicating a static local symbol. In
2400 any case, declare victory and move on; *don't* try
2401 to use n to allocate. */
2402 if (n > (int) strlen (*mangled))
2410 n = strcspn (*mangled, cplus_markers);
2412 string_appendn (declp, *mangled, n);
2416 p = strpbrk (*mangled, cplus_markers);
2417 if (success && ((p == NULL) || (p == *mangled)))
2421 string_append (declp, SCOPE_STRING (work));
2432 string_append (declp, " virtual table");
2434 else if ((*mangled)[0] == '_'
2435 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2436 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2438 /* static data member, "_3foo$varname" for example */
2444 success = demangle_qualified (work, mangled, declp, 0, 1);
2447 success = demangle_template (work, mangled, declp, 0, 1, 1);
2450 n = consume_count (mangled);
2451 if (n < 0 || n > strlen (*mangled))
2456 string_appendn (declp, *mangled, n);
2459 if (success && (p == *mangled))
2461 /* Consumed everything up to the cplus_marker, append the
2464 string_append (declp, SCOPE_STRING (work));
2465 n = strlen (*mangled);
2466 string_appendn (declp, *mangled, n);
2474 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2479 delta = consume_count (mangled);
2484 char *method = internal_cplus_demangle (work, ++*mangled);
2489 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2490 string_append (declp, buf);
2491 string_append (declp, method);
2493 n = strlen (*mangled);
2502 else if (strncmp (*mangled, "__t", 3) == 0
2503 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2505 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2511 success = demangle_qualified (work, mangled, declp, 0, 1);
2514 success = demangle_template (work, mangled, declp, 0, 1, 1);
2517 success = demangle_fund_type (work, mangled, declp);
2520 if (success && **mangled != '\0')
2523 string_append (declp, p);
2533 recursively_demangle(work, mangled, result, namelength)
2534 struct work_stuff *work;
2535 const char **mangled;
2539 char * recurse = (char *)NULL;
2540 char * recurse_dem = (char *)NULL;
2542 recurse = (char *) xmalloc (namelength + 1);
2543 memcpy (recurse, *mangled, namelength);
2544 recurse[namelength] = '\000';
2546 recurse_dem = cplus_demangle (recurse, work->options);
2550 string_append (result, recurse_dem);
2555 string_appendn (result, *mangled, namelength);
2558 *mangled += namelength;
2565 arm_special -- special handling of ARM/lucid mangled strings
2570 arm_special (const char **mangled,
2576 Process some special ARM style mangling forms that don't fit
2577 the normal pattern. For example:
2579 __vtbl__3foo (foo virtual table)
2580 __vtbl__3foo__3bar (bar::foo virtual table)
2585 arm_special (mangled, declp)
2586 const char **mangled;
2593 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2595 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2596 and create the decl. Note that we consume the entire mangled
2597 input string, which means that demangle_signature has no work
2599 scan = *mangled + ARM_VTABLE_STRLEN;
2600 while (*scan != '\0') /* first check it can be demangled */
2602 n = consume_count (&scan);
2605 return (0); /* no good */
2608 if (scan[0] == '_' && scan[1] == '_')
2613 (*mangled) += ARM_VTABLE_STRLEN;
2614 while (**mangled != '\0')
2616 n = consume_count (mangled);
2618 || n > strlen (*mangled))
2620 string_prependn (declp, *mangled, n);
2622 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2624 string_prepend (declp, "::");
2628 string_append (declp, " virtual table");
2641 demangle_qualified -- demangle 'Q' qualified name strings
2646 demangle_qualified (struct work_stuff *, const char *mangled,
2647 string *result, int isfuncname, int append);
2651 Demangle a qualified name, such as "Q25Outer5Inner" which is
2652 the mangled form of "Outer::Inner". The demangled output is
2653 prepended or appended to the result string according to the
2654 state of the append flag.
2656 If isfuncname is nonzero, then the qualified name we are building
2657 is going to be used as a member function name, so if it is a
2658 constructor or destructor function, append an appropriate
2659 constructor or destructor name. I.E. for the above example,
2660 the result for use as a constructor is "Outer::Inner::Inner"
2661 and the result for use as a destructor is "Outer::Inner::~Inner".
2665 Numeric conversion is ASCII dependent (FIXME).
2670 demangle_qualified (work, mangled, result, isfuncname, append)
2671 struct work_stuff *work;
2672 const char **mangled;
2683 int bindex = register_Btype (work);
2685 /* We only make use of ISFUNCNAME if the entity is a constructor or
2687 isfuncname = (isfuncname
2688 && ((work->constructor & 1) || (work->destructor & 1)));
2690 string_init (&temp);
2691 string_init (&last_name);
2693 if ((*mangled)[0] == 'K')
2695 /* Squangling qualified name reuse */
2698 idx = consume_count_with_underscores (mangled);
2699 if (idx == -1 || idx >= work -> numk)
2702 string_append (&temp, work -> ktypevec[idx]);
2705 switch ((*mangled)[1])
2708 /* GNU mangled name with more than 9 classes. The count is preceded
2709 by an underscore (to distinguish it from the <= 9 case) and followed
2710 by an underscore. */
2712 qualifiers = atoi (p);
2713 if (!isdigit ((unsigned char)*p) || *p == '0')
2716 /* Skip the digits. */
2717 while (isdigit ((unsigned char)*p))
2735 /* The count is in a single digit. */
2736 num[0] = (*mangled)[1];
2738 qualifiers = atoi (num);
2740 /* If there is an underscore after the digit, skip it. This is
2741 said to be for ARM-qualified names, but the ARM makes no
2742 mention of such an underscore. Perhaps cfront uses one. */
2743 if ((*mangled)[2] == '_')
2758 /* Pick off the names and collect them in the temp buffer in the order
2759 in which they are found, separated by '::'. */
2761 while (qualifiers-- > 0)
2764 string_clear (&last_name);
2766 if (*mangled[0] == '_')
2769 if (*mangled[0] == 't')
2771 /* Here we always append to TEMP since we will want to use
2772 the template name without the template parameters as a
2773 constructor or destructor name. The appropriate
2774 (parameter-less) value is returned by demangle_template
2775 in LAST_NAME. We do not remember the template type here,
2776 in order to match the G++ mangling algorithm. */
2777 success = demangle_template(work, mangled, &temp,
2782 else if (*mangled[0] == 'K')
2786 idx = consume_count_with_underscores (mangled);
2787 if (idx == -1 || idx >= work->numk)
2790 string_append (&temp, work->ktypevec[idx]);
2793 if (!success) break;
2800 /* Now recursively demangle the qualifier
2801 * This is necessary to deal with templates in
2802 * mangling styles like EDG */
2803 namelength = consume_count (mangled);
2804 if (namelength == -1)
2809 recursively_demangle(work, mangled, &temp, namelength);
2813 success = do_type (work, mangled, &last_name);
2816 string_appends (&temp, &last_name);
2821 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2824 string_append (&temp, SCOPE_STRING (work));
2827 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2829 /* If we are using the result as a function name, we need to append
2830 the appropriate '::' separated constructor or destructor name.
2831 We do this here because this is the most convenient place, where
2832 we already have a pointer to the name and the length of the name. */
2836 string_append (&temp, SCOPE_STRING (work));
2837 if (work -> destructor & 1)
2838 string_append (&temp, "~");
2839 string_appends (&temp, &last_name);
2842 /* Now either prepend the temp buffer to the result, or append it,
2843 depending upon the state of the append flag. */
2846 string_appends (result, &temp);
2849 if (!STRING_EMPTY (result))
2850 string_append (&temp, SCOPE_STRING (work));
2851 string_prepends (result, &temp);
2854 string_delete (&last_name);
2855 string_delete (&temp);
2863 get_count -- convert an ascii count to integer, consuming tokens
2868 get_count (const char **type, int *count)
2872 Assume that *type points at a count in a mangled name; set
2873 *count to its value, and set *type to the next character after
2874 the count. There are some weird rules in effect here.
2876 If *type does not point at a string of digits, return zero.
2878 If *type points at a string of digits followed by an
2879 underscore, set *count to their value as an integer, advance
2880 *type to point *after the underscore, and return 1.
2882 If *type points at a string of digits not followed by an
2883 underscore, consume only the first digit. Set *count to its
2884 value as an integer, leave *type pointing after that digit,
2887 The excuse for this odd behavior: in the ARM and HP demangling
2888 styles, a type can be followed by a repeat count of the form
2891 `x' is a single digit specifying how many additional copies
2892 of the type to append to the argument list, and
2894 `y' is one or more digits, specifying the zero-based index of
2895 the first repeated argument in the list. Yes, as you're
2896 unmangling the name you can figure this out yourself, but
2899 So, for example, in `bar__3fooFPiN51', the first argument is a
2900 pointer to an integer (`Pi'), and then the next five arguments
2901 are the same (`N5'), and the first repeat is the function's
2902 second argument (`1').
2906 get_count (type, count)
2913 if (!isdigit ((unsigned char)**type))
2919 *count = **type - '0';
2921 if (isdigit ((unsigned char)**type))
2931 while (isdigit ((unsigned char)*p));
2942 /* RESULT will be initialised here; it will be freed on failure. The
2943 value returned is really a type_kind_t. */
2946 do_type (work, mangled, result)
2947 struct work_stuff *work;
2948 const char **mangled;
2955 const char *remembered_type;
2958 type_kind_t tk = tk_none;
2960 string_init (&btype);
2961 string_init (&decl);
2962 string_init (result);
2966 while (success && !done)
2972 /* A pointer type */
2976 if (! (work -> options & DMGL_JAVA))
2977 string_prepend (&decl, "*");
2982 /* A reference type */
2985 string_prepend (&decl, "&");
2994 if (!STRING_EMPTY (&decl)
2995 && (decl.b[0] == '*' || decl.b[0] == '&'))
2997 string_prepend (&decl, "(");
2998 string_append (&decl, ")");
3000 string_append (&decl, "[");
3001 if (**mangled != '_')
3002 success = demangle_template_value_parm (work, mangled, &decl,
3004 if (**mangled == '_')
3006 string_append (&decl, "]");
3010 /* A back reference to a previously seen type */
3013 if (!get_count (mangled, &n) || n >= work -> ntypes)
3019 remembered_type = work -> typevec[n];
3020 mangled = &remembered_type;
3027 if (!STRING_EMPTY (&decl)
3028 && (decl.b[0] == '*' || decl.b[0] == '&'))
3030 string_prepend (&decl, "(");
3031 string_append (&decl, ")");
3033 /* After picking off the function args, we expect to either find the
3034 function return type (preceded by an '_') or the end of the
3036 if (!demangle_nested_args (work, mangled, &decl)
3037 || (**mangled != '_' && **mangled != '\0'))
3042 if (success && (**mangled == '_'))
3049 type_quals = TYPE_UNQUALIFIED;
3051 member = **mangled == 'M';
3054 string_append (&decl, ")");
3055 string_prepend (&decl, SCOPE_STRING (work));
3056 if (isdigit ((unsigned char)**mangled))
3058 n = consume_count (mangled);
3060 || (int) strlen (*mangled) < n)
3065 string_prependn (&decl, *mangled, n);
3068 else if (**mangled == 'X' || **mangled == 'Y')
3071 do_type (work, mangled, &temp);
3072 string_prepends (&decl, &temp);
3074 else if (**mangled == 't')
3077 string_init (&temp);
3078 success = demangle_template (work, mangled, &temp,
3082 string_prependn (&decl, temp.b, temp.p - temp.b);
3083 string_clear (&temp);
3094 string_prepend (&decl, "(");
3102 type_quals |= code_for_qualifier (**mangled);
3110 if (*(*mangled)++ != 'F')
3116 if ((member && !demangle_nested_args (work, mangled, &decl))
3117 || **mangled != '_')
3123 if (! PRINT_ANSI_QUALIFIERS)
3127 if (type_quals != TYPE_UNQUALIFIED)
3129 APPEND_BLANK (&decl);
3130 string_append (&decl, qualifier_string (type_quals));
3141 if (PRINT_ANSI_QUALIFIERS)
3143 if (!STRING_EMPTY (&decl))
3144 string_prepend (&decl, " ");
3146 string_prepend (&decl, demangle_qualifier (**mangled));
3161 if (success) switch (**mangled)
3163 /* A qualified name, such as "Outer::Inner". */
3167 success = demangle_qualified (work, mangled, result, 0, 1);
3171 /* A back reference to a previously seen squangled type */
3174 if (!get_count (mangled, &n) || n >= work -> numb)
3177 string_append (result, work->btypevec[n]);
3182 /* A template parm. We substitute the corresponding argument. */
3187 idx = consume_count_with_underscores (mangled);
3190 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3191 || consume_count_with_underscores (mangled) == -1)
3197 if (work->tmpl_argvec)
3198 string_append (result, work->tmpl_argvec[idx]);
3202 sprintf(buf, "T%d", idx);
3203 string_append (result, buf);
3211 success = demangle_fund_type (work, mangled, result);
3213 tk = (type_kind_t) success;
3219 if (!STRING_EMPTY (&decl))
3221 string_append (result, " ");
3222 string_appends (result, &decl);
3226 string_delete (result);
3227 string_delete (&decl);
3230 /* Assume an integral type, if we're not sure. */
3231 return (int) ((tk == tk_none) ? tk_integral : tk);
3236 /* Given a pointer to a type string that represents a fundamental type
3237 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3238 string in which the demangled output is being built in RESULT, and
3239 the WORK structure, decode the types and add them to the result.
3244 "Sl" => "signed long"
3245 "CUs" => "const unsigned short"
3247 The value returned is really a type_kind_t. */
3250 demangle_fund_type (work, mangled, result)
3251 struct work_stuff *work;
3252 const char **mangled;
3260 type_kind_t tk = tk_integral;
3262 string_init (&btype);
3264 /* First pick off any type qualifiers. There can be more than one. */
3273 if (PRINT_ANSI_QUALIFIERS)
3275 if (!STRING_EMPTY (result))
3276 string_prepend (result, " ");
3277 string_prepend (result, demangle_qualifier (**mangled));
3283 APPEND_BLANK (result);
3284 string_append (result, "unsigned");
3286 case 'S': /* signed char only */
3288 APPEND_BLANK (result);
3289 string_append (result, "signed");
3293 APPEND_BLANK (result);
3294 string_append (result, "__complex");
3302 /* Now pick off the fundamental type. There can be only one. */
3311 APPEND_BLANK (result);
3312 string_append (result, "void");
3316 APPEND_BLANK (result);
3317 string_append (result, "long long");
3321 APPEND_BLANK (result);
3322 string_append (result, "long");
3326 APPEND_BLANK (result);
3327 string_append (result, "int");
3331 APPEND_BLANK (result);
3332 string_append (result, "short");
3336 APPEND_BLANK (result);
3337 string_append (result, "bool");
3342 APPEND_BLANK (result);
3343 string_append (result, "char");
3348 APPEND_BLANK (result);
3349 string_append (result, "wchar_t");
3354 APPEND_BLANK (result);
3355 string_append (result, "long double");
3360 APPEND_BLANK (result);
3361 string_append (result, "double");
3366 APPEND_BLANK (result);
3367 string_append (result, "float");
3372 if (!isdigit ((unsigned char)**mangled))
3379 if (**mangled == '_')
3384 i < sizeof (buf) - 1 && **mangled && **mangled != '_';
3387 if (**mangled != '_')
3397 strncpy (buf, *mangled, 2);
3399 *mangled += min (strlen (*mangled), 2);
3401 sscanf (buf, "%x", &dec);
3402 sprintf (buf, "int%i_t", dec);
3403 APPEND_BLANK (result);
3404 string_append (result, buf);
3408 /* An explicit type, such as "6mytype" or "7integer" */
3420 int bindex = register_Btype (work);
3422 string_init (&btype);
3423 if (demangle_class_name (work, mangled, &btype)) {
3424 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3425 APPEND_BLANK (result);
3426 string_appends (result, &btype);
3430 string_delete (&btype);
3435 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3436 string_appends (result, &btype);
3444 return success ? ((int) tk) : 0;
3448 /* Handle a template's value parameter for HP aCC (extension from ARM)
3449 **mangled points to 'S' or 'U' */
3452 do_hpacc_template_const_value (work, mangled, result)
3453 struct work_stuff *work;
3454 const char **mangled;
3459 if (**mangled != 'U' && **mangled != 'S')
3462 unsigned_const = (**mangled == 'U');
3469 string_append (result, "-");
3475 /* special case for -2^31 */
3476 string_append (result, "-2147483648");
3483 /* We have to be looking at an integer now */
3484 if (!(isdigit ((unsigned char)**mangled)))
3487 /* We only deal with integral values for template
3488 parameters -- so it's OK to look only for digits */
3489 while (isdigit ((unsigned char)**mangled))
3491 char_str[0] = **mangled;
3492 string_append (result, char_str);
3497 string_append (result, "U");
3499 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3500 with L or LL suffixes. pai/1997-09-03 */
3502 return 1; /* success */
3505 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3506 **mangled is pointing to the 'A' */
3509 do_hpacc_template_literal (work, mangled, result)
3510 struct work_stuff *work;
3511 const char **mangled;
3514 int literal_len = 0;
3518 if (**mangled != 'A')
3523 literal_len = consume_count (mangled);
3525 if (literal_len <= 0)
3528 /* Literal parameters are names of arrays, functions, etc. and the
3529 canonical representation uses the address operator */
3530 string_append (result, "&");
3532 /* Now recursively demangle the literal name */
3533 recurse = (char *) xmalloc (literal_len + 1);
3534 memcpy (recurse, *mangled, literal_len);
3535 recurse[literal_len] = '\000';
3537 recurse_dem = cplus_demangle (recurse, work->options);
3541 string_append (result, recurse_dem);
3546 string_appendn (result, *mangled, literal_len);
3548 (*mangled) += literal_len;
3555 snarf_numeric_literal (args, arg)
3562 string_append (arg, char_str);
3565 else if (**args == '+')
3568 if (!isdigit ((unsigned char)**args))
3571 while (isdigit ((unsigned char)**args))
3573 char_str[0] = **args;
3574 string_append (arg, char_str);
3581 /* Demangle the next argument, given by MANGLED into RESULT, which
3582 *should be an uninitialized* string. It will be initialized here,
3583 and free'd should anything go wrong. */
3586 do_arg (work, mangled, result)
3587 struct work_stuff *work;
3588 const char **mangled;
3591 /* Remember where we started so that we can record the type, for
3592 non-squangling type remembering. */
3593 const char *start = *mangled;
3595 string_init (result);
3597 if (work->nrepeats > 0)
3601 if (work->previous_argument == 0)
3604 /* We want to reissue the previous type in this argument list. */
3605 string_appends (result, work->previous_argument);
3609 if (**mangled == 'n')
3611 /* A squangling-style repeat. */
3613 work->nrepeats = consume_count(mangled);
3615 if (work->nrepeats <= 0)
3616 /* This was not a repeat count after all. */
3619 if (work->nrepeats > 9)
3621 if (**mangled != '_')
3622 /* The repeat count should be followed by an '_' in this
3629 /* Now, the repeat is all set up. */
3630 return do_arg (work, mangled, result);
3633 /* Save the result in WORK->previous_argument so that we can find it
3634 if it's repeated. Note that saving START is not good enough: we
3635 do not want to add additional types to the back-referenceable
3636 type vector when processing a repeated type. */
3637 if (work->previous_argument)
3638 string_clear (work->previous_argument);
3641 work->previous_argument = (string*) xmalloc (sizeof (string));
3642 string_init (work->previous_argument);
3645 if (!do_type (work, mangled, work->previous_argument))
3648 string_appends (result, work->previous_argument);
3650 remember_type (work, start, *mangled - start);
3655 remember_type (work, start, len)
3656 struct work_stuff *work;
3662 if (work->forgetting_types)
3665 if (work -> ntypes >= work -> typevec_size)
3667 if (work -> typevec_size == 0)
3669 work -> typevec_size = 3;
3671 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3675 work -> typevec_size *= 2;
3677 = (char **) xrealloc ((char *)work -> typevec,
3678 sizeof (char *) * work -> typevec_size);
3681 tem = xmalloc (len + 1);
3682 memcpy (tem, start, len);
3684 work -> typevec[work -> ntypes++] = tem;
3688 /* Remember a K type class qualifier. */
3690 remember_Ktype (work, start, len)
3691 struct work_stuff *work;
3697 if (work -> numk >= work -> ksize)
3699 if (work -> ksize == 0)
3703 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3709 = (char **) xrealloc ((char *)work -> ktypevec,
3710 sizeof (char *) * work -> ksize);
3713 tem = xmalloc (len + 1);
3714 memcpy (tem, start, len);
3716 work -> ktypevec[work -> numk++] = tem;
3719 /* Register a B code, and get an index for it. B codes are registered
3720 as they are seen, rather than as they are completed, so map<temp<char> >
3721 registers map<temp<char> > as B0, and temp<char> as B1 */
3724 register_Btype (work)
3725 struct work_stuff *work;
3729 if (work -> numb >= work -> bsize)
3731 if (work -> bsize == 0)
3735 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3741 = (char **) xrealloc ((char *)work -> btypevec,
3742 sizeof (char *) * work -> bsize);
3745 ret = work -> numb++;
3746 work -> btypevec[ret] = NULL;
3750 /* Store a value into a previously registered B code type. */
3753 remember_Btype (work, start, len, index)
3754 struct work_stuff *work;
3760 tem = xmalloc (len + 1);
3761 memcpy (tem, start, len);
3763 work -> btypevec[index] = tem;
3766 /* Lose all the info related to B and K type codes. */
3768 forget_B_and_K_types (work)
3769 struct work_stuff *work;
3773 while (work -> numk > 0)
3775 i = --(work -> numk);
3776 if (work -> ktypevec[i] != NULL)
3778 free (work -> ktypevec[i]);
3779 work -> ktypevec[i] = NULL;
3783 while (work -> numb > 0)
3785 i = --(work -> numb);
3786 if (work -> btypevec[i] != NULL)
3788 free (work -> btypevec[i]);
3789 work -> btypevec[i] = NULL;
3793 /* Forget the remembered types, but not the type vector itself. */
3797 struct work_stuff *work;
3801 while (work -> ntypes > 0)
3803 i = --(work -> ntypes);
3804 if (work -> typevec[i] != NULL)
3806 free (work -> typevec[i]);
3807 work -> typevec[i] = NULL;
3812 /* Process the argument list part of the signature, after any class spec
3813 has been consumed, as well as the first 'F' character (if any). For
3816 "__als__3fooRT0" => process "RT0"
3817 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3819 DECLP must be already initialised, usually non-empty. It won't be freed
3822 Note that g++ differs significantly from ARM and lucid style mangling
3823 with regards to references to previously seen types. For example, given
3824 the source fragment:
3828 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3831 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3832 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3834 g++ produces the names:
3839 while lcc (and presumably other ARM style compilers as well) produces:
3841 foo__FiR3fooT1T2T1T2
3842 __ct__3fooFiR3fooT1T2T1T2
3844 Note that g++ bases its type numbers starting at zero and counts all
3845 previously seen types, while lucid/ARM bases its type numbers starting
3846 at one and only considers types after it has seen the 'F' character
3847 indicating the start of the function args. For lucid/ARM style, we
3848 account for this difference by discarding any previously seen types when
3849 we see the 'F' character, and subtracting one from the type number
3855 demangle_args (work, mangled, declp)
3856 struct work_stuff *work;
3857 const char **mangled;
3867 if (PRINT_ARG_TYPES)
3869 string_append (declp, "(");
3870 if (**mangled == '\0')
3872 string_append (declp, "void");
3876 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3877 || work->nrepeats > 0)
3879 if ((**mangled == 'N') || (**mangled == 'T'))
3881 temptype = *(*mangled)++;
3883 if (temptype == 'N')
3885 if (!get_count (mangled, &r))
3894 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
3896 /* If we have 10 or more types we might have more than a 1 digit
3897 index so we'll have to consume the whole count here. This
3898 will lose if the next thing is a type name preceded by a
3899 count but it's impossible to demangle that case properly
3900 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3901 Pc, ...)" or "(..., type12, char *, ...)" */
3902 if ((t = consume_count(mangled)) <= 0)
3909 if (!get_count (mangled, &t))
3914 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3918 /* Validate the type index. Protect against illegal indices from
3919 malformed type strings. */
3920 if ((t < 0) || (t >= work -> ntypes))
3924 while (work->nrepeats > 0 || --r >= 0)
3926 tem = work -> typevec[t];
3927 if (need_comma && PRINT_ARG_TYPES)
3929 string_append (declp, ", ");
3931 if (!do_arg (work, &tem, &arg))
3935 if (PRINT_ARG_TYPES)
3937 string_appends (declp, &arg);
3939 string_delete (&arg);
3945 if (need_comma && PRINT_ARG_TYPES)
3946 string_append (declp, ", ");
3947 if (!do_arg (work, mangled, &arg))
3949 if (PRINT_ARG_TYPES)
3950 string_appends (declp, &arg);
3951 string_delete (&arg);
3956 if (**mangled == 'e')
3959 if (PRINT_ARG_TYPES)
3963 string_append (declp, ",");
3965 string_append (declp, "...");
3969 if (PRINT_ARG_TYPES)
3971 string_append (declp, ")");
3976 /* Like demangle_args, but for demangling the argument lists of function
3977 and method pointers or references, not top-level declarations. */
3980 demangle_nested_args (work, mangled, declp)
3981 struct work_stuff *work;
3982 const char **mangled;
3985 string* saved_previous_argument;
3989 /* The G++ name-mangling algorithm does not remember types on nested
3990 argument lists, unless -fsquangling is used, and in that case the
3991 type vector updated by remember_type is not used. So, we turn
3992 off remembering of types here. */
3993 ++work->forgetting_types;
3995 /* For the repeat codes used with -fsquangling, we must keep track of
3996 the last argument. */
3997 saved_previous_argument = work->previous_argument;
3998 saved_nrepeats = work->nrepeats;
3999 work->previous_argument = 0;
4002 /* Actually demangle the arguments. */
4003 result = demangle_args (work, mangled, declp);
4005 /* Restore the previous_argument field. */
4006 if (work->previous_argument)
4007 string_delete (work->previous_argument);
4008 work->previous_argument = saved_previous_argument;
4009 --work->forgetting_types;
4010 work->nrepeats = saved_nrepeats;
4016 demangle_function_name (work, mangled, declp, scan)
4017 struct work_stuff *work;
4018 const char **mangled;
4026 string_appendn (declp, (*mangled), scan - (*mangled));
4027 string_need (declp, 1);
4028 *(declp -> p) = '\0';
4030 /* Consume the function name, including the "__" separating the name
4031 from the signature. We are guaranteed that SCAN points to the
4034 (*mangled) = scan + 2;
4035 /* We may be looking at an instantiation of a template function:
4036 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4037 following _F marks the start of the function arguments. Handle
4038 the template arguments first. */
4040 if (HP_DEMANGLING && (**mangled == 'X'))
4042 demangle_arm_hp_template (work, mangled, 0, declp);
4043 /* This leaves MANGLED pointing to the 'F' marking func args */
4046 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4049 /* See if we have an ARM style constructor or destructor operator.
4050 If so, then just record it, clear the decl, and return.
4051 We can't build the actual constructor/destructor decl until later,
4052 when we recover the class name from the signature. */
4054 if (strcmp (declp -> b, "__ct") == 0)
4056 work -> constructor += 1;
4057 string_clear (declp);
4060 else if (strcmp (declp -> b, "__dt") == 0)
4062 work -> destructor += 1;
4063 string_clear (declp);
4068 if (declp->p - declp->b >= 3
4069 && declp->b[0] == 'o'
4070 && declp->b[1] == 'p'
4071 && strchr (cplus_markers, declp->b[2]) != NULL)
4073 /* see if it's an assignment expression */
4074 if (declp->p - declp->b >= 10 /* op$assign_ */
4075 && memcmp (declp->b + 3, "assign_", 7) == 0)
4077 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4079 int len = declp->p - declp->b - 10;
4080 if ((int) strlen (optable[i].in) == len
4081 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4083 string_clear (declp);
4084 string_append (declp, "operator");
4085 string_append (declp, optable[i].out);
4086 string_append (declp, "=");
4093 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4095 int len = declp->p - declp->b - 3;
4096 if ((int) strlen (optable[i].in) == len
4097 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4099 string_clear (declp);
4100 string_append (declp, "operator");
4101 string_append (declp, optable[i].out);
4107 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4108 && strchr (cplus_markers, declp->b[4]) != NULL)
4110 /* type conversion operator */
4112 if (do_type (work, &tem, &type))
4114 string_clear (declp);
4115 string_append (declp, "operator ");
4116 string_appends (declp, &type);
4117 string_delete (&type);
4120 else if (declp->b[0] == '_' && declp->b[1] == '_'
4121 && declp->b[2] == 'o' && declp->b[3] == 'p')
4124 /* type conversion operator. */
4126 if (do_type (work, &tem, &type))
4128 string_clear (declp);
4129 string_append (declp, "operator ");
4130 string_appends (declp, &type);
4131 string_delete (&type);
4134 else if (declp->b[0] == '_' && declp->b[1] == '_'
4135 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
4136 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
4138 if (declp->b[4] == '\0')
4141 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4143 if (strlen (optable[i].in) == 2
4144 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4146 string_clear (declp);
4147 string_append (declp, "operator");
4148 string_append (declp, optable[i].out);
4155 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4158 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4160 if (strlen (optable[i].in) == 3
4161 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4163 string_clear (declp);
4164 string_append (declp, "operator");
4165 string_append (declp, optable[i].out);
4174 /* a mini string-handling package */
4189 s->p = s->b = xmalloc (n);
4192 else if (s->e - s->p < n)
4197 s->b = xrealloc (s->b, n);
4210 s->b = s->e = s->p = NULL;
4218 s->b = s->p = s->e = NULL;
4234 return (s->b == s->p);
4240 string_append (p, s)
4245 if (s == NULL || *s == '\0')
4249 memcpy (p->p, s, n);
4254 string_appends (p, s)
4263 memcpy (p->p, s->b, n);
4269 string_appendn (p, s, n)
4277 memcpy (p->p, s, n);
4283 string_prepend (p, s)
4287 if (s != NULL && *s != '\0')
4289 string_prependn (p, s, strlen (s));
4294 string_prepends (p, s)
4299 string_prependn (p, s->b, s->p - s->b);
4304 string_prependn (p, s, n)
4314 for (q = p->p - 1; q >= p->b; q--)
4318 memcpy (p->b, s, n);
4323 /* To generate a standalone demangler program for testing purposes,
4324 just compile and link this file with -DMAIN and libiberty.a. When
4325 run, it demangles each command line arg, or each stdin string, and
4326 prints the result on stdout. */
4332 static char *program_name;
4333 static char *program_version = VERSION;
4334 static int flags = DMGL_PARAMS | DMGL_ANSI;
4336 static void demangle_it PARAMS ((char *));
4337 static void usage PARAMS ((FILE *, int));
4338 static void fatal PARAMS ((char *));
4341 demangle_it (mangled_name)
4346 result = cplus_demangle (mangled_name, flags);
4349 printf ("%s\n", mangled_name);
4353 printf ("%s\n", result);
4359 usage (stream, status)
4364 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4365 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4366 [--help] [--version] [arg...]\n",
4371 #define MBUF_SIZE 32767
4372 char mbuffer[MBUF_SIZE];
4374 /* Defined in the automatically-generated underscore.c. */
4375 extern int prepends_underscore;
4377 int strip_underscore = 0;
4379 static struct option long_options[] = {
4380 {"strip-underscores", no_argument, 0, '_'},
4381 {"format", required_argument, 0, 's'},
4382 {"help", no_argument, 0, 'h'},
4383 {"java", no_argument, 0, 'j'},
4384 {"no-strip-underscores", no_argument, 0, 'n'},
4385 {"version", no_argument, 0, 'v'},
4386 {0, no_argument, 0, 0}
4389 /* More 'friendly' abort that prints the line and file.
4390 config.h can #define abort fancy_abort if you like that sort of thing. */
4395 fatal ("Internal gcc abort.");
4399 /* Return the string of non-alnum characters that may occur
4400 as a valid symbol component, in the standard assembler symbol
4404 standard_symbol_characters ()
4410 /* Return the string of non-alnum characters that may occur
4411 as a valid symbol name component in an HP object file.
4413 Note that, since HP's compiler generates object code straight from
4414 C++ source, without going through an assembler, its mangled
4415 identifiers can use all sorts of characters that no assembler would
4416 tolerate, so the alphabet this function creates is a little odd.
4417 Here are some sample mangled identifiers offered by HP:
4419 typeid*__XT24AddressIndExpClassMember_
4420 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
4421 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
4423 This still seems really weird to me, since nowhere else in this
4424 file is there anything to recognize curly brackets, parens, etc.
4425 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
4426 this is right, but I still strongly suspect that there's a
4427 misunderstanding here.
4429 If we decide it's better for c++filt to use HP's assembler syntax
4430 to scrape identifiers out of its input, here's the definition of
4431 the symbol name syntax from the HP assembler manual:
4433 Symbols are composed of uppercase and lowercase letters, decimal
4434 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
4435 underscore (_). A symbol can begin with a letter, digit underscore or
4436 dollar sign. If a symbol begins with a digit, it must contain a
4437 non-digit character.
4441 hp_symbol_characters ()
4443 return "_$.<>#,*&[]:(){}";
4454 char *valid_symbols;
4456 program_name = argv[0];
4458 strip_underscore = prepends_underscore;
4460 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
4470 strip_underscore = 0;
4473 printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
4476 strip_underscore = 1;
4482 if (strcmp (optarg, "gnu") == 0)
4484 current_demangling_style = gnu_demangling;
4486 else if (strcmp (optarg, "lucid") == 0)
4488 current_demangling_style = lucid_demangling;
4490 else if (strcmp (optarg, "arm") == 0)
4492 current_demangling_style = arm_demangling;
4494 else if (strcmp (optarg, "hp") == 0)
4496 current_demangling_style = hp_demangling;
4498 else if (strcmp (optarg, "edg") == 0)
4500 current_demangling_style = edg_demangling;
4504 fprintf (stderr, "%s: unknown demangling style `%s'\n",
4505 program_name, optarg);
4514 for ( ; optind < argc; optind++)
4516 demangle_it (argv[optind]);
4521 switch (current_demangling_style)
4523 case gnu_demangling:
4524 case lucid_demangling:
4525 case arm_demangling:
4526 case edg_demangling:
4527 valid_symbols = standard_symbol_characters ();
4530 valid_symbols = hp_symbol_characters ();
4533 /* Folks should explicitly indicate the appropriate alphabet for
4534 each demangling. Providing a default would allow the
4535 question to go unconsidered. */
4543 /* Try to read a label. */
4544 while (c != EOF && (isalnum (c) || strchr (valid_symbols, c)))
4546 if (i >= MBUF_SIZE-1)
4555 if (mbuffer[0] == '.')
4557 if (strip_underscore && mbuffer[skip_first] == '_')
4565 result = cplus_demangle (mbuffer + skip_first, flags);
4568 if (mbuffer[0] == '.')
4570 fputs (result, stdout);
4574 fputs (mbuffer, stdout);
4591 fprintf (stderr, "%s: %s\n", program_name, str);
4599 register PTR value = (PTR) malloc (size);
4601 fatal ("virtual memory exhausted");
4606 xrealloc (ptr, size)
4610 register PTR value = (PTR) realloc (ptr, size);
4612 fatal ("virtual memory exhausted");