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_class_name PARAMS ((struct work_stuff *, const char **, string *));
292 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
296 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
299 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
302 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
305 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
308 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
311 arm_special PARAMS ((const char **, string *));
314 string_need PARAMS ((string *, int));
317 string_delete PARAMS ((string *));
320 string_init PARAMS ((string *));
323 string_clear PARAMS ((string *));
327 string_empty PARAMS ((string *));
331 string_append PARAMS ((string *, const char *));
334 string_appends PARAMS ((string *, string *));
337 string_appendn PARAMS ((string *, const char *, int));
340 string_prepend PARAMS ((string *, const char *));
343 string_prependn PARAMS ((string *, const char *, int));
346 get_count PARAMS ((const char **, int *));
349 consume_count PARAMS ((const char **));
352 consume_count_with_underscores PARAMS ((const char**));
355 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
358 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
361 do_type PARAMS ((struct work_stuff *, const char **, string *));
364 do_arg PARAMS ((struct work_stuff *, const char **, string *));
367 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
371 remember_type PARAMS ((struct work_stuff *, const char *, int));
374 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
377 register_Btype PARAMS ((struct work_stuff *));
380 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
383 forget_types PARAMS ((struct work_stuff *));
386 forget_B_and_K_types PARAMS ((struct work_stuff *));
389 string_prepends PARAMS ((string *, string *));
392 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
393 string*, type_kind_t));
396 do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
399 do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
402 snarf_numeric_literal PARAMS ((const char **, string *));
404 /* There is a TYPE_QUAL value for each type qualifier. They can be
405 combined by bitwise-or to form the complete set of qualifiers for a
408 #define TYPE_UNQUALIFIED 0x0
409 #define TYPE_QUAL_CONST 0x1
410 #define TYPE_QUAL_VOLATILE 0x2
411 #define TYPE_QUAL_RESTRICT 0x4
414 code_for_qualifier PARAMS ((int));
417 qualifier_string PARAMS ((int));
420 demangle_qualifier PARAMS ((int));
422 /* Translate count to integer, consuming tokens in the process.
423 Conversion terminates on the first non-digit character.
424 Trying to consume something that isn't a count results in
425 no consumption of input and a return of 0. */
433 while (isdigit ((unsigned char)**type))
436 count += **type - '0';
443 /* Like consume_count, but for counts that are preceded and followed
444 by '_' if they are greater than 10. Also, -1 is returned for
445 failure, since 0 can be a valid value. */
448 consume_count_with_underscores (mangled)
449 const char **mangled;
453 if (**mangled == '_')
456 if (!isdigit ((unsigned char)**mangled))
459 idx = consume_count (mangled);
460 if (**mangled != '_')
461 /* The trailing underscore was missing. */
468 if (**mangled < '0' || **mangled > '9')
471 idx = **mangled - '0';
478 /* C is the code for a type-qualifier. Return the TYPE_QUAL
479 corresponding to this qualifier. */
482 code_for_qualifier (c)
488 return TYPE_QUAL_CONST;
491 return TYPE_QUAL_VOLATILE;
494 return TYPE_QUAL_RESTRICT;
500 /* C was an invalid qualifier. */
504 /* Return the string corresponding to the qualifiers given by
508 qualifier_string (type_quals)
513 case TYPE_UNQUALIFIED:
516 case TYPE_QUAL_CONST:
519 case TYPE_QUAL_VOLATILE:
522 case TYPE_QUAL_RESTRICT:
525 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
526 return "const volatile";
528 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
529 return "const __restrict";
531 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
532 return "volatile __restrict";
534 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
535 return "const volatile __restrict";
541 /* TYPE_QUALS was an invalid qualifier set. */
545 /* C is the code for a type-qualifier. Return the string
546 corresponding to this qualifier. This function should only be
547 called with a valid qualifier code. */
550 demangle_qualifier (c)
553 return qualifier_string (code_for_qualifier (c));
557 cplus_demangle_opname (opname, result, options)
564 struct work_stuff work[1];
567 len = strlen(opname);
570 memset ((char *) work, 0, sizeof (work));
571 work->options = options;
573 if (opname[0] == '_' && opname[1] == '_'
574 && opname[2] == 'o' && opname[3] == 'p')
577 /* type conversion operator. */
579 if (do_type (work, &tem, &type))
581 strcat (result, "operator ");
582 strncat (result, type.b, type.p - type.b);
583 string_delete (&type);
587 else if (opname[0] == '_' && opname[1] == '_'
588 && opname[2] >= 'a' && opname[2] <= 'z'
589 && opname[3] >= 'a' && opname[3] <= 'z')
591 if (opname[4] == '\0')
595 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
597 if (strlen (optable[i].in) == 2
598 && memcmp (optable[i].in, opname + 2, 2) == 0)
600 strcat (result, "operator");
601 strcat (result, optable[i].out);
609 if (opname[2] == 'a' && opname[5] == '\0')
613 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
615 if (strlen (optable[i].in) == 3
616 && memcmp (optable[i].in, opname + 2, 3) == 0)
618 strcat (result, "operator");
619 strcat (result, optable[i].out);
630 && strchr (cplus_markers, opname[2]) != NULL)
632 /* see if it's an assignment expression */
633 if (len >= 10 /* op$assign_ */
634 && memcmp (opname + 3, "assign_", 7) == 0)
637 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
640 if ((int) strlen (optable[i].in) == len1
641 && memcmp (optable[i].in, opname + 10, len1) == 0)
643 strcat (result, "operator");
644 strcat (result, optable[i].out);
645 strcat (result, "=");
654 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
657 if ((int) strlen (optable[i].in) == len1
658 && memcmp (optable[i].in, opname + 3, len1) == 0)
660 strcat (result, "operator");
661 strcat (result, optable[i].out);
668 else if (len >= 5 && memcmp (opname, "type", 4) == 0
669 && strchr (cplus_markers, opname[4]) != NULL)
671 /* type conversion operator */
673 if (do_type (work, &tem, &type))
675 strcat (result, "operator ");
676 strncat (result, type.b, type.p - type.b);
677 string_delete (&type);
681 squangle_mop_up (work);
685 /* Takes operator name as e.g. "++" and returns mangled
686 operator name (e.g. "postincrement_expr"), or NULL if not found.
688 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
689 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
692 cplus_mangle_opname (opname, options)
699 len = strlen (opname);
700 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
702 if ((int) strlen (optable[i].out) == len
703 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
704 && memcmp (optable[i].out, opname, len) == 0)
705 return optable[i].in;
710 /* char *cplus_demangle (const char *mangled, int options)
712 If MANGLED is a mangled function name produced by GNU C++, then
713 a pointer to a malloced string giving a C++ representation
714 of the name will be returned; otherwise NULL will be returned.
715 It is the caller's responsibility to free the string which
718 The OPTIONS arg may contain one or more of the following bits:
720 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
722 DMGL_PARAMS Function parameters are included.
726 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
727 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
728 cplus_demangle ("foo__1Ai", 0) => "A::foo"
730 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
731 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
732 cplus_demangle ("foo__1Afe", 0) => "A::foo"
734 Note that any leading underscores, or other such characters prepended by
735 the compilation system, are presumed to have already been stripped from
739 cplus_demangle (mangled, options)
744 struct work_stuff work[1];
745 memset ((char *) work, 0, sizeof (work));
746 work -> options = options;
747 if ((work -> options & DMGL_STYLE_MASK) == 0)
748 work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
750 ret = internal_cplus_demangle (work, mangled);
751 squangle_mop_up (work);
756 /* This function performs most of what cplus_demangle use to do, but
757 to be able to demangle a name with a B, K or n code, we need to
758 have a longer term memory of what types have been seen. The original
759 now intializes and cleans up the squangle code info, while internal
760 calls go directly to this routine to avoid resetting that info. */
763 internal_cplus_demangle (work, mangled)
764 struct work_stuff *work;
770 char *demangled = NULL;
772 s1 = work->constructor;
773 s2 = work->destructor;
774 s3 = work->static_type;
775 s4 = work->type_quals;
776 work->constructor = work->destructor = 0;
777 work->type_quals = TYPE_UNQUALIFIED;
778 work->dllimported = 0;
780 if ((mangled != NULL) && (*mangled != '\0'))
784 /* First check to see if gnu style demangling is active and if the
785 string to be demangled contains a CPLUS_MARKER. If so, attempt to
786 recognize one of the gnu special forms rather than looking for a
787 standard prefix. In particular, don't worry about whether there
788 is a "__" string in the mangled string. Consider "_$_5__foo" for
791 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
793 success = gnu_special (work, &mangled, &decl);
797 success = demangle_prefix (work, &mangled, &decl);
799 if (success && (*mangled != '\0'))
801 success = demangle_signature (work, &mangled, &decl);
803 if (work->constructor == 2)
805 string_prepend (&decl, "global constructors keyed to ");
806 work->constructor = 0;
808 else if (work->destructor == 2)
810 string_prepend (&decl, "global destructors keyed to ");
811 work->destructor = 0;
813 else if (work->dllimported == 1)
815 string_prepend (&decl, "import stub for ");
816 work->dllimported = 0;
818 demangled = mop_up (work, &decl, success);
820 work->constructor = s1;
821 work->destructor = s2;
822 work->static_type = s3;
823 work->type_quals = s4;
828 /* Clear out and squangling related storage */
830 squangle_mop_up (work)
831 struct work_stuff *work;
833 /* clean up the B and K type mangling types. */
834 forget_B_and_K_types (work);
835 if (work -> btypevec != NULL)
837 free ((char *) work -> btypevec);
839 if (work -> ktypevec != NULL)
841 free ((char *) work -> ktypevec);
845 /* Clear out any mangled storage */
848 mop_up (work, declp, success)
849 struct work_stuff *work;
853 char *demangled = NULL;
855 /* Discard the remembered types, if any. */
858 if (work -> typevec != NULL)
860 free ((char *) work -> typevec);
861 work -> typevec = NULL;
863 if (work->tmpl_argvec)
867 for (i = 0; i < work->ntmpl_args; i++)
868 if (work->tmpl_argvec[i])
869 free ((char*) work->tmpl_argvec[i]);
871 free ((char*) work->tmpl_argvec);
872 work->tmpl_argvec = NULL;
874 if (work->previous_argument)
876 string_delete (work->previous_argument);
877 free ((char*) work->previous_argument);
880 /* If demangling was successful, ensure that the demangled string is null
881 terminated and return it. Otherwise, free the demangling decl. */
885 string_delete (declp);
889 string_appendn (declp, "", 1);
890 demangled = declp -> b;
899 demangle_signature -- demangle the signature part of a mangled name
904 demangle_signature (struct work_stuff *work, const char **mangled,
909 Consume and demangle the signature portion of the mangled name.
911 DECLP is the string where demangled output is being built. At
912 entry it contains the demangled root name from the mangled name
913 prefix. I.E. either a demangled operator name or the root function
914 name. In some special cases, it may contain nothing.
916 *MANGLED points to the current unconsumed location in the mangled
917 name. As tokens are consumed and demangling is performed, the
918 pointer is updated to continuously point at the next token to
921 Demangling GNU style mangled names is nasty because there is no
922 explicit token that marks the start of the outermost function
926 demangle_signature (work, mangled, declp)
927 struct work_stuff *work;
928 const char **mangled;
934 int expect_return_type = 0;
935 const char *oldmangled = NULL;
939 while (success && (**mangled != '\0'))
944 oldmangled = *mangled;
945 success = demangle_qualified (work, mangled, declp, 1, 0);
947 remember_type (work, oldmangled, *mangled - oldmangled);
948 if (AUTO_DEMANGLING || GNU_DEMANGLING)
954 oldmangled = *mangled;
955 success = demangle_qualified (work, mangled, declp, 1, 0);
956 if (AUTO_DEMANGLING || GNU_DEMANGLING)
964 /* Static member function */
965 if (oldmangled == NULL)
967 oldmangled = *mangled;
970 work -> static_type = 1;
976 work->type_quals |= code_for_qualifier (**mangled);
978 /* a qualified member function */
979 if (oldmangled == NULL)
980 oldmangled = *mangled;
985 /* Local class name follows after "Lnnn_" */
988 while (**mangled && (**mangled != '_'))
999 case '0': case '1': case '2': case '3': case '4':
1000 case '5': case '6': case '7': case '8': case '9':
1001 if (oldmangled == NULL)
1003 oldmangled = *mangled;
1005 work->temp_start = -1; /* uppermost call to demangle_class */
1006 success = demangle_class (work, mangled, declp);
1009 remember_type (work, oldmangled, *mangled - oldmangled);
1011 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1013 /* EDG and others will have the "F", so we let the loop cycle
1014 if we are looking at one. */
1015 if (**mangled != 'F')
1024 success = do_type (work, mangled, &s);
1027 string_append (&s, SCOPE_STRING (work));
1028 string_prepends (declp, &s);
1037 /* ARM/HP style demangling includes a specific 'F' character after
1038 the class name. For GNU style, it is just implied. So we can
1039 safely just consume any 'F' at this point and be compatible
1040 with either style. */
1046 /* For lucid/ARM/HP style we have to forget any types we might
1047 have remembered up to this point, since they were not argument
1048 types. GNU style considers all types seen as available for
1049 back references. See comment in demangle_args() */
1051 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1053 forget_types (work);
1055 success = demangle_args (work, mangled, declp);
1056 /* After picking off the function args, we expect to either
1057 find the function return type (preceded by an '_') or the
1058 end of the string. */
1059 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1062 /* At this level, we do not care about the return type. */
1063 success = do_type (work, mangled, &tname);
1064 string_delete (&tname);
1071 string_init(&trawname);
1072 string_init(&tname);
1073 if (oldmangled == NULL)
1075 oldmangled = *mangled;
1077 success = demangle_template (work, mangled, &tname,
1081 remember_type (work, oldmangled, *mangled - oldmangled);
1083 string_append (&tname, SCOPE_STRING (work));
1085 string_prepends(declp, &tname);
1086 if (work -> destructor & 1)
1088 string_prepend (&trawname, "~");
1089 string_appends (declp, &trawname);
1090 work->destructor -= 1;
1092 if ((work->constructor & 1) || (work->destructor & 1))
1094 string_appends (declp, &trawname);
1095 work->constructor -= 1;
1097 string_delete(&trawname);
1098 string_delete(&tname);
1104 if (GNU_DEMANGLING && expect_return_type)
1106 /* Read the return type. */
1108 string_init (&return_type);
1111 success = do_type (work, mangled, &return_type);
1112 APPEND_BLANK (&return_type);
1114 string_prepends (declp, &return_type);
1115 string_delete (&return_type);
1119 /* At the outermost level, we cannot have a return type specified,
1120 so if we run into another '_' at this point we are dealing with
1121 a mangled name that is either bogus, or has been mangled by
1122 some algorithm we don't know how to deal with. So just
1123 reject the entire demangling. */
1124 /* However, "_nnn" is an expected suffix for alternate entry point
1125 numbered nnn for a function, with HP aCC, so skip over that
1126 without reporting failure. pai/1997-09-04 */
1130 while (**mangled && isdigit ((unsigned char)**mangled))
1140 /* A G++ template function. Read the template arguments. */
1141 success = demangle_template (work, mangled, declp, 0, 0,
1143 if (!(work->constructor & 1))
1144 expect_return_type = 1;
1153 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1155 /* Assume we have stumbled onto the first outermost function
1156 argument token, and start processing args. */
1158 success = demangle_args (work, mangled, declp);
1162 /* Non-GNU demanglers use a specific token to mark the start
1163 of the outermost function argument tokens. Typically 'F',
1164 for ARM/HP-demangling, for example. So if we find something
1165 we are not prepared for, it must be an error. */
1171 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1174 if (success && expect_func)
1177 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1179 forget_types (work);
1181 success = demangle_args (work, mangled, declp);
1182 /* Since template include the mangling of their return types,
1183 we must set expect_func to 0 so that we don't try do
1184 demangle more arguments the next time we get here. */
1189 if (success && !func_done)
1191 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1193 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1194 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1195 first case, and need to ensure that the '(void)' gets added to
1196 the current declp. Note that with ARM/HP, the first case
1197 represents the name of a static data member 'foo::bar',
1198 which is in the current declp, so we leave it alone. */
1199 success = demangle_args (work, mangled, declp);
1202 if (success && PRINT_ARG_TYPES)
1204 if (work->static_type)
1205 string_append (declp, " static");
1206 if (work->type_quals != TYPE_UNQUALIFIED)
1208 APPEND_BLANK (declp);
1209 string_append (declp, qualifier_string (work->type_quals));
1219 demangle_method_args (work, mangled, declp)
1220 struct work_stuff *work;
1221 const char **mangled;
1226 if (work -> static_type)
1228 string_append (declp, *mangled + 1);
1229 *mangled += strlen (*mangled);
1234 success = demangle_args (work, mangled, declp);
1242 demangle_template_template_parm (work, mangled, tname)
1243 struct work_stuff *work;
1244 const char **mangled;
1253 string_append (tname, "template <");
1254 /* get size of template parameter list */
1255 if (get_count (mangled, &r))
1257 for (i = 0; i < r; i++)
1261 string_append (tname, ", ");
1264 /* Z for type parameters */
1265 if (**mangled == 'Z')
1268 string_append (tname, "class");
1270 /* z for template parameters */
1271 else if (**mangled == 'z')
1275 demangle_template_template_parm (work, mangled, tname);
1283 /* temp is initialized in do_type */
1284 success = do_type (work, mangled, &temp);
1287 string_appends (tname, &temp);
1289 string_delete(&temp);
1299 if (tname->p[-1] == '>')
1300 string_append (tname, " ");
1301 string_append (tname, "> class");
1306 demangle_integral_value (work, mangled, s)
1307 struct work_stuff *work;
1308 const char** mangled;
1313 if (**mangled == 'E')
1315 int need_operator = 0;
1318 string_appendn (s, "(", 1);
1320 while (success && **mangled != 'W' && **mangled != '\0')
1329 len = strlen (*mangled);
1332 i < sizeof (optable) / sizeof (optable [0]);
1335 size_t l = strlen (optable[i].in);
1338 && memcmp (optable[i].in, *mangled, l) == 0)
1340 string_appendn (s, " ", 1);
1341 string_append (s, optable[i].out);
1342 string_appendn (s, " ", 1);
1355 success = demangle_template_value_parm (work, mangled, s,
1359 if (**mangled != 'W')
1363 string_appendn (s, ")", 1);
1367 else if (**mangled == 'Q' || **mangled == 'K')
1368 success = demangle_qualified (work, mangled, s, 0, 1);
1373 if (**mangled == 'm')
1375 string_appendn (s, "-", 1);
1378 while (isdigit ((unsigned char)**mangled))
1380 string_appendn (s, *mangled, 1);
1390 demangle_template_value_parm (work, mangled, s, tk)
1391 struct work_stuff *work;
1392 const char **mangled;
1398 if (**mangled == 'Y')
1400 /* The next argument is a template parameter. */
1404 idx = consume_count_with_underscores (mangled);
1406 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1407 || consume_count_with_underscores (mangled) == -1)
1409 if (work->tmpl_argvec)
1410 string_append (s, work->tmpl_argvec[idx]);
1414 sprintf(buf, "T%d", idx);
1415 string_append (s, buf);
1418 else if (tk == tk_integral)
1419 success = demangle_integral_value (work, mangled, s);
1420 else if (tk == tk_char)
1424 if (**mangled == 'm')
1426 string_appendn (s, "-", 1);
1429 string_appendn (s, "'", 1);
1430 val = consume_count(mangled);
1435 string_appendn (s, &tmp[0], 1);
1436 string_appendn (s, "'", 1);
1438 else if (tk == tk_bool)
1440 int val = consume_count (mangled);
1442 string_appendn (s, "false", 5);
1444 string_appendn (s, "true", 4);
1448 else if (tk == tk_real)
1450 if (**mangled == 'm')
1452 string_appendn (s, "-", 1);
1455 while (isdigit ((unsigned char)**mangled))
1457 string_appendn (s, *mangled, 1);
1460 if (**mangled == '.') /* fraction */
1462 string_appendn (s, ".", 1);
1464 while (isdigit ((unsigned char)**mangled))
1466 string_appendn (s, *mangled, 1);
1470 if (**mangled == 'e') /* exponent */
1472 string_appendn (s, "e", 1);
1474 while (isdigit ((unsigned char)**mangled))
1476 string_appendn (s, *mangled, 1);
1481 else if (tk == tk_pointer || tk == tk_reference)
1483 int symbol_len = consume_count (mangled);
1484 if (symbol_len == 0)
1486 if (symbol_len == 0)
1487 string_appendn (s, "0", 1);
1490 char *p = xmalloc (symbol_len + 1), *q;
1491 strncpy (p, *mangled, symbol_len);
1492 p [symbol_len] = '\0';
1493 /* We use cplus_demangle here, rather than
1494 internal_cplus_demangle, because the name of the entity
1495 mangled here does not make use of any of the squangling
1496 or type-code information we have built up thus far; it is
1497 mangled independently. */
1498 q = cplus_demangle (p, work->options);
1499 if (tk == tk_pointer)
1500 string_appendn (s, "&", 1);
1501 /* FIXME: Pointer-to-member constants should get a
1502 qualifying class name here. */
1505 string_append (s, q);
1509 string_append (s, p);
1512 *mangled += symbol_len;
1518 /* Demangle the template name in MANGLED. The full name of the
1519 template (e.g., S<int>) is placed in TNAME. The name without the
1520 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1521 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1522 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1523 the tmeplate is remembered in the list of back-referenceable
1527 demangle_template (work, mangled, tname, trawname, is_type, remember)
1528 struct work_stuff *work;
1529 const char **mangled;
1547 bindex = register_Btype (work);
1549 /* get template name */
1550 if (**mangled == 'z')
1556 idx = consume_count_with_underscores (mangled);
1558 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1559 || consume_count_with_underscores (mangled) == -1)
1562 if (work->tmpl_argvec)
1564 string_append (tname, work->tmpl_argvec[idx]);
1566 string_append (trawname, work->tmpl_argvec[idx]);
1571 sprintf(buf, "T%d", idx);
1572 string_append (tname, buf);
1574 string_append (trawname, buf);
1579 if ((r = consume_count (mangled)) == 0
1580 || (int) strlen (*mangled) < r)
1584 string_appendn (tname, *mangled, r);
1586 string_appendn (trawname, *mangled, r);
1590 string_append (tname, "<");
1591 /* get size of template parameter list */
1592 if (!get_count (mangled, &r))
1598 /* Create an array for saving the template argument values. */
1599 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
1600 work->ntmpl_args = r;
1601 for (i = 0; i < r; i++)
1602 work->tmpl_argvec[i] = 0;
1604 for (i = 0; i < r; i++)
1608 string_append (tname, ", ");
1610 /* Z for type parameters */
1611 if (**mangled == 'Z')
1614 /* temp is initialized in do_type */
1615 success = do_type (work, mangled, &temp);
1618 string_appends (tname, &temp);
1622 /* Save the template argument. */
1623 int len = temp.p - temp.b;
1624 work->tmpl_argvec[i] = xmalloc (len + 1);
1625 memcpy (work->tmpl_argvec[i], temp.b, len);
1626 work->tmpl_argvec[i][len] = '\0';
1629 string_delete(&temp);
1635 /* z for template parameters */
1636 else if (**mangled == 'z')
1640 success = demangle_template_template_parm (work, mangled, tname);
1643 && (r2 = consume_count (mangled)) > 0
1644 && (int) strlen (*mangled) >= r2)
1646 string_append (tname, " ");
1647 string_appendn (tname, *mangled, r2);
1650 /* Save the template argument. */
1652 work->tmpl_argvec[i] = xmalloc (len + 1);
1653 memcpy (work->tmpl_argvec[i], *mangled, len);
1654 work->tmpl_argvec[i][len] = '\0';
1668 /* otherwise, value parameter */
1670 /* temp is initialized in do_type */
1671 success = do_type (work, mangled, &temp);
1672 string_delete(&temp);
1684 success = demangle_template_value_parm (work, mangled, s,
1685 (type_kind_t) success);
1697 int len = s->p - s->b;
1698 work->tmpl_argvec[i] = xmalloc (len + 1);
1699 memcpy (work->tmpl_argvec[i], s->b, len);
1700 work->tmpl_argvec[i][len] = '\0';
1702 string_appends (tname, s);
1709 if (tname->p[-1] == '>')
1710 string_append (tname, " ");
1711 string_append (tname, ">");
1714 if (is_type && remember)
1715 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
1718 if (work -> static_type)
1720 string_append (declp, *mangled + 1);
1721 *mangled += strlen (*mangled);
1726 success = demangle_args (work, mangled, declp);
1734 arm_pt (work, mangled, n, anchor, args)
1735 struct work_stuff *work;
1736 const char *mangled;
1738 const char **anchor, **args;
1740 /* Check if ARM template with "__pt__" in it ("parameterized type") */
1741 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
1742 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
1745 *args = *anchor + 6;
1746 len = consume_count (args);
1747 if (*args + len == mangled + n && **args == '_')
1753 if (AUTO_DEMANGLING || EDG_DEMANGLING)
1755 if ((*anchor = mystrstr (mangled, "__tm__"))
1756 || (*anchor = mystrstr (mangled, "__ps__"))
1757 || (*anchor = mystrstr (mangled, "__pt__")))
1760 *args = *anchor + 6;
1761 len = consume_count (args);
1762 if (*args + len == mangled + n && **args == '_')
1768 else if ((*anchor = mystrstr (mangled, "__S")))
1771 *args = *anchor + 3;
1772 len = consume_count (args);
1773 if (*args + len == mangled + n && **args == '_')
1785 demangle_arm_hp_template (work, mangled, n, declp)
1786 struct work_stuff *work;
1787 const char **mangled;
1793 const char *e = *mangled + n;
1796 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
1798 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
1800 char *start_spec_args = NULL;
1802 /* First check for and omit template specialization pseudo-arguments,
1803 such as in "Spec<#1,#1.*>" */
1804 start_spec_args = strchr (*mangled, '<');
1805 if (start_spec_args && (start_spec_args - *mangled < n))
1806 string_appendn (declp, *mangled, start_spec_args - *mangled);
1808 string_appendn (declp, *mangled, n);
1809 (*mangled) += n + 1;
1811 if (work->temp_start == -1) /* non-recursive call */
1812 work->temp_start = declp->p - declp->b;
1813 string_append (declp, "<");
1816 string_clear (&arg);
1820 /* 'T' signals a type parameter */
1822 if (!do_type (work, mangled, &arg))
1823 goto hpacc_template_args_done;
1828 /* 'U' or 'S' signals an integral value */
1829 if (!do_hpacc_template_const_value (work, mangled, &arg))
1830 goto hpacc_template_args_done;
1834 /* 'A' signals a named constant expression (literal) */
1835 if (!do_hpacc_template_literal (work, mangled, &arg))
1836 goto hpacc_template_args_done;
1840 /* Today, 1997-09-03, we have only the above types
1841 of template parameters */
1842 /* FIXME: maybe this should fail and return null */
1843 goto hpacc_template_args_done;
1845 string_appends (declp, &arg);
1846 /* Check if we're at the end of template args.
1847 0 if at end of static member of template class,
1848 _ if done with template args for a function */
1849 if ((**mangled == '\000') || (**mangled == '_'))
1852 string_append (declp, ",");
1854 hpacc_template_args_done:
1855 string_append (declp, ">");
1856 string_delete (&arg);
1857 if (**mangled == '_')
1861 /* ARM template? (Also handles HP cfront extensions) */
1862 else if (arm_pt (work, *mangled, n, &p, &args))
1867 string_appendn (declp, *mangled, p - *mangled);
1868 if (work->temp_start == -1) /* non-recursive call */
1869 work->temp_start = declp->p - declp->b;
1870 string_append (declp, "<");
1871 /* should do error checking here */
1873 string_clear (&arg);
1875 /* Check for type or literal here */
1878 /* HP cfront extensions to ARM for template args */
1879 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
1880 /* FIXME: We handle only numeric literals for HP cfront */
1882 /* A typed constant value follows */
1884 if (!do_type (work, &args, &type_str))
1885 goto cfront_template_args_done;
1886 string_append (&arg, "(");
1887 string_appends (&arg, &type_str);
1888 string_append (&arg, ")");
1890 goto cfront_template_args_done;
1892 /* Now snarf a literal value following 'L' */
1893 if (!snarf_numeric_literal (&args, &arg))
1894 goto cfront_template_args_done;
1898 /* Snarf a literal following 'L' */
1900 if (!snarf_numeric_literal (&args, &arg))
1901 goto cfront_template_args_done;
1904 /* Not handling other HP cfront stuff */
1905 if (!do_type (work, &args, &arg))
1906 goto cfront_template_args_done;
1908 string_appends (declp, &arg);
1909 string_append (declp, ",");
1911 cfront_template_args_done:
1912 string_delete (&arg);
1914 --declp->p; /* remove extra comma */
1915 string_append (declp, ">");
1917 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
1918 && (*mangled)[9] == 'N'
1919 && (*mangled)[8] == (*mangled)[10]
1920 && strchr (cplus_markers, (*mangled)[8]))
1922 /* A member of the anonymous namespace. */
1923 string_append (declp, "{anonymous}");
1927 if (work->temp_start == -1) /* non-recursive call only */
1928 work->temp_start = 0; /* disable in recursive calls */
1929 string_appendn (declp, *mangled, n);
1934 /* Extract a class name, possibly a template with arguments, from the
1935 mangled string; qualifiers, local class indicators, etc. have
1936 already been dealt with */
1939 demangle_class_name (work, mangled, declp)
1940 struct work_stuff *work;
1941 const char **mangled;
1947 n = consume_count (mangled);
1948 if ((int) strlen (*mangled) >= n)
1950 demangle_arm_hp_template (work, mangled, n, declp);
1961 demangle_class -- demangle a mangled class sequence
1966 demangle_class (struct work_stuff *work, const char **mangled,
1971 DECLP points to the buffer into which demangling is being done.
1973 *MANGLED points to the current token to be demangled. On input,
1974 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
1975 On exit, it points to the next token after the mangled class on
1976 success, or the first unconsumed token on failure.
1978 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
1979 we are demangling a constructor or destructor. In this case
1980 we prepend "class::class" or "class::~class" to DECLP.
1982 Otherwise, we prepend "class::" to the current DECLP.
1984 Reset the constructor/destructor flags once they have been
1985 "consumed". This allows demangle_class to be called later during
1986 the same demangling, to do normal class demangling.
1988 Returns 1 if demangling is successful, 0 otherwise.
1993 demangle_class (work, mangled, declp)
1994 struct work_stuff *work;
1995 const char **mangled;
2001 char *save_class_name_end = 0;
2003 string_init (&class_name);
2004 btype = register_Btype (work);
2005 if (demangle_class_name (work, mangled, &class_name))
2007 save_class_name_end = class_name.p;
2008 if ((work->constructor & 1) || (work->destructor & 1))
2010 /* adjust so we don't include template args */
2011 if (work->temp_start && (work->temp_start != -1))
2013 class_name.p = class_name.b + work->temp_start;
2015 string_prepends (declp, &class_name);
2016 if (work -> destructor & 1)
2018 string_prepend (declp, "~");
2019 work -> destructor -= 1;
2023 work -> constructor -= 1;
2026 class_name.p = save_class_name_end;
2027 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2028 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2029 string_prepend (declp, SCOPE_STRING (work));
2030 string_prepends (declp, &class_name);
2033 string_delete (&class_name);
2041 demangle_prefix -- consume the mangled name prefix and find signature
2046 demangle_prefix (struct work_stuff *work, const char **mangled,
2051 Consume and demangle the prefix of the mangled name.
2053 DECLP points to the string buffer into which demangled output is
2054 placed. On entry, the buffer is empty. On exit it contains
2055 the root function name, the demangled operator name, or in some
2056 special cases either nothing or the completely demangled result.
2058 MANGLED points to the current pointer into the mangled name. As each
2059 token of the mangled name is consumed, it is updated. Upon entry
2060 the current mangled name pointer points to the first character of
2061 the mangled name. Upon exit, it should point to the first character
2062 of the signature if demangling was successful, or to the first
2063 unconsumed character if demangling of the prefix was unsuccessful.
2065 Returns 1 on success, 0 otherwise.
2069 demangle_prefix (work, mangled, declp)
2070 struct work_stuff *work;
2071 const char **mangled;
2078 if (strlen(*mangled) > 6
2079 && (strncmp(*mangled, "_imp__", 6) == 0
2080 || strncmp(*mangled, "__imp_", 6) == 0))
2082 /* it's a symbol imported from a PE dynamic library. Check for both
2083 new style prefix _imp__ and legacy __imp_ used by older versions
2086 work->dllimported = 1;
2088 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2090 char *marker = strchr (cplus_markers, (*mangled)[8]);
2091 if (marker != NULL && *marker == (*mangled)[10])
2093 if ((*mangled)[9] == 'D')
2095 /* it's a GNU global destructor to be executed at program exit */
2097 work->destructor = 2;
2098 if (gnu_special (work, mangled, declp))
2101 else if ((*mangled)[9] == 'I')
2103 /* it's a GNU global constructor to be executed at program init */
2105 work->constructor = 2;
2106 if (gnu_special (work, mangled, declp))
2111 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2113 /* it's a ARM global destructor to be executed at program exit */
2115 work->destructor = 2;
2117 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2119 /* it's a ARM global constructor to be executed at program initial */
2121 work->constructor = 2;
2124 /* This block of code is a reduction in strength time optimization
2126 scan = mystrstr (*mangled, "__"); */
2132 scan = strchr (scan, '_');
2133 } while (scan != NULL && *++scan != '_');
2135 if (scan != NULL) --scan;
2140 /* We found a sequence of two or more '_', ensure that we start at
2141 the last pair in the sequence. */
2142 i = strspn (scan, "_");
2153 else if (work -> static_type)
2155 if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't'))
2160 else if ((scan == *mangled)
2161 && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q')
2162 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2164 /* The ARM says nothing about the mangling of local variables.
2165 But cfront mangles local variables by prepending __<nesting_level>
2166 to them. As an extension to ARM demangling we handle this case. */
2167 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2168 && isdigit ((unsigned char)scan[2]))
2170 *mangled = scan + 2;
2171 consume_count (mangled);
2172 string_append (declp, *mangled);
2173 *mangled += strlen (*mangled);
2178 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2179 names like __Q2_3foo3bar for nested type names. So don't accept
2180 this style of constructor for cfront demangling. A GNU
2181 style member-template constructor starts with 'H'. */
2182 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2183 work -> constructor += 1;
2184 *mangled = scan + 2;
2187 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2189 /* Cfront-style parameterized type. Handled later as a signature. */
2193 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2195 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2196 || (scan[2] == 'p' && scan[3] == 's')
2197 || (scan[2] == 'p' && scan[3] == 't')))
2199 /* EDG-style parameterized type. Handled later as a signature. */
2203 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2205 else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2])
2206 && (scan[2] != 't'))
2208 /* Mangled name starts with "__". Skip over any leading '_' characters,
2209 then find the next "__" that separates the prefix from the signature.
2211 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2212 || (arm_special (mangled, declp) == 0))
2214 while (*scan == '_')
2218 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2220 /* No separator (I.E. "__not_mangled"), or empty signature
2221 (I.E. "__not_mangled_either__") */
2227 /* Look for the LAST occurrence of __, allowing names to have
2228 the '__' sequence embedded in them.*/
2229 while ((tmp = mystrstr (scan+2, "__")) != NULL)
2231 if (*(scan + 2) == '\0')
2234 demangle_function_name (work, mangled, declp, scan);
2238 else if (*(scan + 2) != '\0')
2240 /* Mangled name does not start with "__" but does have one somewhere
2241 in there with non empty stuff after it. Looks like a global
2243 demangle_function_name (work, mangled, declp, scan);
2247 /* Doesn't look like a mangled name */
2251 if (!success && (work->constructor == 2 || work->destructor == 2))
2253 string_append (declp, *mangled);
2254 *mangled += strlen (*mangled);
2264 gnu_special -- special handling of gnu mangled strings
2269 gnu_special (struct work_stuff *work, const char **mangled,
2275 Process some special GNU style mangling forms that don't fit
2276 the normal pattern. For example:
2278 _$_3foo (destructor for class foo)
2279 _vt$foo (foo virtual table)
2280 _vt$foo$bar (foo::bar virtual table)
2281 __vt_foo (foo virtual table, new style with thunks)
2282 _3foo$varname (static data member)
2283 _Q22rs2tu$vw (static data member)
2284 __t6vector1Zii (constructor with template)
2285 __thunk_4__$_7ostream (virtual function thunk)
2289 gnu_special (work, mangled, declp)
2290 struct work_stuff *work;
2291 const char **mangled;
2298 if ((*mangled)[0] == '_'
2299 && strchr (cplus_markers, (*mangled)[1]) != NULL
2300 && (*mangled)[2] == '_')
2302 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2304 work -> destructor += 1;
2306 else if ((*mangled)[0] == '_'
2307 && (((*mangled)[1] == '_'
2308 && (*mangled)[2] == 'v'
2309 && (*mangled)[3] == 't'
2310 && (*mangled)[4] == '_')
2311 || ((*mangled)[1] == 'v'
2312 && (*mangled)[2] == 't'
2313 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2315 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2316 and create the decl. Note that we consume the entire mangled
2317 input string, which means that demangle_signature has no work
2319 if ((*mangled)[2] == 'v')
2320 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2322 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2323 while (**mangled != '\0')
2329 success = demangle_qualified (work, mangled, declp, 0, 1);
2332 success = demangle_template (work, mangled, declp, 0, 1,
2336 if (isdigit((unsigned char)*mangled[0]))
2338 n = consume_count(mangled);
2339 /* We may be seeing a too-large size, or else a
2340 ".<digits>" indicating a static local symbol. In
2341 any case, declare victory and move on; *don't* try
2342 to use n to allocate. */
2343 if (n > (int) strlen (*mangled))
2351 n = strcspn (*mangled, cplus_markers);
2353 string_appendn (declp, *mangled, n);
2357 p = strpbrk (*mangled, cplus_markers);
2358 if (success && ((p == NULL) || (p == *mangled)))
2362 string_append (declp, SCOPE_STRING (work));
2373 string_append (declp, " virtual table");
2375 else if ((*mangled)[0] == '_'
2376 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2377 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2379 /* static data member, "_3foo$varname" for example */
2385 success = demangle_qualified (work, mangled, declp, 0, 1);
2388 success = demangle_template (work, mangled, declp, 0, 1, 1);
2391 n = consume_count (mangled);
2392 string_appendn (declp, *mangled, n);
2395 if (success && (p == *mangled))
2397 /* Consumed everything up to the cplus_marker, append the
2400 string_append (declp, SCOPE_STRING (work));
2401 n = strlen (*mangled);
2402 string_appendn (declp, *mangled, n);
2410 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2412 int delta = ((*mangled) += 8, consume_count (mangled));
2413 char *method = internal_cplus_demangle (work, ++*mangled);
2417 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2418 string_append (declp, buf);
2419 string_append (declp, method);
2421 n = strlen (*mangled);
2429 else if (strncmp (*mangled, "__t", 3) == 0
2430 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2432 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2438 success = demangle_qualified (work, mangled, declp, 0, 1);
2441 success = demangle_template (work, mangled, declp, 0, 1, 1);
2444 success = demangle_fund_type (work, mangled, declp);
2447 if (success && **mangled != '\0')
2450 string_append (declp, p);
2460 recursively_demangle(work, mangled, result, namelength)
2461 struct work_stuff *work;
2462 const char **mangled;
2466 char * recurse = (char *)NULL;
2467 char * recurse_dem = (char *)NULL;
2469 recurse = (char *) xmalloc (namelength + 1);
2470 memcpy (recurse, *mangled, namelength);
2471 recurse[namelength] = '\000';
2473 recurse_dem = cplus_demangle (recurse, work->options);
2477 string_append (result, recurse_dem);
2482 string_appendn (result, *mangled, namelength);
2485 *mangled += namelength;
2492 arm_special -- special handling of ARM/lucid mangled strings
2497 arm_special (const char **mangled,
2503 Process some special ARM style mangling forms that don't fit
2504 the normal pattern. For example:
2506 __vtbl__3foo (foo virtual table)
2507 __vtbl__3foo__3bar (bar::foo virtual table)
2512 arm_special (mangled, declp)
2513 const char **mangled;
2520 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
2522 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
2523 and create the decl. Note that we consume the entire mangled
2524 input string, which means that demangle_signature has no work
2526 scan = *mangled + ARM_VTABLE_STRLEN;
2527 while (*scan != '\0') /* first check it can be demangled */
2529 n = consume_count (&scan);
2532 return (0); /* no good */
2535 if (scan[0] == '_' && scan[1] == '_')
2540 (*mangled) += ARM_VTABLE_STRLEN;
2541 while (**mangled != '\0')
2543 n = consume_count (mangled);
2544 string_prependn (declp, *mangled, n);
2546 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
2548 string_prepend (declp, "::");
2552 string_append (declp, " virtual table");
2565 demangle_qualified -- demangle 'Q' qualified name strings
2570 demangle_qualified (struct work_stuff *, const char *mangled,
2571 string *result, int isfuncname, int append);
2575 Demangle a qualified name, such as "Q25Outer5Inner" which is
2576 the mangled form of "Outer::Inner". The demangled output is
2577 prepended or appended to the result string according to the
2578 state of the append flag.
2580 If isfuncname is nonzero, then the qualified name we are building
2581 is going to be used as a member function name, so if it is a
2582 constructor or destructor function, append an appropriate
2583 constructor or destructor name. I.E. for the above example,
2584 the result for use as a constructor is "Outer::Inner::Inner"
2585 and the result for use as a destructor is "Outer::Inner::~Inner".
2589 Numeric conversion is ASCII dependent (FIXME).
2594 demangle_qualified (work, mangled, result, isfuncname, append)
2595 struct work_stuff *work;
2596 const char **mangled;
2607 int bindex = register_Btype (work);
2609 /* We only make use of ISFUNCNAME if the entity is a constructor or
2611 isfuncname = (isfuncname
2612 && ((work->constructor & 1) || (work->destructor & 1)));
2614 string_init (&temp);
2615 string_init (&last_name);
2617 if ((*mangled)[0] == 'K')
2619 /* Squangling qualified name reuse */
2622 idx = consume_count_with_underscores (mangled);
2623 if (idx == -1 || idx >= work -> numk)
2626 string_append (&temp, work -> ktypevec[idx]);
2629 switch ((*mangled)[1])
2632 /* GNU mangled name with more than 9 classes. The count is preceded
2633 by an underscore (to distinguish it from the <= 9 case) and followed
2634 by an underscore. */
2636 qualifiers = atoi (p);
2637 if (!isdigit ((unsigned char)*p) || *p == '0')
2640 /* Skip the digits. */
2641 while (isdigit ((unsigned char)*p))
2659 /* The count is in a single digit. */
2660 num[0] = (*mangled)[1];
2662 qualifiers = atoi (num);
2664 /* If there is an underscore after the digit, skip it. This is
2665 said to be for ARM-qualified names, but the ARM makes no
2666 mention of such an underscore. Perhaps cfront uses one. */
2667 if ((*mangled)[2] == '_')
2682 /* Pick off the names and collect them in the temp buffer in the order
2683 in which they are found, separated by '::'. */
2685 while (qualifiers-- > 0)
2688 string_clear (&last_name);
2690 if (*mangled[0] == '_')
2693 if (*mangled[0] == 't')
2695 /* Here we always append to TEMP since we will want to use
2696 the template name without the template parameters as a
2697 constructor or destructor name. The appropriate
2698 (parameter-less) value is returned by demangle_template
2699 in LAST_NAME. We do not remember the template type here,
2700 in order to match the G++ mangling algorithm. */
2701 success = demangle_template(work, mangled, &temp,
2706 else if (*mangled[0] == 'K')
2710 idx = consume_count_with_underscores (mangled);
2711 if (idx == -1 || idx >= work->numk)
2714 string_append (&temp, work->ktypevec[idx]);
2717 if (!success) break;
2724 /* Now recursively demangle the qualifier
2725 * This is necessary to deal with templates in
2726 * mangling styles like EDG */
2727 namelength = consume_count (mangled);
2728 recursively_demangle(work, mangled, &temp, namelength);
2732 success = do_type (work, mangled, &last_name);
2735 string_appends (&temp, &last_name);
2740 remember_Ktype (work, temp.b, LEN_STRING (&temp));
2743 string_append (&temp, SCOPE_STRING (work));
2746 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
2748 /* If we are using the result as a function name, we need to append
2749 the appropriate '::' separated constructor or destructor name.
2750 We do this here because this is the most convenient place, where
2751 we already have a pointer to the name and the length of the name. */
2755 string_append (&temp, SCOPE_STRING (work));
2756 if (work -> destructor & 1)
2757 string_append (&temp, "~");
2758 string_appends (&temp, &last_name);
2761 /* Now either prepend the temp buffer to the result, or append it,
2762 depending upon the state of the append flag. */
2765 string_appends (result, &temp);
2768 if (!STRING_EMPTY (result))
2769 string_append (&temp, SCOPE_STRING (work));
2770 string_prepends (result, &temp);
2773 string_delete (&last_name);
2774 string_delete (&temp);
2782 get_count -- convert an ascii count to integer, consuming tokens
2787 get_count (const char **type, int *count)
2791 Return 0 if no conversion is performed, 1 if a string is converted.
2795 get_count (type, count)
2802 if (!isdigit ((unsigned char)**type))
2808 *count = **type - '0';
2810 if (isdigit ((unsigned char)**type))
2820 while (isdigit ((unsigned char)*p));
2831 /* RESULT will be initialised here; it will be freed on failure. The
2832 value returned is really a type_kind_t. */
2835 do_type (work, mangled, result)
2836 struct work_stuff *work;
2837 const char **mangled;
2844 const char *remembered_type;
2847 type_kind_t tk = tk_none;
2849 string_init (&btype);
2850 string_init (&decl);
2851 string_init (result);
2855 while (success && !done)
2861 /* A pointer type */
2865 string_prepend (&decl, "*");
2870 /* A reference type */
2873 string_prepend (&decl, "&");
2882 if (!STRING_EMPTY (&decl)
2883 && (decl.b[0] == '*' || decl.b[0] == '&'))
2885 string_prepend (&decl, "(");
2886 string_append (&decl, ")");
2888 string_append (&decl, "[");
2889 if (**mangled != '_')
2890 success = demangle_template_value_parm (work, mangled, &decl,
2892 if (**mangled == '_')
2894 string_append (&decl, "]");
2898 /* A back reference to a previously seen type */
2901 if (!get_count (mangled, &n) || n >= work -> ntypes)
2907 remembered_type = work -> typevec[n];
2908 mangled = &remembered_type;
2915 if (!STRING_EMPTY (&decl)
2916 && (decl.b[0] == '*' || decl.b[0] == '&'))
2918 string_prepend (&decl, "(");
2919 string_append (&decl, ")");
2921 /* After picking off the function args, we expect to either find the
2922 function return type (preceded by an '_') or the end of the
2924 if (!demangle_nested_args (work, mangled, &decl)
2925 || (**mangled != '_' && **mangled != '\0'))
2930 if (success && (**mangled == '_'))
2937 type_quals = TYPE_UNQUALIFIED;
2939 member = **mangled == 'M';
2941 if (!isdigit ((unsigned char)**mangled) && **mangled != 't')
2947 string_append (&decl, ")");
2948 string_prepend (&decl, SCOPE_STRING (work));
2949 if (isdigit ((unsigned char)**mangled))
2951 n = consume_count (mangled);
2952 if ((int) strlen (*mangled) < n)
2957 string_prependn (&decl, *mangled, n);
2963 string_init (&temp);
2964 success = demangle_template (work, mangled, &temp,
2968 string_prependn (&decl, temp.b, temp.p - temp.b);
2969 string_clear (&temp);
2974 string_prepend (&decl, "(");
2982 type_quals |= code_for_qualifier (**mangled);
2990 if (*(*mangled)++ != 'F')
2996 if ((member && !demangle_nested_args (work, mangled, &decl))
2997 || **mangled != '_')
3003 if (! PRINT_ANSI_QUALIFIERS)
3007 if (type_quals != TYPE_UNQUALIFIED)
3009 APPEND_BLANK (&decl);
3010 string_append (&decl, qualifier_string (type_quals));
3021 if (PRINT_ANSI_QUALIFIERS)
3023 if (!STRING_EMPTY (&decl))
3024 string_prepend (&decl, " ");
3026 string_prepend (&decl, demangle_qualifier (**mangled));
3041 if (success) switch (**mangled)
3043 /* A qualified name, such as "Outer::Inner". */
3047 success = demangle_qualified (work, mangled, result, 0, 1);
3051 /* A back reference to a previously seen squangled type */
3054 if (!get_count (mangled, &n) || n >= work -> numb)
3057 string_append (result, work->btypevec[n]);
3062 /* A template parm. We substitute the corresponding argument. */
3067 idx = consume_count_with_underscores (mangled);
3070 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3071 || consume_count_with_underscores (mangled) == -1)
3077 if (work->tmpl_argvec)
3078 string_append (result, work->tmpl_argvec[idx]);
3082 sprintf(buf, "T%d", idx);
3083 string_append (result, buf);
3091 success = demangle_fund_type (work, mangled, result);
3093 tk = (type_kind_t) success;
3099 if (!STRING_EMPTY (&decl))
3101 string_append (result, " ");
3102 string_appends (result, &decl);
3106 string_delete (result);
3107 string_delete (&decl);
3110 /* Assume an integral type, if we're not sure. */
3111 return (int) ((tk == tk_none) ? tk_integral : tk);
3116 /* Given a pointer to a type string that represents a fundamental type
3117 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3118 string in which the demangled output is being built in RESULT, and
3119 the WORK structure, decode the types and add them to the result.
3124 "Sl" => "signed long"
3125 "CUs" => "const unsigned short"
3127 The value returned is really a type_kind_t. */
3130 demangle_fund_type (work, mangled, result)
3131 struct work_stuff *work;
3132 const char **mangled;
3140 type_kind_t tk = tk_integral;
3142 string_init (&btype);
3144 /* First pick off any type qualifiers. There can be more than one. */
3153 if (PRINT_ANSI_QUALIFIERS)
3155 if (!STRING_EMPTY (result))
3156 string_prepend (result, " ");
3157 string_prepend (result, demangle_qualifier (**mangled));
3163 APPEND_BLANK (result);
3164 string_append (result, "unsigned");
3166 case 'S': /* signed char only */
3168 APPEND_BLANK (result);
3169 string_append (result, "signed");
3173 APPEND_BLANK (result);
3174 string_append (result, "__complex");
3182 /* Now pick off the fundamental type. There can be only one. */
3191 APPEND_BLANK (result);
3192 string_append (result, "void");
3196 APPEND_BLANK (result);
3197 string_append (result, "long long");
3201 APPEND_BLANK (result);
3202 string_append (result, "long");
3206 APPEND_BLANK (result);
3207 string_append (result, "int");
3211 APPEND_BLANK (result);
3212 string_append (result, "short");
3216 APPEND_BLANK (result);
3217 string_append (result, "bool");
3222 APPEND_BLANK (result);
3223 string_append (result, "char");
3228 APPEND_BLANK (result);
3229 string_append (result, "wchar_t");
3234 APPEND_BLANK (result);
3235 string_append (result, "long double");
3240 APPEND_BLANK (result);
3241 string_append (result, "double");
3246 APPEND_BLANK (result);
3247 string_append (result, "float");
3252 if (!isdigit ((unsigned char)**mangled))
3259 if (**mangled == '_')
3263 for (i = 0; **mangled != '_'; ++(*mangled), ++i)
3270 strncpy (buf, *mangled, 2);
3273 sscanf (buf, "%x", &dec);
3274 sprintf (buf, "int%i_t", dec);
3275 APPEND_BLANK (result);
3276 string_append (result, buf);
3280 /* An explicit type, such as "6mytype" or "7integer" */
3292 int bindex = register_Btype (work);
3294 string_init (&btype);
3295 if (demangle_class_name (work, mangled, &btype)) {
3296 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3297 APPEND_BLANK (result);
3298 string_appends (result, &btype);
3302 string_delete (&btype);
3307 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3308 string_appends (result, &btype);
3316 return success ? ((int) tk) : 0;
3320 /* Handle a template's value parameter for HP aCC (extension from ARM)
3321 **mangled points to 'S' or 'U' */
3324 do_hpacc_template_const_value (work, mangled, result)
3325 struct work_stuff *work;
3326 const char **mangled;
3331 if (**mangled != 'U' && **mangled != 'S')
3334 unsigned_const = (**mangled == 'U');
3341 string_append (result, "-");
3347 /* special case for -2^31 */
3348 string_append (result, "-2147483648");
3355 /* We have to be looking at an integer now */
3356 if (!(isdigit ((unsigned char)**mangled)))
3359 /* We only deal with integral values for template
3360 parameters -- so it's OK to look only for digits */
3361 while (isdigit ((unsigned char)**mangled))
3363 char_str[0] = **mangled;
3364 string_append (result, char_str);
3369 string_append (result, "U");
3371 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3372 with L or LL suffixes. pai/1997-09-03 */
3374 return 1; /* success */
3377 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3378 **mangled is pointing to the 'A' */
3381 do_hpacc_template_literal (work, mangled, result)
3382 struct work_stuff *work;
3383 const char **mangled;
3386 int literal_len = 0;
3390 if (**mangled != 'A')
3395 literal_len = consume_count (mangled);
3400 /* Literal parameters are names of arrays, functions, etc. and the
3401 canonical representation uses the address operator */
3402 string_append (result, "&");
3404 /* Now recursively demangle the literal name */
3405 recurse = (char *) xmalloc (literal_len + 1);
3406 memcpy (recurse, *mangled, literal_len);
3407 recurse[literal_len] = '\000';
3409 recurse_dem = cplus_demangle (recurse, work->options);
3413 string_append (result, recurse_dem);
3418 string_appendn (result, *mangled, literal_len);
3420 (*mangled) += literal_len;
3427 snarf_numeric_literal (args, arg)
3434 string_append (arg, char_str);
3437 else if (**args == '+')
3440 if (!isdigit ((unsigned char)**args))
3443 while (isdigit ((unsigned char)**args))
3445 char_str[0] = **args;
3446 string_append (arg, char_str);
3453 /* Demangle the next argument, given by MANGLED into RESULT, which
3454 *should be an uninitialized* string. It will be initialized here,
3455 and free'd should anything go wrong. */
3458 do_arg (work, mangled, result)
3459 struct work_stuff *work;
3460 const char **mangled;
3463 /* Remember where we started so that we can record the type, for
3464 non-squangling type remembering. */
3465 const char *start = *mangled;
3467 string_init (result);
3469 if (work->nrepeats > 0)
3473 if (work->previous_argument == 0)
3476 /* We want to reissue the previous type in this argument list. */
3477 string_appends (result, work->previous_argument);
3481 if (**mangled == 'n')
3483 /* A squangling-style repeat. */
3485 work->nrepeats = consume_count(mangled);
3487 if (work->nrepeats == 0)
3488 /* This was not a repeat count after all. */
3491 if (work->nrepeats > 9)
3493 if (**mangled != '_')
3494 /* The repeat count should be followed by an '_' in this
3501 /* Now, the repeat is all set up. */
3502 return do_arg (work, mangled, result);
3505 /* Save the result in WORK->previous_argument so that we can find it
3506 if it's repeated. Note that saving START is not good enough: we
3507 do not want to add additional types to the back-referenceable
3508 type vector when processing a repeated type. */
3509 if (work->previous_argument)
3510 string_clear (work->previous_argument);
3513 work->previous_argument = (string*) xmalloc (sizeof (string));
3514 string_init (work->previous_argument);
3517 if (!do_type (work, mangled, work->previous_argument))
3520 string_appends (result, work->previous_argument);
3522 remember_type (work, start, *mangled - start);
3527 remember_type (work, start, len)
3528 struct work_stuff *work;
3534 if (work->forgetting_types)
3537 if (work -> ntypes >= work -> typevec_size)
3539 if (work -> typevec_size == 0)
3541 work -> typevec_size = 3;
3543 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
3547 work -> typevec_size *= 2;
3549 = (char **) xrealloc ((char *)work -> typevec,
3550 sizeof (char *) * work -> typevec_size);
3553 tem = xmalloc (len + 1);
3554 memcpy (tem, start, len);
3556 work -> typevec[work -> ntypes++] = tem;
3560 /* Remember a K type class qualifier. */
3562 remember_Ktype (work, start, len)
3563 struct work_stuff *work;
3569 if (work -> numk >= work -> ksize)
3571 if (work -> ksize == 0)
3575 = (char **) xmalloc (sizeof (char *) * work -> ksize);
3581 = (char **) xrealloc ((char *)work -> ktypevec,
3582 sizeof (char *) * work -> ksize);
3585 tem = xmalloc (len + 1);
3586 memcpy (tem, start, len);
3588 work -> ktypevec[work -> numk++] = tem;
3591 /* Register a B code, and get an index for it. B codes are registered
3592 as they are seen, rather than as they are completed, so map<temp<char> >
3593 registers map<temp<char> > as B0, and temp<char> as B1 */
3596 register_Btype (work)
3597 struct work_stuff *work;
3601 if (work -> numb >= work -> bsize)
3603 if (work -> bsize == 0)
3607 = (char **) xmalloc (sizeof (char *) * work -> bsize);
3613 = (char **) xrealloc ((char *)work -> btypevec,
3614 sizeof (char *) * work -> bsize);
3617 ret = work -> numb++;
3618 work -> btypevec[ret] = NULL;
3622 /* Store a value into a previously registered B code type. */
3625 remember_Btype (work, start, len, index)
3626 struct work_stuff *work;
3632 tem = xmalloc (len + 1);
3633 memcpy (tem, start, len);
3635 work -> btypevec[index] = tem;
3638 /* Lose all the info related to B and K type codes. */
3640 forget_B_and_K_types (work)
3641 struct work_stuff *work;
3645 while (work -> numk > 0)
3647 i = --(work -> numk);
3648 if (work -> ktypevec[i] != NULL)
3650 free (work -> ktypevec[i]);
3651 work -> ktypevec[i] = NULL;
3655 while (work -> numb > 0)
3657 i = --(work -> numb);
3658 if (work -> btypevec[i] != NULL)
3660 free (work -> btypevec[i]);
3661 work -> btypevec[i] = NULL;
3665 /* Forget the remembered types, but not the type vector itself. */
3669 struct work_stuff *work;
3673 while (work -> ntypes > 0)
3675 i = --(work -> ntypes);
3676 if (work -> typevec[i] != NULL)
3678 free (work -> typevec[i]);
3679 work -> typevec[i] = NULL;
3684 /* Process the argument list part of the signature, after any class spec
3685 has been consumed, as well as the first 'F' character (if any). For
3688 "__als__3fooRT0" => process "RT0"
3689 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
3691 DECLP must be already initialised, usually non-empty. It won't be freed
3694 Note that g++ differs significantly from ARM and lucid style mangling
3695 with regards to references to previously seen types. For example, given
3696 the source fragment:
3700 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
3703 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3704 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
3706 g++ produces the names:
3711 while lcc (and presumably other ARM style compilers as well) produces:
3713 foo__FiR3fooT1T2T1T2
3714 __ct__3fooFiR3fooT1T2T1T2
3716 Note that g++ bases its type numbers starting at zero and counts all
3717 previously seen types, while lucid/ARM bases its type numbers starting
3718 at one and only considers types after it has seen the 'F' character
3719 indicating the start of the function args. For lucid/ARM style, we
3720 account for this difference by discarding any previously seen types when
3721 we see the 'F' character, and subtracting one from the type number
3727 demangle_args (work, mangled, declp)
3728 struct work_stuff *work;
3729 const char **mangled;
3739 if (PRINT_ARG_TYPES)
3741 string_append (declp, "(");
3742 if (**mangled == '\0')
3744 string_append (declp, "void");
3748 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
3749 || work->nrepeats > 0)
3751 if ((**mangled == 'N') || (**mangled == 'T'))
3753 temptype = *(*mangled)++;
3755 if (temptype == 'N')
3757 if (!get_count (mangled, &r))
3766 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
3768 /* If we have 10 or more types we might have more than a 1 digit
3769 index so we'll have to consume the whole count here. This
3770 will lose if the next thing is a type name preceded by a
3771 count but it's impossible to demangle that case properly
3772 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
3773 Pc, ...)" or "(..., type12, char *, ...)" */
3774 if ((t = consume_count(mangled)) == 0)
3781 if (!get_count (mangled, &t))
3786 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3790 /* Validate the type index. Protect against illegal indices from
3791 malformed type strings. */
3792 if ((t < 0) || (t >= work -> ntypes))
3796 while (work->nrepeats > 0 || --r >= 0)
3798 tem = work -> typevec[t];
3799 if (need_comma && PRINT_ARG_TYPES)
3801 string_append (declp, ", ");
3803 if (!do_arg (work, &tem, &arg))
3807 if (PRINT_ARG_TYPES)
3809 string_appends (declp, &arg);
3811 string_delete (&arg);
3817 if (need_comma && PRINT_ARG_TYPES)
3818 string_append (declp, ", ");
3819 if (!do_arg (work, mangled, &arg))
3821 if (PRINT_ARG_TYPES)
3822 string_appends (declp, &arg);
3823 string_delete (&arg);
3828 if (**mangled == 'e')
3831 if (PRINT_ARG_TYPES)
3835 string_append (declp, ",");
3837 string_append (declp, "...");
3841 if (PRINT_ARG_TYPES)
3843 string_append (declp, ")");
3848 /* Like demangle_args, but for demangling the argument lists of function
3849 and method pointers or references, not top-level declarations. */
3852 demangle_nested_args (work, mangled, declp)
3853 struct work_stuff *work;
3854 const char **mangled;
3857 string* saved_previous_argument;
3861 /* The G++ name-mangling algorithm does not remember types on nested
3862 argument lists, unless -fsquangling is used, and in that case the
3863 type vector updated by remember_type is not used. So, we turn
3864 off remembering of types here. */
3865 ++work->forgetting_types;
3867 /* For the repeat codes used with -fsquangling, we must keep track of
3868 the last argument. */
3869 saved_previous_argument = work->previous_argument;
3870 saved_nrepeats = work->nrepeats;
3871 work->previous_argument = 0;
3874 /* Actually demangle the arguments. */
3875 result = demangle_args (work, mangled, declp);
3877 /* Restore the previous_argument field. */
3878 if (work->previous_argument)
3879 string_delete (work->previous_argument);
3880 work->previous_argument = saved_previous_argument;
3881 work->nrepeats = saved_nrepeats;
3887 demangle_function_name (work, mangled, declp, scan)
3888 struct work_stuff *work;
3889 const char **mangled;
3897 string_appendn (declp, (*mangled), scan - (*mangled));
3898 string_need (declp, 1);
3899 *(declp -> p) = '\0';
3901 /* Consume the function name, including the "__" separating the name
3902 from the signature. We are guaranteed that SCAN points to the
3905 (*mangled) = scan + 2;
3906 /* We may be looking at an instantiation of a template function:
3907 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
3908 following _F marks the start of the function arguments. Handle
3909 the template arguments first. */
3911 if (HP_DEMANGLING && (**mangled == 'X'))
3913 demangle_arm_hp_template (work, mangled, 0, declp);
3914 /* This leaves MANGLED pointing to the 'F' marking func args */
3917 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
3920 /* See if we have an ARM style constructor or destructor operator.
3921 If so, then just record it, clear the decl, and return.
3922 We can't build the actual constructor/destructor decl until later,
3923 when we recover the class name from the signature. */
3925 if (strcmp (declp -> b, "__ct") == 0)
3927 work -> constructor += 1;
3928 string_clear (declp);
3931 else if (strcmp (declp -> b, "__dt") == 0)
3933 work -> destructor += 1;
3934 string_clear (declp);
3939 if (declp->p - declp->b >= 3
3940 && declp->b[0] == 'o'
3941 && declp->b[1] == 'p'
3942 && strchr (cplus_markers, declp->b[2]) != NULL)
3944 /* see if it's an assignment expression */
3945 if (declp->p - declp->b >= 10 /* op$assign_ */
3946 && memcmp (declp->b + 3, "assign_", 7) == 0)
3948 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3950 int len = declp->p - declp->b - 10;
3951 if ((int) strlen (optable[i].in) == len
3952 && memcmp (optable[i].in, declp->b + 10, len) == 0)
3954 string_clear (declp);
3955 string_append (declp, "operator");
3956 string_append (declp, optable[i].out);
3957 string_append (declp, "=");
3964 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
3966 int len = declp->p - declp->b - 3;
3967 if ((int) strlen (optable[i].in) == len
3968 && memcmp (optable[i].in, declp->b + 3, len) == 0)
3970 string_clear (declp);
3971 string_append (declp, "operator");
3972 string_append (declp, optable[i].out);
3978 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
3979 && strchr (cplus_markers, declp->b[4]) != NULL)
3981 /* type conversion operator */
3983 if (do_type (work, &tem, &type))
3985 string_clear (declp);
3986 string_append (declp, "operator ");
3987 string_appends (declp, &type);
3988 string_delete (&type);
3991 else if (declp->b[0] == '_' && declp->b[1] == '_'
3992 && declp->b[2] == 'o' && declp->b[3] == 'p')
3995 /* type conversion operator. */
3997 if (do_type (work, &tem, &type))
3999 string_clear (declp);
4000 string_append (declp, "operator ");
4001 string_appends (declp, &type);
4002 string_delete (&type);
4005 else if (declp->b[0] == '_' && declp->b[1] == '_'
4006 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
4007 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
4009 if (declp->b[4] == '\0')
4012 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4014 if (strlen (optable[i].in) == 2
4015 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4017 string_clear (declp);
4018 string_append (declp, "operator");
4019 string_append (declp, optable[i].out);
4026 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4029 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
4031 if (strlen (optable[i].in) == 3
4032 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4034 string_clear (declp);
4035 string_append (declp, "operator");
4036 string_append (declp, optable[i].out);
4045 /* a mini string-handling package */
4060 s->p = s->b = xmalloc (n);
4063 else if (s->e - s->p < n)
4068 s->b = xrealloc (s->b, n);
4081 s->b = s->e = s->p = NULL;
4089 s->b = s->p = s->e = NULL;
4105 return (s->b == s->p);
4111 string_append (p, s)
4116 if (s == NULL || *s == '\0')
4120 memcpy (p->p, s, n);
4125 string_appends (p, s)
4134 memcpy (p->p, s->b, n);
4140 string_appendn (p, s, n)
4148 memcpy (p->p, s, n);
4154 string_prepend (p, s)
4158 if (s != NULL && *s != '\0')
4160 string_prependn (p, s, strlen (s));
4165 string_prepends (p, s)
4170 string_prependn (p, s->b, s->p - s->b);
4175 string_prependn (p, s, n)
4185 for (q = p->p - 1; q >= p->b; q--)
4189 memcpy (p->b, s, n);
4194 /* To generate a standalone demangler program for testing purposes,
4195 just compile and link this file with -DMAIN and libiberty.a. When
4196 run, it demangles each command line arg, or each stdin string, and
4197 prints the result on stdout. */
4203 static char *program_name;
4204 static char *program_version = VERSION;
4205 static int flags = DMGL_PARAMS | DMGL_ANSI;
4207 static void demangle_it PARAMS ((char *));
4208 static void usage PARAMS ((FILE *, int));
4209 static void fatal PARAMS ((char *));
4212 demangle_it (mangled_name)
4217 result = cplus_demangle (mangled_name, flags);
4220 printf ("%s\n", mangled_name);
4224 printf ("%s\n", result);
4230 usage (stream, status)
4235 Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\
4236 [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\
4237 [--help] [--version] [arg...]\n",
4242 #define MBUF_SIZE 32767
4243 char mbuffer[MBUF_SIZE];
4245 /* Defined in the automatically-generated underscore.c. */
4246 extern int prepends_underscore;
4248 int strip_underscore = 0;
4250 static struct option long_options[] = {
4251 {"strip-underscores", no_argument, 0, '_'},
4252 {"format", required_argument, 0, 's'},
4253 {"help", no_argument, 0, 'h'},
4254 {"no-strip-underscores", no_argument, 0, 'n'},
4255 {"version", no_argument, 0, 'v'},
4256 {0, no_argument, 0, 0}
4259 /* More 'friendly' abort that prints the line and file.
4260 config.h can #define abort fancy_abort if you like that sort of thing. */
4265 fatal ("Internal gcc abort.");
4276 program_name = argv[0];
4278 strip_underscore = prepends_underscore;
4280 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
4290 strip_underscore = 0;
4293 printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
4296 strip_underscore = 1;
4299 if (strcmp (optarg, "gnu") == 0)
4301 current_demangling_style = gnu_demangling;
4303 else if (strcmp (optarg, "lucid") == 0)
4305 current_demangling_style = lucid_demangling;
4307 else if (strcmp (optarg, "arm") == 0)
4309 current_demangling_style = arm_demangling;
4311 else if (strcmp (optarg, "hp") == 0)
4313 current_demangling_style = hp_demangling;
4315 else if (strcmp (optarg, "edg") == 0)
4317 current_demangling_style = edg_demangling;
4321 fprintf (stderr, "%s: unknown demangling style `%s'\n",
4322 program_name, optarg);
4331 for ( ; optind < argc; optind++)
4333 demangle_it (argv[optind]);
4342 /* Try to read a label. */
4343 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.' ||
4344 c == '<' || c == '>' || c == '#' || c == ',' || c == '*' || c == '&' ||
4345 c == '[' || c == ']' || c == ':' || c == '(' || c == ')'))
4346 /* the ones in the 2nd & 3rd lines were added to handle
4347 HP aCC template specialization manglings */
4349 if (i >= MBUF_SIZE-1)
4358 if (mbuffer[0] == '.')
4360 if (strip_underscore && mbuffer[skip_first] == '_')
4368 result = cplus_demangle (mbuffer + skip_first, flags);
4371 if (mbuffer[0] == '.')
4373 fputs (result, stdout);
4377 fputs (mbuffer, stdout);
4394 fprintf (stderr, "%s: %s\n", program_name, str);
4402 register PTR value = (PTR) malloc (size);
4404 fatal ("virtual memory exhausted");
4409 xrealloc (ptr, size)
4413 register PTR value = (PTR) realloc (ptr, size);
4415 fatal ("virtual memory exhausted");