1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Written by James Clark (jjc@jclark.uucp)
5 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
8 This file is part of the libiberty library.
9 Libiberty is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
14 In addition to the permissions in the GNU Library General Public
15 License, the Free Software Foundation gives you unlimited permission
16 to link the compiled version of this file into combinations with other
17 programs, and to distribute those combinations without any restriction
18 coming from the use of this file. (The Library Public License
19 restrictions do apply in other respects; for example, they cover
20 modification of the file, and distribution when not linked into a
23 Libiberty is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 Library General Public License for more details.
28 You should have received a copy of the GNU Library General Public
29 License along with libiberty; see the file COPYING.LIB. If
30 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
31 Boston, MA 02110-1301, USA. */
33 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
35 This file imports xmalloc and xrealloc, which are like malloc and
36 realloc except that they generate a fatal error if there is no
39 /* This file lives in both GCC and libiberty. When making changes, please
40 try not to break either. */
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 (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 (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 (int ch
)
104 cplus_markers
[0] = ch
;
107 typedef struct string
/* Beware: these aren't required to be */
108 { /* '\0' terminated. */
109 char *b
; /* pointer to start of string */
110 char *p
; /* pointer after last character */
111 char *e
; /* pointer after end of allocated space */
114 /* Stuff that is shared between sub-routines.
115 Using a shared structure allows cplus_demangle to be reentrant. */
131 int static_type
; /* A static member function */
132 int temp_start
; /* index in demangled to start of template args */
133 int type_quals
; /* The type qualifiers. */
134 int dllimported
; /* Symbol imported from a PE DLL */
135 char **tmpl_argvec
; /* Template function arguments. */
136 int ntmpl_args
; /* The number of template function arguments. */
137 int forgetting_types
; /* Nonzero if we are not remembering the types
139 string
* previous_argument
; /* The last function argument demangled. */
140 int nrepeats
; /* The number of times to repeat the previous
144 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
145 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
147 static const struct optable
149 const char *const in
;
150 const char *const out
;
153 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
154 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
155 {"new", " new", 0}, /* old (1.91, and 1.x) */
156 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
157 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
158 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
159 {"as", "=", DMGL_ANSI
}, /* ansi */
160 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
161 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
162 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
163 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
164 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
165 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
166 {"plus", "+", 0}, /* old */
167 {"pl", "+", DMGL_ANSI
}, /* ansi */
168 {"apl", "+=", DMGL_ANSI
}, /* ansi */
169 {"minus", "-", 0}, /* old */
170 {"mi", "-", DMGL_ANSI
}, /* ansi */
171 {"ami", "-=", DMGL_ANSI
}, /* ansi */
172 {"mult", "*", 0}, /* old */
173 {"ml", "*", DMGL_ANSI
}, /* ansi */
174 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
175 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
176 {"convert", "+", 0}, /* old (unary +) */
177 {"negate", "-", 0}, /* old (unary -) */
178 {"trunc_mod", "%", 0}, /* old */
179 {"md", "%", DMGL_ANSI
}, /* ansi */
180 {"amd", "%=", DMGL_ANSI
}, /* ansi */
181 {"trunc_div", "/", 0}, /* old */
182 {"dv", "/", DMGL_ANSI
}, /* ansi */
183 {"adv", "/=", DMGL_ANSI
}, /* ansi */
184 {"truth_andif", "&&", 0}, /* old */
185 {"aa", "&&", DMGL_ANSI
}, /* ansi */
186 {"truth_orif", "||", 0}, /* old */
187 {"oo", "||", DMGL_ANSI
}, /* ansi */
188 {"truth_not", "!", 0}, /* old */
189 {"nt", "!", DMGL_ANSI
}, /* ansi */
190 {"postincrement","++", 0}, /* old */
191 {"pp", "++", DMGL_ANSI
}, /* ansi */
192 {"postdecrement","--", 0}, /* old */
193 {"mm", "--", DMGL_ANSI
}, /* ansi */
194 {"bit_ior", "|", 0}, /* old */
195 {"or", "|", DMGL_ANSI
}, /* ansi */
196 {"aor", "|=", DMGL_ANSI
}, /* ansi */
197 {"bit_xor", "^", 0}, /* old */
198 {"er", "^", DMGL_ANSI
}, /* ansi */
199 {"aer", "^=", DMGL_ANSI
}, /* ansi */
200 {"bit_and", "&", 0}, /* old */
201 {"ad", "&", DMGL_ANSI
}, /* ansi */
202 {"aad", "&=", DMGL_ANSI
}, /* ansi */
203 {"bit_not", "~", 0}, /* old */
204 {"co", "~", DMGL_ANSI
}, /* ansi */
205 {"call", "()", 0}, /* old */
206 {"cl", "()", DMGL_ANSI
}, /* ansi */
207 {"alshift", "<<", 0}, /* old */
208 {"ls", "<<", DMGL_ANSI
}, /* ansi */
209 {"als", "<<=", DMGL_ANSI
}, /* ansi */
210 {"arshift", ">>", 0}, /* old */
211 {"rs", ">>", DMGL_ANSI
}, /* ansi */
212 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
213 {"component", "->", 0}, /* old */
214 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
215 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
216 {"indirect", "*", 0}, /* old */
217 {"method_call", "->()", 0}, /* old */
218 {"addr", "&", 0}, /* old (unary &) */
219 {"array", "[]", 0}, /* old */
220 {"vc", "[]", DMGL_ANSI
}, /* ansi */
221 {"compound", ", ", 0}, /* old */
222 {"cm", ", ", DMGL_ANSI
}, /* ansi */
223 {"cond", "?:", 0}, /* old */
224 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
225 {"max", ">?", 0}, /* old */
226 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
227 {"min", "<?", 0}, /* old */
228 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
229 {"nop", "", 0}, /* old (for operator=) */
230 {"rm", "->*", DMGL_ANSI
}, /* ansi */
231 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
234 /* These values are used to indicate the various type varieties.
235 They are all non-zero so that they can be used as `success'
237 typedef enum type_kind_t
248 const struct demangler_engine libiberty_demanglers
[] =
251 NO_DEMANGLING_STYLE_STRING
,
253 "Demangling disabled"
257 AUTO_DEMANGLING_STYLE_STRING
,
259 "Automatic selection based on executable"
263 GNU_DEMANGLING_STYLE_STRING
,
265 "GNU (g++) style demangling"
269 LUCID_DEMANGLING_STYLE_STRING
,
271 "Lucid (lcc) style demangling"
275 ARM_DEMANGLING_STYLE_STRING
,
277 "ARM style demangling"
281 HP_DEMANGLING_STYLE_STRING
,
283 "HP (aCC) style demangling"
287 EDG_DEMANGLING_STYLE_STRING
,
289 "EDG style demangling"
293 GNU_V3_DEMANGLING_STYLE_STRING
,
295 "GNU (g++) V3 ABI-style demangling"
299 JAVA_DEMANGLING_STYLE_STRING
,
301 "Java style demangling"
305 GNAT_DEMANGLING_STYLE_STRING
,
307 "GNAT style demangling"
311 NULL
, unknown_demangling
, NULL
315 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
316 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
317 string_append(str, " ");}
318 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
320 /* The scope separator appropriate for the language being demangled. */
322 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
324 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
325 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
327 /* Prototypes for local functions */
329 static void delete_work_stuff (struct work_stuff
*);
331 static void delete_non_B_K_work_stuff (struct work_stuff
*);
333 static char *mop_up (struct work_stuff
*, string
*, int);
335 static void squangle_mop_up (struct work_stuff
*);
337 static void work_stuff_copy_to_from (struct work_stuff
*, struct work_stuff
*);
341 demangle_method_args (struct work_stuff
*, const char **, string
*);
345 internal_cplus_demangle (struct work_stuff
*, const char *);
348 demangle_template_template_parm (struct work_stuff
*work
,
349 const char **, string
*);
352 demangle_template (struct work_stuff
*work
, const char **, string
*,
356 arm_pt (struct work_stuff
*, const char *, int, const char **,
360 demangle_class_name (struct work_stuff
*, const char **, string
*);
363 demangle_qualified (struct work_stuff
*, const char **, string
*,
366 static int demangle_class (struct work_stuff
*, const char **, string
*);
368 static int demangle_fund_type (struct work_stuff
*, const char **, string
*);
370 static int demangle_signature (struct work_stuff
*, const char **, string
*);
372 static int demangle_prefix (struct work_stuff
*, const char **, string
*);
374 static int gnu_special (struct work_stuff
*, const char **, string
*);
376 static int arm_special (const char **, string
*);
378 static void string_need (string
*, int);
380 static void string_delete (string
*);
383 string_init (string
*);
385 static void string_clear (string
*);
388 static int string_empty (string
*);
391 static void string_append (string
*, const char *);
393 static void string_appends (string
*, string
*);
395 static void string_appendn (string
*, const char *, int);
397 static void string_prepend (string
*, const char *);
399 static void string_prependn (string
*, const char *, int);
401 static void string_append_template_idx (string
*, int);
403 static int get_count (const char **, int *);
405 static int consume_count (const char **);
407 static int consume_count_with_underscores (const char**);
409 static int demangle_args (struct work_stuff
*, const char **, string
*);
411 static int demangle_nested_args (struct work_stuff
*, const char**, string
*);
413 static int do_type (struct work_stuff
*, const char **, string
*);
415 static int do_arg (struct work_stuff
*, const char **, string
*);
418 demangle_function_name (struct work_stuff
*, const char **, string
*,
422 iterate_demangle_function (struct work_stuff
*,
423 const char **, string
*, const char *);
425 static void remember_type (struct work_stuff
*, const char *, int);
427 static void remember_Btype (struct work_stuff
*, const char *, int, int);
429 static int register_Btype (struct work_stuff
*);
431 static void remember_Ktype (struct work_stuff
*, const char *, int);
433 static void forget_types (struct work_stuff
*);
435 static void forget_B_and_K_types (struct work_stuff
*);
437 static void string_prepends (string
*, string
*);
440 demangle_template_value_parm (struct work_stuff
*, const char**,
441 string
*, type_kind_t
);
444 do_hpacc_template_const_value (struct work_stuff
*, const char **, string
*);
447 do_hpacc_template_literal (struct work_stuff
*, const char **, string
*);
449 static int snarf_numeric_literal (const char **, string
*);
451 /* There is a TYPE_QUAL value for each type qualifier. They can be
452 combined by bitwise-or to form the complete set of qualifiers for a
455 #define TYPE_UNQUALIFIED 0x0
456 #define TYPE_QUAL_CONST 0x1
457 #define TYPE_QUAL_VOLATILE 0x2
458 #define TYPE_QUAL_RESTRICT 0x4
460 static int code_for_qualifier (int);
462 static const char* qualifier_string (int);
464 static const char* demangle_qualifier (int);
466 static int demangle_expression (struct work_stuff
*, const char **, string
*,
470 demangle_integral_value (struct work_stuff
*, const char **, string
*);
473 demangle_real_value (struct work_stuff
*, const char **, string
*);
476 demangle_arm_hp_template (struct work_stuff
*, const char **, int, string
*);
479 recursively_demangle (struct work_stuff
*, const char **, string
*, int);
481 static void grow_vect (char **, size_t *, size_t, int);
483 /* Translate count to integer, consuming tokens in the process.
484 Conversion terminates on the first non-digit character.
486 Trying to consume something that isn't a count results in no
487 consumption of input and a return of -1.
489 Overflow consumes the rest of the digits, and returns -1. */
492 consume_count (const char **type
)
496 if (! ISDIGIT ((unsigned char)**type
))
499 while (ISDIGIT ((unsigned char)**type
))
503 /* Check for overflow.
504 We assume that count is represented using two's-complement;
505 no power of two is divisible by ten, so if an overflow occurs
506 when multiplying by ten, the result will not be a multiple of
508 if ((count
% 10) != 0)
510 while (ISDIGIT ((unsigned char) **type
))
515 count
+= **type
- '0';
526 /* Like consume_count, but for counts that are preceded and followed
527 by '_' if they are greater than 10. Also, -1 is returned for
528 failure, since 0 can be a valid value. */
531 consume_count_with_underscores (const char **mangled
)
535 if (**mangled
== '_')
538 if (!ISDIGIT ((unsigned char)**mangled
))
541 idx
= consume_count (mangled
);
542 if (**mangled
!= '_')
543 /* The trailing underscore was missing. */
550 if (**mangled
< '0' || **mangled
> '9')
553 idx
= **mangled
- '0';
560 /* C is the code for a type-qualifier. Return the TYPE_QUAL
561 corresponding to this qualifier. */
564 code_for_qualifier (int c
)
569 return TYPE_QUAL_CONST
;
572 return TYPE_QUAL_VOLATILE
;
575 return TYPE_QUAL_RESTRICT
;
581 /* C was an invalid qualifier. */
585 /* Return the string corresponding to the qualifiers given by
589 qualifier_string (int type_quals
)
593 case TYPE_UNQUALIFIED
:
596 case TYPE_QUAL_CONST
:
599 case TYPE_QUAL_VOLATILE
:
602 case TYPE_QUAL_RESTRICT
:
605 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
606 return "const volatile";
608 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
609 return "const __restrict";
611 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
612 return "volatile __restrict";
614 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
615 return "const volatile __restrict";
621 /* TYPE_QUALS was an invalid qualifier set. */
625 /* C is the code for a type-qualifier. Return the string
626 corresponding to this qualifier. This function should only be
627 called with a valid qualifier code. */
630 demangle_qualifier (int c
)
632 return qualifier_string (code_for_qualifier (c
));
636 cplus_demangle_opname (const char *opname
, char *result
, int options
)
640 struct work_stuff work
[1];
643 len
= strlen(opname
);
646 memset ((char *) work
, 0, sizeof (work
));
647 work
->options
= options
;
649 if (opname
[0] == '_' && opname
[1] == '_'
650 && opname
[2] == 'o' && opname
[3] == 'p')
653 /* type conversion operator. */
655 if (do_type (work
, &tem
, &type
))
657 strcat (result
, "operator ");
658 strncat (result
, type
.b
, type
.p
- type
.b
);
659 string_delete (&type
);
663 else if (opname
[0] == '_' && opname
[1] == '_'
664 && ISLOWER((unsigned char)opname
[2])
665 && ISLOWER((unsigned char)opname
[3]))
667 if (opname
[4] == '\0')
671 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
673 if (strlen (optable
[i
].in
) == 2
674 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
676 strcat (result
, "operator");
677 strcat (result
, optable
[i
].out
);
685 if (opname
[2] == 'a' && opname
[5] == '\0')
689 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
691 if (strlen (optable
[i
].in
) == 3
692 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
694 strcat (result
, "operator");
695 strcat (result
, optable
[i
].out
);
706 && strchr (cplus_markers
, opname
[2]) != NULL
)
708 /* see if it's an assignment expression */
709 if (len
>= 10 /* op$assign_ */
710 && memcmp (opname
+ 3, "assign_", 7) == 0)
713 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
716 if ((int) strlen (optable
[i
].in
) == len1
717 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
719 strcat (result
, "operator");
720 strcat (result
, optable
[i
].out
);
721 strcat (result
, "=");
730 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
733 if ((int) strlen (optable
[i
].in
) == len1
734 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
736 strcat (result
, "operator");
737 strcat (result
, optable
[i
].out
);
744 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
745 && strchr (cplus_markers
, opname
[4]) != NULL
)
747 /* type conversion operator */
749 if (do_type (work
, &tem
, &type
))
751 strcat (result
, "operator ");
752 strncat (result
, type
.b
, type
.p
- type
.b
);
753 string_delete (&type
);
757 squangle_mop_up (work
);
762 /* Takes operator name as e.g. "++" and returns mangled
763 operator name (e.g. "postincrement_expr"), or NULL if not found.
765 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
766 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
769 cplus_mangle_opname (const char *opname
, int options
)
774 len
= strlen (opname
);
775 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
777 if ((int) strlen (optable
[i
].out
) == len
778 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
779 && memcmp (optable
[i
].out
, opname
, len
) == 0)
780 return optable
[i
].in
;
785 /* Add a routine to set the demangling style to be sure it is valid and
786 allow for any demangler initialization that maybe necessary. */
788 enum demangling_styles
789 cplus_demangle_set_style (enum demangling_styles style
)
791 const struct demangler_engine
*demangler
= libiberty_demanglers
;
793 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
794 if (style
== demangler
->demangling_style
)
796 current_demangling_style
= style
;
797 return current_demangling_style
;
800 return unknown_demangling
;
803 /* Do string name to style translation */
805 enum demangling_styles
806 cplus_demangle_name_to_style (const char *name
)
808 const struct demangler_engine
*demangler
= libiberty_demanglers
;
810 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
811 if (strcmp (name
, demangler
->demangling_style_name
) == 0)
812 return demangler
->demangling_style
;
814 return unknown_demangling
;
817 /* char *cplus_demangle (const char *mangled, int options)
819 If MANGLED is a mangled function name produced by GNU C++, then
820 a pointer to a @code{malloc}ed string giving a C++ representation
821 of the name will be returned; otherwise NULL will be returned.
822 It is the caller's responsibility to free the string which
825 The OPTIONS arg may contain one or more of the following bits:
827 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
829 DMGL_PARAMS Function parameters are included.
833 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
834 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
835 cplus_demangle ("foo__1Ai", 0) => "A::foo"
837 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
838 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
839 cplus_demangle ("foo__1Afe", 0) => "A::foo"
841 Note that any leading underscores, or other such characters prepended by
842 the compilation system, are presumed to have already been stripped from
846 cplus_demangle (const char *mangled
, int options
)
849 struct work_stuff work
[1];
851 if (current_demangling_style
== no_demangling
)
852 return xstrdup (mangled
);
854 memset ((char *) work
, 0, sizeof (work
));
855 work
->options
= options
;
856 if ((work
->options
& DMGL_STYLE_MASK
) == 0)
857 work
->options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
859 /* The V3 ABI demangling is implemented elsewhere. */
860 if (GNU_V3_DEMANGLING
|| AUTO_DEMANGLING
)
862 ret
= cplus_demangle_v3 (mangled
, work
->options
);
863 if (ret
|| GNU_V3_DEMANGLING
)
869 ret
= java_demangle_v3 (mangled
);
875 return ada_demangle(mangled
,options
);
877 ret
= internal_cplus_demangle (work
, mangled
);
878 squangle_mop_up (work
);
883 /* Assuming *OLD_VECT points to an array of *SIZE objects of size
884 ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
885 updating *OLD_VECT and *SIZE as necessary. */
888 grow_vect (char **old_vect
, size_t *size
, size_t min_size
, int element_size
)
890 if (*size
< min_size
)
893 if (*size
< min_size
)
895 *old_vect
= XRESIZEVAR (char, *old_vect
, *size
* element_size
);
899 /* Demangle ada names:
900 1. Discard final __{DIGIT}+ or ${DIGIT}+
901 2. Convert other instances of embedded "__" to `.'.
902 3. Discard leading _ada_.
903 4. Remove everything after first ___ if it is followed by 'X'.
904 5. Put symbols that should be suppressed in <...> brackets.
905 The resulting string is valid until the next call of ada_demangle. */
908 ada_demangle (const char *mangled
, int option ATTRIBUTE_UNUSED
)
913 char *demangled
= NULL
;
915 size_t demangled_size
= 0;
919 if (strncmp (mangled
, "_ada_", 5) == 0)
925 if (mangled
[0] == '_' || mangled
[0] == '<')
928 p
= strstr (mangled
, "___");
930 len0
= strlen (mangled
);
942 /* Make demangled big enough for possible expansion by operator name. */
943 grow_vect (&demangled
,
944 &demangled_size
, 2 * len0
+ 1,
947 if (ISDIGIT ((unsigned char) mangled
[len0
- 1])) {
948 for (i
= len0
- 2; i
>= 0 && ISDIGIT ((unsigned char) mangled
[i
]); i
-= 1)
950 if (i
> 1 && mangled
[i
] == '_' && mangled
[i
- 1] == '_')
955 else if (mangled
[i
] == '$')
962 for (i
= 0, j
= 0; i
< len0
&& ! ISALPHA ((unsigned char)mangled
[i
]);
964 demangled
[j
] = mangled
[i
];
968 if (i
< len0
- 2 && mangled
[i
] == '_' && mangled
[i
+ 1] == '_')
976 demangled
[j
] = mangled
[i
];
980 demangled
[j
] = '\000';
982 for (i
= 0; demangled
[i
] != '\0'; i
+= 1)
983 if (ISUPPER ((unsigned char)demangled
[i
]) || demangled
[i
] == ' ')
995 grow_vect (&demangled
,
996 &demangled_size
, strlen (mangled
) + 3,
999 if (mangled
[0] == '<')
1000 strcpy (demangled
, mangled
);
1002 sprintf (demangled
, "<%s>", mangled
);
1007 /* This function performs most of what cplus_demangle use to do, but
1008 to be able to demangle a name with a B, K or n code, we need to
1009 have a longer term memory of what types have been seen. The original
1010 now initializes and cleans up the squangle code info, while internal
1011 calls go directly to this routine to avoid resetting that info. */
1014 internal_cplus_demangle (struct work_stuff
*work
, const char *mangled
)
1019 char *demangled
= NULL
;
1021 s1
= work
->constructor
;
1022 s2
= work
->destructor
;
1023 s3
= work
->static_type
;
1024 s4
= work
->type_quals
;
1025 work
->constructor
= work
->destructor
= 0;
1026 work
->type_quals
= TYPE_UNQUALIFIED
;
1027 work
->dllimported
= 0;
1029 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
1031 string_init (&decl
);
1033 /* First check to see if gnu style demangling is active and if the
1034 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1035 recognize one of the gnu special forms rather than looking for a
1036 standard prefix. In particular, don't worry about whether there
1037 is a "__" string in the mangled string. Consider "_$_5__foo" for
1040 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
1042 success
= gnu_special (work
, &mangled
, &decl
);
1046 success
= demangle_prefix (work
, &mangled
, &decl
);
1048 if (success
&& (*mangled
!= '\0'))
1050 success
= demangle_signature (work
, &mangled
, &decl
);
1052 if (work
->constructor
== 2)
1054 string_prepend (&decl
, "global constructors keyed to ");
1055 work
->constructor
= 0;
1057 else if (work
->destructor
== 2)
1059 string_prepend (&decl
, "global destructors keyed to ");
1060 work
->destructor
= 0;
1062 else if (work
->dllimported
== 1)
1064 string_prepend (&decl
, "import stub for ");
1065 work
->dllimported
= 0;
1067 demangled
= mop_up (work
, &decl
, success
);
1069 work
->constructor
= s1
;
1070 work
->destructor
= s2
;
1071 work
->static_type
= s3
;
1072 work
->type_quals
= s4
;
1077 /* Clear out and squangling related storage */
1079 squangle_mop_up (struct work_stuff
*work
)
1081 /* clean up the B and K type mangling types. */
1082 forget_B_and_K_types (work
);
1083 if (work
-> btypevec
!= NULL
)
1085 free ((char *) work
-> btypevec
);
1087 if (work
-> ktypevec
!= NULL
)
1089 free ((char *) work
-> ktypevec
);
1094 /* Copy the work state and storage. */
1097 work_stuff_copy_to_from (struct work_stuff
*to
, struct work_stuff
*from
)
1101 delete_work_stuff (to
);
1103 /* Shallow-copy scalars. */
1104 memcpy (to
, from
, sizeof (*to
));
1106 /* Deep-copy dynamic storage. */
1107 if (from
->typevec_size
)
1108 to
->typevec
= XNEWVEC (char *, from
->typevec_size
);
1110 for (i
= 0; i
< from
->ntypes
; i
++)
1112 int len
= strlen (from
->typevec
[i
]) + 1;
1114 to
->typevec
[i
] = XNEWVEC (char, len
);
1115 memcpy (to
->typevec
[i
], from
->typevec
[i
], len
);
1119 to
->ktypevec
= XNEWVEC (char *, from
->ksize
);
1121 for (i
= 0; i
< from
->numk
; i
++)
1123 int len
= strlen (from
->ktypevec
[i
]) + 1;
1125 to
->ktypevec
[i
] = XNEWVEC (char, len
);
1126 memcpy (to
->ktypevec
[i
], from
->ktypevec
[i
], len
);
1130 to
->btypevec
= XNEWVEC (char *, from
->bsize
);
1132 for (i
= 0; i
< from
->numb
; i
++)
1134 int len
= strlen (from
->btypevec
[i
]) + 1;
1136 to
->btypevec
[i
] = XNEWVEC (char , len
);
1137 memcpy (to
->btypevec
[i
], from
->btypevec
[i
], len
);
1140 if (from
->ntmpl_args
)
1141 to
->tmpl_argvec
= XNEWVEC (char *, from
->ntmpl_args
);
1143 for (i
= 0; i
< from
->ntmpl_args
; i
++)
1145 int len
= strlen (from
->tmpl_argvec
[i
]) + 1;
1147 to
->tmpl_argvec
[i
] = XNEWVEC (char, len
);
1148 memcpy (to
->tmpl_argvec
[i
], from
->tmpl_argvec
[i
], len
);
1151 if (from
->previous_argument
)
1153 to
->previous_argument
= XNEW (string
);
1154 string_init (to
->previous_argument
);
1155 string_appends (to
->previous_argument
, from
->previous_argument
);
1160 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1163 delete_non_B_K_work_stuff (struct work_stuff
*work
)
1165 /* Discard the remembered types, if any. */
1167 forget_types (work
);
1168 if (work
-> typevec
!= NULL
)
1170 free ((char *) work
-> typevec
);
1171 work
-> typevec
= NULL
;
1172 work
-> typevec_size
= 0;
1174 if (work
->tmpl_argvec
)
1178 for (i
= 0; i
< work
->ntmpl_args
; i
++)
1179 if (work
->tmpl_argvec
[i
])
1180 free ((char*) work
->tmpl_argvec
[i
]);
1182 free ((char*) work
->tmpl_argvec
);
1183 work
->tmpl_argvec
= NULL
;
1185 if (work
->previous_argument
)
1187 string_delete (work
->previous_argument
);
1188 free ((char*) work
->previous_argument
);
1189 work
->previous_argument
= NULL
;
1194 /* Delete all dynamic storage in work_stuff. */
1196 delete_work_stuff (struct work_stuff
*work
)
1198 delete_non_B_K_work_stuff (work
);
1199 squangle_mop_up (work
);
1203 /* Clear out any mangled storage */
1206 mop_up (struct work_stuff
*work
, string
*declp
, int success
)
1208 char *demangled
= NULL
;
1210 delete_non_B_K_work_stuff (work
);
1212 /* If demangling was successful, ensure that the demangled string is null
1213 terminated and return it. Otherwise, free the demangling decl. */
1217 string_delete (declp
);
1221 string_appendn (declp
, "", 1);
1222 demangled
= declp
->b
;
1231 demangle_signature -- demangle the signature part of a mangled name
1236 demangle_signature (struct work_stuff *work, const char **mangled,
1241 Consume and demangle the signature portion of the mangled name.
1243 DECLP is the string where demangled output is being built. At
1244 entry it contains the demangled root name from the mangled name
1245 prefix. I.E. either a demangled operator name or the root function
1246 name. In some special cases, it may contain nothing.
1248 *MANGLED points to the current unconsumed location in the mangled
1249 name. As tokens are consumed and demangling is performed, the
1250 pointer is updated to continuously point at the next token to
1253 Demangling GNU style mangled names is nasty because there is no
1254 explicit token that marks the start of the outermost function
1258 demangle_signature (struct work_stuff
*work
,
1259 const char **mangled
, string
*declp
)
1263 int expect_func
= 0;
1264 int expect_return_type
= 0;
1265 const char *oldmangled
= NULL
;
1269 while (success
&& (**mangled
!= '\0'))
1274 oldmangled
= *mangled
;
1275 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1277 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1278 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1284 oldmangled
= *mangled
;
1285 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1286 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1294 /* Static member function */
1295 if (oldmangled
== NULL
)
1297 oldmangled
= *mangled
;
1300 work
-> static_type
= 1;
1306 work
->type_quals
|= code_for_qualifier (**mangled
);
1308 /* a qualified member function */
1309 if (oldmangled
== NULL
)
1310 oldmangled
= *mangled
;
1315 /* Local class name follows after "Lnnn_" */
1318 while (**mangled
&& (**mangled
!= '_'))
1329 case '0': case '1': case '2': case '3': case '4':
1330 case '5': case '6': case '7': case '8': case '9':
1331 if (oldmangled
== NULL
)
1333 oldmangled
= *mangled
;
1335 work
->temp_start
= -1; /* uppermost call to demangle_class */
1336 success
= demangle_class (work
, mangled
, declp
);
1339 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1341 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1343 /* EDG and others will have the "F", so we let the loop cycle
1344 if we are looking at one. */
1345 if (**mangled
!= 'F')
1354 success
= do_type (work
, mangled
, &s
);
1357 string_append (&s
, SCOPE_STRING (work
));
1358 string_prepends (declp
, &s
);
1368 /* ARM/HP style demangling includes a specific 'F' character after
1369 the class name. For GNU style, it is just implied. So we can
1370 safely just consume any 'F' at this point and be compatible
1371 with either style. */
1377 /* For lucid/ARM/HP style we have to forget any types we might
1378 have remembered up to this point, since they were not argument
1379 types. GNU style considers all types seen as available for
1380 back references. See comment in demangle_args() */
1382 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1384 forget_types (work
);
1386 success
= demangle_args (work
, mangled
, declp
);
1387 /* After picking off the function args, we expect to either
1388 find the function return type (preceded by an '_') or the
1389 end of the string. */
1390 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1393 /* At this level, we do not care about the return type. */
1394 success
= do_type (work
, mangled
, &tname
);
1395 string_delete (&tname
);
1402 string_init(&trawname
);
1403 string_init(&tname
);
1404 if (oldmangled
== NULL
)
1406 oldmangled
= *mangled
;
1408 success
= demangle_template (work
, mangled
, &tname
,
1412 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1414 string_append (&tname
, SCOPE_STRING (work
));
1416 string_prepends(declp
, &tname
);
1417 if (work
-> destructor
& 1)
1419 string_prepend (&trawname
, "~");
1420 string_appends (declp
, &trawname
);
1421 work
->destructor
-= 1;
1423 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1425 string_appends (declp
, &trawname
);
1426 work
->constructor
-= 1;
1428 string_delete(&trawname
);
1429 string_delete(&tname
);
1435 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
) && expect_return_type
)
1437 /* Read the return type. */
1441 success
= do_type (work
, mangled
, &return_type
);
1442 APPEND_BLANK (&return_type
);
1444 string_prepends (declp
, &return_type
);
1445 string_delete (&return_type
);
1449 /* At the outermost level, we cannot have a return type specified,
1450 so if we run into another '_' at this point we are dealing with
1451 a mangled name that is either bogus, or has been mangled by
1452 some algorithm we don't know how to deal with. So just
1453 reject the entire demangling. */
1454 /* However, "_nnn" is an expected suffix for alternate entry point
1455 numbered nnn for a function, with HP aCC, so skip over that
1456 without reporting failure. pai/1997-09-04 */
1460 while (**mangled
&& ISDIGIT ((unsigned char)**mangled
))
1468 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1470 /* A G++ template function. Read the template arguments. */
1471 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1473 if (!(work
->constructor
& 1))
1474 expect_return_type
= 1;
1483 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1485 /* Assume we have stumbled onto the first outermost function
1486 argument token, and start processing args. */
1488 success
= demangle_args (work
, mangled
, declp
);
1492 /* Non-GNU demanglers use a specific token to mark the start
1493 of the outermost function argument tokens. Typically 'F',
1494 for ARM/HP-demangling, for example. So if we find something
1495 we are not prepared for, it must be an error. */
1501 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1504 if (success
&& expect_func
)
1507 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1509 forget_types (work
);
1511 success
= demangle_args (work
, mangled
, declp
);
1512 /* Since template include the mangling of their return types,
1513 we must set expect_func to 0 so that we don't try do
1514 demangle more arguments the next time we get here. */
1519 if (success
&& !func_done
)
1521 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1523 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1524 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1525 first case, and need to ensure that the '(void)' gets added to
1526 the current declp. Note that with ARM/HP, the first case
1527 represents the name of a static data member 'foo::bar',
1528 which is in the current declp, so we leave it alone. */
1529 success
= demangle_args (work
, mangled
, declp
);
1532 if (success
&& PRINT_ARG_TYPES
)
1534 if (work
->static_type
)
1535 string_append (declp
, " static");
1536 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1538 APPEND_BLANK (declp
);
1539 string_append (declp
, qualifier_string (work
->type_quals
));
1549 demangle_method_args (struct work_stuff
*work
, const char **mangled
,
1554 if (work
-> static_type
)
1556 string_append (declp
, *mangled
+ 1);
1557 *mangled
+= strlen (*mangled
);
1562 success
= demangle_args (work
, mangled
, declp
);
1570 demangle_template_template_parm (struct work_stuff
*work
,
1571 const char **mangled
, string
*tname
)
1579 string_append (tname
, "template <");
1580 /* get size of template parameter list */
1581 if (get_count (mangled
, &r
))
1583 for (i
= 0; i
< r
; i
++)
1587 string_append (tname
, ", ");
1590 /* Z for type parameters */
1591 if (**mangled
== 'Z')
1594 string_append (tname
, "class");
1596 /* z for template parameters */
1597 else if (**mangled
== 'z')
1601 demangle_template_template_parm (work
, mangled
, tname
);
1609 /* temp is initialized in do_type */
1610 success
= do_type (work
, mangled
, &temp
);
1613 string_appends (tname
, &temp
);
1615 string_delete(&temp
);
1625 if (tname
->p
[-1] == '>')
1626 string_append (tname
, " ");
1627 string_append (tname
, "> class");
1632 demangle_expression (struct work_stuff
*work
, const char **mangled
,
1633 string
*s
, type_kind_t tk
)
1635 int need_operator
= 0;
1639 string_appendn (s
, "(", 1);
1641 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1650 len
= strlen (*mangled
);
1652 for (i
= 0; i
< ARRAY_SIZE (optable
); ++i
)
1654 size_t l
= strlen (optable
[i
].in
);
1657 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1659 string_appendn (s
, " ", 1);
1660 string_append (s
, optable
[i
].out
);
1661 string_appendn (s
, " ", 1);
1674 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1677 if (**mangled
!= 'W')
1681 string_appendn (s
, ")", 1);
1689 demangle_integral_value (struct work_stuff
*work
,
1690 const char **mangled
, string
*s
)
1694 if (**mangled
== 'E')
1695 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1696 else if (**mangled
== 'Q' || **mangled
== 'K')
1697 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1702 /* By default, we let the number decide whether we shall consume an
1704 int multidigit_without_leading_underscore
= 0;
1705 int leave_following_underscore
= 0;
1709 if (**mangled
== '_')
1711 if (mangled
[0][1] == 'm')
1713 /* Since consume_count_with_underscores does not handle the
1714 `m'-prefix we must do it here, using consume_count and
1715 adjusting underscores: we have to consume the underscore
1716 matching the prepended one. */
1717 multidigit_without_leading_underscore
= 1;
1718 string_appendn (s
, "-", 1);
1723 /* Do not consume a following underscore;
1724 consume_count_with_underscores will consume what
1725 should be consumed. */
1726 leave_following_underscore
= 1;
1731 /* Negative numbers are indicated with a leading `m'. */
1732 if (**mangled
== 'm')
1734 string_appendn (s
, "-", 1);
1737 /* Since consume_count_with_underscores does not handle
1738 multi-digit numbers that do not start with an underscore,
1739 and this number can be an integer template parameter,
1740 we have to call consume_count. */
1741 multidigit_without_leading_underscore
= 1;
1742 /* These multi-digit numbers never end on an underscore,
1743 so if there is one then don't eat it. */
1744 leave_following_underscore
= 1;
1747 /* We must call consume_count if we expect to remove a trailing
1748 underscore, since consume_count_with_underscores expects
1749 the leading underscore (that we consumed) if it is to handle
1750 multi-digit numbers. */
1751 if (multidigit_without_leading_underscore
)
1752 value
= consume_count (mangled
);
1754 value
= consume_count_with_underscores (mangled
);
1758 char buf
[INTBUF_SIZE
];
1759 sprintf (buf
, "%d", value
);
1760 string_append (s
, buf
);
1762 /* Numbers not otherwise delimited, might have an underscore
1763 appended as a delimeter, which we should skip.
1765 ??? This used to always remove a following underscore, which
1766 is wrong. If other (arbitrary) cases are followed by an
1767 underscore, we need to do something more radical. */
1769 if ((value
> 9 || multidigit_without_leading_underscore
)
1770 && ! leave_following_underscore
1771 && **mangled
== '_')
1782 /* Demangle the real value in MANGLED. */
1785 demangle_real_value (struct work_stuff
*work
,
1786 const char **mangled
, string
*s
)
1788 if (**mangled
== 'E')
1789 return demangle_expression (work
, mangled
, s
, tk_real
);
1791 if (**mangled
== 'm')
1793 string_appendn (s
, "-", 1);
1796 while (ISDIGIT ((unsigned char)**mangled
))
1798 string_appendn (s
, *mangled
, 1);
1801 if (**mangled
== '.') /* fraction */
1803 string_appendn (s
, ".", 1);
1805 while (ISDIGIT ((unsigned char)**mangled
))
1807 string_appendn (s
, *mangled
, 1);
1811 if (**mangled
== 'e') /* exponent */
1813 string_appendn (s
, "e", 1);
1815 while (ISDIGIT ((unsigned char)**mangled
))
1817 string_appendn (s
, *mangled
, 1);
1826 demangle_template_value_parm (struct work_stuff
*work
, const char **mangled
,
1827 string
*s
, type_kind_t tk
)
1831 if (**mangled
== 'Y')
1833 /* The next argument is a template parameter. */
1837 idx
= consume_count_with_underscores (mangled
);
1839 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1840 || consume_count_with_underscores (mangled
) == -1)
1842 if (work
->tmpl_argvec
)
1843 string_append (s
, work
->tmpl_argvec
[idx
]);
1845 string_append_template_idx (s
, idx
);
1847 else if (tk
== tk_integral
)
1848 success
= demangle_integral_value (work
, mangled
, s
);
1849 else if (tk
== tk_char
)
1853 if (**mangled
== 'm')
1855 string_appendn (s
, "-", 1);
1858 string_appendn (s
, "'", 1);
1859 val
= consume_count(mangled
);
1866 string_appendn (s
, &tmp
[0], 1);
1867 string_appendn (s
, "'", 1);
1870 else if (tk
== tk_bool
)
1872 int val
= consume_count (mangled
);
1874 string_appendn (s
, "false", 5);
1876 string_appendn (s
, "true", 4);
1880 else if (tk
== tk_real
)
1881 success
= demangle_real_value (work
, mangled
, s
);
1882 else if (tk
== tk_pointer
|| tk
== tk_reference
)
1884 if (**mangled
== 'Q')
1885 success
= demangle_qualified (work
, mangled
, s
,
1890 int symbol_len
= consume_count (mangled
);
1891 if (symbol_len
== -1)
1893 if (symbol_len
== 0)
1894 string_appendn (s
, "0", 1);
1897 char *p
= XNEWVEC (char, symbol_len
+ 1), *q
;
1898 strncpy (p
, *mangled
, symbol_len
);
1899 p
[symbol_len
] = '\0';
1900 /* We use cplus_demangle here, rather than
1901 internal_cplus_demangle, because the name of the entity
1902 mangled here does not make use of any of the squangling
1903 or type-code information we have built up thus far; it is
1904 mangled independently. */
1905 q
= cplus_demangle (p
, work
->options
);
1906 if (tk
== tk_pointer
)
1907 string_appendn (s
, "&", 1);
1908 /* FIXME: Pointer-to-member constants should get a
1909 qualifying class name here. */
1912 string_append (s
, q
);
1916 string_append (s
, p
);
1919 *mangled
+= symbol_len
;
1926 /* Demangle the template name in MANGLED. The full name of the
1927 template (e.g., S<int>) is placed in TNAME. The name without the
1928 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1929 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1930 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1931 the template is remembered in the list of back-referenceable
1935 demangle_template (struct work_stuff
*work
, const char **mangled
,
1936 string
*tname
, string
*trawname
,
1937 int is_type
, int remember
)
1943 int is_java_array
= 0;
1949 /* get template name */
1950 if (**mangled
== 'z')
1956 idx
= consume_count_with_underscores (mangled
);
1958 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1959 || consume_count_with_underscores (mangled
) == -1)
1962 if (work
->tmpl_argvec
)
1964 string_append (tname
, work
->tmpl_argvec
[idx
]);
1966 string_append (trawname
, work
->tmpl_argvec
[idx
]);
1970 string_append_template_idx (tname
, idx
);
1972 string_append_template_idx (trawname
, idx
);
1977 if ((r
= consume_count (mangled
)) <= 0
1978 || (int) strlen (*mangled
) < r
)
1982 is_java_array
= (work
-> options
& DMGL_JAVA
)
1983 && strncmp (*mangled
, "JArray1Z", 8) == 0;
1984 if (! is_java_array
)
1986 string_appendn (tname
, *mangled
, r
);
1989 string_appendn (trawname
, *mangled
, r
);
1994 string_append (tname
, "<");
1995 /* get size of template parameter list */
1996 if (!get_count (mangled
, &r
))
2002 /* Create an array for saving the template argument values. */
2003 work
->tmpl_argvec
= XNEWVEC (char *, r
);
2004 work
->ntmpl_args
= r
;
2005 for (i
= 0; i
< r
; i
++)
2006 work
->tmpl_argvec
[i
] = 0;
2008 for (i
= 0; i
< r
; i
++)
2012 string_append (tname
, ", ");
2014 /* Z for type parameters */
2015 if (**mangled
== 'Z')
2018 /* temp is initialized in do_type */
2019 success
= do_type (work
, mangled
, &temp
);
2022 string_appends (tname
, &temp
);
2026 /* Save the template argument. */
2027 int len
= temp
.p
- temp
.b
;
2028 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2029 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
2030 work
->tmpl_argvec
[i
][len
] = '\0';
2033 string_delete(&temp
);
2039 /* z for template parameters */
2040 else if (**mangled
== 'z')
2044 success
= demangle_template_template_parm (work
, mangled
, tname
);
2047 && (r2
= consume_count (mangled
)) > 0
2048 && (int) strlen (*mangled
) >= r2
)
2050 string_append (tname
, " ");
2051 string_appendn (tname
, *mangled
, r2
);
2054 /* Save the template argument. */
2056 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2057 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
2058 work
->tmpl_argvec
[i
][len
] = '\0';
2072 /* otherwise, value parameter */
2074 /* temp is initialized in do_type */
2075 success
= do_type (work
, mangled
, &temp
);
2076 string_delete(&temp
);
2088 success
= demangle_template_value_parm (work
, mangled
, s
,
2089 (type_kind_t
) success
);
2101 int len
= s
->p
- s
->b
;
2102 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2103 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
2104 work
->tmpl_argvec
[i
][len
] = '\0';
2106 string_appends (tname
, s
);
2114 string_append (tname
, "[]");
2118 if (tname
->p
[-1] == '>')
2119 string_append (tname
, " ");
2120 string_append (tname
, ">");
2123 if (is_type
&& remember
)
2125 const int bindex
= register_Btype (work
);
2126 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
2130 if (work -> static_type)
2132 string_append (declp, *mangled + 1);
2133 *mangled += strlen (*mangled);
2138 success = demangle_args (work, mangled, declp);
2146 arm_pt (struct work_stuff
*work
, const char *mangled
,
2147 int n
, const char **anchor
, const char **args
)
2149 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2150 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2151 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= strstr (mangled
, "__pt__")))
2154 *args
= *anchor
+ 6;
2155 len
= consume_count (args
);
2158 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2164 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
2166 if ((*anchor
= strstr (mangled
, "__tm__"))
2167 || (*anchor
= strstr (mangled
, "__ps__"))
2168 || (*anchor
= strstr (mangled
, "__pt__")))
2171 *args
= *anchor
+ 6;
2172 len
= consume_count (args
);
2175 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2181 else if ((*anchor
= strstr (mangled
, "__S")))
2184 *args
= *anchor
+ 3;
2185 len
= consume_count (args
);
2188 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2200 demangle_arm_hp_template (struct work_stuff
*work
, const char **mangled
,
2201 int n
, string
*declp
)
2205 const char *e
= *mangled
+ n
;
2208 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2210 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
2212 char *start_spec_args
= NULL
;
2215 /* First check for and omit template specialization pseudo-arguments,
2216 such as in "Spec<#1,#1.*>" */
2217 start_spec_args
= strchr (*mangled
, '<');
2218 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
2219 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
2221 string_appendn (declp
, *mangled
, n
);
2222 (*mangled
) += n
+ 1;
2224 if (work
->temp_start
== -1) /* non-recursive call */
2225 work
->temp_start
= declp
->p
- declp
->b
;
2227 /* We want to unconditionally demangle parameter types in
2228 template parameters. */
2229 hold_options
= work
->options
;
2230 work
->options
|= DMGL_PARAMS
;
2232 string_append (declp
, "<");
2235 string_delete (&arg
);
2239 /* 'T' signals a type parameter */
2241 if (!do_type (work
, mangled
, &arg
))
2242 goto hpacc_template_args_done
;
2247 /* 'U' or 'S' signals an integral value */
2248 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
2249 goto hpacc_template_args_done
;
2253 /* 'A' signals a named constant expression (literal) */
2254 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
2255 goto hpacc_template_args_done
;
2259 /* Today, 1997-09-03, we have only the above types
2260 of template parameters */
2261 /* FIXME: maybe this should fail and return null */
2262 goto hpacc_template_args_done
;
2264 string_appends (declp
, &arg
);
2265 /* Check if we're at the end of template args.
2266 0 if at end of static member of template class,
2267 _ if done with template args for a function */
2268 if ((**mangled
== '\000') || (**mangled
== '_'))
2271 string_append (declp
, ",");
2273 hpacc_template_args_done
:
2274 string_append (declp
, ">");
2275 string_delete (&arg
);
2276 if (**mangled
== '_')
2278 work
->options
= hold_options
;
2281 /* ARM template? (Also handles HP cfront extensions) */
2282 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
2288 string_appendn (declp
, *mangled
, p
- *mangled
);
2289 if (work
->temp_start
== -1) /* non-recursive call */
2290 work
->temp_start
= declp
->p
- declp
->b
;
2292 /* We want to unconditionally demangle parameter types in
2293 template parameters. */
2294 hold_options
= work
->options
;
2295 work
->options
|= DMGL_PARAMS
;
2297 string_append (declp
, "<");
2298 /* should do error checking here */
2300 string_delete (&arg
);
2302 /* Check for type or literal here */
2305 /* HP cfront extensions to ARM for template args */
2306 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2307 /* FIXME: We handle only numeric literals for HP cfront */
2309 /* A typed constant value follows */
2311 if (!do_type (work
, &args
, &type_str
))
2312 goto cfront_template_args_done
;
2313 string_append (&arg
, "(");
2314 string_appends (&arg
, &type_str
);
2315 string_delete (&type_str
);
2316 string_append (&arg
, ")");
2318 goto cfront_template_args_done
;
2320 /* Now snarf a literal value following 'L' */
2321 if (!snarf_numeric_literal (&args
, &arg
))
2322 goto cfront_template_args_done
;
2326 /* Snarf a literal following 'L' */
2328 if (!snarf_numeric_literal (&args
, &arg
))
2329 goto cfront_template_args_done
;
2332 /* Not handling other HP cfront stuff */
2334 const char* old_args
= args
;
2335 if (!do_type (work
, &args
, &arg
))
2336 goto cfront_template_args_done
;
2338 /* Fail if we didn't make any progress: prevent infinite loop. */
2339 if (args
== old_args
)
2341 work
->options
= hold_options
;
2346 string_appends (declp
, &arg
);
2347 string_append (declp
, ",");
2349 cfront_template_args_done
:
2350 string_delete (&arg
);
2352 --declp
->p
; /* remove extra comma */
2353 string_append (declp
, ">");
2354 work
->options
= hold_options
;
2356 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2357 && (*mangled
)[9] == 'N'
2358 && (*mangled
)[8] == (*mangled
)[10]
2359 && strchr (cplus_markers
, (*mangled
)[8]))
2361 /* A member of the anonymous namespace. */
2362 string_append (declp
, "{anonymous}");
2366 if (work
->temp_start
== -1) /* non-recursive call only */
2367 work
->temp_start
= 0; /* disable in recursive calls */
2368 string_appendn (declp
, *mangled
, n
);
2373 /* Extract a class name, possibly a template with arguments, from the
2374 mangled string; qualifiers, local class indicators, etc. have
2375 already been dealt with */
2378 demangle_class_name (struct work_stuff
*work
, const char **mangled
,
2384 n
= consume_count (mangled
);
2387 if ((int) strlen (*mangled
) >= n
)
2389 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2400 demangle_class -- demangle a mangled class sequence
2405 demangle_class (struct work_stuff *work, const char **mangled,
2410 DECLP points to the buffer into which demangling is being done.
2412 *MANGLED points to the current token to be demangled. On input,
2413 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2414 On exit, it points to the next token after the mangled class on
2415 success, or the first unconsumed token on failure.
2417 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2418 we are demangling a constructor or destructor. In this case
2419 we prepend "class::class" or "class::~class" to DECLP.
2421 Otherwise, we prepend "class::" to the current DECLP.
2423 Reset the constructor/destructor flags once they have been
2424 "consumed". This allows demangle_class to be called later during
2425 the same demangling, to do normal class demangling.
2427 Returns 1 if demangling is successful, 0 otherwise.
2432 demangle_class (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2437 char *save_class_name_end
= 0;
2439 string_init (&class_name
);
2440 btype
= register_Btype (work
);
2441 if (demangle_class_name (work
, mangled
, &class_name
))
2443 save_class_name_end
= class_name
.p
;
2444 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2446 /* adjust so we don't include template args */
2447 if (work
->temp_start
&& (work
->temp_start
!= -1))
2449 class_name
.p
= class_name
.b
+ work
->temp_start
;
2451 string_prepends (declp
, &class_name
);
2452 if (work
-> destructor
& 1)
2454 string_prepend (declp
, "~");
2455 work
-> destructor
-= 1;
2459 work
-> constructor
-= 1;
2462 class_name
.p
= save_class_name_end
;
2463 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2464 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2465 string_prepend (declp
, SCOPE_STRING (work
));
2466 string_prepends (declp
, &class_name
);
2469 string_delete (&class_name
);
2474 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2475 the rightmost guess.
2477 Find the correct "__"-sequence where the function name ends and the
2478 signature starts, which is ambiguous with GNU mangling.
2479 Call demangle_signature here, so we can make sure we found the right
2480 one; *mangled will be consumed so caller will not make further calls to
2481 demangle_signature. */
2484 iterate_demangle_function (struct work_stuff
*work
, const char **mangled
,
2485 string
*declp
, const char *scan
)
2487 const char *mangle_init
= *mangled
;
2490 struct work_stuff work_init
;
2492 if (*(scan
+ 2) == '\0')
2495 /* Do not iterate for some demangling modes, or if there's only one
2496 "__"-sequence. This is the normal case. */
2497 if (ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
2498 || strstr (scan
+ 2, "__") == NULL
)
2499 return demangle_function_name (work
, mangled
, declp
, scan
);
2501 /* Save state so we can restart if the guess at the correct "__" was
2503 string_init (&decl_init
);
2504 string_appends (&decl_init
, declp
);
2505 memset (&work_init
, 0, sizeof work_init
);
2506 work_stuff_copy_to_from (&work_init
, work
);
2508 /* Iterate over occurrences of __, allowing names and types to have a
2509 "__" sequence in them. We must start with the first (not the last)
2510 occurrence, since "__" most often occur between independent mangled
2511 parts, hence starting at the last occurence inside a signature
2512 might get us a "successful" demangling of the signature. */
2516 if (demangle_function_name (work
, mangled
, declp
, scan
))
2518 success
= demangle_signature (work
, mangled
, declp
);
2523 /* Reset demangle state for the next round. */
2524 *mangled
= mangle_init
;
2525 string_clear (declp
);
2526 string_appends (declp
, &decl_init
);
2527 work_stuff_copy_to_from (work
, &work_init
);
2529 /* Leave this underscore-sequence. */
2532 /* Scan for the next "__" sequence. */
2533 while (*scan
&& (scan
[0] != '_' || scan
[1] != '_'))
2536 /* Move to last "__" in this sequence. */
2537 while (*scan
&& *scan
== '_')
2542 /* Delete saved state. */
2543 delete_work_stuff (&work_init
);
2544 string_delete (&decl_init
);
2553 demangle_prefix -- consume the mangled name prefix and find signature
2558 demangle_prefix (struct work_stuff *work, const char **mangled,
2563 Consume and demangle the prefix of the mangled name.
2564 While processing the function name root, arrange to call
2565 demangle_signature if the root is ambiguous.
2567 DECLP points to the string buffer into which demangled output is
2568 placed. On entry, the buffer is empty. On exit it contains
2569 the root function name, the demangled operator name, or in some
2570 special cases either nothing or the completely demangled result.
2572 MANGLED points to the current pointer into the mangled name. As each
2573 token of the mangled name is consumed, it is updated. Upon entry
2574 the current mangled name pointer points to the first character of
2575 the mangled name. Upon exit, it should point to the first character
2576 of the signature if demangling was successful, or to the first
2577 unconsumed character if demangling of the prefix was unsuccessful.
2579 Returns 1 on success, 0 otherwise.
2583 demangle_prefix (struct work_stuff
*work
, const char **mangled
,
2590 if (strlen(*mangled
) > 6
2591 && (strncmp(*mangled
, "_imp__", 6) == 0
2592 || strncmp(*mangled
, "__imp_", 6) == 0))
2594 /* it's a symbol imported from a PE dynamic library. Check for both
2595 new style prefix _imp__ and legacy __imp_ used by older versions
2598 work
->dllimported
= 1;
2600 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2602 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2603 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2605 if ((*mangled
)[9] == 'D')
2607 /* it's a GNU global destructor to be executed at program exit */
2609 work
->destructor
= 2;
2610 if (gnu_special (work
, mangled
, declp
))
2613 else if ((*mangled
)[9] == 'I')
2615 /* it's a GNU global constructor to be executed at program init */
2617 work
->constructor
= 2;
2618 if (gnu_special (work
, mangled
, declp
))
2623 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2625 /* it's a ARM global destructor to be executed at program exit */
2627 work
->destructor
= 2;
2629 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2631 /* it's a ARM global constructor to be executed at program initial */
2633 work
->constructor
= 2;
2636 /* This block of code is a reduction in strength time optimization
2638 scan = strstr (*mangled, "__"); */
2644 scan
= strchr (scan
, '_');
2645 } while (scan
!= NULL
&& *++scan
!= '_');
2647 if (scan
!= NULL
) --scan
;
2652 /* We found a sequence of two or more '_', ensure that we start at
2653 the last pair in the sequence. */
2654 i
= strspn (scan
, "_");
2665 else if (work
-> static_type
)
2667 if (!ISDIGIT ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2672 else if ((scan
== *mangled
)
2673 && (ISDIGIT ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2674 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2676 /* The ARM says nothing about the mangling of local variables.
2677 But cfront mangles local variables by prepending __<nesting_level>
2678 to them. As an extension to ARM demangling we handle this case. */
2679 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2680 && ISDIGIT ((unsigned char)scan
[2]))
2682 *mangled
= scan
+ 2;
2683 consume_count (mangled
);
2684 string_append (declp
, *mangled
);
2685 *mangled
+= strlen (*mangled
);
2690 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2691 names like __Q2_3foo3bar for nested type names. So don't accept
2692 this style of constructor for cfront demangling. A GNU
2693 style member-template constructor starts with 'H'. */
2694 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2695 work
-> constructor
+= 1;
2696 *mangled
= scan
+ 2;
2699 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2701 /* Cfront-style parameterized type. Handled later as a signature. */
2705 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2707 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2708 || (scan
[2] == 'p' && scan
[3] == 's')
2709 || (scan
[2] == 'p' && scan
[3] == 't')))
2711 /* EDG-style parameterized type. Handled later as a signature. */
2715 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2717 else if ((scan
== *mangled
) && !ISDIGIT ((unsigned char)scan
[2])
2718 && (scan
[2] != 't'))
2720 /* Mangled name starts with "__". Skip over any leading '_' characters,
2721 then find the next "__" that separates the prefix from the signature.
2723 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2724 || (arm_special (mangled
, declp
) == 0))
2726 while (*scan
== '_')
2730 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2732 /* No separator (I.E. "__not_mangled"), or empty signature
2733 (I.E. "__not_mangled_either__") */
2737 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2740 else if (*(scan
+ 2) != '\0')
2742 /* Mangled name does not start with "__" but does have one somewhere
2743 in there with non empty stuff after it. Looks like a global
2744 function name. Iterate over all "__":s until the right
2746 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2750 /* Doesn't look like a mangled name */
2754 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2756 string_append (declp
, *mangled
);
2757 *mangled
+= strlen (*mangled
);
2767 gnu_special -- special handling of gnu mangled strings
2772 gnu_special (struct work_stuff *work, const char **mangled,
2778 Process some special GNU style mangling forms that don't fit
2779 the normal pattern. For example:
2781 _$_3foo (destructor for class foo)
2782 _vt$foo (foo virtual table)
2783 _vt$foo$bar (foo::bar virtual table)
2784 __vt_foo (foo virtual table, new style with thunks)
2785 _3foo$varname (static data member)
2786 _Q22rs2tu$vw (static data member)
2787 __t6vector1Zii (constructor with template)
2788 __thunk_4__$_7ostream (virtual function thunk)
2792 gnu_special (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2798 if ((*mangled
)[0] == '_'
2799 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2800 && (*mangled
)[2] == '_')
2802 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2804 work
-> destructor
+= 1;
2806 else if ((*mangled
)[0] == '_'
2807 && (((*mangled
)[1] == '_'
2808 && (*mangled
)[2] == 'v'
2809 && (*mangled
)[3] == 't'
2810 && (*mangled
)[4] == '_')
2811 || ((*mangled
)[1] == 'v'
2812 && (*mangled
)[2] == 't'
2813 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2815 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2816 and create the decl. Note that we consume the entire mangled
2817 input string, which means that demangle_signature has no work
2819 if ((*mangled
)[2] == 'v')
2820 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2822 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2823 while (**mangled
!= '\0')
2829 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2832 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2836 if (ISDIGIT((unsigned char)*mangled
[0]))
2838 n
= consume_count(mangled
);
2839 /* We may be seeing a too-large size, or else a
2840 ".<digits>" indicating a static local symbol. In
2841 any case, declare victory and move on; *don't* try
2842 to use n to allocate. */
2843 if (n
> (int) strlen (*mangled
))
2851 n
= strcspn (*mangled
, cplus_markers
);
2853 string_appendn (declp
, *mangled
, n
);
2857 p
= strpbrk (*mangled
, cplus_markers
);
2858 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2862 string_append (declp
, SCOPE_STRING (work
));
2873 string_append (declp
, " virtual table");
2875 else if ((*mangled
)[0] == '_'
2876 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
2877 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
2879 /* static data member, "_3foo$varname" for example */
2885 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2888 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2891 n
= consume_count (mangled
);
2892 if (n
< 0 || n
> (long) strlen (*mangled
))
2898 if (n
> 10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2899 && (*mangled
)[9] == 'N'
2900 && (*mangled
)[8] == (*mangled
)[10]
2901 && strchr (cplus_markers
, (*mangled
)[8]))
2903 /* A member of the anonymous namespace. There's information
2904 about what identifier or filename it was keyed to, but
2905 it's just there to make the mangled name unique; we just
2907 string_append (declp
, "{anonymous}");
2910 /* Now p points to the marker before the N, so we need to
2911 update it to the first marker after what we consumed. */
2912 p
= strpbrk (*mangled
, cplus_markers
);
2916 string_appendn (declp
, *mangled
, n
);
2919 if (success
&& (p
== *mangled
))
2921 /* Consumed everything up to the cplus_marker, append the
2924 string_append (declp
, SCOPE_STRING (work
));
2925 n
= strlen (*mangled
);
2926 string_appendn (declp
, *mangled
, n
);
2934 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
2939 delta
= consume_count (mangled
);
2944 char *method
= internal_cplus_demangle (work
, ++*mangled
);
2949 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
2950 string_append (declp
, buf
);
2951 string_append (declp
, method
);
2953 n
= strlen (*mangled
);
2962 else if (strncmp (*mangled
, "__t", 3) == 0
2963 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
2965 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
2971 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2974 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2977 success
= do_type (work
, mangled
, declp
);
2980 if (success
&& **mangled
!= '\0')
2983 string_append (declp
, p
);
2993 recursively_demangle(struct work_stuff
*work
, const char **mangled
,
2994 string
*result
, int namelength
)
2996 char * recurse
= (char *)NULL
;
2997 char * recurse_dem
= (char *)NULL
;
2999 recurse
= XNEWVEC (char, namelength
+ 1);
3000 memcpy (recurse
, *mangled
, namelength
);
3001 recurse
[namelength
] = '\000';
3003 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3007 string_append (result
, recurse_dem
);
3012 string_appendn (result
, *mangled
, namelength
);
3015 *mangled
+= namelength
;
3022 arm_special -- special handling of ARM/lucid mangled strings
3027 arm_special (const char **mangled,
3033 Process some special ARM style mangling forms that don't fit
3034 the normal pattern. For example:
3036 __vtbl__3foo (foo virtual table)
3037 __vtbl__3foo__3bar (bar::foo virtual table)
3042 arm_special (const char **mangled
, string
*declp
)
3048 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
3050 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3051 and create the decl. Note that we consume the entire mangled
3052 input string, which means that demangle_signature has no work
3054 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
3055 while (*scan
!= '\0') /* first check it can be demangled */
3057 n
= consume_count (&scan
);
3060 return (0); /* no good */
3063 if (scan
[0] == '_' && scan
[1] == '_')
3068 (*mangled
) += ARM_VTABLE_STRLEN
;
3069 while (**mangled
!= '\0')
3071 n
= consume_count (mangled
);
3073 || n
> (long) strlen (*mangled
))
3075 string_prependn (declp
, *mangled
, n
);
3077 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
3079 string_prepend (declp
, "::");
3083 string_append (declp
, " virtual table");
3096 demangle_qualified -- demangle 'Q' qualified name strings
3101 demangle_qualified (struct work_stuff *, const char *mangled,
3102 string *result, int isfuncname, int append);
3106 Demangle a qualified name, such as "Q25Outer5Inner" which is
3107 the mangled form of "Outer::Inner". The demangled output is
3108 prepended or appended to the result string according to the
3109 state of the append flag.
3111 If isfuncname is nonzero, then the qualified name we are building
3112 is going to be used as a member function name, so if it is a
3113 constructor or destructor function, append an appropriate
3114 constructor or destructor name. I.E. for the above example,
3115 the result for use as a constructor is "Outer::Inner::Inner"
3116 and the result for use as a destructor is "Outer::Inner::~Inner".
3120 Numeric conversion is ASCII dependent (FIXME).
3125 demangle_qualified (struct work_stuff
*work
, const char **mangled
,
3126 string
*result
, int isfuncname
, int append
)
3133 int bindex
= register_Btype (work
);
3135 /* We only make use of ISFUNCNAME if the entity is a constructor or
3137 isfuncname
= (isfuncname
3138 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
3140 string_init (&temp
);
3141 string_init (&last_name
);
3143 if ((*mangled
)[0] == 'K')
3145 /* Squangling qualified name reuse */
3148 idx
= consume_count_with_underscores (mangled
);
3149 if (idx
== -1 || idx
>= work
-> numk
)
3152 string_append (&temp
, work
-> ktypevec
[idx
]);
3155 switch ((*mangled
)[1])
3158 /* GNU mangled name with more than 9 classes. The count is preceded
3159 by an underscore (to distinguish it from the <= 9 case) and followed
3160 by an underscore. */
3162 qualifiers
= consume_count_with_underscores (mangled
);
3163 if (qualifiers
== -1)
3176 /* The count is in a single digit. */
3177 num
[0] = (*mangled
)[1];
3179 qualifiers
= atoi (num
);
3181 /* If there is an underscore after the digit, skip it. This is
3182 said to be for ARM-qualified names, but the ARM makes no
3183 mention of such an underscore. Perhaps cfront uses one. */
3184 if ((*mangled
)[2] == '_')
3199 /* Pick off the names and collect them in the temp buffer in the order
3200 in which they are found, separated by '::'. */
3202 while (qualifiers
-- > 0)
3205 string_clear (&last_name
);
3207 if (*mangled
[0] == '_')
3210 if (*mangled
[0] == 't')
3212 /* Here we always append to TEMP since we will want to use
3213 the template name without the template parameters as a
3214 constructor or destructor name. The appropriate
3215 (parameter-less) value is returned by demangle_template
3216 in LAST_NAME. We do not remember the template type here,
3217 in order to match the G++ mangling algorithm. */
3218 success
= demangle_template(work
, mangled
, &temp
,
3223 else if (*mangled
[0] == 'K')
3227 idx
= consume_count_with_underscores (mangled
);
3228 if (idx
== -1 || idx
>= work
->numk
)
3231 string_append (&temp
, work
->ktypevec
[idx
]);
3234 if (!success
) break;
3241 /* Now recursively demangle the qualifier
3242 * This is necessary to deal with templates in
3243 * mangling styles like EDG */
3244 namelength
= consume_count (mangled
);
3245 if (namelength
== -1)
3250 recursively_demangle(work
, mangled
, &temp
, namelength
);
3254 string_delete (&last_name
);
3255 success
= do_type (work
, mangled
, &last_name
);
3258 string_appends (&temp
, &last_name
);
3263 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
3266 string_append (&temp
, SCOPE_STRING (work
));
3269 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
3271 /* If we are using the result as a function name, we need to append
3272 the appropriate '::' separated constructor or destructor name.
3273 We do this here because this is the most convenient place, where
3274 we already have a pointer to the name and the length of the name. */
3278 string_append (&temp
, SCOPE_STRING (work
));
3279 if (work
-> destructor
& 1)
3280 string_append (&temp
, "~");
3281 string_appends (&temp
, &last_name
);
3284 /* Now either prepend the temp buffer to the result, or append it,
3285 depending upon the state of the append flag. */
3288 string_appends (result
, &temp
);
3291 if (!STRING_EMPTY (result
))
3292 string_append (&temp
, SCOPE_STRING (work
));
3293 string_prepends (result
, &temp
);
3296 string_delete (&last_name
);
3297 string_delete (&temp
);
3305 get_count -- convert an ascii count to integer, consuming tokens
3310 get_count (const char **type, int *count)
3314 Assume that *type points at a count in a mangled name; set
3315 *count to its value, and set *type to the next character after
3316 the count. There are some weird rules in effect here.
3318 If *type does not point at a string of digits, return zero.
3320 If *type points at a string of digits followed by an
3321 underscore, set *count to their value as an integer, advance
3322 *type to point *after the underscore, and return 1.
3324 If *type points at a string of digits not followed by an
3325 underscore, consume only the first digit. Set *count to its
3326 value as an integer, leave *type pointing after that digit,
3329 The excuse for this odd behavior: in the ARM and HP demangling
3330 styles, a type can be followed by a repeat count of the form
3333 `x' is a single digit specifying how many additional copies
3334 of the type to append to the argument list, and
3336 `y' is one or more digits, specifying the zero-based index of
3337 the first repeated argument in the list. Yes, as you're
3338 unmangling the name you can figure this out yourself, but
3341 So, for example, in `bar__3fooFPiN51', the first argument is a
3342 pointer to an integer (`Pi'), and then the next five arguments
3343 are the same (`N5'), and the first repeat is the function's
3344 second argument (`1').
3348 get_count (const char **type
, int *count
)
3353 if (!ISDIGIT ((unsigned char)**type
))
3357 *count
= **type
- '0';
3359 if (ISDIGIT ((unsigned char)**type
))
3369 while (ISDIGIT ((unsigned char)*p
));
3380 /* RESULT will be initialised here; it will be freed on failure. The
3381 value returned is really a type_kind_t. */
3384 do_type (struct work_stuff
*work
, const char **mangled
, string
*result
)
3390 const char *remembered_type
;
3392 type_kind_t tk
= tk_none
;
3394 string_init (&decl
);
3395 string_init (result
);
3399 while (success
&& !done
)
3405 /* A pointer type */
3409 if (! (work
-> options
& DMGL_JAVA
))
3410 string_prepend (&decl
, "*");
3415 /* A reference type */
3418 string_prepend (&decl
, "&");
3427 if (!STRING_EMPTY (&decl
)
3428 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3430 string_prepend (&decl
, "(");
3431 string_append (&decl
, ")");
3433 string_append (&decl
, "[");
3434 if (**mangled
!= '_')
3435 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3437 if (**mangled
== '_')
3439 string_append (&decl
, "]");
3443 /* A back reference to a previously seen type */
3446 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3452 remembered_type
= work
-> typevec
[n
];
3453 mangled
= &remembered_type
;
3460 if (!STRING_EMPTY (&decl
)
3461 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3463 string_prepend (&decl
, "(");
3464 string_append (&decl
, ")");
3466 /* After picking off the function args, we expect to either find the
3467 function return type (preceded by an '_') or the end of the
3469 if (!demangle_nested_args (work
, mangled
, &decl
)
3470 || (**mangled
!= '_' && **mangled
!= '\0'))
3475 if (success
&& (**mangled
== '_'))
3482 type_quals
= TYPE_UNQUALIFIED
;
3484 member
= **mangled
== 'M';
3487 string_append (&decl
, ")");
3489 /* We don't need to prepend `::' for a qualified name;
3490 demangle_qualified will do that for us. */
3491 if (**mangled
!= 'Q')
3492 string_prepend (&decl
, SCOPE_STRING (work
));
3494 if (ISDIGIT ((unsigned char)**mangled
))
3496 n
= consume_count (mangled
);
3498 || (int) strlen (*mangled
) < n
)
3503 string_prependn (&decl
, *mangled
, n
);
3506 else if (**mangled
== 'X' || **mangled
== 'Y')
3509 do_type (work
, mangled
, &temp
);
3510 string_prepends (&decl
, &temp
);
3511 string_delete (&temp
);
3513 else if (**mangled
== 't')
3516 string_init (&temp
);
3517 success
= demangle_template (work
, mangled
, &temp
,
3521 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3522 string_delete (&temp
);
3527 else if (**mangled
== 'Q')
3529 success
= demangle_qualified (work
, mangled
, &decl
,
3541 string_prepend (&decl
, "(");
3549 type_quals
|= code_for_qualifier (**mangled
);
3557 if (*(*mangled
)++ != 'F')
3563 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3564 || **mangled
!= '_')
3570 if (! PRINT_ANSI_QUALIFIERS
)
3574 if (type_quals
!= TYPE_UNQUALIFIED
)
3576 APPEND_BLANK (&decl
);
3577 string_append (&decl
, qualifier_string (type_quals
));
3588 if (PRINT_ANSI_QUALIFIERS
)
3590 if (!STRING_EMPTY (&decl
))
3591 string_prepend (&decl
, " ");
3593 string_prepend (&decl
, demangle_qualifier (**mangled
));
3608 if (success
) switch (**mangled
)
3610 /* A qualified name, such as "Outer::Inner". */
3614 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3618 /* A back reference to a previously seen squangled type */
3621 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3624 string_append (result
, work
->btypevec
[n
]);
3629 /* A template parm. We substitute the corresponding argument. */
3634 idx
= consume_count_with_underscores (mangled
);
3637 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3638 || consume_count_with_underscores (mangled
) == -1)
3644 if (work
->tmpl_argvec
)
3645 string_append (result
, work
->tmpl_argvec
[idx
]);
3647 string_append_template_idx (result
, idx
);
3654 success
= demangle_fund_type (work
, mangled
, result
);
3656 tk
= (type_kind_t
) success
;
3662 if (!STRING_EMPTY (&decl
))
3664 string_append (result
, " ");
3665 string_appends (result
, &decl
);
3669 string_delete (result
);
3670 string_delete (&decl
);
3673 /* Assume an integral type, if we're not sure. */
3674 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3679 /* Given a pointer to a type string that represents a fundamental type
3680 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3681 string in which the demangled output is being built in RESULT, and
3682 the WORK structure, decode the types and add them to the result.
3687 "Sl" => "signed long"
3688 "CUs" => "const unsigned short"
3690 The value returned is really a type_kind_t. */
3693 demangle_fund_type (struct work_stuff
*work
,
3694 const char **mangled
, string
*result
)
3698 char buf
[INTBUF_SIZE
+ 5 /* 'int%u_t' */];
3699 unsigned int dec
= 0;
3700 type_kind_t tk
= tk_integral
;
3702 /* First pick off any type qualifiers. There can be more than one. */
3711 if (PRINT_ANSI_QUALIFIERS
)
3713 if (!STRING_EMPTY (result
))
3714 string_prepend (result
, " ");
3715 string_prepend (result
, demangle_qualifier (**mangled
));
3721 APPEND_BLANK (result
);
3722 string_append (result
, "unsigned");
3724 case 'S': /* signed char only */
3726 APPEND_BLANK (result
);
3727 string_append (result
, "signed");
3731 APPEND_BLANK (result
);
3732 string_append (result
, "__complex");
3740 /* Now pick off the fundamental type. There can be only one. */
3749 APPEND_BLANK (result
);
3750 string_append (result
, "void");
3754 APPEND_BLANK (result
);
3755 string_append (result
, "long long");
3759 APPEND_BLANK (result
);
3760 string_append (result
, "long");
3764 APPEND_BLANK (result
);
3765 string_append (result
, "int");
3769 APPEND_BLANK (result
);
3770 string_append (result
, "short");
3774 APPEND_BLANK (result
);
3775 string_append (result
, "bool");
3780 APPEND_BLANK (result
);
3781 string_append (result
, "char");
3786 APPEND_BLANK (result
);
3787 string_append (result
, "wchar_t");
3792 APPEND_BLANK (result
);
3793 string_append (result
, "long double");
3798 APPEND_BLANK (result
);
3799 string_append (result
, "double");
3804 APPEND_BLANK (result
);
3805 string_append (result
, "float");
3810 if (!ISDIGIT ((unsigned char)**mangled
))
3817 if (**mangled
== '_')
3822 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3825 if (**mangled
!= '_')
3835 strncpy (buf
, *mangled
, 2);
3837 *mangled
+= min (strlen (*mangled
), 2);
3839 sscanf (buf
, "%x", &dec
);
3840 sprintf (buf
, "int%u_t", dec
);
3841 APPEND_BLANK (result
);
3842 string_append (result
, buf
);
3846 /* An explicit type, such as "6mytype" or "7integer" */
3858 int bindex
= register_Btype (work
);
3860 string_init (&btype
);
3861 if (demangle_class_name (work
, mangled
, &btype
)) {
3862 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3863 APPEND_BLANK (result
);
3864 string_appends (result
, &btype
);
3868 string_delete (&btype
);
3874 string_init (&btype
);
3875 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
3876 string_appends (result
, &btype
);
3877 string_delete (&btype
);
3885 return success
? ((int) tk
) : 0;
3889 /* Handle a template's value parameter for HP aCC (extension from ARM)
3890 **mangled points to 'S' or 'U' */
3893 do_hpacc_template_const_value (struct work_stuff
*work ATTRIBUTE_UNUSED
,
3894 const char **mangled
, string
*result
)
3898 if (**mangled
!= 'U' && **mangled
!= 'S')
3901 unsigned_const
= (**mangled
== 'U');
3908 string_append (result
, "-");
3914 /* special case for -2^31 */
3915 string_append (result
, "-2147483648");
3922 /* We have to be looking at an integer now */
3923 if (!(ISDIGIT ((unsigned char)**mangled
)))
3926 /* We only deal with integral values for template
3927 parameters -- so it's OK to look only for digits */
3928 while (ISDIGIT ((unsigned char)**mangled
))
3930 char_str
[0] = **mangled
;
3931 string_append (result
, char_str
);
3936 string_append (result
, "U");
3938 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3939 with L or LL suffixes. pai/1997-09-03 */
3941 return 1; /* success */
3944 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3945 **mangled is pointing to the 'A' */
3948 do_hpacc_template_literal (struct work_stuff
*work
, const char **mangled
,
3951 int literal_len
= 0;
3955 if (**mangled
!= 'A')
3960 literal_len
= consume_count (mangled
);
3962 if (literal_len
<= 0)
3965 /* Literal parameters are names of arrays, functions, etc. and the
3966 canonical representation uses the address operator */
3967 string_append (result
, "&");
3969 /* Now recursively demangle the literal name */
3970 recurse
= XNEWVEC (char, literal_len
+ 1);
3971 memcpy (recurse
, *mangled
, literal_len
);
3972 recurse
[literal_len
] = '\000';
3974 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3978 string_append (result
, recurse_dem
);
3983 string_appendn (result
, *mangled
, literal_len
);
3985 (*mangled
) += literal_len
;
3992 snarf_numeric_literal (const char **args
, string
*arg
)
3997 string_append (arg
, char_str
);
4000 else if (**args
== '+')
4003 if (!ISDIGIT ((unsigned char)**args
))
4006 while (ISDIGIT ((unsigned char)**args
))
4008 char_str
[0] = **args
;
4009 string_append (arg
, char_str
);
4016 /* Demangle the next argument, given by MANGLED into RESULT, which
4017 *should be an uninitialized* string. It will be initialized here,
4018 and free'd should anything go wrong. */
4021 do_arg (struct work_stuff
*work
, const char **mangled
, string
*result
)
4023 /* Remember where we started so that we can record the type, for
4024 non-squangling type remembering. */
4025 const char *start
= *mangled
;
4027 string_init (result
);
4029 if (work
->nrepeats
> 0)
4033 if (work
->previous_argument
== 0)
4036 /* We want to reissue the previous type in this argument list. */
4037 string_appends (result
, work
->previous_argument
);
4041 if (**mangled
== 'n')
4043 /* A squangling-style repeat. */
4045 work
->nrepeats
= consume_count(mangled
);
4047 if (work
->nrepeats
<= 0)
4048 /* This was not a repeat count after all. */
4051 if (work
->nrepeats
> 9)
4053 if (**mangled
!= '_')
4054 /* The repeat count should be followed by an '_' in this
4061 /* Now, the repeat is all set up. */
4062 return do_arg (work
, mangled
, result
);
4065 /* Save the result in WORK->previous_argument so that we can find it
4066 if it's repeated. Note that saving START is not good enough: we
4067 do not want to add additional types to the back-referenceable
4068 type vector when processing a repeated type. */
4069 if (work
->previous_argument
)
4070 string_delete (work
->previous_argument
);
4072 work
->previous_argument
= XNEW (string
);
4074 if (!do_type (work
, mangled
, work
->previous_argument
))
4077 string_appends (result
, work
->previous_argument
);
4079 remember_type (work
, start
, *mangled
- start
);
4084 remember_type (struct work_stuff
*work
, const char *start
, int len
)
4088 if (work
->forgetting_types
)
4091 if (work
-> ntypes
>= work
-> typevec_size
)
4093 if (work
-> typevec_size
== 0)
4095 work
-> typevec_size
= 3;
4096 work
-> typevec
= XNEWVEC (char *, work
->typevec_size
);
4100 work
-> typevec_size
*= 2;
4102 = XRESIZEVEC (char *, work
->typevec
, work
->typevec_size
);
4105 tem
= XNEWVEC (char, len
+ 1);
4106 memcpy (tem
, start
, len
);
4108 work
-> typevec
[work
-> ntypes
++] = tem
;
4112 /* Remember a K type class qualifier. */
4114 remember_Ktype (struct work_stuff
*work
, const char *start
, int len
)
4118 if (work
-> numk
>= work
-> ksize
)
4120 if (work
-> ksize
== 0)
4123 work
-> ktypevec
= XNEWVEC (char *, work
->ksize
);
4129 = XRESIZEVEC (char *, work
->ktypevec
, work
->ksize
);
4132 tem
= XNEWVEC (char, len
+ 1);
4133 memcpy (tem
, start
, len
);
4135 work
-> ktypevec
[work
-> numk
++] = tem
;
4138 /* Register a B code, and get an index for it. B codes are registered
4139 as they are seen, rather than as they are completed, so map<temp<char> >
4140 registers map<temp<char> > as B0, and temp<char> as B1 */
4143 register_Btype (struct work_stuff
*work
)
4147 if (work
-> numb
>= work
-> bsize
)
4149 if (work
-> bsize
== 0)
4152 work
-> btypevec
= XNEWVEC (char *, work
->bsize
);
4158 = XRESIZEVEC (char *, work
->btypevec
, work
->bsize
);
4161 ret
= work
-> numb
++;
4162 work
-> btypevec
[ret
] = NULL
;
4166 /* Store a value into a previously registered B code type. */
4169 remember_Btype (struct work_stuff
*work
, const char *start
,
4174 tem
= XNEWVEC (char, len
+ 1);
4175 memcpy (tem
, start
, len
);
4177 work
-> btypevec
[index
] = tem
;
4180 /* Lose all the info related to B and K type codes. */
4182 forget_B_and_K_types (struct work_stuff
*work
)
4186 while (work
-> numk
> 0)
4188 i
= --(work
-> numk
);
4189 if (work
-> ktypevec
[i
] != NULL
)
4191 free (work
-> ktypevec
[i
]);
4192 work
-> ktypevec
[i
] = NULL
;
4196 while (work
-> numb
> 0)
4198 i
= --(work
-> numb
);
4199 if (work
-> btypevec
[i
] != NULL
)
4201 free (work
-> btypevec
[i
]);
4202 work
-> btypevec
[i
] = NULL
;
4206 /* Forget the remembered types, but not the type vector itself. */
4209 forget_types (struct work_stuff
*work
)
4213 while (work
-> ntypes
> 0)
4215 i
= --(work
-> ntypes
);
4216 if (work
-> typevec
[i
] != NULL
)
4218 free (work
-> typevec
[i
]);
4219 work
-> typevec
[i
] = NULL
;
4224 /* Process the argument list part of the signature, after any class spec
4225 has been consumed, as well as the first 'F' character (if any). For
4228 "__als__3fooRT0" => process "RT0"
4229 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4231 DECLP must be already initialised, usually non-empty. It won't be freed
4234 Note that g++ differs significantly from ARM and lucid style mangling
4235 with regards to references to previously seen types. For example, given
4236 the source fragment:
4240 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4243 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4244 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4246 g++ produces the names:
4251 while lcc (and presumably other ARM style compilers as well) produces:
4253 foo__FiR3fooT1T2T1T2
4254 __ct__3fooFiR3fooT1T2T1T2
4256 Note that g++ bases its type numbers starting at zero and counts all
4257 previously seen types, while lucid/ARM bases its type numbers starting
4258 at one and only considers types after it has seen the 'F' character
4259 indicating the start of the function args. For lucid/ARM style, we
4260 account for this difference by discarding any previously seen types when
4261 we see the 'F' character, and subtracting one from the type number
4267 demangle_args (struct work_stuff
*work
, const char **mangled
,
4277 if (PRINT_ARG_TYPES
)
4279 string_append (declp
, "(");
4280 if (**mangled
== '\0')
4282 string_append (declp
, "void");
4286 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
4287 || work
->nrepeats
> 0)
4289 if ((**mangled
== 'N') || (**mangled
== 'T'))
4291 temptype
= *(*mangled
)++;
4293 if (temptype
== 'N')
4295 if (!get_count (mangled
, &r
))
4304 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
4306 /* If we have 10 or more types we might have more than a 1 digit
4307 index so we'll have to consume the whole count here. This
4308 will lose if the next thing is a type name preceded by a
4309 count but it's impossible to demangle that case properly
4310 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4311 Pc, ...)" or "(..., type12, char *, ...)" */
4312 if ((t
= consume_count(mangled
)) <= 0)
4319 if (!get_count (mangled
, &t
))
4324 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4328 /* Validate the type index. Protect against illegal indices from
4329 malformed type strings. */
4330 if ((t
< 0) || (t
>= work
-> ntypes
))
4334 while (work
->nrepeats
> 0 || --r
>= 0)
4336 tem
= work
-> typevec
[t
];
4337 if (need_comma
&& PRINT_ARG_TYPES
)
4339 string_append (declp
, ", ");
4341 if (!do_arg (work
, &tem
, &arg
))
4345 if (PRINT_ARG_TYPES
)
4347 string_appends (declp
, &arg
);
4349 string_delete (&arg
);
4355 if (need_comma
&& PRINT_ARG_TYPES
)
4356 string_append (declp
, ", ");
4357 if (!do_arg (work
, mangled
, &arg
))
4359 if (PRINT_ARG_TYPES
)
4360 string_appends (declp
, &arg
);
4361 string_delete (&arg
);
4366 if (**mangled
== 'e')
4369 if (PRINT_ARG_TYPES
)
4373 string_append (declp
, ",");
4375 string_append (declp
, "...");
4379 if (PRINT_ARG_TYPES
)
4381 string_append (declp
, ")");
4386 /* Like demangle_args, but for demangling the argument lists of function
4387 and method pointers or references, not top-level declarations. */
4390 demangle_nested_args (struct work_stuff
*work
, const char **mangled
,
4393 string
* saved_previous_argument
;
4397 /* The G++ name-mangling algorithm does not remember types on nested
4398 argument lists, unless -fsquangling is used, and in that case the
4399 type vector updated by remember_type is not used. So, we turn
4400 off remembering of types here. */
4401 ++work
->forgetting_types
;
4403 /* For the repeat codes used with -fsquangling, we must keep track of
4404 the last argument. */
4405 saved_previous_argument
= work
->previous_argument
;
4406 saved_nrepeats
= work
->nrepeats
;
4407 work
->previous_argument
= 0;
4410 /* Actually demangle the arguments. */
4411 result
= demangle_args (work
, mangled
, declp
);
4413 /* Restore the previous_argument field. */
4414 if (work
->previous_argument
)
4416 string_delete (work
->previous_argument
);
4417 free ((char *) work
->previous_argument
);
4419 work
->previous_argument
= saved_previous_argument
;
4420 --work
->forgetting_types
;
4421 work
->nrepeats
= saved_nrepeats
;
4426 /* Returns 1 if a valid function name was found or 0 otherwise. */
4429 demangle_function_name (struct work_stuff
*work
, const char **mangled
,
4430 string
*declp
, const char *scan
)
4436 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4437 string_need (declp
, 1);
4438 *(declp
-> p
) = '\0';
4440 /* Consume the function name, including the "__" separating the name
4441 from the signature. We are guaranteed that SCAN points to the
4444 (*mangled
) = scan
+ 2;
4445 /* We may be looking at an instantiation of a template function:
4446 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4447 following _F marks the start of the function arguments. Handle
4448 the template arguments first. */
4450 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4452 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4453 /* This leaves MANGLED pointing to the 'F' marking func args */
4456 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4459 /* See if we have an ARM style constructor or destructor operator.
4460 If so, then just record it, clear the decl, and return.
4461 We can't build the actual constructor/destructor decl until later,
4462 when we recover the class name from the signature. */
4464 if (strcmp (declp
-> b
, "__ct") == 0)
4466 work
-> constructor
+= 1;
4467 string_clear (declp
);
4470 else if (strcmp (declp
-> b
, "__dt") == 0)
4472 work
-> destructor
+= 1;
4473 string_clear (declp
);
4478 if (declp
->p
- declp
->b
>= 3
4479 && declp
->b
[0] == 'o'
4480 && declp
->b
[1] == 'p'
4481 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4483 /* see if it's an assignment expression */
4484 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4485 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4487 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4489 int len
= declp
->p
- declp
->b
- 10;
4490 if ((int) strlen (optable
[i
].in
) == len
4491 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4493 string_clear (declp
);
4494 string_append (declp
, "operator");
4495 string_append (declp
, optable
[i
].out
);
4496 string_append (declp
, "=");
4503 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4505 int len
= declp
->p
- declp
->b
- 3;
4506 if ((int) strlen (optable
[i
].in
) == len
4507 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4509 string_clear (declp
);
4510 string_append (declp
, "operator");
4511 string_append (declp
, optable
[i
].out
);
4517 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4518 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4520 /* type conversion operator */
4522 if (do_type (work
, &tem
, &type
))
4524 string_clear (declp
);
4525 string_append (declp
, "operator ");
4526 string_appends (declp
, &type
);
4527 string_delete (&type
);
4530 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4531 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4534 /* type conversion operator. */
4536 if (do_type (work
, &tem
, &type
))
4538 string_clear (declp
);
4539 string_append (declp
, "operator ");
4540 string_appends (declp
, &type
);
4541 string_delete (&type
);
4544 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4545 && ISLOWER((unsigned char)declp
->b
[2])
4546 && ISLOWER((unsigned char)declp
->b
[3]))
4548 if (declp
->b
[4] == '\0')
4551 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4553 if (strlen (optable
[i
].in
) == 2
4554 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4556 string_clear (declp
);
4557 string_append (declp
, "operator");
4558 string_append (declp
, optable
[i
].out
);
4565 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4568 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4570 if (strlen (optable
[i
].in
) == 3
4571 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4573 string_clear (declp
);
4574 string_append (declp
, "operator");
4575 string_append (declp
, optable
[i
].out
);
4583 /* If a function name was obtained but it's not valid, we were not
4585 if (LEN_STRING (declp
) == 1 && declp
->b
[0] == '.')
4591 /* a mini string-handling package */
4594 string_need (string
*s
, int n
)
4604 s
->p
= s
->b
= XNEWVEC (char, n
);
4607 else if (s
->e
- s
->p
< n
)
4612 s
->b
= XRESIZEVEC (char, s
->b
, n
);
4619 string_delete (string
*s
)
4624 s
->b
= s
->e
= s
->p
= NULL
;
4629 string_init (string
*s
)
4631 s
->b
= s
->p
= s
->e
= NULL
;
4635 string_clear (string
*s
)
4643 string_empty (string
*s
)
4645 return (s
->b
== s
->p
);
4651 string_append (string
*p
, const char *s
)
4654 if (s
== NULL
|| *s
== '\0')
4658 memcpy (p
->p
, s
, n
);
4663 string_appends (string
*p
, string
*s
)
4671 memcpy (p
->p
, s
->b
, n
);
4677 string_appendn (string
*p
, const char *s
, int n
)
4682 memcpy (p
->p
, s
, n
);
4688 string_prepend (string
*p
, const char *s
)
4690 if (s
!= NULL
&& *s
!= '\0')
4692 string_prependn (p
, s
, strlen (s
));
4697 string_prepends (string
*p
, string
*s
)
4701 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4706 string_prependn (string
*p
, const char *s
, int n
)
4713 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4717 memcpy (p
->b
, s
, n
);
4723 string_append_template_idx (string
*s
, int idx
)
4725 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4726 sprintf(buf
, "T%d", idx
);
4727 string_append (s
, buf
);