1 /* Demangler for GNU C++
2 Copyright 1989, 91, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
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. */
255 #define SCOPE_STRING(work) "::"
257 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
258 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
260 /* Prototypes for local functions */
263 mop_up PARAMS ((struct work_stuff *, string *, int));
266 squangle_mop_up PARAMS ((struct work_stuff *));
270 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
274 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
277 demangle_template_template_parm PARAMS ((struct work_stuff *work,
278 const char **, string *));
281 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
282 string *, int, int));
285 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
289 demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *));
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 ((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 ((char));
420 qualifier_string PARAMS ((int));
423 demangle_qualifier PARAMS ((char));
425 /* Translate count to integer, consuming tokens in the process.
426 Conversion terminates on the first non-digit character.
427 Trying to consume something that isn't a count results in
428 no consumption of input and a return of 0. */
436 while (isdigit ((unsigned char)**type))
439 count += **type - '0';
446 /* Like consume_count, but for counts that are preceded and followed
447 by '_' if they are greater than 10. Also, -1 is returned for
448 failure, since 0 can be a valid value. */
451 consume_count_with_underscores (mangled)
452 const char **mangled;
456 if (**mangled == '_')
459 if (!isdigit ((unsigned char)**mangled))
462 idx = consume_count (mangled);
463 if (**mangled != '_')
464 /* The trailing underscore was missing. */
471 if (**mangled < '0' || **mangled > '9')
474 idx = **mangled - '0';
481 /* C is the code for a type-qualifier. Return the TYPE_QUAL
482 corresponding to this qualifier. */
485 code_for_qualifier (c)
491 return TYPE_QUAL_CONST;
494 return TYPE_QUAL_VOLATILE;
497 return TYPE_QUAL_RESTRICT;
503 /* C was an invalid qualifier. */
507 /* Return the string corresponding to the qualifiers given by
511 qualifier_string (type_quals)
516 case TYPE_UNQUALIFIED:
519 case TYPE_QUAL_CONST:
522 case TYPE_QUAL_VOLATILE:
525 case TYPE_QUAL_RESTRICT:
528 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
529 return "const volatile";
531 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
532 return "const __restrict";
534 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
535 return "volatile __restrict";
537 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
538 return "const volatile __restrict";
544 /* TYPE_QUALS was an invalid qualifier set. */
548 /* C is the code for a type-qualifier. Return the string
549 corresponding to this qualifier. This function should only be
550 called with a valid qualifier code. */
553 demangle_qualifier (c)
556 return qualifier_string (code_for_qualifier (c));
560 cplus_demangle_opname (opname, result, options)
567 struct work_stuff work[1];
570 len = strlen(opname);
573 memset ((char *) work, 0, sizeof (work));
574 work->options = options;
576 if (opname[0] == '_' && opname[1] == '_'
577 && opname[2] == 'o' && opname[3] == 'p')
580 /* type conversion operator. */
582 if (do_type (work, &tem, &type))
584 strcat (result, "operator ");
585 strncat (result, type.b, type.p - type.b);
586 string_delete (&type);
590 else if (opname[0] == '_' && opname[1] == '_'
591 && opname[2] >= 'a' && opname[2] <= 'z'
592 && opname[3] >= 'a' && opname[3] <= 'z')
594 if (opname[4] == '\0')
598 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
600 if (strlen (optable[i].in) == 2
601 && memcmp (optable[i].in, opname + 2, 2) == 0)
603 strcat (result, "operator");
604 strcat (result, optable[i].out);
612 if (opname[2] == 'a' && opname[5] == '\0')
616 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
618 if (strlen (optable[i].in) == 3
619 && memcmp (optable[i].in, opname + 2, 3) == 0)
621 strcat (result, "operator");
622 strcat (result, optable[i].out);
633 && strchr (cplus_markers, opname[2]) != NULL)
635 /* see if it's an assignment expression */
636 if (len >= 10 /* op$assign_ */
637 && memcmp (opname + 3, "assign_", 7) == 0)
640 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
643 if ((int) strlen (optable[i].in) == len1
644 && memcmp (optable[i].in, opname + 10, len1) == 0)
646 strcat (result, "operator");
647 strcat (result, optable[i].out);
648 strcat (result, "=");
657 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
660 if ((int) strlen (optable[i].in) == len1
661 && memcmp (optable[i].in, opname + 3, len1) == 0)
663 strcat (result, "operator");
664 strcat (result, optable[i].out);
671 else if (len >= 5 && memcmp (opname, "type", 4) == 0
672 && strchr (cplus_markers, opname[4]) != NULL)
674 /* type conversion operator */
676 if (do_type (work, &tem, &type))
678 strcat (result, "operator ");
679 strncat (result, type.b, type.p - type.b);
680 string_delete (&type);
684 squangle_mop_up (work);
688 /* Takes operator name as e.g. "++" and returns mangled
689 operator name (e.g. "postincrement_expr"), or NULL if not found.
691 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
692 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
695 cplus_mangle_opname (opname, options)
702 len = strlen (opname);
703 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
705 if ((int) strlen (optable[i].out) == len
706 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
707 && memcmp (optable[i].out, opname, len) == 0)
708 return optable[i].in;
713 /* char *cplus_demangle (const char *mangled, int options)
715 If MANGLED is a mangled function name produced by GNU C++, then
716 a pointer to a malloced string giving a C++ representation
717 of the name will be returned; otherwise NULL will be returned.
718 It is the caller's responsibility to free the string which
721 The OPTIONS arg may contain one or more of the following bits:
723 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
725 DMGL_PARAMS Function parameters are included.
729 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
730 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
731 cplus_demangle ("foo__1Ai", 0) => "A::foo"
733 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
734 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
735 cplus_demangle ("foo__1Afe", 0) => "A::foo"
737 Note that any leading underscores, or other such characters prepended by
738 the compilation system, are presumed to have already been stripped from
742 cplus_demangle (mangled, options)
747 struct work_stuff work[1];
748 memset ((char *) work, 0, sizeof (work));
749 work -> options = options;
750 if ((work -> options & DMGL_STYLE_MASK) == 0)
751 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
753 ret = internal_cplus_demangle (work, mangled);
754 squangle_mop_up (work);
759 /* This function performs most of what cplus_demangle use to do, but
760 to be able to demangle a name with a B, K or n code, we need to
761 have a longer term memory of what types have been seen. The original
762 now intializes and cleans up the squangle code info, while internal
763 calls go directly to this routine to avoid resetting that info. */
766 internal_cplus_demangle (work, mangled)
767 struct work_stuff *work;
773 char *demangled = NULL;
775 s1 = work->constructor;
776 s2 = work->destructor;
777 s3 = work->static_type;
778 s4 = work->type_quals;
779 work->constructor = work->destructor = 0;
780 work->type_quals = TYPE_UNQUALIFIED;
781 work->dllimported = 0;
783 if ((mangled != NULL) && (*mangled != '\0'))
787 /* First check to see if gnu style demangling is active and if the
788 string to be demangled contains a CPLUS_MARKER. If so, attempt to
789 recognize one of the gnu special forms rather than looking for a
790 standard prefix. In particular, don't worry about whether there
791 is a "__" string in the mangled string. Consider "_$_5__foo" for
794 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
796 success = gnu_special (work, &mangled, &decl);
800 success = demangle_prefix (work, &mangled, &decl);
802 if (success && (*mangled != '\0'))
804 success = demangle_signature (work, &mangled, &decl);
806 if (work->constructor == 2)
808 string_prepend (&decl, "global constructors keyed to ");
809 work->constructor = 0;
811 else if (work->destructor == 2)
813 string_prepend (&decl, "global destructors keyed to ");
814 work->destructor = 0;
816 else if (work->dllimported == 1)
818 string_prepend (&decl, "import stub for ");
819 work->dllimported = 0;
821 demangled = mop_up (work, &decl, success);
823 work->constructor = s1;
824 work->destructor = s2;
825 work->static_type = s3;
826 work->type_quals = s4;
831 /* Clear out and squangling related storage */
833 squangle_mop_up (work)
834 struct work_stuff *work;
836 /* clean up the B and K type mangling types. */
837 forget_B_and_K_types (work);
838 if (work -> btypevec != NULL)
840 free ((char *) work -> btypevec);
842 if (work -> ktypevec != NULL)
844 free ((char *) work -> ktypevec);
848 /* Clear out any mangled storage */
851 mop_up (work, declp, success)
852 struct work_stuff *work;
856 char *demangled = NULL;
858 /* Discard the remembered types, if any. */
861 if (work -> typevec != NULL)
863 free ((char *) work -> typevec);
864 work -> typevec = NULL;
866 if (work->tmpl_argvec)
870 for (i = 0; i < work->ntmpl_args; i++)
871 if (work->tmpl_argvec[i])
872 free ((char*) work->tmpl_argvec[i]);
874 free ((char*) work->tmpl_argvec);
875 work->tmpl_argvec = NULL;
877 if (work->previous_argument)
879 string_delete (work->previous_argument);
880 free ((char*) work->previous_argument);
883 /* If demangling was successful, ensure that the demangled string is null
884 terminated and return it. Otherwise, free the demangling decl. */
888 string_delete (declp);
892 string_appendn (declp, "", 1);
893 demangled = declp -> b;
902 demangle_signature -- demangle the signature part of a mangled name
907 demangle_signature (struct work_stuff *work, const char **mangled,
912 Consume and demangle the signature portion of the mangled name.
914 DECLP is the string where demangled output is being built. At
915 entry it contains the demangled root name from the mangled name
916 prefix. I.E. either a demangled operator name or the root function
917 name. In some special cases, it may contain nothing.
919 *MANGLED points to the current unconsumed location in the mangled
920 name. As tokens are consumed and demangling is performed, the
921 pointer is updated to continuously point at the next token to
924 Demangling GNU style mangled names is nasty because there is no
925 explicit token that marks the start of the outermost function
929 demangle_signature (work, mangled, declp)
930 struct work_stuff *work;
931 const char **mangled;
937 int expect_return_type = 0;
938 const char *oldmangled = NULL;
942 while (success && (**mangled != '\0'))
947 oldmangled = *mangled;
948 success = demangle_qualified (work, mangled, declp, 1, 0);
950 remember_type (work, oldmangled, *mangled - oldmangled);
951 if (AUTO_DEMANGLING || GNU_DEMANGLING)
957 oldmangled = *mangled;
958 success = demangle_qualified (work, mangled, declp, 1, 0);
959 if (AUTO_DEMANGLING || GNU_DEMANGLING)
967 /* Static member function */
968 if (oldmangled == NULL)
970 oldmangled = *mangled;
973 work -> static_type = 1;
979 work->type_quals |= code_for_qualifier (**mangled);
981 /* a qualified member function */
982 if (oldmangled == NULL)
983 oldmangled = *mangled;
988 /* Local class name follows after "Lnnn_" */
991 while (**mangled && (**mangled != '_'))
1002 case '0': case '1': case '2': case '3': case '4':
1003 case '5': case '6': case '7': case '8': case '9':
1004 if (oldmangled == NULL)
1006 oldmangled = *mangled;
1008 work->temp_start = -1; /* uppermost call to demangle_class */
1009 success = demangle_class (work, mangled, declp);
1012 remember_type (work, oldmangled, *mangled - oldmangled);
1014 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1016 /* EDG and others will have the "F", so we let the loop cycle
1017 if we are looking at one. */
1018 if (**mangled != 'F')
1027 success = do_type (work, mangled, &s);
1030 string_append (&s, SCOPE_STRING (work));
1031 string_prepends (declp, &s);
1040 /* ARM/HP style demangling includes a specific 'F' character after
1041 the class name. For GNU style, it is just implied. So we can
1042 safely just consume any 'F' at this point and be compatible
1043 with either style. */
1049 /* For lucid/ARM/HP style we have to forget any types we might
1050 have remembered up to this point, since they were not argument
1051 types. GNU style considers all types seen as available for
1052 back references. See comment in demangle_args() */
1054 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1056 forget_types (work);
1058 success = demangle_args (work, mangled, declp);
1059 /* After picking off the function args, we expect to either
1060 find the function return type (preceded by an '_') or the
1061 end of the string. */
1062 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1065 /* At this level, we do not care about the return type. */
1066 success = do_type (work, mangled, &tname);
1067 string_delete (&tname);
1074 string_init(&trawname);
1075 string_init(&tname);
1076 if (oldmangled == NULL)
1078 oldmangled = *mangled;
1080 success = demangle_template (work, mangled, &tname,
1084 remember_type (work, oldmangled, *mangled - oldmangled);
1086 string_append (&tname, SCOPE_STRING (work));
1088 string_prepends(declp, &tname);
1089 if (work -> destructor & 1)
1091 string_prepend (&trawname, "~");
1092 string_appends (declp, &trawname);
1093 work->destructor -= 1;
1095 if ((work->constructor & 1) || (work->destructor & 1))
1097 string_appends (declp, &trawname);
1098 work->constructor -= 1;
1100 string_delete(&trawname);
1101 string_delete(&tname);
1107 if (GNU_DEMANGLING && expect_return_type)
1109 /* Read the return type. */
1111 string_init (&return_type);
1114 success = do_type (work, mangled, &return_type);
1115 APPEND_BLANK (&return_type);
1117 string_prepends (declp, &return_type);
1118 string_delete (&return_type);
1122 /* At the outermost level, we cannot have a return type specified,
1123 so if we run into another '_' at this point we are dealing with
1124 a mangled name that is either bogus, or has been mangled by
1125 some algorithm we don't know how to deal with. So just
1126 reject the entire demangling. */
1127 /* However, "_nnn" is an expected suffix for alternate entry point
1128 numbered nnn for a function, with HP aCC, so skip over that
1129 without reporting failure. pai/1997-09-04 */
1133 while (**mangled && isdigit (**mangled))
1143 /* A G++ template function. Read the template arguments. */
1144 success = demangle_template (work, mangled, declp, 0, 0,
1146 if (!(work->constructor & 1))
1147 expect_return_type = 1;
1156 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1158 /* Assume we have stumbled onto the first outermost function
1159 argument token, and start processing args. */
1161 success = demangle_args (work, mangled, declp);
1165 /* Non-GNU demanglers use a specific token to mark the start
1166 of the outermost function argument tokens. Typically 'F',
1167 for ARM/HP-demangling, for example. So if we find something
1168 we are not prepared for, it must be an error. */
1174 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1177 if (success && expect_func)
1180 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1182 forget_types (work);
1184 success = demangle_args (work, mangled, declp);
1185 /* Since template include the mangling of their return types,
1186 we must set expect_func to 0 so that we don't try do
1187 demangle more arguments the next time we get here. */
1192 if (success && !func_done)
1194 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1196 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1197 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1198 first case, and need to ensure that the '(void)' gets added to
1199 the current declp. Note that with ARM/HP, the first case
1200 represents the name of a static data member 'foo::bar',
1201 which is in the current declp, so we leave it alone. */
1202 success = demangle_args (work, mangled, declp);
1205 if (success && PRINT_ARG_TYPES)
1207 if (work->static_type)
1208 string_append (declp, " static");
1209 if (work->type_quals != TYPE_UNQUALIFIED)
1211 APPEND_BLANK (declp);
1212 string_append (declp, qualifier_string (work->type_quals));
1222 demangle_method_args (work, mangled, declp)
1223 struct work_stuff *work;
1224 const char **mangled;
1229 if (work -> static_type)
1231 string_append (declp, *mangled + 1);
1232 *mangled += strlen (*mangled);
1237 success = demangle_args (work, mangled, declp);
1245 demangle_template_template_parm (work, mangled, tname)
1246 struct work_stuff *work;
1247 const char **mangled;
1256 string_append (tname, "template <");
1257 /* get size of template parameter list */
1258 if (get_count (mangled, &r))
1260 for (i = 0; i < r; i++)
1264 string_append (tname, ", ");
1267 /* Z for type parameters */
1268 if (**mangled == 'Z')
1271 string_append (tname, "class");
1273 /* z for template parameters */
1274 else if (**mangled == 'z')
1278 demangle_template_template_parm (work, mangled, tname);
1286 /* temp is initialized in do_type */
1287 success = do_type (work, mangled, &temp);
1290 string_appends (tname, &temp);
1292 string_delete(&temp);
1302 if (tname->p[-1] == '>')
1303 string_append (tname, " ");
1304 string_append (tname, "> class");
1309 demangle_integral_value (work, mangled, s)
1310 struct work_stuff *work;
1311 const char** mangled;
1316 if (**mangled == 'E')
1318 int need_operator = 0;
1321 string_appendn (s, "(", 1);
1323 while (success && **mangled != 'W' && **mangled != '\0')
1332 len = strlen (*mangled);
1335 i < sizeof (optable) / sizeof (optable [0]);
1338 size_t l = strlen (optable[i].in);
1341 && memcmp (optable[i].in, *mangled, l) == 0)
1343 string_appendn (s, " ", 1);
1344 string_append (s, optable[i].out);
1345 string_appendn (s, " ", 1);
1358 success = demangle_template_value_parm (work, mangled, s,
1362 if (**mangled != 'W')
1366 string_appendn (s, ")", 1);
1370 else if (**mangled == 'Q' || **mangled == 'K')
1371 success = demangle_qualified (work, mangled, s, 0, 1);
1376 if (**mangled == 'm')
1378 string_appendn (s, "-", 1);
1381 while (isdigit ((unsigned char)**mangled))
1383 string_appendn (s, *mangled, 1);
1393 demangle_template_value_parm (work, mangled, s, tk)
1394 struct work_stuff *work;
1395 const char **mangled;
1401 if (**mangled == 'Y')
1403 /* The next argument is a template parameter. */
1407 idx = consume_count_with_underscores (mangled);
1409 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1410 || consume_count_with_underscores (mangled) == -1)
1412 if (work->tmpl_argvec)
1413 string_append (s, work->tmpl_argvec[idx]);
1417 sprintf(buf, "T%d", idx);
1418 string_append (s, buf);
1421 else if (tk == tk_integral)
1422 success = demangle_integral_value (work, mangled, s);
1423 else if (tk == tk_char)
1427 if (**mangled == 'm')
1429 string_appendn (s, "-", 1);
1432 string_appendn (s, "'", 1);
1433 val = consume_count(mangled);
1438 string_appendn (s, &tmp[0], 1);
1439 string_appendn (s, "'", 1);
1441 else if (tk == tk_bool)
1443 int val = consume_count (mangled);
1445 string_appendn (s, "false", 5);
1447 string_appendn (s, "true", 4);
1451 else if (tk == tk_real)
1453 if (**mangled == 'm')
1455 string_appendn (s, "-", 1);
1458 while (isdigit ((unsigned char)**mangled))
1460 string_appendn (s, *mangled, 1);
1463 if (**mangled == '.') /* fraction */
1465 string_appendn (s, ".", 1);
1467 while (isdigit ((unsigned char)**mangled))
1469 string_appendn (s, *mangled, 1);
1473 if (**mangled == 'e') /* exponent */
1475 string_appendn (s, "e", 1);
1477 while (isdigit ((unsigned char)**mangled))
1479 string_appendn (s, *mangled, 1);
1484 else if (tk == tk_pointer || tk == tk_reference)
1486 int symbol_len = consume_count (mangled);
1487 if (symbol_len == 0)
1489 if (symbol_len == 0)
1490 string_appendn (s, "0", 1);
1493 char *p = xmalloc (symbol_len + 1), *q;
1494 strncpy (p, *mangled, symbol_len);
1495 p [symbol_len] = '\0';
1496 /* We use cplus_demangle here, rather than
1497 internal_cplus_demangle, because the name of the entity
1498 mangled here does not make use of any of the squangling
1499 or type-code information we have built up thus far; it is
1500 mangled independently. */
1501 q = cplus_demangle (p, work->options);
1502 if (tk == tk_pointer)
1503 string_appendn (s, "&", 1);
1504 /* FIXME: Pointer-to-member constants should get a
1505 qualifying class name here. */
1508 string_append (s, q);
1512 string_append (s, p);
1515 *mangled += symbol_len;
1521 /* Demangle the template name in MANGLED. The full name of the
1522 template (e.g., S<int>) is placed in TNAME. The name without the
1523 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1524 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1525 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1526 the tmeplate is remembered in the list of back-referenceable
1530 demangle_template (work, mangled, tname, trawname, is_type, remember)
1531 struct work_stuff *work;
1532 const char **mangled;
1550 bindex = register_Btype (work);
1552 /* get template name */
1553 if (**mangled == 'z')
1559 idx = consume_count_with_underscores (mangled);
1561 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1562 || consume_count_with_underscores (mangled) == -1)
1565 if (work->tmpl_argvec)
1567 string_append (tname, work->tmpl_argvec[idx]);
1569 string_append (trawname, work->tmpl_argvec[idx]);
1574 sprintf(buf, "T%d", idx);
1575 string_append (tname, buf);
1577 string_append (trawname, buf);
1582 if ((r = consume_count (mangled)) == 0
1583 || (int) strlen (*mangled) < r)
1587 string_appendn (tname, *mangled, r);
1589 string_appendn (trawname, *mangled, r);
1593 string_append (tname, "<");
1594 /* get size of template parameter list */
1595 if (!get_count (mangled, &r))
1601 /* Create an array for saving the template argument values. */
1602 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1603 work->ntmpl_args = r;
1604 for (i = 0; i < r; i++)
1605 work->tmpl_argvec[i] = 0;
1607 for (i = 0; i < r; i++)
1611 string_append (tname, ", ");
1613 /* Z for type parameters */
1614 if (**mangled == 'Z')
1617 /* temp is initialized in do_type */
1618 success = do_type (work, mangled, &temp);
1621 string_appends (tname, &temp);
1625 /* Save the template argument. */
1626 int len = temp.p - temp.b;
1627 work->tmpl_argvec[i] = xmalloc (len + 1);
1628 memcpy (work->tmpl_argvec[i], temp.b, len);
1629 work->tmpl_argvec[i][len] = '\0';
1632 string_delete(&temp);
1638 /* z for template parameters */
1639 else if (**mangled == 'z')
1643 success = demangle_template_template_parm (work, mangled, tname);
1646 && (r2 = consume_count (mangled)) > 0
1647 && (int) strlen (*mangled) >= r2)
1649 string_append (tname, " ");
1650 string_appendn (tname, *mangled, r2);
1653 /* Save the template argument. */
1655 work->tmpl_argvec[i] = xmalloc (len + 1);
1656 memcpy (work->tmpl_argvec[i], *mangled, len);
1657 work->tmpl_argvec[i][len] = '\0';
1671 /* otherwise, value parameter */
1673 /* temp is initialized in do_type */
1674 success = do_type (work, mangled, &temp);
1675 string_delete(&temp);
1687 success = demangle_template_value_parm (work, mangled, s,
1688 (type_kind_t) success);
1700 int len = s->p - s->b;
1701 work->tmpl_argvec[i] = xmalloc (len + 1);
1702 memcpy (work->tmpl_argvec[i], s->b, len);
1703 work->tmpl_argvec[i][len] = '\0';
1705 string_appends (tname, s);
1712 if (tname->p[-1] == '>')
1713 string_append (tname, " ");
1714 string_append (tname, ">");
1717 if (is_type && remember)
1718 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1721 if (work -> static_type)
1723 string_append (declp, *mangled + 1);
1724 *mangled += strlen (*mangled);
1729 success = demangle_args (work, mangled, declp);
1737 arm_pt (work, mangled, n, anchor, args)
1738 struct work_stuff *work;
1739 const char *mangled;
1741 const char **anchor, **args;
1743 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1744 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1745 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
1748 *args = *anchor + 6;
1749 len = consume_count (args);
1750 if (*args + len == mangled + n && **args == '_')
1756 if (AUTO_DEMANGLING || EDG_DEMANGLING)
1758 if ((*anchor = mystrstr (mangled, "__tm__"))
1759 || (*anchor = mystrstr (mangled, "__ps__"))
1760 || (*anchor = mystrstr (mangled, "__pt__")))
1763 *args = *anchor + 6;
1764 len = consume_count (args);
1765 if (*args + len == mangled + n && **args == '_')
1771 else if (*anchor = mystrstr (mangled, "__S"))
1774 *args = *anchor + 3;
1775 len = consume_count (args);
1776 if (*args + len == mangled + n && **args == '_')
1788 demangle_arm_hp_template (work, mangled, n, declp)
1789 struct work_stuff *work;
1790 const char **mangled;
1796 const char *e = *mangled + n;
1799 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1801 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
1803 char *start_spec_args = NULL;
1805 /* First check for and omit template specialization pseudo-arguments,
1806 such as in "Spec<#1,#1.*>" */
1807 start_spec_args = strchr (*mangled, '<');
1808 if (start_spec_args && (start_spec_args - *mangled < n))
1809 string_appendn (declp, *mangled, start_spec_args - *mangled);
1811 string_appendn (declp, *mangled, n);
1812 (*mangled) += n + 1;
1814 if (work->temp_start == -1) /* non-recursive call */
1815 work->temp_start = declp->p - declp->b;
1816 string_append (declp, "<");
1819 string_clear (&arg);
1823 /* 'T' signals a type parameter */
1825 if (!do_type (work, mangled, &arg))
1826 goto hpacc_template_args_done;
1831 /* 'U' or 'S' signals an integral value */
1832 if (!do_hpacc_template_const_value (work, mangled, &arg))
1833 goto hpacc_template_args_done;
1837 /* 'A' signals a named constant expression (literal) */
1838 if (!do_hpacc_template_literal (work, mangled, &arg))
1839 goto hpacc_template_args_done;
1843 /* Today, 1997-09-03, we have only the above types
1844 of template parameters */
1845 /* FIXME: maybe this should fail and return null */
1846 goto hpacc_template_args_done;
1848 string_appends (declp, &arg);
1849 /* Check if we're at the end of template args.
1850 0 if at end of static member of template class,
1851 _ if done with template args for a function */
1852 if ((**mangled == '\000') || (**mangled == '_'))
1855 string_append (declp, ",");
1857 hpacc_template_args_done:
1858 string_append (declp, ">");
1859 string_delete (&arg);
1860 if (**mangled == '_')
1864 /* ARM template? (Also handles HP cfront extensions) */
1865 else if (arm_pt (work, *mangled, n, &p, &args))
1870 string_appendn (declp, *mangled, p - *mangled);
1871 if (work->temp_start == -1) /* non-recursive call */
1872 work->temp_start = declp->p - declp->b;
1873 string_append (declp, "<");
1874 /* should do error checking here */
1876 string_clear (&arg);
1878 /* Check for type or literal here */
1881 /* HP cfront extensions to ARM for template args */
1882 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1883 /* FIXME: We handle only numeric literals for HP cfront */
1885 /* A typed constant value follows */
1887 if (!do_type (work, &args, &type_str))
1888 goto cfront_template_args_done;
1889 string_append (&arg, "(");
1890 string_appends (&arg, &type_str);
1891 string_append (&arg, ")");
1893 goto cfront_template_args_done;
1895 /* Now snarf a literal value following 'L' */
1896 if (!snarf_numeric_literal (&args, &arg))
1897 goto cfront_template_args_done;
1901 /* Snarf a literal following 'L' */
1903 if (!snarf_numeric_literal (&args, &arg))
1904 goto cfront_template_args_done;
1907 /* Not handling other HP cfront stuff */
1908 if (!do_type (work, &args, &arg))
1909 goto cfront_template_args_done;
1911 string_appends (declp, &arg);
1912 string_append (declp, ",");
1914 cfront_template_args_done:
1915 string_delete (&arg);
1917 --declp->p; /* remove extra comma */
1918 string_append (declp, ">");
1920 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1921 && (*mangled)[9] == 'N'
1922 && (*mangled)[8] == (*mangled)[10]
1923 && strchr (cplus_markers, (*mangled)[8]))
1925 /* A member of the anonymous namespace. */
1926 string_append (declp, "{anonymous}");
1930 if (work->temp_start == -1) /* non-recursive call only */
1931 work->temp_start = 0; /* disable in recursive calls */
1932 string_appendn (declp, *mangled, n);
1937 /* Extract a class name, possibly a template with arguments, from the
1938 mangled string; qualifiers, local class indicators, etc. have
1939 already been dealt with */
1942 demangle_class_name (work, mangled, declp)
1943 struct work_stuff *work;
1944 const char **mangled;
1950 n = consume_count (mangled);
1951 if ((int) strlen (*mangled) >= n)
1953 demangle_arm_hp_template (work, mangled, n, declp);
1964 demangle_class -- demangle a mangled class sequence
1969 demangle_class (struct work_stuff *work, const char **mangled,
1974 DECLP points to the buffer into which demangling is being done.
1976 *MANGLED points to the current token to be demangled. On input,
1977 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1978 On exit, it points to the next token after the mangled class on
1979 success, or the first unconsumed token on failure.
1981 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1982 we are demangling a constructor or destructor. In this case
1983 we prepend "class::class" or "class::~class" to DECLP.
1985 Otherwise, we prepend "class::" to the current DECLP.
1987 Reset the constructor/destructor flags once they have been
1988 "consumed". This allows demangle_class to be called later during
1989 the same demangling, to do normal class demangling.
1991 Returns 1 if demangling is successful, 0 otherwise.
1996 demangle_class (work, mangled, declp)
1997 struct work_stuff *work;
1998 const char **mangled;
2004 char *save_class_name_end = 0;
2006 string_init (&class_name);
2007 btype = register_Btype (work);
2008 if (demangle_class_name (work, mangled, &class_name))
2010 save_class_name_end = class_name.p;
2011 if ((work->constructor & 1) || (work->destructor & 1))
2013 /* adjust so we don't include template args */
2014 if (work->temp_start && (work->temp_start != -1))
2016 class_name.p = class_name.b + work->temp_start;
2018 string_prepends (declp, &class_name);
2019 if (work -> destructor & 1)
2021 string_prepend (declp, "~");
2022 work -> destructor -= 1;
2026 work -> constructor -= 1;
2029 class_name.p = save_class_name_end;
2030 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2031 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2032 string_prepend (declp, SCOPE_STRING (work));
2033 string_prepends (declp, &class_name);
2036 string_delete (&class_name);
2044 demangle_prefix -- consume the mangled name prefix and find signature
2049 demangle_prefix (struct work_stuff *work, const char **mangled,
2054 Consume and demangle the prefix of the mangled name.
2056 DECLP points to the string buffer into which demangled output is
2057 placed. On entry, the buffer is empty. On exit it contains
2058 the root function name, the demangled operator name, or in some
2059 special cases either nothing or the completely demangled result.
2061 MANGLED points to the current pointer into the mangled name. As each
2062 token of the mangled name is consumed, it is updated. Upon entry
2063 the current mangled name pointer points to the first character of
2064 the mangled name. Upon exit, it should point to the first character
2065 of the signature if demangling was successful, or to the first
2066 unconsumed character if demangling of the prefix was unsuccessful.
2068 Returns 1 on success, 0 otherwise.
2072 demangle_prefix (work, mangled, declp)
2073 struct work_stuff *work;
2074 const char **mangled;
2081 if (strlen(*mangled) > 6
2082 && (strncmp(*mangled, "_imp__", 6) == 0
2083 || strncmp(*mangled, "__imp_", 6) == 0))
2085 /* it's a symbol imported from a PE dynamic library. Check for both
2086 new style prefix _imp__ and legacy __imp_ used by older versions
2089 work->dllimported = 1;
2091 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2093 char *marker = strchr (cplus_markers, (*mangled)[8]);
2094 if (marker != NULL && *marker == (*mangled)[10])
2096 if ((*mangled)[9] == 'D')
2098 /* it's a GNU global destructor to be executed at program exit */
2100 work->destructor = 2;
2101 if (gnu_special (work, mangled, declp))
2104 else if ((*mangled)[9] == 'I')
2106 /* it's a GNU global constructor to be executed at program init */
2108 work->constructor = 2;
2109 if (gnu_special (work, mangled, declp))
2114 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2116 /* it's a ARM global destructor to be executed at program exit */
2118 work->destructor = 2;
2120 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2122 /* it's a ARM global constructor to be executed at program initial */
2124 work->constructor = 2;
2127 /* This block of code is a reduction in strength time optimization
2129 scan = mystrstr (*mangled, "__"); */
2135 scan = strchr (scan, '_');
2136 } while (scan != NULL && *++scan != '_');
2138 if (scan != NULL) --scan;
2143 /* We found a sequence of two or more '_', ensure that we start at
2144 the last pair in the sequence. */
2145 i = strspn (scan, "_");
2156 else if (work -> static_type)
2158 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
2163 else if ((scan == *mangled)
2164 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
2165 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2167 /* The ARM says nothing about the mangling of local variables.
2168 But cfront mangles local variables by prepending __<nesting_level>
2169 to them. As an extension to ARM demangling we handle this case. */
2170 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2171 && isdigit ((unsigned char)scan[2]))
2173 *mangled = scan + 2;
2174 consume_count (mangled);
2175 string_append (declp, *mangled);
2176 *mangled += strlen (*mangled);
2181 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2182 names like __Q2_3foo3bar for nested type names. So don't accept
2183 this style of constructor for cfront demangling. A GNU
2184 style member-template constructor starts with 'H'. */
2185 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2186 work -> constructor += 1;
2187 *mangled = scan + 2;
2190 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2192 /* Cfront-style parameterized type. Handled later as a signature. */
2196 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2198 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2199 || (scan[2] == 'p' && scan[3] == 's')
2200 || (scan[2] == 'p' && scan[3] == 't')))
2202 /* EDG-style parameterized type. Handled later as a signature. */
2206 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2208 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
2209 && (scan[2] != 't'))
2211 /* Mangled name starts with "__". Skip over any leading '_' characters,
2212 then find the next "__" that separates the prefix from the signature.
2214 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2215 || (arm_special (mangled, declp) == 0))
2217 while (*scan == '_')
2221 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2223 /* No separator (I.E. "__not_mangled"), or empty signature
2224 (I.E. "__not_mangled_either__") */
2230 /* Look for the LAST occurrence of __, allowing names to have
2231 the '__' sequence embedded in them.*/
2232 while ((tmp = mystrstr (scan+2, "__")) != NULL)
2234 if (*(scan + 2) == '\0')
2237 demangle_function_name (work, mangled, declp, scan);
2241 else if (*(scan + 2) != '\0')
2243 /* Mangled name does not start with "__" but does have one somewhere
2244 in there with non empty stuff after it. Looks like a global
2246 demangle_function_name (work, mangled, declp, scan);
2250 /* Doesn't look like a mangled name */
2254 if (!success && (work->constructor == 2 || work->destructor == 2))
2256 string_append (declp, *mangled);
2257 *mangled += strlen (*mangled);
2267 gnu_special -- special handling of gnu mangled strings
2272 gnu_special (struct work_stuff *work, const char **mangled,
2278 Process some special GNU style mangling forms that don't fit
2279 the normal pattern. For example:
2281 _$_3foo (destructor for class foo)
2282 _vt$foo (foo virtual table)
2283 _vt$foo$bar (foo::bar virtual table)
2284 __vt_foo (foo virtual table, new style with thunks)
2285 _3foo$varname (static data member)
2286 _Q22rs2tu$vw (static data member)
2287 __t6vector1Zii (constructor with template)
2288 __thunk_4__$_7ostream (virtual function thunk)
2292 gnu_special (work, mangled, declp)
2293 struct work_stuff *work;
2294 const char **mangled;
2301 if ((*mangled)[0] == '_'
2302 && strchr (cplus_markers, (*mangled)[1]) != NULL
2303 && (*mangled)[2] == '_')
2305 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2307 work -> destructor += 1;
2309 else if ((*mangled)[0] == '_'
2310 && (((*mangled)[1] == '_'
2311 && (*mangled)[2] == 'v'
2312 && (*mangled)[3] == 't'
2313 && (*mangled)[4] == '_')
2314 || ((*mangled)[1] == 'v'
2315 && (*mangled)[2] == 't'
2316 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2318 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2319 and create the decl. Note that we consume the entire mangled
2320 input string, which means that demangle_signature has no work
2322 if ((*mangled)[2] == 'v')
2323 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2325 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2326 while (**mangled != '\0')
2332 success = demangle_qualified (work, mangled, declp, 0, 1);
2335 success = demangle_template (work, mangled, declp, 0, 1,
2339 if (isdigit((unsigned char)*mangled[0]))
2341 n = consume_count(mangled);
2342 /* We may be seeing a too-large size, or else a
2343 ".<digits>" indicating a static local symbol. In
2344 any case, declare victory and move on; *don't* try
2345 to use n to allocate. */
2346 if (n > (int) strlen (*mangled))
2354 n = strcspn (*mangled, cplus_markers);
2356 string_appendn (declp, *mangled, n);
2360 p = strpbrk (*mangled, cplus_markers);
2361 if (success && ((p == NULL) || (p == *mangled)))
2365 string_append (declp, SCOPE_STRING (work));
2376 string_append (declp, " virtual table");
2378 else if ((*mangled)[0] == '_'
2379 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2380 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2382 /* static data member, "_3foo$varname" for example */
2388 success = demangle_qualified (work, mangled, declp, 0, 1);
2391 success = demangle_template (work, mangled, declp, 0, 1, 1);
2394 n = consume_count (mangled);
2395 string_appendn (declp, *mangled, n);
2398 if (success && (p == *mangled))
2400 /* Consumed everything up to the cplus_marker, append the
2403 string_append (declp, SCOPE_STRING (work));
2404 n = strlen (*mangled);
2405 string_appendn (declp, *mangled, n);
2413 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2415 int delta = ((*mangled) += 8, consume_count (mangled));
2416 char *method = internal_cplus_demangle (work, ++*mangled);
2420 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2421 string_append (declp, buf);
2422 string_append (declp, method);
2424 n = strlen (*mangled);
2432 else if (strncmp (*mangled, "__t", 3) == 0
2433 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2435 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2441 success = demangle_qualified (work, mangled, declp, 0, 1);
2444 success = demangle_template (work, mangled, declp, 0, 1, 1);
2447 success = demangle_fund_type (work, mangled, declp);
2450 if (success && **mangled != '\0')
2453 string_append (declp, p);
2463 recursively_demangle(work, mangled, result, namelength)
2464 struct work_stuff *work;
2465 const char **mangled;
2469 char * recurse = (char *)NULL;
2470 char * recurse_dem = (char *)NULL;
2472 recurse = (char *) xmalloc (namelength + 1);
2473 memcpy (recurse, *mangled, namelength);
2474 recurse[namelength] = '\000';
2476 recurse_dem = cplus_demangle (recurse, work->options);
2480 string_append (result, recurse_dem);
2485 string_appendn (result, *mangled, namelength);
2488 *mangled += namelength;
2495 arm_special -- special handling of ARM/lucid mangled strings
2500 arm_special (const char **mangled,
2506 Process some special ARM style mangling forms that don't fit
2507 the normal pattern. For example:
2509 __vtbl__3foo (foo virtual table)
2510 __vtbl__3foo__3bar (bar::foo virtual table)
2515 arm_special (mangled, declp)
2516 const char **mangled;
2523 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2525 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2526 and create the decl. Note that we consume the entire mangled
2527 input string, which means that demangle_signature has no work
2529 scan = *mangled + ARM_VTABLE_STRLEN;
2530 while (*scan != '\0') /* first check it can be demangled */
2532 n = consume_count (&scan);
2535 return (0); /* no good */
2538 if (scan[0] == '_' && scan[1] == '_')
2543 (*mangled) += ARM_VTABLE_STRLEN;
2544 while (**mangled != '\0')
2546 n = consume_count (mangled);
2547 string_prependn (declp, *mangled, n);
2549 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2551 string_prepend (declp, "::");
2555 string_append (declp, " virtual table");
2568 demangle_qualified -- demangle 'Q' qualified name strings
2573 demangle_qualified (struct work_stuff *, const char *mangled,
2574 string *result, int isfuncname, int append);
2578 Demangle a qualified name, such as "Q25Outer5Inner" which is
2579 the mangled form of "Outer::Inner". The demangled output is
2580 prepended or appended to the result string according to the
2581 state of the append flag.
2583 If isfuncname is nonzero, then the qualified name we are building
2584 is going to be used as a member function name, so if it is a
2585 constructor or destructor function, append an appropriate
2586 constructor or destructor name. I.E. for the above example,
2587 the result for use as a constructor is "Outer::Inner::Inner"
2588 and the result for use as a destructor is "Outer::Inner::~Inner".
2592 Numeric conversion is ASCII dependent (FIXME).
2597 demangle_qualified (work, mangled, result, isfuncname, append)
2598 struct work_stuff *work;
2599 const char **mangled;
2610 int bindex = register_Btype (work);
2612 /* We only make use of ISFUNCNAME if the entity is a constructor or
2614 isfuncname = (isfuncname
2615 && ((work->constructor & 1) || (work->destructor & 1)));
2617 string_init (&temp);
2618 string_init (&last_name);
2620 if ((*mangled)[0] == 'K')
2622 /* Squangling qualified name reuse */
2625 idx = consume_count_with_underscores (mangled);
2626 if (idx == -1 || idx >= work -> numk)
2629 string_append (&temp, work -> ktypevec[idx]);
2632 switch ((*mangled)[1])
2635 /* GNU mangled name with more than 9 classes. The count is preceded
2636 by an underscore (to distinguish it from the <= 9 case) and followed
2637 by an underscore. */
2639 qualifiers = atoi (p);
2640 if (!isdigit ((unsigned char)*p) || *p == '0')
2643 /* Skip the digits. */
2644 while (isdigit ((unsigned char)*p))
2662 /* The count is in a single digit. */
2663 num[0] = (*mangled)[1];
2665 qualifiers = atoi (num);
2667 /* If there is an underscore after the digit, skip it. This is
2668 said to be for ARM-qualified names, but the ARM makes no
2669 mention of such an underscore. Perhaps cfront uses one. */
2670 if ((*mangled)[2] == '_')
2685 /* Pick off the names and collect them in the temp buffer in the order
2686 in which they are found, separated by '::'. */
2688 while (qualifiers-- > 0)
2691 string_clear (&last_name);
2693 if (*mangled[0] == '_')
2696 if (*mangled[0] == 't')
2698 /* Here we always append to TEMP since we will want to use
2699 the template name without the template parameters as a
2700 constructor or destructor name. The appropriate
2701 (parameter-less) value is returned by demangle_template
2702 in LAST_NAME. We do not remember the template type here,
2703 in order to match the G++ mangling algorithm. */
2704 success = demangle_template(work, mangled, &temp,
2709 else if (*mangled[0] == 'K')
2713 idx = consume_count_with_underscores (mangled);
2714 if (idx == -1 || idx >= work->numk)
2717 string_append (&temp, work->ktypevec[idx]);
2720 if (!success) break;
2727 /* Now recursively demangle the qualifier
2728 * This is necessary to deal with templates in
2729 * mangling styles like EDG */
2730 namelength = consume_count (mangled);
2731 recursively_demangle(work, mangled, &temp, namelength);
2735 success = do_type (work, mangled, &last_name);
2738 string_appends (&temp, &last_name);
2743 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2746 string_append (&temp, SCOPE_STRING (work));
2749 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2751 /* If we are using the result as a function name, we need to append
2752 the appropriate '::' separated constructor or destructor name.
2753 We do this here because this is the most convenient place, where
2754 we already have a pointer to the name and the length of the name. */
2758 string_append (&temp, SCOPE_STRING (work));
2759 if (work -> destructor & 1)
2760 string_append (&temp, "~");
2761 string_appends (&temp, &last_name);
2764 /* Now either prepend the temp buffer to the result, or append it,
2765 depending upon the state of the append flag. */
2768 string_appends (result, &temp);
2771 if (!STRING_EMPTY (result))
2772 string_append (&temp, SCOPE_STRING (work));
2773 string_prepends (result, &temp);
2776 string_delete (&last_name);
2777 string_delete (&temp);
2785 get_count -- convert an ascii count to integer, consuming tokens
2790 get_count (const char **type, int *count)
2794 Return 0 if no conversion is performed, 1 if a string is converted.
2798 get_count (type, count)
2805 if (!isdigit ((unsigned char)**type))
2811 *count = **type - '0';
2813 if (isdigit ((unsigned char)**type))
2823 while (isdigit ((unsigned char)*p));
2834 /* RESULT will be initialised here; it will be freed on failure. The
2835 value returned is really a type_kind_t. */
2838 do_type (work, mangled, result)
2839 struct work_stuff *work;
2840 const char **mangled;
2847 const char *remembered_type;
2850 type_kind_t tk = tk_none;
2852 string_init (&btype);
2853 string_init (&decl);
2854 string_init (result);
2858 while (success && !done)
2864 /* A pointer type */
2868 string_prepend (&decl, "*");
2873 /* A reference type */
2876 string_prepend (&decl, "&");
2885 if (!STRING_EMPTY (&decl)
2886 && (decl.b[0] == '*' || decl.b[0] == '&'))
2888 string_prepend (&decl, "(");
2889 string_append (&decl, ")");
2891 string_append (&decl, "[");
2892 if (**mangled != '_')
2893 success = demangle_template_value_parm (work, mangled, &decl,
2895 if (**mangled == '_')
2897 string_append (&decl, "]");
2901 /* A back reference to a previously seen type */
2904 if (!get_count (mangled, &n) || n >= work -> ntypes)
2910 remembered_type = work -> typevec[n];
2911 mangled = &remembered_type;
2918 if (!STRING_EMPTY (&decl)
2919 && (decl.b[0] == '*' || decl.b[0] == '&'))
2921 string_prepend (&decl, "(");
2922 string_append (&decl, ")");
2924 /* After picking off the function args, we expect to either find the
2925 function return type (preceded by an '_') or the end of the
2927 if (!demangle_nested_args (work, mangled, &decl)
2928 || (**mangled != '_' && **mangled != '\0'))
2933 if (success && (**mangled == '_'))
2940 type_quals = TYPE_UNQUALIFIED;
2942 member = **mangled == 'M';
2944 if (!isdigit ((unsigned char)**mangled) && **mangled != 't')
2950 string_append (&decl, ")");
2951 string_prepend (&decl, SCOPE_STRING (work));
2952 if (isdigit ((unsigned char)**mangled))
2954 n = consume_count (mangled);
2955 if ((int) strlen (*mangled) < n)
2960 string_prependn (&decl, *mangled, n);
2966 string_init (&temp);
2967 success = demangle_template (work, mangled, &temp,
2971 string_prependn (&decl, temp.b, temp.p - temp.b);
2972 string_clear (&temp);
2977 string_prepend (&decl, "(");
2985 type_quals |= code_for_qualifier (**mangled);
2993 if (*(*mangled)++ != 'F')
2999 if ((member && !demangle_nested_args (work, mangled, &decl))
3000 || **mangled != '_')
3006 if (! PRINT_ANSI_QUALIFIERS)
3010 if (type_quals != TYPE_UNQUALIFIED)
3012 APPEND_BLANK (&decl);
3013 string_append (&decl, qualifier_string (type_quals));
3024 if (PRINT_ANSI_QUALIFIERS)
3026 if (!STRING_EMPTY (&decl))
3027 string_prepend (&decl, " ");
3029 string_prepend (&decl, demangle_qualifier (**mangled));
3044 if (success) switch (**mangled)
3046 /* A qualified name, such as "Outer::Inner". */
3050 success = demangle_qualified (work, mangled, result, 0, 1);
3054 /* A back reference to a previously seen squangled type */
3057 if (!get_count (mangled, &n) || n >= work -> numb)
3060 string_append (result, work->btypevec[n]);
3065 /* A template parm. We substitute the corresponding argument. */
3070 idx = consume_count_with_underscores (mangled);
3073 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3074 || consume_count_with_underscores (mangled) == -1)
3080 if (work->tmpl_argvec)
3081 string_append (result, work->tmpl_argvec[idx]);
3085 sprintf(buf, "T%d", idx);
3086 string_append (result, buf);
3094 success = demangle_fund_type (work, mangled, result);
3096 tk = (type_kind_t) success;
3102 if (!STRING_EMPTY (&decl))
3104 string_append (result, " ");
3105 string_appends (result, &decl);
3109 string_delete (result);
3110 string_delete (&decl);
3113 /* Assume an integral type, if we're not sure. */
3114 return (int) ((tk == tk_none) ? tk_integral : tk);
3119 /* Given a pointer to a type string that represents a fundamental type
3120 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3121 string in which the demangled output is being built in RESULT, and
3122 the WORK structure, decode the types and add them to the result.
3127 "Sl" => "signed long"
3128 "CUs" => "const unsigned short"
3130 The value returned is really a type_kind_t. */
3133 demangle_fund_type (work, mangled, result)
3134 struct work_stuff *work;
3135 const char **mangled;
3143 type_kind_t tk = tk_integral;
3145 string_init (&btype);
3147 /* First pick off any type qualifiers. There can be more than one. */
3156 if (PRINT_ANSI_QUALIFIERS)
3158 if (!STRING_EMPTY (result))
3159 string_prepend (result, " ");
3160 string_prepend (result, demangle_qualifier (**mangled));
3166 APPEND_BLANK (result);
3167 string_append (result, "unsigned");
3169 case 'S': /* signed char only */
3171 APPEND_BLANK (result);
3172 string_append (result, "signed");
3176 APPEND_BLANK (result);
3177 string_append (result, "__complex");
3185 /* Now pick off the fundamental type. There can be only one. */
3194 APPEND_BLANK (result);
3195 string_append (result, "void");
3199 APPEND_BLANK (result);
3200 string_append (result, "long long");
3204 APPEND_BLANK (result);
3205 string_append (result, "long");
3209 APPEND_BLANK (result);
3210 string_append (result, "int");
3214 APPEND_BLANK (result);
3215 string_append (result, "short");
3219 APPEND_BLANK (result);
3220 string_append (result, "bool");
3225 APPEND_BLANK (result);
3226 string_append (result, "char");
3231 APPEND_BLANK (result);
3232 string_append (result, "wchar_t");
3237 APPEND_BLANK (result);
3238 string_append (result, "long double");
3243 APPEND_BLANK (result);
3244 string_append (result, "double");
3249 APPEND_BLANK (result);
3250 string_append (result, "float");
3255 if (!isdigit ((unsigned char)**mangled))
3262 if (**mangled == '_')
3266 for (i = 0; **mangled != '_'; ++(*mangled), ++i)
3273 strncpy (buf, *mangled, 2);
3276 sscanf (buf, "%x", &dec);
3277 sprintf (buf, "int%i_t", dec);
3278 APPEND_BLANK (result);
3279 string_append (result, buf);
3283 /* An explicit type, such as "6mytype" or "7integer" */
3295 int bindex = register_Btype (work);
3297 string_init (&btype);
3298 if (demangle_class_name (work, mangled, &btype)) {
3299 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3300 APPEND_BLANK (result);
3301 string_appends (result, &btype);
3305 string_delete (&btype);
3310 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3311 string_appends (result, &btype);
3319 return success ? ((int) tk) : 0;
3323 /* Handle a template's value parameter for HP aCC (extension from ARM)
3324 **mangled points to 'S' or 'U' */
3327 do_hpacc_template_const_value (work, mangled, result)
3328 struct work_stuff *work;
3329 const char **mangled;
3334 if (**mangled != 'U' && **mangled != 'S')
3337 unsigned_const = (**mangled == 'U');
3344 string_append (result, "-");
3350 /* special case for -2^31 */
3351 string_append (result, "-2147483648");
3358 /* We have to be looking at an integer now */
3359 if (!(isdigit (**mangled)))
3362 /* We only deal with integral values for template
3363 parameters -- so it's OK to look only for digits */
3364 while (isdigit (**mangled))
3366 char_str[0] = **mangled;
3367 string_append (result, char_str);
3372 string_append (result, "U");
3374 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3375 with L or LL suffixes. pai/1997-09-03 */
3377 return 1; /* success */
3380 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3381 **mangled is pointing to the 'A' */
3384 do_hpacc_template_literal (work, mangled, result)
3385 struct work_stuff *work;
3386 const char **mangled;
3389 int literal_len = 0;
3394 if (**mangled != 'A')
3399 literal_len = consume_count (mangled);
3404 /* Literal parameters are names of arrays, functions, etc. and the
3405 canonical representation uses the address operator */
3406 string_append (result, "&");
3408 /* Now recursively demangle the literal name */
3409 recurse = (char *) xmalloc (literal_len + 1);
3410 memcpy (recurse, *mangled, literal_len);
3411 recurse[literal_len] = '\000';
3413 recurse_dem = cplus_demangle (recurse, work->options);
3417 string_append (result, recurse_dem);
3422 string_appendn (result, *mangled, literal_len);
3424 (*mangled) += literal_len;
3431 snarf_numeric_literal (args, arg)
3438 string_append (arg, char_str);
3441 else if (**args == '+')
3444 if (!isdigit (**args))
3447 while (isdigit (**args))
3449 char_str[0] = **args;
3450 string_append (arg, char_str);
3457 /* Demangle the next argument, given by MANGLED into RESULT, which
3458 *should be an uninitialized* string. It will be initialized here,
3459 and free'd should anything go wrong. */
3462 do_arg (work, mangled, result)
3463 struct work_stuff *work;
3464 const char **mangled;
3467 /* Remember where we started so that we can record the type, for
3468 non-squangling type remembering. */
3469 const char *start = *mangled;
3471 string_init (result);
3473 if (work->nrepeats > 0)
3477 if (work->previous_argument == 0)
3480 /* We want to reissue the previous type in this argument list. */
3481 string_appends (result, work->previous_argument);
3485 if (**mangled == 'n')
3487 /* A squangling-style repeat. */
3489 work->nrepeats = consume_count(mangled);
3491 if (work->nrepeats == 0)
3492 /* This was not a repeat count after all. */
3495 if (work->nrepeats > 9)
3497 if (**mangled != '_')
3498 /* The repeat count should be followed by an '_' in this
3505 /* Now, the repeat is all set up. */
3506 return do_arg (work, mangled, result);
3509 /* Save the result in WORK->previous_argument so that we can find it
3510 if it's repeated. Note that saving START is not good enough: we
3511 do not want to add additional types to the back-referenceable
3512 type vector when processing a repeated type. */
3513 if (work->previous_argument)
3514 string_clear (work->previous_argument);
3517 work->previous_argument = (string*) xmalloc (sizeof (string));
3518 string_init (work->previous_argument);
3521 if (!do_type (work, mangled, work->previous_argument))
3524 string_appends (result, work->previous_argument);
3526 remember_type (work, start, *mangled - start);
3531 remember_type (work, start, len)
3532 struct work_stuff *work;
3538 if (work->forgetting_types)
3541 if (work -> ntypes >= work -> typevec_size)
3543 if (work -> typevec_size == 0)
3545 work -> typevec_size = 3;
3547 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3551 work -> typevec_size *= 2;
3553 = (char **) xrealloc ((char *)work -> typevec,
3554 sizeof (char *) * work -> typevec_size);
3557 tem = xmalloc (len + 1);
3558 memcpy (tem, start, len);
3560 work -> typevec[work -> ntypes++] = tem;
3564 /* Remember a K type class qualifier. */
3566 remember_Ktype (work, start, len)
3567 struct work_stuff *work;
3573 if (work -> numk >= work -> ksize)
3575 if (work -> ksize == 0)
3579 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3585 = (char **) xrealloc ((char *)work -> ktypevec,
3586 sizeof (char *) * work -> ksize);
3589 tem = xmalloc (len + 1);
3590 memcpy (tem, start, len);
3592 work -> ktypevec[work -> numk++] = tem;
3595 /* Register a B code, and get an index for it. B codes are registered
3596 as they are seen, rather than as they are completed, so map<temp<char> >
3597 registers map<temp<char> > as B0, and temp<char> as B1 */
3600 register_Btype (work)
3601 struct work_stuff *work;
3605 if (work -> numb >= work -> bsize)
3607 if (work -> bsize == 0)
3611 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3617 = (char **) xrealloc ((char *)work -> btypevec,
3618 sizeof (char *) * work -> bsize);
3621 ret = work -> numb++;
3622 work -> btypevec[ret] = NULL;
3626 /* Store a value into a previously registered B code type. */
3629 remember_Btype (work, start, len, index)
3630 struct work_stuff *work;
3636 tem = xmalloc (len + 1);
3637 memcpy (tem, start, len);
3639 work -> btypevec[index] = tem;
3642 /* Lose all the info related to B and K type codes. */
3644 forget_B_and_K_types (work)
3645 struct work_stuff *work;
3649 while (work -> numk > 0)
3651 i = --(work -> numk);
3652 if (work -> ktypevec[i] != NULL)
3654 free (work -> ktypevec[i]);
3655 work -> ktypevec[i] = NULL;
3659 while (work -> numb > 0)
3661 i = --(work -> numb);
3662 if (work -> btypevec[i] != NULL)
3664 free (work -> btypevec[i]);
3665 work -> btypevec[i] = NULL;
3669 /* Forget the remembered types, but not the type vector itself. */
3673 struct work_stuff *work;
3677 while (work -> ntypes > 0)
3679 i = --(work -> ntypes);
3680 if (work -> typevec[i] != NULL)
3682 free (work -> typevec[i]);
3683 work -> typevec[i] = NULL;
3688 /* Process the argument list part of the signature, after any class spec
3689 has been consumed, as well as the first 'F' character (if any). For
3692 "__als__3fooRT0" => process "RT0"
3693 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3695 DECLP must be already initialised, usually non-empty. It won't be freed
3698 Note that g++ differs significantly from ARM and lucid style mangling
3699 with regards to references to previously seen types. For example, given
3700 the source fragment:
3704 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3707 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3708 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3710 g++ produces the names:
3715 while lcc (and presumably other ARM style compilers as well) produces:
3717 foo__FiR3fooT1T2T1T2
3718 __ct__3fooFiR3fooT1T2T1T2
3720 Note that g++ bases its type numbers starting at zero and counts all
3721 previously seen types, while lucid/ARM bases its type numbers starting
3722 at one and only considers types after it has seen the 'F' character
3723 indicating the start of the function args. For lucid/ARM style, we
3724 account for this difference by discarding any previously seen types when
3725 we see the 'F' character, and subtracting one from the type number
3731 demangle_args (work, mangled, declp)
3732 struct work_stuff *work;
3733 const char **mangled;
3743 if (PRINT_ARG_TYPES)
3745 string_append (declp, "(");
3746 if (**mangled == '\0')
3748 string_append (declp, "void");
3752 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3753 || work->nrepeats > 0)
3755 if ((**mangled == 'N') || (**mangled == 'T'))
3757 temptype = *(*mangled)++;
3759 if (temptype == 'N')
3761 if (!get_count (mangled, &r))
3770 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
3772 /* If we have 10 or more types we might have more than a 1 digit
3773 index so we'll have to consume the whole count here. This
3774 will lose if the next thing is a type name preceded by a
3775 count but it's impossible to demangle that case properly
3776 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3777 Pc, ...)" or "(..., type12, char *, ...)" */
3778 if ((t = consume_count(mangled)) == 0)
3785 if (!get_count (mangled, &t))
3790 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3794 /* Validate the type index. Protect against illegal indices from
3795 malformed type strings. */
3796 if ((t < 0) || (t >= work -> ntypes))
3800 while (work->nrepeats > 0 || --r >= 0)
3802 tem = work -> typevec[t];
3803 if (need_comma && PRINT_ARG_TYPES)
3805 string_append (declp, ", ");
3807 if (!do_arg (work, &tem, &arg))
3811 if (PRINT_ARG_TYPES)
3813 string_appends (declp, &arg);
3815 string_delete (&arg);
3821 if (need_comma && PRINT_ARG_TYPES)
3822 string_append (declp, ", ");
3823 if (!do_arg (work, mangled, &arg))
3825 if (PRINT_ARG_TYPES)
3826 string_appends (declp, &arg);
3827 string_delete (&arg);
3832 if (**mangled == 'e')
3835 if (PRINT_ARG_TYPES)
3839 string_append (declp, ",");
3841 string_append (declp, "...");
3845 if (PRINT_ARG_TYPES)
3847 string_append (declp, ")");
3852 /* Like demangle_args, but for demangling the argument lists of function
3853 and method pointers or references, not top-level declarations. */
3856 demangle_nested_args (work, mangled, declp)
3857 struct work_stuff *work;
3858 const char **mangled;
3861 string* saved_previous_argument;
3865 /* The G++ name-mangling algorithm does not remember types on nested
3866 argument lists, unless -fsquangling is used, and in that case the
3867 type vector updated by remember_type is not used. So, we turn
3868 off remembering of types here. */
3869 ++work->forgetting_types;
3871 /* For the repeat codes used with -fsquangling, we must keep track of
3872 the last argument. */
3873 saved_previous_argument = work->previous_argument;
3874 saved_nrepeats = work->nrepeats;
3875 work->previous_argument = 0;
3878 /* Actually demangle the arguments. */
3879 result = demangle_args (work, mangled, declp);
3881 /* Restore the previous_argument field. */
3882 if (work->previous_argument)
3883 string_delete (work->previous_argument);
3884 work->previous_argument = saved_previous_argument;
3885 work->nrepeats = saved_nrepeats;
3891 demangle_function_name (work, mangled, declp, scan)
3892 struct work_stuff *work;
3893 const char **mangled;
3901 string_appendn (declp, (*mangled), scan - (*mangled));
3902 string_need (declp, 1);
3903 *(declp -> p) = '\0';
3905 /* Consume the function name, including the "__" separating the name
3906 from the signature. We are guaranteed that SCAN points to the
3909 (*mangled) = scan + 2;
3910 /* We may be looking at an instantiation of a template function:
3911 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
3912 following _F marks the start of the function arguments. Handle
3913 the template arguments first. */
3915 if (HP_DEMANGLING && (**mangled == 'X'))
3917 demangle_arm_hp_template (work, mangled, 0, declp);
3918 /* This leaves MANGLED pointing to the 'F' marking func args */
3921 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3924 /* See if we have an ARM style constructor or destructor operator.
3925 If so, then just record it, clear the decl, and return.
3926 We can't build the actual constructor/destructor decl until later,
3927 when we recover the class name from the signature. */
3929 if (strcmp (declp -> b, "__ct") == 0)
3931 work -> constructor += 1;
3932 string_clear (declp);
3935 else if (strcmp (declp -> b, "__dt") == 0)
3937 work -> destructor += 1;
3938 string_clear (declp);
3943 if (declp->p - declp->b >= 3
3944 && declp->b[0] == 'o'
3945 && declp->b[1] == 'p'
3946 && strchr (cplus_markers, declp->b[2]) != NULL)
3948 /* see if it's an assignment expression */
3949 if (declp->p - declp->b >= 10 /* op$assign_ */
3950 && memcmp (declp->b + 3, "assign_", 7) == 0)
3952 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3954 int len = declp->p - declp->b - 10;
3955 if ((int) strlen (optable[i].in) == len
3956 && memcmp (optable[i].in, declp->b + 10, len) == 0)
3958 string_clear (declp);
3959 string_append (declp, "operator");
3960 string_append (declp, optable[i].out);
3961 string_append (declp, "=");
3968 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3970 int len = declp->p - declp->b - 3;
3971 if ((int) strlen (optable[i].in) == len
3972 && memcmp (optable[i].in, declp->b + 3, len) == 0)
3974 string_clear (declp);
3975 string_append (declp, "operator");
3976 string_append (declp, optable[i].out);
3982 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
3983 && strchr (cplus_markers, declp->b[4]) != NULL)
3985 /* type conversion operator */
3987 if (do_type (work, &tem, &type))
3989 string_clear (declp);
3990 string_append (declp, "operator ");
3991 string_appends (declp, &type);
3992 string_delete (&type);
3995 else if (declp->b[0] == '_' && declp->b[1] == '_'
3996 && declp->b[2] == 'o' && declp->b[3] == 'p')
3999 /* type conversion operator. */
4001 if (do_type (work, &tem, &type))
4003 string_clear (declp);
4004 string_append (declp, "operator ");
4005 string_appends (declp, &type);
4006 string_delete (&type);
4009 else if (declp->b[0] == '_' && declp->b[1] == '_'
4010 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
4011 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
4013 if (declp->b[4] == '\0')
4016 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4018 if (strlen (optable[i].in) == 2
4019 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4021 string_clear (declp);
4022 string_append (declp, "operator");
4023 string_append (declp, optable[i].out);
4030 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4033 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4035 if (strlen (optable[i].in) == 3
4036 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4038 string_clear (declp);
4039 string_append (declp, "operator");
4040 string_append (declp, optable[i].out);
4049 /* a mini string-handling package */
4064 s->p = s->b = xmalloc (n);
4067 else if (s->e - s->p < n)
4072 s->b = xrealloc (s->b, n);
4085 s->b = s->e = s->p = NULL;
4093 s->b = s->p = s->e = NULL;
4109 return (s->b == s->p);
4115 string_append (p, s)
4120 if (s == NULL || *s == '\0')
4124 memcpy (p->p, s, n);
4129 string_appends (p, s)
4138 memcpy (p->p, s->b, n);
4144 string_appendn (p, s, n)
4152 memcpy (p->p, s, n);
4158 string_prepend (p, s)
4162 if (s != NULL && *s != '\0')
4164 string_prependn (p, s, strlen (s));
4169 string_prepends (p, s)
4174 string_prependn (p, s->b, s->p - s->b);
4179 string_prependn (p, s, n)
4189 for (q = p->p - 1; q >= p->b; q--)
4193 memcpy (p->b, s, n);
4198 /* To generate a standalone demangler program for testing purposes,
4199 just compile and link this file with -DMAIN and libiberty.a. When
4200 run, it demangles each command line arg, or each stdin string, and
4201 prints the result on stdout. */
4207 static char *program_name;
4208 static char *program_version = VERSION;
4209 static int flags = DMGL_PARAMS | DMGL_ANSI;
4211 static void demangle_it PARAMS ((char *));
4212 static void usage PARAMS ((FILE *, int));
4213 static void fatal PARAMS ((char *));
4216 demangle_it (mangled_name)
4221 result = cplus_demangle (mangled_name, flags);
4224 printf ("%s\n", mangled_name);
4228 printf ("%s\n", result);
4234 usage (stream, status)
4239 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4240 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4241 [--help] [--version] [arg...]\n",
4246 #define MBUF_SIZE 32767
4247 char mbuffer[MBUF_SIZE];
4249 /* Defined in the automatically-generated underscore.c. */
4250 extern int prepends_underscore;
4252 int strip_underscore = 0;
4254 static struct option long_options[] = {
4255 {"strip-underscores", no_argument, 0, '_'},
4256 {"format", required_argument, 0, 's'},
4257 {"help", no_argument, 0, 'h'},
4258 {"no-strip-underscores", no_argument, 0, 'n'},
4259 {"version", no_argument, 0, 'v'},
4260 {0, no_argument, 0, 0}
4263 /* More 'friendly' abort that prints the line and file.
4264 config.h can #define abort fancy_abort if you like that sort of thing. */
4269 fatal ("Internal gcc abort.");
4280 program_name = argv[0];
4282 strip_underscore = prepends_underscore;
4284 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
4294 strip_underscore = 0;
4297 printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
4300 strip_underscore = 1;
4303 if (strcmp (optarg, "gnu") == 0)
4305 current_demangling_style = gnu_demangling;
4307 else if (strcmp (optarg, "lucid") == 0)
4309 current_demangling_style = lucid_demangling;
4311 else if (strcmp (optarg, "arm") == 0)
4313 current_demangling_style = arm_demangling;
4315 else if (strcmp (optarg, "hp") == 0)
4317 current_demangling_style = hp_demangling;
4319 else if (strcmp (optarg, "edg") == 0)
4321 current_demangling_style = edg_demangling;
4325 fprintf (stderr, "%s: unknown demangling style `%s'\n",
4326 program_name, optarg);
4335 for ( ; optind < argc; optind++)
4337 demangle_it (argv[optind]);
4346 /* Try to read a label. */
4347 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.' ||
4348 c == '<' || c == '>' || c == '#' || c == ',' || c == '*' || c == '&' ||
4349 c == '[' || c == ']' || c == ':' || c == '(' || c == ')'))
4350 /* the ones in the 2nd & 3rd lines were added to handle
4351 HP aCC template specialization manglings */
4353 if (i >= MBUF_SIZE-1)
4362 if (mbuffer[0] == '.')
4364 if (strip_underscore && mbuffer[skip_first] == '_')
4372 result = cplus_demangle (mbuffer + skip_first, flags);
4375 if (mbuffer[0] == '.')
4377 fputs (result, stdout);
4381 fputs (mbuffer, stdout);
4398 fprintf (stderr, "%s: %s\n", program_name, str);
4406 register PTR value = (PTR) malloc (size);
4408 fatal ("virtual memory exhausted");
4413 xrealloc (ptr, size)
4417 register PTR value = (PTR) realloc (ptr, size);
4419 fatal ("virtual memory exhausted");