1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Written by James Clark (jjc@jclark.uucp)
5 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
8 This file is part of the libiberty library.
9 Libiberty is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
14 In addition to the permissions in the GNU Library General Public
15 License, the Free Software Foundation gives you unlimited permission
16 to link the compiled version of this file into combinations with other
17 programs, and to distribute those combinations without any restriction
18 coming from the use of this file. (The Library Public License
19 restrictions do apply in other respects; for example, they cover
20 modification of the file, and distribution when not linked into a
23 Libiberty is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 Library General Public License for more details.
28 You should have received a copy of the GNU Library General Public
29 License along with libiberty; see the file COPYING.LIB. If
30 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
31 Boston, MA 02110-1301, USA. */
33 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
35 This file imports xmalloc and xrealloc, which are like malloc and
36 realloc except that they generate a fatal error if there is no
39 /* This file lives in both GCC and libiberty. When making changes, please
40 try not to break either. */
42 #if 0 /* in valgrind */
46 #endif /* ! in valgrind */
48 #if 0 /* in valgrind */
49 #include "safe-ctype.h"
50 #endif /* ! in valgrind */
52 #if 0 /* in valgrind */
53 #include <sys/types.h>
56 #endif /* ! in valgrind */
58 #if 0 /* in valgrind */
65 #endif /* ! in valgrind */
67 #if 0 /* in valgrind */
69 #undef CURRENT_DEMANGLING_STYLE
70 #define CURRENT_DEMANGLING_STYLE work->options
71 #endif /* ! in valgrind */
73 #if 0 /* in valgrind */
74 #include "libiberty.h"
75 #endif /* ! in valgrind */
77 #include "vg_libciface.h"
81 #include "safe-ctype.h"
83 static char *ada_demangle (const char *, int);
85 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
87 /* A value at least one greater than the maximum number of characters
88 that will be output when using the `%d' format with `printf'. */
89 #define INTBUF_SIZE 32
91 extern void fancy_abort (void) ATTRIBUTE_NORETURN;
93 /* In order to allow a single demangler executable to demangle strings
94 using various common values of CPLUS_MARKER, as well as any specific
95 one set at compile time, we maintain a string containing all the
96 commonly used ones, and check to see if the marker we are looking for
97 is in that string. CPLUS_MARKER is usually '$' on systems where the
98 assembler can deal with that. Where the assembler can't, it's usually
99 '.' (but on many systems '.' is used for other things). We put the
100 current defined CPLUS_MARKER first (which defaults to '$'), followed
101 by the next most common value, followed by an explicit '$' in case
102 the value of CPLUS_MARKER is not '$'.
104 We could avoid this if we could just get g++ to tell us what the actual
105 cplus marker character is as part of the debug information, perhaps by
106 ensuring that it is the character that terminates the gcc<n>_compiled
107 marker symbol (FIXME). */
109 #if !defined (CPLUS_MARKER)
110 #define CPLUS_MARKER '$'
113 enum demangling_styles current_demangling_style = auto_demangling;
115 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
117 static char char_str[2] = { '\000', '\000' };
120 set_cplus_marker_for_demangling (int ch)
122 cplus_markers[0] = ch;
125 typedef struct string /* Beware: these aren't required to be */
126 { /* '\0' terminated. */
127 char *b; /* pointer to start of string */
128 char *p; /* pointer after last character */
129 char *e; /* pointer after end of allocated space */
132 /* Stuff that is shared between sub-routines.
133 Using a shared structure allows cplus_demangle to be reentrant. */
149 int static_type; /* A static member function */
150 int temp_start; /* index in demangled to start of template args */
151 int type_quals; /* The type qualifiers. */
152 int dllimported; /* Symbol imported from a PE DLL */
153 char **tmpl_argvec; /* Template function arguments. */
154 int ntmpl_args; /* The number of template function arguments. */
155 int forgetting_types; /* Nonzero if we are not remembering the types
157 string* previous_argument; /* The last function argument demangled. */
158 int nrepeats; /* The number of times to repeat the previous
162 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
163 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
165 static const struct optable
167 const char *const in;
168 const char *const out;
171 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
172 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
173 {"new", " new", 0}, /* old (1.91, and 1.x) */
174 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
175 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
176 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
177 {"as", "=", DMGL_ANSI}, /* ansi */
178 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
179 {"eq", "==", DMGL_ANSI}, /* old, ansi */
180 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
181 {"gt", ">", DMGL_ANSI}, /* old, ansi */
182 {"le", "<=", DMGL_ANSI}, /* old, ansi */
183 {"lt", "<", DMGL_ANSI}, /* old, ansi */
184 {"plus", "+", 0}, /* old */
185 {"pl", "+", DMGL_ANSI}, /* ansi */
186 {"apl", "+=", DMGL_ANSI}, /* ansi */
187 {"minus", "-", 0}, /* old */
188 {"mi", "-", DMGL_ANSI}, /* ansi */
189 {"ami", "-=", DMGL_ANSI}, /* ansi */
190 {"mult", "*", 0}, /* old */
191 {"ml", "*", DMGL_ANSI}, /* ansi */
192 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
193 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
194 {"convert", "+", 0}, /* old (unary +) */
195 {"negate", "-", 0}, /* old (unary -) */
196 {"trunc_mod", "%", 0}, /* old */
197 {"md", "%", DMGL_ANSI}, /* ansi */
198 {"amd", "%=", DMGL_ANSI}, /* ansi */
199 {"trunc_div", "/", 0}, /* old */
200 {"dv", "/", DMGL_ANSI}, /* ansi */
201 {"adv", "/=", DMGL_ANSI}, /* ansi */
202 {"truth_andif", "&&", 0}, /* old */
203 {"aa", "&&", DMGL_ANSI}, /* ansi */
204 {"truth_orif", "||", 0}, /* old */
205 {"oo", "||", DMGL_ANSI}, /* ansi */
206 {"truth_not", "!", 0}, /* old */
207 {"nt", "!", DMGL_ANSI}, /* ansi */
208 {"postincrement","++", 0}, /* old */
209 {"pp", "++", DMGL_ANSI}, /* ansi */
210 {"postdecrement","--", 0}, /* old */
211 {"mm", "--", DMGL_ANSI}, /* ansi */
212 {"bit_ior", "|", 0}, /* old */
213 {"or", "|", DMGL_ANSI}, /* ansi */
214 {"aor", "|=", DMGL_ANSI}, /* ansi */
215 {"bit_xor", "^", 0}, /* old */
216 {"er", "^", DMGL_ANSI}, /* ansi */
217 {"aer", "^=", DMGL_ANSI}, /* ansi */
218 {"bit_and", "&", 0}, /* old */
219 {"ad", "&", DMGL_ANSI}, /* ansi */
220 {"aad", "&=", DMGL_ANSI}, /* ansi */
221 {"bit_not", "~", 0}, /* old */
222 {"co", "~", DMGL_ANSI}, /* ansi */
223 {"call", "()", 0}, /* old */
224 {"cl", "()", DMGL_ANSI}, /* ansi */
225 {"alshift", "<<", 0}, /* old */
226 {"ls", "<<", DMGL_ANSI}, /* ansi */
227 {"als", "<<=", DMGL_ANSI}, /* ansi */
228 {"arshift", ">>", 0}, /* old */
229 {"rs", ">>", DMGL_ANSI}, /* ansi */
230 {"ars", ">>=", DMGL_ANSI}, /* ansi */
231 {"component", "->", 0}, /* old */
232 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
233 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
234 {"indirect", "*", 0}, /* old */
235 {"method_call", "->()", 0}, /* old */
236 {"addr", "&", 0}, /* old (unary &) */
237 {"array", "[]", 0}, /* old */
238 {"vc", "[]", DMGL_ANSI}, /* ansi */
239 {"compound", ", ", 0}, /* old */
240 {"cm", ", ", DMGL_ANSI}, /* ansi */
241 {"cond", "?:", 0}, /* old */
242 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
243 {"max", ">?", 0}, /* old */
244 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
245 {"min", "<?", 0}, /* old */
246 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
247 {"nop", "", 0}, /* old (for operator=) */
248 {"rm", "->*", DMGL_ANSI}, /* ansi */
249 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
252 /* These values are used to indicate the various type varieties.
253 They are all non-zero so that they can be used as `success'
255 typedef enum type_kind_t
266 const struct demangler_engine libiberty_demanglers[] =
269 NO_DEMANGLING_STYLE_STRING,
271 "Demangling disabled"
275 AUTO_DEMANGLING_STYLE_STRING,
277 "Automatic selection based on executable"
281 GNU_DEMANGLING_STYLE_STRING,
283 "GNU (g++) style demangling"
287 LUCID_DEMANGLING_STYLE_STRING,
289 "Lucid (lcc) style demangling"
293 ARM_DEMANGLING_STYLE_STRING,
295 "ARM style demangling"
299 HP_DEMANGLING_STYLE_STRING,
301 "HP (aCC) style demangling"
305 EDG_DEMANGLING_STYLE_STRING,
307 "EDG style demangling"
311 GNU_V3_DEMANGLING_STYLE_STRING,
313 "GNU (g++) V3 ABI-style demangling"
317 JAVA_DEMANGLING_STYLE_STRING,
319 "Java style demangling"
323 GNAT_DEMANGLING_STYLE_STRING,
325 "GNAT style demangling"
329 NULL, unknown_demangling, NULL
333 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
334 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
335 string_append(str, " ");}
336 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
338 /* The scope separator appropriate for the language being demangled. */
340 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
342 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
343 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
345 /* Prototypes for local functions */
347 static void delete_work_stuff (struct work_stuff *);
349 static void delete_non_B_K_work_stuff (struct work_stuff *);
351 static char *mop_up (struct work_stuff *, string *, int);
353 static void squangle_mop_up (struct work_stuff *);
355 static void work_stuff_copy_to_from (struct work_stuff *, struct work_stuff *);
359 demangle_method_args (struct work_stuff *, const char **, string *);
363 internal_cplus_demangle (struct work_stuff *, const char *);
366 demangle_template_template_parm (struct work_stuff *work,
367 const char **, string *);
370 demangle_template (struct work_stuff *work, const char **, string *,
374 arm_pt (const char *, int, const char **, const char **);
377 demangle_class_name (struct work_stuff *, const char **, string *);
380 demangle_qualified (struct work_stuff *, const char **, string *,
383 static int demangle_class (struct work_stuff *, const char **, string *);
385 static int demangle_fund_type (struct work_stuff *, const char **, string *);
387 static int demangle_signature (struct work_stuff *, const char **, string *);
389 static int demangle_prefix (struct work_stuff *, const char **, string *);
391 static int gnu_special (struct work_stuff *, const char **, string *);
393 static int arm_special (const char **, string *);
395 static void string_need (string *, int);
397 static void string_delete (string *);
400 string_init (string *);
402 static void string_clear (string *);
405 static int string_empty (string *);
408 static void string_append (string *, const char *);
410 static void string_appends (string *, string *);
412 static void string_appendn (string *, const char *, int);
414 static void string_prepend (string *, const char *);
416 static void string_prependn (string *, const char *, int);
418 static void string_append_template_idx (string *, int);
420 static int get_count (const char **, int *);
422 static int consume_count (const char **);
424 static int consume_count_with_underscores (const char**);
426 static int demangle_args (struct work_stuff *, const char **, string *);
428 static int demangle_nested_args (struct work_stuff*, const char**, string*);
430 static int do_type (struct work_stuff *, const char **, string *);
432 static int do_arg (struct work_stuff *, const char **, string *);
435 demangle_function_name (struct work_stuff *, const char **, string *,
439 iterate_demangle_function (struct work_stuff *,
440 const char **, string *, const char *);
442 static void remember_type (struct work_stuff *, const char *, int);
444 static void remember_Btype (struct work_stuff *, const char *, int, int);
446 static int register_Btype (struct work_stuff *);
448 static void remember_Ktype (struct work_stuff *, const char *, int);
450 static void forget_types (struct work_stuff *);
452 static void forget_B_and_K_types (struct work_stuff *);
454 static void string_prepends (string *, string *);
457 demangle_template_value_parm (struct work_stuff*, const char**,
458 string*, type_kind_t);
461 do_hpacc_template_const_value (struct work_stuff *, const char **, string *);
464 do_hpacc_template_literal (struct work_stuff *, const char **, string *);
466 static int snarf_numeric_literal (const char **, string *);
468 /* There is a TYPE_QUAL value for each type qualifier. They can be
469 combined by bitwise-or to form the complete set of qualifiers for a
472 #define TYPE_UNQUALIFIED 0x0
473 #define TYPE_QUAL_CONST 0x1
474 #define TYPE_QUAL_VOLATILE 0x2
475 #define TYPE_QUAL_RESTRICT 0x4
477 static int code_for_qualifier (int);
479 static const char* qualifier_string (int);
481 static const char* demangle_qualifier (int);
483 static int demangle_expression (struct work_stuff *, const char **, string *,
487 demangle_integral_value (struct work_stuff *, const char **, string *);
490 demangle_real_value (struct work_stuff *, const char **, string *);
493 demangle_arm_hp_template (struct work_stuff *, const char **, int, string *);
496 recursively_demangle (struct work_stuff *, const char **, string *, int);
498 static void grow_vect (char **, size_t *, size_t, int);
500 /* Translate count to integer, consuming tokens in the process.
501 Conversion terminates on the first non-digit character.
503 Trying to consume something that isn't a count results in no
504 consumption of input and a return of -1.
506 Overflow consumes the rest of the digits, and returns -1. */
509 consume_count (const char **type)
513 if (! ISDIGIT ((unsigned char)**type))
516 while (ISDIGIT ((unsigned char)**type))
520 /* Check for overflow.
521 We assume that count is represented using two's-complement;
522 no power of two is divisible by ten, so if an overflow occurs
523 when multiplying by ten, the result will not be a multiple of
525 if ((count % 10) != 0)
527 while (ISDIGIT ((unsigned char) **type))
532 count += **type - '0';
543 /* Like consume_count, but for counts that are preceded and followed
544 by '_' if they are greater than 10. Also, -1 is returned for
545 failure, since 0 can be a valid value. */
548 consume_count_with_underscores (const char **mangled)
552 if (**mangled == '_')
555 if (!ISDIGIT ((unsigned char)**mangled))
558 idx = consume_count (mangled);
559 if (**mangled != '_')
560 /* The trailing underscore was missing. */
567 if (**mangled < '0' || **mangled > '9')
570 idx = **mangled - '0';
577 /* C is the code for a type-qualifier. Return the TYPE_QUAL
578 corresponding to this qualifier. */
581 code_for_qualifier (int c)
586 return TYPE_QUAL_CONST;
589 return TYPE_QUAL_VOLATILE;
592 return TYPE_QUAL_RESTRICT;
598 /* C was an invalid qualifier. */
602 /* Return the string corresponding to the qualifiers given by
606 qualifier_string (int type_quals)
610 case TYPE_UNQUALIFIED:
613 case TYPE_QUAL_CONST:
616 case TYPE_QUAL_VOLATILE:
619 case TYPE_QUAL_RESTRICT:
622 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
623 return "const volatile";
625 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
626 return "const __restrict";
628 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
629 return "volatile __restrict";
631 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
632 return "const volatile __restrict";
638 /* TYPE_QUALS was an invalid qualifier set. */
642 /* C is the code for a type-qualifier. Return the string
643 corresponding to this qualifier. This function should only be
644 called with a valid qualifier code. */
647 demangle_qualifier (int c)
649 return qualifier_string (code_for_qualifier (c));
653 cplus_demangle_opname (const char *opname, char *result, int options)
657 struct work_stuff work[1];
660 len = strlen(opname);
663 memset ((char *) work, 0, sizeof (work));
664 work->options = options;
666 if (opname[0] == '_' && opname[1] == '_'
667 && opname[2] == 'o' && opname[3] == 'p')
670 /* type conversion operator. */
672 if (do_type (work, &tem, &type))
674 strcat (result, "operator ");
675 strncat (result, type.b, type.p - type.b);
676 string_delete (&type);
680 else if (opname[0] == '_' && opname[1] == '_'
681 && ISLOWER((unsigned char)opname[2])
682 && ISLOWER((unsigned char)opname[3]))
684 if (opname[4] == '\0')
688 for (i = 0; i < ARRAY_SIZE (optable); i++)
690 if (strlen (optable[i].in) == 2
691 && memcmp (optable[i].in, opname + 2, 2) == 0)
693 strcat (result, "operator");
694 strcat (result, optable[i].out);
702 if (opname[2] == 'a' && opname[5] == '\0')
706 for (i = 0; i < ARRAY_SIZE (optable); i++)
708 if (strlen (optable[i].in) == 3
709 && memcmp (optable[i].in, opname + 2, 3) == 0)
711 strcat (result, "operator");
712 strcat (result, optable[i].out);
723 && strchr (cplus_markers, opname[2]) != NULL)
725 /* see if it's an assignment expression */
726 if (len >= 10 /* op$assign_ */
727 && memcmp (opname + 3, "assign_", 7) == 0)
730 for (i = 0; i < ARRAY_SIZE (optable); i++)
733 if ((int) strlen (optable[i].in) == len1
734 && memcmp (optable[i].in, opname + 10, len1) == 0)
736 strcat (result, "operator");
737 strcat (result, optable[i].out);
738 strcat (result, "=");
747 for (i = 0; i < ARRAY_SIZE (optable); i++)
750 if ((int) strlen (optable[i].in) == len1
751 && memcmp (optable[i].in, opname + 3, len1) == 0)
753 strcat (result, "operator");
754 strcat (result, optable[i].out);
761 else if (len >= 5 && memcmp (opname, "type", 4) == 0
762 && strchr (cplus_markers, opname[4]) != NULL)
764 /* type conversion operator */
766 if (do_type (work, &tem, &type))
768 strcat (result, "operator ");
769 strncat (result, type.b, type.p - type.b);
770 string_delete (&type);
774 squangle_mop_up (work);
779 /* Takes operator name as e.g. "++" and returns mangled
780 operator name (e.g. "postincrement_expr"), or NULL if not found.
782 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
783 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
786 cplus_mangle_opname (const char *opname, int options)
791 len = strlen (opname);
792 for (i = 0; i < ARRAY_SIZE (optable); i++)
794 if ((int) strlen (optable[i].out) == len
795 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
796 && memcmp (optable[i].out, opname, len) == 0)
797 return optable[i].in;
802 /* Add a routine to set the demangling style to be sure it is valid and
803 allow for any demangler initialization that maybe necessary. */
805 enum demangling_styles
806 cplus_demangle_set_style (enum demangling_styles style)
808 const struct demangler_engine *demangler = libiberty_demanglers;
810 for (; demangler->demangling_style != unknown_demangling; ++demangler)
811 if (style == demangler->demangling_style)
813 current_demangling_style = style;
814 return current_demangling_style;
817 return unknown_demangling;
820 /* Do string name to style translation */
822 enum demangling_styles
823 cplus_demangle_name_to_style (const char *name)
825 const struct demangler_engine *demangler = libiberty_demanglers;
827 for (; demangler->demangling_style != unknown_demangling; ++demangler)
828 if (strcmp (name, demangler->demangling_style_name) == 0)
829 return demangler->demangling_style;
831 return unknown_demangling;
834 /* char *cplus_demangle (const char *mangled, int options)
836 If MANGLED is a mangled function name produced by GNU C++, then
837 a pointer to a @code{malloc}ed string giving a C++ representation
838 of the name will be returned; otherwise NULL will be returned.
839 It is the caller's responsibility to free the string which
842 The OPTIONS arg may contain one or more of the following bits:
844 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
846 DMGL_PARAMS Function parameters are included.
850 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
851 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
852 cplus_demangle ("foo__1Ai", 0) => "A::foo"
854 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
855 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
856 cplus_demangle ("foo__1Afe", 0) => "A::foo"
858 Note that any leading underscores, or other such characters prepended by
859 the compilation system, are presumed to have already been stripped from
863 ML_(cplus_demangle) (const char *mangled, int options)
866 struct work_stuff work[1];
868 if (current_demangling_style == no_demangling)
869 return xstrdup (mangled);
871 memset ((char *) work, 0, sizeof (work));
872 work->options = options;
873 if ((work->options & DMGL_STYLE_MASK) == 0)
874 work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
876 /* The V3 ABI demangling is implemented elsewhere. */
877 if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
879 ret = cplus_demangle_v3 (mangled, work->options);
880 if (ret || GNU_V3_DEMANGLING)
886 ret = java_demangle_v3 (mangled);
892 return ada_demangle(mangled,options);
894 ret = internal_cplus_demangle (work, mangled);
895 squangle_mop_up (work);
900 /* Assuming *OLD_VECT points to an array of *SIZE objects of size
901 ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
902 updating *OLD_VECT and *SIZE as necessary. */
905 grow_vect (char **old_vect, size_t *size, size_t min_size, int element_size)
907 if (*size < min_size)
910 if (*size < min_size)
912 *old_vect = XRESIZEVAR (char, *old_vect, *size * element_size);
916 /* Demangle ada names:
917 1. Discard final __{DIGIT}+ or ${DIGIT}+
918 2. Convert other instances of embedded "__" to `.'.
919 3. Discard leading _ada_.
920 4. Remove everything after first ___ if it is followed by 'X'.
921 5. Put symbols that should be suppressed in <...> brackets.
922 The resulting string is valid until the next call of ada_demangle. */
925 ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
930 char *demangled = NULL;
932 size_t demangled_size = 0;
936 if (strncmp (mangled, "_ada_", 5) == 0)
942 if (mangled[0] == '_' || mangled[0] == '<')
945 p = strstr (mangled, "___");
947 len0 = strlen (mangled);
959 /* Make demangled big enough for possible expansion by operator name. */
960 grow_vect (&demangled,
961 &demangled_size, 2 * len0 + 1,
964 if (ISDIGIT ((unsigned char) mangled[len0 - 1])) {
965 for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1)
967 if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_')
972 else if (mangled[i] == '$')
979 for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]);
981 demangled[j] = mangled[i];
985 if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_')
993 demangled[j] = mangled[i];
997 demangled[j] = '\000';
999 for (i = 0; demangled[i] != '\0'; i += 1)
1000 if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ')
1009 grow_vect (&demangled,
1010 &demangled_size, strlen (mangled) + 3,
1013 if (mangled[0] == '<')
1014 strcpy (demangled, mangled);
1016 sprintf (demangled, "<%s>", mangled);
1021 /* This function performs most of what cplus_demangle use to do, but
1022 to be able to demangle a name with a B, K or n code, we need to
1023 have a longer term memory of what types have been seen. The original
1024 now initializes and cleans up the squangle code info, while internal
1025 calls go directly to this routine to avoid resetting that info. */
1028 internal_cplus_demangle (struct work_stuff *work, const char *mangled)
1033 char *demangled = NULL;
1035 s1 = work->constructor;
1036 s2 = work->destructor;
1037 s3 = work->static_type;
1038 s4 = work->type_quals;
1039 work->constructor = work->destructor = 0;
1040 work->type_quals = TYPE_UNQUALIFIED;
1041 work->dllimported = 0;
1043 if ((mangled != NULL) && (*mangled != '\0'))
1045 string_init (&decl);
1047 /* First check to see if gnu style demangling is active and if the
1048 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1049 recognize one of the gnu special forms rather than looking for a
1050 standard prefix. In particular, don't worry about whether there
1051 is a "__" string in the mangled string. Consider "_$_5__foo" for
1054 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
1056 success = gnu_special (work, &mangled, &decl);
1060 success = demangle_prefix (work, &mangled, &decl);
1062 if (success && (*mangled != '\0'))
1064 success = demangle_signature (work, &mangled, &decl);
1066 if (work->constructor == 2)
1068 string_prepend (&decl, "global constructors keyed to ");
1069 work->constructor = 0;
1071 else if (work->destructor == 2)
1073 string_prepend (&decl, "global destructors keyed to ");
1074 work->destructor = 0;
1076 else if (work->dllimported == 1)
1078 string_prepend (&decl, "import stub for ");
1079 work->dllimported = 0;
1081 demangled = mop_up (work, &decl, success);
1083 work->constructor = s1;
1084 work->destructor = s2;
1085 work->static_type = s3;
1086 work->type_quals = s4;
1091 /* Clear out and squangling related storage */
1093 squangle_mop_up (struct work_stuff *work)
1095 /* clean up the B and K type mangling types. */
1096 forget_B_and_K_types (work);
1097 if (work -> btypevec != NULL)
1099 free ((char *) work -> btypevec);
1101 if (work -> ktypevec != NULL)
1103 free ((char *) work -> ktypevec);
1108 /* Copy the work state and storage. */
1111 work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from)
1115 delete_work_stuff (to);
1117 /* Shallow-copy scalars. */
1118 memcpy (to, from, sizeof (*to));
1120 /* Deep-copy dynamic storage. */
1121 if (from->typevec_size)
1122 to->typevec = XNEWVEC (char *, from->typevec_size);
1124 for (i = 0; i < from->ntypes; i++)
1126 int len = strlen (from->typevec[i]) + 1;
1128 to->typevec[i] = XNEWVEC (char, len);
1129 memcpy (to->typevec[i], from->typevec[i], len);
1133 to->ktypevec = XNEWVEC (char *, from->ksize);
1135 for (i = 0; i < from->numk; i++)
1137 int len = strlen (from->ktypevec[i]) + 1;
1139 to->ktypevec[i] = XNEWVEC (char, len);
1140 memcpy (to->ktypevec[i], from->ktypevec[i], len);
1144 to->btypevec = XNEWVEC (char *, from->bsize);
1146 for (i = 0; i < from->numb; i++)
1148 int len = strlen (from->btypevec[i]) + 1;
1150 to->btypevec[i] = XNEWVEC (char , len);
1151 memcpy (to->btypevec[i], from->btypevec[i], len);
1154 if (from->ntmpl_args)
1155 to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args);
1157 for (i = 0; i < from->ntmpl_args; i++)
1159 int len = strlen (from->tmpl_argvec[i]) + 1;
1161 to->tmpl_argvec[i] = XNEWVEC (char, len);
1162 memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len);
1165 if (from->previous_argument)
1167 to->previous_argument = XNEW (string);
1168 string_init (to->previous_argument);
1169 string_appends (to->previous_argument, from->previous_argument);
1174 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1177 delete_non_B_K_work_stuff (struct work_stuff *work)
1179 /* Discard the remembered types, if any. */
1181 forget_types (work);
1182 if (work -> typevec != NULL)
1184 free ((char *) work -> typevec);
1185 work -> typevec = NULL;
1186 work -> typevec_size = 0;
1188 if (work->tmpl_argvec)
1192 for (i = 0; i < work->ntmpl_args; i++)
1193 if (work->tmpl_argvec[i])
1194 free ((char*) work->tmpl_argvec[i]);
1196 free ((char*) work->tmpl_argvec);
1197 work->tmpl_argvec = NULL;
1199 if (work->previous_argument)
1201 string_delete (work->previous_argument);
1202 free ((char*) work->previous_argument);
1203 work->previous_argument = NULL;
1208 /* Delete all dynamic storage in work_stuff. */
1210 delete_work_stuff (struct work_stuff *work)
1212 delete_non_B_K_work_stuff (work);
1213 squangle_mop_up (work);
1217 /* Clear out any mangled storage */
1220 mop_up (struct work_stuff *work, string *declp, int success)
1222 char *demangled = NULL;
1224 delete_non_B_K_work_stuff (work);
1226 /* If demangling was successful, ensure that the demangled string is null
1227 terminated and return it. Otherwise, free the demangling decl. */
1231 string_delete (declp);
1235 string_appendn (declp, "", 1);
1236 demangled = declp->b;
1245 demangle_signature -- demangle the signature part of a mangled name
1250 demangle_signature (struct work_stuff *work, const char **mangled,
1255 Consume and demangle the signature portion of the mangled name.
1257 DECLP is the string where demangled output is being built. At
1258 entry it contains the demangled root name from the mangled name
1259 prefix. I.E. either a demangled operator name or the root function
1260 name. In some special cases, it may contain nothing.
1262 *MANGLED points to the current unconsumed location in the mangled
1263 name. As tokens are consumed and demangling is performed, the
1264 pointer is updated to continuously point at the next token to
1267 Demangling GNU style mangled names is nasty because there is no
1268 explicit token that marks the start of the outermost function
1272 demangle_signature (struct work_stuff *work,
1273 const char **mangled, string *declp)
1277 int expect_func = 0;
1278 int expect_return_type = 0;
1279 const char *oldmangled = NULL;
1283 while (success && (**mangled != '\0'))
1288 oldmangled = *mangled;
1289 success = demangle_qualified (work, mangled, declp, 1, 0);
1291 remember_type (work, oldmangled, *mangled - oldmangled);
1292 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1298 //oldmangled = *mangled;
1299 success = demangle_qualified (work, mangled, declp, 1, 0);
1300 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1308 /* Static member function */
1309 if (oldmangled == NULL)
1311 oldmangled = *mangled;
1314 work -> static_type = 1;
1320 work->type_quals |= code_for_qualifier (**mangled);
1322 /* a qualified member function */
1323 if (oldmangled == NULL)
1324 oldmangled = *mangled;
1329 /* Local class name follows after "Lnnn_" */
1332 while (**mangled && (**mangled != '_'))
1343 case '0': case '1': case '2': case '3': case '4':
1344 case '5': case '6': case '7': case '8': case '9':
1345 if (oldmangled == NULL)
1347 oldmangled = *mangled;
1349 work->temp_start = -1; /* uppermost call to demangle_class */
1350 success = demangle_class (work, mangled, declp);
1353 remember_type (work, oldmangled, *mangled - oldmangled);
1355 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1357 /* EDG and others will have the "F", so we let the loop cycle
1358 if we are looking at one. */
1359 if (**mangled != 'F')
1368 success = do_type (work, mangled, &s);
1371 string_append (&s, SCOPE_STRING (work));
1372 string_prepends (declp, &s);
1382 /* ARM/HP style demangling includes a specific 'F' character after
1383 the class name. For GNU style, it is just implied. So we can
1384 safely just consume any 'F' at this point and be compatible
1385 with either style. */
1391 /* For lucid/ARM/HP style we have to forget any types we might
1392 have remembered up to this point, since they were not argument
1393 types. GNU style considers all types seen as available for
1394 back references. See comment in demangle_args() */
1396 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1398 forget_types (work);
1400 success = demangle_args (work, mangled, declp);
1401 /* After picking off the function args, we expect to either
1402 find the function return type (preceded by an '_') or the
1403 end of the string. */
1404 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1407 /* At this level, we do not care about the return type. */
1408 success = do_type (work, mangled, &tname);
1409 string_delete (&tname);
1416 string_init(&trawname);
1417 string_init(&tname);
1418 if (oldmangled == NULL)
1420 oldmangled = *mangled;
1422 success = demangle_template (work, mangled, &tname,
1426 remember_type (work, oldmangled, *mangled - oldmangled);
1428 string_append (&tname, SCOPE_STRING (work));
1430 string_prepends(declp, &tname);
1431 if (work -> destructor & 1)
1433 string_prepend (&trawname, "~");
1434 string_appends (declp, &trawname);
1435 work->destructor -= 1;
1437 if ((work->constructor & 1) || (work->destructor & 1))
1439 string_appends (declp, &trawname);
1440 work->constructor -= 1;
1442 string_delete(&trawname);
1443 string_delete(&tname);
1449 if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
1451 /* Read the return type. */
1455 success = do_type (work, mangled, &return_type);
1456 APPEND_BLANK (&return_type);
1458 string_prepends (declp, &return_type);
1459 string_delete (&return_type);
1463 /* At the outermost level, we cannot have a return type specified,
1464 so if we run into another '_' at this point we are dealing with
1465 a mangled name that is either bogus, or has been mangled by
1466 some algorithm we don't know how to deal with. So just
1467 reject the entire demangling. */
1468 /* However, "_nnn" is an expected suffix for alternate entry point
1469 numbered nnn for a function, with HP aCC, so skip over that
1470 without reporting failure. pai/1997-09-04 */
1474 while (**mangled && ISDIGIT ((unsigned char)**mangled))
1482 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1484 /* A G++ template function. Read the template arguments. */
1485 success = demangle_template (work, mangled, declp, 0, 0,
1487 if (!(work->constructor & 1))
1488 expect_return_type = 1;
1497 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1499 /* Assume we have stumbled onto the first outermost function
1500 argument token, and start processing args. */
1502 success = demangle_args (work, mangled, declp);
1506 /* Non-GNU demanglers use a specific token to mark the start
1507 of the outermost function argument tokens. Typically 'F',
1508 for ARM/HP-demangling, for example. So if we find something
1509 we are not prepared for, it must be an error. */
1515 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1518 if (success && expect_func)
1521 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1523 forget_types (work);
1525 success = demangle_args (work, mangled, declp);
1526 /* Since template include the mangling of their return types,
1527 we must set expect_func to 0 so that we don't try do
1528 demangle more arguments the next time we get here. */
1533 if (success && !func_done)
1535 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1537 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1538 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1539 first case, and need to ensure that the '(void)' gets added to
1540 the current declp. Note that with ARM/HP, the first case
1541 represents the name of a static data member 'foo::bar',
1542 which is in the current declp, so we leave it alone. */
1543 success = demangle_args (work, mangled, declp);
1546 if (success && PRINT_ARG_TYPES)
1548 if (work->static_type)
1549 string_append (declp, " static");
1550 if (work->type_quals != TYPE_UNQUALIFIED)
1552 APPEND_BLANK (declp);
1553 string_append (declp, qualifier_string (work->type_quals));
1563 demangle_method_args (struct work_stuff *work, const char **mangled,
1568 if (work -> static_type)
1570 string_append (declp, *mangled + 1);
1571 *mangled += strlen (*mangled);
1576 success = demangle_args (work, mangled, declp);
1584 demangle_template_template_parm (struct work_stuff *work,
1585 const char **mangled, string *tname)
1593 string_append (tname, "template <");
1594 /* get size of template parameter list */
1595 if (get_count (mangled, &r))
1597 for (i = 0; i < r; i++)
1601 string_append (tname, ", ");
1604 /* Z for type parameters */
1605 if (**mangled == 'Z')
1608 string_append (tname, "class");
1610 /* z for template parameters */
1611 else if (**mangled == 'z')
1615 demangle_template_template_parm (work, mangled, tname);
1623 /* temp is initialized in do_type */
1624 success = do_type (work, mangled, &temp);
1627 string_appends (tname, &temp);
1629 string_delete(&temp);
1639 if (tname->p[-1] == '>')
1640 string_append (tname, " ");
1641 string_append (tname, "> class");
1646 demangle_expression (struct work_stuff *work, const char **mangled,
1647 string *s, type_kind_t tk)
1649 int need_operator = 0;
1653 string_appendn (s, "(", 1);
1655 while (success && **mangled != 'W' && **mangled != '\0')
1664 len = strlen (*mangled);
1666 for (i = 0; i < ARRAY_SIZE (optable); ++i)
1668 size_t l = strlen (optable[i].in);
1671 && memcmp (optable[i].in, *mangled, l) == 0)
1673 string_appendn (s, " ", 1);
1674 string_append (s, optable[i].out);
1675 string_appendn (s, " ", 1);
1688 success = demangle_template_value_parm (work, mangled, s, tk);
1691 if (**mangled != 'W')
1695 string_appendn (s, ")", 1);
1703 demangle_integral_value (struct work_stuff *work,
1704 const char **mangled, string *s)
1708 if (**mangled == 'E')
1709 success = demangle_expression (work, mangled, s, tk_integral);
1710 else if (**mangled == 'Q' || **mangled == 'K')
1711 success = demangle_qualified (work, mangled, s, 0, 1);
1716 /* By default, we let the number decide whether we shall consume an
1718 int multidigit_without_leading_underscore = 0;
1719 int leave_following_underscore = 0;
1723 if (**mangled == '_')
1725 if (mangled[0][1] == 'm')
1727 /* Since consume_count_with_underscores does not handle the
1728 `m'-prefix we must do it here, using consume_count and
1729 adjusting underscores: we have to consume the underscore
1730 matching the prepended one. */
1731 multidigit_without_leading_underscore = 1;
1732 string_appendn (s, "-", 1);
1737 /* Do not consume a following underscore;
1738 consume_count_with_underscores will consume what
1739 should be consumed. */
1740 leave_following_underscore = 1;
1745 /* Negative numbers are indicated with a leading `m'. */
1746 if (**mangled == 'm')
1748 string_appendn (s, "-", 1);
1751 /* Since consume_count_with_underscores does not handle
1752 multi-digit numbers that do not start with an underscore,
1753 and this number can be an integer template parameter,
1754 we have to call consume_count. */
1755 multidigit_without_leading_underscore = 1;
1756 /* These multi-digit numbers never end on an underscore,
1757 so if there is one then don't eat it. */
1758 leave_following_underscore = 1;
1761 /* We must call consume_count if we expect to remove a trailing
1762 underscore, since consume_count_with_underscores expects
1763 the leading underscore (that we consumed) if it is to handle
1764 multi-digit numbers. */
1765 if (multidigit_without_leading_underscore)
1766 value = consume_count (mangled);
1768 value = consume_count_with_underscores (mangled);
1772 char buf[INTBUF_SIZE];
1773 sprintf (buf, "%d", value);
1774 string_append (s, buf);
1776 /* Numbers not otherwise delimited, might have an underscore
1777 appended as a delimeter, which we should skip.
1779 ??? This used to always remove a following underscore, which
1780 is wrong. If other (arbitrary) cases are followed by an
1781 underscore, we need to do something more radical. */
1783 if ((value > 9 || multidigit_without_leading_underscore)
1784 && ! leave_following_underscore
1785 && **mangled == '_')
1796 /* Demangle the real value in MANGLED. */
1799 demangle_real_value (struct work_stuff *work,
1800 const char **mangled, string *s)
1802 if (**mangled == 'E')
1803 return demangle_expression (work, mangled, s, tk_real);
1805 if (**mangled == 'm')
1807 string_appendn (s, "-", 1);
1810 while (ISDIGIT ((unsigned char)**mangled))
1812 string_appendn (s, *mangled, 1);
1815 if (**mangled == '.') /* fraction */
1817 string_appendn (s, ".", 1);
1819 while (ISDIGIT ((unsigned char)**mangled))
1821 string_appendn (s, *mangled, 1);
1825 if (**mangled == 'e') /* exponent */
1827 string_appendn (s, "e", 1);
1829 while (ISDIGIT ((unsigned char)**mangled))
1831 string_appendn (s, *mangled, 1);
1840 demangle_template_value_parm (struct work_stuff *work, const char **mangled,
1841 string *s, type_kind_t tk)
1845 if (**mangled == 'Y')
1847 /* The next argument is a template parameter. */
1851 idx = consume_count_with_underscores (mangled);
1853 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1854 || consume_count_with_underscores (mangled) == -1)
1856 if (work->tmpl_argvec)
1857 string_append (s, work->tmpl_argvec[idx]);
1859 string_append_template_idx (s, idx);
1861 else if (tk == tk_integral)
1862 success = demangle_integral_value (work, mangled, s);
1863 else if (tk == tk_char)
1867 if (**mangled == 'm')
1869 string_appendn (s, "-", 1);
1872 string_appendn (s, "'", 1);
1873 val = consume_count(mangled);
1880 string_appendn (s, &tmp[0], 1);
1881 string_appendn (s, "'", 1);
1884 else if (tk == tk_bool)
1886 int val = consume_count (mangled);
1888 string_appendn (s, "false", 5);
1890 string_appendn (s, "true", 4);
1894 else if (tk == tk_real)
1895 success = demangle_real_value (work, mangled, s);
1896 else if (tk == tk_pointer || tk == tk_reference)
1898 if (**mangled == 'Q')
1899 success = demangle_qualified (work, mangled, s,
1904 int symbol_len = consume_count (mangled);
1905 if (symbol_len == -1)
1907 if (symbol_len == 0)
1908 string_appendn (s, "0", 1);
1911 char *p = XNEWVEC (char, symbol_len + 1), *q;
1912 strncpy (p, *mangled, symbol_len);
1913 p [symbol_len] = '\0';
1914 /* We use cplus_demangle here, rather than
1915 internal_cplus_demangle, because the name of the entity
1916 mangled here does not make use of any of the squangling
1917 or type-code information we have built up thus far; it is
1918 mangled independently. */
1919 q = ML_(cplus_demangle) (p, work->options);
1920 if (tk == tk_pointer)
1921 string_appendn (s, "&", 1);
1922 /* FIXME: Pointer-to-member constants should get a
1923 qualifying class name here. */
1926 string_append (s, q);
1930 string_append (s, p);
1933 *mangled += symbol_len;
1940 /* Demangle the template name in MANGLED. The full name of the
1941 template (e.g., S<int>) is placed in TNAME. The name without the
1942 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1943 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1944 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1945 the template is remembered in the list of back-referenceable
1949 demangle_template (struct work_stuff *work, const char **mangled,
1950 string *tname, string *trawname,
1951 int is_type, int remember)
1957 int is_java_array = 0;
1963 /* get template name */
1964 if (**mangled == 'z')
1970 idx = consume_count_with_underscores (mangled);
1972 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1973 || consume_count_with_underscores (mangled) == -1)
1976 if (work->tmpl_argvec)
1978 string_append (tname, work->tmpl_argvec[idx]);
1980 string_append (trawname, work->tmpl_argvec[idx]);
1984 string_append_template_idx (tname, idx);
1986 string_append_template_idx (trawname, idx);
1991 if ((r = consume_count (mangled)) <= 0
1992 || (int) strlen (*mangled) < r)
1996 is_java_array = (work -> options & DMGL_JAVA)
1997 && strncmp (*mangled, "JArray1Z", 8) == 0;
1998 if (! is_java_array)
2000 string_appendn (tname, *mangled, r);
2003 string_appendn (trawname, *mangled, r);
2008 string_append (tname, "<");
2009 /* get size of template parameter list */
2010 if (!get_count (mangled, &r))
2016 /* Create an array for saving the template argument values. */
2017 work->tmpl_argvec = XNEWVEC (char *, r);
2018 work->ntmpl_args = r;
2019 for (i = 0; i < r; i++)
2020 work->tmpl_argvec[i] = 0;
2022 for (i = 0; i < r; i++)
2026 string_append (tname, ", ");
2028 /* Z for type parameters */
2029 if (**mangled == 'Z')
2032 /* temp is initialized in do_type */
2033 success = do_type (work, mangled, &temp);
2036 string_appends (tname, &temp);
2040 /* Save the template argument. */
2041 int len = temp.p - temp.b;
2042 work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2043 memcpy (work->tmpl_argvec[i], temp.b, len);
2044 work->tmpl_argvec[i][len] = '\0';
2047 string_delete(&temp);
2053 /* z for template parameters */
2054 else if (**mangled == 'z')
2058 success = demangle_template_template_parm (work, mangled, tname);
2061 && (r2 = consume_count (mangled)) > 0
2062 && (int) strlen (*mangled) >= r2)
2064 string_append (tname, " ");
2065 string_appendn (tname, *mangled, r2);
2068 /* Save the template argument. */
2070 work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2071 memcpy (work->tmpl_argvec[i], *mangled, len);
2072 work->tmpl_argvec[i][len] = '\0';
2086 /* otherwise, value parameter */
2088 /* temp is initialized in do_type */
2089 success = do_type (work, mangled, &temp);
2090 string_delete(&temp);
2102 success = demangle_template_value_parm (work, mangled, s,
2103 (type_kind_t) success);
2115 int len = s->p - s->b;
2116 work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2117 memcpy (work->tmpl_argvec[i], s->b, len);
2118 work->tmpl_argvec[i][len] = '\0';
2120 string_appends (tname, s);
2128 string_append (tname, "[]");
2132 if (tname->p[-1] == '>')
2133 string_append (tname, " ");
2134 string_append (tname, ">");
2137 if (is_type && remember)
2139 const int bindex = register_Btype (work);
2140 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
2144 if (work -> static_type)
2146 string_append (declp, *mangled + 1);
2147 *mangled += strlen (*mangled);
2152 success = demangle_args (work, mangled, declp);
2160 arm_pt (const char *mangled,
2161 int n, const char **anchor, const char **args)
2163 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2164 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2165 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__")))
2168 *args = *anchor + 6;
2169 len = consume_count (args);
2172 if (*args + len == mangled + n && **args == '_')
2178 if (AUTO_DEMANGLING || EDG_DEMANGLING)
2180 if ((*anchor = strstr (mangled, "__tm__"))
2181 || (*anchor = strstr (mangled, "__ps__"))
2182 || (*anchor = strstr (mangled, "__pt__")))
2185 *args = *anchor + 6;
2186 len = consume_count (args);
2189 if (*args + len == mangled + n && **args == '_')
2195 else if ((*anchor = strstr (mangled, "__S")))
2198 *args = *anchor + 3;
2199 len = consume_count (args);
2202 if (*args + len == mangled + n && **args == '_')
2214 demangle_arm_hp_template (struct work_stuff *work, const char **mangled,
2215 int n, string *declp)
2219 const char *e = *mangled + n;
2222 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2224 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
2226 char *start_spec_args = NULL;
2229 /* First check for and omit template specialization pseudo-arguments,
2230 such as in "Spec<#1,#1.*>" */
2231 start_spec_args = strchr (*mangled, '<');
2232 if (start_spec_args && (start_spec_args - *mangled < n))
2233 string_appendn (declp, *mangled, start_spec_args - *mangled);
2235 string_appendn (declp, *mangled, n);
2236 (*mangled) += n + 1;
2238 if (work->temp_start == -1) /* non-recursive call */
2239 work->temp_start = declp->p - declp->b;
2241 /* We want to unconditionally demangle parameter types in
2242 template parameters. */
2243 hold_options = work->options;
2244 work->options |= DMGL_PARAMS;
2246 string_append (declp, "<");
2249 string_delete (&arg);
2253 /* 'T' signals a type parameter */
2255 if (!do_type (work, mangled, &arg))
2256 goto hpacc_template_args_done;
2261 /* 'U' or 'S' signals an integral value */
2262 if (!do_hpacc_template_const_value (work, mangled, &arg))
2263 goto hpacc_template_args_done;
2267 /* 'A' signals a named constant expression (literal) */
2268 if (!do_hpacc_template_literal (work, mangled, &arg))
2269 goto hpacc_template_args_done;
2273 /* Today, 1997-09-03, we have only the above types
2274 of template parameters */
2275 /* FIXME: maybe this should fail and return null */
2276 goto hpacc_template_args_done;
2278 string_appends (declp, &arg);
2279 /* Check if we're at the end of template args.
2280 0 if at end of static member of template class,
2281 _ if done with template args for a function */
2282 if ((**mangled == '\000') || (**mangled == '_'))
2285 string_append (declp, ",");
2287 hpacc_template_args_done:
2288 string_append (declp, ">");
2289 string_delete (&arg);
2290 if (**mangled == '_')
2292 work->options = hold_options;
2295 /* ARM template? (Also handles HP cfront extensions) */
2296 else if (arm_pt (*mangled, n, &p, &args))
2302 string_appendn (declp, *mangled, p - *mangled);
2303 if (work->temp_start == -1) /* non-recursive call */
2304 work->temp_start = declp->p - declp->b;
2306 /* We want to unconditionally demangle parameter types in
2307 template parameters. */
2308 hold_options = work->options;
2309 work->options |= DMGL_PARAMS;
2311 string_append (declp, "<");
2312 /* should do error checking here */
2314 string_delete (&arg);
2316 /* Check for type or literal here */
2319 /* HP cfront extensions to ARM for template args */
2320 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2321 /* FIXME: We handle only numeric literals for HP cfront */
2323 /* A typed constant value follows */
2325 if (!do_type (work, &args, &type_str))
2326 goto cfront_template_args_done;
2327 string_append (&arg, "(");
2328 string_appends (&arg, &type_str);
2329 string_delete (&type_str);
2330 string_append (&arg, ")");
2332 goto cfront_template_args_done;
2334 /* Now snarf a literal value following 'L' */
2335 if (!snarf_numeric_literal (&args, &arg))
2336 goto cfront_template_args_done;
2340 /* Snarf a literal following 'L' */
2342 if (!snarf_numeric_literal (&args, &arg))
2343 goto cfront_template_args_done;
2346 /* Not handling other HP cfront stuff */
2348 const char* old_args = args;
2349 if (!do_type (work, &args, &arg))
2350 goto cfront_template_args_done;
2352 /* Fail if we didn't make any progress: prevent infinite loop. */
2353 if (args == old_args)
2355 work->options = hold_options;
2360 string_appends (declp, &arg);
2361 string_append (declp, ",");
2363 cfront_template_args_done:
2364 string_delete (&arg);
2366 --declp->p; /* remove extra comma */
2367 string_append (declp, ">");
2368 work->options = hold_options;
2370 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2371 && (*mangled)[9] == 'N'
2372 && (*mangled)[8] == (*mangled)[10]
2373 && strchr (cplus_markers, (*mangled)[8]))
2375 /* A member of the anonymous namespace. */
2376 string_append (declp, "{anonymous}");
2380 if (work->temp_start == -1) /* non-recursive call only */
2381 work->temp_start = 0; /* disable in recursive calls */
2382 string_appendn (declp, *mangled, n);
2387 /* Extract a class name, possibly a template with arguments, from the
2388 mangled string; qualifiers, local class indicators, etc. have
2389 already been dealt with */
2392 demangle_class_name (struct work_stuff *work, const char **mangled,
2398 n = consume_count (mangled);
2401 if ((int) strlen (*mangled) >= n)
2403 demangle_arm_hp_template (work, mangled, n, declp);
2414 demangle_class -- demangle a mangled class sequence
2419 demangle_class (struct work_stuff *work, const char **mangled,
2424 DECLP points to the buffer into which demangling is being done.
2426 *MANGLED points to the current token to be demangled. On input,
2427 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2428 On exit, it points to the next token after the mangled class on
2429 success, or the first unconsumed token on failure.
2431 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2432 we are demangling a constructor or destructor. In this case
2433 we prepend "class::class" or "class::~class" to DECLP.
2435 Otherwise, we prepend "class::" to the current DECLP.
2437 Reset the constructor/destructor flags once they have been
2438 "consumed". This allows demangle_class to be called later during
2439 the same demangling, to do normal class demangling.
2441 Returns 1 if demangling is successful, 0 otherwise.
2446 demangle_class (struct work_stuff *work, const char **mangled, string *declp)
2451 char *save_class_name_end = 0;
2453 string_init (&class_name);
2454 btype = register_Btype (work);
2455 if (demangle_class_name (work, mangled, &class_name))
2457 save_class_name_end = class_name.p;
2458 if ((work->constructor & 1) || (work->destructor & 1))
2460 /* adjust so we don't include template args */
2461 if (work->temp_start && (work->temp_start != -1))
2463 class_name.p = class_name.b + work->temp_start;
2465 string_prepends (declp, &class_name);
2466 if (work -> destructor & 1)
2468 string_prepend (declp, "~");
2469 work -> destructor -= 1;
2473 work -> constructor -= 1;
2476 class_name.p = save_class_name_end;
2477 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2478 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2479 string_prepend (declp, SCOPE_STRING (work));
2480 string_prepends (declp, &class_name);
2483 string_delete (&class_name);
2488 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2489 the rightmost guess.
2491 Find the correct "__"-sequence where the function name ends and the
2492 signature starts, which is ambiguous with GNU mangling.
2493 Call demangle_signature here, so we can make sure we found the right
2494 one; *mangled will be consumed so caller will not make further calls to
2495 demangle_signature. */
2498 iterate_demangle_function (struct work_stuff *work, const char **mangled,
2499 string *declp, const char *scan)
2501 const char *mangle_init = *mangled;
2504 struct work_stuff work_init;
2506 if (*(scan + 2) == '\0')
2509 /* Do not iterate for some demangling modes, or if there's only one
2510 "__"-sequence. This is the normal case. */
2511 if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
2512 || strstr (scan + 2, "__") == NULL)
2513 return demangle_function_name (work, mangled, declp, scan);
2515 /* Save state so we can restart if the guess at the correct "__" was
2517 string_init (&decl_init);
2518 string_appends (&decl_init, declp);
2519 memset (&work_init, 0, sizeof work_init);
2520 work_stuff_copy_to_from (&work_init, work);
2522 /* Iterate over occurrences of __, allowing names and types to have a
2523 "__" sequence in them. We must start with the first (not the last)
2524 occurrence, since "__" most often occur between independent mangled
2525 parts, hence starting at the last occurence inside a signature
2526 might get us a "successful" demangling of the signature. */
2530 if (demangle_function_name (work, mangled, declp, scan))
2532 success = demangle_signature (work, mangled, declp);
2537 /* Reset demangle state for the next round. */
2538 *mangled = mangle_init;
2539 string_clear (declp);
2540 string_appends (declp, &decl_init);
2541 work_stuff_copy_to_from (work, &work_init);
2543 /* Leave this underscore-sequence. */
2546 /* Scan for the next "__" sequence. */
2547 while (*scan && (scan[0] != '_' || scan[1] != '_'))
2550 /* Move to last "__" in this sequence. */
2551 while (*scan && *scan == '_')
2556 /* Delete saved state. */
2557 delete_work_stuff (&work_init);
2558 string_delete (&decl_init);
2567 demangle_prefix -- consume the mangled name prefix and find signature
2572 demangle_prefix (struct work_stuff *work, const char **mangled,
2577 Consume and demangle the prefix of the mangled name.
2578 While processing the function name root, arrange to call
2579 demangle_signature if the root is ambiguous.
2581 DECLP points to the string buffer into which demangled output is
2582 placed. On entry, the buffer is empty. On exit it contains
2583 the root function name, the demangled operator name, or in some
2584 special cases either nothing or the completely demangled result.
2586 MANGLED points to the current pointer into the mangled name. As each
2587 token of the mangled name is consumed, it is updated. Upon entry
2588 the current mangled name pointer points to the first character of
2589 the mangled name. Upon exit, it should point to the first character
2590 of the signature if demangling was successful, or to the first
2591 unconsumed character if demangling of the prefix was unsuccessful.
2593 Returns 1 on success, 0 otherwise.
2597 demangle_prefix (struct work_stuff *work, const char **mangled,
2604 if (strlen(*mangled) > 6
2605 && (strncmp(*mangled, "_imp__", 6) == 0
2606 || strncmp(*mangled, "__imp_", 6) == 0))
2608 /* it's a symbol imported from a PE dynamic library. Check for both
2609 new style prefix _imp__ and legacy __imp_ used by older versions
2612 work->dllimported = 1;
2614 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2616 char *marker = strchr (cplus_markers, (*mangled)[8]);
2617 if (marker != NULL && *marker == (*mangled)[10])
2619 if ((*mangled)[9] == 'D')
2621 /* it's a GNU global destructor to be executed at program exit */
2623 work->destructor = 2;
2624 if (gnu_special (work, mangled, declp))
2627 else if ((*mangled)[9] == 'I')
2629 /* it's a GNU global constructor to be executed at program init */
2631 work->constructor = 2;
2632 if (gnu_special (work, mangled, declp))
2637 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2639 /* it's a ARM global destructor to be executed at program exit */
2641 work->destructor = 2;
2643 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2645 /* it's a ARM global constructor to be executed at program initial */
2647 work->constructor = 2;
2650 /* This block of code is a reduction in strength time optimization
2652 scan = strstr (*mangled, "__"); */
2658 scan = strchr (scan, '_');
2659 } while (scan != NULL && *++scan != '_');
2661 if (scan != NULL) --scan;
2666 /* We found a sequence of two or more '_', ensure that we start at
2667 the last pair in the sequence. */
2668 i = strspn (scan, "_");
2679 else if (work -> static_type)
2681 if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2686 else if ((scan == *mangled)
2687 && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2688 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2690 /* The ARM says nothing about the mangling of local variables.
2691 But cfront mangles local variables by prepending __<nesting_level>
2692 to them. As an extension to ARM demangling we handle this case. */
2693 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2694 && ISDIGIT ((unsigned char)scan[2]))
2696 *mangled = scan + 2;
2697 consume_count (mangled);
2698 string_append (declp, *mangled);
2699 *mangled += strlen (*mangled);
2704 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2705 names like __Q2_3foo3bar for nested type names. So don't accept
2706 this style of constructor for cfront demangling. A GNU
2707 style member-template constructor starts with 'H'. */
2708 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2709 work -> constructor += 1;
2710 *mangled = scan + 2;
2713 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2715 /* Cfront-style parameterized type. Handled later as a signature. */
2719 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2721 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2722 || (scan[2] == 'p' && scan[3] == 's')
2723 || (scan[2] == 'p' && scan[3] == 't')))
2725 /* EDG-style parameterized type. Handled later as a signature. */
2729 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2731 else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2732 && (scan[2] != 't'))
2734 /* Mangled name starts with "__". Skip over any leading '_' characters,
2735 then find the next "__" that separates the prefix from the signature.
2737 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2738 || (arm_special (mangled, declp) == 0))
2740 while (*scan == '_')
2744 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2746 /* No separator (I.E. "__not_mangled"), or empty signature
2747 (I.E. "__not_mangled_either__") */
2751 return iterate_demangle_function (work, mangled, declp, scan);
2754 else if (*(scan + 2) != '\0')
2756 /* Mangled name does not start with "__" but does have one somewhere
2757 in there with non empty stuff after it. Looks like a global
2758 function name. Iterate over all "__":s until the right
2760 return iterate_demangle_function (work, mangled, declp, scan);
2764 /* Doesn't look like a mangled name */
2768 if (!success && (work->constructor == 2 || work->destructor == 2))
2770 string_append (declp, *mangled);
2771 *mangled += strlen (*mangled);
2781 gnu_special -- special handling of gnu mangled strings
2786 gnu_special (struct work_stuff *work, const char **mangled,
2792 Process some special GNU style mangling forms that don't fit
2793 the normal pattern. For example:
2795 _$_3foo (destructor for class foo)
2796 _vt$foo (foo virtual table)
2797 _vt$foo$bar (foo::bar virtual table)
2798 __vt_foo (foo virtual table, new style with thunks)
2799 _3foo$varname (static data member)
2800 _Q22rs2tu$vw (static data member)
2801 __t6vector1Zii (constructor with template)
2802 __thunk_4__$_7ostream (virtual function thunk)
2806 gnu_special (struct work_stuff *work, const char **mangled, string *declp)
2812 if ((*mangled)[0] == '_'
2813 && strchr (cplus_markers, (*mangled)[1]) != NULL
2814 && (*mangled)[2] == '_')
2816 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2818 work -> destructor += 1;
2820 else if ((*mangled)[0] == '_'
2821 && (((*mangled)[1] == '_'
2822 && (*mangled)[2] == 'v'
2823 && (*mangled)[3] == 't'
2824 && (*mangled)[4] == '_')
2825 || ((*mangled)[1] == 'v'
2826 && (*mangled)[2] == 't'
2827 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2829 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2830 and create the decl. Note that we consume the entire mangled
2831 input string, which means that demangle_signature has no work
2833 if ((*mangled)[2] == 'v')
2834 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2836 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2837 while (**mangled != '\0')
2843 success = demangle_qualified (work, mangled, declp, 0, 1);
2846 success = demangle_template (work, mangled, declp, 0, 1,
2850 if (ISDIGIT((unsigned char)*mangled[0]))
2852 n = consume_count(mangled);
2853 /* We may be seeing a too-large size, or else a
2854 ".<digits>" indicating a static local symbol. In
2855 any case, declare victory and move on; *don't* try
2856 to use n to allocate. */
2857 if (n > (int) strlen (*mangled))
2865 n = strcspn (*mangled, cplus_markers);
2867 string_appendn (declp, *mangled, n);
2871 p = strpbrk (*mangled, cplus_markers);
2872 if (success && ((p == NULL) || (p == *mangled)))
2876 string_append (declp, SCOPE_STRING (work));
2887 string_append (declp, " virtual table");
2889 else if ((*mangled)[0] == '_'
2890 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2891 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2893 /* static data member, "_3foo$varname" for example */
2899 success = demangle_qualified (work, mangled, declp, 0, 1);
2902 success = demangle_template (work, mangled, declp, 0, 1, 1);
2905 n = consume_count (mangled);
2906 if (n < 0 || n > (long) strlen (*mangled))
2912 if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2913 && (*mangled)[9] == 'N'
2914 && (*mangled)[8] == (*mangled)[10]
2915 && strchr (cplus_markers, (*mangled)[8]))
2917 /* A member of the anonymous namespace. There's information
2918 about what identifier or filename it was keyed to, but
2919 it's just there to make the mangled name unique; we just
2921 string_append (declp, "{anonymous}");
2924 /* Now p points to the marker before the N, so we need to
2925 update it to the first marker after what we consumed. */
2926 p = strpbrk (*mangled, cplus_markers);
2930 string_appendn (declp, *mangled, n);
2933 if (success && (p == *mangled))
2935 /* Consumed everything up to the cplus_marker, append the
2938 string_append (declp, SCOPE_STRING (work));
2939 n = strlen (*mangled);
2940 string_appendn (declp, *mangled, n);
2948 else if (strncmp (*mangled, "__thunk_", 8) == 0)
2953 delta = consume_count (mangled);
2958 char *method = internal_cplus_demangle (work, ++*mangled);
2963 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
2964 string_append (declp, buf);
2965 string_append (declp, method);
2967 n = strlen (*mangled);
2976 else if (strncmp (*mangled, "__t", 3) == 0
2977 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
2979 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
2985 success = demangle_qualified (work, mangled, declp, 0, 1);
2988 success = demangle_template (work, mangled, declp, 0, 1, 1);
2991 success = do_type (work, mangled, declp);
2994 if (success && **mangled != '\0')
2997 string_append (declp, p);
3007 recursively_demangle(struct work_stuff *work, const char **mangled,
3008 string *result, int namelength)
3010 char * recurse = (char *)NULL;
3011 char * recurse_dem = (char *)NULL;
3013 recurse = XNEWVEC (char, namelength + 1);
3014 memcpy (recurse, *mangled, namelength);
3015 recurse[namelength] = '\000';
3017 recurse_dem = ML_(cplus_demangle) (recurse, work->options);
3021 string_append (result, recurse_dem);
3026 string_appendn (result, *mangled, namelength);
3029 *mangled += namelength;
3036 arm_special -- special handling of ARM/lucid mangled strings
3041 arm_special (const char **mangled,
3047 Process some special ARM style mangling forms that don't fit
3048 the normal pattern. For example:
3050 __vtbl__3foo (foo virtual table)
3051 __vtbl__3foo__3bar (bar::foo virtual table)
3056 arm_special (const char **mangled, string *declp)
3062 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3064 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3065 and create the decl. Note that we consume the entire mangled
3066 input string, which means that demangle_signature has no work
3068 scan = *mangled + ARM_VTABLE_STRLEN;
3069 while (*scan != '\0') /* first check it can be demangled */
3071 n = consume_count (&scan);
3074 return (0); /* no good */
3077 if (scan[0] == '_' && scan[1] == '_')
3082 (*mangled) += ARM_VTABLE_STRLEN;
3083 while (**mangled != '\0')
3085 n = consume_count (mangled);
3087 || n > (long) strlen (*mangled))
3089 string_prependn (declp, *mangled, n);
3091 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3093 string_prepend (declp, "::");
3097 string_append (declp, " virtual table");
3110 demangle_qualified -- demangle 'Q' qualified name strings
3115 demangle_qualified (struct work_stuff *, const char *mangled,
3116 string *result, int isfuncname, int append);
3120 Demangle a qualified name, such as "Q25Outer5Inner" which is
3121 the mangled form of "Outer::Inner". The demangled output is
3122 prepended or appended to the result string according to the
3123 state of the append flag.
3125 If isfuncname is nonzero, then the qualified name we are building
3126 is going to be used as a member function name, so if it is a
3127 constructor or destructor function, append an appropriate
3128 constructor or destructor name. I.E. for the above example,
3129 the result for use as a constructor is "Outer::Inner::Inner"
3130 and the result for use as a destructor is "Outer::Inner::~Inner".
3134 Numeric conversion is ASCII dependent (FIXME).
3139 demangle_qualified (struct work_stuff *work, const char **mangled,
3140 string *result, int isfuncname, int append)
3147 int bindex = register_Btype (work);
3149 /* We only make use of ISFUNCNAME if the entity is a constructor or
3151 isfuncname = (isfuncname
3152 && ((work->constructor & 1) || (work->destructor & 1)));
3154 string_init (&temp);
3155 string_init (&last_name);
3157 if ((*mangled)[0] == 'K')
3159 /* Squangling qualified name reuse */
3162 idx = consume_count_with_underscores (mangled);
3163 if (idx == -1 || idx >= work -> numk)
3166 string_append (&temp, work -> ktypevec[idx]);
3169 switch ((*mangled)[1])
3172 /* GNU mangled name with more than 9 classes. The count is preceded
3173 by an underscore (to distinguish it from the <= 9 case) and followed
3174 by an underscore. */
3176 qualifiers = consume_count_with_underscores (mangled);
3177 if (qualifiers == -1)
3190 /* The count is in a single digit. */
3191 num[0] = (*mangled)[1];
3193 qualifiers = atoi (num);
3195 /* If there is an underscore after the digit, skip it. This is
3196 said to be for ARM-qualified names, but the ARM makes no
3197 mention of such an underscore. Perhaps cfront uses one. */
3198 if ((*mangled)[2] == '_')
3213 /* Pick off the names and collect them in the temp buffer in the order
3214 in which they are found, separated by '::'. */
3216 while (qualifiers-- > 0)
3219 string_clear (&last_name);
3221 if (*mangled[0] == '_')
3224 if (*mangled[0] == 't')
3226 /* Here we always append to TEMP since we will want to use
3227 the template name without the template parameters as a
3228 constructor or destructor name. The appropriate
3229 (parameter-less) value is returned by demangle_template
3230 in LAST_NAME. We do not remember the template type here,
3231 in order to match the G++ mangling algorithm. */
3232 success = demangle_template(work, mangled, &temp,
3237 else if (*mangled[0] == 'K')
3241 idx = consume_count_with_underscores (mangled);
3242 if (idx == -1 || idx >= work->numk)
3245 string_append (&temp, work->ktypevec[idx]);
3248 if (!success) break;
3255 /* Now recursively demangle the qualifier
3256 * This is necessary to deal with templates in
3257 * mangling styles like EDG */
3258 namelength = consume_count (mangled);
3259 if (namelength == -1)
3264 recursively_demangle(work, mangled, &temp, namelength);
3268 string_delete (&last_name);
3269 success = do_type (work, mangled, &last_name);
3272 string_appends (&temp, &last_name);
3277 remember_Ktype (work, temp.b, LEN_STRING (&temp));
3280 string_append (&temp, SCOPE_STRING (work));
3283 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3285 /* If we are using the result as a function name, we need to append
3286 the appropriate '::' separated constructor or destructor name.
3287 We do this here because this is the most convenient place, where
3288 we already have a pointer to the name and the length of the name. */
3292 string_append (&temp, SCOPE_STRING (work));
3293 if (work -> destructor & 1)
3294 string_append (&temp, "~");
3295 string_appends (&temp, &last_name);
3298 /* Now either prepend the temp buffer to the result, or append it,
3299 depending upon the state of the append flag. */
3302 string_appends (result, &temp);
3305 if (!STRING_EMPTY (result))
3306 string_append (&temp, SCOPE_STRING (work));
3307 string_prepends (result, &temp);
3310 string_delete (&last_name);
3311 string_delete (&temp);
3319 get_count -- convert an ascii count to integer, consuming tokens
3324 get_count (const char **type, int *count)
3328 Assume that *type points at a count in a mangled name; set
3329 *count to its value, and set *type to the next character after
3330 the count. There are some weird rules in effect here.
3332 If *type does not point at a string of digits, return zero.
3334 If *type points at a string of digits followed by an
3335 underscore, set *count to their value as an integer, advance
3336 *type to point *after the underscore, and return 1.
3338 If *type points at a string of digits not followed by an
3339 underscore, consume only the first digit. Set *count to its
3340 value as an integer, leave *type pointing after that digit,
3343 The excuse for this odd behavior: in the ARM and HP demangling
3344 styles, a type can be followed by a repeat count of the form
3347 `x' is a single digit specifying how many additional copies
3348 of the type to append to the argument list, and
3350 `y' is one or more digits, specifying the zero-based index of
3351 the first repeated argument in the list. Yes, as you're
3352 unmangling the name you can figure this out yourself, but
3355 So, for example, in `bar__3fooFPiN51', the first argument is a
3356 pointer to an integer (`Pi'), and then the next five arguments
3357 are the same (`N5'), and the first repeat is the function's
3358 second argument (`1').
3362 get_count (const char **type, int *count)
3367 if (!ISDIGIT ((unsigned char)**type))
3371 *count = **type - '0';
3373 if (ISDIGIT ((unsigned char)**type))
3383 while (ISDIGIT ((unsigned char)*p));
3394 /* RESULT will be initialised here; it will be freed on failure. The
3395 value returned is really a type_kind_t. */
3398 do_type (struct work_stuff *work, const char **mangled, string *result)
3404 const char *remembered_type;
3406 type_kind_t tk = tk_none;
3408 string_init (&decl);
3409 string_init (result);
3413 while (success && !done)
3419 /* A pointer type */
3423 if (! (work -> options & DMGL_JAVA))
3424 string_prepend (&decl, "*");
3429 /* A reference type */
3432 string_prepend (&decl, "&");
3441 if (!STRING_EMPTY (&decl)
3442 && (decl.b[0] == '*' || decl.b[0] == '&'))
3444 string_prepend (&decl, "(");
3445 string_append (&decl, ")");
3447 string_append (&decl, "[");
3448 if (**mangled != '_')
3449 success = demangle_template_value_parm (work, mangled, &decl,
3451 if (**mangled == '_')
3453 string_append (&decl, "]");
3457 /* A back reference to a previously seen type */
3460 if (!get_count (mangled, &n) || n >= work -> ntypes)
3466 remembered_type = work -> typevec[n];
3467 mangled = &remembered_type;
3474 if (!STRING_EMPTY (&decl)
3475 && (decl.b[0] == '*' || decl.b[0] == '&'))
3477 string_prepend (&decl, "(");
3478 string_append (&decl, ")");
3480 /* After picking off the function args, we expect to either find the
3481 function return type (preceded by an '_') or the end of the
3483 if (!demangle_nested_args (work, mangled, &decl)
3484 || (**mangled != '_' && **mangled != '\0'))
3489 if (success && (**mangled == '_'))
3496 type_quals = TYPE_UNQUALIFIED;
3498 member = **mangled == 'M';
3501 string_append (&decl, ")");
3503 /* We don't need to prepend `::' for a qualified name;
3504 demangle_qualified will do that for us. */
3505 if (**mangled != 'Q')
3506 string_prepend (&decl, SCOPE_STRING (work));
3508 if (ISDIGIT ((unsigned char)**mangled))
3510 n = consume_count (mangled);
3512 || (int) strlen (*mangled) < n)
3517 string_prependn (&decl, *mangled, n);
3520 else if (**mangled == 'X' || **mangled == 'Y')
3523 do_type (work, mangled, &temp);
3524 string_prepends (&decl, &temp);
3525 string_delete (&temp);
3527 else if (**mangled == 't')
3530 string_init (&temp);
3531 success = demangle_template (work, mangled, &temp,
3535 string_prependn (&decl, temp.b, temp.p - temp.b);
3536 string_delete (&temp);
3541 else if (**mangled == 'Q')
3543 success = demangle_qualified (work, mangled, &decl,
3555 string_prepend (&decl, "(");
3563 type_quals |= code_for_qualifier (**mangled);
3571 if (*(*mangled)++ != 'F')
3577 if ((member && !demangle_nested_args (work, mangled, &decl))
3578 || **mangled != '_')
3584 if (! PRINT_ANSI_QUALIFIERS)
3588 if (type_quals != TYPE_UNQUALIFIED)
3590 APPEND_BLANK (&decl);
3591 string_append (&decl, qualifier_string (type_quals));
3602 if (PRINT_ANSI_QUALIFIERS)
3604 if (!STRING_EMPTY (&decl))
3605 string_prepend (&decl, " ");
3607 string_prepend (&decl, demangle_qualifier (**mangled));
3622 if (success) switch (**mangled)
3624 /* A qualified name, such as "Outer::Inner". */
3628 success = demangle_qualified (work, mangled, result, 0, 1);
3632 /* A back reference to a previously seen squangled type */
3635 if (!get_count (mangled, &n) || n >= work -> numb)
3638 string_append (result, work->btypevec[n]);
3643 /* A template parm. We substitute the corresponding argument. */
3648 idx = consume_count_with_underscores (mangled);
3651 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3652 || consume_count_with_underscores (mangled) == -1)
3658 if (work->tmpl_argvec)
3659 string_append (result, work->tmpl_argvec[idx]);
3661 string_append_template_idx (result, idx);
3668 success = demangle_fund_type (work, mangled, result);
3670 tk = (type_kind_t) success;
3676 if (!STRING_EMPTY (&decl))
3678 string_append (result, " ");
3679 string_appends (result, &decl);
3683 string_delete (result);
3684 string_delete (&decl);
3687 /* Assume an integral type, if we're not sure. */
3688 return (int) ((tk == tk_none) ? tk_integral : tk);
3693 /* Given a pointer to a type string that represents a fundamental type
3694 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3695 string in which the demangled output is being built in RESULT, and
3696 the WORK structure, decode the types and add them to the result.
3701 "Sl" => "signed long"
3702 "CUs" => "const unsigned short"
3704 The value returned is really a type_kind_t. */
3707 demangle_fund_type (struct work_stuff *work,
3708 const char **mangled, string *result)
3712 char buf[INTBUF_SIZE + 5 /* 'int%u_t' */];
3713 /* unsigned int dec = 0; */ /* JRS 2008-Oct-26: unused (see below) */
3714 type_kind_t tk = tk_integral;
3716 /* First pick off any type qualifiers. There can be more than one. */
3725 if (PRINT_ANSI_QUALIFIERS)
3727 if (!STRING_EMPTY (result))
3728 string_prepend (result, " ");
3729 string_prepend (result, demangle_qualifier (**mangled));
3735 APPEND_BLANK (result);
3736 string_append (result, "unsigned");
3738 case 'S': /* signed char only */
3740 APPEND_BLANK (result);
3741 string_append (result, "signed");
3745 APPEND_BLANK (result);
3746 string_append (result, "__complex");
3754 /* Now pick off the fundamental type. There can be only one. */
3763 APPEND_BLANK (result);
3764 string_append (result, "void");
3768 APPEND_BLANK (result);
3769 string_append (result, "long long");
3773 APPEND_BLANK (result);
3774 string_append (result, "long");
3778 APPEND_BLANK (result);
3779 string_append (result, "int");
3783 APPEND_BLANK (result);
3784 string_append (result, "short");
3788 APPEND_BLANK (result);
3789 string_append (result, "bool");
3794 APPEND_BLANK (result);
3795 string_append (result, "char");
3800 APPEND_BLANK (result);
3801 string_append (result, "wchar_t");
3806 APPEND_BLANK (result);
3807 string_append (result, "long double");
3812 APPEND_BLANK (result);
3813 string_append (result, "double");
3818 APPEND_BLANK (result);
3819 string_append (result, "float");
3824 if (!ISDIGIT ((unsigned char)**mangled))
3831 if (**mangled == '_')
3836 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3839 if (**mangled != '_')
3849 strncpy (buf, *mangled, 2);
3851 *mangled += min (strlen (*mangled), 2);
3853 /* JRS 2008-Oct-26: the next two commented out lines have been
3854 replaced by the sprintf that follows. This is to avoid use
3855 of sscanf. This hack is merely copied from the old demangler
3856 port (by Michael Matz, Simon Hausmann?) -- I have no idea if
3857 it is really correct/safe, but it looks ok. */
3858 /*sscanf (buf, "%x", &dec);
3859 sprintf (buf, "int%u_t", dec);*/
3860 sprintf (buf, "%s", "intXX_t");
3861 /* end JRS 2008-Oct-26 */
3862 APPEND_BLANK (result);
3863 string_append (result, buf);
3867 /* An explicit type, such as "6mytype" or "7integer" */
3879 int bindex = register_Btype (work);
3881 string_init (&btype);
3882 if (demangle_class_name (work, mangled, &btype)) {
3883 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3884 APPEND_BLANK (result);
3885 string_appends (result, &btype);
3889 string_delete (&btype);
3895 string_init (&btype);
3896 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3897 string_appends (result, &btype);
3898 string_delete (&btype);
3906 return success ? ((int) tk) : 0;
3910 /* Handle a template's value parameter for HP aCC (extension from ARM)
3911 **mangled points to 'S' or 'U' */
3914 do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED,
3915 const char **mangled, string *result)
3919 if (**mangled != 'U' && **mangled != 'S')
3922 unsigned_const = (**mangled == 'U');
3929 string_append (result, "-");
3935 /* special case for -2^31 */
3936 string_append (result, "-2147483648");
3943 /* We have to be looking at an integer now */
3944 if (!(ISDIGIT ((unsigned char)**mangled)))
3947 /* We only deal with integral values for template
3948 parameters -- so it's OK to look only for digits */
3949 while (ISDIGIT ((unsigned char)**mangled))
3951 char_str[0] = **mangled;
3952 string_append (result, char_str);
3957 string_append (result, "U");
3959 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3960 with L or LL suffixes. pai/1997-09-03 */
3962 return 1; /* success */
3965 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3966 **mangled is pointing to the 'A' */
3969 do_hpacc_template_literal (struct work_stuff *work, const char **mangled,
3972 int literal_len = 0;
3976 if (**mangled != 'A')
3981 literal_len = consume_count (mangled);
3983 if (literal_len <= 0)
3986 /* Literal parameters are names of arrays, functions, etc. and the
3987 canonical representation uses the address operator */
3988 string_append (result, "&");
3990 /* Now recursively demangle the literal name */
3991 recurse = XNEWVEC (char, literal_len + 1);
3992 memcpy (recurse, *mangled, literal_len);
3993 recurse[literal_len] = '\000';
3995 recurse_dem = ML_(cplus_demangle) (recurse, work->options);
3999 string_append (result, recurse_dem);
4004 string_appendn (result, *mangled, literal_len);
4006 (*mangled) += literal_len;
4013 snarf_numeric_literal (const char **args, string *arg)
4018 string_append (arg, char_str);
4021 else if (**args == '+')
4024 if (!ISDIGIT ((unsigned char)**args))
4027 while (ISDIGIT ((unsigned char)**args))
4029 char_str[0] = **args;
4030 string_append (arg, char_str);
4037 /* Demangle the next argument, given by MANGLED into RESULT, which
4038 *should be an uninitialized* string. It will be initialized here,
4039 and free'd should anything go wrong. */
4042 do_arg (struct work_stuff *work, const char **mangled, string *result)
4044 /* Remember where we started so that we can record the type, for
4045 non-squangling type remembering. */
4046 const char *start = *mangled;
4048 string_init (result);
4050 if (work->nrepeats > 0)
4054 if (work->previous_argument == 0)
4057 /* We want to reissue the previous type in this argument list. */
4058 string_appends (result, work->previous_argument);
4062 if (**mangled == 'n')
4064 /* A squangling-style repeat. */
4066 work->nrepeats = consume_count(mangled);
4068 if (work->nrepeats <= 0)
4069 /* This was not a repeat count after all. */
4072 if (work->nrepeats > 9)
4074 if (**mangled != '_')
4075 /* The repeat count should be followed by an '_' in this
4082 /* Now, the repeat is all set up. */
4083 return do_arg (work, mangled, result);
4086 /* Save the result in WORK->previous_argument so that we can find it
4087 if it's repeated. Note that saving START is not good enough: we
4088 do not want to add additional types to the back-referenceable
4089 type vector when processing a repeated type. */
4090 if (work->previous_argument)
4091 string_delete (work->previous_argument);
4093 work->previous_argument = XNEW (string);
4095 if (!do_type (work, mangled, work->previous_argument))
4098 string_appends (result, work->previous_argument);
4100 remember_type (work, start, *mangled - start);
4105 remember_type (struct work_stuff *work, const char *start, int len)
4109 if (work->forgetting_types)
4112 if (work -> ntypes >= work -> typevec_size)
4114 if (work -> typevec_size == 0)
4116 work -> typevec_size = 3;
4117 work -> typevec = XNEWVEC (char *, work->typevec_size);
4121 work -> typevec_size *= 2;
4123 = XRESIZEVEC (char *, work->typevec, work->typevec_size);
4126 tem = XNEWVEC (char, len + 1);
4127 memcpy (tem, start, len);
4129 work -> typevec[work -> ntypes++] = tem;
4133 /* Remember a K type class qualifier. */
4135 remember_Ktype (struct work_stuff *work, const char *start, int len)
4139 if (work -> numk >= work -> ksize)
4141 if (work -> ksize == 0)
4144 work -> ktypevec = XNEWVEC (char *, work->ksize);
4150 = XRESIZEVEC (char *, work->ktypevec, work->ksize);
4153 tem = XNEWVEC (char, len + 1);
4154 memcpy (tem, start, len);
4156 work -> ktypevec[work -> numk++] = tem;
4159 /* Register a B code, and get an index for it. B codes are registered
4160 as they are seen, rather than as they are completed, so map<temp<char> >
4161 registers map<temp<char> > as B0, and temp<char> as B1 */
4164 register_Btype (struct work_stuff *work)
4168 if (work -> numb >= work -> bsize)
4170 if (work -> bsize == 0)
4173 work -> btypevec = XNEWVEC (char *, work->bsize);
4179 = XRESIZEVEC (char *, work->btypevec, work->bsize);
4182 ret = work -> numb++;
4183 work -> btypevec[ret] = NULL;
4187 /* Store a value into a previously registered B code type. */
4190 remember_Btype (struct work_stuff *work, const char *start,
4195 tem = XNEWVEC (char, len + 1);
4196 memcpy (tem, start, len);
4198 work -> btypevec[indx] = tem;
4201 /* Lose all the info related to B and K type codes. */
4203 forget_B_and_K_types (struct work_stuff *work)
4207 while (work -> numk > 0)
4209 i = --(work -> numk);
4210 if (work -> ktypevec[i] != NULL)
4212 free (work -> ktypevec[i]);
4213 work -> ktypevec[i] = NULL;
4217 while (work -> numb > 0)
4219 i = --(work -> numb);
4220 if (work -> btypevec[i] != NULL)
4222 free (work -> btypevec[i]);
4223 work -> btypevec[i] = NULL;
4227 /* Forget the remembered types, but not the type vector itself. */
4230 forget_types (struct work_stuff *work)
4234 while (work -> ntypes > 0)
4236 i = --(work -> ntypes);
4237 if (work -> typevec[i] != NULL)
4239 free (work -> typevec[i]);
4240 work -> typevec[i] = NULL;
4245 /* Process the argument list part of the signature, after any class spec
4246 has been consumed, as well as the first 'F' character (if any). For
4249 "__als__3fooRT0" => process "RT0"
4250 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4252 DECLP must be already initialised, usually non-empty. It won't be freed
4255 Note that g++ differs significantly from ARM and lucid style mangling
4256 with regards to references to previously seen types. For example, given
4257 the source fragment:
4261 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4264 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4265 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4267 g++ produces the names:
4272 while lcc (and presumably other ARM style compilers as well) produces:
4274 foo__FiR3fooT1T2T1T2
4275 __ct__3fooFiR3fooT1T2T1T2
4277 Note that g++ bases its type numbers starting at zero and counts all
4278 previously seen types, while lucid/ARM bases its type numbers starting
4279 at one and only considers types after it has seen the 'F' character
4280 indicating the start of the function args. For lucid/ARM style, we
4281 account for this difference by discarding any previously seen types when
4282 we see the 'F' character, and subtracting one from the type number
4288 demangle_args (struct work_stuff *work, const char **mangled,
4298 if (PRINT_ARG_TYPES)
4300 string_append (declp, "(");
4301 if (**mangled == '\0')
4303 string_append (declp, "void");
4307 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4308 || work->nrepeats > 0)
4310 if ((**mangled == 'N') || (**mangled == 'T'))
4312 temptype = *(*mangled)++;
4314 if (temptype == 'N')
4316 if (!get_count (mangled, &r))
4325 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4327 /* If we have 10 or more types we might have more than a 1 digit
4328 index so we'll have to consume the whole count here. This
4329 will lose if the next thing is a type name preceded by a
4330 count but it's impossible to demangle that case properly
4331 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4332 Pc, ...)" or "(..., type12, char *, ...)" */
4333 if ((t = consume_count(mangled)) <= 0)
4340 if (!get_count (mangled, &t))
4345 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4349 /* Validate the type index. Protect against illegal indices from
4350 malformed type strings. */
4351 if ((t < 0) || (t >= work -> ntypes))
4355 while (work->nrepeats > 0 || --r >= 0)
4357 tem = work -> typevec[t];
4358 if (need_comma && PRINT_ARG_TYPES)
4360 string_append (declp, ", ");
4362 if (!do_arg (work, &tem, &arg))
4366 if (PRINT_ARG_TYPES)
4368 string_appends (declp, &arg);
4370 string_delete (&arg);
4376 if (need_comma && PRINT_ARG_TYPES)
4377 string_append (declp, ", ");
4378 if (!do_arg (work, mangled, &arg))
4380 if (PRINT_ARG_TYPES)
4381 string_appends (declp, &arg);
4382 string_delete (&arg);
4387 if (**mangled == 'e')
4390 if (PRINT_ARG_TYPES)
4394 string_append (declp, ",");
4396 string_append (declp, "...");
4400 if (PRINT_ARG_TYPES)
4402 string_append (declp, ")");
4407 /* Like demangle_args, but for demangling the argument lists of function
4408 and method pointers or references, not top-level declarations. */
4411 demangle_nested_args (struct work_stuff *work, const char **mangled,
4414 string* saved_previous_argument;
4418 /* The G++ name-mangling algorithm does not remember types on nested
4419 argument lists, unless -fsquangling is used, and in that case the
4420 type vector updated by remember_type is not used. So, we turn
4421 off remembering of types here. */
4422 ++work->forgetting_types;
4424 /* For the repeat codes used with -fsquangling, we must keep track of
4425 the last argument. */
4426 saved_previous_argument = work->previous_argument;
4427 saved_nrepeats = work->nrepeats;
4428 work->previous_argument = 0;
4431 /* Actually demangle the arguments. */
4432 result = demangle_args (work, mangled, declp);
4434 /* Restore the previous_argument field. */
4435 if (work->previous_argument)
4437 string_delete (work->previous_argument);
4438 free ((char *) work->previous_argument);
4440 work->previous_argument = saved_previous_argument;
4441 --work->forgetting_types;
4442 work->nrepeats = saved_nrepeats;
4447 /* Returns 1 if a valid function name was found or 0 otherwise. */
4450 demangle_function_name (struct work_stuff *work, const char **mangled,
4451 string *declp, const char *scan)
4457 string_appendn (declp, (*mangled), scan - (*mangled));
4458 string_need (declp, 1);
4459 *(declp -> p) = '\0';
4461 /* Consume the function name, including the "__" separating the name
4462 from the signature. We are guaranteed that SCAN points to the
4465 (*mangled) = scan + 2;
4466 /* We may be looking at an instantiation of a template function:
4467 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4468 following _F marks the start of the function arguments. Handle
4469 the template arguments first. */
4471 if (HP_DEMANGLING && (**mangled == 'X'))
4473 demangle_arm_hp_template (work, mangled, 0, declp);
4474 /* This leaves MANGLED pointing to the 'F' marking func args */
4477 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4480 /* See if we have an ARM style constructor or destructor operator.
4481 If so, then just record it, clear the decl, and return.
4482 We can't build the actual constructor/destructor decl until later,
4483 when we recover the class name from the signature. */
4485 if (strcmp (declp -> b, "__ct") == 0)
4487 work -> constructor += 1;
4488 string_clear (declp);
4491 else if (strcmp (declp -> b, "__dt") == 0)
4493 work -> destructor += 1;
4494 string_clear (declp);
4499 if (declp->p - declp->b >= 3
4500 && declp->b[0] == 'o'
4501 && declp->b[1] == 'p'
4502 && strchr (cplus_markers, declp->b[2]) != NULL)
4504 /* see if it's an assignment expression */
4505 if (declp->p - declp->b >= 10 /* op$assign_ */
4506 && memcmp (declp->b + 3, "assign_", 7) == 0)
4508 for (i = 0; i < ARRAY_SIZE (optable); i++)
4510 int len = declp->p - declp->b - 10;
4511 if ((int) strlen (optable[i].in) == len
4512 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4514 string_clear (declp);
4515 string_append (declp, "operator");
4516 string_append (declp, optable[i].out);
4517 string_append (declp, "=");
4524 for (i = 0; i < ARRAY_SIZE (optable); i++)
4526 int len = declp->p - declp->b - 3;
4527 if ((int) strlen (optable[i].in) == len
4528 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4530 string_clear (declp);
4531 string_append (declp, "operator");
4532 string_append (declp, optable[i].out);
4538 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4539 && strchr (cplus_markers, declp->b[4]) != NULL)
4541 /* type conversion operator */
4543 if (do_type (work, &tem, &type))
4545 string_clear (declp);
4546 string_append (declp, "operator ");
4547 string_appends (declp, &type);
4548 string_delete (&type);
4551 else if (declp->b[0] == '_' && declp->b[1] == '_'
4552 && declp->b[2] == 'o' && declp->b[3] == 'p')
4555 /* type conversion operator. */
4557 if (do_type (work, &tem, &type))
4559 string_clear (declp);
4560 string_append (declp, "operator ");
4561 string_appends (declp, &type);
4562 string_delete (&type);
4565 else if (declp->b[0] == '_' && declp->b[1] == '_'
4566 && ISLOWER((unsigned char)declp->b[2])
4567 && ISLOWER((unsigned char)declp->b[3]))
4569 if (declp->b[4] == '\0')
4572 for (i = 0; i < ARRAY_SIZE (optable); i++)
4574 if (strlen (optable[i].in) == 2
4575 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4577 string_clear (declp);
4578 string_append (declp, "operator");
4579 string_append (declp, optable[i].out);
4585 /* BEGIN hack inserted 20050403 by JRS to deal with apparently
4586 non-cfront compliant new[]/delete[] manglings generated by
4587 the Portland Group's C++ compiler. */
4589 if (strcmp (declp -> b, "__nwa") == 0) {
4590 string_clear (declp);
4591 string_append (declp, "operator new[]");
4594 if (strcmp (declp -> b, "__dla") == 0) {
4595 string_clear (declp);
4596 string_append (declp, "operator delete[]");
4602 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4605 for (i = 0; i < ARRAY_SIZE (optable); i++)
4607 if (strlen (optable[i].in) == 3
4608 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4610 string_clear (declp);
4611 string_append (declp, "operator");
4612 string_append (declp, optable[i].out);
4620 /* If a function name was obtained but it's not valid, we were not
4622 if (LEN_STRING (declp) == 1 && declp->b[0] == '.')
4628 /* a mini string-handling package */
4631 string_need (string *s, int n)
4641 s->p = s->b = XNEWVEC (char, n);
4644 else if (s->e - s->p < n)
4649 s->b = XRESIZEVEC (char, s->b, n);
4656 string_delete (string *s)
4661 s->b = s->e = s->p = NULL;
4666 string_init (string *s)
4668 s->b = s->p = s->e = NULL;
4672 string_clear (string *s)
4680 string_empty (string *s)
4682 return (s->b == s->p);
4688 string_append (string *p, const char *s)
4691 if (s == NULL || *s == '\0')
4695 memcpy (p->p, s, n);
4700 string_appends (string *p, string *s)
4708 memcpy (p->p, s->b, n);
4714 string_appendn (string *p, const char *s, int n)
4719 memcpy (p->p, s, n);
4725 string_prepend (string *p, const char *s)
4727 if (s != NULL && *s != '\0')
4729 string_prependn (p, s, strlen (s));
4734 string_prepends (string *p, string *s)
4738 string_prependn (p, s->b, s->p - s->b);
4743 string_prependn (string *p, const char *s, int n)
4750 for (q = p->p - 1; q >= p->b; q--)
4754 memcpy (p->b, s, n);
4760 string_append_template_idx (string *s, int idx)
4762 char buf[INTBUF_SIZE + 1 /* 'T' */];
4763 sprintf(buf, "T%d", idx);
4764 string_append (s, buf);