1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001 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., 59 Temple Place - Suite 330,
31 Boston, MA 02111-1307, 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. */
46 #include "safe-ctype.h"
48 #include <sys/types.h>
60 #undef CURRENT_DEMANGLING_STYLE
61 #define CURRENT_DEMANGLING_STYLE work->options
63 #include "libiberty.h"
65 static char *ada_demangle PARAMS ((const char *, int));
67 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
69 /* A value at least one greater than the maximum number of characters
70 that will be output when using the `%d' format with `printf'. */
71 #define INTBUF_SIZE 32
73 extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
75 /* In order to allow a single demangler executable to demangle strings
76 using various common values of CPLUS_MARKER, as well as any specific
77 one set at compile time, we maintain a string containing all the
78 commonly used ones, and check to see if the marker we are looking for
79 is in that string. CPLUS_MARKER is usually '$' on systems where the
80 assembler can deal with that. Where the assembler can't, it's usually
81 '.' (but on many systems '.' is used for other things). We put the
82 current defined CPLUS_MARKER first (which defaults to '$'), followed
83 by the next most common value, followed by an explicit '$' in case
84 the value of CPLUS_MARKER is not '$'.
86 We could avoid this if we could just get g++ to tell us what the actual
87 cplus marker character is as part of the debug information, perhaps by
88 ensuring that it is the character that terminates the gcc<n>_compiled
89 marker symbol (FIXME). */
91 #if !defined (CPLUS_MARKER)
92 #define CPLUS_MARKER '$'
95 enum demangling_styles current_demangling_style = auto_demangling;
97 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
99 static char char_str[2] = { '\000', '\000' };
102 set_cplus_marker_for_demangling (ch)
105 cplus_markers[0] = ch;
108 typedef struct string /* Beware: these aren't required to be */
109 { /* '\0' terminated. */
110 char *b; /* pointer to start of string */
111 char *p; /* pointer after last character */
112 char *e; /* pointer after end of allocated space */
115 /* Stuff that is shared between sub-routines.
116 Using a shared structure allows cplus_demangle to be reentrant. */
132 int static_type; /* A static member function */
133 int temp_start; /* index in demangled to start of template args */
134 int type_quals; /* The type qualifiers. */
135 int dllimported; /* Symbol imported from a PE DLL */
136 char **tmpl_argvec; /* Template function arguments. */
137 int ntmpl_args; /* The number of template function arguments. */
138 int forgetting_types; /* Nonzero if we are not remembering the types
140 string* previous_argument; /* The last function argument demangled. */
141 int nrepeats; /* The number of times to repeat the previous
145 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
146 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
148 static const struct optable
150 const char *const in;
151 const char *const out;
154 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
155 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
156 {"new", " new", 0}, /* old (1.91, and 1.x) */
157 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
158 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
159 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
160 {"as", "=", DMGL_ANSI}, /* ansi */
161 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
162 {"eq", "==", DMGL_ANSI}, /* old, ansi */
163 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
164 {"gt", ">", DMGL_ANSI}, /* old, ansi */
165 {"le", "<=", DMGL_ANSI}, /* old, ansi */
166 {"lt", "<", DMGL_ANSI}, /* old, ansi */
167 {"plus", "+", 0}, /* old */
168 {"pl", "+", DMGL_ANSI}, /* ansi */
169 {"apl", "+=", DMGL_ANSI}, /* ansi */
170 {"minus", "-", 0}, /* old */
171 {"mi", "-", DMGL_ANSI}, /* ansi */
172 {"ami", "-=", DMGL_ANSI}, /* ansi */
173 {"mult", "*", 0}, /* old */
174 {"ml", "*", DMGL_ANSI}, /* ansi */
175 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
176 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
177 {"convert", "+", 0}, /* old (unary +) */
178 {"negate", "-", 0}, /* old (unary -) */
179 {"trunc_mod", "%", 0}, /* old */
180 {"md", "%", DMGL_ANSI}, /* ansi */
181 {"amd", "%=", DMGL_ANSI}, /* ansi */
182 {"trunc_div", "/", 0}, /* old */
183 {"dv", "/", DMGL_ANSI}, /* ansi */
184 {"adv", "/=", DMGL_ANSI}, /* ansi */
185 {"truth_andif", "&&", 0}, /* old */
186 {"aa", "&&", DMGL_ANSI}, /* ansi */
187 {"truth_orif", "||", 0}, /* old */
188 {"oo", "||", DMGL_ANSI}, /* ansi */
189 {"truth_not", "!", 0}, /* old */
190 {"nt", "!", DMGL_ANSI}, /* ansi */
191 {"postincrement","++", 0}, /* old */
192 {"pp", "++", DMGL_ANSI}, /* ansi */
193 {"postdecrement","--", 0}, /* old */
194 {"mm", "--", DMGL_ANSI}, /* ansi */
195 {"bit_ior", "|", 0}, /* old */
196 {"or", "|", DMGL_ANSI}, /* ansi */
197 {"aor", "|=", DMGL_ANSI}, /* ansi */
198 {"bit_xor", "^", 0}, /* old */
199 {"er", "^", DMGL_ANSI}, /* ansi */
200 {"aer", "^=", DMGL_ANSI}, /* ansi */
201 {"bit_and", "&", 0}, /* old */
202 {"ad", "&", DMGL_ANSI}, /* ansi */
203 {"aad", "&=", DMGL_ANSI}, /* ansi */
204 {"bit_not", "~", 0}, /* old */
205 {"co", "~", DMGL_ANSI}, /* ansi */
206 {"call", "()", 0}, /* old */
207 {"cl", "()", DMGL_ANSI}, /* ansi */
208 {"alshift", "<<", 0}, /* old */
209 {"ls", "<<", DMGL_ANSI}, /* ansi */
210 {"als", "<<=", DMGL_ANSI}, /* ansi */
211 {"arshift", ">>", 0}, /* old */
212 {"rs", ">>", DMGL_ANSI}, /* ansi */
213 {"ars", ">>=", DMGL_ANSI}, /* ansi */
214 {"component", "->", 0}, /* old */
215 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
216 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
217 {"indirect", "*", 0}, /* old */
218 {"method_call", "->()", 0}, /* old */
219 {"addr", "&", 0}, /* old (unary &) */
220 {"array", "[]", 0}, /* old */
221 {"vc", "[]", DMGL_ANSI}, /* ansi */
222 {"compound", ", ", 0}, /* old */
223 {"cm", ", ", DMGL_ANSI}, /* ansi */
224 {"cond", "?:", 0}, /* old */
225 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
226 {"max", ">?", 0}, /* old */
227 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
228 {"min", "<?", 0}, /* old */
229 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
230 {"nop", "", 0}, /* old (for operator=) */
231 {"rm", "->*", DMGL_ANSI}, /* ansi */
232 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
235 /* These values are used to indicate the various type varieties.
236 They are all non-zero so that they can be used as `success'
238 typedef enum type_kind_t
249 const struct demangler_engine libiberty_demanglers[] =
252 NO_DEMANGLING_STYLE_STRING,
254 "Demangling disabled"
258 AUTO_DEMANGLING_STYLE_STRING,
260 "Automatic selection based on executable"
264 GNU_DEMANGLING_STYLE_STRING,
266 "GNU (g++) style demangling"
270 LUCID_DEMANGLING_STYLE_STRING,
272 "Lucid (lcc) style demangling"
276 ARM_DEMANGLING_STYLE_STRING,
278 "ARM style demangling"
282 HP_DEMANGLING_STYLE_STRING,
284 "HP (aCC) style demangling"
288 EDG_DEMANGLING_STYLE_STRING,
290 "EDG style demangling"
294 GNU_V3_DEMANGLING_STYLE_STRING,
296 "GNU (g++) V3 ABI-style demangling"
300 JAVA_DEMANGLING_STYLE_STRING,
302 "Java style demangling"
306 GNAT_DEMANGLING_STYLE_STRING,
308 "GNAT style demangling"
312 NULL, unknown_demangling, NULL
316 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
317 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
318 string_append(str, " ");}
319 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
321 /* The scope separator appropriate for the language being demangled. */
323 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
325 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
326 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
328 /* Prototypes for local functions */
331 delete_work_stuff PARAMS ((struct work_stuff *));
334 delete_non_B_K_work_stuff PARAMS ((struct work_stuff *));
337 mop_up PARAMS ((struct work_stuff *, string *, int));
340 squangle_mop_up PARAMS ((struct work_stuff *));
343 work_stuff_copy_to_from PARAMS ((struct work_stuff *, struct work_stuff *));
347 demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
351 internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
354 demangle_template_template_parm PARAMS ((struct work_stuff *work,
355 const char **, string *));
358 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
359 string *, int, int));
362 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
366 demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
369 demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
373 demangle_class PARAMS ((struct work_stuff *, const char **, string *));
376 demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
379 demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
382 demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
385 gnu_special PARAMS ((struct work_stuff *, const char **, string *));
388 arm_special PARAMS ((const char **, string *));
391 string_need PARAMS ((string *, int));
394 string_delete PARAMS ((string *));
397 string_init PARAMS ((string *));
400 string_clear PARAMS ((string *));
404 string_empty PARAMS ((string *));
408 string_append PARAMS ((string *, const char *));
411 string_appends PARAMS ((string *, string *));
414 string_appendn PARAMS ((string *, const char *, int));
417 string_prepend PARAMS ((string *, const char *));
420 string_prependn PARAMS ((string *, const char *, int));
423 string_append_template_idx PARAMS ((string *, int));
426 get_count PARAMS ((const char **, int *));
429 consume_count PARAMS ((const char **));
432 consume_count_with_underscores PARAMS ((const char**));
435 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
438 demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
441 do_type PARAMS ((struct work_stuff *, const char **, string *));
444 do_arg PARAMS ((struct work_stuff *, const char **, string *));
447 demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
451 iterate_demangle_function PARAMS ((struct work_stuff *,
452 const char **, string *, const char *));
455 remember_type PARAMS ((struct work_stuff *, const char *, int));
458 remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
461 register_Btype PARAMS ((struct work_stuff *));
464 remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
467 forget_types PARAMS ((struct work_stuff *));
470 forget_B_and_K_types PARAMS ((struct work_stuff *));
473 string_prepends PARAMS ((string *, string *));
476 demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
477 string*, type_kind_t));
480 do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
483 do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
486 snarf_numeric_literal PARAMS ((const char **, string *));
488 /* There is a TYPE_QUAL value for each type qualifier. They can be
489 combined by bitwise-or to form the complete set of qualifiers for a
492 #define TYPE_UNQUALIFIED 0x0
493 #define TYPE_QUAL_CONST 0x1
494 #define TYPE_QUAL_VOLATILE 0x2
495 #define TYPE_QUAL_RESTRICT 0x4
498 code_for_qualifier PARAMS ((int));
501 qualifier_string PARAMS ((int));
504 demangle_qualifier PARAMS ((int));
507 demangle_expression PARAMS ((struct work_stuff *, const char **, string *,
511 demangle_integral_value PARAMS ((struct work_stuff *, const char **,
515 demangle_real_value PARAMS ((struct work_stuff *, const char **, string *));
518 demangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int,
522 recursively_demangle PARAMS ((struct work_stuff *, const char **, string *,
526 grow_vect PARAMS ((char **, size_t *, size_t, int));
528 /* Translate count to integer, consuming tokens in the process.
529 Conversion terminates on the first non-digit character.
531 Trying to consume something that isn't a count results in no
532 consumption of input and a return of -1.
534 Overflow consumes the rest of the digits, and returns -1. */
542 if (! ISDIGIT ((unsigned char)**type))
545 while (ISDIGIT ((unsigned char)**type))
549 /* Check for overflow.
550 We assume that count is represented using two's-complement;
551 no power of two is divisible by ten, so if an overflow occurs
552 when multiplying by ten, the result will not be a multiple of
554 if ((count % 10) != 0)
556 while (ISDIGIT ((unsigned char) **type))
561 count += **type - '0';
572 /* Like consume_count, but for counts that are preceded and followed
573 by '_' if they are greater than 10. Also, -1 is returned for
574 failure, since 0 can be a valid value. */
577 consume_count_with_underscores (mangled)
578 const char **mangled;
582 if (**mangled == '_')
585 if (!ISDIGIT ((unsigned char)**mangled))
588 idx = consume_count (mangled);
589 if (**mangled != '_')
590 /* The trailing underscore was missing. */
597 if (**mangled < '0' || **mangled > '9')
600 idx = **mangled - '0';
607 /* C is the code for a type-qualifier. Return the TYPE_QUAL
608 corresponding to this qualifier. */
611 code_for_qualifier (c)
617 return TYPE_QUAL_CONST;
620 return TYPE_QUAL_VOLATILE;
623 return TYPE_QUAL_RESTRICT;
629 /* C was an invalid qualifier. */
633 /* Return the string corresponding to the qualifiers given by
637 qualifier_string (type_quals)
642 case TYPE_UNQUALIFIED:
645 case TYPE_QUAL_CONST:
648 case TYPE_QUAL_VOLATILE:
651 case TYPE_QUAL_RESTRICT:
654 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
655 return "const volatile";
657 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
658 return "const __restrict";
660 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
661 return "volatile __restrict";
663 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
664 return "const volatile __restrict";
670 /* TYPE_QUALS was an invalid qualifier set. */
674 /* C is the code for a type-qualifier. Return the string
675 corresponding to this qualifier. This function should only be
676 called with a valid qualifier code. */
679 demangle_qualifier (c)
682 return qualifier_string (code_for_qualifier (c));
686 cplus_demangle_opname (opname, result, options)
693 struct work_stuff work[1];
696 len = strlen(opname);
699 memset ((char *) work, 0, sizeof (work));
700 work->options = options;
702 if (opname[0] == '_' && opname[1] == '_'
703 && opname[2] == 'o' && opname[3] == 'p')
706 /* type conversion operator. */
708 if (do_type (work, &tem, &type))
710 strcat (result, "operator ");
711 strncat (result, type.b, type.p - type.b);
712 string_delete (&type);
716 else if (opname[0] == '_' && opname[1] == '_'
717 && ISLOWER((unsigned char)opname[2])
718 && ISLOWER((unsigned char)opname[3]))
720 if (opname[4] == '\0')
724 for (i = 0; i < ARRAY_SIZE (optable); i++)
726 if (strlen (optable[i].in) == 2
727 && memcmp (optable[i].in, opname + 2, 2) == 0)
729 strcat (result, "operator");
730 strcat (result, optable[i].out);
738 if (opname[2] == 'a' && opname[5] == '\0')
742 for (i = 0; i < ARRAY_SIZE (optable); i++)
744 if (strlen (optable[i].in) == 3
745 && memcmp (optable[i].in, opname + 2, 3) == 0)
747 strcat (result, "operator");
748 strcat (result, optable[i].out);
759 && strchr (cplus_markers, opname[2]) != NULL)
761 /* see if it's an assignment expression */
762 if (len >= 10 /* op$assign_ */
763 && memcmp (opname + 3, "assign_", 7) == 0)
766 for (i = 0; i < ARRAY_SIZE (optable); i++)
769 if ((int) strlen (optable[i].in) == len1
770 && memcmp (optable[i].in, opname + 10, len1) == 0)
772 strcat (result, "operator");
773 strcat (result, optable[i].out);
774 strcat (result, "=");
783 for (i = 0; i < ARRAY_SIZE (optable); i++)
786 if ((int) strlen (optable[i].in) == len1
787 && memcmp (optable[i].in, opname + 3, len1) == 0)
789 strcat (result, "operator");
790 strcat (result, optable[i].out);
797 else if (len >= 5 && memcmp (opname, "type", 4) == 0
798 && strchr (cplus_markers, opname[4]) != NULL)
800 /* type conversion operator */
802 if (do_type (work, &tem, &type))
804 strcat (result, "operator ");
805 strncat (result, type.b, type.p - type.b);
806 string_delete (&type);
810 squangle_mop_up (work);
815 /* Takes operator name as e.g. "++" and returns mangled
816 operator name (e.g. "postincrement_expr"), or NULL if not found.
818 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
819 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
822 cplus_mangle_opname (opname, options)
829 len = strlen (opname);
830 for (i = 0; i < ARRAY_SIZE (optable); i++)
832 if ((int) strlen (optable[i].out) == len
833 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
834 && memcmp (optable[i].out, opname, len) == 0)
835 return optable[i].in;
840 /* Add a routine to set the demangling style to be sure it is valid and
841 allow for any demangler initialization that maybe necessary. */
843 enum demangling_styles
844 cplus_demangle_set_style (style)
845 enum demangling_styles style;
847 const struct demangler_engine *demangler = libiberty_demanglers;
849 for (; demangler->demangling_style != unknown_demangling; ++demangler)
850 if (style == demangler->demangling_style)
852 current_demangling_style = style;
853 return current_demangling_style;
856 return unknown_demangling;
859 /* Do string name to style translation */
861 enum demangling_styles
862 cplus_demangle_name_to_style (name)
865 const struct demangler_engine *demangler = libiberty_demanglers;
867 for (; demangler->demangling_style != unknown_demangling; ++demangler)
868 if (strcmp (name, demangler->demangling_style_name) == 0)
869 return demangler->demangling_style;
871 return unknown_demangling;
874 /* char *cplus_demangle (const char *mangled, int options)
876 If MANGLED is a mangled function name produced by GNU C++, then
877 a pointer to a @code{malloc}ed string giving a C++ representation
878 of the name will be returned; otherwise NULL will be returned.
879 It is the caller's responsibility to free the string which
882 The OPTIONS arg may contain one or more of the following bits:
884 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
886 DMGL_PARAMS Function parameters are included.
890 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
891 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
892 cplus_demangle ("foo__1Ai", 0) => "A::foo"
894 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
895 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
896 cplus_demangle ("foo__1Afe", 0) => "A::foo"
898 Note that any leading underscores, or other such characters prepended by
899 the compilation system, are presumed to have already been stripped from
903 cplus_demangle (mangled, options)
908 struct work_stuff work[1];
910 if (current_demangling_style == no_demangling)
911 return xstrdup (mangled);
913 memset ((char *) work, 0, sizeof (work));
914 work->options = options;
915 if ((work->options & DMGL_STYLE_MASK) == 0)
916 work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
918 /* The V3 ABI demangling is implemented elsewhere. */
919 if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
921 ret = cplus_demangle_v3 (mangled, work->options);
922 if (ret || GNU_V3_DEMANGLING)
928 ret = java_demangle_v3 (mangled);
934 return ada_demangle(mangled,options);
936 ret = internal_cplus_demangle (work, mangled);
937 squangle_mop_up (work);
942 /* Assuming *OLD_VECT points to an array of *SIZE objects of size
943 ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
944 updating *OLD_VECT and *SIZE as necessary. */
947 grow_vect (old_vect, size, min_size, element_size)
953 if (*size < min_size)
956 if (*size < min_size)
958 *old_vect = (void *) xrealloc (*old_vect, *size * element_size);
962 /* Demangle ada names:
963 1. Discard final __{DIGIT}+ or ${DIGIT}+
964 2. Convert other instances of embedded "__" to `.'.
965 3. Discard leading _ada_.
966 4. Remove everything after first ___ if it is followed by 'X'.
967 5. Put symbols that should be suppressed in <...> brackets.
968 The resulting string is valid until the next call of ada_demangle. */
971 ada_demangle (mangled, option)
973 int option ATTRIBUTE_UNUSED;
978 char *demangled = NULL;
981 size_t demangled_size = 0;
985 if (strncmp (mangled, "_ada_", 5) == 0)
991 if (mangled[0] == '_' || mangled[0] == '<')
994 p = strstr (mangled, "___");
996 len0 = strlen (mangled);
1008 /* Make demangled big enough for possible expansion by operator name. */
1009 grow_vect (&demangled,
1010 &demangled_size, 2 * len0 + 1,
1013 if (ISDIGIT ((unsigned char) mangled[len0 - 1])) {
1014 for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1)
1016 if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_')
1021 else if (mangled[i] == '$')
1028 for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]);
1030 demangled[j] = mangled[i];
1037 if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_')
1040 changed = at_start_name = 1;
1045 demangled[j] = mangled[i];
1049 demangled[j] = '\000';
1051 for (i = 0; demangled[i] != '\0'; i += 1)
1052 if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ')
1061 grow_vect (&demangled,
1062 &demangled_size, strlen (mangled) + 3,
1065 if (mangled[0] == '<')
1066 strcpy (demangled, mangled);
1068 sprintf (demangled, "<%s>", mangled);
1073 /* This function performs most of what cplus_demangle use to do, but
1074 to be able to demangle a name with a B, K or n code, we need to
1075 have a longer term memory of what types have been seen. The original
1076 now initializes and cleans up the squangle code info, while internal
1077 calls go directly to this routine to avoid resetting that info. */
1080 internal_cplus_demangle (work, mangled)
1081 struct work_stuff *work;
1082 const char *mangled;
1087 char *demangled = NULL;
1089 s1 = work->constructor;
1090 s2 = work->destructor;
1091 s3 = work->static_type;
1092 s4 = work->type_quals;
1093 work->constructor = work->destructor = 0;
1094 work->type_quals = TYPE_UNQUALIFIED;
1095 work->dllimported = 0;
1097 if ((mangled != NULL) && (*mangled != '\0'))
1099 string_init (&decl);
1101 /* First check to see if gnu style demangling is active and if the
1102 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1103 recognize one of the gnu special forms rather than looking for a
1104 standard prefix. In particular, don't worry about whether there
1105 is a "__" string in the mangled string. Consider "_$_5__foo" for
1108 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
1110 success = gnu_special (work, &mangled, &decl);
1114 success = demangle_prefix (work, &mangled, &decl);
1116 if (success && (*mangled != '\0'))
1118 success = demangle_signature (work, &mangled, &decl);
1120 if (work->constructor == 2)
1122 string_prepend (&decl, "global constructors keyed to ");
1123 work->constructor = 0;
1125 else if (work->destructor == 2)
1127 string_prepend (&decl, "global destructors keyed to ");
1128 work->destructor = 0;
1130 else if (work->dllimported == 1)
1132 string_prepend (&decl, "import stub for ");
1133 work->dllimported = 0;
1135 demangled = mop_up (work, &decl, success);
1137 work->constructor = s1;
1138 work->destructor = s2;
1139 work->static_type = s3;
1140 work->type_quals = s4;
1145 /* Clear out and squangling related storage */
1147 squangle_mop_up (work)
1148 struct work_stuff *work;
1150 /* clean up the B and K type mangling types. */
1151 forget_B_and_K_types (work);
1152 if (work -> btypevec != NULL)
1154 free ((char *) work -> btypevec);
1156 if (work -> ktypevec != NULL)
1158 free ((char *) work -> ktypevec);
1163 /* Copy the work state and storage. */
1166 work_stuff_copy_to_from (to, from)
1167 struct work_stuff *to;
1168 struct work_stuff *from;
1172 delete_work_stuff (to);
1174 /* Shallow-copy scalars. */
1175 memcpy (to, from, sizeof (*to));
1177 /* Deep-copy dynamic storage. */
1178 if (from->typevec_size)
1180 = (char **) xmalloc (from->typevec_size * sizeof (to->typevec[0]));
1182 for (i = 0; i < from->ntypes; i++)
1184 int len = strlen (from->typevec[i]) + 1;
1186 to->typevec[i] = xmalloc (len);
1187 memcpy (to->typevec[i], from->typevec[i], len);
1192 = (char **) xmalloc (from->ksize * sizeof (to->ktypevec[0]));
1194 for (i = 0; i < from->numk; i++)
1196 int len = strlen (from->ktypevec[i]) + 1;
1198 to->ktypevec[i] = xmalloc (len);
1199 memcpy (to->ktypevec[i], from->ktypevec[i], len);
1204 = (char **) xmalloc (from->bsize * sizeof (to->btypevec[0]));
1206 for (i = 0; i < from->numb; i++)
1208 int len = strlen (from->btypevec[i]) + 1;
1210 to->btypevec[i] = xmalloc (len);
1211 memcpy (to->btypevec[i], from->btypevec[i], len);
1214 if (from->ntmpl_args)
1216 = (char **) xmalloc (from->ntmpl_args * sizeof (to->tmpl_argvec[0]));
1218 for (i = 0; i < from->ntmpl_args; i++)
1220 int len = strlen (from->tmpl_argvec[i]) + 1;
1222 to->tmpl_argvec[i] = xmalloc (len);
1223 memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len);
1226 if (from->previous_argument)
1228 to->previous_argument = (string*) xmalloc (sizeof (string));
1229 string_init (to->previous_argument);
1230 string_appends (to->previous_argument, from->previous_argument);
1235 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1238 delete_non_B_K_work_stuff (work)
1239 struct work_stuff *work;
1241 /* Discard the remembered types, if any. */
1243 forget_types (work);
1244 if (work -> typevec != NULL)
1246 free ((char *) work -> typevec);
1247 work -> typevec = NULL;
1248 work -> typevec_size = 0;
1250 if (work->tmpl_argvec)
1254 for (i = 0; i < work->ntmpl_args; i++)
1255 if (work->tmpl_argvec[i])
1256 free ((char*) work->tmpl_argvec[i]);
1258 free ((char*) work->tmpl_argvec);
1259 work->tmpl_argvec = NULL;
1261 if (work->previous_argument)
1263 string_delete (work->previous_argument);
1264 free ((char*) work->previous_argument);
1265 work->previous_argument = NULL;
1270 /* Delete all dynamic storage in work_stuff. */
1272 delete_work_stuff (work)
1273 struct work_stuff *work;
1275 delete_non_B_K_work_stuff (work);
1276 squangle_mop_up (work);
1280 /* Clear out any mangled storage */
1283 mop_up (work, declp, success)
1284 struct work_stuff *work;
1288 char *demangled = NULL;
1290 delete_non_B_K_work_stuff (work);
1292 /* If demangling was successful, ensure that the demangled string is null
1293 terminated and return it. Otherwise, free the demangling decl. */
1297 string_delete (declp);
1301 string_appendn (declp, "", 1);
1302 demangled = declp->b;
1311 demangle_signature -- demangle the signature part of a mangled name
1316 demangle_signature (struct work_stuff *work, const char **mangled,
1321 Consume and demangle the signature portion of the mangled name.
1323 DECLP is the string where demangled output is being built. At
1324 entry it contains the demangled root name from the mangled name
1325 prefix. I.E. either a demangled operator name or the root function
1326 name. In some special cases, it may contain nothing.
1328 *MANGLED points to the current unconsumed location in the mangled
1329 name. As tokens are consumed and demangling is performed, the
1330 pointer is updated to continuously point at the next token to
1333 Demangling GNU style mangled names is nasty because there is no
1334 explicit token that marks the start of the outermost function
1338 demangle_signature (work, mangled, declp)
1339 struct work_stuff *work;
1340 const char **mangled;
1345 int expect_func = 0;
1346 int expect_return_type = 0;
1347 const char *oldmangled = NULL;
1351 while (success && (**mangled != '\0'))
1356 oldmangled = *mangled;
1357 success = demangle_qualified (work, mangled, declp, 1, 0);
1359 remember_type (work, oldmangled, *mangled - oldmangled);
1360 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1366 oldmangled = *mangled;
1367 success = demangle_qualified (work, mangled, declp, 1, 0);
1368 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1376 /* Static member function */
1377 if (oldmangled == NULL)
1379 oldmangled = *mangled;
1382 work -> static_type = 1;
1388 work->type_quals |= code_for_qualifier (**mangled);
1390 /* a qualified member function */
1391 if (oldmangled == NULL)
1392 oldmangled = *mangled;
1397 /* Local class name follows after "Lnnn_" */
1400 while (**mangled && (**mangled != '_'))
1411 case '0': case '1': case '2': case '3': case '4':
1412 case '5': case '6': case '7': case '8': case '9':
1413 if (oldmangled == NULL)
1415 oldmangled = *mangled;
1417 work->temp_start = -1; /* uppermost call to demangle_class */
1418 success = demangle_class (work, mangled, declp);
1421 remember_type (work, oldmangled, *mangled - oldmangled);
1423 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1425 /* EDG and others will have the "F", so we let the loop cycle
1426 if we are looking at one. */
1427 if (**mangled != 'F')
1436 success = do_type (work, mangled, &s);
1439 string_append (&s, SCOPE_STRING (work));
1440 string_prepends (declp, &s);
1450 /* ARM/HP style demangling includes a specific 'F' character after
1451 the class name. For GNU style, it is just implied. So we can
1452 safely just consume any 'F' at this point and be compatible
1453 with either style. */
1459 /* For lucid/ARM/HP style we have to forget any types we might
1460 have remembered up to this point, since they were not argument
1461 types. GNU style considers all types seen as available for
1462 back references. See comment in demangle_args() */
1464 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1466 forget_types (work);
1468 success = demangle_args (work, mangled, declp);
1469 /* After picking off the function args, we expect to either
1470 find the function return type (preceded by an '_') or the
1471 end of the string. */
1472 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1475 /* At this level, we do not care about the return type. */
1476 success = do_type (work, mangled, &tname);
1477 string_delete (&tname);
1484 string_init(&trawname);
1485 string_init(&tname);
1486 if (oldmangled == NULL)
1488 oldmangled = *mangled;
1490 success = demangle_template (work, mangled, &tname,
1494 remember_type (work, oldmangled, *mangled - oldmangled);
1496 string_append (&tname, SCOPE_STRING (work));
1498 string_prepends(declp, &tname);
1499 if (work -> destructor & 1)
1501 string_prepend (&trawname, "~");
1502 string_appends (declp, &trawname);
1503 work->destructor -= 1;
1505 if ((work->constructor & 1) || (work->destructor & 1))
1507 string_appends (declp, &trawname);
1508 work->constructor -= 1;
1510 string_delete(&trawname);
1511 string_delete(&tname);
1517 if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
1519 /* Read the return type. */
1523 success = do_type (work, mangled, &return_type);
1524 APPEND_BLANK (&return_type);
1526 string_prepends (declp, &return_type);
1527 string_delete (&return_type);
1531 /* At the outermost level, we cannot have a return type specified,
1532 so if we run into another '_' at this point we are dealing with
1533 a mangled name that is either bogus, or has been mangled by
1534 some algorithm we don't know how to deal with. So just
1535 reject the entire demangling. */
1536 /* However, "_nnn" is an expected suffix for alternate entry point
1537 numbered nnn for a function, with HP aCC, so skip over that
1538 without reporting failure. pai/1997-09-04 */
1542 while (**mangled && ISDIGIT ((unsigned char)**mangled))
1550 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1552 /* A G++ template function. Read the template arguments. */
1553 success = demangle_template (work, mangled, declp, 0, 0,
1555 if (!(work->constructor & 1))
1556 expect_return_type = 1;
1565 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1567 /* Assume we have stumbled onto the first outermost function
1568 argument token, and start processing args. */
1570 success = demangle_args (work, mangled, declp);
1574 /* Non-GNU demanglers use a specific token to mark the start
1575 of the outermost function argument tokens. Typically 'F',
1576 for ARM/HP-demangling, for example. So if we find something
1577 we are not prepared for, it must be an error. */
1583 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1586 if (success && expect_func)
1589 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1591 forget_types (work);
1593 success = demangle_args (work, mangled, declp);
1594 /* Since template include the mangling of their return types,
1595 we must set expect_func to 0 so that we don't try do
1596 demangle more arguments the next time we get here. */
1601 if (success && !func_done)
1603 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1605 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1606 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1607 first case, and need to ensure that the '(void)' gets added to
1608 the current declp. Note that with ARM/HP, the first case
1609 represents the name of a static data member 'foo::bar',
1610 which is in the current declp, so we leave it alone. */
1611 success = demangle_args (work, mangled, declp);
1614 if (success && PRINT_ARG_TYPES)
1616 if (work->static_type)
1617 string_append (declp, " static");
1618 if (work->type_quals != TYPE_UNQUALIFIED)
1620 APPEND_BLANK (declp);
1621 string_append (declp, qualifier_string (work->type_quals));
1631 demangle_method_args (work, mangled, declp)
1632 struct work_stuff *work;
1633 const char **mangled;
1638 if (work -> static_type)
1640 string_append (declp, *mangled + 1);
1641 *mangled += strlen (*mangled);
1646 success = demangle_args (work, mangled, declp);
1654 demangle_template_template_parm (work, mangled, tname)
1655 struct work_stuff *work;
1656 const char **mangled;
1665 string_append (tname, "template <");
1666 /* get size of template parameter list */
1667 if (get_count (mangled, &r))
1669 for (i = 0; i < r; i++)
1673 string_append (tname, ", ");
1676 /* Z for type parameters */
1677 if (**mangled == 'Z')
1680 string_append (tname, "class");
1682 /* z for template parameters */
1683 else if (**mangled == 'z')
1687 demangle_template_template_parm (work, mangled, tname);
1695 /* temp is initialized in do_type */
1696 success = do_type (work, mangled, &temp);
1699 string_appends (tname, &temp);
1701 string_delete(&temp);
1711 if (tname->p[-1] == '>')
1712 string_append (tname, " ");
1713 string_append (tname, "> class");
1718 demangle_expression (work, mangled, s, tk)
1719 struct work_stuff *work;
1720 const char** mangled;
1724 int need_operator = 0;
1728 string_appendn (s, "(", 1);
1730 while (success && **mangled != 'W' && **mangled != '\0')
1739 len = strlen (*mangled);
1741 for (i = 0; i < ARRAY_SIZE (optable); ++i)
1743 size_t l = strlen (optable[i].in);
1746 && memcmp (optable[i].in, *mangled, l) == 0)
1748 string_appendn (s, " ", 1);
1749 string_append (s, optable[i].out);
1750 string_appendn (s, " ", 1);
1763 success = demangle_template_value_parm (work, mangled, s, tk);
1766 if (**mangled != 'W')
1770 string_appendn (s, ")", 1);
1778 demangle_integral_value (work, mangled, s)
1779 struct work_stuff *work;
1780 const char** mangled;
1785 if (**mangled == 'E')
1786 success = demangle_expression (work, mangled, s, tk_integral);
1787 else if (**mangled == 'Q' || **mangled == 'K')
1788 success = demangle_qualified (work, mangled, s, 0, 1);
1793 /* By default, we let the number decide whether we shall consume an
1795 int multidigit_without_leading_underscore = 0;
1796 int leave_following_underscore = 0;
1800 /* Negative numbers are indicated with a leading `m'. */
1801 if (**mangled == 'm')
1803 string_appendn (s, "-", 1);
1806 else if (mangled[0][0] == '_' && mangled[0][1] == 'm')
1808 /* Since consume_count_with_underscores does not handle the
1809 `m'-prefix we must do it here, using consume_count and
1810 adjusting underscores: we have to consume the underscore
1811 matching the prepended one. */
1812 multidigit_without_leading_underscore = 1;
1813 string_appendn (s, "-", 1);
1816 else if (**mangled == '_')
1818 /* Do not consume a following underscore;
1819 multidigit_without_leading_underscore will consume what should be
1821 leave_following_underscore = 1;
1825 /* Since consume_count_with_underscores does not handle
1826 multi-digit numbers that do not start with an underscore,
1827 and this number can be an integer template parameter,
1828 we have to call consume_count. */
1829 multidigit_without_leading_underscore = 1;
1830 /* These multi-digit numbers never end on an underscore,
1831 so if there is one then don't eat it. */
1832 leave_following_underscore = 1;
1835 /* We must call consume_count if we expect to remove a trailing
1836 underscore, since consume_count_with_underscores expects
1837 the leading underscore (that we consumed) if it is to handle
1838 multi-digit numbers. */
1839 if (multidigit_without_leading_underscore)
1840 value = consume_count (mangled);
1842 value = consume_count_with_underscores (mangled);
1846 char buf[INTBUF_SIZE];
1847 sprintf (buf, "%d", value);
1848 string_append (s, buf);
1850 /* Numbers not otherwise delimited, might have an underscore
1851 appended as a delimeter, which we should skip.
1853 ??? This used to always remove a following underscore, which
1854 is wrong. If other (arbitrary) cases are followed by an
1855 underscore, we need to do something more radical. */
1857 if ((value > 9 || multidigit_without_leading_underscore)
1858 && ! leave_following_underscore
1859 && **mangled == '_')
1870 /* Demangle the real value in MANGLED. */
1873 demangle_real_value (work, mangled, s)
1874 struct work_stuff *work;
1875 const char **mangled;
1878 if (**mangled == 'E')
1879 return demangle_expression (work, mangled, s, tk_real);
1881 if (**mangled == 'm')
1883 string_appendn (s, "-", 1);
1886 while (ISDIGIT ((unsigned char)**mangled))
1888 string_appendn (s, *mangled, 1);
1891 if (**mangled == '.') /* fraction */
1893 string_appendn (s, ".", 1);
1895 while (ISDIGIT ((unsigned char)**mangled))
1897 string_appendn (s, *mangled, 1);
1901 if (**mangled == 'e') /* exponent */
1903 string_appendn (s, "e", 1);
1905 while (ISDIGIT ((unsigned char)**mangled))
1907 string_appendn (s, *mangled, 1);
1916 demangle_template_value_parm (work, mangled, s, tk)
1917 struct work_stuff *work;
1918 const char **mangled;
1924 if (**mangled == 'Y')
1926 /* The next argument is a template parameter. */
1930 idx = consume_count_with_underscores (mangled);
1932 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1933 || consume_count_with_underscores (mangled) == -1)
1935 if (work->tmpl_argvec)
1936 string_append (s, work->tmpl_argvec[idx]);
1938 string_append_template_idx (s, idx);
1940 else if (tk == tk_integral)
1941 success = demangle_integral_value (work, mangled, s);
1942 else if (tk == tk_char)
1946 if (**mangled == 'm')
1948 string_appendn (s, "-", 1);
1951 string_appendn (s, "'", 1);
1952 val = consume_count(mangled);
1959 string_appendn (s, &tmp[0], 1);
1960 string_appendn (s, "'", 1);
1963 else if (tk == tk_bool)
1965 int val = consume_count (mangled);
1967 string_appendn (s, "false", 5);
1969 string_appendn (s, "true", 4);
1973 else if (tk == tk_real)
1974 success = demangle_real_value (work, mangled, s);
1975 else if (tk == tk_pointer || tk == tk_reference)
1977 if (**mangled == 'Q')
1978 success = demangle_qualified (work, mangled, s,
1983 int symbol_len = consume_count (mangled);
1984 if (symbol_len == -1)
1986 if (symbol_len == 0)
1987 string_appendn (s, "0", 1);
1990 char *p = xmalloc (symbol_len + 1), *q;
1991 strncpy (p, *mangled, symbol_len);
1992 p [symbol_len] = '\0';
1993 /* We use cplus_demangle here, rather than
1994 internal_cplus_demangle, because the name of the entity
1995 mangled here does not make use of any of the squangling
1996 or type-code information we have built up thus far; it is
1997 mangled independently. */
1998 q = cplus_demangle (p, work->options);
1999 if (tk == tk_pointer)
2000 string_appendn (s, "&", 1);
2001 /* FIXME: Pointer-to-member constants should get a
2002 qualifying class name here. */
2005 string_append (s, q);
2009 string_append (s, p);
2012 *mangled += symbol_len;
2019 /* Demangle the template name in MANGLED. The full name of the
2020 template (e.g., S<int>) is placed in TNAME. The name without the
2021 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2022 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2023 not a function template. If both IS_TYPE and REMEMBER are nonzero,
2024 the template is remembered in the list of back-referenceable
2028 demangle_template (work, mangled, tname, trawname, is_type, remember)
2029 struct work_stuff *work;
2030 const char **mangled;
2041 int is_java_array = 0;
2049 bindex = register_Btype (work);
2051 /* get template name */
2052 if (**mangled == 'z')
2058 idx = consume_count_with_underscores (mangled);
2060 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2061 || consume_count_with_underscores (mangled) == -1)
2064 if (work->tmpl_argvec)
2066 string_append (tname, work->tmpl_argvec[idx]);
2068 string_append (trawname, work->tmpl_argvec[idx]);
2072 string_append_template_idx (tname, idx);
2074 string_append_template_idx (trawname, idx);
2079 if ((r = consume_count (mangled)) <= 0
2080 || (int) strlen (*mangled) < r)
2084 is_java_array = (work -> options & DMGL_JAVA)
2085 && strncmp (*mangled, "JArray1Z", 8) == 0;
2086 if (! is_java_array)
2088 string_appendn (tname, *mangled, r);
2091 string_appendn (trawname, *mangled, r);
2096 string_append (tname, "<");
2097 /* get size of template parameter list */
2098 if (!get_count (mangled, &r))
2104 /* Create an array for saving the template argument values. */
2105 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
2106 work->ntmpl_args = r;
2107 for (i = 0; i < r; i++)
2108 work->tmpl_argvec[i] = 0;
2110 for (i = 0; i < r; i++)
2114 string_append (tname, ", ");
2116 /* Z for type parameters */
2117 if (**mangled == 'Z')
2120 /* temp is initialized in do_type */
2121 success = do_type (work, mangled, &temp);
2124 string_appends (tname, &temp);
2128 /* Save the template argument. */
2129 int len = temp.p - temp.b;
2130 work->tmpl_argvec[i] = xmalloc (len + 1);
2131 memcpy (work->tmpl_argvec[i], temp.b, len);
2132 work->tmpl_argvec[i][len] = '\0';
2135 string_delete(&temp);
2141 /* z for template parameters */
2142 else if (**mangled == 'z')
2146 success = demangle_template_template_parm (work, mangled, tname);
2149 && (r2 = consume_count (mangled)) > 0
2150 && (int) strlen (*mangled) >= r2)
2152 string_append (tname, " ");
2153 string_appendn (tname, *mangled, r2);
2156 /* Save the template argument. */
2158 work->tmpl_argvec[i] = xmalloc (len + 1);
2159 memcpy (work->tmpl_argvec[i], *mangled, len);
2160 work->tmpl_argvec[i][len] = '\0';
2174 /* otherwise, value parameter */
2176 /* temp is initialized in do_type */
2177 success = do_type (work, mangled, &temp);
2178 string_delete(&temp);
2190 success = demangle_template_value_parm (work, mangled, s,
2191 (type_kind_t) success);
2203 int len = s->p - s->b;
2204 work->tmpl_argvec[i] = xmalloc (len + 1);
2205 memcpy (work->tmpl_argvec[i], s->b, len);
2206 work->tmpl_argvec[i][len] = '\0';
2208 string_appends (tname, s);
2216 string_append (tname, "[]");
2220 if (tname->p[-1] == '>')
2221 string_append (tname, " ");
2222 string_append (tname, ">");
2225 if (is_type && remember)
2226 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
2229 if (work -> static_type)
2231 string_append (declp, *mangled + 1);
2232 *mangled += strlen (*mangled);
2237 success = demangle_args (work, mangled, declp);
2245 arm_pt (work, mangled, n, anchor, args)
2246 struct work_stuff *work;
2247 const char *mangled;
2249 const char **anchor, **args;
2251 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2252 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2253 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__")))
2256 *args = *anchor + 6;
2257 len = consume_count (args);
2260 if (*args + len == mangled + n && **args == '_')
2266 if (AUTO_DEMANGLING || EDG_DEMANGLING)
2268 if ((*anchor = strstr (mangled, "__tm__"))
2269 || (*anchor = strstr (mangled, "__ps__"))
2270 || (*anchor = strstr (mangled, "__pt__")))
2273 *args = *anchor + 6;
2274 len = consume_count (args);
2277 if (*args + len == mangled + n && **args == '_')
2283 else if ((*anchor = strstr (mangled, "__S")))
2286 *args = *anchor + 3;
2287 len = consume_count (args);
2290 if (*args + len == mangled + n && **args == '_')
2302 demangle_arm_hp_template (work, mangled, n, declp)
2303 struct work_stuff *work;
2304 const char **mangled;
2310 const char *e = *mangled + n;
2313 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2315 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
2317 char *start_spec_args = NULL;
2319 /* First check for and omit template specialization pseudo-arguments,
2320 such as in "Spec<#1,#1.*>" */
2321 start_spec_args = strchr (*mangled, '<');
2322 if (start_spec_args && (start_spec_args - *mangled < n))
2323 string_appendn (declp, *mangled, start_spec_args - *mangled);
2325 string_appendn (declp, *mangled, n);
2326 (*mangled) += n + 1;
2328 if (work->temp_start == -1) /* non-recursive call */
2329 work->temp_start = declp->p - declp->b;
2330 string_append (declp, "<");
2333 string_delete (&arg);
2337 /* 'T' signals a type parameter */
2339 if (!do_type (work, mangled, &arg))
2340 goto hpacc_template_args_done;
2345 /* 'U' or 'S' signals an integral value */
2346 if (!do_hpacc_template_const_value (work, mangled, &arg))
2347 goto hpacc_template_args_done;
2351 /* 'A' signals a named constant expression (literal) */
2352 if (!do_hpacc_template_literal (work, mangled, &arg))
2353 goto hpacc_template_args_done;
2357 /* Today, 1997-09-03, we have only the above types
2358 of template parameters */
2359 /* FIXME: maybe this should fail and return null */
2360 goto hpacc_template_args_done;
2362 string_appends (declp, &arg);
2363 /* Check if we're at the end of template args.
2364 0 if at end of static member of template class,
2365 _ if done with template args for a function */
2366 if ((**mangled == '\000') || (**mangled == '_'))
2369 string_append (declp, ",");
2371 hpacc_template_args_done:
2372 string_append (declp, ">");
2373 string_delete (&arg);
2374 if (**mangled == '_')
2378 /* ARM template? (Also handles HP cfront extensions) */
2379 else if (arm_pt (work, *mangled, n, &p, &args))
2384 string_appendn (declp, *mangled, p - *mangled);
2385 if (work->temp_start == -1) /* non-recursive call */
2386 work->temp_start = declp->p - declp->b;
2387 string_append (declp, "<");
2388 /* should do error checking here */
2390 string_delete (&arg);
2392 /* Check for type or literal here */
2395 /* HP cfront extensions to ARM for template args */
2396 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2397 /* FIXME: We handle only numeric literals for HP cfront */
2399 /* A typed constant value follows */
2401 if (!do_type (work, &args, &type_str))
2402 goto cfront_template_args_done;
2403 string_append (&arg, "(");
2404 string_appends (&arg, &type_str);
2405 string_delete (&type_str);
2406 string_append (&arg, ")");
2408 goto cfront_template_args_done;
2410 /* Now snarf a literal value following 'L' */
2411 if (!snarf_numeric_literal (&args, &arg))
2412 goto cfront_template_args_done;
2416 /* Snarf a literal following 'L' */
2418 if (!snarf_numeric_literal (&args, &arg))
2419 goto cfront_template_args_done;
2422 /* Not handling other HP cfront stuff */
2424 const char* old_args = args;
2425 if (!do_type (work, &args, &arg))
2426 goto cfront_template_args_done;
2428 /* Fail if we didn't make any progress: prevent infinite loop. */
2429 if (args == old_args)
2433 string_appends (declp, &arg);
2434 string_append (declp, ",");
2436 cfront_template_args_done:
2437 string_delete (&arg);
2439 --declp->p; /* remove extra comma */
2440 string_append (declp, ">");
2442 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2443 && (*mangled)[9] == 'N'
2444 && (*mangled)[8] == (*mangled)[10]
2445 && strchr (cplus_markers, (*mangled)[8]))
2447 /* A member of the anonymous namespace. */
2448 string_append (declp, "{anonymous}");
2452 if (work->temp_start == -1) /* non-recursive call only */
2453 work->temp_start = 0; /* disable in recursive calls */
2454 string_appendn (declp, *mangled, n);
2459 /* Extract a class name, possibly a template with arguments, from the
2460 mangled string; qualifiers, local class indicators, etc. have
2461 already been dealt with */
2464 demangle_class_name (work, mangled, declp)
2465 struct work_stuff *work;
2466 const char **mangled;
2472 n = consume_count (mangled);
2475 if ((int) strlen (*mangled) >= n)
2477 demangle_arm_hp_template (work, mangled, n, declp);
2488 demangle_class -- demangle a mangled class sequence
2493 demangle_class (struct work_stuff *work, const char **mangled,
2498 DECLP points to the buffer into which demangling is being done.
2500 *MANGLED points to the current token to be demangled. On input,
2501 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2502 On exit, it points to the next token after the mangled class on
2503 success, or the first unconsumed token on failure.
2505 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2506 we are demangling a constructor or destructor. In this case
2507 we prepend "class::class" or "class::~class" to DECLP.
2509 Otherwise, we prepend "class::" to the current DECLP.
2511 Reset the constructor/destructor flags once they have been
2512 "consumed". This allows demangle_class to be called later during
2513 the same demangling, to do normal class demangling.
2515 Returns 1 if demangling is successful, 0 otherwise.
2520 demangle_class (work, mangled, declp)
2521 struct work_stuff *work;
2522 const char **mangled;
2528 char *save_class_name_end = 0;
2530 string_init (&class_name);
2531 btype = register_Btype (work);
2532 if (demangle_class_name (work, mangled, &class_name))
2534 save_class_name_end = class_name.p;
2535 if ((work->constructor & 1) || (work->destructor & 1))
2537 /* adjust so we don't include template args */
2538 if (work->temp_start && (work->temp_start != -1))
2540 class_name.p = class_name.b + work->temp_start;
2542 string_prepends (declp, &class_name);
2543 if (work -> destructor & 1)
2545 string_prepend (declp, "~");
2546 work -> destructor -= 1;
2550 work -> constructor -= 1;
2553 class_name.p = save_class_name_end;
2554 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2555 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2556 string_prepend (declp, SCOPE_STRING (work));
2557 string_prepends (declp, &class_name);
2560 string_delete (&class_name);
2565 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2566 the rightmost guess.
2568 Find the correct "__"-sequence where the function name ends and the
2569 signature starts, which is ambiguous with GNU mangling.
2570 Call demangle_signature here, so we can make sure we found the right
2571 one; *mangled will be consumed so caller will not make further calls to
2572 demangle_signature. */
2575 iterate_demangle_function (work, mangled, declp, scan)
2576 struct work_stuff *work;
2577 const char **mangled;
2581 const char *mangle_init = *mangled;
2584 struct work_stuff work_init;
2586 if (*(scan + 2) == '\0')
2589 /* Do not iterate for some demangling modes, or if there's only one
2590 "__"-sequence. This is the normal case. */
2591 if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
2592 || strstr (scan + 2, "__") == NULL)
2594 demangle_function_name (work, mangled, declp, scan);
2598 /* Save state so we can restart if the guess at the correct "__" was
2600 string_init (&decl_init);
2601 string_appends (&decl_init, declp);
2602 memset (&work_init, 0, sizeof work_init);
2603 work_stuff_copy_to_from (&work_init, work);
2605 /* Iterate over occurrences of __, allowing names and types to have a
2606 "__" sequence in them. We must start with the first (not the last)
2607 occurrence, since "__" most often occur between independent mangled
2608 parts, hence starting at the last occurence inside a signature
2609 might get us a "successful" demangling of the signature. */
2613 demangle_function_name (work, mangled, declp, scan);
2614 success = demangle_signature (work, mangled, declp);
2618 /* Reset demangle state for the next round. */
2619 *mangled = mangle_init;
2620 string_clear (declp);
2621 string_appends (declp, &decl_init);
2622 work_stuff_copy_to_from (work, &work_init);
2624 /* Leave this underscore-sequence. */
2627 /* Scan for the next "__" sequence. */
2628 while (*scan && (scan[0] != '_' || scan[1] != '_'))
2631 /* Move to last "__" in this sequence. */
2632 while (*scan && *scan == '_')
2637 /* Delete saved state. */
2638 delete_work_stuff (&work_init);
2639 string_delete (&decl_init);
2648 demangle_prefix -- consume the mangled name prefix and find signature
2653 demangle_prefix (struct work_stuff *work, const char **mangled,
2658 Consume and demangle the prefix of the mangled name.
2659 While processing the function name root, arrange to call
2660 demangle_signature if the root is ambiguous.
2662 DECLP points to the string buffer into which demangled output is
2663 placed. On entry, the buffer is empty. On exit it contains
2664 the root function name, the demangled operator name, or in some
2665 special cases either nothing or the completely demangled result.
2667 MANGLED points to the current pointer into the mangled name. As each
2668 token of the mangled name is consumed, it is updated. Upon entry
2669 the current mangled name pointer points to the first character of
2670 the mangled name. Upon exit, it should point to the first character
2671 of the signature if demangling was successful, or to the first
2672 unconsumed character if demangling of the prefix was unsuccessful.
2674 Returns 1 on success, 0 otherwise.
2678 demangle_prefix (work, mangled, declp)
2679 struct work_stuff *work;
2680 const char **mangled;
2687 if (strlen(*mangled) > 6
2688 && (strncmp(*mangled, "_imp__", 6) == 0
2689 || strncmp(*mangled, "__imp_", 6) == 0))
2691 /* it's a symbol imported from a PE dynamic library. Check for both
2692 new style prefix _imp__ and legacy __imp_ used by older versions
2695 work->dllimported = 1;
2697 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2699 char *marker = strchr (cplus_markers, (*mangled)[8]);
2700 if (marker != NULL && *marker == (*mangled)[10])
2702 if ((*mangled)[9] == 'D')
2704 /* it's a GNU global destructor to be executed at program exit */
2706 work->destructor = 2;
2707 if (gnu_special (work, mangled, declp))
2710 else if ((*mangled)[9] == 'I')
2712 /* it's a GNU global constructor to be executed at program init */
2714 work->constructor = 2;
2715 if (gnu_special (work, mangled, declp))
2720 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2722 /* it's a ARM global destructor to be executed at program exit */
2724 work->destructor = 2;
2726 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2728 /* it's a ARM global constructor to be executed at program initial */
2730 work->constructor = 2;
2733 /* This block of code is a reduction in strength time optimization
2735 scan = strstr (*mangled, "__"); */
2741 scan = strchr (scan, '_');
2742 } while (scan != NULL && *++scan != '_');
2744 if (scan != NULL) --scan;
2749 /* We found a sequence of two or more '_', ensure that we start at
2750 the last pair in the sequence. */
2751 i = strspn (scan, "_");
2762 else if (work -> static_type)
2764 if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2769 else if ((scan == *mangled)
2770 && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2771 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2773 /* The ARM says nothing about the mangling of local variables.
2774 But cfront mangles local variables by prepending __<nesting_level>
2775 to them. As an extension to ARM demangling we handle this case. */
2776 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2777 && ISDIGIT ((unsigned char)scan[2]))
2779 *mangled = scan + 2;
2780 consume_count (mangled);
2781 string_append (declp, *mangled);
2782 *mangled += strlen (*mangled);
2787 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2788 names like __Q2_3foo3bar for nested type names. So don't accept
2789 this style of constructor for cfront demangling. A GNU
2790 style member-template constructor starts with 'H'. */
2791 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2792 work -> constructor += 1;
2793 *mangled = scan + 2;
2796 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2798 /* Cfront-style parameterized type. Handled later as a signature. */
2802 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2804 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2805 || (scan[2] == 'p' && scan[3] == 's')
2806 || (scan[2] == 'p' && scan[3] == 't')))
2808 /* EDG-style parameterized type. Handled later as a signature. */
2812 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2814 else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2815 && (scan[2] != 't'))
2817 /* Mangled name starts with "__". Skip over any leading '_' characters,
2818 then find the next "__" that separates the prefix from the signature.
2820 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2821 || (arm_special (mangled, declp) == 0))
2823 while (*scan == '_')
2827 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2829 /* No separator (I.E. "__not_mangled"), or empty signature
2830 (I.E. "__not_mangled_either__") */
2834 return iterate_demangle_function (work, mangled, declp, scan);
2837 else if (*(scan + 2) != '\0')
2839 /* Mangled name does not start with "__" but does have one somewhere
2840 in there with non empty stuff after it. Looks like a global
2841 function name. Iterate over all "__":s until the right
2843 return iterate_demangle_function (work, mangled, declp, scan);
2847 /* Doesn't look like a mangled name */
2851 if (!success && (work->constructor == 2 || work->destructor == 2))
2853 string_append (declp, *mangled);
2854 *mangled += strlen (*mangled);
2864 gnu_special -- special handling of gnu mangled strings
2869 gnu_special (struct work_stuff *work, const char **mangled,
2875 Process some special GNU style mangling forms that don't fit
2876 the normal pattern. For example:
2878 _$_3foo (destructor for class foo)
2879 _vt$foo (foo virtual table)
2880 _vt$foo$bar (foo::bar virtual table)
2881 __vt_foo (foo virtual table, new style with thunks)
2882 _3foo$varname (static data member)
2883 _Q22rs2tu$vw (static data member)
2884 __t6vector1Zii (constructor with template)
2885 __thunk_4__$_7ostream (virtual function thunk)
2889 gnu_special (work, mangled, declp)
2890 struct work_stuff *work;
2891 const char **mangled;
2898 if ((*mangled)[0] == '_'
2899 && strchr (cplus_markers, (*mangled)[1]) != NULL
2900 && (*mangled)[2] == '_')
2902 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2904 work -> destructor += 1;
2906 else if ((*mangled)[0] == '_'
2907 && (((*mangled)[1] == '_'
2908 && (*mangled)[2] == 'v'
2909 && (*mangled)[3] == 't'
2910 && (*mangled)[4] == '_')
2911 || ((*mangled)[1] == 'v'
2912 && (*mangled)[2] == 't'
2913 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2915 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2916 and create the decl. Note that we consume the entire mangled
2917 input string, which means that demangle_signature has no work
2919 if ((*mangled)[2] == 'v')
2920 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2922 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2923 while (**mangled != '\0')
2929 success = demangle_qualified (work, mangled, declp, 0, 1);
2932 success = demangle_template (work, mangled, declp, 0, 1,
2936 if (ISDIGIT((unsigned char)*mangled[0]))
2938 n = consume_count(mangled);
2939 /* We may be seeing a too-large size, or else a
2940 ".<digits>" indicating a static local symbol. In
2941 any case, declare victory and move on; *don't* try
2942 to use n to allocate. */
2943 if (n > (int) strlen (*mangled))
2951 n = strcspn (*mangled, cplus_markers);
2953 string_appendn (declp, *mangled, n);
2957 p = strpbrk (*mangled, cplus_markers);
2958 if (success && ((p == NULL) || (p == *mangled)))
2962 string_append (declp, SCOPE_STRING (work));
2973 string_append (declp, " virtual table");
2975 else if ((*mangled)[0] == '_'
2976 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2977 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2979 /* static data member, "_3foo$varname" for example */
2985 success = demangle_qualified (work, mangled, declp, 0, 1);
2988 success = demangle_template (work, mangled, declp, 0, 1, 1);
2991 n = consume_count (mangled);
2992 if (n < 0 || n > (long) strlen (*mangled))
2998 if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2999 && (*mangled)[9] == 'N'
3000 && (*mangled)[8] == (*mangled)[10]
3001 && strchr (cplus_markers, (*mangled)[8]))
3003 /* A member of the anonymous namespace. There's information
3004 about what identifier or filename it was keyed to, but
3005 it's just there to make the mangled name unique; we just
3007 string_append (declp, "{anonymous}");
3010 /* Now p points to the marker before the N, so we need to
3011 update it to the first marker after what we consumed. */
3012 p = strpbrk (*mangled, cplus_markers);
3016 string_appendn (declp, *mangled, n);
3019 if (success && (p == *mangled))
3021 /* Consumed everything up to the cplus_marker, append the
3024 string_append (declp, SCOPE_STRING (work));
3025 n = strlen (*mangled);
3026 string_appendn (declp, *mangled, n);
3034 else if (strncmp (*mangled, "__thunk_", 8) == 0)
3039 delta = consume_count (mangled);
3044 char *method = internal_cplus_demangle (work, ++*mangled);
3049 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
3050 string_append (declp, buf);
3051 string_append (declp, method);
3053 n = strlen (*mangled);
3062 else if (strncmp (*mangled, "__t", 3) == 0
3063 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
3065 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
3071 success = demangle_qualified (work, mangled, declp, 0, 1);
3074 success = demangle_template (work, mangled, declp, 0, 1, 1);
3077 success = do_type (work, mangled, declp);
3080 if (success && **mangled != '\0')
3083 string_append (declp, p);
3093 recursively_demangle(work, mangled, result, namelength)
3094 struct work_stuff *work;
3095 const char **mangled;
3099 char * recurse = (char *)NULL;
3100 char * recurse_dem = (char *)NULL;
3102 recurse = (char *) xmalloc (namelength + 1);
3103 memcpy (recurse, *mangled, namelength);
3104 recurse[namelength] = '\000';
3106 recurse_dem = cplus_demangle (recurse, work->options);
3110 string_append (result, recurse_dem);
3115 string_appendn (result, *mangled, namelength);
3118 *mangled += namelength;
3125 arm_special -- special handling of ARM/lucid mangled strings
3130 arm_special (const char **mangled,
3136 Process some special ARM style mangling forms that don't fit
3137 the normal pattern. For example:
3139 __vtbl__3foo (foo virtual table)
3140 __vtbl__3foo__3bar (bar::foo virtual table)
3145 arm_special (mangled, declp)
3146 const char **mangled;
3153 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3155 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3156 and create the decl. Note that we consume the entire mangled
3157 input string, which means that demangle_signature has no work
3159 scan = *mangled + ARM_VTABLE_STRLEN;
3160 while (*scan != '\0') /* first check it can be demangled */
3162 n = consume_count (&scan);
3165 return (0); /* no good */
3168 if (scan[0] == '_' && scan[1] == '_')
3173 (*mangled) += ARM_VTABLE_STRLEN;
3174 while (**mangled != '\0')
3176 n = consume_count (mangled);
3178 || n > (long) strlen (*mangled))
3180 string_prependn (declp, *mangled, n);
3182 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3184 string_prepend (declp, "::");
3188 string_append (declp, " virtual table");
3201 demangle_qualified -- demangle 'Q' qualified name strings
3206 demangle_qualified (struct work_stuff *, const char *mangled,
3207 string *result, int isfuncname, int append);
3211 Demangle a qualified name, such as "Q25Outer5Inner" which is
3212 the mangled form of "Outer::Inner". The demangled output is
3213 prepended or appended to the result string according to the
3214 state of the append flag.
3216 If isfuncname is nonzero, then the qualified name we are building
3217 is going to be used as a member function name, so if it is a
3218 constructor or destructor function, append an appropriate
3219 constructor or destructor name. I.E. for the above example,
3220 the result for use as a constructor is "Outer::Inner::Inner"
3221 and the result for use as a destructor is "Outer::Inner::~Inner".
3225 Numeric conversion is ASCII dependent (FIXME).
3230 demangle_qualified (work, mangled, result, isfuncname, append)
3231 struct work_stuff *work;
3232 const char **mangled;
3242 int bindex = register_Btype (work);
3244 /* We only make use of ISFUNCNAME if the entity is a constructor or
3246 isfuncname = (isfuncname
3247 && ((work->constructor & 1) || (work->destructor & 1)));
3249 string_init (&temp);
3250 string_init (&last_name);
3252 if ((*mangled)[0] == 'K')
3254 /* Squangling qualified name reuse */
3257 idx = consume_count_with_underscores (mangled);
3258 if (idx == -1 || idx >= work -> numk)
3261 string_append (&temp, work -> ktypevec[idx]);
3264 switch ((*mangled)[1])
3267 /* GNU mangled name with more than 9 classes. The count is preceded
3268 by an underscore (to distinguish it from the <= 9 case) and followed
3269 by an underscore. */
3271 qualifiers = consume_count_with_underscores (mangled);
3272 if (qualifiers == -1)
3285 /* The count is in a single digit. */
3286 num[0] = (*mangled)[1];
3288 qualifiers = atoi (num);
3290 /* If there is an underscore after the digit, skip it. This is
3291 said to be for ARM-qualified names, but the ARM makes no
3292 mention of such an underscore. Perhaps cfront uses one. */
3293 if ((*mangled)[2] == '_')
3308 /* Pick off the names and collect them in the temp buffer in the order
3309 in which they are found, separated by '::'. */
3311 while (qualifiers-- > 0)
3314 string_clear (&last_name);
3316 if (*mangled[0] == '_')
3319 if (*mangled[0] == 't')
3321 /* Here we always append to TEMP since we will want to use
3322 the template name without the template parameters as a
3323 constructor or destructor name. The appropriate
3324 (parameter-less) value is returned by demangle_template
3325 in LAST_NAME. We do not remember the template type here,
3326 in order to match the G++ mangling algorithm. */
3327 success = demangle_template(work, mangled, &temp,
3332 else if (*mangled[0] == 'K')
3336 idx = consume_count_with_underscores (mangled);
3337 if (idx == -1 || idx >= work->numk)
3340 string_append (&temp, work->ktypevec[idx]);
3343 if (!success) break;
3350 /* Now recursively demangle the qualifier
3351 * This is necessary to deal with templates in
3352 * mangling styles like EDG */
3353 namelength = consume_count (mangled);
3354 if (namelength == -1)
3359 recursively_demangle(work, mangled, &temp, namelength);
3363 string_delete (&last_name);
3364 success = do_type (work, mangled, &last_name);
3367 string_appends (&temp, &last_name);
3372 remember_Ktype (work, temp.b, LEN_STRING (&temp));
3375 string_append (&temp, SCOPE_STRING (work));
3378 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3380 /* If we are using the result as a function name, we need to append
3381 the appropriate '::' separated constructor or destructor name.
3382 We do this here because this is the most convenient place, where
3383 we already have a pointer to the name and the length of the name. */
3387 string_append (&temp, SCOPE_STRING (work));
3388 if (work -> destructor & 1)
3389 string_append (&temp, "~");
3390 string_appends (&temp, &last_name);
3393 /* Now either prepend the temp buffer to the result, or append it,
3394 depending upon the state of the append flag. */
3397 string_appends (result, &temp);
3400 if (!STRING_EMPTY (result))
3401 string_append (&temp, SCOPE_STRING (work));
3402 string_prepends (result, &temp);
3405 string_delete (&last_name);
3406 string_delete (&temp);
3414 get_count -- convert an ascii count to integer, consuming tokens
3419 get_count (const char **type, int *count)
3423 Assume that *type points at a count in a mangled name; set
3424 *count to its value, and set *type to the next character after
3425 the count. There are some weird rules in effect here.
3427 If *type does not point at a string of digits, return zero.
3429 If *type points at a string of digits followed by an
3430 underscore, set *count to their value as an integer, advance
3431 *type to point *after the underscore, and return 1.
3433 If *type points at a string of digits not followed by an
3434 underscore, consume only the first digit. Set *count to its
3435 value as an integer, leave *type pointing after that digit,
3438 The excuse for this odd behavior: in the ARM and HP demangling
3439 styles, a type can be followed by a repeat count of the form
3442 `x' is a single digit specifying how many additional copies
3443 of the type to append to the argument list, and
3445 `y' is one or more digits, specifying the zero-based index of
3446 the first repeated argument in the list. Yes, as you're
3447 unmangling the name you can figure this out yourself, but
3450 So, for example, in `bar__3fooFPiN51', the first argument is a
3451 pointer to an integer (`Pi'), and then the next five arguments
3452 are the same (`N5'), and the first repeat is the function's
3453 second argument (`1').
3457 get_count (type, count)
3464 if (!ISDIGIT ((unsigned char)**type))
3468 *count = **type - '0';
3470 if (ISDIGIT ((unsigned char)**type))
3480 while (ISDIGIT ((unsigned char)*p));
3491 /* RESULT will be initialised here; it will be freed on failure. The
3492 value returned is really a type_kind_t. */
3495 do_type (work, mangled, result)
3496 struct work_stuff *work;
3497 const char **mangled;
3504 const char *remembered_type;
3506 type_kind_t tk = tk_none;
3508 string_init (&decl);
3509 string_init (result);
3513 while (success && !done)
3519 /* A pointer type */
3523 if (! (work -> options & DMGL_JAVA))
3524 string_prepend (&decl, "*");
3529 /* A reference type */
3532 string_prepend (&decl, "&");
3541 if (!STRING_EMPTY (&decl)
3542 && (decl.b[0] == '*' || decl.b[0] == '&'))
3544 string_prepend (&decl, "(");
3545 string_append (&decl, ")");
3547 string_append (&decl, "[");
3548 if (**mangled != '_')
3549 success = demangle_template_value_parm (work, mangled, &decl,
3551 if (**mangled == '_')
3553 string_append (&decl, "]");
3557 /* A back reference to a previously seen type */
3560 if (!get_count (mangled, &n) || n >= work -> ntypes)
3566 remembered_type = work -> typevec[n];
3567 mangled = &remembered_type;
3574 if (!STRING_EMPTY (&decl)
3575 && (decl.b[0] == '*' || decl.b[0] == '&'))
3577 string_prepend (&decl, "(");
3578 string_append (&decl, ")");
3580 /* After picking off the function args, we expect to either find the
3581 function return type (preceded by an '_') or the end of the
3583 if (!demangle_nested_args (work, mangled, &decl)
3584 || (**mangled != '_' && **mangled != '\0'))
3589 if (success && (**mangled == '_'))
3596 type_quals = TYPE_UNQUALIFIED;
3598 member = **mangled == 'M';
3601 string_append (&decl, ")");
3603 /* We don't need to prepend `::' for a qualified name;
3604 demangle_qualified will do that for us. */
3605 if (**mangled != 'Q')
3606 string_prepend (&decl, SCOPE_STRING (work));
3608 if (ISDIGIT ((unsigned char)**mangled))
3610 n = consume_count (mangled);
3612 || (int) strlen (*mangled) < n)
3617 string_prependn (&decl, *mangled, n);
3620 else if (**mangled == 'X' || **mangled == 'Y')
3623 do_type (work, mangled, &temp);
3624 string_prepends (&decl, &temp);
3625 string_delete (&temp);
3627 else if (**mangled == 't')
3630 string_init (&temp);
3631 success = demangle_template (work, mangled, &temp,
3635 string_prependn (&decl, temp.b, temp.p - temp.b);
3636 string_delete (&temp);
3641 else if (**mangled == 'Q')
3643 success = demangle_qualified (work, mangled, &decl,
3655 string_prepend (&decl, "(");
3663 type_quals |= code_for_qualifier (**mangled);
3671 if (*(*mangled)++ != 'F')
3677 if ((member && !demangle_nested_args (work, mangled, &decl))
3678 || **mangled != '_')
3684 if (! PRINT_ANSI_QUALIFIERS)
3688 if (type_quals != TYPE_UNQUALIFIED)
3690 APPEND_BLANK (&decl);
3691 string_append (&decl, qualifier_string (type_quals));
3702 if (PRINT_ANSI_QUALIFIERS)
3704 if (!STRING_EMPTY (&decl))
3705 string_prepend (&decl, " ");
3707 string_prepend (&decl, demangle_qualifier (**mangled));
3722 if (success) switch (**mangled)
3724 /* A qualified name, such as "Outer::Inner". */
3728 success = demangle_qualified (work, mangled, result, 0, 1);
3732 /* A back reference to a previously seen squangled type */
3735 if (!get_count (mangled, &n) || n >= work -> numb)
3738 string_append (result, work->btypevec[n]);
3743 /* A template parm. We substitute the corresponding argument. */
3748 idx = consume_count_with_underscores (mangled);
3751 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3752 || consume_count_with_underscores (mangled) == -1)
3758 if (work->tmpl_argvec)
3759 string_append (result, work->tmpl_argvec[idx]);
3761 string_append_template_idx (result, idx);
3768 success = demangle_fund_type (work, mangled, result);
3770 tk = (type_kind_t) success;
3776 if (!STRING_EMPTY (&decl))
3778 string_append (result, " ");
3779 string_appends (result, &decl);
3783 string_delete (result);
3784 string_delete (&decl);
3787 /* Assume an integral type, if we're not sure. */
3788 return (int) ((tk == tk_none) ? tk_integral : tk);
3793 /* Given a pointer to a type string that represents a fundamental type
3794 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3795 string in which the demangled output is being built in RESULT, and
3796 the WORK structure, decode the types and add them to the result.
3801 "Sl" => "signed long"
3802 "CUs" => "const unsigned short"
3804 The value returned is really a type_kind_t. */
3807 demangle_fund_type (work, mangled, result)
3808 struct work_stuff *work;
3809 const char **mangled;
3815 unsigned int dec = 0;
3816 type_kind_t tk = tk_integral;
3818 /* First pick off any type qualifiers. There can be more than one. */
3827 if (PRINT_ANSI_QUALIFIERS)
3829 if (!STRING_EMPTY (result))
3830 string_prepend (result, " ");
3831 string_prepend (result, demangle_qualifier (**mangled));
3837 APPEND_BLANK (result);
3838 string_append (result, "unsigned");
3840 case 'S': /* signed char only */
3842 APPEND_BLANK (result);
3843 string_append (result, "signed");
3847 APPEND_BLANK (result);
3848 string_append (result, "__complex");
3856 /* Now pick off the fundamental type. There can be only one. */
3865 APPEND_BLANK (result);
3866 string_append (result, "void");
3870 APPEND_BLANK (result);
3871 string_append (result, "long long");
3875 APPEND_BLANK (result);
3876 string_append (result, "long");
3880 APPEND_BLANK (result);
3881 string_append (result, "int");
3885 APPEND_BLANK (result);
3886 string_append (result, "short");
3890 APPEND_BLANK (result);
3891 string_append (result, "bool");
3896 APPEND_BLANK (result);
3897 string_append (result, "char");
3902 APPEND_BLANK (result);
3903 string_append (result, "wchar_t");
3908 APPEND_BLANK (result);
3909 string_append (result, "long double");
3914 APPEND_BLANK (result);
3915 string_append (result, "double");
3920 APPEND_BLANK (result);
3921 string_append (result, "float");
3926 if (!ISDIGIT ((unsigned char)**mangled))
3933 if (**mangled == '_')
3938 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
3941 if (**mangled != '_')
3951 strncpy (buf, *mangled, 2);
3953 *mangled += min (strlen (*mangled), 2);
3955 sscanf (buf, "%x", &dec);
3956 sprintf (buf, "int%u_t", dec);
3957 APPEND_BLANK (result);
3958 string_append (result, buf);
3962 /* An explicit type, such as "6mytype" or "7integer" */
3974 int bindex = register_Btype (work);
3976 string_init (&btype);
3977 if (demangle_class_name (work, mangled, &btype)) {
3978 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3979 APPEND_BLANK (result);
3980 string_appends (result, &btype);
3984 string_delete (&btype);
3990 string_init (&btype);
3991 success = demangle_template (work, mangled, &btype, 0, 1, 1);
3992 string_appends (result, &btype);
3993 string_delete (&btype);
4001 return success ? ((int) tk) : 0;
4005 /* Handle a template's value parameter for HP aCC (extension from ARM)
4006 **mangled points to 'S' or 'U' */
4009 do_hpacc_template_const_value (work, mangled, result)
4010 struct work_stuff *work ATTRIBUTE_UNUSED;
4011 const char **mangled;
4016 if (**mangled != 'U' && **mangled != 'S')
4019 unsigned_const = (**mangled == 'U');
4026 string_append (result, "-");
4032 /* special case for -2^31 */
4033 string_append (result, "-2147483648");
4040 /* We have to be looking at an integer now */
4041 if (!(ISDIGIT ((unsigned char)**mangled)))
4044 /* We only deal with integral values for template
4045 parameters -- so it's OK to look only for digits */
4046 while (ISDIGIT ((unsigned char)**mangled))
4048 char_str[0] = **mangled;
4049 string_append (result, char_str);
4054 string_append (result, "U");
4056 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4057 with L or LL suffixes. pai/1997-09-03 */
4059 return 1; /* success */
4062 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4063 **mangled is pointing to the 'A' */
4066 do_hpacc_template_literal (work, mangled, result)
4067 struct work_stuff *work;
4068 const char **mangled;
4071 int literal_len = 0;
4075 if (**mangled != 'A')
4080 literal_len = consume_count (mangled);
4082 if (literal_len <= 0)
4085 /* Literal parameters are names of arrays, functions, etc. and the
4086 canonical representation uses the address operator */
4087 string_append (result, "&");
4089 /* Now recursively demangle the literal name */
4090 recurse = (char *) xmalloc (literal_len + 1);
4091 memcpy (recurse, *mangled, literal_len);
4092 recurse[literal_len] = '\000';
4094 recurse_dem = cplus_demangle (recurse, work->options);
4098 string_append (result, recurse_dem);
4103 string_appendn (result, *mangled, literal_len);
4105 (*mangled) += literal_len;
4112 snarf_numeric_literal (args, arg)
4119 string_append (arg, char_str);
4122 else if (**args == '+')
4125 if (!ISDIGIT ((unsigned char)**args))
4128 while (ISDIGIT ((unsigned char)**args))
4130 char_str[0] = **args;
4131 string_append (arg, char_str);
4138 /* Demangle the next argument, given by MANGLED into RESULT, which
4139 *should be an uninitialized* string. It will be initialized here,
4140 and free'd should anything go wrong. */
4143 do_arg (work, mangled, result)
4144 struct work_stuff *work;
4145 const char **mangled;
4148 /* Remember where we started so that we can record the type, for
4149 non-squangling type remembering. */
4150 const char *start = *mangled;
4152 string_init (result);
4154 if (work->nrepeats > 0)
4158 if (work->previous_argument == 0)
4161 /* We want to reissue the previous type in this argument list. */
4162 string_appends (result, work->previous_argument);
4166 if (**mangled == 'n')
4168 /* A squangling-style repeat. */
4170 work->nrepeats = consume_count(mangled);
4172 if (work->nrepeats <= 0)
4173 /* This was not a repeat count after all. */
4176 if (work->nrepeats > 9)
4178 if (**mangled != '_')
4179 /* The repeat count should be followed by an '_' in this
4186 /* Now, the repeat is all set up. */
4187 return do_arg (work, mangled, result);
4190 /* Save the result in WORK->previous_argument so that we can find it
4191 if it's repeated. Note that saving START is not good enough: we
4192 do not want to add additional types to the back-referenceable
4193 type vector when processing a repeated type. */
4194 if (work->previous_argument)
4195 string_delete (work->previous_argument);
4197 work->previous_argument = (string*) xmalloc (sizeof (string));
4199 if (!do_type (work, mangled, work->previous_argument))
4202 string_appends (result, work->previous_argument);
4204 remember_type (work, start, *mangled - start);
4209 remember_type (work, start, len)
4210 struct work_stuff *work;
4216 if (work->forgetting_types)
4219 if (work -> ntypes >= work -> typevec_size)
4221 if (work -> typevec_size == 0)
4223 work -> typevec_size = 3;
4225 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
4229 work -> typevec_size *= 2;
4231 = (char **) xrealloc ((char *)work -> typevec,
4232 sizeof (char *) * work -> typevec_size);
4235 tem = xmalloc (len + 1);
4236 memcpy (tem, start, len);
4238 work -> typevec[work -> ntypes++] = tem;
4242 /* Remember a K type class qualifier. */
4244 remember_Ktype (work, start, len)
4245 struct work_stuff *work;
4251 if (work -> numk >= work -> ksize)
4253 if (work -> ksize == 0)
4257 = (char **) xmalloc (sizeof (char *) * work -> ksize);
4263 = (char **) xrealloc ((char *)work -> ktypevec,
4264 sizeof (char *) * work -> ksize);
4267 tem = xmalloc (len + 1);
4268 memcpy (tem, start, len);
4270 work -> ktypevec[work -> numk++] = tem;
4273 /* Register a B code, and get an index for it. B codes are registered
4274 as they are seen, rather than as they are completed, so map<temp<char> >
4275 registers map<temp<char> > as B0, and temp<char> as B1 */
4278 register_Btype (work)
4279 struct work_stuff *work;
4283 if (work -> numb >= work -> bsize)
4285 if (work -> bsize == 0)
4289 = (char **) xmalloc (sizeof (char *) * work -> bsize);
4295 = (char **) xrealloc ((char *)work -> btypevec,
4296 sizeof (char *) * work -> bsize);
4299 ret = work -> numb++;
4300 work -> btypevec[ret] = NULL;
4304 /* Store a value into a previously registered B code type. */
4307 remember_Btype (work, start, len, index)
4308 struct work_stuff *work;
4314 tem = xmalloc (len + 1);
4315 memcpy (tem, start, len);
4317 work -> btypevec[index] = tem;
4320 /* Lose all the info related to B and K type codes. */
4322 forget_B_and_K_types (work)
4323 struct work_stuff *work;
4327 while (work -> numk > 0)
4329 i = --(work -> numk);
4330 if (work -> ktypevec[i] != NULL)
4332 free (work -> ktypevec[i]);
4333 work -> ktypevec[i] = NULL;
4337 while (work -> numb > 0)
4339 i = --(work -> numb);
4340 if (work -> btypevec[i] != NULL)
4342 free (work -> btypevec[i]);
4343 work -> btypevec[i] = NULL;
4347 /* Forget the remembered types, but not the type vector itself. */
4351 struct work_stuff *work;
4355 while (work -> ntypes > 0)
4357 i = --(work -> ntypes);
4358 if (work -> typevec[i] != NULL)
4360 free (work -> typevec[i]);
4361 work -> typevec[i] = NULL;
4366 /* Process the argument list part of the signature, after any class spec
4367 has been consumed, as well as the first 'F' character (if any). For
4370 "__als__3fooRT0" => process "RT0"
4371 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4373 DECLP must be already initialised, usually non-empty. It won't be freed
4376 Note that g++ differs significantly from ARM and lucid style mangling
4377 with regards to references to previously seen types. For example, given
4378 the source fragment:
4382 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4385 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4386 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4388 g++ produces the names:
4393 while lcc (and presumably other ARM style compilers as well) produces:
4395 foo__FiR3fooT1T2T1T2
4396 __ct__3fooFiR3fooT1T2T1T2
4398 Note that g++ bases its type numbers starting at zero and counts all
4399 previously seen types, while lucid/ARM bases its type numbers starting
4400 at one and only considers types after it has seen the 'F' character
4401 indicating the start of the function args. For lucid/ARM style, we
4402 account for this difference by discarding any previously seen types when
4403 we see the 'F' character, and subtracting one from the type number
4409 demangle_args (work, mangled, declp)
4410 struct work_stuff *work;
4411 const char **mangled;
4421 if (PRINT_ARG_TYPES)
4423 string_append (declp, "(");
4424 if (**mangled == '\0')
4426 string_append (declp, "void");
4430 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4431 || work->nrepeats > 0)
4433 if ((**mangled == 'N') || (**mangled == 'T'))
4435 temptype = *(*mangled)++;
4437 if (temptype == 'N')
4439 if (!get_count (mangled, &r))
4448 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4450 /* If we have 10 or more types we might have more than a 1 digit
4451 index so we'll have to consume the whole count here. This
4452 will lose if the next thing is a type name preceded by a
4453 count but it's impossible to demangle that case properly
4454 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4455 Pc, ...)" or "(..., type12, char *, ...)" */
4456 if ((t = consume_count(mangled)) <= 0)
4463 if (!get_count (mangled, &t))
4468 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4472 /* Validate the type index. Protect against illegal indices from
4473 malformed type strings. */
4474 if ((t < 0) || (t >= work -> ntypes))
4478 while (work->nrepeats > 0 || --r >= 0)
4480 tem = work -> typevec[t];
4481 if (need_comma && PRINT_ARG_TYPES)
4483 string_append (declp, ", ");
4485 if (!do_arg (work, &tem, &arg))
4489 if (PRINT_ARG_TYPES)
4491 string_appends (declp, &arg);
4493 string_delete (&arg);
4499 if (need_comma && PRINT_ARG_TYPES)
4500 string_append (declp, ", ");
4501 if (!do_arg (work, mangled, &arg))
4503 if (PRINT_ARG_TYPES)
4504 string_appends (declp, &arg);
4505 string_delete (&arg);
4510 if (**mangled == 'e')
4513 if (PRINT_ARG_TYPES)
4517 string_append (declp, ",");
4519 string_append (declp, "...");
4523 if (PRINT_ARG_TYPES)
4525 string_append (declp, ")");
4530 /* Like demangle_args, but for demangling the argument lists of function
4531 and method pointers or references, not top-level declarations. */
4534 demangle_nested_args (work, mangled, declp)
4535 struct work_stuff *work;
4536 const char **mangled;
4539 string* saved_previous_argument;
4543 /* The G++ name-mangling algorithm does not remember types on nested
4544 argument lists, unless -fsquangling is used, and in that case the
4545 type vector updated by remember_type is not used. So, we turn
4546 off remembering of types here. */
4547 ++work->forgetting_types;
4549 /* For the repeat codes used with -fsquangling, we must keep track of
4550 the last argument. */
4551 saved_previous_argument = work->previous_argument;
4552 saved_nrepeats = work->nrepeats;
4553 work->previous_argument = 0;
4556 /* Actually demangle the arguments. */
4557 result = demangle_args (work, mangled, declp);
4559 /* Restore the previous_argument field. */
4560 if (work->previous_argument)
4562 string_delete (work->previous_argument);
4563 free ((char *) work->previous_argument);
4565 work->previous_argument = saved_previous_argument;
4566 --work->forgetting_types;
4567 work->nrepeats = saved_nrepeats;
4573 demangle_function_name (work, mangled, declp, scan)
4574 struct work_stuff *work;
4575 const char **mangled;
4583 string_appendn (declp, (*mangled), scan - (*mangled));
4584 string_need (declp, 1);
4585 *(declp -> p) = '\0';
4587 /* Consume the function name, including the "__" separating the name
4588 from the signature. We are guaranteed that SCAN points to the
4591 (*mangled) = scan + 2;
4592 /* We may be looking at an instantiation of a template function:
4593 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4594 following _F marks the start of the function arguments. Handle
4595 the template arguments first. */
4597 if (HP_DEMANGLING && (**mangled == 'X'))
4599 demangle_arm_hp_template (work, mangled, 0, declp);
4600 /* This leaves MANGLED pointing to the 'F' marking func args */
4603 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4606 /* See if we have an ARM style constructor or destructor operator.
4607 If so, then just record it, clear the decl, and return.
4608 We can't build the actual constructor/destructor decl until later,
4609 when we recover the class name from the signature. */
4611 if (strcmp (declp -> b, "__ct") == 0)
4613 work -> constructor += 1;
4614 string_clear (declp);
4617 else if (strcmp (declp -> b, "__dt") == 0)
4619 work -> destructor += 1;
4620 string_clear (declp);
4625 if (declp->p - declp->b >= 3
4626 && declp->b[0] == 'o'
4627 && declp->b[1] == 'p'
4628 && strchr (cplus_markers, declp->b[2]) != NULL)
4630 /* see if it's an assignment expression */
4631 if (declp->p - declp->b >= 10 /* op$assign_ */
4632 && memcmp (declp->b + 3, "assign_", 7) == 0)
4634 for (i = 0; i < ARRAY_SIZE (optable); i++)
4636 int len = declp->p - declp->b - 10;
4637 if ((int) strlen (optable[i].in) == len
4638 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4640 string_clear (declp);
4641 string_append (declp, "operator");
4642 string_append (declp, optable[i].out);
4643 string_append (declp, "=");
4650 for (i = 0; i < ARRAY_SIZE (optable); i++)
4652 int len = declp->p - declp->b - 3;
4653 if ((int) strlen (optable[i].in) == len
4654 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4656 string_clear (declp);
4657 string_append (declp, "operator");
4658 string_append (declp, optable[i].out);
4664 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4665 && strchr (cplus_markers, declp->b[4]) != NULL)
4667 /* type conversion operator */
4669 if (do_type (work, &tem, &type))
4671 string_clear (declp);
4672 string_append (declp, "operator ");
4673 string_appends (declp, &type);
4674 string_delete (&type);
4677 else if (declp->b[0] == '_' && declp->b[1] == '_'
4678 && declp->b[2] == 'o' && declp->b[3] == 'p')
4681 /* type conversion operator. */
4683 if (do_type (work, &tem, &type))
4685 string_clear (declp);
4686 string_append (declp, "operator ");
4687 string_appends (declp, &type);
4688 string_delete (&type);
4691 else if (declp->b[0] == '_' && declp->b[1] == '_'
4692 && ISLOWER((unsigned char)declp->b[2])
4693 && ISLOWER((unsigned char)declp->b[3]))
4695 if (declp->b[4] == '\0')
4698 for (i = 0; i < ARRAY_SIZE (optable); i++)
4700 if (strlen (optable[i].in) == 2
4701 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4703 string_clear (declp);
4704 string_append (declp, "operator");
4705 string_append (declp, optable[i].out);
4712 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4715 for (i = 0; i < ARRAY_SIZE (optable); i++)
4717 if (strlen (optable[i].in) == 3
4718 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4720 string_clear (declp);
4721 string_append (declp, "operator");
4722 string_append (declp, optable[i].out);
4731 /* a mini string-handling package */
4746 s->p = s->b = xmalloc (n);
4749 else if (s->e - s->p < n)
4754 s->b = xrealloc (s->b, n);
4767 s->b = s->e = s->p = NULL;
4775 s->b = s->p = s->e = NULL;
4791 return (s->b == s->p);
4797 string_append (p, s)
4802 if (s == NULL || *s == '\0')
4806 memcpy (p->p, s, n);
4811 string_appends (p, s)
4820 memcpy (p->p, s->b, n);
4826 string_appendn (p, s, n)
4834 memcpy (p->p, s, n);
4840 string_prepend (p, s)
4844 if (s != NULL && *s != '\0')
4846 string_prependn (p, s, strlen (s));
4851 string_prepends (p, s)
4856 string_prependn (p, s->b, s->p - s->b);
4861 string_prependn (p, s, n)
4871 for (q = p->p - 1; q >= p->b; q--)
4875 memcpy (p->b, s, n);
4881 string_append_template_idx (s, idx)
4885 char buf[INTBUF_SIZE + 1 /* 'T' */];
4886 sprintf(buf, "T%d", idx);
4887 string_append (s, buf);