1 /* Demangler for GNU C++
2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
4 Written by James Clark (jjc@jclark.uucp)
5 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
6 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
8 This file is part of the libiberty library.
9 Libiberty is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
14 In addition to the permissions in the GNU Library General Public
15 License, the Free Software Foundation gives you unlimited permission
16 to link the compiled version of this file into combinations with other
17 programs, and to distribute those combinations without any restriction
18 coming from the use of this file. (The Library Public License
19 restrictions do apply in other respects; for example, they cover
20 modification of the file, and distribution when not linked into a
23 Libiberty is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 Library General Public License for more details.
28 You should have received a copy of the GNU Library General Public
29 License along with libiberty; see the file COPYING.LIB. If
30 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
31 Boston, MA 02110-1301, USA. */
33 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
35 This file imports xmalloc and xrealloc, which are like malloc and
36 realloc except that they generate a fatal error if there is no
39 /* This file lives in both GCC and libiberty. When making changes, please
40 try not to break either. */
46 #include "safe-ctype.h"
48 #include <sys/types.h>
60 #undef CURRENT_DEMANGLING_STYLE
61 #define CURRENT_DEMANGLING_STYLE work->options
63 #include "libiberty.h"
65 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
67 /* A value at least one greater than the maximum number of characters
68 that will be output when using the `%d' format with `printf'. */
69 #define INTBUF_SIZE 32
71 extern void fancy_abort (void) ATTRIBUTE_NORETURN
;
73 /* In order to allow a single demangler executable to demangle strings
74 using various common values of CPLUS_MARKER, as well as any specific
75 one set at compile time, we maintain a string containing all the
76 commonly used ones, and check to see if the marker we are looking for
77 is in that string. CPLUS_MARKER is usually '$' on systems where the
78 assembler can deal with that. Where the assembler can't, it's usually
79 '.' (but on many systems '.' is used for other things). We put the
80 current defined CPLUS_MARKER first (which defaults to '$'), followed
81 by the next most common value, followed by an explicit '$' in case
82 the value of CPLUS_MARKER is not '$'.
84 We could avoid this if we could just get g++ to tell us what the actual
85 cplus marker character is as part of the debug information, perhaps by
86 ensuring that it is the character that terminates the gcc<n>_compiled
87 marker symbol (FIXME). */
89 #if !defined (CPLUS_MARKER)
90 #define CPLUS_MARKER '$'
93 enum demangling_styles current_demangling_style
= auto_demangling
;
95 static char cplus_markers
[] = { CPLUS_MARKER
, '.', '$', '\0' };
97 static char char_str
[2] = { '\000', '\000' };
100 set_cplus_marker_for_demangling (int ch
)
102 cplus_markers
[0] = ch
;
105 typedef struct string
/* Beware: these aren't required to be */
106 { /* '\0' terminated. */
107 char *b
; /* pointer to start of string */
108 char *p
; /* pointer after last character */
109 char *e
; /* pointer after end of allocated space */
112 /* Stuff that is shared between sub-routines.
113 Using a shared structure allows cplus_demangle to be reentrant. */
129 int static_type
; /* A static member function */
130 int temp_start
; /* index in demangled to start of template args */
131 int type_quals
; /* The type qualifiers. */
132 int dllimported
; /* Symbol imported from a PE DLL */
133 char **tmpl_argvec
; /* Template function arguments. */
134 int ntmpl_args
; /* The number of template function arguments. */
135 int forgetting_types
; /* Nonzero if we are not remembering the types
137 string
* previous_argument
; /* The last function argument demangled. */
138 int nrepeats
; /* The number of times to repeat the previous
142 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
143 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
145 static const struct optable
147 const char *const in
;
148 const char *const out
;
151 {"nw", " new", DMGL_ANSI
}, /* new (1.92, ansi) */
152 {"dl", " delete", DMGL_ANSI
}, /* new (1.92, ansi) */
153 {"new", " new", 0}, /* old (1.91, and 1.x) */
154 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
155 {"vn", " new []", DMGL_ANSI
}, /* GNU, pending ansi */
156 {"vd", " delete []", DMGL_ANSI
}, /* GNU, pending ansi */
157 {"as", "=", DMGL_ANSI
}, /* ansi */
158 {"ne", "!=", DMGL_ANSI
}, /* old, ansi */
159 {"eq", "==", DMGL_ANSI
}, /* old, ansi */
160 {"ge", ">=", DMGL_ANSI
}, /* old, ansi */
161 {"gt", ">", DMGL_ANSI
}, /* old, ansi */
162 {"le", "<=", DMGL_ANSI
}, /* old, ansi */
163 {"lt", "<", DMGL_ANSI
}, /* old, ansi */
164 {"plus", "+", 0}, /* old */
165 {"pl", "+", DMGL_ANSI
}, /* ansi */
166 {"apl", "+=", DMGL_ANSI
}, /* ansi */
167 {"minus", "-", 0}, /* old */
168 {"mi", "-", DMGL_ANSI
}, /* ansi */
169 {"ami", "-=", DMGL_ANSI
}, /* ansi */
170 {"mult", "*", 0}, /* old */
171 {"ml", "*", DMGL_ANSI
}, /* ansi */
172 {"amu", "*=", DMGL_ANSI
}, /* ansi (ARM/Lucid) */
173 {"aml", "*=", DMGL_ANSI
}, /* ansi (GNU/g++) */
174 {"convert", "+", 0}, /* old (unary +) */
175 {"negate", "-", 0}, /* old (unary -) */
176 {"trunc_mod", "%", 0}, /* old */
177 {"md", "%", DMGL_ANSI
}, /* ansi */
178 {"amd", "%=", DMGL_ANSI
}, /* ansi */
179 {"trunc_div", "/", 0}, /* old */
180 {"dv", "/", DMGL_ANSI
}, /* ansi */
181 {"adv", "/=", DMGL_ANSI
}, /* ansi */
182 {"truth_andif", "&&", 0}, /* old */
183 {"aa", "&&", DMGL_ANSI
}, /* ansi */
184 {"truth_orif", "||", 0}, /* old */
185 {"oo", "||", DMGL_ANSI
}, /* ansi */
186 {"truth_not", "!", 0}, /* old */
187 {"nt", "!", DMGL_ANSI
}, /* ansi */
188 {"postincrement","++", 0}, /* old */
189 {"pp", "++", DMGL_ANSI
}, /* ansi */
190 {"postdecrement","--", 0}, /* old */
191 {"mm", "--", DMGL_ANSI
}, /* ansi */
192 {"bit_ior", "|", 0}, /* old */
193 {"or", "|", DMGL_ANSI
}, /* ansi */
194 {"aor", "|=", DMGL_ANSI
}, /* ansi */
195 {"bit_xor", "^", 0}, /* old */
196 {"er", "^", DMGL_ANSI
}, /* ansi */
197 {"aer", "^=", DMGL_ANSI
}, /* ansi */
198 {"bit_and", "&", 0}, /* old */
199 {"ad", "&", DMGL_ANSI
}, /* ansi */
200 {"aad", "&=", DMGL_ANSI
}, /* ansi */
201 {"bit_not", "~", 0}, /* old */
202 {"co", "~", DMGL_ANSI
}, /* ansi */
203 {"call", "()", 0}, /* old */
204 {"cl", "()", DMGL_ANSI
}, /* ansi */
205 {"alshift", "<<", 0}, /* old */
206 {"ls", "<<", DMGL_ANSI
}, /* ansi */
207 {"als", "<<=", DMGL_ANSI
}, /* ansi */
208 {"arshift", ">>", 0}, /* old */
209 {"rs", ">>", DMGL_ANSI
}, /* ansi */
210 {"ars", ">>=", DMGL_ANSI
}, /* ansi */
211 {"component", "->", 0}, /* old */
212 {"pt", "->", DMGL_ANSI
}, /* ansi; Lucid C++ form */
213 {"rf", "->", DMGL_ANSI
}, /* ansi; ARM/GNU form */
214 {"indirect", "*", 0}, /* old */
215 {"method_call", "->()", 0}, /* old */
216 {"addr", "&", 0}, /* old (unary &) */
217 {"array", "[]", 0}, /* old */
218 {"vc", "[]", DMGL_ANSI
}, /* ansi */
219 {"compound", ", ", 0}, /* old */
220 {"cm", ", ", DMGL_ANSI
}, /* ansi */
221 {"cond", "?:", 0}, /* old */
222 {"cn", "?:", DMGL_ANSI
}, /* pseudo-ansi */
223 {"max", ">?", 0}, /* old */
224 {"mx", ">?", DMGL_ANSI
}, /* pseudo-ansi */
225 {"min", "<?", 0}, /* old */
226 {"mn", "<?", DMGL_ANSI
}, /* pseudo-ansi */
227 {"nop", "", 0}, /* old (for operator=) */
228 {"rm", "->*", DMGL_ANSI
}, /* ansi */
229 {"sz", "sizeof ", DMGL_ANSI
} /* pseudo-ansi */
232 /* These values are used to indicate the various type varieties.
233 They are all non-zero so that they can be used as `success'
235 typedef enum type_kind_t
246 const struct demangler_engine libiberty_demanglers
[] =
249 NO_DEMANGLING_STYLE_STRING
,
251 "Demangling disabled"
255 AUTO_DEMANGLING_STYLE_STRING
,
257 "Automatic selection based on executable"
261 GNU_DEMANGLING_STYLE_STRING
,
263 "GNU (g++) style demangling"
267 LUCID_DEMANGLING_STYLE_STRING
,
269 "Lucid (lcc) style demangling"
273 ARM_DEMANGLING_STYLE_STRING
,
275 "ARM style demangling"
279 HP_DEMANGLING_STYLE_STRING
,
281 "HP (aCC) style demangling"
285 EDG_DEMANGLING_STYLE_STRING
,
287 "EDG style demangling"
291 GNU_V3_DEMANGLING_STYLE_STRING
,
293 "GNU (g++) V3 ABI-style demangling"
297 JAVA_DEMANGLING_STYLE_STRING
,
299 "Java style demangling"
303 GNAT_DEMANGLING_STYLE_STRING
,
305 "GNAT style demangling"
309 DLANG_DEMANGLING_STYLE_STRING
,
311 "DLANG style demangling"
315 NULL
, unknown_demangling
, NULL
319 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
320 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
321 string_append(str, " ");}
322 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
324 /* The scope separator appropriate for the language being demangled. */
326 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
328 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
329 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
331 /* Prototypes for local functions */
333 static void delete_work_stuff (struct work_stuff
*);
335 static void delete_non_B_K_work_stuff (struct work_stuff
*);
337 static char *mop_up (struct work_stuff
*, string
*, int);
339 static void squangle_mop_up (struct work_stuff
*);
341 static void work_stuff_copy_to_from (struct work_stuff
*, struct work_stuff
*);
345 demangle_method_args (struct work_stuff
*, const char **, string
*);
349 internal_cplus_demangle (struct work_stuff
*, const char *);
352 demangle_template_template_parm (struct work_stuff
*work
,
353 const char **, string
*);
356 demangle_template (struct work_stuff
*work
, const char **, string
*,
360 arm_pt (struct work_stuff
*, const char *, int, const char **,
364 demangle_class_name (struct work_stuff
*, const char **, string
*);
367 demangle_qualified (struct work_stuff
*, const char **, string
*,
370 static int demangle_class (struct work_stuff
*, const char **, string
*);
372 static int demangle_fund_type (struct work_stuff
*, const char **, string
*);
374 static int demangle_signature (struct work_stuff
*, const char **, string
*);
376 static int demangle_prefix (struct work_stuff
*, const char **, string
*);
378 static int gnu_special (struct work_stuff
*, const char **, string
*);
380 static int arm_special (const char **, string
*);
382 static void string_need (string
*, int);
384 static void string_delete (string
*);
387 string_init (string
*);
389 static void string_clear (string
*);
392 static int string_empty (string
*);
395 static void string_append (string
*, const char *);
397 static void string_appends (string
*, string
*);
399 static void string_appendn (string
*, const char *, int);
401 static void string_prepend (string
*, const char *);
403 static void string_prependn (string
*, const char *, int);
405 static void string_append_template_idx (string
*, int);
407 static int get_count (const char **, int *);
409 static int consume_count (const char **);
411 static int consume_count_with_underscores (const char**);
413 static int demangle_args (struct work_stuff
*, const char **, string
*);
415 static int demangle_nested_args (struct work_stuff
*, const char**, string
*);
417 static int do_type (struct work_stuff
*, const char **, string
*);
419 static int do_arg (struct work_stuff
*, const char **, string
*);
422 demangle_function_name (struct work_stuff
*, const char **, string
*,
426 iterate_demangle_function (struct work_stuff
*,
427 const char **, string
*, const char *);
429 static void remember_type (struct work_stuff
*, const char *, int);
431 static void remember_Btype (struct work_stuff
*, const char *, int, int);
433 static int register_Btype (struct work_stuff
*);
435 static void remember_Ktype (struct work_stuff
*, const char *, int);
437 static void forget_types (struct work_stuff
*);
439 static void forget_B_and_K_types (struct work_stuff
*);
441 static void string_prepends (string
*, string
*);
444 demangle_template_value_parm (struct work_stuff
*, const char**,
445 string
*, type_kind_t
);
448 do_hpacc_template_const_value (struct work_stuff
*, const char **, string
*);
451 do_hpacc_template_literal (struct work_stuff
*, const char **, string
*);
453 static int snarf_numeric_literal (const char **, string
*);
455 /* There is a TYPE_QUAL value for each type qualifier. They can be
456 combined by bitwise-or to form the complete set of qualifiers for a
459 #define TYPE_UNQUALIFIED 0x0
460 #define TYPE_QUAL_CONST 0x1
461 #define TYPE_QUAL_VOLATILE 0x2
462 #define TYPE_QUAL_RESTRICT 0x4
464 static int code_for_qualifier (int);
466 static const char* qualifier_string (int);
468 static const char* demangle_qualifier (int);
470 static int demangle_expression (struct work_stuff
*, const char **, string
*,
474 demangle_integral_value (struct work_stuff
*, const char **, string
*);
477 demangle_real_value (struct work_stuff
*, const char **, string
*);
480 demangle_arm_hp_template (struct work_stuff
*, const char **, int, string
*);
483 recursively_demangle (struct work_stuff
*, const char **, string
*, int);
485 /* Translate count to integer, consuming tokens in the process.
486 Conversion terminates on the first non-digit character.
488 Trying to consume something that isn't a count results in no
489 consumption of input and a return of -1.
491 Overflow consumes the rest of the digits, and returns -1. */
494 consume_count (const char **type
)
498 if (! ISDIGIT ((unsigned char)**type
))
501 while (ISDIGIT ((unsigned char)**type
))
505 /* Check for overflow.
506 We assume that count is represented using two's-complement;
507 no power of two is divisible by ten, so if an overflow occurs
508 when multiplying by ten, the result will not be a multiple of
510 if ((count
% 10) != 0)
512 while (ISDIGIT ((unsigned char) **type
))
517 count
+= **type
- '0';
528 /* Like consume_count, but for counts that are preceded and followed
529 by '_' if they are greater than 10. Also, -1 is returned for
530 failure, since 0 can be a valid value. */
533 consume_count_with_underscores (const char **mangled
)
537 if (**mangled
== '_')
540 if (!ISDIGIT ((unsigned char)**mangled
))
543 idx
= consume_count (mangled
);
544 if (**mangled
!= '_')
545 /* The trailing underscore was missing. */
552 if (**mangled
< '0' || **mangled
> '9')
555 idx
= **mangled
- '0';
562 /* C is the code for a type-qualifier. Return the TYPE_QUAL
563 corresponding to this qualifier. */
566 code_for_qualifier (int c
)
571 return TYPE_QUAL_CONST
;
574 return TYPE_QUAL_VOLATILE
;
577 return TYPE_QUAL_RESTRICT
;
583 /* C was an invalid qualifier. */
587 /* Return the string corresponding to the qualifiers given by
591 qualifier_string (int type_quals
)
595 case TYPE_UNQUALIFIED
:
598 case TYPE_QUAL_CONST
:
601 case TYPE_QUAL_VOLATILE
:
604 case TYPE_QUAL_RESTRICT
:
607 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
608 return "const volatile";
610 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
611 return "const __restrict";
613 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
614 return "volatile __restrict";
616 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
617 return "const volatile __restrict";
623 /* TYPE_QUALS was an invalid qualifier set. */
627 /* C is the code for a type-qualifier. Return the string
628 corresponding to this qualifier. This function should only be
629 called with a valid qualifier code. */
632 demangle_qualifier (int c
)
634 return qualifier_string (code_for_qualifier (c
));
638 cplus_demangle_opname (const char *opname
, char *result
, int options
)
642 struct work_stuff work
[1];
645 len
= strlen(opname
);
648 memset ((char *) work
, 0, sizeof (work
));
649 work
->options
= options
;
651 if (opname
[0] == '_' && opname
[1] == '_'
652 && opname
[2] == 'o' && opname
[3] == 'p')
655 /* type conversion operator. */
657 if (do_type (work
, &tem
, &type
))
659 strcat (result
, "operator ");
660 strncat (result
, type
.b
, type
.p
- type
.b
);
661 string_delete (&type
);
665 else if (opname
[0] == '_' && opname
[1] == '_'
666 && ISLOWER((unsigned char)opname
[2])
667 && ISLOWER((unsigned char)opname
[3]))
669 if (opname
[4] == '\0')
673 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
675 if (strlen (optable
[i
].in
) == 2
676 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
678 strcat (result
, "operator");
679 strcat (result
, optable
[i
].out
);
687 if (opname
[2] == 'a' && opname
[5] == '\0')
691 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
693 if (strlen (optable
[i
].in
) == 3
694 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
696 strcat (result
, "operator");
697 strcat (result
, optable
[i
].out
);
708 && strchr (cplus_markers
, opname
[2]) != NULL
)
710 /* see if it's an assignment expression */
711 if (len
>= 10 /* op$assign_ */
712 && memcmp (opname
+ 3, "assign_", 7) == 0)
715 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
718 if ((int) strlen (optable
[i
].in
) == len1
719 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
721 strcat (result
, "operator");
722 strcat (result
, optable
[i
].out
);
723 strcat (result
, "=");
732 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
735 if ((int) strlen (optable
[i
].in
) == len1
736 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
738 strcat (result
, "operator");
739 strcat (result
, optable
[i
].out
);
746 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
747 && strchr (cplus_markers
, opname
[4]) != NULL
)
749 /* type conversion operator */
751 if (do_type (work
, &tem
, &type
))
753 strcat (result
, "operator ");
754 strncat (result
, type
.b
, type
.p
- type
.b
);
755 string_delete (&type
);
759 squangle_mop_up (work
);
764 /* Takes operator name as e.g. "++" and returns mangled
765 operator name (e.g. "postincrement_expr"), or NULL if not found.
767 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
768 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
771 cplus_mangle_opname (const char *opname
, int options
)
776 len
= strlen (opname
);
777 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
779 if ((int) strlen (optable
[i
].out
) == len
780 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
781 && memcmp (optable
[i
].out
, opname
, len
) == 0)
782 return optable
[i
].in
;
787 /* Add a routine to set the demangling style to be sure it is valid and
788 allow for any demangler initialization that maybe necessary. */
790 enum demangling_styles
791 cplus_demangle_set_style (enum demangling_styles style
)
793 const struct demangler_engine
*demangler
= libiberty_demanglers
;
795 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
796 if (style
== demangler
->demangling_style
)
798 current_demangling_style
= style
;
799 return current_demangling_style
;
802 return unknown_demangling
;
805 /* Do string name to style translation */
807 enum demangling_styles
808 cplus_demangle_name_to_style (const char *name
)
810 const struct demangler_engine
*demangler
= libiberty_demanglers
;
812 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
813 if (strcmp (name
, demangler
->demangling_style_name
) == 0)
814 return demangler
->demangling_style
;
816 return unknown_demangling
;
819 /* char *cplus_demangle (const char *mangled, int options)
821 If MANGLED is a mangled function name produced by GNU C++, then
822 a pointer to a @code{malloc}ed string giving a C++ representation
823 of the name will be returned; otherwise NULL will be returned.
824 It is the caller's responsibility to free the string which
827 The OPTIONS arg may contain one or more of the following bits:
829 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
831 DMGL_PARAMS Function parameters are included.
835 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
836 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
837 cplus_demangle ("foo__1Ai", 0) => "A::foo"
839 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
840 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
841 cplus_demangle ("foo__1Afe", 0) => "A::foo"
843 Note that any leading underscores, or other such characters prepended by
844 the compilation system, are presumed to have already been stripped from
848 cplus_demangle (const char *mangled
, int options
)
851 struct work_stuff work
[1];
853 if (current_demangling_style
== no_demangling
)
854 return xstrdup (mangled
);
856 memset ((char *) work
, 0, sizeof (work
));
857 work
->options
= options
;
858 if ((work
->options
& DMGL_STYLE_MASK
) == 0)
859 work
->options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
861 /* The V3 ABI demangling is implemented elsewhere. */
862 if (GNU_V3_DEMANGLING
|| AUTO_DEMANGLING
)
864 ret
= cplus_demangle_v3 (mangled
, work
->options
);
865 if (ret
|| GNU_V3_DEMANGLING
)
871 ret
= java_demangle_v3 (mangled
);
877 return ada_demangle (mangled
, options
);
879 if (DLANG_DEMANGLING
)
881 ret
= dlang_demangle (mangled
, options
);
886 ret
= internal_cplus_demangle (work
, mangled
);
887 squangle_mop_up (work
);
891 /* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
894 ada_demangle (const char *mangled
, int option ATTRIBUTE_UNUSED
)
901 /* Discard leading _ada_, which is used for library level subprograms. */
902 if (strncmp (mangled
, "_ada_", 5) == 0)
905 /* All ada unit names are lower-case. */
906 if (!ISLOWER (mangled
[0]))
909 /* Most of the demangling will trivially remove chars. Operator names
910 may add one char but because they are always preceeded by '__' which is
911 replaced by '.', they eventually never expand the size.
912 A few special names such as '___elabs' add a few chars (at most 7), but
913 they occur only once. */
914 len0
= strlen (mangled
) + 7 + 1;
915 demangled
= XNEWVEC (char, len0
);
921 /* An entity names is expected. */
924 /* An identifier, which is always lower case. */
927 while (ISLOWER(*p
) || ISDIGIT (*p
)
928 || (p
[0] == '_' && (ISLOWER (p
[1]) || ISDIGIT (p
[1]))));
930 else if (p
[0] == 'O')
932 /* An operator name. */
933 static const char * const operators
[][2] =
934 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
935 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
936 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
937 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
938 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
939 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
940 {"Oexpon", "**"}, {NULL
, NULL
}};
943 for (k
= 0; operators
[k
][0] != NULL
; k
++)
945 size_t slen
= strlen (operators
[k
][0]);
946 if (strncmp (p
, operators
[k
][0], slen
) == 0)
949 slen
= strlen (operators
[k
][1]);
951 memcpy (d
, operators
[k
][1], slen
);
957 /* Operator not found. */
958 if (operators
[k
][0] == NULL
)
963 /* Not a GNAT encoding. */
967 /* The name can be directly followed by some uppercase letters. */
968 if (p
[0] == 'T' && p
[1] == 'K')
971 if (p
[2] == 'B' && p
[3] == 0)
973 /* Subprogram for task body. */
976 else if (p
[2] == '_' && p
[3] == '_')
978 /* Inner declarations in a task. */
986 if (p
[0] == 'E' && p
[1] == 0)
988 /* Exception name. */
991 if ((p
[0] == 'P' || p
[0] == 'N') && p
[1] == 0)
993 /* Protected type subprogram. */
996 if ((*p
== 'N' || *p
== 'S') && p
[1] == 0)
998 /* Enumerated type name table. */
1005 while (p
[0] == 'n' || p
[0] == 'b')
1008 if (p
[0] == 'S' && p
[1] != 0 && (p
[2] == '_' || p
[2] == 0))
1010 /* Stream operations. */
1033 else if (p
[0] == 'D')
1035 /* Controlled type operation. */
1058 /* Standard separator. Handled first. */
1063 /* Overloading number. */
1066 while (ISDIGIT (*p
) || (p
[0] == '_' && ISDIGIT (p
[1])));
1070 while (p
[0] == 'n' || p
[0] == 'b')
1074 else if (p
[0] == '_' && p
[1] != '_')
1076 /* Special names. */
1077 static const char * const special
[][2] = {
1078 { "_elabb", "'Elab_Body" },
1079 { "_elabs", "'Elab_Spec" },
1080 { "_size", "'Size" },
1081 { "_alignment", "'Alignment" },
1082 { "_assign", ".\":=\"" },
1087 for (k
= 0; special
[k
][0] != NULL
; k
++)
1089 size_t slen
= strlen (special
[k
][0]);
1090 if (strncmp (p
, special
[k
][0], slen
) == 0)
1093 slen
= strlen (special
[k
][1]);
1094 memcpy (d
, special
[k
][1], slen
);
1099 if (special
[k
][0] != NULL
)
1110 else if (p
[1] == 'B' || p
[1] == 'E')
1112 /* Entry Body or barrier Evaluation. */
1114 while (ISDIGIT (*p
))
1116 if (p
[0] == 's' && p
[1] == 0)
1125 if (p
[0] == '.' && ISDIGIT (p
[1]))
1127 /* Nested subprogram. */
1129 while (ISDIGIT (*p
))
1134 /* End of mangled name. */
1144 len0
= strlen (mangled
);
1145 demangled
= XNEWVEC (char, len0
+ 3);
1147 if (mangled
[0] == '<')
1148 strcpy (demangled
, mangled
);
1150 sprintf (demangled
, "<%s>", mangled
);
1155 /* This function performs most of what cplus_demangle use to do, but
1156 to be able to demangle a name with a B, K or n code, we need to
1157 have a longer term memory of what types have been seen. The original
1158 now initializes and cleans up the squangle code info, while internal
1159 calls go directly to this routine to avoid resetting that info. */
1162 internal_cplus_demangle (struct work_stuff
*work
, const char *mangled
)
1167 char *demangled
= NULL
;
1169 s1
= work
->constructor
;
1170 s2
= work
->destructor
;
1171 s3
= work
->static_type
;
1172 s4
= work
->type_quals
;
1173 work
->constructor
= work
->destructor
= 0;
1174 work
->type_quals
= TYPE_UNQUALIFIED
;
1175 work
->dllimported
= 0;
1177 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
1179 string_init (&decl
);
1181 /* First check to see if gnu style demangling is active and if the
1182 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1183 recognize one of the gnu special forms rather than looking for a
1184 standard prefix. In particular, don't worry about whether there
1185 is a "__" string in the mangled string. Consider "_$_5__foo" for
1188 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
1190 success
= gnu_special (work
, &mangled
, &decl
);
1193 delete_work_stuff (work
);
1194 string_delete (&decl
);
1199 success
= demangle_prefix (work
, &mangled
, &decl
);
1201 if (success
&& (*mangled
!= '\0'))
1203 success
= demangle_signature (work
, &mangled
, &decl
);
1205 if (work
->constructor
== 2)
1207 string_prepend (&decl
, "global constructors keyed to ");
1208 work
->constructor
= 0;
1210 else if (work
->destructor
== 2)
1212 string_prepend (&decl
, "global destructors keyed to ");
1213 work
->destructor
= 0;
1215 else if (work
->dllimported
== 1)
1217 string_prepend (&decl
, "import stub for ");
1218 work
->dllimported
= 0;
1220 demangled
= mop_up (work
, &decl
, success
);
1222 work
->constructor
= s1
;
1223 work
->destructor
= s2
;
1224 work
->static_type
= s3
;
1225 work
->type_quals
= s4
;
1230 /* Clear out and squangling related storage */
1232 squangle_mop_up (struct work_stuff
*work
)
1234 /* clean up the B and K type mangling types. */
1235 forget_B_and_K_types (work
);
1236 if (work
-> btypevec
!= NULL
)
1238 free ((char *) work
-> btypevec
);
1239 work
->btypevec
= NULL
;
1242 if (work
-> ktypevec
!= NULL
)
1244 free ((char *) work
-> ktypevec
);
1245 work
->ktypevec
= NULL
;
1251 /* Copy the work state and storage. */
1254 work_stuff_copy_to_from (struct work_stuff
*to
, struct work_stuff
*from
)
1258 delete_work_stuff (to
);
1260 /* Shallow-copy scalars. */
1261 memcpy (to
, from
, sizeof (*to
));
1263 /* Deep-copy dynamic storage. */
1264 if (from
->typevec_size
)
1265 to
->typevec
= XNEWVEC (char *, from
->typevec_size
);
1267 for (i
= 0; i
< from
->ntypes
; i
++)
1269 int len
= strlen (from
->typevec
[i
]) + 1;
1271 to
->typevec
[i
] = XNEWVEC (char, len
);
1272 memcpy (to
->typevec
[i
], from
->typevec
[i
], len
);
1276 to
->ktypevec
= XNEWVEC (char *, from
->ksize
);
1278 for (i
= 0; i
< from
->numk
; i
++)
1280 int len
= strlen (from
->ktypevec
[i
]) + 1;
1282 to
->ktypevec
[i
] = XNEWVEC (char, len
);
1283 memcpy (to
->ktypevec
[i
], from
->ktypevec
[i
], len
);
1287 to
->btypevec
= XNEWVEC (char *, from
->bsize
);
1289 for (i
= 0; i
< from
->numb
; i
++)
1291 int len
= strlen (from
->btypevec
[i
]) + 1;
1293 to
->btypevec
[i
] = XNEWVEC (char , len
);
1294 memcpy (to
->btypevec
[i
], from
->btypevec
[i
], len
);
1297 if (from
->ntmpl_args
)
1298 to
->tmpl_argvec
= XNEWVEC (char *, from
->ntmpl_args
);
1300 for (i
= 0; i
< from
->ntmpl_args
; i
++)
1302 int len
= strlen (from
->tmpl_argvec
[i
]) + 1;
1304 to
->tmpl_argvec
[i
] = XNEWVEC (char, len
);
1305 memcpy (to
->tmpl_argvec
[i
], from
->tmpl_argvec
[i
], len
);
1308 if (from
->previous_argument
)
1310 to
->previous_argument
= XNEW (string
);
1311 string_init (to
->previous_argument
);
1312 string_appends (to
->previous_argument
, from
->previous_argument
);
1317 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1320 delete_non_B_K_work_stuff (struct work_stuff
*work
)
1322 /* Discard the remembered types, if any. */
1324 forget_types (work
);
1325 if (work
-> typevec
!= NULL
)
1327 free ((char *) work
-> typevec
);
1328 work
-> typevec
= NULL
;
1329 work
-> typevec_size
= 0;
1331 if (work
->tmpl_argvec
)
1335 for (i
= 0; i
< work
->ntmpl_args
; i
++)
1336 free ((char*) work
->tmpl_argvec
[i
]);
1338 free ((char*) work
->tmpl_argvec
);
1339 work
->tmpl_argvec
= NULL
;
1341 if (work
->previous_argument
)
1343 string_delete (work
->previous_argument
);
1344 free ((char*) work
->previous_argument
);
1345 work
->previous_argument
= NULL
;
1350 /* Delete all dynamic storage in work_stuff. */
1352 delete_work_stuff (struct work_stuff
*work
)
1354 delete_non_B_K_work_stuff (work
);
1355 squangle_mop_up (work
);
1359 /* Clear out any mangled storage */
1362 mop_up (struct work_stuff
*work
, string
*declp
, int success
)
1364 char *demangled
= NULL
;
1366 delete_non_B_K_work_stuff (work
);
1368 /* If demangling was successful, ensure that the demangled string is null
1369 terminated and return it. Otherwise, free the demangling decl. */
1373 string_delete (declp
);
1377 string_appendn (declp
, "", 1);
1378 demangled
= declp
->b
;
1387 demangle_signature -- demangle the signature part of a mangled name
1392 demangle_signature (struct work_stuff *work, const char **mangled,
1397 Consume and demangle the signature portion of the mangled name.
1399 DECLP is the string where demangled output is being built. At
1400 entry it contains the demangled root name from the mangled name
1401 prefix. I.E. either a demangled operator name or the root function
1402 name. In some special cases, it may contain nothing.
1404 *MANGLED points to the current unconsumed location in the mangled
1405 name. As tokens are consumed and demangling is performed, the
1406 pointer is updated to continuously point at the next token to
1409 Demangling GNU style mangled names is nasty because there is no
1410 explicit token that marks the start of the outermost function
1414 demangle_signature (struct work_stuff
*work
,
1415 const char **mangled
, string
*declp
)
1419 int expect_func
= 0;
1420 int expect_return_type
= 0;
1421 const char *oldmangled
= NULL
;
1425 while (success
&& (**mangled
!= '\0'))
1430 oldmangled
= *mangled
;
1431 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1433 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1434 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1440 oldmangled
= *mangled
;
1441 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1442 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1450 /* Static member function */
1451 if (oldmangled
== NULL
)
1453 oldmangled
= *mangled
;
1456 work
-> static_type
= 1;
1462 work
->type_quals
|= code_for_qualifier (**mangled
);
1464 /* a qualified member function */
1465 if (oldmangled
== NULL
)
1466 oldmangled
= *mangled
;
1471 /* Local class name follows after "Lnnn_" */
1474 while (**mangled
&& (**mangled
!= '_'))
1485 case '0': case '1': case '2': case '3': case '4':
1486 case '5': case '6': case '7': case '8': case '9':
1487 if (oldmangled
== NULL
)
1489 oldmangled
= *mangled
;
1491 work
->temp_start
= -1; /* uppermost call to demangle_class */
1492 success
= demangle_class (work
, mangled
, declp
);
1495 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1497 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1499 /* EDG and others will have the "F", so we let the loop cycle
1500 if we are looking at one. */
1501 if (**mangled
!= 'F')
1510 success
= do_type (work
, mangled
, &s
);
1513 string_append (&s
, SCOPE_STRING (work
));
1514 string_prepends (declp
, &s
);
1524 /* ARM/HP style demangling includes a specific 'F' character after
1525 the class name. For GNU style, it is just implied. So we can
1526 safely just consume any 'F' at this point and be compatible
1527 with either style. */
1533 /* For lucid/ARM/HP style we have to forget any types we might
1534 have remembered up to this point, since they were not argument
1535 types. GNU style considers all types seen as available for
1536 back references. See comment in demangle_args() */
1538 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1540 forget_types (work
);
1542 success
= demangle_args (work
, mangled
, declp
);
1543 /* After picking off the function args, we expect to either
1544 find the function return type (preceded by an '_') or the
1545 end of the string. */
1546 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1549 /* At this level, we do not care about the return type. */
1550 success
= do_type (work
, mangled
, &tname
);
1551 string_delete (&tname
);
1558 string_init(&trawname
);
1559 string_init(&tname
);
1560 if (oldmangled
== NULL
)
1562 oldmangled
= *mangled
;
1564 success
= demangle_template (work
, mangled
, &tname
,
1568 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1570 string_append (&tname
, SCOPE_STRING (work
));
1572 string_prepends(declp
, &tname
);
1573 if (work
-> destructor
& 1)
1575 string_prepend (&trawname
, "~");
1576 string_appends (declp
, &trawname
);
1577 work
->destructor
-= 1;
1579 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1581 string_appends (declp
, &trawname
);
1582 work
->constructor
-= 1;
1584 string_delete(&trawname
);
1585 string_delete(&tname
);
1591 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
) && expect_return_type
)
1593 /* Read the return type. */
1597 success
= do_type (work
, mangled
, &return_type
);
1598 APPEND_BLANK (&return_type
);
1600 string_prepends (declp
, &return_type
);
1601 string_delete (&return_type
);
1605 /* At the outermost level, we cannot have a return type specified,
1606 so if we run into another '_' at this point we are dealing with
1607 a mangled name that is either bogus, or has been mangled by
1608 some algorithm we don't know how to deal with. So just
1609 reject the entire demangling. */
1610 /* However, "_nnn" is an expected suffix for alternate entry point
1611 numbered nnn for a function, with HP aCC, so skip over that
1612 without reporting failure. pai/1997-09-04 */
1616 while (**mangled
&& ISDIGIT ((unsigned char)**mangled
))
1624 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1626 /* A G++ template function. Read the template arguments. */
1627 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1629 if (!(work
->constructor
& 1))
1630 expect_return_type
= 1;
1639 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1641 /* Assume we have stumbled onto the first outermost function
1642 argument token, and start processing args. */
1644 success
= demangle_args (work
, mangled
, declp
);
1648 /* Non-GNU demanglers use a specific token to mark the start
1649 of the outermost function argument tokens. Typically 'F',
1650 for ARM/HP-demangling, for example. So if we find something
1651 we are not prepared for, it must be an error. */
1657 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1660 if (success
&& expect_func
)
1663 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1665 forget_types (work
);
1667 success
= demangle_args (work
, mangled
, declp
);
1668 /* Since template include the mangling of their return types,
1669 we must set expect_func to 0 so that we don't try do
1670 demangle more arguments the next time we get here. */
1675 if (success
&& !func_done
)
1677 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1679 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1680 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1681 first case, and need to ensure that the '(void)' gets added to
1682 the current declp. Note that with ARM/HP, the first case
1683 represents the name of a static data member 'foo::bar',
1684 which is in the current declp, so we leave it alone. */
1685 success
= demangle_args (work
, mangled
, declp
);
1688 if (success
&& PRINT_ARG_TYPES
)
1690 if (work
->static_type
)
1691 string_append (declp
, " static");
1692 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1694 APPEND_BLANK (declp
);
1695 string_append (declp
, qualifier_string (work
->type_quals
));
1705 demangle_method_args (struct work_stuff
*work
, const char **mangled
,
1710 if (work
-> static_type
)
1712 string_append (declp
, *mangled
+ 1);
1713 *mangled
+= strlen (*mangled
);
1718 success
= demangle_args (work
, mangled
, declp
);
1726 demangle_template_template_parm (struct work_stuff
*work
,
1727 const char **mangled
, string
*tname
)
1735 string_append (tname
, "template <");
1736 /* get size of template parameter list */
1737 if (get_count (mangled
, &r
))
1739 for (i
= 0; i
< r
; i
++)
1743 string_append (tname
, ", ");
1746 /* Z for type parameters */
1747 if (**mangled
== 'Z')
1750 string_append (tname
, "class");
1752 /* z for template parameters */
1753 else if (**mangled
== 'z')
1757 demangle_template_template_parm (work
, mangled
, tname
);
1765 /* temp is initialized in do_type */
1766 success
= do_type (work
, mangled
, &temp
);
1769 string_appends (tname
, &temp
);
1771 string_delete(&temp
);
1781 if (tname
->p
[-1] == '>')
1782 string_append (tname
, " ");
1783 string_append (tname
, "> class");
1788 demangle_expression (struct work_stuff
*work
, const char **mangled
,
1789 string
*s
, type_kind_t tk
)
1791 int need_operator
= 0;
1795 string_appendn (s
, "(", 1);
1797 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1806 len
= strlen (*mangled
);
1808 for (i
= 0; i
< ARRAY_SIZE (optable
); ++i
)
1810 size_t l
= strlen (optable
[i
].in
);
1813 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1815 string_appendn (s
, " ", 1);
1816 string_append (s
, optable
[i
].out
);
1817 string_appendn (s
, " ", 1);
1830 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1833 if (**mangled
!= 'W')
1837 string_appendn (s
, ")", 1);
1845 demangle_integral_value (struct work_stuff
*work
,
1846 const char **mangled
, string
*s
)
1850 if (**mangled
== 'E')
1851 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1852 else if (**mangled
== 'Q' || **mangled
== 'K')
1853 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1858 /* By default, we let the number decide whether we shall consume an
1860 int multidigit_without_leading_underscore
= 0;
1861 int leave_following_underscore
= 0;
1865 if (**mangled
== '_')
1867 if (mangled
[0][1] == 'm')
1869 /* Since consume_count_with_underscores does not handle the
1870 `m'-prefix we must do it here, using consume_count and
1871 adjusting underscores: we have to consume the underscore
1872 matching the prepended one. */
1873 multidigit_without_leading_underscore
= 1;
1874 string_appendn (s
, "-", 1);
1879 /* Do not consume a following underscore;
1880 consume_count_with_underscores will consume what
1881 should be consumed. */
1882 leave_following_underscore
= 1;
1887 /* Negative numbers are indicated with a leading `m'. */
1888 if (**mangled
== 'm')
1890 string_appendn (s
, "-", 1);
1893 /* Since consume_count_with_underscores does not handle
1894 multi-digit numbers that do not start with an underscore,
1895 and this number can be an integer template parameter,
1896 we have to call consume_count. */
1897 multidigit_without_leading_underscore
= 1;
1898 /* These multi-digit numbers never end on an underscore,
1899 so if there is one then don't eat it. */
1900 leave_following_underscore
= 1;
1903 /* We must call consume_count if we expect to remove a trailing
1904 underscore, since consume_count_with_underscores expects
1905 the leading underscore (that we consumed) if it is to handle
1906 multi-digit numbers. */
1907 if (multidigit_without_leading_underscore
)
1908 value
= consume_count (mangled
);
1910 value
= consume_count_with_underscores (mangled
);
1914 char buf
[INTBUF_SIZE
];
1915 sprintf (buf
, "%d", value
);
1916 string_append (s
, buf
);
1918 /* Numbers not otherwise delimited, might have an underscore
1919 appended as a delimeter, which we should skip.
1921 ??? This used to always remove a following underscore, which
1922 is wrong. If other (arbitrary) cases are followed by an
1923 underscore, we need to do something more radical. */
1925 if ((value
> 9 || multidigit_without_leading_underscore
)
1926 && ! leave_following_underscore
1927 && **mangled
== '_')
1938 /* Demangle the real value in MANGLED. */
1941 demangle_real_value (struct work_stuff
*work
,
1942 const char **mangled
, string
*s
)
1944 if (**mangled
== 'E')
1945 return demangle_expression (work
, mangled
, s
, tk_real
);
1947 if (**mangled
== 'm')
1949 string_appendn (s
, "-", 1);
1952 while (ISDIGIT ((unsigned char)**mangled
))
1954 string_appendn (s
, *mangled
, 1);
1957 if (**mangled
== '.') /* fraction */
1959 string_appendn (s
, ".", 1);
1961 while (ISDIGIT ((unsigned char)**mangled
))
1963 string_appendn (s
, *mangled
, 1);
1967 if (**mangled
== 'e') /* exponent */
1969 string_appendn (s
, "e", 1);
1971 while (ISDIGIT ((unsigned char)**mangled
))
1973 string_appendn (s
, *mangled
, 1);
1982 demangle_template_value_parm (struct work_stuff
*work
, const char **mangled
,
1983 string
*s
, type_kind_t tk
)
1987 if (**mangled
== 'Y')
1989 /* The next argument is a template parameter. */
1993 idx
= consume_count_with_underscores (mangled
);
1995 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1996 || consume_count_with_underscores (mangled
) == -1)
1998 if (work
->tmpl_argvec
)
1999 string_append (s
, work
->tmpl_argvec
[idx
]);
2001 string_append_template_idx (s
, idx
);
2003 else if (tk
== tk_integral
)
2004 success
= demangle_integral_value (work
, mangled
, s
);
2005 else if (tk
== tk_char
)
2009 if (**mangled
== 'm')
2011 string_appendn (s
, "-", 1);
2014 string_appendn (s
, "'", 1);
2015 val
= consume_count(mangled
);
2022 string_appendn (s
, &tmp
[0], 1);
2023 string_appendn (s
, "'", 1);
2026 else if (tk
== tk_bool
)
2028 int val
= consume_count (mangled
);
2030 string_appendn (s
, "false", 5);
2032 string_appendn (s
, "true", 4);
2036 else if (tk
== tk_real
)
2037 success
= demangle_real_value (work
, mangled
, s
);
2038 else if (tk
== tk_pointer
|| tk
== tk_reference
)
2040 if (**mangled
== 'Q')
2041 success
= demangle_qualified (work
, mangled
, s
,
2046 int symbol_len
= consume_count (mangled
);
2047 if (symbol_len
== -1)
2049 if (symbol_len
== 0)
2050 string_appendn (s
, "0", 1);
2053 char *p
= XNEWVEC (char, symbol_len
+ 1), *q
;
2054 strncpy (p
, *mangled
, symbol_len
);
2055 p
[symbol_len
] = '\0';
2056 /* We use cplus_demangle here, rather than
2057 internal_cplus_demangle, because the name of the entity
2058 mangled here does not make use of any of the squangling
2059 or type-code information we have built up thus far; it is
2060 mangled independently. */
2061 q
= cplus_demangle (p
, work
->options
);
2062 if (tk
== tk_pointer
)
2063 string_appendn (s
, "&", 1);
2064 /* FIXME: Pointer-to-member constants should get a
2065 qualifying class name here. */
2068 string_append (s
, q
);
2072 string_append (s
, p
);
2075 *mangled
+= symbol_len
;
2082 /* Demangle the template name in MANGLED. The full name of the
2083 template (e.g., S<int>) is placed in TNAME. The name without the
2084 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2085 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2086 not a function template. If both IS_TYPE and REMEMBER are nonzero,
2087 the template is remembered in the list of back-referenceable
2091 demangle_template (struct work_stuff
*work
, const char **mangled
,
2092 string
*tname
, string
*trawname
,
2093 int is_type
, int remember
)
2099 int is_java_array
= 0;
2105 /* get template name */
2106 if (**mangled
== 'z')
2112 idx
= consume_count_with_underscores (mangled
);
2114 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2115 || consume_count_with_underscores (mangled
) == -1)
2118 if (work
->tmpl_argvec
)
2120 string_append (tname
, work
->tmpl_argvec
[idx
]);
2122 string_append (trawname
, work
->tmpl_argvec
[idx
]);
2126 string_append_template_idx (tname
, idx
);
2128 string_append_template_idx (trawname
, idx
);
2133 if ((r
= consume_count (mangled
)) <= 0
2134 || (int) strlen (*mangled
) < r
)
2138 is_java_array
= (work
-> options
& DMGL_JAVA
)
2139 && strncmp (*mangled
, "JArray1Z", 8) == 0;
2140 if (! is_java_array
)
2142 string_appendn (tname
, *mangled
, r
);
2145 string_appendn (trawname
, *mangled
, r
);
2150 string_append (tname
, "<");
2151 /* get size of template parameter list */
2152 if (!get_count (mangled
, &r
))
2158 /* Create an array for saving the template argument values. */
2159 work
->tmpl_argvec
= XNEWVEC (char *, r
);
2160 work
->ntmpl_args
= r
;
2161 for (i
= 0; i
< r
; i
++)
2162 work
->tmpl_argvec
[i
] = 0;
2164 for (i
= 0; i
< r
; i
++)
2168 string_append (tname
, ", ");
2170 /* Z for type parameters */
2171 if (**mangled
== 'Z')
2174 /* temp is initialized in do_type */
2175 success
= do_type (work
, mangled
, &temp
);
2178 string_appends (tname
, &temp
);
2182 /* Save the template argument. */
2183 int len
= temp
.p
- temp
.b
;
2184 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2185 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
2186 work
->tmpl_argvec
[i
][len
] = '\0';
2189 string_delete(&temp
);
2195 /* z for template parameters */
2196 else if (**mangled
== 'z')
2200 success
= demangle_template_template_parm (work
, mangled
, tname
);
2203 && (r2
= consume_count (mangled
)) > 0
2204 && (int) strlen (*mangled
) >= r2
)
2206 string_append (tname
, " ");
2207 string_appendn (tname
, *mangled
, r2
);
2210 /* Save the template argument. */
2212 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2213 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
2214 work
->tmpl_argvec
[i
][len
] = '\0';
2228 /* otherwise, value parameter */
2230 /* temp is initialized in do_type */
2231 success
= do_type (work
, mangled
, &temp
);
2232 string_delete(&temp
);
2244 success
= demangle_template_value_parm (work
, mangled
, s
,
2245 (type_kind_t
) success
);
2257 int len
= s
->p
- s
->b
;
2258 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2259 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
2260 work
->tmpl_argvec
[i
][len
] = '\0';
2262 string_appends (tname
, s
);
2270 string_append (tname
, "[]");
2274 if (tname
->p
[-1] == '>')
2275 string_append (tname
, " ");
2276 string_append (tname
, ">");
2279 if (is_type
&& remember
)
2281 const int bindex
= register_Btype (work
);
2282 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
2286 if (work -> static_type)
2288 string_append (declp, *mangled + 1);
2289 *mangled += strlen (*mangled);
2294 success = demangle_args (work, mangled, declp);
2302 arm_pt (struct work_stuff
*work
, const char *mangled
,
2303 int n
, const char **anchor
, const char **args
)
2305 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2306 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2307 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= strstr (mangled
, "__pt__")))
2310 *args
= *anchor
+ 6;
2311 len
= consume_count (args
);
2314 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2320 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
2322 if ((*anchor
= strstr (mangled
, "__tm__"))
2323 || (*anchor
= strstr (mangled
, "__ps__"))
2324 || (*anchor
= strstr (mangled
, "__pt__")))
2327 *args
= *anchor
+ 6;
2328 len
= consume_count (args
);
2331 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2337 else if ((*anchor
= strstr (mangled
, "__S")))
2340 *args
= *anchor
+ 3;
2341 len
= consume_count (args
);
2344 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2356 demangle_arm_hp_template (struct work_stuff
*work
, const char **mangled
,
2357 int n
, string
*declp
)
2361 const char *e
= *mangled
+ n
;
2364 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2366 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
2368 char *start_spec_args
= NULL
;
2371 /* First check for and omit template specialization pseudo-arguments,
2372 such as in "Spec<#1,#1.*>" */
2373 start_spec_args
= strchr (*mangled
, '<');
2374 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
2375 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
2377 string_appendn (declp
, *mangled
, n
);
2378 (*mangled
) += n
+ 1;
2380 if (work
->temp_start
== -1) /* non-recursive call */
2381 work
->temp_start
= declp
->p
- declp
->b
;
2383 /* We want to unconditionally demangle parameter types in
2384 template parameters. */
2385 hold_options
= work
->options
;
2386 work
->options
|= DMGL_PARAMS
;
2388 string_append (declp
, "<");
2391 string_delete (&arg
);
2395 /* 'T' signals a type parameter */
2397 if (!do_type (work
, mangled
, &arg
))
2398 goto hpacc_template_args_done
;
2403 /* 'U' or 'S' signals an integral value */
2404 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
2405 goto hpacc_template_args_done
;
2409 /* 'A' signals a named constant expression (literal) */
2410 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
2411 goto hpacc_template_args_done
;
2415 /* Today, 1997-09-03, we have only the above types
2416 of template parameters */
2417 /* FIXME: maybe this should fail and return null */
2418 goto hpacc_template_args_done
;
2420 string_appends (declp
, &arg
);
2421 /* Check if we're at the end of template args.
2422 0 if at end of static member of template class,
2423 _ if done with template args for a function */
2424 if ((**mangled
== '\000') || (**mangled
== '_'))
2427 string_append (declp
, ",");
2429 hpacc_template_args_done
:
2430 string_append (declp
, ">");
2431 string_delete (&arg
);
2432 if (**mangled
== '_')
2434 work
->options
= hold_options
;
2437 /* ARM template? (Also handles HP cfront extensions) */
2438 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
2444 string_appendn (declp
, *mangled
, p
- *mangled
);
2445 if (work
->temp_start
== -1) /* non-recursive call */
2446 work
->temp_start
= declp
->p
- declp
->b
;
2448 /* We want to unconditionally demangle parameter types in
2449 template parameters. */
2450 hold_options
= work
->options
;
2451 work
->options
|= DMGL_PARAMS
;
2453 string_append (declp
, "<");
2454 /* should do error checking here */
2456 string_delete (&arg
);
2458 /* Check for type or literal here */
2461 /* HP cfront extensions to ARM for template args */
2462 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2463 /* FIXME: We handle only numeric literals for HP cfront */
2465 /* A typed constant value follows */
2467 if (!do_type (work
, &args
, &type_str
))
2468 goto cfront_template_args_done
;
2469 string_append (&arg
, "(");
2470 string_appends (&arg
, &type_str
);
2471 string_delete (&type_str
);
2472 string_append (&arg
, ")");
2474 goto cfront_template_args_done
;
2476 /* Now snarf a literal value following 'L' */
2477 if (!snarf_numeric_literal (&args
, &arg
))
2478 goto cfront_template_args_done
;
2482 /* Snarf a literal following 'L' */
2484 if (!snarf_numeric_literal (&args
, &arg
))
2485 goto cfront_template_args_done
;
2488 /* Not handling other HP cfront stuff */
2490 const char* old_args
= args
;
2491 if (!do_type (work
, &args
, &arg
))
2492 goto cfront_template_args_done
;
2494 /* Fail if we didn't make any progress: prevent infinite loop. */
2495 if (args
== old_args
)
2497 work
->options
= hold_options
;
2502 string_appends (declp
, &arg
);
2503 string_append (declp
, ",");
2505 cfront_template_args_done
:
2506 string_delete (&arg
);
2508 --declp
->p
; /* remove extra comma */
2509 string_append (declp
, ">");
2510 work
->options
= hold_options
;
2512 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2513 && (*mangled
)[9] == 'N'
2514 && (*mangled
)[8] == (*mangled
)[10]
2515 && strchr (cplus_markers
, (*mangled
)[8]))
2517 /* A member of the anonymous namespace. */
2518 string_append (declp
, "{anonymous}");
2522 if (work
->temp_start
== -1) /* non-recursive call only */
2523 work
->temp_start
= 0; /* disable in recursive calls */
2524 string_appendn (declp
, *mangled
, n
);
2529 /* Extract a class name, possibly a template with arguments, from the
2530 mangled string; qualifiers, local class indicators, etc. have
2531 already been dealt with */
2534 demangle_class_name (struct work_stuff
*work
, const char **mangled
,
2540 n
= consume_count (mangled
);
2543 if ((int) strlen (*mangled
) >= n
)
2545 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2556 demangle_class -- demangle a mangled class sequence
2561 demangle_class (struct work_stuff *work, const char **mangled,
2566 DECLP points to the buffer into which demangling is being done.
2568 *MANGLED points to the current token to be demangled. On input,
2569 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2570 On exit, it points to the next token after the mangled class on
2571 success, or the first unconsumed token on failure.
2573 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2574 we are demangling a constructor or destructor. In this case
2575 we prepend "class::class" or "class::~class" to DECLP.
2577 Otherwise, we prepend "class::" to the current DECLP.
2579 Reset the constructor/destructor flags once they have been
2580 "consumed". This allows demangle_class to be called later during
2581 the same demangling, to do normal class demangling.
2583 Returns 1 if demangling is successful, 0 otherwise.
2588 demangle_class (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2593 char *save_class_name_end
= 0;
2595 string_init (&class_name
);
2596 btype
= register_Btype (work
);
2597 if (demangle_class_name (work
, mangled
, &class_name
))
2599 save_class_name_end
= class_name
.p
;
2600 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2602 /* adjust so we don't include template args */
2603 if (work
->temp_start
&& (work
->temp_start
!= -1))
2605 class_name
.p
= class_name
.b
+ work
->temp_start
;
2607 string_prepends (declp
, &class_name
);
2608 if (work
-> destructor
& 1)
2610 string_prepend (declp
, "~");
2611 work
-> destructor
-= 1;
2615 work
-> constructor
-= 1;
2618 class_name
.p
= save_class_name_end
;
2619 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2620 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2621 string_prepend (declp
, SCOPE_STRING (work
));
2622 string_prepends (declp
, &class_name
);
2625 string_delete (&class_name
);
2630 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2631 the rightmost guess.
2633 Find the correct "__"-sequence where the function name ends and the
2634 signature starts, which is ambiguous with GNU mangling.
2635 Call demangle_signature here, so we can make sure we found the right
2636 one; *mangled will be consumed so caller will not make further calls to
2637 demangle_signature. */
2640 iterate_demangle_function (struct work_stuff
*work
, const char **mangled
,
2641 string
*declp
, const char *scan
)
2643 const char *mangle_init
= *mangled
;
2646 struct work_stuff work_init
;
2648 if (*(scan
+ 2) == '\0')
2651 /* Do not iterate for some demangling modes, or if there's only one
2652 "__"-sequence. This is the normal case. */
2653 if (ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
2654 || strstr (scan
+ 2, "__") == NULL
)
2655 return demangle_function_name (work
, mangled
, declp
, scan
);
2657 /* Save state so we can restart if the guess at the correct "__" was
2659 string_init (&decl_init
);
2660 string_appends (&decl_init
, declp
);
2661 memset (&work_init
, 0, sizeof work_init
);
2662 work_stuff_copy_to_from (&work_init
, work
);
2664 /* Iterate over occurrences of __, allowing names and types to have a
2665 "__" sequence in them. We must start with the first (not the last)
2666 occurrence, since "__" most often occur between independent mangled
2667 parts, hence starting at the last occurence inside a signature
2668 might get us a "successful" demangling of the signature. */
2672 if (demangle_function_name (work
, mangled
, declp
, scan
))
2674 success
= demangle_signature (work
, mangled
, declp
);
2679 /* Reset demangle state for the next round. */
2680 *mangled
= mangle_init
;
2681 string_clear (declp
);
2682 string_appends (declp
, &decl_init
);
2683 work_stuff_copy_to_from (work
, &work_init
);
2685 /* Leave this underscore-sequence. */
2688 /* Scan for the next "__" sequence. */
2689 while (*scan
&& (scan
[0] != '_' || scan
[1] != '_'))
2692 /* Move to last "__" in this sequence. */
2693 while (*scan
&& *scan
== '_')
2698 /* Delete saved state. */
2699 delete_work_stuff (&work_init
);
2700 string_delete (&decl_init
);
2709 demangle_prefix -- consume the mangled name prefix and find signature
2714 demangle_prefix (struct work_stuff *work, const char **mangled,
2719 Consume and demangle the prefix of the mangled name.
2720 While processing the function name root, arrange to call
2721 demangle_signature if the root is ambiguous.
2723 DECLP points to the string buffer into which demangled output is
2724 placed. On entry, the buffer is empty. On exit it contains
2725 the root function name, the demangled operator name, or in some
2726 special cases either nothing or the completely demangled result.
2728 MANGLED points to the current pointer into the mangled name. As each
2729 token of the mangled name is consumed, it is updated. Upon entry
2730 the current mangled name pointer points to the first character of
2731 the mangled name. Upon exit, it should point to the first character
2732 of the signature if demangling was successful, or to the first
2733 unconsumed character if demangling of the prefix was unsuccessful.
2735 Returns 1 on success, 0 otherwise.
2739 demangle_prefix (struct work_stuff
*work
, const char **mangled
,
2746 if (strlen(*mangled
) > 6
2747 && (strncmp(*mangled
, "_imp__", 6) == 0
2748 || strncmp(*mangled
, "__imp_", 6) == 0))
2750 /* it's a symbol imported from a PE dynamic library. Check for both
2751 new style prefix _imp__ and legacy __imp_ used by older versions
2754 work
->dllimported
= 1;
2756 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2758 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2759 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2761 if ((*mangled
)[9] == 'D')
2763 /* it's a GNU global destructor to be executed at program exit */
2765 work
->destructor
= 2;
2766 if (gnu_special (work
, mangled
, declp
))
2769 else if ((*mangled
)[9] == 'I')
2771 /* it's a GNU global constructor to be executed at program init */
2773 work
->constructor
= 2;
2774 if (gnu_special (work
, mangled
, declp
))
2779 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2781 /* it's a ARM global destructor to be executed at program exit */
2783 work
->destructor
= 2;
2785 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2787 /* it's a ARM global constructor to be executed at program initial */
2789 work
->constructor
= 2;
2792 /* This block of code is a reduction in strength time optimization
2794 scan = strstr (*mangled, "__"); */
2800 scan
= strchr (scan
, '_');
2801 } while (scan
!= NULL
&& *++scan
!= '_');
2803 if (scan
!= NULL
) --scan
;
2808 /* We found a sequence of two or more '_', ensure that we start at
2809 the last pair in the sequence. */
2810 i
= strspn (scan
, "_");
2821 else if (work
-> static_type
)
2823 if (!ISDIGIT ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2828 else if ((scan
== *mangled
)
2829 && (ISDIGIT ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2830 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2832 /* The ARM says nothing about the mangling of local variables.
2833 But cfront mangles local variables by prepending __<nesting_level>
2834 to them. As an extension to ARM demangling we handle this case. */
2835 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2836 && ISDIGIT ((unsigned char)scan
[2]))
2838 *mangled
= scan
+ 2;
2839 consume_count (mangled
);
2840 string_append (declp
, *mangled
);
2841 *mangled
+= strlen (*mangled
);
2846 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2847 names like __Q2_3foo3bar for nested type names. So don't accept
2848 this style of constructor for cfront demangling. A GNU
2849 style member-template constructor starts with 'H'. */
2850 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2851 work
-> constructor
+= 1;
2852 *mangled
= scan
+ 2;
2855 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2857 /* Cfront-style parameterized type. Handled later as a signature. */
2861 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2863 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2864 || (scan
[2] == 'p' && scan
[3] == 's')
2865 || (scan
[2] == 'p' && scan
[3] == 't')))
2867 /* EDG-style parameterized type. Handled later as a signature. */
2871 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2873 else if ((scan
== *mangled
) && !ISDIGIT ((unsigned char)scan
[2])
2874 && (scan
[2] != 't'))
2876 /* Mangled name starts with "__". Skip over any leading '_' characters,
2877 then find the next "__" that separates the prefix from the signature.
2879 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2880 || (arm_special (mangled
, declp
) == 0))
2882 while (*scan
== '_')
2886 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2888 /* No separator (I.E. "__not_mangled"), or empty signature
2889 (I.E. "__not_mangled_either__") */
2893 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2896 else if (*(scan
+ 2) != '\0')
2898 /* Mangled name does not start with "__" but does have one somewhere
2899 in there with non empty stuff after it. Looks like a global
2900 function name. Iterate over all "__":s until the right
2902 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2906 /* Doesn't look like a mangled name */
2910 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2912 string_append (declp
, *mangled
);
2913 *mangled
+= strlen (*mangled
);
2923 gnu_special -- special handling of gnu mangled strings
2928 gnu_special (struct work_stuff *work, const char **mangled,
2934 Process some special GNU style mangling forms that don't fit
2935 the normal pattern. For example:
2937 _$_3foo (destructor for class foo)
2938 _vt$foo (foo virtual table)
2939 _vt$foo$bar (foo::bar virtual table)
2940 __vt_foo (foo virtual table, new style with thunks)
2941 _3foo$varname (static data member)
2942 _Q22rs2tu$vw (static data member)
2943 __t6vector1Zii (constructor with template)
2944 __thunk_4__$_7ostream (virtual function thunk)
2948 gnu_special (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2954 if ((*mangled
)[0] == '_'
2955 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2956 && (*mangled
)[2] == '_')
2958 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2960 work
-> destructor
+= 1;
2962 else if ((*mangled
)[0] == '_'
2963 && (((*mangled
)[1] == '_'
2964 && (*mangled
)[2] == 'v'
2965 && (*mangled
)[3] == 't'
2966 && (*mangled
)[4] == '_')
2967 || ((*mangled
)[1] == 'v'
2968 && (*mangled
)[2] == 't'
2969 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2971 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2972 and create the decl. Note that we consume the entire mangled
2973 input string, which means that demangle_signature has no work
2975 if ((*mangled
)[2] == 'v')
2976 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2978 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2979 while (**mangled
!= '\0')
2985 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2988 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2992 if (ISDIGIT((unsigned char)*mangled
[0]))
2994 n
= consume_count(mangled
);
2995 /* We may be seeing a too-large size, or else a
2996 ".<digits>" indicating a static local symbol. In
2997 any case, declare victory and move on; *don't* try
2998 to use n to allocate. */
2999 if (n
> (int) strlen (*mangled
))
3007 n
= strcspn (*mangled
, cplus_markers
);
3009 string_appendn (declp
, *mangled
, n
);
3013 p
= strpbrk (*mangled
, cplus_markers
);
3014 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
3018 string_append (declp
, SCOPE_STRING (work
));
3029 string_append (declp
, " virtual table");
3031 else if ((*mangled
)[0] == '_'
3032 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
3033 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
3035 /* static data member, "_3foo$varname" for example */
3041 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3044 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3047 n
= consume_count (mangled
);
3048 if (n
< 0 || n
> (long) strlen (*mangled
))
3054 if (n
> 10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
3055 && (*mangled
)[9] == 'N'
3056 && (*mangled
)[8] == (*mangled
)[10]
3057 && strchr (cplus_markers
, (*mangled
)[8]))
3059 /* A member of the anonymous namespace. There's information
3060 about what identifier or filename it was keyed to, but
3061 it's just there to make the mangled name unique; we just
3063 string_append (declp
, "{anonymous}");
3066 /* Now p points to the marker before the N, so we need to
3067 update it to the first marker after what we consumed. */
3068 p
= strpbrk (*mangled
, cplus_markers
);
3072 string_appendn (declp
, *mangled
, n
);
3075 if (success
&& (p
== *mangled
))
3077 /* Consumed everything up to the cplus_marker, append the
3080 string_append (declp
, SCOPE_STRING (work
));
3081 n
= strlen (*mangled
);
3082 string_appendn (declp
, *mangled
, n
);
3090 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
3095 delta
= consume_count (mangled
);
3100 char *method
= internal_cplus_demangle (work
, ++*mangled
);
3105 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
3106 string_append (declp
, buf
);
3107 string_append (declp
, method
);
3109 n
= strlen (*mangled
);
3118 else if (strncmp (*mangled
, "__t", 3) == 0
3119 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
3121 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
3127 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3130 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3133 success
= do_type (work
, mangled
, declp
);
3136 if (success
&& **mangled
!= '\0')
3139 string_append (declp
, p
);
3149 recursively_demangle(struct work_stuff
*work
, const char **mangled
,
3150 string
*result
, int namelength
)
3152 char * recurse
= (char *)NULL
;
3153 char * recurse_dem
= (char *)NULL
;
3155 recurse
= XNEWVEC (char, namelength
+ 1);
3156 memcpy (recurse
, *mangled
, namelength
);
3157 recurse
[namelength
] = '\000';
3159 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3163 string_append (result
, recurse_dem
);
3168 string_appendn (result
, *mangled
, namelength
);
3171 *mangled
+= namelength
;
3178 arm_special -- special handling of ARM/lucid mangled strings
3183 arm_special (const char **mangled,
3189 Process some special ARM style mangling forms that don't fit
3190 the normal pattern. For example:
3192 __vtbl__3foo (foo virtual table)
3193 __vtbl__3foo__3bar (bar::foo virtual table)
3198 arm_special (const char **mangled
, string
*declp
)
3204 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
3206 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3207 and create the decl. Note that we consume the entire mangled
3208 input string, which means that demangle_signature has no work
3210 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
3211 while (*scan
!= '\0') /* first check it can be demangled */
3213 n
= consume_count (&scan
);
3216 return (0); /* no good */
3219 if (scan
[0] == '_' && scan
[1] == '_')
3224 (*mangled
) += ARM_VTABLE_STRLEN
;
3225 while (**mangled
!= '\0')
3227 n
= consume_count (mangled
);
3229 || n
> (long) strlen (*mangled
))
3231 string_prependn (declp
, *mangled
, n
);
3233 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
3235 string_prepend (declp
, "::");
3239 string_append (declp
, " virtual table");
3252 demangle_qualified -- demangle 'Q' qualified name strings
3257 demangle_qualified (struct work_stuff *, const char *mangled,
3258 string *result, int isfuncname, int append);
3262 Demangle a qualified name, such as "Q25Outer5Inner" which is
3263 the mangled form of "Outer::Inner". The demangled output is
3264 prepended or appended to the result string according to the
3265 state of the append flag.
3267 If isfuncname is nonzero, then the qualified name we are building
3268 is going to be used as a member function name, so if it is a
3269 constructor or destructor function, append an appropriate
3270 constructor or destructor name. I.E. for the above example,
3271 the result for use as a constructor is "Outer::Inner::Inner"
3272 and the result for use as a destructor is "Outer::Inner::~Inner".
3276 Numeric conversion is ASCII dependent (FIXME).
3281 demangle_qualified (struct work_stuff
*work
, const char **mangled
,
3282 string
*result
, int isfuncname
, int append
)
3289 int bindex
= register_Btype (work
);
3291 /* We only make use of ISFUNCNAME if the entity is a constructor or
3293 isfuncname
= (isfuncname
3294 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
3296 string_init (&temp
);
3297 string_init (&last_name
);
3299 if ((*mangled
)[0] == 'K')
3301 /* Squangling qualified name reuse */
3304 idx
= consume_count_with_underscores (mangled
);
3305 if (idx
== -1 || idx
>= work
-> numk
)
3308 string_append (&temp
, work
-> ktypevec
[idx
]);
3311 switch ((*mangled
)[1])
3314 /* GNU mangled name with more than 9 classes. The count is preceded
3315 by an underscore (to distinguish it from the <= 9 case) and followed
3316 by an underscore. */
3318 qualifiers
= consume_count_with_underscores (mangled
);
3319 if (qualifiers
== -1)
3332 /* The count is in a single digit. */
3333 num
[0] = (*mangled
)[1];
3335 qualifiers
= atoi (num
);
3337 /* If there is an underscore after the digit, skip it. This is
3338 said to be for ARM-qualified names, but the ARM makes no
3339 mention of such an underscore. Perhaps cfront uses one. */
3340 if ((*mangled
)[2] == '_')
3355 /* Pick off the names and collect them in the temp buffer in the order
3356 in which they are found, separated by '::'. */
3358 while (qualifiers
-- > 0)
3361 string_clear (&last_name
);
3363 if (*mangled
[0] == '_')
3366 if (*mangled
[0] == 't')
3368 /* Here we always append to TEMP since we will want to use
3369 the template name without the template parameters as a
3370 constructor or destructor name. The appropriate
3371 (parameter-less) value is returned by demangle_template
3372 in LAST_NAME. We do not remember the template type here,
3373 in order to match the G++ mangling algorithm. */
3374 success
= demangle_template(work
, mangled
, &temp
,
3379 else if (*mangled
[0] == 'K')
3383 idx
= consume_count_with_underscores (mangled
);
3384 if (idx
== -1 || idx
>= work
->numk
)
3387 string_append (&temp
, work
->ktypevec
[idx
]);
3390 if (!success
) break;
3397 /* Now recursively demangle the qualifier
3398 * This is necessary to deal with templates in
3399 * mangling styles like EDG */
3400 namelength
= consume_count (mangled
);
3401 if (namelength
== -1)
3406 recursively_demangle(work
, mangled
, &temp
, namelength
);
3410 string_delete (&last_name
);
3411 success
= do_type (work
, mangled
, &last_name
);
3414 string_appends (&temp
, &last_name
);
3419 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
3422 string_append (&temp
, SCOPE_STRING (work
));
3425 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
3427 /* If we are using the result as a function name, we need to append
3428 the appropriate '::' separated constructor or destructor name.
3429 We do this here because this is the most convenient place, where
3430 we already have a pointer to the name and the length of the name. */
3434 string_append (&temp
, SCOPE_STRING (work
));
3435 if (work
-> destructor
& 1)
3436 string_append (&temp
, "~");
3437 string_appends (&temp
, &last_name
);
3440 /* Now either prepend the temp buffer to the result, or append it,
3441 depending upon the state of the append flag. */
3444 string_appends (result
, &temp
);
3447 if (!STRING_EMPTY (result
))
3448 string_append (&temp
, SCOPE_STRING (work
));
3449 string_prepends (result
, &temp
);
3452 string_delete (&last_name
);
3453 string_delete (&temp
);
3461 get_count -- convert an ascii count to integer, consuming tokens
3466 get_count (const char **type, int *count)
3470 Assume that *type points at a count in a mangled name; set
3471 *count to its value, and set *type to the next character after
3472 the count. There are some weird rules in effect here.
3474 If *type does not point at a string of digits, return zero.
3476 If *type points at a string of digits followed by an
3477 underscore, set *count to their value as an integer, advance
3478 *type to point *after the underscore, and return 1.
3480 If *type points at a string of digits not followed by an
3481 underscore, consume only the first digit. Set *count to its
3482 value as an integer, leave *type pointing after that digit,
3485 The excuse for this odd behavior: in the ARM and HP demangling
3486 styles, a type can be followed by a repeat count of the form
3489 `x' is a single digit specifying how many additional copies
3490 of the type to append to the argument list, and
3492 `y' is one or more digits, specifying the zero-based index of
3493 the first repeated argument in the list. Yes, as you're
3494 unmangling the name you can figure this out yourself, but
3497 So, for example, in `bar__3fooFPiN51', the first argument is a
3498 pointer to an integer (`Pi'), and then the next five arguments
3499 are the same (`N5'), and the first repeat is the function's
3500 second argument (`1').
3504 get_count (const char **type
, int *count
)
3509 if (!ISDIGIT ((unsigned char)**type
))
3513 *count
= **type
- '0';
3515 if (ISDIGIT ((unsigned char)**type
))
3525 while (ISDIGIT ((unsigned char)*p
));
3536 /* RESULT will be initialised here; it will be freed on failure. The
3537 value returned is really a type_kind_t. */
3540 do_type (struct work_stuff
*work
, const char **mangled
, string
*result
)
3546 const char *remembered_type
;
3548 type_kind_t tk
= tk_none
;
3550 string_init (&decl
);
3551 string_init (result
);
3555 while (success
&& !done
)
3561 /* A pointer type */
3565 if (! (work
-> options
& DMGL_JAVA
))
3566 string_prepend (&decl
, "*");
3571 /* A reference type */
3574 string_prepend (&decl
, "&");
3583 if (!STRING_EMPTY (&decl
)
3584 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3586 string_prepend (&decl
, "(");
3587 string_append (&decl
, ")");
3589 string_append (&decl
, "[");
3590 if (**mangled
!= '_')
3591 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3593 if (**mangled
== '_')
3595 string_append (&decl
, "]");
3599 /* A back reference to a previously seen type */
3602 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3608 remembered_type
= work
-> typevec
[n
];
3609 mangled
= &remembered_type
;
3616 if (!STRING_EMPTY (&decl
)
3617 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3619 string_prepend (&decl
, "(");
3620 string_append (&decl
, ")");
3622 /* After picking off the function args, we expect to either find the
3623 function return type (preceded by an '_') or the end of the
3625 if (!demangle_nested_args (work
, mangled
, &decl
)
3626 || (**mangled
!= '_' && **mangled
!= '\0'))
3631 if (success
&& (**mangled
== '_'))
3638 type_quals
= TYPE_UNQUALIFIED
;
3640 member
= **mangled
== 'M';
3643 string_append (&decl
, ")");
3645 /* We don't need to prepend `::' for a qualified name;
3646 demangle_qualified will do that for us. */
3647 if (**mangled
!= 'Q')
3648 string_prepend (&decl
, SCOPE_STRING (work
));
3650 if (ISDIGIT ((unsigned char)**mangled
))
3652 n
= consume_count (mangled
);
3654 || (int) strlen (*mangled
) < n
)
3659 string_prependn (&decl
, *mangled
, n
);
3662 else if (**mangled
== 'X' || **mangled
== 'Y')
3665 do_type (work
, mangled
, &temp
);
3666 string_prepends (&decl
, &temp
);
3667 string_delete (&temp
);
3669 else if (**mangled
== 't')
3672 string_init (&temp
);
3673 success
= demangle_template (work
, mangled
, &temp
,
3677 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3678 string_delete (&temp
);
3682 string_delete (&temp
);
3686 else if (**mangled
== 'Q')
3688 success
= demangle_qualified (work
, mangled
, &decl
,
3700 string_prepend (&decl
, "(");
3708 type_quals
|= code_for_qualifier (**mangled
);
3716 if (*(*mangled
)++ != 'F')
3722 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3723 || **mangled
!= '_')
3729 if (! PRINT_ANSI_QUALIFIERS
)
3733 if (type_quals
!= TYPE_UNQUALIFIED
)
3735 APPEND_BLANK (&decl
);
3736 string_append (&decl
, qualifier_string (type_quals
));
3747 if (PRINT_ANSI_QUALIFIERS
)
3749 if (!STRING_EMPTY (&decl
))
3750 string_prepend (&decl
, " ");
3752 string_prepend (&decl
, demangle_qualifier (**mangled
));
3767 if (success
) switch (**mangled
)
3769 /* A qualified name, such as "Outer::Inner". */
3773 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3777 /* A back reference to a previously seen squangled type */
3780 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3783 string_append (result
, work
->btypevec
[n
]);
3788 /* A template parm. We substitute the corresponding argument. */
3793 idx
= consume_count_with_underscores (mangled
);
3796 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3797 || consume_count_with_underscores (mangled
) == -1)
3803 if (work
->tmpl_argvec
)
3804 string_append (result
, work
->tmpl_argvec
[idx
]);
3806 string_append_template_idx (result
, idx
);
3813 success
= demangle_fund_type (work
, mangled
, result
);
3815 tk
= (type_kind_t
) success
;
3821 if (!STRING_EMPTY (&decl
))
3823 string_append (result
, " ");
3824 string_appends (result
, &decl
);
3828 string_delete (result
);
3829 string_delete (&decl
);
3832 /* Assume an integral type, if we're not sure. */
3833 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3838 /* Given a pointer to a type string that represents a fundamental type
3839 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3840 string in which the demangled output is being built in RESULT, and
3841 the WORK structure, decode the types and add them to the result.
3846 "Sl" => "signed long"
3847 "CUs" => "const unsigned short"
3849 The value returned is really a type_kind_t. */
3852 demangle_fund_type (struct work_stuff
*work
,
3853 const char **mangled
, string
*result
)
3857 char buf
[INTBUF_SIZE
+ 5 /* 'int%u_t' */];
3858 unsigned int dec
= 0;
3859 type_kind_t tk
= tk_integral
;
3861 /* First pick off any type qualifiers. There can be more than one. */
3870 if (PRINT_ANSI_QUALIFIERS
)
3872 if (!STRING_EMPTY (result
))
3873 string_prepend (result
, " ");
3874 string_prepend (result
, demangle_qualifier (**mangled
));
3880 APPEND_BLANK (result
);
3881 string_append (result
, "unsigned");
3883 case 'S': /* signed char only */
3885 APPEND_BLANK (result
);
3886 string_append (result
, "signed");
3890 APPEND_BLANK (result
);
3891 string_append (result
, "__complex");
3899 /* Now pick off the fundamental type. There can be only one. */
3908 APPEND_BLANK (result
);
3909 string_append (result
, "void");
3913 APPEND_BLANK (result
);
3914 string_append (result
, "long long");
3918 APPEND_BLANK (result
);
3919 string_append (result
, "long");
3923 APPEND_BLANK (result
);
3924 string_append (result
, "int");
3928 APPEND_BLANK (result
);
3929 string_append (result
, "short");
3933 APPEND_BLANK (result
);
3934 string_append (result
, "bool");
3939 APPEND_BLANK (result
);
3940 string_append (result
, "char");
3945 APPEND_BLANK (result
);
3946 string_append (result
, "wchar_t");
3951 APPEND_BLANK (result
);
3952 string_append (result
, "long double");
3957 APPEND_BLANK (result
);
3958 string_append (result
, "double");
3963 APPEND_BLANK (result
);
3964 string_append (result
, "float");
3969 if (!ISDIGIT ((unsigned char)**mangled
))
3976 if (**mangled
== '_')
3981 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3984 if (**mangled
!= '_')
3994 strncpy (buf
, *mangled
, 2);
3996 *mangled
+= min (strlen (*mangled
), 2);
3998 sscanf (buf
, "%x", &dec
);
3999 sprintf (buf
, "int%u_t", dec
);
4000 APPEND_BLANK (result
);
4001 string_append (result
, buf
);
4005 /* An explicit type, such as "6mytype" or "7integer" */
4017 int bindex
= register_Btype (work
);
4019 string_init (&btype
);
4020 if (demangle_class_name (work
, mangled
, &btype
)) {
4021 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
4022 APPEND_BLANK (result
);
4023 string_appends (result
, &btype
);
4027 string_delete (&btype
);
4033 string_init (&btype
);
4034 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
4035 string_appends (result
, &btype
);
4036 string_delete (&btype
);
4044 return success
? ((int) tk
) : 0;
4048 /* Handle a template's value parameter for HP aCC (extension from ARM)
4049 **mangled points to 'S' or 'U' */
4052 do_hpacc_template_const_value (struct work_stuff
*work ATTRIBUTE_UNUSED
,
4053 const char **mangled
, string
*result
)
4057 if (**mangled
!= 'U' && **mangled
!= 'S')
4060 unsigned_const
= (**mangled
== 'U');
4067 string_append (result
, "-");
4073 /* special case for -2^31 */
4074 string_append (result
, "-2147483648");
4081 /* We have to be looking at an integer now */
4082 if (!(ISDIGIT ((unsigned char)**mangled
)))
4085 /* We only deal with integral values for template
4086 parameters -- so it's OK to look only for digits */
4087 while (ISDIGIT ((unsigned char)**mangled
))
4089 char_str
[0] = **mangled
;
4090 string_append (result
, char_str
);
4095 string_append (result
, "U");
4097 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4098 with L or LL suffixes. pai/1997-09-03 */
4100 return 1; /* success */
4103 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4104 **mangled is pointing to the 'A' */
4107 do_hpacc_template_literal (struct work_stuff
*work
, const char **mangled
,
4110 int literal_len
= 0;
4114 if (**mangled
!= 'A')
4119 literal_len
= consume_count (mangled
);
4121 if (literal_len
<= 0)
4124 /* Literal parameters are names of arrays, functions, etc. and the
4125 canonical representation uses the address operator */
4126 string_append (result
, "&");
4128 /* Now recursively demangle the literal name */
4129 recurse
= XNEWVEC (char, literal_len
+ 1);
4130 memcpy (recurse
, *mangled
, literal_len
);
4131 recurse
[literal_len
] = '\000';
4133 recurse_dem
= cplus_demangle (recurse
, work
->options
);
4137 string_append (result
, recurse_dem
);
4142 string_appendn (result
, *mangled
, literal_len
);
4144 (*mangled
) += literal_len
;
4151 snarf_numeric_literal (const char **args
, string
*arg
)
4156 string_append (arg
, char_str
);
4159 else if (**args
== '+')
4162 if (!ISDIGIT ((unsigned char)**args
))
4165 while (ISDIGIT ((unsigned char)**args
))
4167 char_str
[0] = **args
;
4168 string_append (arg
, char_str
);
4175 /* Demangle the next argument, given by MANGLED into RESULT, which
4176 *should be an uninitialized* string. It will be initialized here,
4177 and free'd should anything go wrong. */
4180 do_arg (struct work_stuff
*work
, const char **mangled
, string
*result
)
4182 /* Remember where we started so that we can record the type, for
4183 non-squangling type remembering. */
4184 const char *start
= *mangled
;
4186 string_init (result
);
4188 if (work
->nrepeats
> 0)
4192 if (work
->previous_argument
== 0)
4195 /* We want to reissue the previous type in this argument list. */
4196 string_appends (result
, work
->previous_argument
);
4200 if (**mangled
== 'n')
4202 /* A squangling-style repeat. */
4204 work
->nrepeats
= consume_count(mangled
);
4206 if (work
->nrepeats
<= 0)
4207 /* This was not a repeat count after all. */
4210 if (work
->nrepeats
> 9)
4212 if (**mangled
!= '_')
4213 /* The repeat count should be followed by an '_' in this
4220 /* Now, the repeat is all set up. */
4221 return do_arg (work
, mangled
, result
);
4224 /* Save the result in WORK->previous_argument so that we can find it
4225 if it's repeated. Note that saving START is not good enough: we
4226 do not want to add additional types to the back-referenceable
4227 type vector when processing a repeated type. */
4228 if (work
->previous_argument
)
4229 string_delete (work
->previous_argument
);
4231 work
->previous_argument
= XNEW (string
);
4233 if (!do_type (work
, mangled
, work
->previous_argument
))
4236 string_appends (result
, work
->previous_argument
);
4238 remember_type (work
, start
, *mangled
- start
);
4243 remember_type (struct work_stuff
*work
, const char *start
, int len
)
4247 if (work
->forgetting_types
)
4250 if (work
-> ntypes
>= work
-> typevec_size
)
4252 if (work
-> typevec_size
== 0)
4254 work
-> typevec_size
= 3;
4255 work
-> typevec
= XNEWVEC (char *, work
->typevec_size
);
4259 work
-> typevec_size
*= 2;
4261 = XRESIZEVEC (char *, work
->typevec
, work
->typevec_size
);
4264 tem
= XNEWVEC (char, len
+ 1);
4265 memcpy (tem
, start
, len
);
4267 work
-> typevec
[work
-> ntypes
++] = tem
;
4271 /* Remember a K type class qualifier. */
4273 remember_Ktype (struct work_stuff
*work
, const char *start
, int len
)
4277 if (work
-> numk
>= work
-> ksize
)
4279 if (work
-> ksize
== 0)
4282 work
-> ktypevec
= XNEWVEC (char *, work
->ksize
);
4288 = XRESIZEVEC (char *, work
->ktypevec
, work
->ksize
);
4291 tem
= XNEWVEC (char, len
+ 1);
4292 memcpy (tem
, start
, len
);
4294 work
-> ktypevec
[work
-> numk
++] = tem
;
4297 /* Register a B code, and get an index for it. B codes are registered
4298 as they are seen, rather than as they are completed, so map<temp<char> >
4299 registers map<temp<char> > as B0, and temp<char> as B1 */
4302 register_Btype (struct work_stuff
*work
)
4306 if (work
-> numb
>= work
-> bsize
)
4308 if (work
-> bsize
== 0)
4311 work
-> btypevec
= XNEWVEC (char *, work
->bsize
);
4317 = XRESIZEVEC (char *, work
->btypevec
, work
->bsize
);
4320 ret
= work
-> numb
++;
4321 work
-> btypevec
[ret
] = NULL
;
4325 /* Store a value into a previously registered B code type. */
4328 remember_Btype (struct work_stuff
*work
, const char *start
,
4333 tem
= XNEWVEC (char, len
+ 1);
4334 memcpy (tem
, start
, len
);
4336 work
-> btypevec
[index
] = tem
;
4339 /* Lose all the info related to B and K type codes. */
4341 forget_B_and_K_types (struct work_stuff
*work
)
4345 while (work
-> numk
> 0)
4347 i
= --(work
-> numk
);
4348 if (work
-> ktypevec
[i
] != NULL
)
4350 free (work
-> ktypevec
[i
]);
4351 work
-> ktypevec
[i
] = NULL
;
4355 while (work
-> numb
> 0)
4357 i
= --(work
-> numb
);
4358 if (work
-> btypevec
[i
] != NULL
)
4360 free (work
-> btypevec
[i
]);
4361 work
-> btypevec
[i
] = NULL
;
4365 /* Forget the remembered types, but not the type vector itself. */
4368 forget_types (struct work_stuff
*work
)
4372 while (work
-> ntypes
> 0)
4374 i
= --(work
-> ntypes
);
4375 if (work
-> typevec
[i
] != NULL
)
4377 free (work
-> typevec
[i
]);
4378 work
-> typevec
[i
] = NULL
;
4383 /* Process the argument list part of the signature, after any class spec
4384 has been consumed, as well as the first 'F' character (if any). For
4387 "__als__3fooRT0" => process "RT0"
4388 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4390 DECLP must be already initialised, usually non-empty. It won't be freed
4393 Note that g++ differs significantly from ARM and lucid style mangling
4394 with regards to references to previously seen types. For example, given
4395 the source fragment:
4399 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4402 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4403 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4405 g++ produces the names:
4410 while lcc (and presumably other ARM style compilers as well) produces:
4412 foo__FiR3fooT1T2T1T2
4413 __ct__3fooFiR3fooT1T2T1T2
4415 Note that g++ bases its type numbers starting at zero and counts all
4416 previously seen types, while lucid/ARM bases its type numbers starting
4417 at one and only considers types after it has seen the 'F' character
4418 indicating the start of the function args. For lucid/ARM style, we
4419 account for this difference by discarding any previously seen types when
4420 we see the 'F' character, and subtracting one from the type number
4426 demangle_args (struct work_stuff
*work
, const char **mangled
,
4436 if (PRINT_ARG_TYPES
)
4438 string_append (declp
, "(");
4439 if (**mangled
== '\0')
4441 string_append (declp
, "void");
4445 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
4446 || work
->nrepeats
> 0)
4448 if ((**mangled
== 'N') || (**mangled
== 'T'))
4450 temptype
= *(*mangled
)++;
4452 if (temptype
== 'N')
4454 if (!get_count (mangled
, &r
))
4463 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
4465 /* If we have 10 or more types we might have more than a 1 digit
4466 index so we'll have to consume the whole count here. This
4467 will lose if the next thing is a type name preceded by a
4468 count but it's impossible to demangle that case properly
4469 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4470 Pc, ...)" or "(..., type12, char *, ...)" */
4471 if ((t
= consume_count(mangled
)) <= 0)
4478 if (!get_count (mangled
, &t
))
4483 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4487 /* Validate the type index. Protect against illegal indices from
4488 malformed type strings. */
4489 if ((t
< 0) || (t
>= work
-> ntypes
))
4493 while (work
->nrepeats
> 0 || --r
>= 0)
4495 tem
= work
-> typevec
[t
];
4496 if (need_comma
&& PRINT_ARG_TYPES
)
4498 string_append (declp
, ", ");
4500 if (!do_arg (work
, &tem
, &arg
))
4504 if (PRINT_ARG_TYPES
)
4506 string_appends (declp
, &arg
);
4508 string_delete (&arg
);
4514 if (need_comma
&& PRINT_ARG_TYPES
)
4515 string_append (declp
, ", ");
4516 if (!do_arg (work
, mangled
, &arg
))
4518 if (PRINT_ARG_TYPES
)
4519 string_appends (declp
, &arg
);
4520 string_delete (&arg
);
4525 if (**mangled
== 'e')
4528 if (PRINT_ARG_TYPES
)
4532 string_append (declp
, ",");
4534 string_append (declp
, "...");
4538 if (PRINT_ARG_TYPES
)
4540 string_append (declp
, ")");
4545 /* Like demangle_args, but for demangling the argument lists of function
4546 and method pointers or references, not top-level declarations. */
4549 demangle_nested_args (struct work_stuff
*work
, const char **mangled
,
4552 string
* saved_previous_argument
;
4556 /* The G++ name-mangling algorithm does not remember types on nested
4557 argument lists, unless -fsquangling is used, and in that case the
4558 type vector updated by remember_type is not used. So, we turn
4559 off remembering of types here. */
4560 ++work
->forgetting_types
;
4562 /* For the repeat codes used with -fsquangling, we must keep track of
4563 the last argument. */
4564 saved_previous_argument
= work
->previous_argument
;
4565 saved_nrepeats
= work
->nrepeats
;
4566 work
->previous_argument
= 0;
4569 /* Actually demangle the arguments. */
4570 result
= demangle_args (work
, mangled
, declp
);
4572 /* Restore the previous_argument field. */
4573 if (work
->previous_argument
)
4575 string_delete (work
->previous_argument
);
4576 free ((char *) work
->previous_argument
);
4578 work
->previous_argument
= saved_previous_argument
;
4579 --work
->forgetting_types
;
4580 work
->nrepeats
= saved_nrepeats
;
4585 /* Returns 1 if a valid function name was found or 0 otherwise. */
4588 demangle_function_name (struct work_stuff
*work
, const char **mangled
,
4589 string
*declp
, const char *scan
)
4595 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4596 string_need (declp
, 1);
4597 *(declp
-> p
) = '\0';
4599 /* Consume the function name, including the "__" separating the name
4600 from the signature. We are guaranteed that SCAN points to the
4603 (*mangled
) = scan
+ 2;
4604 /* We may be looking at an instantiation of a template function:
4605 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4606 following _F marks the start of the function arguments. Handle
4607 the template arguments first. */
4609 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4611 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4612 /* This leaves MANGLED pointing to the 'F' marking func args */
4615 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4618 /* See if we have an ARM style constructor or destructor operator.
4619 If so, then just record it, clear the decl, and return.
4620 We can't build the actual constructor/destructor decl until later,
4621 when we recover the class name from the signature. */
4623 if (strcmp (declp
-> b
, "__ct") == 0)
4625 work
-> constructor
+= 1;
4626 string_clear (declp
);
4629 else if (strcmp (declp
-> b
, "__dt") == 0)
4631 work
-> destructor
+= 1;
4632 string_clear (declp
);
4637 if (declp
->p
- declp
->b
>= 3
4638 && declp
->b
[0] == 'o'
4639 && declp
->b
[1] == 'p'
4640 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4642 /* see if it's an assignment expression */
4643 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4644 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4646 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4648 int len
= declp
->p
- declp
->b
- 10;
4649 if ((int) strlen (optable
[i
].in
) == len
4650 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4652 string_clear (declp
);
4653 string_append (declp
, "operator");
4654 string_append (declp
, optable
[i
].out
);
4655 string_append (declp
, "=");
4662 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4664 int len
= declp
->p
- declp
->b
- 3;
4665 if ((int) strlen (optable
[i
].in
) == len
4666 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4668 string_clear (declp
);
4669 string_append (declp
, "operator");
4670 string_append (declp
, optable
[i
].out
);
4676 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4677 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4679 /* type conversion operator */
4681 if (do_type (work
, &tem
, &type
))
4683 string_clear (declp
);
4684 string_append (declp
, "operator ");
4685 string_appends (declp
, &type
);
4686 string_delete (&type
);
4689 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4690 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4693 /* type conversion operator. */
4695 if (do_type (work
, &tem
, &type
))
4697 string_clear (declp
);
4698 string_append (declp
, "operator ");
4699 string_appends (declp
, &type
);
4700 string_delete (&type
);
4703 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4704 && ISLOWER((unsigned char)declp
->b
[2])
4705 && ISLOWER((unsigned char)declp
->b
[3]))
4707 if (declp
->b
[4] == '\0')
4710 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4712 if (strlen (optable
[i
].in
) == 2
4713 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4715 string_clear (declp
);
4716 string_append (declp
, "operator");
4717 string_append (declp
, optable
[i
].out
);
4724 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4727 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4729 if (strlen (optable
[i
].in
) == 3
4730 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4732 string_clear (declp
);
4733 string_append (declp
, "operator");
4734 string_append (declp
, optable
[i
].out
);
4742 /* If a function name was obtained but it's not valid, we were not
4744 if (LEN_STRING (declp
) == 1 && declp
->b
[0] == '.')
4750 /* a mini string-handling package */
4753 string_need (string
*s
, int n
)
4763 s
->p
= s
->b
= XNEWVEC (char, n
);
4766 else if (s
->e
- s
->p
< n
)
4771 s
->b
= XRESIZEVEC (char, s
->b
, n
);
4778 string_delete (string
*s
)
4783 s
->b
= s
->e
= s
->p
= NULL
;
4788 string_init (string
*s
)
4790 s
->b
= s
->p
= s
->e
= NULL
;
4794 string_clear (string
*s
)
4802 string_empty (string
*s
)
4804 return (s
->b
== s
->p
);
4810 string_append (string
*p
, const char *s
)
4813 if (s
== NULL
|| *s
== '\0')
4817 memcpy (p
->p
, s
, n
);
4822 string_appends (string
*p
, string
*s
)
4830 memcpy (p
->p
, s
->b
, n
);
4836 string_appendn (string
*p
, const char *s
, int n
)
4841 memcpy (p
->p
, s
, n
);
4847 string_prepend (string
*p
, const char *s
)
4849 if (s
!= NULL
&& *s
!= '\0')
4851 string_prependn (p
, s
, strlen (s
));
4856 string_prepends (string
*p
, string
*s
)
4860 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4865 string_prependn (string
*p
, const char *s
, int n
)
4872 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4876 memcpy (p
->b
, s
, n
);
4882 string_append_template_idx (string
*s
, int idx
)
4884 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4885 sprintf(buf
, "T%d", idx
);
4886 string_append (s
, buf
);