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., 59 Temple Place - Suite 330,
31 Boston, MA 02111-1307, USA. */
33 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
35 This file imports xmalloc and xrealloc, which are like malloc and
36 realloc except that they generate a fatal error if there is no
39 /* This file lives in both GCC and libiberty. When making changes, please
40 try not to break either. */
46 #include "safe-ctype.h"
48 #include <sys/types.h>
60 #undef CURRENT_DEMANGLING_STYLE
61 #define CURRENT_DEMANGLING_STYLE work->options
63 #include "libiberty.h"
65 static char *ada_demangle (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
= (void *) xrealloc (*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
] == ' ')
992 grow_vect (&demangled
,
993 &demangled_size
, strlen (mangled
) + 3,
996 if (mangled
[0] == '<')
997 strcpy (demangled
, mangled
);
999 sprintf (demangled
, "<%s>", mangled
);
1004 /* This function performs most of what cplus_demangle use to do, but
1005 to be able to demangle a name with a B, K or n code, we need to
1006 have a longer term memory of what types have been seen. The original
1007 now initializes and cleans up the squangle code info, while internal
1008 calls go directly to this routine to avoid resetting that info. */
1011 internal_cplus_demangle (struct work_stuff
*work
, const char *mangled
)
1016 char *demangled
= NULL
;
1018 s1
= work
->constructor
;
1019 s2
= work
->destructor
;
1020 s3
= work
->static_type
;
1021 s4
= work
->type_quals
;
1022 work
->constructor
= work
->destructor
= 0;
1023 work
->type_quals
= TYPE_UNQUALIFIED
;
1024 work
->dllimported
= 0;
1026 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
1028 string_init (&decl
);
1030 /* First check to see if gnu style demangling is active and if the
1031 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1032 recognize one of the gnu special forms rather than looking for a
1033 standard prefix. In particular, don't worry about whether there
1034 is a "__" string in the mangled string. Consider "_$_5__foo" for
1037 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
1039 success
= gnu_special (work
, &mangled
, &decl
);
1043 success
= demangle_prefix (work
, &mangled
, &decl
);
1045 if (success
&& (*mangled
!= '\0'))
1047 success
= demangle_signature (work
, &mangled
, &decl
);
1049 if (work
->constructor
== 2)
1051 string_prepend (&decl
, "global constructors keyed to ");
1052 work
->constructor
= 0;
1054 else if (work
->destructor
== 2)
1056 string_prepend (&decl
, "global destructors keyed to ");
1057 work
->destructor
= 0;
1059 else if (work
->dllimported
== 1)
1061 string_prepend (&decl
, "import stub for ");
1062 work
->dllimported
= 0;
1064 demangled
= mop_up (work
, &decl
, success
);
1066 work
->constructor
= s1
;
1067 work
->destructor
= s2
;
1068 work
->static_type
= s3
;
1069 work
->type_quals
= s4
;
1074 /* Clear out and squangling related storage */
1076 squangle_mop_up (struct work_stuff
*work
)
1078 /* clean up the B and K type mangling types. */
1079 forget_B_and_K_types (work
);
1080 if (work
-> btypevec
!= NULL
)
1082 free ((char *) work
-> btypevec
);
1084 if (work
-> ktypevec
!= NULL
)
1086 free ((char *) work
-> ktypevec
);
1091 /* Copy the work state and storage. */
1094 work_stuff_copy_to_from (struct work_stuff
*to
, struct work_stuff
*from
)
1098 delete_work_stuff (to
);
1100 /* Shallow-copy scalars. */
1101 memcpy (to
, from
, sizeof (*to
));
1103 /* Deep-copy dynamic storage. */
1104 if (from
->typevec_size
)
1106 = (char **) xmalloc (from
->typevec_size
* sizeof (to
->typevec
[0]));
1108 for (i
= 0; i
< from
->ntypes
; i
++)
1110 int len
= strlen (from
->typevec
[i
]) + 1;
1112 to
->typevec
[i
] = xmalloc (len
);
1113 memcpy (to
->typevec
[i
], from
->typevec
[i
], len
);
1118 = (char **) xmalloc (from
->ksize
* sizeof (to
->ktypevec
[0]));
1120 for (i
= 0; i
< from
->numk
; i
++)
1122 int len
= strlen (from
->ktypevec
[i
]) + 1;
1124 to
->ktypevec
[i
] = xmalloc (len
);
1125 memcpy (to
->ktypevec
[i
], from
->ktypevec
[i
], len
);
1130 = (char **) xmalloc (from
->bsize
* sizeof (to
->btypevec
[0]));
1132 for (i
= 0; i
< from
->numb
; i
++)
1134 int len
= strlen (from
->btypevec
[i
]) + 1;
1136 to
->btypevec
[i
] = xmalloc (len
);
1137 memcpy (to
->btypevec
[i
], from
->btypevec
[i
], len
);
1140 if (from
->ntmpl_args
)
1142 = (char **) xmalloc (from
->ntmpl_args
* sizeof (to
->tmpl_argvec
[0]));
1144 for (i
= 0; i
< from
->ntmpl_args
; i
++)
1146 int len
= strlen (from
->tmpl_argvec
[i
]) + 1;
1148 to
->tmpl_argvec
[i
] = xmalloc (len
);
1149 memcpy (to
->tmpl_argvec
[i
], from
->tmpl_argvec
[i
], len
);
1152 if (from
->previous_argument
)
1154 to
->previous_argument
= (string
*) xmalloc (sizeof (string
));
1155 string_init (to
->previous_argument
);
1156 string_appends (to
->previous_argument
, from
->previous_argument
);
1161 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1164 delete_non_B_K_work_stuff (struct work_stuff
*work
)
1166 /* Discard the remembered types, if any. */
1168 forget_types (work
);
1169 if (work
-> typevec
!= NULL
)
1171 free ((char *) work
-> typevec
);
1172 work
-> typevec
= NULL
;
1173 work
-> typevec_size
= 0;
1175 if (work
->tmpl_argvec
)
1179 for (i
= 0; i
< work
->ntmpl_args
; i
++)
1180 if (work
->tmpl_argvec
[i
])
1181 free ((char*) work
->tmpl_argvec
[i
]);
1183 free ((char*) work
->tmpl_argvec
);
1184 work
->tmpl_argvec
= NULL
;
1186 if (work
->previous_argument
)
1188 string_delete (work
->previous_argument
);
1189 free ((char*) work
->previous_argument
);
1190 work
->previous_argument
= NULL
;
1195 /* Delete all dynamic storage in work_stuff. */
1197 delete_work_stuff (struct work_stuff
*work
)
1199 delete_non_B_K_work_stuff (work
);
1200 squangle_mop_up (work
);
1204 /* Clear out any mangled storage */
1207 mop_up (struct work_stuff
*work
, string
*declp
, int success
)
1209 char *demangled
= NULL
;
1211 delete_non_B_K_work_stuff (work
);
1213 /* If demangling was successful, ensure that the demangled string is null
1214 terminated and return it. Otherwise, free the demangling decl. */
1218 string_delete (declp
);
1222 string_appendn (declp
, "", 1);
1223 demangled
= declp
->b
;
1232 demangle_signature -- demangle the signature part of a mangled name
1237 demangle_signature (struct work_stuff *work, const char **mangled,
1242 Consume and demangle the signature portion of the mangled name.
1244 DECLP is the string where demangled output is being built. At
1245 entry it contains the demangled root name from the mangled name
1246 prefix. I.E. either a demangled operator name or the root function
1247 name. In some special cases, it may contain nothing.
1249 *MANGLED points to the current unconsumed location in the mangled
1250 name. As tokens are consumed and demangling is performed, the
1251 pointer is updated to continuously point at the next token to
1254 Demangling GNU style mangled names is nasty because there is no
1255 explicit token that marks the start of the outermost function
1259 demangle_signature (struct work_stuff
*work
,
1260 const char **mangled
, string
*declp
)
1264 int expect_func
= 0;
1265 int expect_return_type
= 0;
1266 const char *oldmangled
= NULL
;
1270 while (success
&& (**mangled
!= '\0'))
1275 oldmangled
= *mangled
;
1276 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1278 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1279 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1285 oldmangled
= *mangled
;
1286 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1287 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1295 /* Static member function */
1296 if (oldmangled
== NULL
)
1298 oldmangled
= *mangled
;
1301 work
-> static_type
= 1;
1307 work
->type_quals
|= code_for_qualifier (**mangled
);
1309 /* a qualified member function */
1310 if (oldmangled
== NULL
)
1311 oldmangled
= *mangled
;
1316 /* Local class name follows after "Lnnn_" */
1319 while (**mangled
&& (**mangled
!= '_'))
1330 case '0': case '1': case '2': case '3': case '4':
1331 case '5': case '6': case '7': case '8': case '9':
1332 if (oldmangled
== NULL
)
1334 oldmangled
= *mangled
;
1336 work
->temp_start
= -1; /* uppermost call to demangle_class */
1337 success
= demangle_class (work
, mangled
, declp
);
1340 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1342 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1344 /* EDG and others will have the "F", so we let the loop cycle
1345 if we are looking at one. */
1346 if (**mangled
!= 'F')
1355 success
= do_type (work
, mangled
, &s
);
1358 string_append (&s
, SCOPE_STRING (work
));
1359 string_prepends (declp
, &s
);
1369 /* ARM/HP style demangling includes a specific 'F' character after
1370 the class name. For GNU style, it is just implied. So we can
1371 safely just consume any 'F' at this point and be compatible
1372 with either style. */
1378 /* For lucid/ARM/HP style we have to forget any types we might
1379 have remembered up to this point, since they were not argument
1380 types. GNU style considers all types seen as available for
1381 back references. See comment in demangle_args() */
1383 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1385 forget_types (work
);
1387 success
= demangle_args (work
, mangled
, declp
);
1388 /* After picking off the function args, we expect to either
1389 find the function return type (preceded by an '_') or the
1390 end of the string. */
1391 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1394 /* At this level, we do not care about the return type. */
1395 success
= do_type (work
, mangled
, &tname
);
1396 string_delete (&tname
);
1403 string_init(&trawname
);
1404 string_init(&tname
);
1405 if (oldmangled
== NULL
)
1407 oldmangled
= *mangled
;
1409 success
= demangle_template (work
, mangled
, &tname
,
1413 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1415 string_append (&tname
, SCOPE_STRING (work
));
1417 string_prepends(declp
, &tname
);
1418 if (work
-> destructor
& 1)
1420 string_prepend (&trawname
, "~");
1421 string_appends (declp
, &trawname
);
1422 work
->destructor
-= 1;
1424 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1426 string_appends (declp
, &trawname
);
1427 work
->constructor
-= 1;
1429 string_delete(&trawname
);
1430 string_delete(&tname
);
1436 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
) && expect_return_type
)
1438 /* Read the return type. */
1442 success
= do_type (work
, mangled
, &return_type
);
1443 APPEND_BLANK (&return_type
);
1445 string_prepends (declp
, &return_type
);
1446 string_delete (&return_type
);
1450 /* At the outermost level, we cannot have a return type specified,
1451 so if we run into another '_' at this point we are dealing with
1452 a mangled name that is either bogus, or has been mangled by
1453 some algorithm we don't know how to deal with. So just
1454 reject the entire demangling. */
1455 /* However, "_nnn" is an expected suffix for alternate entry point
1456 numbered nnn for a function, with HP aCC, so skip over that
1457 without reporting failure. pai/1997-09-04 */
1461 while (**mangled
&& ISDIGIT ((unsigned char)**mangled
))
1469 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1471 /* A G++ template function. Read the template arguments. */
1472 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1474 if (!(work
->constructor
& 1))
1475 expect_return_type
= 1;
1484 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1486 /* Assume we have stumbled onto the first outermost function
1487 argument token, and start processing args. */
1489 success
= demangle_args (work
, mangled
, declp
);
1493 /* Non-GNU demanglers use a specific token to mark the start
1494 of the outermost function argument tokens. Typically 'F',
1495 for ARM/HP-demangling, for example. So if we find something
1496 we are not prepared for, it must be an error. */
1502 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1505 if (success
&& expect_func
)
1508 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1510 forget_types (work
);
1512 success
= demangle_args (work
, mangled
, declp
);
1513 /* Since template include the mangling of their return types,
1514 we must set expect_func to 0 so that we don't try do
1515 demangle more arguments the next time we get here. */
1520 if (success
&& !func_done
)
1522 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1524 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1525 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1526 first case, and need to ensure that the '(void)' gets added to
1527 the current declp. Note that with ARM/HP, the first case
1528 represents the name of a static data member 'foo::bar',
1529 which is in the current declp, so we leave it alone. */
1530 success
= demangle_args (work
, mangled
, declp
);
1533 if (success
&& PRINT_ARG_TYPES
)
1535 if (work
->static_type
)
1536 string_append (declp
, " static");
1537 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1539 APPEND_BLANK (declp
);
1540 string_append (declp
, qualifier_string (work
->type_quals
));
1550 demangle_method_args (struct work_stuff
*work
, const char **mangled
,
1555 if (work
-> static_type
)
1557 string_append (declp
, *mangled
+ 1);
1558 *mangled
+= strlen (*mangled
);
1563 success
= demangle_args (work
, mangled
, declp
);
1571 demangle_template_template_parm (struct work_stuff
*work
,
1572 const char **mangled
, string
*tname
)
1580 string_append (tname
, "template <");
1581 /* get size of template parameter list */
1582 if (get_count (mangled
, &r
))
1584 for (i
= 0; i
< r
; i
++)
1588 string_append (tname
, ", ");
1591 /* Z for type parameters */
1592 if (**mangled
== 'Z')
1595 string_append (tname
, "class");
1597 /* z for template parameters */
1598 else if (**mangled
== 'z')
1602 demangle_template_template_parm (work
, mangled
, tname
);
1610 /* temp is initialized in do_type */
1611 success
= do_type (work
, mangled
, &temp
);
1614 string_appends (tname
, &temp
);
1616 string_delete(&temp
);
1626 if (tname
->p
[-1] == '>')
1627 string_append (tname
, " ");
1628 string_append (tname
, "> class");
1633 demangle_expression (struct work_stuff
*work
, const char **mangled
,
1634 string
*s
, type_kind_t tk
)
1636 int need_operator
= 0;
1640 string_appendn (s
, "(", 1);
1642 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1651 len
= strlen (*mangled
);
1653 for (i
= 0; i
< ARRAY_SIZE (optable
); ++i
)
1655 size_t l
= strlen (optable
[i
].in
);
1658 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1660 string_appendn (s
, " ", 1);
1661 string_append (s
, optable
[i
].out
);
1662 string_appendn (s
, " ", 1);
1675 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1678 if (**mangled
!= 'W')
1682 string_appendn (s
, ")", 1);
1690 demangle_integral_value (struct work_stuff
*work
,
1691 const char **mangled
, string
*s
)
1695 if (**mangled
== 'E')
1696 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1697 else if (**mangled
== 'Q' || **mangled
== 'K')
1698 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1703 /* By default, we let the number decide whether we shall consume an
1705 int multidigit_without_leading_underscore
= 0;
1706 int leave_following_underscore
= 0;
1710 if (**mangled
== '_')
1712 if (mangled
[0][1] == 'm')
1714 /* Since consume_count_with_underscores does not handle the
1715 `m'-prefix we must do it here, using consume_count and
1716 adjusting underscores: we have to consume the underscore
1717 matching the prepended one. */
1718 multidigit_without_leading_underscore
= 1;
1719 string_appendn (s
, "-", 1);
1724 /* Do not consume a following underscore;
1725 consume_count_with_underscores will consume what
1726 should be consumed. */
1727 leave_following_underscore
= 1;
1732 /* Negative numbers are indicated with a leading `m'. */
1733 if (**mangled
== 'm')
1735 string_appendn (s
, "-", 1);
1738 /* Since consume_count_with_underscores does not handle
1739 multi-digit numbers that do not start with an underscore,
1740 and this number can be an integer template parameter,
1741 we have to call consume_count. */
1742 multidigit_without_leading_underscore
= 1;
1743 /* These multi-digit numbers never end on an underscore,
1744 so if there is one then don't eat it. */
1745 leave_following_underscore
= 1;
1748 /* We must call consume_count if we expect to remove a trailing
1749 underscore, since consume_count_with_underscores expects
1750 the leading underscore (that we consumed) if it is to handle
1751 multi-digit numbers. */
1752 if (multidigit_without_leading_underscore
)
1753 value
= consume_count (mangled
);
1755 value
= consume_count_with_underscores (mangled
);
1759 char buf
[INTBUF_SIZE
];
1760 sprintf (buf
, "%d", value
);
1761 string_append (s
, buf
);
1763 /* Numbers not otherwise delimited, might have an underscore
1764 appended as a delimeter, which we should skip.
1766 ??? This used to always remove a following underscore, which
1767 is wrong. If other (arbitrary) cases are followed by an
1768 underscore, we need to do something more radical. */
1770 if ((value
> 9 || multidigit_without_leading_underscore
)
1771 && ! leave_following_underscore
1772 && **mangled
== '_')
1783 /* Demangle the real value in MANGLED. */
1786 demangle_real_value (struct work_stuff
*work
,
1787 const char **mangled
, string
*s
)
1789 if (**mangled
== 'E')
1790 return demangle_expression (work
, mangled
, s
, tk_real
);
1792 if (**mangled
== 'm')
1794 string_appendn (s
, "-", 1);
1797 while (ISDIGIT ((unsigned char)**mangled
))
1799 string_appendn (s
, *mangled
, 1);
1802 if (**mangled
== '.') /* fraction */
1804 string_appendn (s
, ".", 1);
1806 while (ISDIGIT ((unsigned char)**mangled
))
1808 string_appendn (s
, *mangled
, 1);
1812 if (**mangled
== 'e') /* exponent */
1814 string_appendn (s
, "e", 1);
1816 while (ISDIGIT ((unsigned char)**mangled
))
1818 string_appendn (s
, *mangled
, 1);
1827 demangle_template_value_parm (struct work_stuff
*work
, const char **mangled
,
1828 string
*s
, type_kind_t tk
)
1832 if (**mangled
== 'Y')
1834 /* The next argument is a template parameter. */
1838 idx
= consume_count_with_underscores (mangled
);
1840 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1841 || consume_count_with_underscores (mangled
) == -1)
1843 if (work
->tmpl_argvec
)
1844 string_append (s
, work
->tmpl_argvec
[idx
]);
1846 string_append_template_idx (s
, idx
);
1848 else if (tk
== tk_integral
)
1849 success
= demangle_integral_value (work
, mangled
, s
);
1850 else if (tk
== tk_char
)
1854 if (**mangled
== 'm')
1856 string_appendn (s
, "-", 1);
1859 string_appendn (s
, "'", 1);
1860 val
= consume_count(mangled
);
1867 string_appendn (s
, &tmp
[0], 1);
1868 string_appendn (s
, "'", 1);
1871 else if (tk
== tk_bool
)
1873 int val
= consume_count (mangled
);
1875 string_appendn (s
, "false", 5);
1877 string_appendn (s
, "true", 4);
1881 else if (tk
== tk_real
)
1882 success
= demangle_real_value (work
, mangled
, s
);
1883 else if (tk
== tk_pointer
|| tk
== tk_reference
)
1885 if (**mangled
== 'Q')
1886 success
= demangle_qualified (work
, mangled
, s
,
1891 int symbol_len
= consume_count (mangled
);
1892 if (symbol_len
== -1)
1894 if (symbol_len
== 0)
1895 string_appendn (s
, "0", 1);
1898 char *p
= xmalloc (symbol_len
+ 1), *q
;
1899 strncpy (p
, *mangled
, symbol_len
);
1900 p
[symbol_len
] = '\0';
1901 /* We use cplus_demangle here, rather than
1902 internal_cplus_demangle, because the name of the entity
1903 mangled here does not make use of any of the squangling
1904 or type-code information we have built up thus far; it is
1905 mangled independently. */
1906 q
= cplus_demangle (p
, work
->options
);
1907 if (tk
== tk_pointer
)
1908 string_appendn (s
, "&", 1);
1909 /* FIXME: Pointer-to-member constants should get a
1910 qualifying class name here. */
1913 string_append (s
, q
);
1917 string_append (s
, p
);
1920 *mangled
+= symbol_len
;
1927 /* Demangle the template name in MANGLED. The full name of the
1928 template (e.g., S<int>) is placed in TNAME. The name without the
1929 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
1930 non-NULL. If IS_TYPE is nonzero, this template is a type template,
1931 not a function template. If both IS_TYPE and REMEMBER are nonzero,
1932 the template is remembered in the list of back-referenceable
1936 demangle_template (struct work_stuff
*work
, const char **mangled
,
1937 string
*tname
, string
*trawname
,
1938 int is_type
, int remember
)
1944 int is_java_array
= 0;
1950 /* get template name */
1951 if (**mangled
== 'z')
1957 idx
= consume_count_with_underscores (mangled
);
1959 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1960 || consume_count_with_underscores (mangled
) == -1)
1963 if (work
->tmpl_argvec
)
1965 string_append (tname
, work
->tmpl_argvec
[idx
]);
1967 string_append (trawname
, work
->tmpl_argvec
[idx
]);
1971 string_append_template_idx (tname
, idx
);
1973 string_append_template_idx (trawname
, idx
);
1978 if ((r
= consume_count (mangled
)) <= 0
1979 || (int) strlen (*mangled
) < r
)
1983 is_java_array
= (work
-> options
& DMGL_JAVA
)
1984 && strncmp (*mangled
, "JArray1Z", 8) == 0;
1985 if (! is_java_array
)
1987 string_appendn (tname
, *mangled
, r
);
1990 string_appendn (trawname
, *mangled
, r
);
1995 string_append (tname
, "<");
1996 /* get size of template parameter list */
1997 if (!get_count (mangled
, &r
))
2003 /* Create an array for saving the template argument values. */
2004 work
->tmpl_argvec
= (char**) xmalloc (r
* sizeof (char *));
2005 work
->ntmpl_args
= r
;
2006 for (i
= 0; i
< r
; i
++)
2007 work
->tmpl_argvec
[i
] = 0;
2009 for (i
= 0; i
< r
; i
++)
2013 string_append (tname
, ", ");
2015 /* Z for type parameters */
2016 if (**mangled
== 'Z')
2019 /* temp is initialized in do_type */
2020 success
= do_type (work
, mangled
, &temp
);
2023 string_appends (tname
, &temp
);
2027 /* Save the template argument. */
2028 int len
= temp
.p
- temp
.b
;
2029 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
2030 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
2031 work
->tmpl_argvec
[i
][len
] = '\0';
2034 string_delete(&temp
);
2040 /* z for template parameters */
2041 else if (**mangled
== 'z')
2045 success
= demangle_template_template_parm (work
, mangled
, tname
);
2048 && (r2
= consume_count (mangled
)) > 0
2049 && (int) strlen (*mangled
) >= r2
)
2051 string_append (tname
, " ");
2052 string_appendn (tname
, *mangled
, r2
);
2055 /* Save the template argument. */
2057 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
2058 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
2059 work
->tmpl_argvec
[i
][len
] = '\0';
2073 /* otherwise, value parameter */
2075 /* temp is initialized in do_type */
2076 success
= do_type (work
, mangled
, &temp
);
2077 string_delete(&temp
);
2089 success
= demangle_template_value_parm (work
, mangled
, s
,
2090 (type_kind_t
) success
);
2102 int len
= s
->p
- s
->b
;
2103 work
->tmpl_argvec
[i
] = xmalloc (len
+ 1);
2104 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
2105 work
->tmpl_argvec
[i
][len
] = '\0';
2107 string_appends (tname
, s
);
2115 string_append (tname
, "[]");
2119 if (tname
->p
[-1] == '>')
2120 string_append (tname
, " ");
2121 string_append (tname
, ">");
2124 if (is_type
&& remember
)
2126 const int bindex
= register_Btype (work
);
2127 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
2131 if (work -> static_type)
2133 string_append (declp, *mangled + 1);
2134 *mangled += strlen (*mangled);
2139 success = demangle_args (work, mangled, declp);
2147 arm_pt (struct work_stuff
*work
, const char *mangled
,
2148 int n
, const char **anchor
, const char **args
)
2150 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2151 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2152 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= strstr (mangled
, "__pt__")))
2155 *args
= *anchor
+ 6;
2156 len
= consume_count (args
);
2159 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2165 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
2167 if ((*anchor
= strstr (mangled
, "__tm__"))
2168 || (*anchor
= strstr (mangled
, "__ps__"))
2169 || (*anchor
= strstr (mangled
, "__pt__")))
2172 *args
= *anchor
+ 6;
2173 len
= consume_count (args
);
2176 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2182 else if ((*anchor
= strstr (mangled
, "__S")))
2185 *args
= *anchor
+ 3;
2186 len
= consume_count (args
);
2189 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2201 demangle_arm_hp_template (struct work_stuff
*work
, const char **mangled
,
2202 int n
, string
*declp
)
2206 const char *e
= *mangled
+ n
;
2209 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2211 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
2213 char *start_spec_args
= NULL
;
2216 /* First check for and omit template specialization pseudo-arguments,
2217 such as in "Spec<#1,#1.*>" */
2218 start_spec_args
= strchr (*mangled
, '<');
2219 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
2220 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
2222 string_appendn (declp
, *mangled
, n
);
2223 (*mangled
) += n
+ 1;
2225 if (work
->temp_start
== -1) /* non-recursive call */
2226 work
->temp_start
= declp
->p
- declp
->b
;
2228 /* We want to unconditionally demangle parameter types in
2229 template parameters. */
2230 hold_options
= work
->options
;
2231 work
->options
|= DMGL_PARAMS
;
2233 string_append (declp
, "<");
2236 string_delete (&arg
);
2240 /* 'T' signals a type parameter */
2242 if (!do_type (work
, mangled
, &arg
))
2243 goto hpacc_template_args_done
;
2248 /* 'U' or 'S' signals an integral value */
2249 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
2250 goto hpacc_template_args_done
;
2254 /* 'A' signals a named constant expression (literal) */
2255 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
2256 goto hpacc_template_args_done
;
2260 /* Today, 1997-09-03, we have only the above types
2261 of template parameters */
2262 /* FIXME: maybe this should fail and return null */
2263 goto hpacc_template_args_done
;
2265 string_appends (declp
, &arg
);
2266 /* Check if we're at the end of template args.
2267 0 if at end of static member of template class,
2268 _ if done with template args for a function */
2269 if ((**mangled
== '\000') || (**mangled
== '_'))
2272 string_append (declp
, ",");
2274 hpacc_template_args_done
:
2275 string_append (declp
, ">");
2276 string_delete (&arg
);
2277 if (**mangled
== '_')
2279 work
->options
= hold_options
;
2282 /* ARM template? (Also handles HP cfront extensions) */
2283 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
2289 string_appendn (declp
, *mangled
, p
- *mangled
);
2290 if (work
->temp_start
== -1) /* non-recursive call */
2291 work
->temp_start
= declp
->p
- declp
->b
;
2293 /* We want to unconditionally demangle parameter types in
2294 template parameters. */
2295 hold_options
= work
->options
;
2296 work
->options
|= DMGL_PARAMS
;
2298 string_append (declp
, "<");
2299 /* should do error checking here */
2301 string_delete (&arg
);
2303 /* Check for type or literal here */
2306 /* HP cfront extensions to ARM for template args */
2307 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2308 /* FIXME: We handle only numeric literals for HP cfront */
2310 /* A typed constant value follows */
2312 if (!do_type (work
, &args
, &type_str
))
2313 goto cfront_template_args_done
;
2314 string_append (&arg
, "(");
2315 string_appends (&arg
, &type_str
);
2316 string_delete (&type_str
);
2317 string_append (&arg
, ")");
2319 goto cfront_template_args_done
;
2321 /* Now snarf a literal value following 'L' */
2322 if (!snarf_numeric_literal (&args
, &arg
))
2323 goto cfront_template_args_done
;
2327 /* Snarf a literal following 'L' */
2329 if (!snarf_numeric_literal (&args
, &arg
))
2330 goto cfront_template_args_done
;
2333 /* Not handling other HP cfront stuff */
2335 const char* old_args
= args
;
2336 if (!do_type (work
, &args
, &arg
))
2337 goto cfront_template_args_done
;
2339 /* Fail if we didn't make any progress: prevent infinite loop. */
2340 if (args
== old_args
)
2342 work
->options
= hold_options
;
2347 string_appends (declp
, &arg
);
2348 string_append (declp
, ",");
2350 cfront_template_args_done
:
2351 string_delete (&arg
);
2353 --declp
->p
; /* remove extra comma */
2354 string_append (declp
, ">");
2355 work
->options
= hold_options
;
2357 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2358 && (*mangled
)[9] == 'N'
2359 && (*mangled
)[8] == (*mangled
)[10]
2360 && strchr (cplus_markers
, (*mangled
)[8]))
2362 /* A member of the anonymous namespace. */
2363 string_append (declp
, "{anonymous}");
2367 if (work
->temp_start
== -1) /* non-recursive call only */
2368 work
->temp_start
= 0; /* disable in recursive calls */
2369 string_appendn (declp
, *mangled
, n
);
2374 /* Extract a class name, possibly a template with arguments, from the
2375 mangled string; qualifiers, local class indicators, etc. have
2376 already been dealt with */
2379 demangle_class_name (struct work_stuff
*work
, const char **mangled
,
2385 n
= consume_count (mangled
);
2388 if ((int) strlen (*mangled
) >= n
)
2390 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2401 demangle_class -- demangle a mangled class sequence
2406 demangle_class (struct work_stuff *work, const char **mangled,
2411 DECLP points to the buffer into which demangling is being done.
2413 *MANGLED points to the current token to be demangled. On input,
2414 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2415 On exit, it points to the next token after the mangled class on
2416 success, or the first unconsumed token on failure.
2418 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2419 we are demangling a constructor or destructor. In this case
2420 we prepend "class::class" or "class::~class" to DECLP.
2422 Otherwise, we prepend "class::" to the current DECLP.
2424 Reset the constructor/destructor flags once they have been
2425 "consumed". This allows demangle_class to be called later during
2426 the same demangling, to do normal class demangling.
2428 Returns 1 if demangling is successful, 0 otherwise.
2433 demangle_class (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2438 char *save_class_name_end
= 0;
2440 string_init (&class_name
);
2441 btype
= register_Btype (work
);
2442 if (demangle_class_name (work
, mangled
, &class_name
))
2444 save_class_name_end
= class_name
.p
;
2445 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2447 /* adjust so we don't include template args */
2448 if (work
->temp_start
&& (work
->temp_start
!= -1))
2450 class_name
.p
= class_name
.b
+ work
->temp_start
;
2452 string_prepends (declp
, &class_name
);
2453 if (work
-> destructor
& 1)
2455 string_prepend (declp
, "~");
2456 work
-> destructor
-= 1;
2460 work
-> constructor
-= 1;
2463 class_name
.p
= save_class_name_end
;
2464 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2465 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2466 string_prepend (declp
, SCOPE_STRING (work
));
2467 string_prepends (declp
, &class_name
);
2470 string_delete (&class_name
);
2475 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2476 the rightmost guess.
2478 Find the correct "__"-sequence where the function name ends and the
2479 signature starts, which is ambiguous with GNU mangling.
2480 Call demangle_signature here, so we can make sure we found the right
2481 one; *mangled will be consumed so caller will not make further calls to
2482 demangle_signature. */
2485 iterate_demangle_function (struct work_stuff
*work
, const char **mangled
,
2486 string
*declp
, const char *scan
)
2488 const char *mangle_init
= *mangled
;
2491 struct work_stuff work_init
;
2493 if (*(scan
+ 2) == '\0')
2496 /* Do not iterate for some demangling modes, or if there's only one
2497 "__"-sequence. This is the normal case. */
2498 if (ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
2499 || strstr (scan
+ 2, "__") == NULL
)
2501 demangle_function_name (work
, mangled
, declp
, scan
);
2505 /* Save state so we can restart if the guess at the correct "__" was
2507 string_init (&decl_init
);
2508 string_appends (&decl_init
, declp
);
2509 memset (&work_init
, 0, sizeof work_init
);
2510 work_stuff_copy_to_from (&work_init
, work
);
2512 /* Iterate over occurrences of __, allowing names and types to have a
2513 "__" sequence in them. We must start with the first (not the last)
2514 occurrence, since "__" most often occur between independent mangled
2515 parts, hence starting at the last occurence inside a signature
2516 might get us a "successful" demangling of the signature. */
2520 demangle_function_name (work
, mangled
, declp
, scan
);
2521 success
= demangle_signature (work
, mangled
, declp
);
2525 /* Reset demangle state for the next round. */
2526 *mangled
= mangle_init
;
2527 string_clear (declp
);
2528 string_appends (declp
, &decl_init
);
2529 work_stuff_copy_to_from (work
, &work_init
);
2531 /* Leave this underscore-sequence. */
2534 /* Scan for the next "__" sequence. */
2535 while (*scan
&& (scan
[0] != '_' || scan
[1] != '_'))
2538 /* Move to last "__" in this sequence. */
2539 while (*scan
&& *scan
== '_')
2544 /* Delete saved state. */
2545 delete_work_stuff (&work_init
);
2546 string_delete (&decl_init
);
2555 demangle_prefix -- consume the mangled name prefix and find signature
2560 demangle_prefix (struct work_stuff *work, const char **mangled,
2565 Consume and demangle the prefix of the mangled name.
2566 While processing the function name root, arrange to call
2567 demangle_signature if the root is ambiguous.
2569 DECLP points to the string buffer into which demangled output is
2570 placed. On entry, the buffer is empty. On exit it contains
2571 the root function name, the demangled operator name, or in some
2572 special cases either nothing or the completely demangled result.
2574 MANGLED points to the current pointer into the mangled name. As each
2575 token of the mangled name is consumed, it is updated. Upon entry
2576 the current mangled name pointer points to the first character of
2577 the mangled name. Upon exit, it should point to the first character
2578 of the signature if demangling was successful, or to the first
2579 unconsumed character if demangling of the prefix was unsuccessful.
2581 Returns 1 on success, 0 otherwise.
2585 demangle_prefix (struct work_stuff
*work
, const char **mangled
,
2592 if (strlen(*mangled
) > 6
2593 && (strncmp(*mangled
, "_imp__", 6) == 0
2594 || strncmp(*mangled
, "__imp_", 6) == 0))
2596 /* it's a symbol imported from a PE dynamic library. Check for both
2597 new style prefix _imp__ and legacy __imp_ used by older versions
2600 work
->dllimported
= 1;
2602 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2604 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2605 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2607 if ((*mangled
)[9] == 'D')
2609 /* it's a GNU global destructor to be executed at program exit */
2611 work
->destructor
= 2;
2612 if (gnu_special (work
, mangled
, declp
))
2615 else if ((*mangled
)[9] == 'I')
2617 /* it's a GNU global constructor to be executed at program init */
2619 work
->constructor
= 2;
2620 if (gnu_special (work
, mangled
, declp
))
2625 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2627 /* it's a ARM global destructor to be executed at program exit */
2629 work
->destructor
= 2;
2631 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2633 /* it's a ARM global constructor to be executed at program initial */
2635 work
->constructor
= 2;
2638 /* This block of code is a reduction in strength time optimization
2640 scan = strstr (*mangled, "__"); */
2646 scan
= strchr (scan
, '_');
2647 } while (scan
!= NULL
&& *++scan
!= '_');
2649 if (scan
!= NULL
) --scan
;
2654 /* We found a sequence of two or more '_', ensure that we start at
2655 the last pair in the sequence. */
2656 i
= strspn (scan
, "_");
2667 else if (work
-> static_type
)
2669 if (!ISDIGIT ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2674 else if ((scan
== *mangled
)
2675 && (ISDIGIT ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2676 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2678 /* The ARM says nothing about the mangling of local variables.
2679 But cfront mangles local variables by prepending __<nesting_level>
2680 to them. As an extension to ARM demangling we handle this case. */
2681 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2682 && ISDIGIT ((unsigned char)scan
[2]))
2684 *mangled
= scan
+ 2;
2685 consume_count (mangled
);
2686 string_append (declp
, *mangled
);
2687 *mangled
+= strlen (*mangled
);
2692 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2693 names like __Q2_3foo3bar for nested type names. So don't accept
2694 this style of constructor for cfront demangling. A GNU
2695 style member-template constructor starts with 'H'. */
2696 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2697 work
-> constructor
+= 1;
2698 *mangled
= scan
+ 2;
2701 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2703 /* Cfront-style parameterized type. Handled later as a signature. */
2707 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2709 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2710 || (scan
[2] == 'p' && scan
[3] == 's')
2711 || (scan
[2] == 'p' && scan
[3] == 't')))
2713 /* EDG-style parameterized type. Handled later as a signature. */
2717 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2719 else if ((scan
== *mangled
) && !ISDIGIT ((unsigned char)scan
[2])
2720 && (scan
[2] != 't'))
2722 /* Mangled name starts with "__". Skip over any leading '_' characters,
2723 then find the next "__" that separates the prefix from the signature.
2725 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2726 || (arm_special (mangled
, declp
) == 0))
2728 while (*scan
== '_')
2732 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2734 /* No separator (I.E. "__not_mangled"), or empty signature
2735 (I.E. "__not_mangled_either__") */
2739 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2742 else if (*(scan
+ 2) != '\0')
2744 /* Mangled name does not start with "__" but does have one somewhere
2745 in there with non empty stuff after it. Looks like a global
2746 function name. Iterate over all "__":s until the right
2748 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2752 /* Doesn't look like a mangled name */
2756 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2758 string_append (declp
, *mangled
);
2759 *mangled
+= strlen (*mangled
);
2769 gnu_special -- special handling of gnu mangled strings
2774 gnu_special (struct work_stuff *work, const char **mangled,
2780 Process some special GNU style mangling forms that don't fit
2781 the normal pattern. For example:
2783 _$_3foo (destructor for class foo)
2784 _vt$foo (foo virtual table)
2785 _vt$foo$bar (foo::bar virtual table)
2786 __vt_foo (foo virtual table, new style with thunks)
2787 _3foo$varname (static data member)
2788 _Q22rs2tu$vw (static data member)
2789 __t6vector1Zii (constructor with template)
2790 __thunk_4__$_7ostream (virtual function thunk)
2794 gnu_special (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2800 if ((*mangled
)[0] == '_'
2801 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2802 && (*mangled
)[2] == '_')
2804 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2806 work
-> destructor
+= 1;
2808 else if ((*mangled
)[0] == '_'
2809 && (((*mangled
)[1] == '_'
2810 && (*mangled
)[2] == 'v'
2811 && (*mangled
)[3] == 't'
2812 && (*mangled
)[4] == '_')
2813 || ((*mangled
)[1] == 'v'
2814 && (*mangled
)[2] == 't'
2815 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2817 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2818 and create the decl. Note that we consume the entire mangled
2819 input string, which means that demangle_signature has no work
2821 if ((*mangled
)[2] == 'v')
2822 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2824 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2825 while (**mangled
!= '\0')
2831 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2834 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2838 if (ISDIGIT((unsigned char)*mangled
[0]))
2840 n
= consume_count(mangled
);
2841 /* We may be seeing a too-large size, or else a
2842 ".<digits>" indicating a static local symbol. In
2843 any case, declare victory and move on; *don't* try
2844 to use n to allocate. */
2845 if (n
> (int) strlen (*mangled
))
2853 n
= strcspn (*mangled
, cplus_markers
);
2855 string_appendn (declp
, *mangled
, n
);
2859 p
= strpbrk (*mangled
, cplus_markers
);
2860 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2864 string_append (declp
, SCOPE_STRING (work
));
2875 string_append (declp
, " virtual table");
2877 else if ((*mangled
)[0] == '_'
2878 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
2879 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
2881 /* static data member, "_3foo$varname" for example */
2887 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2890 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2893 n
= consume_count (mangled
);
2894 if (n
< 0 || n
> (long) strlen (*mangled
))
2900 if (n
> 10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2901 && (*mangled
)[9] == 'N'
2902 && (*mangled
)[8] == (*mangled
)[10]
2903 && strchr (cplus_markers
, (*mangled
)[8]))
2905 /* A member of the anonymous namespace. There's information
2906 about what identifier or filename it was keyed to, but
2907 it's just there to make the mangled name unique; we just
2909 string_append (declp
, "{anonymous}");
2912 /* Now p points to the marker before the N, so we need to
2913 update it to the first marker after what we consumed. */
2914 p
= strpbrk (*mangled
, cplus_markers
);
2918 string_appendn (declp
, *mangled
, n
);
2921 if (success
&& (p
== *mangled
))
2923 /* Consumed everything up to the cplus_marker, append the
2926 string_append (declp
, SCOPE_STRING (work
));
2927 n
= strlen (*mangled
);
2928 string_appendn (declp
, *mangled
, n
);
2936 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
2941 delta
= consume_count (mangled
);
2946 char *method
= internal_cplus_demangle (work
, ++*mangled
);
2951 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
2952 string_append (declp
, buf
);
2953 string_append (declp
, method
);
2955 n
= strlen (*mangled
);
2964 else if (strncmp (*mangled
, "__t", 3) == 0
2965 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
2967 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
2973 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2976 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
2979 success
= do_type (work
, mangled
, declp
);
2982 if (success
&& **mangled
!= '\0')
2985 string_append (declp
, p
);
2995 recursively_demangle(struct work_stuff
*work
, const char **mangled
,
2996 string
*result
, int namelength
)
2998 char * recurse
= (char *)NULL
;
2999 char * recurse_dem
= (char *)NULL
;
3001 recurse
= (char *) xmalloc (namelength
+ 1);
3002 memcpy (recurse
, *mangled
, namelength
);
3003 recurse
[namelength
] = '\000';
3005 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3009 string_append (result
, recurse_dem
);
3014 string_appendn (result
, *mangled
, namelength
);
3017 *mangled
+= namelength
;
3024 arm_special -- special handling of ARM/lucid mangled strings
3029 arm_special (const char **mangled,
3035 Process some special ARM style mangling forms that don't fit
3036 the normal pattern. For example:
3038 __vtbl__3foo (foo virtual table)
3039 __vtbl__3foo__3bar (bar::foo virtual table)
3044 arm_special (const char **mangled
, string
*declp
)
3050 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
3052 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3053 and create the decl. Note that we consume the entire mangled
3054 input string, which means that demangle_signature has no work
3056 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
3057 while (*scan
!= '\0') /* first check it can be demangled */
3059 n
= consume_count (&scan
);
3062 return (0); /* no good */
3065 if (scan
[0] == '_' && scan
[1] == '_')
3070 (*mangled
) += ARM_VTABLE_STRLEN
;
3071 while (**mangled
!= '\0')
3073 n
= consume_count (mangled
);
3075 || n
> (long) strlen (*mangled
))
3077 string_prependn (declp
, *mangled
, n
);
3079 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
3081 string_prepend (declp
, "::");
3085 string_append (declp
, " virtual table");
3098 demangle_qualified -- demangle 'Q' qualified name strings
3103 demangle_qualified (struct work_stuff *, const char *mangled,
3104 string *result, int isfuncname, int append);
3108 Demangle a qualified name, such as "Q25Outer5Inner" which is
3109 the mangled form of "Outer::Inner". The demangled output is
3110 prepended or appended to the result string according to the
3111 state of the append flag.
3113 If isfuncname is nonzero, then the qualified name we are building
3114 is going to be used as a member function name, so if it is a
3115 constructor or destructor function, append an appropriate
3116 constructor or destructor name. I.E. for the above example,
3117 the result for use as a constructor is "Outer::Inner::Inner"
3118 and the result for use as a destructor is "Outer::Inner::~Inner".
3122 Numeric conversion is ASCII dependent (FIXME).
3127 demangle_qualified (struct work_stuff
*work
, const char **mangled
,
3128 string
*result
, int isfuncname
, int append
)
3135 int bindex
= register_Btype (work
);
3137 /* We only make use of ISFUNCNAME if the entity is a constructor or
3139 isfuncname
= (isfuncname
3140 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
3142 string_init (&temp
);
3143 string_init (&last_name
);
3145 if ((*mangled
)[0] == 'K')
3147 /* Squangling qualified name reuse */
3150 idx
= consume_count_with_underscores (mangled
);
3151 if (idx
== -1 || idx
>= work
-> numk
)
3154 string_append (&temp
, work
-> ktypevec
[idx
]);
3157 switch ((*mangled
)[1])
3160 /* GNU mangled name with more than 9 classes. The count is preceded
3161 by an underscore (to distinguish it from the <= 9 case) and followed
3162 by an underscore. */
3164 qualifiers
= consume_count_with_underscores (mangled
);
3165 if (qualifiers
== -1)
3178 /* The count is in a single digit. */
3179 num
[0] = (*mangled
)[1];
3181 qualifiers
= atoi (num
);
3183 /* If there is an underscore after the digit, skip it. This is
3184 said to be for ARM-qualified names, but the ARM makes no
3185 mention of such an underscore. Perhaps cfront uses one. */
3186 if ((*mangled
)[2] == '_')
3201 /* Pick off the names and collect them in the temp buffer in the order
3202 in which they are found, separated by '::'. */
3204 while (qualifiers
-- > 0)
3207 string_clear (&last_name
);
3209 if (*mangled
[0] == '_')
3212 if (*mangled
[0] == 't')
3214 /* Here we always append to TEMP since we will want to use
3215 the template name without the template parameters as a
3216 constructor or destructor name. The appropriate
3217 (parameter-less) value is returned by demangle_template
3218 in LAST_NAME. We do not remember the template type here,
3219 in order to match the G++ mangling algorithm. */
3220 success
= demangle_template(work
, mangled
, &temp
,
3225 else if (*mangled
[0] == 'K')
3229 idx
= consume_count_with_underscores (mangled
);
3230 if (idx
== -1 || idx
>= work
->numk
)
3233 string_append (&temp
, work
->ktypevec
[idx
]);
3236 if (!success
) break;
3243 /* Now recursively demangle the qualifier
3244 * This is necessary to deal with templates in
3245 * mangling styles like EDG */
3246 namelength
= consume_count (mangled
);
3247 if (namelength
== -1)
3252 recursively_demangle(work
, mangled
, &temp
, namelength
);
3256 string_delete (&last_name
);
3257 success
= do_type (work
, mangled
, &last_name
);
3260 string_appends (&temp
, &last_name
);
3265 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
3268 string_append (&temp
, SCOPE_STRING (work
));
3271 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
3273 /* If we are using the result as a function name, we need to append
3274 the appropriate '::' separated constructor or destructor name.
3275 We do this here because this is the most convenient place, where
3276 we already have a pointer to the name and the length of the name. */
3280 string_append (&temp
, SCOPE_STRING (work
));
3281 if (work
-> destructor
& 1)
3282 string_append (&temp
, "~");
3283 string_appends (&temp
, &last_name
);
3286 /* Now either prepend the temp buffer to the result, or append it,
3287 depending upon the state of the append flag. */
3290 string_appends (result
, &temp
);
3293 if (!STRING_EMPTY (result
))
3294 string_append (&temp
, SCOPE_STRING (work
));
3295 string_prepends (result
, &temp
);
3298 string_delete (&last_name
);
3299 string_delete (&temp
);
3307 get_count -- convert an ascii count to integer, consuming tokens
3312 get_count (const char **type, int *count)
3316 Assume that *type points at a count in a mangled name; set
3317 *count to its value, and set *type to the next character after
3318 the count. There are some weird rules in effect here.
3320 If *type does not point at a string of digits, return zero.
3322 If *type points at a string of digits followed by an
3323 underscore, set *count to their value as an integer, advance
3324 *type to point *after the underscore, and return 1.
3326 If *type points at a string of digits not followed by an
3327 underscore, consume only the first digit. Set *count to its
3328 value as an integer, leave *type pointing after that digit,
3331 The excuse for this odd behavior: in the ARM and HP demangling
3332 styles, a type can be followed by a repeat count of the form
3335 `x' is a single digit specifying how many additional copies
3336 of the type to append to the argument list, and
3338 `y' is one or more digits, specifying the zero-based index of
3339 the first repeated argument in the list. Yes, as you're
3340 unmangling the name you can figure this out yourself, but
3343 So, for example, in `bar__3fooFPiN51', the first argument is a
3344 pointer to an integer (`Pi'), and then the next five arguments
3345 are the same (`N5'), and the first repeat is the function's
3346 second argument (`1').
3350 get_count (const char **type
, int *count
)
3355 if (!ISDIGIT ((unsigned char)**type
))
3359 *count
= **type
- '0';
3361 if (ISDIGIT ((unsigned char)**type
))
3371 while (ISDIGIT ((unsigned char)*p
));
3382 /* RESULT will be initialised here; it will be freed on failure. The
3383 value returned is really a type_kind_t. */
3386 do_type (struct work_stuff
*work
, const char **mangled
, string
*result
)
3392 const char *remembered_type
;
3394 type_kind_t tk
= tk_none
;
3396 string_init (&decl
);
3397 string_init (result
);
3401 while (success
&& !done
)
3407 /* A pointer type */
3411 if (! (work
-> options
& DMGL_JAVA
))
3412 string_prepend (&decl
, "*");
3417 /* A reference type */
3420 string_prepend (&decl
, "&");
3429 if (!STRING_EMPTY (&decl
)
3430 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3432 string_prepend (&decl
, "(");
3433 string_append (&decl
, ")");
3435 string_append (&decl
, "[");
3436 if (**mangled
!= '_')
3437 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3439 if (**mangled
== '_')
3441 string_append (&decl
, "]");
3445 /* A back reference to a previously seen type */
3448 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3454 remembered_type
= work
-> typevec
[n
];
3455 mangled
= &remembered_type
;
3462 if (!STRING_EMPTY (&decl
)
3463 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3465 string_prepend (&decl
, "(");
3466 string_append (&decl
, ")");
3468 /* After picking off the function args, we expect to either find the
3469 function return type (preceded by an '_') or the end of the
3471 if (!demangle_nested_args (work
, mangled
, &decl
)
3472 || (**mangled
!= '_' && **mangled
!= '\0'))
3477 if (success
&& (**mangled
== '_'))
3484 type_quals
= TYPE_UNQUALIFIED
;
3486 member
= **mangled
== 'M';
3489 string_append (&decl
, ")");
3491 /* We don't need to prepend `::' for a qualified name;
3492 demangle_qualified will do that for us. */
3493 if (**mangled
!= 'Q')
3494 string_prepend (&decl
, SCOPE_STRING (work
));
3496 if (ISDIGIT ((unsigned char)**mangled
))
3498 n
= consume_count (mangled
);
3500 || (int) strlen (*mangled
) < n
)
3505 string_prependn (&decl
, *mangled
, n
);
3508 else if (**mangled
== 'X' || **mangled
== 'Y')
3511 do_type (work
, mangled
, &temp
);
3512 string_prepends (&decl
, &temp
);
3513 string_delete (&temp
);
3515 else if (**mangled
== 't')
3518 string_init (&temp
);
3519 success
= demangle_template (work
, mangled
, &temp
,
3523 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3524 string_delete (&temp
);
3529 else if (**mangled
== 'Q')
3531 success
= demangle_qualified (work
, mangled
, &decl
,
3543 string_prepend (&decl
, "(");
3551 type_quals
|= code_for_qualifier (**mangled
);
3559 if (*(*mangled
)++ != 'F')
3565 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3566 || **mangled
!= '_')
3572 if (! PRINT_ANSI_QUALIFIERS
)
3576 if (type_quals
!= TYPE_UNQUALIFIED
)
3578 APPEND_BLANK (&decl
);
3579 string_append (&decl
, qualifier_string (type_quals
));
3590 if (PRINT_ANSI_QUALIFIERS
)
3592 if (!STRING_EMPTY (&decl
))
3593 string_prepend (&decl
, " ");
3595 string_prepend (&decl
, demangle_qualifier (**mangled
));
3610 if (success
) switch (**mangled
)
3612 /* A qualified name, such as "Outer::Inner". */
3616 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3620 /* A back reference to a previously seen squangled type */
3623 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3626 string_append (result
, work
->btypevec
[n
]);
3631 /* A template parm. We substitute the corresponding argument. */
3636 idx
= consume_count_with_underscores (mangled
);
3639 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3640 || consume_count_with_underscores (mangled
) == -1)
3646 if (work
->tmpl_argvec
)
3647 string_append (result
, work
->tmpl_argvec
[idx
]);
3649 string_append_template_idx (result
, idx
);
3656 success
= demangle_fund_type (work
, mangled
, result
);
3658 tk
= (type_kind_t
) success
;
3664 if (!STRING_EMPTY (&decl
))
3666 string_append (result
, " ");
3667 string_appends (result
, &decl
);
3671 string_delete (result
);
3672 string_delete (&decl
);
3675 /* Assume an integral type, if we're not sure. */
3676 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3681 /* Given a pointer to a type string that represents a fundamental type
3682 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3683 string in which the demangled output is being built in RESULT, and
3684 the WORK structure, decode the types and add them to the result.
3689 "Sl" => "signed long"
3690 "CUs" => "const unsigned short"
3692 The value returned is really a type_kind_t. */
3695 demangle_fund_type (struct work_stuff
*work
,
3696 const char **mangled
, string
*result
)
3701 unsigned int dec
= 0;
3702 type_kind_t tk
= tk_integral
;
3704 /* First pick off any type qualifiers. There can be more than one. */
3713 if (PRINT_ANSI_QUALIFIERS
)
3715 if (!STRING_EMPTY (result
))
3716 string_prepend (result
, " ");
3717 string_prepend (result
, demangle_qualifier (**mangled
));
3723 APPEND_BLANK (result
);
3724 string_append (result
, "unsigned");
3726 case 'S': /* signed char only */
3728 APPEND_BLANK (result
);
3729 string_append (result
, "signed");
3733 APPEND_BLANK (result
);
3734 string_append (result
, "__complex");
3742 /* Now pick off the fundamental type. There can be only one. */
3751 APPEND_BLANK (result
);
3752 string_append (result
, "void");
3756 APPEND_BLANK (result
);
3757 string_append (result
, "long long");
3761 APPEND_BLANK (result
);
3762 string_append (result
, "long");
3766 APPEND_BLANK (result
);
3767 string_append (result
, "int");
3771 APPEND_BLANK (result
);
3772 string_append (result
, "short");
3776 APPEND_BLANK (result
);
3777 string_append (result
, "bool");
3782 APPEND_BLANK (result
);
3783 string_append (result
, "char");
3788 APPEND_BLANK (result
);
3789 string_append (result
, "wchar_t");
3794 APPEND_BLANK (result
);
3795 string_append (result
, "long double");
3800 APPEND_BLANK (result
);
3801 string_append (result
, "double");
3806 APPEND_BLANK (result
);
3807 string_append (result
, "float");
3812 if (!ISDIGIT ((unsigned char)**mangled
))
3819 if (**mangled
== '_')
3824 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3827 if (**mangled
!= '_')
3837 strncpy (buf
, *mangled
, 2);
3839 *mangled
+= min (strlen (*mangled
), 2);
3841 sscanf (buf
, "%x", &dec
);
3842 sprintf (buf
, "int%u_t", dec
);
3843 APPEND_BLANK (result
);
3844 string_append (result
, buf
);
3848 /* An explicit type, such as "6mytype" or "7integer" */
3860 int bindex
= register_Btype (work
);
3862 string_init (&btype
);
3863 if (demangle_class_name (work
, mangled
, &btype
)) {
3864 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3865 APPEND_BLANK (result
);
3866 string_appends (result
, &btype
);
3870 string_delete (&btype
);
3876 string_init (&btype
);
3877 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
3878 string_appends (result
, &btype
);
3879 string_delete (&btype
);
3887 return success
? ((int) tk
) : 0;
3891 /* Handle a template's value parameter for HP aCC (extension from ARM)
3892 **mangled points to 'S' or 'U' */
3895 do_hpacc_template_const_value (struct work_stuff
*work ATTRIBUTE_UNUSED
,
3896 const char **mangled
, string
*result
)
3900 if (**mangled
!= 'U' && **mangled
!= 'S')
3903 unsigned_const
= (**mangled
== 'U');
3910 string_append (result
, "-");
3916 /* special case for -2^31 */
3917 string_append (result
, "-2147483648");
3924 /* We have to be looking at an integer now */
3925 if (!(ISDIGIT ((unsigned char)**mangled
)))
3928 /* We only deal with integral values for template
3929 parameters -- so it's OK to look only for digits */
3930 while (ISDIGIT ((unsigned char)**mangled
))
3932 char_str
[0] = **mangled
;
3933 string_append (result
, char_str
);
3938 string_append (result
, "U");
3940 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
3941 with L or LL suffixes. pai/1997-09-03 */
3943 return 1; /* success */
3946 /* Handle a template's literal parameter for HP aCC (extension from ARM)
3947 **mangled is pointing to the 'A' */
3950 do_hpacc_template_literal (struct work_stuff
*work
, const char **mangled
,
3953 int literal_len
= 0;
3957 if (**mangled
!= 'A')
3962 literal_len
= consume_count (mangled
);
3964 if (literal_len
<= 0)
3967 /* Literal parameters are names of arrays, functions, etc. and the
3968 canonical representation uses the address operator */
3969 string_append (result
, "&");
3971 /* Now recursively demangle the literal name */
3972 recurse
= (char *) xmalloc (literal_len
+ 1);
3973 memcpy (recurse
, *mangled
, literal_len
);
3974 recurse
[literal_len
] = '\000';
3976 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3980 string_append (result
, recurse_dem
);
3985 string_appendn (result
, *mangled
, literal_len
);
3987 (*mangled
) += literal_len
;
3994 snarf_numeric_literal (const char **args
, string
*arg
)
3999 string_append (arg
, char_str
);
4002 else if (**args
== '+')
4005 if (!ISDIGIT ((unsigned char)**args
))
4008 while (ISDIGIT ((unsigned char)**args
))
4010 char_str
[0] = **args
;
4011 string_append (arg
, char_str
);
4018 /* Demangle the next argument, given by MANGLED into RESULT, which
4019 *should be an uninitialized* string. It will be initialized here,
4020 and free'd should anything go wrong. */
4023 do_arg (struct work_stuff
*work
, const char **mangled
, string
*result
)
4025 /* Remember where we started so that we can record the type, for
4026 non-squangling type remembering. */
4027 const char *start
= *mangled
;
4029 string_init (result
);
4031 if (work
->nrepeats
> 0)
4035 if (work
->previous_argument
== 0)
4038 /* We want to reissue the previous type in this argument list. */
4039 string_appends (result
, work
->previous_argument
);
4043 if (**mangled
== 'n')
4045 /* A squangling-style repeat. */
4047 work
->nrepeats
= consume_count(mangled
);
4049 if (work
->nrepeats
<= 0)
4050 /* This was not a repeat count after all. */
4053 if (work
->nrepeats
> 9)
4055 if (**mangled
!= '_')
4056 /* The repeat count should be followed by an '_' in this
4063 /* Now, the repeat is all set up. */
4064 return do_arg (work
, mangled
, result
);
4067 /* Save the result in WORK->previous_argument so that we can find it
4068 if it's repeated. Note that saving START is not good enough: we
4069 do not want to add additional types to the back-referenceable
4070 type vector when processing a repeated type. */
4071 if (work
->previous_argument
)
4072 string_delete (work
->previous_argument
);
4074 work
->previous_argument
= (string
*) xmalloc (sizeof (string
));
4076 if (!do_type (work
, mangled
, work
->previous_argument
))
4079 string_appends (result
, work
->previous_argument
);
4081 remember_type (work
, start
, *mangled
- start
);
4086 remember_type (struct work_stuff
*work
, const char *start
, int len
)
4090 if (work
->forgetting_types
)
4093 if (work
-> ntypes
>= work
-> typevec_size
)
4095 if (work
-> typevec_size
== 0)
4097 work
-> typevec_size
= 3;
4099 = (char **) xmalloc (sizeof (char *) * work
-> typevec_size
);
4103 work
-> typevec_size
*= 2;
4105 = (char **) xrealloc ((char *)work
-> typevec
,
4106 sizeof (char *) * work
-> typevec_size
);
4109 tem
= xmalloc (len
+ 1);
4110 memcpy (tem
, start
, len
);
4112 work
-> typevec
[work
-> ntypes
++] = tem
;
4116 /* Remember a K type class qualifier. */
4118 remember_Ktype (struct work_stuff
*work
, const char *start
, int len
)
4122 if (work
-> numk
>= work
-> ksize
)
4124 if (work
-> ksize
== 0)
4128 = (char **) xmalloc (sizeof (char *) * work
-> ksize
);
4134 = (char **) xrealloc ((char *)work
-> ktypevec
,
4135 sizeof (char *) * work
-> ksize
);
4138 tem
= xmalloc (len
+ 1);
4139 memcpy (tem
, start
, len
);
4141 work
-> ktypevec
[work
-> numk
++] = tem
;
4144 /* Register a B code, and get an index for it. B codes are registered
4145 as they are seen, rather than as they are completed, so map<temp<char> >
4146 registers map<temp<char> > as B0, and temp<char> as B1 */
4149 register_Btype (struct work_stuff
*work
)
4153 if (work
-> numb
>= work
-> bsize
)
4155 if (work
-> bsize
== 0)
4159 = (char **) xmalloc (sizeof (char *) * work
-> bsize
);
4165 = (char **) xrealloc ((char *)work
-> btypevec
,
4166 sizeof (char *) * work
-> bsize
);
4169 ret
= work
-> numb
++;
4170 work
-> btypevec
[ret
] = NULL
;
4174 /* Store a value into a previously registered B code type. */
4177 remember_Btype (struct work_stuff
*work
, const char *start
,
4182 tem
= xmalloc (len
+ 1);
4183 memcpy (tem
, start
, len
);
4185 work
-> btypevec
[index
] = tem
;
4188 /* Lose all the info related to B and K type codes. */
4190 forget_B_and_K_types (struct work_stuff
*work
)
4194 while (work
-> numk
> 0)
4196 i
= --(work
-> numk
);
4197 if (work
-> ktypevec
[i
] != NULL
)
4199 free (work
-> ktypevec
[i
]);
4200 work
-> ktypevec
[i
] = NULL
;
4204 while (work
-> numb
> 0)
4206 i
= --(work
-> numb
);
4207 if (work
-> btypevec
[i
] != NULL
)
4209 free (work
-> btypevec
[i
]);
4210 work
-> btypevec
[i
] = NULL
;
4214 /* Forget the remembered types, but not the type vector itself. */
4217 forget_types (struct work_stuff
*work
)
4221 while (work
-> ntypes
> 0)
4223 i
= --(work
-> ntypes
);
4224 if (work
-> typevec
[i
] != NULL
)
4226 free (work
-> typevec
[i
]);
4227 work
-> typevec
[i
] = NULL
;
4232 /* Process the argument list part of the signature, after any class spec
4233 has been consumed, as well as the first 'F' character (if any). For
4236 "__als__3fooRT0" => process "RT0"
4237 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4239 DECLP must be already initialised, usually non-empty. It won't be freed
4242 Note that g++ differs significantly from ARM and lucid style mangling
4243 with regards to references to previously seen types. For example, given
4244 the source fragment:
4248 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4251 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4252 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4254 g++ produces the names:
4259 while lcc (and presumably other ARM style compilers as well) produces:
4261 foo__FiR3fooT1T2T1T2
4262 __ct__3fooFiR3fooT1T2T1T2
4264 Note that g++ bases its type numbers starting at zero and counts all
4265 previously seen types, while lucid/ARM bases its type numbers starting
4266 at one and only considers types after it has seen the 'F' character
4267 indicating the start of the function args. For lucid/ARM style, we
4268 account for this difference by discarding any previously seen types when
4269 we see the 'F' character, and subtracting one from the type number
4275 demangle_args (struct work_stuff
*work
, const char **mangled
,
4285 if (PRINT_ARG_TYPES
)
4287 string_append (declp
, "(");
4288 if (**mangled
== '\0')
4290 string_append (declp
, "void");
4294 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
4295 || work
->nrepeats
> 0)
4297 if ((**mangled
== 'N') || (**mangled
== 'T'))
4299 temptype
= *(*mangled
)++;
4301 if (temptype
== 'N')
4303 if (!get_count (mangled
, &r
))
4312 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
4314 /* If we have 10 or more types we might have more than a 1 digit
4315 index so we'll have to consume the whole count here. This
4316 will lose if the next thing is a type name preceded by a
4317 count but it's impossible to demangle that case properly
4318 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4319 Pc, ...)" or "(..., type12, char *, ...)" */
4320 if ((t
= consume_count(mangled
)) <= 0)
4327 if (!get_count (mangled
, &t
))
4332 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4336 /* Validate the type index. Protect against illegal indices from
4337 malformed type strings. */
4338 if ((t
< 0) || (t
>= work
-> ntypes
))
4342 while (work
->nrepeats
> 0 || --r
>= 0)
4344 tem
= work
-> typevec
[t
];
4345 if (need_comma
&& PRINT_ARG_TYPES
)
4347 string_append (declp
, ", ");
4349 if (!do_arg (work
, &tem
, &arg
))
4353 if (PRINT_ARG_TYPES
)
4355 string_appends (declp
, &arg
);
4357 string_delete (&arg
);
4363 if (need_comma
&& PRINT_ARG_TYPES
)
4364 string_append (declp
, ", ");
4365 if (!do_arg (work
, mangled
, &arg
))
4367 if (PRINT_ARG_TYPES
)
4368 string_appends (declp
, &arg
);
4369 string_delete (&arg
);
4374 if (**mangled
== 'e')
4377 if (PRINT_ARG_TYPES
)
4381 string_append (declp
, ",");
4383 string_append (declp
, "...");
4387 if (PRINT_ARG_TYPES
)
4389 string_append (declp
, ")");
4394 /* Like demangle_args, but for demangling the argument lists of function
4395 and method pointers or references, not top-level declarations. */
4398 demangle_nested_args (struct work_stuff
*work
, const char **mangled
,
4401 string
* saved_previous_argument
;
4405 /* The G++ name-mangling algorithm does not remember types on nested
4406 argument lists, unless -fsquangling is used, and in that case the
4407 type vector updated by remember_type is not used. So, we turn
4408 off remembering of types here. */
4409 ++work
->forgetting_types
;
4411 /* For the repeat codes used with -fsquangling, we must keep track of
4412 the last argument. */
4413 saved_previous_argument
= work
->previous_argument
;
4414 saved_nrepeats
= work
->nrepeats
;
4415 work
->previous_argument
= 0;
4418 /* Actually demangle the arguments. */
4419 result
= demangle_args (work
, mangled
, declp
);
4421 /* Restore the previous_argument field. */
4422 if (work
->previous_argument
)
4424 string_delete (work
->previous_argument
);
4425 free ((char *) work
->previous_argument
);
4427 work
->previous_argument
= saved_previous_argument
;
4428 --work
->forgetting_types
;
4429 work
->nrepeats
= saved_nrepeats
;
4435 demangle_function_name (struct work_stuff
*work
, const char **mangled
,
4436 string
*declp
, const char *scan
)
4442 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4443 string_need (declp
, 1);
4444 *(declp
-> p
) = '\0';
4446 /* Consume the function name, including the "__" separating the name
4447 from the signature. We are guaranteed that SCAN points to the
4450 (*mangled
) = scan
+ 2;
4451 /* We may be looking at an instantiation of a template function:
4452 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4453 following _F marks the start of the function arguments. Handle
4454 the template arguments first. */
4456 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4458 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4459 /* This leaves MANGLED pointing to the 'F' marking func args */
4462 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4465 /* See if we have an ARM style constructor or destructor operator.
4466 If so, then just record it, clear the decl, and return.
4467 We can't build the actual constructor/destructor decl until later,
4468 when we recover the class name from the signature. */
4470 if (strcmp (declp
-> b
, "__ct") == 0)
4472 work
-> constructor
+= 1;
4473 string_clear (declp
);
4476 else if (strcmp (declp
-> b
, "__dt") == 0)
4478 work
-> destructor
+= 1;
4479 string_clear (declp
);
4484 if (declp
->p
- declp
->b
>= 3
4485 && declp
->b
[0] == 'o'
4486 && declp
->b
[1] == 'p'
4487 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4489 /* see if it's an assignment expression */
4490 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4491 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4493 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4495 int len
= declp
->p
- declp
->b
- 10;
4496 if ((int) strlen (optable
[i
].in
) == len
4497 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4499 string_clear (declp
);
4500 string_append (declp
, "operator");
4501 string_append (declp
, optable
[i
].out
);
4502 string_append (declp
, "=");
4509 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4511 int len
= declp
->p
- declp
->b
- 3;
4512 if ((int) strlen (optable
[i
].in
) == len
4513 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4515 string_clear (declp
);
4516 string_append (declp
, "operator");
4517 string_append (declp
, optable
[i
].out
);
4523 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4524 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4526 /* type conversion operator */
4528 if (do_type (work
, &tem
, &type
))
4530 string_clear (declp
);
4531 string_append (declp
, "operator ");
4532 string_appends (declp
, &type
);
4533 string_delete (&type
);
4536 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4537 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4540 /* type conversion operator. */
4542 if (do_type (work
, &tem
, &type
))
4544 string_clear (declp
);
4545 string_append (declp
, "operator ");
4546 string_appends (declp
, &type
);
4547 string_delete (&type
);
4550 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4551 && ISLOWER((unsigned char)declp
->b
[2])
4552 && ISLOWER((unsigned char)declp
->b
[3]))
4554 if (declp
->b
[4] == '\0')
4557 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4559 if (strlen (optable
[i
].in
) == 2
4560 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4562 string_clear (declp
);
4563 string_append (declp
, "operator");
4564 string_append (declp
, optable
[i
].out
);
4571 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4574 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4576 if (strlen (optable
[i
].in
) == 3
4577 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4579 string_clear (declp
);
4580 string_append (declp
, "operator");
4581 string_append (declp
, optable
[i
].out
);
4590 /* a mini string-handling package */
4593 string_need (string
*s
, int n
)
4603 s
->p
= s
->b
= xmalloc (n
);
4606 else if (s
->e
- s
->p
< n
)
4611 s
->b
= xrealloc (s
->b
, n
);
4618 string_delete (string
*s
)
4623 s
->b
= s
->e
= s
->p
= NULL
;
4628 string_init (string
*s
)
4630 s
->b
= s
->p
= s
->e
= NULL
;
4634 string_clear (string
*s
)
4642 string_empty (string
*s
)
4644 return (s
->b
== s
->p
);
4650 string_append (string
*p
, const char *s
)
4653 if (s
== NULL
|| *s
== '\0')
4657 memcpy (p
->p
, s
, n
);
4662 string_appends (string
*p
, string
*s
)
4670 memcpy (p
->p
, s
->b
, n
);
4676 string_appendn (string
*p
, const char *s
, int n
)
4681 memcpy (p
->p
, s
, n
);
4687 string_prepend (string
*p
, const char *s
)
4689 if (s
!= NULL
&& *s
!= '\0')
4691 string_prependn (p
, s
, strlen (s
));
4696 string_prepends (string
*p
, string
*s
)
4700 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4705 string_prependn (string
*p
, const char *s
, int n
)
4712 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4716 memcpy (p
->b
, s
, n
);
4722 string_append_template_idx (string
*s
, int idx
)
4724 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4725 sprintf(buf
, "T%d", idx
);
4726 string_append (s
, buf
);