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
;
1241 if (work
-> ktypevec
!= NULL
)
1243 free ((char *) work
-> ktypevec
);
1244 work
->ktypevec
= NULL
;
1249 /* Copy the work state and storage. */
1252 work_stuff_copy_to_from (struct work_stuff
*to
, struct work_stuff
*from
)
1256 delete_work_stuff (to
);
1258 /* Shallow-copy scalars. */
1259 memcpy (to
, from
, sizeof (*to
));
1261 /* Deep-copy dynamic storage. */
1262 if (from
->typevec_size
)
1263 to
->typevec
= XNEWVEC (char *, from
->typevec_size
);
1265 for (i
= 0; i
< from
->ntypes
; i
++)
1267 int len
= strlen (from
->typevec
[i
]) + 1;
1269 to
->typevec
[i
] = XNEWVEC (char, len
);
1270 memcpy (to
->typevec
[i
], from
->typevec
[i
], len
);
1274 to
->ktypevec
= XNEWVEC (char *, from
->ksize
);
1276 for (i
= 0; i
< from
->numk
; i
++)
1278 int len
= strlen (from
->ktypevec
[i
]) + 1;
1280 to
->ktypevec
[i
] = XNEWVEC (char, len
);
1281 memcpy (to
->ktypevec
[i
], from
->ktypevec
[i
], len
);
1285 to
->btypevec
= XNEWVEC (char *, from
->bsize
);
1287 for (i
= 0; i
< from
->numb
; i
++)
1289 int len
= strlen (from
->btypevec
[i
]) + 1;
1291 to
->btypevec
[i
] = XNEWVEC (char , len
);
1292 memcpy (to
->btypevec
[i
], from
->btypevec
[i
], len
);
1295 if (from
->ntmpl_args
)
1296 to
->tmpl_argvec
= XNEWVEC (char *, from
->ntmpl_args
);
1298 for (i
= 0; i
< from
->ntmpl_args
; i
++)
1300 int len
= strlen (from
->tmpl_argvec
[i
]) + 1;
1302 to
->tmpl_argvec
[i
] = XNEWVEC (char, len
);
1303 memcpy (to
->tmpl_argvec
[i
], from
->tmpl_argvec
[i
], len
);
1306 if (from
->previous_argument
)
1308 to
->previous_argument
= XNEW (string
);
1309 string_init (to
->previous_argument
);
1310 string_appends (to
->previous_argument
, from
->previous_argument
);
1315 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1318 delete_non_B_K_work_stuff (struct work_stuff
*work
)
1320 /* Discard the remembered types, if any. */
1322 forget_types (work
);
1323 if (work
-> typevec
!= NULL
)
1325 free ((char *) work
-> typevec
);
1326 work
-> typevec
= NULL
;
1327 work
-> typevec_size
= 0;
1329 if (work
->tmpl_argvec
)
1333 for (i
= 0; i
< work
->ntmpl_args
; i
++)
1334 free ((char*) work
->tmpl_argvec
[i
]);
1336 free ((char*) work
->tmpl_argvec
);
1337 work
->tmpl_argvec
= NULL
;
1339 if (work
->previous_argument
)
1341 string_delete (work
->previous_argument
);
1342 free ((char*) work
->previous_argument
);
1343 work
->previous_argument
= NULL
;
1348 /* Delete all dynamic storage in work_stuff. */
1350 delete_work_stuff (struct work_stuff
*work
)
1352 delete_non_B_K_work_stuff (work
);
1353 squangle_mop_up (work
);
1357 /* Clear out any mangled storage */
1360 mop_up (struct work_stuff
*work
, string
*declp
, int success
)
1362 char *demangled
= NULL
;
1364 delete_non_B_K_work_stuff (work
);
1366 /* If demangling was successful, ensure that the demangled string is null
1367 terminated and return it. Otherwise, free the demangling decl. */
1371 string_delete (declp
);
1375 string_appendn (declp
, "", 1);
1376 demangled
= declp
->b
;
1385 demangle_signature -- demangle the signature part of a mangled name
1390 demangle_signature (struct work_stuff *work, const char **mangled,
1395 Consume and demangle the signature portion of the mangled name.
1397 DECLP is the string where demangled output is being built. At
1398 entry it contains the demangled root name from the mangled name
1399 prefix. I.E. either a demangled operator name or the root function
1400 name. In some special cases, it may contain nothing.
1402 *MANGLED points to the current unconsumed location in the mangled
1403 name. As tokens are consumed and demangling is performed, the
1404 pointer is updated to continuously point at the next token to
1407 Demangling GNU style mangled names is nasty because there is no
1408 explicit token that marks the start of the outermost function
1412 demangle_signature (struct work_stuff
*work
,
1413 const char **mangled
, string
*declp
)
1417 int expect_func
= 0;
1418 int expect_return_type
= 0;
1419 const char *oldmangled
= NULL
;
1423 while (success
&& (**mangled
!= '\0'))
1428 oldmangled
= *mangled
;
1429 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1431 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1432 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1438 oldmangled
= *mangled
;
1439 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1440 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1448 /* Static member function */
1449 if (oldmangled
== NULL
)
1451 oldmangled
= *mangled
;
1454 work
-> static_type
= 1;
1460 work
->type_quals
|= code_for_qualifier (**mangled
);
1462 /* a qualified member function */
1463 if (oldmangled
== NULL
)
1464 oldmangled
= *mangled
;
1469 /* Local class name follows after "Lnnn_" */
1472 while (**mangled
&& (**mangled
!= '_'))
1483 case '0': case '1': case '2': case '3': case '4':
1484 case '5': case '6': case '7': case '8': case '9':
1485 if (oldmangled
== NULL
)
1487 oldmangled
= *mangled
;
1489 work
->temp_start
= -1; /* uppermost call to demangle_class */
1490 success
= demangle_class (work
, mangled
, declp
);
1493 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1495 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1497 /* EDG and others will have the "F", so we let the loop cycle
1498 if we are looking at one. */
1499 if (**mangled
!= 'F')
1508 success
= do_type (work
, mangled
, &s
);
1511 string_append (&s
, SCOPE_STRING (work
));
1512 string_prepends (declp
, &s
);
1522 /* ARM/HP style demangling includes a specific 'F' character after
1523 the class name. For GNU style, it is just implied. So we can
1524 safely just consume any 'F' at this point and be compatible
1525 with either style. */
1531 /* For lucid/ARM/HP style we have to forget any types we might
1532 have remembered up to this point, since they were not argument
1533 types. GNU style considers all types seen as available for
1534 back references. See comment in demangle_args() */
1536 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1538 forget_types (work
);
1540 success
= demangle_args (work
, mangled
, declp
);
1541 /* After picking off the function args, we expect to either
1542 find the function return type (preceded by an '_') or the
1543 end of the string. */
1544 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1547 /* At this level, we do not care about the return type. */
1548 success
= do_type (work
, mangled
, &tname
);
1549 string_delete (&tname
);
1556 string_init(&trawname
);
1557 string_init(&tname
);
1558 if (oldmangled
== NULL
)
1560 oldmangled
= *mangled
;
1562 success
= demangle_template (work
, mangled
, &tname
,
1566 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1568 string_append (&tname
, SCOPE_STRING (work
));
1570 string_prepends(declp
, &tname
);
1571 if (work
-> destructor
& 1)
1573 string_prepend (&trawname
, "~");
1574 string_appends (declp
, &trawname
);
1575 work
->destructor
-= 1;
1577 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1579 string_appends (declp
, &trawname
);
1580 work
->constructor
-= 1;
1582 string_delete(&trawname
);
1583 string_delete(&tname
);
1589 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
) && expect_return_type
)
1591 /* Read the return type. */
1595 success
= do_type (work
, mangled
, &return_type
);
1596 APPEND_BLANK (&return_type
);
1598 string_prepends (declp
, &return_type
);
1599 string_delete (&return_type
);
1603 /* At the outermost level, we cannot have a return type specified,
1604 so if we run into another '_' at this point we are dealing with
1605 a mangled name that is either bogus, or has been mangled by
1606 some algorithm we don't know how to deal with. So just
1607 reject the entire demangling. */
1608 /* However, "_nnn" is an expected suffix for alternate entry point
1609 numbered nnn for a function, with HP aCC, so skip over that
1610 without reporting failure. pai/1997-09-04 */
1614 while (**mangled
&& ISDIGIT ((unsigned char)**mangled
))
1622 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1624 /* A G++ template function. Read the template arguments. */
1625 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1627 if (!(work
->constructor
& 1))
1628 expect_return_type
= 1;
1637 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1639 /* Assume we have stumbled onto the first outermost function
1640 argument token, and start processing args. */
1642 success
= demangle_args (work
, mangled
, declp
);
1646 /* Non-GNU demanglers use a specific token to mark the start
1647 of the outermost function argument tokens. Typically 'F',
1648 for ARM/HP-demangling, for example. So if we find something
1649 we are not prepared for, it must be an error. */
1655 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1658 if (success
&& expect_func
)
1661 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1663 forget_types (work
);
1665 success
= demangle_args (work
, mangled
, declp
);
1666 /* Since template include the mangling of their return types,
1667 we must set expect_func to 0 so that we don't try do
1668 demangle more arguments the next time we get here. */
1673 if (success
&& !func_done
)
1675 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1677 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1678 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1679 first case, and need to ensure that the '(void)' gets added to
1680 the current declp. Note that with ARM/HP, the first case
1681 represents the name of a static data member 'foo::bar',
1682 which is in the current declp, so we leave it alone. */
1683 success
= demangle_args (work
, mangled
, declp
);
1686 if (success
&& PRINT_ARG_TYPES
)
1688 if (work
->static_type
)
1689 string_append (declp
, " static");
1690 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1692 APPEND_BLANK (declp
);
1693 string_append (declp
, qualifier_string (work
->type_quals
));
1703 demangle_method_args (struct work_stuff
*work
, const char **mangled
,
1708 if (work
-> static_type
)
1710 string_append (declp
, *mangled
+ 1);
1711 *mangled
+= strlen (*mangled
);
1716 success
= demangle_args (work
, mangled
, declp
);
1724 demangle_template_template_parm (struct work_stuff
*work
,
1725 const char **mangled
, string
*tname
)
1733 string_append (tname
, "template <");
1734 /* get size of template parameter list */
1735 if (get_count (mangled
, &r
))
1737 for (i
= 0; i
< r
; i
++)
1741 string_append (tname
, ", ");
1744 /* Z for type parameters */
1745 if (**mangled
== 'Z')
1748 string_append (tname
, "class");
1750 /* z for template parameters */
1751 else if (**mangled
== 'z')
1755 demangle_template_template_parm (work
, mangled
, tname
);
1763 /* temp is initialized in do_type */
1764 success
= do_type (work
, mangled
, &temp
);
1767 string_appends (tname
, &temp
);
1769 string_delete(&temp
);
1779 if (tname
->p
[-1] == '>')
1780 string_append (tname
, " ");
1781 string_append (tname
, "> class");
1786 demangle_expression (struct work_stuff
*work
, const char **mangled
,
1787 string
*s
, type_kind_t tk
)
1789 int need_operator
= 0;
1793 string_appendn (s
, "(", 1);
1795 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1804 len
= strlen (*mangled
);
1806 for (i
= 0; i
< ARRAY_SIZE (optable
); ++i
)
1808 size_t l
= strlen (optable
[i
].in
);
1811 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1813 string_appendn (s
, " ", 1);
1814 string_append (s
, optable
[i
].out
);
1815 string_appendn (s
, " ", 1);
1828 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1831 if (**mangled
!= 'W')
1835 string_appendn (s
, ")", 1);
1843 demangle_integral_value (struct work_stuff
*work
,
1844 const char **mangled
, string
*s
)
1848 if (**mangled
== 'E')
1849 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1850 else if (**mangled
== 'Q' || **mangled
== 'K')
1851 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1856 /* By default, we let the number decide whether we shall consume an
1858 int multidigit_without_leading_underscore
= 0;
1859 int leave_following_underscore
= 0;
1863 if (**mangled
== '_')
1865 if (mangled
[0][1] == 'm')
1867 /* Since consume_count_with_underscores does not handle the
1868 `m'-prefix we must do it here, using consume_count and
1869 adjusting underscores: we have to consume the underscore
1870 matching the prepended one. */
1871 multidigit_without_leading_underscore
= 1;
1872 string_appendn (s
, "-", 1);
1877 /* Do not consume a following underscore;
1878 consume_count_with_underscores will consume what
1879 should be consumed. */
1880 leave_following_underscore
= 1;
1885 /* Negative numbers are indicated with a leading `m'. */
1886 if (**mangled
== 'm')
1888 string_appendn (s
, "-", 1);
1891 /* Since consume_count_with_underscores does not handle
1892 multi-digit numbers that do not start with an underscore,
1893 and this number can be an integer template parameter,
1894 we have to call consume_count. */
1895 multidigit_without_leading_underscore
= 1;
1896 /* These multi-digit numbers never end on an underscore,
1897 so if there is one then don't eat it. */
1898 leave_following_underscore
= 1;
1901 /* We must call consume_count if we expect to remove a trailing
1902 underscore, since consume_count_with_underscores expects
1903 the leading underscore (that we consumed) if it is to handle
1904 multi-digit numbers. */
1905 if (multidigit_without_leading_underscore
)
1906 value
= consume_count (mangled
);
1908 value
= consume_count_with_underscores (mangled
);
1912 char buf
[INTBUF_SIZE
];
1913 sprintf (buf
, "%d", value
);
1914 string_append (s
, buf
);
1916 /* Numbers not otherwise delimited, might have an underscore
1917 appended as a delimeter, which we should skip.
1919 ??? This used to always remove a following underscore, which
1920 is wrong. If other (arbitrary) cases are followed by an
1921 underscore, we need to do something more radical. */
1923 if ((value
> 9 || multidigit_without_leading_underscore
)
1924 && ! leave_following_underscore
1925 && **mangled
== '_')
1936 /* Demangle the real value in MANGLED. */
1939 demangle_real_value (struct work_stuff
*work
,
1940 const char **mangled
, string
*s
)
1942 if (**mangled
== 'E')
1943 return demangle_expression (work
, mangled
, s
, tk_real
);
1945 if (**mangled
== 'm')
1947 string_appendn (s
, "-", 1);
1950 while (ISDIGIT ((unsigned char)**mangled
))
1952 string_appendn (s
, *mangled
, 1);
1955 if (**mangled
== '.') /* fraction */
1957 string_appendn (s
, ".", 1);
1959 while (ISDIGIT ((unsigned char)**mangled
))
1961 string_appendn (s
, *mangled
, 1);
1965 if (**mangled
== 'e') /* exponent */
1967 string_appendn (s
, "e", 1);
1969 while (ISDIGIT ((unsigned char)**mangled
))
1971 string_appendn (s
, *mangled
, 1);
1980 demangle_template_value_parm (struct work_stuff
*work
, const char **mangled
,
1981 string
*s
, type_kind_t tk
)
1985 if (**mangled
== 'Y')
1987 /* The next argument is a template parameter. */
1991 idx
= consume_count_with_underscores (mangled
);
1993 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1994 || consume_count_with_underscores (mangled
) == -1)
1996 if (work
->tmpl_argvec
)
1997 string_append (s
, work
->tmpl_argvec
[idx
]);
1999 string_append_template_idx (s
, idx
);
2001 else if (tk
== tk_integral
)
2002 success
= demangle_integral_value (work
, mangled
, s
);
2003 else if (tk
== tk_char
)
2007 if (**mangled
== 'm')
2009 string_appendn (s
, "-", 1);
2012 string_appendn (s
, "'", 1);
2013 val
= consume_count(mangled
);
2020 string_appendn (s
, &tmp
[0], 1);
2021 string_appendn (s
, "'", 1);
2024 else if (tk
== tk_bool
)
2026 int val
= consume_count (mangled
);
2028 string_appendn (s
, "false", 5);
2030 string_appendn (s
, "true", 4);
2034 else if (tk
== tk_real
)
2035 success
= demangle_real_value (work
, mangled
, s
);
2036 else if (tk
== tk_pointer
|| tk
== tk_reference
)
2038 if (**mangled
== 'Q')
2039 success
= demangle_qualified (work
, mangled
, s
,
2044 int symbol_len
= consume_count (mangled
);
2045 if (symbol_len
== -1)
2047 if (symbol_len
== 0)
2048 string_appendn (s
, "0", 1);
2051 char *p
= XNEWVEC (char, symbol_len
+ 1), *q
;
2052 strncpy (p
, *mangled
, symbol_len
);
2053 p
[symbol_len
] = '\0';
2054 /* We use cplus_demangle here, rather than
2055 internal_cplus_demangle, because the name of the entity
2056 mangled here does not make use of any of the squangling
2057 or type-code information we have built up thus far; it is
2058 mangled independently. */
2059 q
= cplus_demangle (p
, work
->options
);
2060 if (tk
== tk_pointer
)
2061 string_appendn (s
, "&", 1);
2062 /* FIXME: Pointer-to-member constants should get a
2063 qualifying class name here. */
2066 string_append (s
, q
);
2070 string_append (s
, p
);
2073 *mangled
+= symbol_len
;
2080 /* Demangle the template name in MANGLED. The full name of the
2081 template (e.g., S<int>) is placed in TNAME. The name without the
2082 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2083 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2084 not a function template. If both IS_TYPE and REMEMBER are nonzero,
2085 the template is remembered in the list of back-referenceable
2089 demangle_template (struct work_stuff
*work
, const char **mangled
,
2090 string
*tname
, string
*trawname
,
2091 int is_type
, int remember
)
2097 int is_java_array
= 0;
2103 /* get template name */
2104 if (**mangled
== 'z')
2110 idx
= consume_count_with_underscores (mangled
);
2112 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2113 || consume_count_with_underscores (mangled
) == -1)
2116 if (work
->tmpl_argvec
)
2118 string_append (tname
, work
->tmpl_argvec
[idx
]);
2120 string_append (trawname
, work
->tmpl_argvec
[idx
]);
2124 string_append_template_idx (tname
, idx
);
2126 string_append_template_idx (trawname
, idx
);
2131 if ((r
= consume_count (mangled
)) <= 0
2132 || (int) strlen (*mangled
) < r
)
2136 is_java_array
= (work
-> options
& DMGL_JAVA
)
2137 && strncmp (*mangled
, "JArray1Z", 8) == 0;
2138 if (! is_java_array
)
2140 string_appendn (tname
, *mangled
, r
);
2143 string_appendn (trawname
, *mangled
, r
);
2148 string_append (tname
, "<");
2149 /* get size of template parameter list */
2150 if (!get_count (mangled
, &r
))
2156 /* Create an array for saving the template argument values. */
2157 work
->tmpl_argvec
= XNEWVEC (char *, r
);
2158 work
->ntmpl_args
= r
;
2159 for (i
= 0; i
< r
; i
++)
2160 work
->tmpl_argvec
[i
] = 0;
2162 for (i
= 0; i
< r
; i
++)
2166 string_append (tname
, ", ");
2168 /* Z for type parameters */
2169 if (**mangled
== 'Z')
2172 /* temp is initialized in do_type */
2173 success
= do_type (work
, mangled
, &temp
);
2176 string_appends (tname
, &temp
);
2180 /* Save the template argument. */
2181 int len
= temp
.p
- temp
.b
;
2182 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2183 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
2184 work
->tmpl_argvec
[i
][len
] = '\0';
2187 string_delete(&temp
);
2193 /* z for template parameters */
2194 else if (**mangled
== 'z')
2198 success
= demangle_template_template_parm (work
, mangled
, tname
);
2201 && (r2
= consume_count (mangled
)) > 0
2202 && (int) strlen (*mangled
) >= r2
)
2204 string_append (tname
, " ");
2205 string_appendn (tname
, *mangled
, r2
);
2208 /* Save the template argument. */
2210 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2211 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
2212 work
->tmpl_argvec
[i
][len
] = '\0';
2226 /* otherwise, value parameter */
2228 /* temp is initialized in do_type */
2229 success
= do_type (work
, mangled
, &temp
);
2230 string_delete(&temp
);
2242 success
= demangle_template_value_parm (work
, mangled
, s
,
2243 (type_kind_t
) success
);
2255 int len
= s
->p
- s
->b
;
2256 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2257 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
2258 work
->tmpl_argvec
[i
][len
] = '\0';
2260 string_appends (tname
, s
);
2268 string_append (tname
, "[]");
2272 if (tname
->p
[-1] == '>')
2273 string_append (tname
, " ");
2274 string_append (tname
, ">");
2277 if (is_type
&& remember
)
2279 const int bindex
= register_Btype (work
);
2280 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
2284 if (work -> static_type)
2286 string_append (declp, *mangled + 1);
2287 *mangled += strlen (*mangled);
2292 success = demangle_args (work, mangled, declp);
2300 arm_pt (struct work_stuff
*work
, const char *mangled
,
2301 int n
, const char **anchor
, const char **args
)
2303 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2304 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2305 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= strstr (mangled
, "__pt__")))
2308 *args
= *anchor
+ 6;
2309 len
= consume_count (args
);
2312 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2318 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
2320 if ((*anchor
= strstr (mangled
, "__tm__"))
2321 || (*anchor
= strstr (mangled
, "__ps__"))
2322 || (*anchor
= strstr (mangled
, "__pt__")))
2325 *args
= *anchor
+ 6;
2326 len
= consume_count (args
);
2329 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2335 else if ((*anchor
= strstr (mangled
, "__S")))
2338 *args
= *anchor
+ 3;
2339 len
= consume_count (args
);
2342 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2354 demangle_arm_hp_template (struct work_stuff
*work
, const char **mangled
,
2355 int n
, string
*declp
)
2359 const char *e
= *mangled
+ n
;
2362 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2364 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
2366 char *start_spec_args
= NULL
;
2369 /* First check for and omit template specialization pseudo-arguments,
2370 such as in "Spec<#1,#1.*>" */
2371 start_spec_args
= strchr (*mangled
, '<');
2372 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
2373 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
2375 string_appendn (declp
, *mangled
, n
);
2376 (*mangled
) += n
+ 1;
2378 if (work
->temp_start
== -1) /* non-recursive call */
2379 work
->temp_start
= declp
->p
- declp
->b
;
2381 /* We want to unconditionally demangle parameter types in
2382 template parameters. */
2383 hold_options
= work
->options
;
2384 work
->options
|= DMGL_PARAMS
;
2386 string_append (declp
, "<");
2389 string_delete (&arg
);
2393 /* 'T' signals a type parameter */
2395 if (!do_type (work
, mangled
, &arg
))
2396 goto hpacc_template_args_done
;
2401 /* 'U' or 'S' signals an integral value */
2402 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
2403 goto hpacc_template_args_done
;
2407 /* 'A' signals a named constant expression (literal) */
2408 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
2409 goto hpacc_template_args_done
;
2413 /* Today, 1997-09-03, we have only the above types
2414 of template parameters */
2415 /* FIXME: maybe this should fail and return null */
2416 goto hpacc_template_args_done
;
2418 string_appends (declp
, &arg
);
2419 /* Check if we're at the end of template args.
2420 0 if at end of static member of template class,
2421 _ if done with template args for a function */
2422 if ((**mangled
== '\000') || (**mangled
== '_'))
2425 string_append (declp
, ",");
2427 hpacc_template_args_done
:
2428 string_append (declp
, ">");
2429 string_delete (&arg
);
2430 if (**mangled
== '_')
2432 work
->options
= hold_options
;
2435 /* ARM template? (Also handles HP cfront extensions) */
2436 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
2442 string_appendn (declp
, *mangled
, p
- *mangled
);
2443 if (work
->temp_start
== -1) /* non-recursive call */
2444 work
->temp_start
= declp
->p
- declp
->b
;
2446 /* We want to unconditionally demangle parameter types in
2447 template parameters. */
2448 hold_options
= work
->options
;
2449 work
->options
|= DMGL_PARAMS
;
2451 string_append (declp
, "<");
2452 /* should do error checking here */
2454 string_delete (&arg
);
2456 /* Check for type or literal here */
2459 /* HP cfront extensions to ARM for template args */
2460 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2461 /* FIXME: We handle only numeric literals for HP cfront */
2463 /* A typed constant value follows */
2465 if (!do_type (work
, &args
, &type_str
))
2466 goto cfront_template_args_done
;
2467 string_append (&arg
, "(");
2468 string_appends (&arg
, &type_str
);
2469 string_delete (&type_str
);
2470 string_append (&arg
, ")");
2472 goto cfront_template_args_done
;
2474 /* Now snarf a literal value following 'L' */
2475 if (!snarf_numeric_literal (&args
, &arg
))
2476 goto cfront_template_args_done
;
2480 /* Snarf a literal following 'L' */
2482 if (!snarf_numeric_literal (&args
, &arg
))
2483 goto cfront_template_args_done
;
2486 /* Not handling other HP cfront stuff */
2488 const char* old_args
= args
;
2489 if (!do_type (work
, &args
, &arg
))
2490 goto cfront_template_args_done
;
2492 /* Fail if we didn't make any progress: prevent infinite loop. */
2493 if (args
== old_args
)
2495 work
->options
= hold_options
;
2500 string_appends (declp
, &arg
);
2501 string_append (declp
, ",");
2503 cfront_template_args_done
:
2504 string_delete (&arg
);
2506 --declp
->p
; /* remove extra comma */
2507 string_append (declp
, ">");
2508 work
->options
= hold_options
;
2510 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2511 && (*mangled
)[9] == 'N'
2512 && (*mangled
)[8] == (*mangled
)[10]
2513 && strchr (cplus_markers
, (*mangled
)[8]))
2515 /* A member of the anonymous namespace. */
2516 string_append (declp
, "{anonymous}");
2520 if (work
->temp_start
== -1) /* non-recursive call only */
2521 work
->temp_start
= 0; /* disable in recursive calls */
2522 string_appendn (declp
, *mangled
, n
);
2527 /* Extract a class name, possibly a template with arguments, from the
2528 mangled string; qualifiers, local class indicators, etc. have
2529 already been dealt with */
2532 demangle_class_name (struct work_stuff
*work
, const char **mangled
,
2538 n
= consume_count (mangled
);
2541 if ((int) strlen (*mangled
) >= n
)
2543 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2554 demangle_class -- demangle a mangled class sequence
2559 demangle_class (struct work_stuff *work, const char **mangled,
2564 DECLP points to the buffer into which demangling is being done.
2566 *MANGLED points to the current token to be demangled. On input,
2567 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2568 On exit, it points to the next token after the mangled class on
2569 success, or the first unconsumed token on failure.
2571 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2572 we are demangling a constructor or destructor. In this case
2573 we prepend "class::class" or "class::~class" to DECLP.
2575 Otherwise, we prepend "class::" to the current DECLP.
2577 Reset the constructor/destructor flags once they have been
2578 "consumed". This allows demangle_class to be called later during
2579 the same demangling, to do normal class demangling.
2581 Returns 1 if demangling is successful, 0 otherwise.
2586 demangle_class (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2591 char *save_class_name_end
= 0;
2593 string_init (&class_name
);
2594 btype
= register_Btype (work
);
2595 if (demangle_class_name (work
, mangled
, &class_name
))
2597 save_class_name_end
= class_name
.p
;
2598 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2600 /* adjust so we don't include template args */
2601 if (work
->temp_start
&& (work
->temp_start
!= -1))
2603 class_name
.p
= class_name
.b
+ work
->temp_start
;
2605 string_prepends (declp
, &class_name
);
2606 if (work
-> destructor
& 1)
2608 string_prepend (declp
, "~");
2609 work
-> destructor
-= 1;
2613 work
-> constructor
-= 1;
2616 class_name
.p
= save_class_name_end
;
2617 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2618 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2619 string_prepend (declp
, SCOPE_STRING (work
));
2620 string_prepends (declp
, &class_name
);
2623 string_delete (&class_name
);
2628 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2629 the rightmost guess.
2631 Find the correct "__"-sequence where the function name ends and the
2632 signature starts, which is ambiguous with GNU mangling.
2633 Call demangle_signature here, so we can make sure we found the right
2634 one; *mangled will be consumed so caller will not make further calls to
2635 demangle_signature. */
2638 iterate_demangle_function (struct work_stuff
*work
, const char **mangled
,
2639 string
*declp
, const char *scan
)
2641 const char *mangle_init
= *mangled
;
2644 struct work_stuff work_init
;
2646 if (*(scan
+ 2) == '\0')
2649 /* Do not iterate for some demangling modes, or if there's only one
2650 "__"-sequence. This is the normal case. */
2651 if (ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
2652 || strstr (scan
+ 2, "__") == NULL
)
2653 return demangle_function_name (work
, mangled
, declp
, scan
);
2655 /* Save state so we can restart if the guess at the correct "__" was
2657 string_init (&decl_init
);
2658 string_appends (&decl_init
, declp
);
2659 memset (&work_init
, 0, sizeof work_init
);
2660 work_stuff_copy_to_from (&work_init
, work
);
2662 /* Iterate over occurrences of __, allowing names and types to have a
2663 "__" sequence in them. We must start with the first (not the last)
2664 occurrence, since "__" most often occur between independent mangled
2665 parts, hence starting at the last occurence inside a signature
2666 might get us a "successful" demangling of the signature. */
2670 if (demangle_function_name (work
, mangled
, declp
, scan
))
2672 success
= demangle_signature (work
, mangled
, declp
);
2677 /* Reset demangle state for the next round. */
2678 *mangled
= mangle_init
;
2679 string_clear (declp
);
2680 string_appends (declp
, &decl_init
);
2681 work_stuff_copy_to_from (work
, &work_init
);
2683 /* Leave this underscore-sequence. */
2686 /* Scan for the next "__" sequence. */
2687 while (*scan
&& (scan
[0] != '_' || scan
[1] != '_'))
2690 /* Move to last "__" in this sequence. */
2691 while (*scan
&& *scan
== '_')
2696 /* Delete saved state. */
2697 delete_work_stuff (&work_init
);
2698 string_delete (&decl_init
);
2707 demangle_prefix -- consume the mangled name prefix and find signature
2712 demangle_prefix (struct work_stuff *work, const char **mangled,
2717 Consume and demangle the prefix of the mangled name.
2718 While processing the function name root, arrange to call
2719 demangle_signature if the root is ambiguous.
2721 DECLP points to the string buffer into which demangled output is
2722 placed. On entry, the buffer is empty. On exit it contains
2723 the root function name, the demangled operator name, or in some
2724 special cases either nothing or the completely demangled result.
2726 MANGLED points to the current pointer into the mangled name. As each
2727 token of the mangled name is consumed, it is updated. Upon entry
2728 the current mangled name pointer points to the first character of
2729 the mangled name. Upon exit, it should point to the first character
2730 of the signature if demangling was successful, or to the first
2731 unconsumed character if demangling of the prefix was unsuccessful.
2733 Returns 1 on success, 0 otherwise.
2737 demangle_prefix (struct work_stuff
*work
, const char **mangled
,
2744 if (strlen(*mangled
) > 6
2745 && (strncmp(*mangled
, "_imp__", 6) == 0
2746 || strncmp(*mangled
, "__imp_", 6) == 0))
2748 /* it's a symbol imported from a PE dynamic library. Check for both
2749 new style prefix _imp__ and legacy __imp_ used by older versions
2752 work
->dllimported
= 1;
2754 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2756 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2757 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2759 if ((*mangled
)[9] == 'D')
2761 /* it's a GNU global destructor to be executed at program exit */
2763 work
->destructor
= 2;
2764 if (gnu_special (work
, mangled
, declp
))
2767 else if ((*mangled
)[9] == 'I')
2769 /* it's a GNU global constructor to be executed at program init */
2771 work
->constructor
= 2;
2772 if (gnu_special (work
, mangled
, declp
))
2777 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2779 /* it's a ARM global destructor to be executed at program exit */
2781 work
->destructor
= 2;
2783 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2785 /* it's a ARM global constructor to be executed at program initial */
2787 work
->constructor
= 2;
2790 /* This block of code is a reduction in strength time optimization
2792 scan = strstr (*mangled, "__"); */
2798 scan
= strchr (scan
, '_');
2799 } while (scan
!= NULL
&& *++scan
!= '_');
2801 if (scan
!= NULL
) --scan
;
2806 /* We found a sequence of two or more '_', ensure that we start at
2807 the last pair in the sequence. */
2808 i
= strspn (scan
, "_");
2819 else if (work
-> static_type
)
2821 if (!ISDIGIT ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2826 else if ((scan
== *mangled
)
2827 && (ISDIGIT ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2828 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2830 /* The ARM says nothing about the mangling of local variables.
2831 But cfront mangles local variables by prepending __<nesting_level>
2832 to them. As an extension to ARM demangling we handle this case. */
2833 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2834 && ISDIGIT ((unsigned char)scan
[2]))
2836 *mangled
= scan
+ 2;
2837 consume_count (mangled
);
2838 string_append (declp
, *mangled
);
2839 *mangled
+= strlen (*mangled
);
2844 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2845 names like __Q2_3foo3bar for nested type names. So don't accept
2846 this style of constructor for cfront demangling. A GNU
2847 style member-template constructor starts with 'H'. */
2848 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2849 work
-> constructor
+= 1;
2850 *mangled
= scan
+ 2;
2853 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2855 /* Cfront-style parameterized type. Handled later as a signature. */
2859 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2861 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2862 || (scan
[2] == 'p' && scan
[3] == 's')
2863 || (scan
[2] == 'p' && scan
[3] == 't')))
2865 /* EDG-style parameterized type. Handled later as a signature. */
2869 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2871 else if ((scan
== *mangled
) && !ISDIGIT ((unsigned char)scan
[2])
2872 && (scan
[2] != 't'))
2874 /* Mangled name starts with "__". Skip over any leading '_' characters,
2875 then find the next "__" that separates the prefix from the signature.
2877 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2878 || (arm_special (mangled
, declp
) == 0))
2880 while (*scan
== '_')
2884 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2886 /* No separator (I.E. "__not_mangled"), or empty signature
2887 (I.E. "__not_mangled_either__") */
2891 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2894 else if (*(scan
+ 2) != '\0')
2896 /* Mangled name does not start with "__" but does have one somewhere
2897 in there with non empty stuff after it. Looks like a global
2898 function name. Iterate over all "__":s until the right
2900 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2904 /* Doesn't look like a mangled name */
2908 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2910 string_append (declp
, *mangled
);
2911 *mangled
+= strlen (*mangled
);
2921 gnu_special -- special handling of gnu mangled strings
2926 gnu_special (struct work_stuff *work, const char **mangled,
2932 Process some special GNU style mangling forms that don't fit
2933 the normal pattern. For example:
2935 _$_3foo (destructor for class foo)
2936 _vt$foo (foo virtual table)
2937 _vt$foo$bar (foo::bar virtual table)
2938 __vt_foo (foo virtual table, new style with thunks)
2939 _3foo$varname (static data member)
2940 _Q22rs2tu$vw (static data member)
2941 __t6vector1Zii (constructor with template)
2942 __thunk_4__$_7ostream (virtual function thunk)
2946 gnu_special (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2952 if ((*mangled
)[0] == '_'
2953 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2954 && (*mangled
)[2] == '_')
2956 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2958 work
-> destructor
+= 1;
2960 else if ((*mangled
)[0] == '_'
2961 && (((*mangled
)[1] == '_'
2962 && (*mangled
)[2] == 'v'
2963 && (*mangled
)[3] == 't'
2964 && (*mangled
)[4] == '_')
2965 || ((*mangled
)[1] == 'v'
2966 && (*mangled
)[2] == 't'
2967 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2969 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2970 and create the decl. Note that we consume the entire mangled
2971 input string, which means that demangle_signature has no work
2973 if ((*mangled
)[2] == 'v')
2974 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2976 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2977 while (**mangled
!= '\0')
2983 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2986 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2990 if (ISDIGIT((unsigned char)*mangled
[0]))
2992 n
= consume_count(mangled
);
2993 /* We may be seeing a too-large size, or else a
2994 ".<digits>" indicating a static local symbol. In
2995 any case, declare victory and move on; *don't* try
2996 to use n to allocate. */
2997 if (n
> (int) strlen (*mangled
))
3005 n
= strcspn (*mangled
, cplus_markers
);
3007 string_appendn (declp
, *mangled
, n
);
3011 p
= strpbrk (*mangled
, cplus_markers
);
3012 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
3016 string_append (declp
, SCOPE_STRING (work
));
3027 string_append (declp
, " virtual table");
3029 else if ((*mangled
)[0] == '_'
3030 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
3031 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
3033 /* static data member, "_3foo$varname" for example */
3039 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3042 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3045 n
= consume_count (mangled
);
3046 if (n
< 0 || n
> (long) strlen (*mangled
))
3052 if (n
> 10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
3053 && (*mangled
)[9] == 'N'
3054 && (*mangled
)[8] == (*mangled
)[10]
3055 && strchr (cplus_markers
, (*mangled
)[8]))
3057 /* A member of the anonymous namespace. There's information
3058 about what identifier or filename it was keyed to, but
3059 it's just there to make the mangled name unique; we just
3061 string_append (declp
, "{anonymous}");
3064 /* Now p points to the marker before the N, so we need to
3065 update it to the first marker after what we consumed. */
3066 p
= strpbrk (*mangled
, cplus_markers
);
3070 string_appendn (declp
, *mangled
, n
);
3073 if (success
&& (p
== *mangled
))
3075 /* Consumed everything up to the cplus_marker, append the
3078 string_append (declp
, SCOPE_STRING (work
));
3079 n
= strlen (*mangled
);
3080 string_appendn (declp
, *mangled
, n
);
3088 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
3093 delta
= consume_count (mangled
);
3098 char *method
= internal_cplus_demangle (work
, ++*mangled
);
3103 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
3104 string_append (declp
, buf
);
3105 string_append (declp
, method
);
3107 n
= strlen (*mangled
);
3116 else if (strncmp (*mangled
, "__t", 3) == 0
3117 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
3119 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
3125 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3128 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3131 success
= do_type (work
, mangled
, declp
);
3134 if (success
&& **mangled
!= '\0')
3137 string_append (declp
, p
);
3147 recursively_demangle(struct work_stuff
*work
, const char **mangled
,
3148 string
*result
, int namelength
)
3150 char * recurse
= (char *)NULL
;
3151 char * recurse_dem
= (char *)NULL
;
3153 recurse
= XNEWVEC (char, namelength
+ 1);
3154 memcpy (recurse
, *mangled
, namelength
);
3155 recurse
[namelength
] = '\000';
3157 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3161 string_append (result
, recurse_dem
);
3166 string_appendn (result
, *mangled
, namelength
);
3169 *mangled
+= namelength
;
3176 arm_special -- special handling of ARM/lucid mangled strings
3181 arm_special (const char **mangled,
3187 Process some special ARM style mangling forms that don't fit
3188 the normal pattern. For example:
3190 __vtbl__3foo (foo virtual table)
3191 __vtbl__3foo__3bar (bar::foo virtual table)
3196 arm_special (const char **mangled
, string
*declp
)
3202 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
3204 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3205 and create the decl. Note that we consume the entire mangled
3206 input string, which means that demangle_signature has no work
3208 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
3209 while (*scan
!= '\0') /* first check it can be demangled */
3211 n
= consume_count (&scan
);
3214 return (0); /* no good */
3217 if (scan
[0] == '_' && scan
[1] == '_')
3222 (*mangled
) += ARM_VTABLE_STRLEN
;
3223 while (**mangled
!= '\0')
3225 n
= consume_count (mangled
);
3227 || n
> (long) strlen (*mangled
))
3229 string_prependn (declp
, *mangled
, n
);
3231 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
3233 string_prepend (declp
, "::");
3237 string_append (declp
, " virtual table");
3250 demangle_qualified -- demangle 'Q' qualified name strings
3255 demangle_qualified (struct work_stuff *, const char *mangled,
3256 string *result, int isfuncname, int append);
3260 Demangle a qualified name, such as "Q25Outer5Inner" which is
3261 the mangled form of "Outer::Inner". The demangled output is
3262 prepended or appended to the result string according to the
3263 state of the append flag.
3265 If isfuncname is nonzero, then the qualified name we are building
3266 is going to be used as a member function name, so if it is a
3267 constructor or destructor function, append an appropriate
3268 constructor or destructor name. I.E. for the above example,
3269 the result for use as a constructor is "Outer::Inner::Inner"
3270 and the result for use as a destructor is "Outer::Inner::~Inner".
3274 Numeric conversion is ASCII dependent (FIXME).
3279 demangle_qualified (struct work_stuff
*work
, const char **mangled
,
3280 string
*result
, int isfuncname
, int append
)
3287 int bindex
= register_Btype (work
);
3289 /* We only make use of ISFUNCNAME if the entity is a constructor or
3291 isfuncname
= (isfuncname
3292 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
3294 string_init (&temp
);
3295 string_init (&last_name
);
3297 if ((*mangled
)[0] == 'K')
3299 /* Squangling qualified name reuse */
3302 idx
= consume_count_with_underscores (mangled
);
3303 if (idx
== -1 || idx
>= work
-> numk
)
3306 string_append (&temp
, work
-> ktypevec
[idx
]);
3309 switch ((*mangled
)[1])
3312 /* GNU mangled name with more than 9 classes. The count is preceded
3313 by an underscore (to distinguish it from the <= 9 case) and followed
3314 by an underscore. */
3316 qualifiers
= consume_count_with_underscores (mangled
);
3317 if (qualifiers
== -1)
3330 /* The count is in a single digit. */
3331 num
[0] = (*mangled
)[1];
3333 qualifiers
= atoi (num
);
3335 /* If there is an underscore after the digit, skip it. This is
3336 said to be for ARM-qualified names, but the ARM makes no
3337 mention of such an underscore. Perhaps cfront uses one. */
3338 if ((*mangled
)[2] == '_')
3353 /* Pick off the names and collect them in the temp buffer in the order
3354 in which they are found, separated by '::'. */
3356 while (qualifiers
-- > 0)
3359 string_clear (&last_name
);
3361 if (*mangled
[0] == '_')
3364 if (*mangled
[0] == 't')
3366 /* Here we always append to TEMP since we will want to use
3367 the template name without the template parameters as a
3368 constructor or destructor name. The appropriate
3369 (parameter-less) value is returned by demangle_template
3370 in LAST_NAME. We do not remember the template type here,
3371 in order to match the G++ mangling algorithm. */
3372 success
= demangle_template(work
, mangled
, &temp
,
3377 else if (*mangled
[0] == 'K')
3381 idx
= consume_count_with_underscores (mangled
);
3382 if (idx
== -1 || idx
>= work
->numk
)
3385 string_append (&temp
, work
->ktypevec
[idx
]);
3388 if (!success
) break;
3395 /* Now recursively demangle the qualifier
3396 * This is necessary to deal with templates in
3397 * mangling styles like EDG */
3398 namelength
= consume_count (mangled
);
3399 if (namelength
== -1)
3404 recursively_demangle(work
, mangled
, &temp
, namelength
);
3408 string_delete (&last_name
);
3409 success
= do_type (work
, mangled
, &last_name
);
3412 string_appends (&temp
, &last_name
);
3417 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
3420 string_append (&temp
, SCOPE_STRING (work
));
3423 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
3425 /* If we are using the result as a function name, we need to append
3426 the appropriate '::' separated constructor or destructor name.
3427 We do this here because this is the most convenient place, where
3428 we already have a pointer to the name and the length of the name. */
3432 string_append (&temp
, SCOPE_STRING (work
));
3433 if (work
-> destructor
& 1)
3434 string_append (&temp
, "~");
3435 string_appends (&temp
, &last_name
);
3438 /* Now either prepend the temp buffer to the result, or append it,
3439 depending upon the state of the append flag. */
3442 string_appends (result
, &temp
);
3445 if (!STRING_EMPTY (result
))
3446 string_append (&temp
, SCOPE_STRING (work
));
3447 string_prepends (result
, &temp
);
3450 string_delete (&last_name
);
3451 string_delete (&temp
);
3459 get_count -- convert an ascii count to integer, consuming tokens
3464 get_count (const char **type, int *count)
3468 Assume that *type points at a count in a mangled name; set
3469 *count to its value, and set *type to the next character after
3470 the count. There are some weird rules in effect here.
3472 If *type does not point at a string of digits, return zero.
3474 If *type points at a string of digits followed by an
3475 underscore, set *count to their value as an integer, advance
3476 *type to point *after the underscore, and return 1.
3478 If *type points at a string of digits not followed by an
3479 underscore, consume only the first digit. Set *count to its
3480 value as an integer, leave *type pointing after that digit,
3483 The excuse for this odd behavior: in the ARM and HP demangling
3484 styles, a type can be followed by a repeat count of the form
3487 `x' is a single digit specifying how many additional copies
3488 of the type to append to the argument list, and
3490 `y' is one or more digits, specifying the zero-based index of
3491 the first repeated argument in the list. Yes, as you're
3492 unmangling the name you can figure this out yourself, but
3495 So, for example, in `bar__3fooFPiN51', the first argument is a
3496 pointer to an integer (`Pi'), and then the next five arguments
3497 are the same (`N5'), and the first repeat is the function's
3498 second argument (`1').
3502 get_count (const char **type
, int *count
)
3507 if (!ISDIGIT ((unsigned char)**type
))
3511 *count
= **type
- '0';
3513 if (ISDIGIT ((unsigned char)**type
))
3523 while (ISDIGIT ((unsigned char)*p
));
3534 /* RESULT will be initialised here; it will be freed on failure. The
3535 value returned is really a type_kind_t. */
3538 do_type (struct work_stuff
*work
, const char **mangled
, string
*result
)
3544 const char *remembered_type
;
3546 type_kind_t tk
= tk_none
;
3548 string_init (&decl
);
3549 string_init (result
);
3553 while (success
&& !done
)
3559 /* A pointer type */
3563 if (! (work
-> options
& DMGL_JAVA
))
3564 string_prepend (&decl
, "*");
3569 /* A reference type */
3572 string_prepend (&decl
, "&");
3581 if (!STRING_EMPTY (&decl
)
3582 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3584 string_prepend (&decl
, "(");
3585 string_append (&decl
, ")");
3587 string_append (&decl
, "[");
3588 if (**mangled
!= '_')
3589 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3591 if (**mangled
== '_')
3593 string_append (&decl
, "]");
3597 /* A back reference to a previously seen type */
3600 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3606 remembered_type
= work
-> typevec
[n
];
3607 mangled
= &remembered_type
;
3614 if (!STRING_EMPTY (&decl
)
3615 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3617 string_prepend (&decl
, "(");
3618 string_append (&decl
, ")");
3620 /* After picking off the function args, we expect to either find the
3621 function return type (preceded by an '_') or the end of the
3623 if (!demangle_nested_args (work
, mangled
, &decl
)
3624 || (**mangled
!= '_' && **mangled
!= '\0'))
3629 if (success
&& (**mangled
== '_'))
3636 type_quals
= TYPE_UNQUALIFIED
;
3638 member
= **mangled
== 'M';
3641 string_append (&decl
, ")");
3643 /* We don't need to prepend `::' for a qualified name;
3644 demangle_qualified will do that for us. */
3645 if (**mangled
!= 'Q')
3646 string_prepend (&decl
, SCOPE_STRING (work
));
3648 if (ISDIGIT ((unsigned char)**mangled
))
3650 n
= consume_count (mangled
);
3652 || (int) strlen (*mangled
) < n
)
3657 string_prependn (&decl
, *mangled
, n
);
3660 else if (**mangled
== 'X' || **mangled
== 'Y')
3663 do_type (work
, mangled
, &temp
);
3664 string_prepends (&decl
, &temp
);
3665 string_delete (&temp
);
3667 else if (**mangled
== 't')
3670 string_init (&temp
);
3671 success
= demangle_template (work
, mangled
, &temp
,
3675 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3676 string_delete (&temp
);
3680 string_delete (&temp
);
3684 else if (**mangled
== 'Q')
3686 success
= demangle_qualified (work
, mangled
, &decl
,
3698 string_prepend (&decl
, "(");
3706 type_quals
|= code_for_qualifier (**mangled
);
3714 if (*(*mangled
)++ != 'F')
3720 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3721 || **mangled
!= '_')
3727 if (! PRINT_ANSI_QUALIFIERS
)
3731 if (type_quals
!= TYPE_UNQUALIFIED
)
3733 APPEND_BLANK (&decl
);
3734 string_append (&decl
, qualifier_string (type_quals
));
3745 if (PRINT_ANSI_QUALIFIERS
)
3747 if (!STRING_EMPTY (&decl
))
3748 string_prepend (&decl
, " ");
3750 string_prepend (&decl
, demangle_qualifier (**mangled
));
3765 if (success
) switch (**mangled
)
3767 /* A qualified name, such as "Outer::Inner". */
3771 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3775 /* A back reference to a previously seen squangled type */
3778 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3781 string_append (result
, work
->btypevec
[n
]);
3786 /* A template parm. We substitute the corresponding argument. */
3791 idx
= consume_count_with_underscores (mangled
);
3794 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3795 || consume_count_with_underscores (mangled
) == -1)
3801 if (work
->tmpl_argvec
)
3802 string_append (result
, work
->tmpl_argvec
[idx
]);
3804 string_append_template_idx (result
, idx
);
3811 success
= demangle_fund_type (work
, mangled
, result
);
3813 tk
= (type_kind_t
) success
;
3819 if (!STRING_EMPTY (&decl
))
3821 string_append (result
, " ");
3822 string_appends (result
, &decl
);
3826 string_delete (result
);
3827 string_delete (&decl
);
3830 /* Assume an integral type, if we're not sure. */
3831 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3836 /* Given a pointer to a type string that represents a fundamental type
3837 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3838 string in which the demangled output is being built in RESULT, and
3839 the WORK structure, decode the types and add them to the result.
3844 "Sl" => "signed long"
3845 "CUs" => "const unsigned short"
3847 The value returned is really a type_kind_t. */
3850 demangle_fund_type (struct work_stuff
*work
,
3851 const char **mangled
, string
*result
)
3855 char buf
[INTBUF_SIZE
+ 5 /* 'int%u_t' */];
3856 unsigned int dec
= 0;
3857 type_kind_t tk
= tk_integral
;
3859 /* First pick off any type qualifiers. There can be more than one. */
3868 if (PRINT_ANSI_QUALIFIERS
)
3870 if (!STRING_EMPTY (result
))
3871 string_prepend (result
, " ");
3872 string_prepend (result
, demangle_qualifier (**mangled
));
3878 APPEND_BLANK (result
);
3879 string_append (result
, "unsigned");
3881 case 'S': /* signed char only */
3883 APPEND_BLANK (result
);
3884 string_append (result
, "signed");
3888 APPEND_BLANK (result
);
3889 string_append (result
, "__complex");
3897 /* Now pick off the fundamental type. There can be only one. */
3906 APPEND_BLANK (result
);
3907 string_append (result
, "void");
3911 APPEND_BLANK (result
);
3912 string_append (result
, "long long");
3916 APPEND_BLANK (result
);
3917 string_append (result
, "long");
3921 APPEND_BLANK (result
);
3922 string_append (result
, "int");
3926 APPEND_BLANK (result
);
3927 string_append (result
, "short");
3931 APPEND_BLANK (result
);
3932 string_append (result
, "bool");
3937 APPEND_BLANK (result
);
3938 string_append (result
, "char");
3943 APPEND_BLANK (result
);
3944 string_append (result
, "wchar_t");
3949 APPEND_BLANK (result
);
3950 string_append (result
, "long double");
3955 APPEND_BLANK (result
);
3956 string_append (result
, "double");
3961 APPEND_BLANK (result
);
3962 string_append (result
, "float");
3967 if (!ISDIGIT ((unsigned char)**mangled
))
3974 if (**mangled
== '_')
3979 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3982 if (**mangled
!= '_')
3992 strncpy (buf
, *mangled
, 2);
3994 *mangled
+= min (strlen (*mangled
), 2);
3996 sscanf (buf
, "%x", &dec
);
3997 sprintf (buf
, "int%u_t", dec
);
3998 APPEND_BLANK (result
);
3999 string_append (result
, buf
);
4003 /* An explicit type, such as "6mytype" or "7integer" */
4015 int bindex
= register_Btype (work
);
4017 string_init (&btype
);
4018 if (demangle_class_name (work
, mangled
, &btype
)) {
4019 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
4020 APPEND_BLANK (result
);
4021 string_appends (result
, &btype
);
4025 string_delete (&btype
);
4031 string_init (&btype
);
4032 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
4033 string_appends (result
, &btype
);
4034 string_delete (&btype
);
4042 return success
? ((int) tk
) : 0;
4046 /* Handle a template's value parameter for HP aCC (extension from ARM)
4047 **mangled points to 'S' or 'U' */
4050 do_hpacc_template_const_value (struct work_stuff
*work ATTRIBUTE_UNUSED
,
4051 const char **mangled
, string
*result
)
4055 if (**mangled
!= 'U' && **mangled
!= 'S')
4058 unsigned_const
= (**mangled
== 'U');
4065 string_append (result
, "-");
4071 /* special case for -2^31 */
4072 string_append (result
, "-2147483648");
4079 /* We have to be looking at an integer now */
4080 if (!(ISDIGIT ((unsigned char)**mangled
)))
4083 /* We only deal with integral values for template
4084 parameters -- so it's OK to look only for digits */
4085 while (ISDIGIT ((unsigned char)**mangled
))
4087 char_str
[0] = **mangled
;
4088 string_append (result
, char_str
);
4093 string_append (result
, "U");
4095 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4096 with L or LL suffixes. pai/1997-09-03 */
4098 return 1; /* success */
4101 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4102 **mangled is pointing to the 'A' */
4105 do_hpacc_template_literal (struct work_stuff
*work
, const char **mangled
,
4108 int literal_len
= 0;
4112 if (**mangled
!= 'A')
4117 literal_len
= consume_count (mangled
);
4119 if (literal_len
<= 0)
4122 /* Literal parameters are names of arrays, functions, etc. and the
4123 canonical representation uses the address operator */
4124 string_append (result
, "&");
4126 /* Now recursively demangle the literal name */
4127 recurse
= XNEWVEC (char, literal_len
+ 1);
4128 memcpy (recurse
, *mangled
, literal_len
);
4129 recurse
[literal_len
] = '\000';
4131 recurse_dem
= cplus_demangle (recurse
, work
->options
);
4135 string_append (result
, recurse_dem
);
4140 string_appendn (result
, *mangled
, literal_len
);
4142 (*mangled
) += literal_len
;
4149 snarf_numeric_literal (const char **args
, string
*arg
)
4154 string_append (arg
, char_str
);
4157 else if (**args
== '+')
4160 if (!ISDIGIT ((unsigned char)**args
))
4163 while (ISDIGIT ((unsigned char)**args
))
4165 char_str
[0] = **args
;
4166 string_append (arg
, char_str
);
4173 /* Demangle the next argument, given by MANGLED into RESULT, which
4174 *should be an uninitialized* string. It will be initialized here,
4175 and free'd should anything go wrong. */
4178 do_arg (struct work_stuff
*work
, const char **mangled
, string
*result
)
4180 /* Remember where we started so that we can record the type, for
4181 non-squangling type remembering. */
4182 const char *start
= *mangled
;
4184 string_init (result
);
4186 if (work
->nrepeats
> 0)
4190 if (work
->previous_argument
== 0)
4193 /* We want to reissue the previous type in this argument list. */
4194 string_appends (result
, work
->previous_argument
);
4198 if (**mangled
== 'n')
4200 /* A squangling-style repeat. */
4202 work
->nrepeats
= consume_count(mangled
);
4204 if (work
->nrepeats
<= 0)
4205 /* This was not a repeat count after all. */
4208 if (work
->nrepeats
> 9)
4210 if (**mangled
!= '_')
4211 /* The repeat count should be followed by an '_' in this
4218 /* Now, the repeat is all set up. */
4219 return do_arg (work
, mangled
, result
);
4222 /* Save the result in WORK->previous_argument so that we can find it
4223 if it's repeated. Note that saving START is not good enough: we
4224 do not want to add additional types to the back-referenceable
4225 type vector when processing a repeated type. */
4226 if (work
->previous_argument
)
4227 string_delete (work
->previous_argument
);
4229 work
->previous_argument
= XNEW (string
);
4231 if (!do_type (work
, mangled
, work
->previous_argument
))
4234 string_appends (result
, work
->previous_argument
);
4236 remember_type (work
, start
, *mangled
- start
);
4241 remember_type (struct work_stuff
*work
, const char *start
, int len
)
4245 if (work
->forgetting_types
)
4248 if (work
-> ntypes
>= work
-> typevec_size
)
4250 if (work
-> typevec_size
== 0)
4252 work
-> typevec_size
= 3;
4253 work
-> typevec
= XNEWVEC (char *, work
->typevec_size
);
4257 work
-> typevec_size
*= 2;
4259 = XRESIZEVEC (char *, work
->typevec
, work
->typevec_size
);
4262 tem
= XNEWVEC (char, len
+ 1);
4263 memcpy (tem
, start
, len
);
4265 work
-> typevec
[work
-> ntypes
++] = tem
;
4269 /* Remember a K type class qualifier. */
4271 remember_Ktype (struct work_stuff
*work
, const char *start
, int len
)
4275 if (work
-> numk
>= work
-> ksize
)
4277 if (work
-> ksize
== 0)
4280 work
-> ktypevec
= XNEWVEC (char *, work
->ksize
);
4286 = XRESIZEVEC (char *, work
->ktypevec
, work
->ksize
);
4289 tem
= XNEWVEC (char, len
+ 1);
4290 memcpy (tem
, start
, len
);
4292 work
-> ktypevec
[work
-> numk
++] = tem
;
4295 /* Register a B code, and get an index for it. B codes are registered
4296 as they are seen, rather than as they are completed, so map<temp<char> >
4297 registers map<temp<char> > as B0, and temp<char> as B1 */
4300 register_Btype (struct work_stuff
*work
)
4304 if (work
-> numb
>= work
-> bsize
)
4306 if (work
-> bsize
== 0)
4309 work
-> btypevec
= XNEWVEC (char *, work
->bsize
);
4315 = XRESIZEVEC (char *, work
->btypevec
, work
->bsize
);
4318 ret
= work
-> numb
++;
4319 work
-> btypevec
[ret
] = NULL
;
4323 /* Store a value into a previously registered B code type. */
4326 remember_Btype (struct work_stuff
*work
, const char *start
,
4331 tem
= XNEWVEC (char, len
+ 1);
4332 memcpy (tem
, start
, len
);
4334 work
-> btypevec
[index
] = tem
;
4337 /* Lose all the info related to B and K type codes. */
4339 forget_B_and_K_types (struct work_stuff
*work
)
4343 while (work
-> numk
> 0)
4345 i
= --(work
-> numk
);
4346 if (work
-> ktypevec
[i
] != NULL
)
4348 free (work
-> ktypevec
[i
]);
4349 work
-> ktypevec
[i
] = NULL
;
4353 while (work
-> numb
> 0)
4355 i
= --(work
-> numb
);
4356 if (work
-> btypevec
[i
] != NULL
)
4358 free (work
-> btypevec
[i
]);
4359 work
-> btypevec
[i
] = NULL
;
4363 /* Forget the remembered types, but not the type vector itself. */
4366 forget_types (struct work_stuff
*work
)
4370 while (work
-> ntypes
> 0)
4372 i
= --(work
-> ntypes
);
4373 if (work
-> typevec
[i
] != NULL
)
4375 free (work
-> typevec
[i
]);
4376 work
-> typevec
[i
] = NULL
;
4381 /* Process the argument list part of the signature, after any class spec
4382 has been consumed, as well as the first 'F' character (if any). For
4385 "__als__3fooRT0" => process "RT0"
4386 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4388 DECLP must be already initialised, usually non-empty. It won't be freed
4391 Note that g++ differs significantly from ARM and lucid style mangling
4392 with regards to references to previously seen types. For example, given
4393 the source fragment:
4397 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4400 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4401 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4403 g++ produces the names:
4408 while lcc (and presumably other ARM style compilers as well) produces:
4410 foo__FiR3fooT1T2T1T2
4411 __ct__3fooFiR3fooT1T2T1T2
4413 Note that g++ bases its type numbers starting at zero and counts all
4414 previously seen types, while lucid/ARM bases its type numbers starting
4415 at one and only considers types after it has seen the 'F' character
4416 indicating the start of the function args. For lucid/ARM style, we
4417 account for this difference by discarding any previously seen types when
4418 we see the 'F' character, and subtracting one from the type number
4424 demangle_args (struct work_stuff
*work
, const char **mangled
,
4434 if (PRINT_ARG_TYPES
)
4436 string_append (declp
, "(");
4437 if (**mangled
== '\0')
4439 string_append (declp
, "void");
4443 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
4444 || work
->nrepeats
> 0)
4446 if ((**mangled
== 'N') || (**mangled
== 'T'))
4448 temptype
= *(*mangled
)++;
4450 if (temptype
== 'N')
4452 if (!get_count (mangled
, &r
))
4461 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
4463 /* If we have 10 or more types we might have more than a 1 digit
4464 index so we'll have to consume the whole count here. This
4465 will lose if the next thing is a type name preceded by a
4466 count but it's impossible to demangle that case properly
4467 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4468 Pc, ...)" or "(..., type12, char *, ...)" */
4469 if ((t
= consume_count(mangled
)) <= 0)
4476 if (!get_count (mangled
, &t
))
4481 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4485 /* Validate the type index. Protect against illegal indices from
4486 malformed type strings. */
4487 if ((t
< 0) || (t
>= work
-> ntypes
))
4491 while (work
->nrepeats
> 0 || --r
>= 0)
4493 tem
= work
-> typevec
[t
];
4494 if (need_comma
&& PRINT_ARG_TYPES
)
4496 string_append (declp
, ", ");
4498 if (!do_arg (work
, &tem
, &arg
))
4502 if (PRINT_ARG_TYPES
)
4504 string_appends (declp
, &arg
);
4506 string_delete (&arg
);
4512 if (need_comma
&& PRINT_ARG_TYPES
)
4513 string_append (declp
, ", ");
4514 if (!do_arg (work
, mangled
, &arg
))
4516 if (PRINT_ARG_TYPES
)
4517 string_appends (declp
, &arg
);
4518 string_delete (&arg
);
4523 if (**mangled
== 'e')
4526 if (PRINT_ARG_TYPES
)
4530 string_append (declp
, ",");
4532 string_append (declp
, "...");
4536 if (PRINT_ARG_TYPES
)
4538 string_append (declp
, ")");
4543 /* Like demangle_args, but for demangling the argument lists of function
4544 and method pointers or references, not top-level declarations. */
4547 demangle_nested_args (struct work_stuff
*work
, const char **mangled
,
4550 string
* saved_previous_argument
;
4554 /* The G++ name-mangling algorithm does not remember types on nested
4555 argument lists, unless -fsquangling is used, and in that case the
4556 type vector updated by remember_type is not used. So, we turn
4557 off remembering of types here. */
4558 ++work
->forgetting_types
;
4560 /* For the repeat codes used with -fsquangling, we must keep track of
4561 the last argument. */
4562 saved_previous_argument
= work
->previous_argument
;
4563 saved_nrepeats
= work
->nrepeats
;
4564 work
->previous_argument
= 0;
4567 /* Actually demangle the arguments. */
4568 result
= demangle_args (work
, mangled
, declp
);
4570 /* Restore the previous_argument field. */
4571 if (work
->previous_argument
)
4573 string_delete (work
->previous_argument
);
4574 free ((char *) work
->previous_argument
);
4576 work
->previous_argument
= saved_previous_argument
;
4577 --work
->forgetting_types
;
4578 work
->nrepeats
= saved_nrepeats
;
4583 /* Returns 1 if a valid function name was found or 0 otherwise. */
4586 demangle_function_name (struct work_stuff
*work
, const char **mangled
,
4587 string
*declp
, const char *scan
)
4593 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4594 string_need (declp
, 1);
4595 *(declp
-> p
) = '\0';
4597 /* Consume the function name, including the "__" separating the name
4598 from the signature. We are guaranteed that SCAN points to the
4601 (*mangled
) = scan
+ 2;
4602 /* We may be looking at an instantiation of a template function:
4603 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4604 following _F marks the start of the function arguments. Handle
4605 the template arguments first. */
4607 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4609 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4610 /* This leaves MANGLED pointing to the 'F' marking func args */
4613 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4616 /* See if we have an ARM style constructor or destructor operator.
4617 If so, then just record it, clear the decl, and return.
4618 We can't build the actual constructor/destructor decl until later,
4619 when we recover the class name from the signature. */
4621 if (strcmp (declp
-> b
, "__ct") == 0)
4623 work
-> constructor
+= 1;
4624 string_clear (declp
);
4627 else if (strcmp (declp
-> b
, "__dt") == 0)
4629 work
-> destructor
+= 1;
4630 string_clear (declp
);
4635 if (declp
->p
- declp
->b
>= 3
4636 && declp
->b
[0] == 'o'
4637 && declp
->b
[1] == 'p'
4638 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4640 /* see if it's an assignment expression */
4641 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4642 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4644 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4646 int len
= declp
->p
- declp
->b
- 10;
4647 if ((int) strlen (optable
[i
].in
) == len
4648 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4650 string_clear (declp
);
4651 string_append (declp
, "operator");
4652 string_append (declp
, optable
[i
].out
);
4653 string_append (declp
, "=");
4660 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4662 int len
= declp
->p
- declp
->b
- 3;
4663 if ((int) strlen (optable
[i
].in
) == len
4664 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4666 string_clear (declp
);
4667 string_append (declp
, "operator");
4668 string_append (declp
, optable
[i
].out
);
4674 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4675 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4677 /* type conversion operator */
4679 if (do_type (work
, &tem
, &type
))
4681 string_clear (declp
);
4682 string_append (declp
, "operator ");
4683 string_appends (declp
, &type
);
4684 string_delete (&type
);
4687 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4688 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4691 /* type conversion operator. */
4693 if (do_type (work
, &tem
, &type
))
4695 string_clear (declp
);
4696 string_append (declp
, "operator ");
4697 string_appends (declp
, &type
);
4698 string_delete (&type
);
4701 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4702 && ISLOWER((unsigned char)declp
->b
[2])
4703 && ISLOWER((unsigned char)declp
->b
[3]))
4705 if (declp
->b
[4] == '\0')
4708 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4710 if (strlen (optable
[i
].in
) == 2
4711 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4713 string_clear (declp
);
4714 string_append (declp
, "operator");
4715 string_append (declp
, optable
[i
].out
);
4722 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4725 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4727 if (strlen (optable
[i
].in
) == 3
4728 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4730 string_clear (declp
);
4731 string_append (declp
, "operator");
4732 string_append (declp
, optable
[i
].out
);
4740 /* If a function name was obtained but it's not valid, we were not
4742 if (LEN_STRING (declp
) == 1 && declp
->b
[0] == '.')
4748 /* a mini string-handling package */
4751 string_need (string
*s
, int n
)
4761 s
->p
= s
->b
= XNEWVEC (char, n
);
4764 else if (s
->e
- s
->p
< n
)
4769 s
->b
= XRESIZEVEC (char, s
->b
, n
);
4776 string_delete (string
*s
)
4781 s
->b
= s
->e
= s
->p
= NULL
;
4786 string_init (string
*s
)
4788 s
->b
= s
->p
= s
->e
= NULL
;
4792 string_clear (string
*s
)
4800 string_empty (string
*s
)
4802 return (s
->b
== s
->p
);
4808 string_append (string
*p
, const char *s
)
4811 if (s
== NULL
|| *s
== '\0')
4815 memcpy (p
->p
, s
, n
);
4820 string_appends (string
*p
, string
*s
)
4828 memcpy (p
->p
, s
->b
, n
);
4834 string_appendn (string
*p
, const char *s
, int n
)
4839 memcpy (p
->p
, s
, n
);
4845 string_prepend (string
*p
, const char *s
)
4847 if (s
!= NULL
&& *s
!= '\0')
4849 string_prependn (p
, s
, strlen (s
));
4854 string_prepends (string
*p
, string
*s
)
4858 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4863 string_prependn (string
*p
, const char *s
, int n
)
4870 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4874 memcpy (p
->b
, s
, n
);
4880 string_append_template_idx (string
*s
, int idx
)
4882 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4883 sprintf(buf
, "T%d", idx
);
4884 string_append (s
, buf
);