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 NULL
, unknown_demangling
, NULL
313 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
314 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
315 string_append(str, " ");}
316 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
318 /* The scope separator appropriate for the language being demangled. */
320 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
322 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
323 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
325 /* Prototypes for local functions */
327 static void delete_work_stuff (struct work_stuff
*);
329 static void delete_non_B_K_work_stuff (struct work_stuff
*);
331 static char *mop_up (struct work_stuff
*, string
*, int);
333 static void squangle_mop_up (struct work_stuff
*);
335 static void work_stuff_copy_to_from (struct work_stuff
*, struct work_stuff
*);
339 demangle_method_args (struct work_stuff
*, const char **, string
*);
343 internal_cplus_demangle (struct work_stuff
*, const char *);
346 demangle_template_template_parm (struct work_stuff
*work
,
347 const char **, string
*);
350 demangle_template (struct work_stuff
*work
, const char **, string
*,
354 arm_pt (struct work_stuff
*, const char *, int, const char **,
358 demangle_class_name (struct work_stuff
*, const char **, string
*);
361 demangle_qualified (struct work_stuff
*, const char **, string
*,
364 static int demangle_class (struct work_stuff
*, const char **, string
*);
366 static int demangle_fund_type (struct work_stuff
*, const char **, string
*);
368 static int demangle_signature (struct work_stuff
*, const char **, string
*);
370 static int demangle_prefix (struct work_stuff
*, const char **, string
*);
372 static int gnu_special (struct work_stuff
*, const char **, string
*);
374 static int arm_special (const char **, string
*);
376 static void string_need (string
*, int);
378 static void string_delete (string
*);
381 string_init (string
*);
383 static void string_clear (string
*);
386 static int string_empty (string
*);
389 static void string_append (string
*, const char *);
391 static void string_appends (string
*, string
*);
393 static void string_appendn (string
*, const char *, int);
395 static void string_prepend (string
*, const char *);
397 static void string_prependn (string
*, const char *, int);
399 static void string_append_template_idx (string
*, int);
401 static int get_count (const char **, int *);
403 static int consume_count (const char **);
405 static int consume_count_with_underscores (const char**);
407 static int demangle_args (struct work_stuff
*, const char **, string
*);
409 static int demangle_nested_args (struct work_stuff
*, const char**, string
*);
411 static int do_type (struct work_stuff
*, const char **, string
*);
413 static int do_arg (struct work_stuff
*, const char **, string
*);
416 demangle_function_name (struct work_stuff
*, const char **, string
*,
420 iterate_demangle_function (struct work_stuff
*,
421 const char **, string
*, const char *);
423 static void remember_type (struct work_stuff
*, const char *, int);
425 static void remember_Btype (struct work_stuff
*, const char *, int, int);
427 static int register_Btype (struct work_stuff
*);
429 static void remember_Ktype (struct work_stuff
*, const char *, int);
431 static void forget_types (struct work_stuff
*);
433 static void forget_B_and_K_types (struct work_stuff
*);
435 static void string_prepends (string
*, string
*);
438 demangle_template_value_parm (struct work_stuff
*, const char**,
439 string
*, type_kind_t
);
442 do_hpacc_template_const_value (struct work_stuff
*, const char **, string
*);
445 do_hpacc_template_literal (struct work_stuff
*, const char **, string
*);
447 static int snarf_numeric_literal (const char **, string
*);
449 /* There is a TYPE_QUAL value for each type qualifier. They can be
450 combined by bitwise-or to form the complete set of qualifiers for a
453 #define TYPE_UNQUALIFIED 0x0
454 #define TYPE_QUAL_CONST 0x1
455 #define TYPE_QUAL_VOLATILE 0x2
456 #define TYPE_QUAL_RESTRICT 0x4
458 static int code_for_qualifier (int);
460 static const char* qualifier_string (int);
462 static const char* demangle_qualifier (int);
464 static int demangle_expression (struct work_stuff
*, const char **, string
*,
468 demangle_integral_value (struct work_stuff
*, const char **, string
*);
471 demangle_real_value (struct work_stuff
*, const char **, string
*);
474 demangle_arm_hp_template (struct work_stuff
*, const char **, int, string
*);
477 recursively_demangle (struct work_stuff
*, const char **, string
*, int);
479 /* Translate count to integer, consuming tokens in the process.
480 Conversion terminates on the first non-digit character.
482 Trying to consume something that isn't a count results in no
483 consumption of input and a return of -1.
485 Overflow consumes the rest of the digits, and returns -1. */
488 consume_count (const char **type
)
492 if (! ISDIGIT ((unsigned char)**type
))
495 while (ISDIGIT ((unsigned char)**type
))
499 /* Check for overflow.
500 We assume that count is represented using two's-complement;
501 no power of two is divisible by ten, so if an overflow occurs
502 when multiplying by ten, the result will not be a multiple of
504 if ((count
% 10) != 0)
506 while (ISDIGIT ((unsigned char) **type
))
511 count
+= **type
- '0';
522 /* Like consume_count, but for counts that are preceded and followed
523 by '_' if they are greater than 10. Also, -1 is returned for
524 failure, since 0 can be a valid value. */
527 consume_count_with_underscores (const char **mangled
)
531 if (**mangled
== '_')
534 if (!ISDIGIT ((unsigned char)**mangled
))
537 idx
= consume_count (mangled
);
538 if (**mangled
!= '_')
539 /* The trailing underscore was missing. */
546 if (**mangled
< '0' || **mangled
> '9')
549 idx
= **mangled
- '0';
556 /* C is the code for a type-qualifier. Return the TYPE_QUAL
557 corresponding to this qualifier. */
560 code_for_qualifier (int c
)
565 return TYPE_QUAL_CONST
;
568 return TYPE_QUAL_VOLATILE
;
571 return TYPE_QUAL_RESTRICT
;
577 /* C was an invalid qualifier. */
581 /* Return the string corresponding to the qualifiers given by
585 qualifier_string (int type_quals
)
589 case TYPE_UNQUALIFIED
:
592 case TYPE_QUAL_CONST
:
595 case TYPE_QUAL_VOLATILE
:
598 case TYPE_QUAL_RESTRICT
:
601 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
:
602 return "const volatile";
604 case TYPE_QUAL_CONST
| TYPE_QUAL_RESTRICT
:
605 return "const __restrict";
607 case TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
608 return "volatile __restrict";
610 case TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT
:
611 return "const volatile __restrict";
617 /* TYPE_QUALS was an invalid qualifier set. */
621 /* C is the code for a type-qualifier. Return the string
622 corresponding to this qualifier. This function should only be
623 called with a valid qualifier code. */
626 demangle_qualifier (int c
)
628 return qualifier_string (code_for_qualifier (c
));
632 cplus_demangle_opname (const char *opname
, char *result
, int options
)
636 struct work_stuff work
[1];
639 len
= strlen(opname
);
642 memset ((char *) work
, 0, sizeof (work
));
643 work
->options
= options
;
645 if (opname
[0] == '_' && opname
[1] == '_'
646 && opname
[2] == 'o' && opname
[3] == 'p')
649 /* type conversion operator. */
651 if (do_type (work
, &tem
, &type
))
653 strcat (result
, "operator ");
654 strncat (result
, type
.b
, type
.p
- type
.b
);
655 string_delete (&type
);
659 else if (opname
[0] == '_' && opname
[1] == '_'
660 && ISLOWER((unsigned char)opname
[2])
661 && ISLOWER((unsigned char)opname
[3]))
663 if (opname
[4] == '\0')
667 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
669 if (strlen (optable
[i
].in
) == 2
670 && memcmp (optable
[i
].in
, opname
+ 2, 2) == 0)
672 strcat (result
, "operator");
673 strcat (result
, optable
[i
].out
);
681 if (opname
[2] == 'a' && opname
[5] == '\0')
685 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
687 if (strlen (optable
[i
].in
) == 3
688 && memcmp (optable
[i
].in
, opname
+ 2, 3) == 0)
690 strcat (result
, "operator");
691 strcat (result
, optable
[i
].out
);
702 && strchr (cplus_markers
, opname
[2]) != NULL
)
704 /* see if it's an assignment expression */
705 if (len
>= 10 /* op$assign_ */
706 && memcmp (opname
+ 3, "assign_", 7) == 0)
709 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
712 if ((int) strlen (optable
[i
].in
) == len1
713 && memcmp (optable
[i
].in
, opname
+ 10, len1
) == 0)
715 strcat (result
, "operator");
716 strcat (result
, optable
[i
].out
);
717 strcat (result
, "=");
726 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
729 if ((int) strlen (optable
[i
].in
) == len1
730 && memcmp (optable
[i
].in
, opname
+ 3, len1
) == 0)
732 strcat (result
, "operator");
733 strcat (result
, optable
[i
].out
);
740 else if (len
>= 5 && memcmp (opname
, "type", 4) == 0
741 && strchr (cplus_markers
, opname
[4]) != NULL
)
743 /* type conversion operator */
745 if (do_type (work
, &tem
, &type
))
747 strcat (result
, "operator ");
748 strncat (result
, type
.b
, type
.p
- type
.b
);
749 string_delete (&type
);
753 squangle_mop_up (work
);
758 /* Takes operator name as e.g. "++" and returns mangled
759 operator name (e.g. "postincrement_expr"), or NULL if not found.
761 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
762 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
765 cplus_mangle_opname (const char *opname
, int options
)
770 len
= strlen (opname
);
771 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
773 if ((int) strlen (optable
[i
].out
) == len
774 && (options
& DMGL_ANSI
) == (optable
[i
].flags
& DMGL_ANSI
)
775 && memcmp (optable
[i
].out
, opname
, len
) == 0)
776 return optable
[i
].in
;
781 /* Add a routine to set the demangling style to be sure it is valid and
782 allow for any demangler initialization that maybe necessary. */
784 enum demangling_styles
785 cplus_demangle_set_style (enum demangling_styles style
)
787 const struct demangler_engine
*demangler
= libiberty_demanglers
;
789 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
790 if (style
== demangler
->demangling_style
)
792 current_demangling_style
= style
;
793 return current_demangling_style
;
796 return unknown_demangling
;
799 /* Do string name to style translation */
801 enum demangling_styles
802 cplus_demangle_name_to_style (const char *name
)
804 const struct demangler_engine
*demangler
= libiberty_demanglers
;
806 for (; demangler
->demangling_style
!= unknown_demangling
; ++demangler
)
807 if (strcmp (name
, demangler
->demangling_style_name
) == 0)
808 return demangler
->demangling_style
;
810 return unknown_demangling
;
813 /* char *cplus_demangle (const char *mangled, int options)
815 If MANGLED is a mangled function name produced by GNU C++, then
816 a pointer to a @code{malloc}ed string giving a C++ representation
817 of the name will be returned; otherwise NULL will be returned.
818 It is the caller's responsibility to free the string which
821 The OPTIONS arg may contain one or more of the following bits:
823 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
825 DMGL_PARAMS Function parameters are included.
829 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
830 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
831 cplus_demangle ("foo__1Ai", 0) => "A::foo"
833 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
834 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
835 cplus_demangle ("foo__1Afe", 0) => "A::foo"
837 Note that any leading underscores, or other such characters prepended by
838 the compilation system, are presumed to have already been stripped from
842 cplus_demangle (const char *mangled
, int options
)
845 struct work_stuff work
[1];
847 if (current_demangling_style
== no_demangling
)
848 return xstrdup (mangled
);
850 memset ((char *) work
, 0, sizeof (work
));
851 work
->options
= options
;
852 if ((work
->options
& DMGL_STYLE_MASK
) == 0)
853 work
->options
|= (int) current_demangling_style
& DMGL_STYLE_MASK
;
855 /* The V3 ABI demangling is implemented elsewhere. */
856 if (GNU_V3_DEMANGLING
|| AUTO_DEMANGLING
)
858 ret
= cplus_demangle_v3 (mangled
, work
->options
);
859 if (ret
|| GNU_V3_DEMANGLING
)
865 ret
= java_demangle_v3 (mangled
);
871 return ada_demangle (mangled
, options
);
873 ret
= internal_cplus_demangle (work
, mangled
);
874 squangle_mop_up (work
);
878 /* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
881 ada_demangle (const char *mangled
, int option ATTRIBUTE_UNUSED
)
886 char *demangled
= NULL
;
888 /* Discard leading _ada_, which is used for library level subprograms. */
889 if (strncmp (mangled
, "_ada_", 5) == 0)
892 /* All ada unit names are lower-case. */
893 if (!ISLOWER (mangled
[0]))
896 /* Most of the demangling will trivially remove chars. Operator names
897 may add one char but because they are always preceeded by '__' which is
898 replaced by '.', they eventually never expand the size.
899 A few special names such as '___elabs' add a few chars (at most 7), but
900 they occur only once. */
901 len0
= strlen (mangled
) + 7 + 1;
902 demangled
= XNEWVEC (char, len0
);
908 /* An entity names is expected. */
911 /* An identifier, which is always lower case. */
914 while (ISLOWER(*p
) || ISDIGIT (*p
)
915 || (p
[0] == '_' && (ISLOWER (p
[1]) || ISDIGIT (p
[1]))));
917 else if (p
[0] == 'O')
919 /* An operator name. */
920 static const char * const operators
[][2] =
921 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
922 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
923 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
924 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
925 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
926 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
927 {"Oexpon", "**"}, {NULL
, NULL
}};
930 for (k
= 0; operators
[k
][0] != NULL
; k
++)
932 size_t slen
= strlen (operators
[k
][0]);
933 if (strncmp (p
, operators
[k
][0], slen
) == 0)
936 slen
= strlen (operators
[k
][1]);
938 memcpy (d
, operators
[k
][1], slen
);
944 /* Operator not found. */
945 if (operators
[k
][0] == NULL
)
950 /* Not a GNAT encoding. */
954 /* The name can be directly followed by some uppercase letters. */
955 if (p
[0] == 'T' && p
[1] == 'K')
958 if (p
[2] == 'B' && p
[3] == 0)
960 /* Subprogram for task body. */
963 else if (p
[2] == '_' && p
[3] == '_')
965 /* Inner declarations in a task. */
973 if (p
[0] == 'E' && p
[1] == 0)
975 /* Exception name. */
978 if ((p
[0] == 'P' || p
[0] == 'N') && p
[1] == 0)
980 /* Protected type subprogram. */
983 if ((*p
== 'N' || *p
== 'S') && p
[1] == 0)
985 /* Enumerated type name table. */
992 while (p
[0] == 'n' || p
[0] == 'b')
995 if (p
[0] == 'S' && p
[1] != 0 && (p
[2] == '_' || p
[2] == 0))
997 /* Stream operations. */
1020 else if (p
[0] == 'D')
1022 /* Controlled type operation. */
1045 /* Standard separator. Handled first. */
1050 /* Overloading number. */
1053 while (ISDIGIT (*p
) || (p
[0] == '_' && ISDIGIT (p
[1])));
1057 while (p
[0] == 'n' || p
[0] == 'b')
1061 else if (p
[0] == '_' && p
[1] != '_')
1063 /* Special names. */
1064 static const char * const special
[][2] = {
1065 { "_elabb", "'Elab_Body" },
1066 { "_elabs", "'Elab_Spec" },
1067 { "_size", "'Size" },
1068 { "_alignment", "'Alignment" },
1069 { "_assign", ".\":=\"" },
1074 for (k
= 0; special
[k
][0] != NULL
; k
++)
1076 size_t slen
= strlen (special
[k
][0]);
1077 if (strncmp (p
, special
[k
][0], slen
) == 0)
1080 slen
= strlen (special
[k
][1]);
1081 memcpy (d
, special
[k
][1], slen
);
1086 if (special
[k
][0] != NULL
)
1097 else if (p
[1] == 'B' || p
[1] == 'E')
1099 /* Entry Body or barrier Evaluation. */
1101 while (ISDIGIT (*p
))
1103 if (p
[0] == 's' && p
[1] == 0)
1112 if (p
[0] == '.' && ISDIGIT (p
[1]))
1114 /* Nested subprogram. */
1116 while (ISDIGIT (*p
))
1121 /* End of mangled name. */
1131 len0
= strlen (mangled
);
1133 demangled
= XNEWVEC (char, len0
+ 3);
1135 if (mangled
[0] == '<')
1136 strcpy (demangled
, mangled
);
1138 sprintf (demangled
, "<%s>", mangled
);
1143 /* This function performs most of what cplus_demangle use to do, but
1144 to be able to demangle a name with a B, K or n code, we need to
1145 have a longer term memory of what types have been seen. The original
1146 now initializes and cleans up the squangle code info, while internal
1147 calls go directly to this routine to avoid resetting that info. */
1150 internal_cplus_demangle (struct work_stuff
*work
, const char *mangled
)
1155 char *demangled
= NULL
;
1157 s1
= work
->constructor
;
1158 s2
= work
->destructor
;
1159 s3
= work
->static_type
;
1160 s4
= work
->type_quals
;
1161 work
->constructor
= work
->destructor
= 0;
1162 work
->type_quals
= TYPE_UNQUALIFIED
;
1163 work
->dllimported
= 0;
1165 if ((mangled
!= NULL
) && (*mangled
!= '\0'))
1167 string_init (&decl
);
1169 /* First check to see if gnu style demangling is active and if the
1170 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1171 recognize one of the gnu special forms rather than looking for a
1172 standard prefix. In particular, don't worry about whether there
1173 is a "__" string in the mangled string. Consider "_$_5__foo" for
1176 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
))
1178 success
= gnu_special (work
, &mangled
, &decl
);
1182 success
= demangle_prefix (work
, &mangled
, &decl
);
1184 if (success
&& (*mangled
!= '\0'))
1186 success
= demangle_signature (work
, &mangled
, &decl
);
1188 if (work
->constructor
== 2)
1190 string_prepend (&decl
, "global constructors keyed to ");
1191 work
->constructor
= 0;
1193 else if (work
->destructor
== 2)
1195 string_prepend (&decl
, "global destructors keyed to ");
1196 work
->destructor
= 0;
1198 else if (work
->dllimported
== 1)
1200 string_prepend (&decl
, "import stub for ");
1201 work
->dllimported
= 0;
1203 demangled
= mop_up (work
, &decl
, success
);
1205 work
->constructor
= s1
;
1206 work
->destructor
= s2
;
1207 work
->static_type
= s3
;
1208 work
->type_quals
= s4
;
1213 /* Clear out and squangling related storage */
1215 squangle_mop_up (struct work_stuff
*work
)
1217 /* clean up the B and K type mangling types. */
1218 forget_B_and_K_types (work
);
1219 if (work
-> btypevec
!= NULL
)
1221 free ((char *) work
-> btypevec
);
1223 if (work
-> ktypevec
!= NULL
)
1225 free ((char *) work
-> ktypevec
);
1230 /* Copy the work state and storage. */
1233 work_stuff_copy_to_from (struct work_stuff
*to
, struct work_stuff
*from
)
1237 delete_work_stuff (to
);
1239 /* Shallow-copy scalars. */
1240 memcpy (to
, from
, sizeof (*to
));
1242 /* Deep-copy dynamic storage. */
1243 if (from
->typevec_size
)
1244 to
->typevec
= XNEWVEC (char *, from
->typevec_size
);
1246 for (i
= 0; i
< from
->ntypes
; i
++)
1248 int len
= strlen (from
->typevec
[i
]) + 1;
1250 to
->typevec
[i
] = XNEWVEC (char, len
);
1251 memcpy (to
->typevec
[i
], from
->typevec
[i
], len
);
1255 to
->ktypevec
= XNEWVEC (char *, from
->ksize
);
1257 for (i
= 0; i
< from
->numk
; i
++)
1259 int len
= strlen (from
->ktypevec
[i
]) + 1;
1261 to
->ktypevec
[i
] = XNEWVEC (char, len
);
1262 memcpy (to
->ktypevec
[i
], from
->ktypevec
[i
], len
);
1266 to
->btypevec
= XNEWVEC (char *, from
->bsize
);
1268 for (i
= 0; i
< from
->numb
; i
++)
1270 int len
= strlen (from
->btypevec
[i
]) + 1;
1272 to
->btypevec
[i
] = XNEWVEC (char , len
);
1273 memcpy (to
->btypevec
[i
], from
->btypevec
[i
], len
);
1276 if (from
->ntmpl_args
)
1277 to
->tmpl_argvec
= XNEWVEC (char *, from
->ntmpl_args
);
1279 for (i
= 0; i
< from
->ntmpl_args
; i
++)
1281 int len
= strlen (from
->tmpl_argvec
[i
]) + 1;
1283 to
->tmpl_argvec
[i
] = XNEWVEC (char, len
);
1284 memcpy (to
->tmpl_argvec
[i
], from
->tmpl_argvec
[i
], len
);
1287 if (from
->previous_argument
)
1289 to
->previous_argument
= XNEW (string
);
1290 string_init (to
->previous_argument
);
1291 string_appends (to
->previous_argument
, from
->previous_argument
);
1296 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1299 delete_non_B_K_work_stuff (struct work_stuff
*work
)
1301 /* Discard the remembered types, if any. */
1303 forget_types (work
);
1304 if (work
-> typevec
!= NULL
)
1306 free ((char *) work
-> typevec
);
1307 work
-> typevec
= NULL
;
1308 work
-> typevec_size
= 0;
1310 if (work
->tmpl_argvec
)
1314 for (i
= 0; i
< work
->ntmpl_args
; i
++)
1315 if (work
->tmpl_argvec
[i
])
1316 free ((char*) work
->tmpl_argvec
[i
]);
1318 free ((char*) work
->tmpl_argvec
);
1319 work
->tmpl_argvec
= NULL
;
1321 if (work
->previous_argument
)
1323 string_delete (work
->previous_argument
);
1324 free ((char*) work
->previous_argument
);
1325 work
->previous_argument
= NULL
;
1330 /* Delete all dynamic storage in work_stuff. */
1332 delete_work_stuff (struct work_stuff
*work
)
1334 delete_non_B_K_work_stuff (work
);
1335 squangle_mop_up (work
);
1339 /* Clear out any mangled storage */
1342 mop_up (struct work_stuff
*work
, string
*declp
, int success
)
1344 char *demangled
= NULL
;
1346 delete_non_B_K_work_stuff (work
);
1348 /* If demangling was successful, ensure that the demangled string is null
1349 terminated and return it. Otherwise, free the demangling decl. */
1353 string_delete (declp
);
1357 string_appendn (declp
, "", 1);
1358 demangled
= declp
->b
;
1367 demangle_signature -- demangle the signature part of a mangled name
1372 demangle_signature (struct work_stuff *work, const char **mangled,
1377 Consume and demangle the signature portion of the mangled name.
1379 DECLP is the string where demangled output is being built. At
1380 entry it contains the demangled root name from the mangled name
1381 prefix. I.E. either a demangled operator name or the root function
1382 name. In some special cases, it may contain nothing.
1384 *MANGLED points to the current unconsumed location in the mangled
1385 name. As tokens are consumed and demangling is performed, the
1386 pointer is updated to continuously point at the next token to
1389 Demangling GNU style mangled names is nasty because there is no
1390 explicit token that marks the start of the outermost function
1394 demangle_signature (struct work_stuff
*work
,
1395 const char **mangled
, string
*declp
)
1399 int expect_func
= 0;
1400 int expect_return_type
= 0;
1401 const char *oldmangled
= NULL
;
1405 while (success
&& (**mangled
!= '\0'))
1410 oldmangled
= *mangled
;
1411 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1413 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1414 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1420 oldmangled
= *mangled
;
1421 success
= demangle_qualified (work
, mangled
, declp
, 1, 0);
1422 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1430 /* Static member function */
1431 if (oldmangled
== NULL
)
1433 oldmangled
= *mangled
;
1436 work
-> static_type
= 1;
1442 work
->type_quals
|= code_for_qualifier (**mangled
);
1444 /* a qualified member function */
1445 if (oldmangled
== NULL
)
1446 oldmangled
= *mangled
;
1451 /* Local class name follows after "Lnnn_" */
1454 while (**mangled
&& (**mangled
!= '_'))
1465 case '0': case '1': case '2': case '3': case '4':
1466 case '5': case '6': case '7': case '8': case '9':
1467 if (oldmangled
== NULL
)
1469 oldmangled
= *mangled
;
1471 work
->temp_start
= -1; /* uppermost call to demangle_class */
1472 success
= demangle_class (work
, mangled
, declp
);
1475 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1477 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
|| EDG_DEMANGLING
)
1479 /* EDG and others will have the "F", so we let the loop cycle
1480 if we are looking at one. */
1481 if (**mangled
!= 'F')
1490 success
= do_type (work
, mangled
, &s
);
1493 string_append (&s
, SCOPE_STRING (work
));
1494 string_prepends (declp
, &s
);
1504 /* ARM/HP style demangling includes a specific 'F' character after
1505 the class name. For GNU style, it is just implied. So we can
1506 safely just consume any 'F' at this point and be compatible
1507 with either style. */
1513 /* For lucid/ARM/HP style we have to forget any types we might
1514 have remembered up to this point, since they were not argument
1515 types. GNU style considers all types seen as available for
1516 back references. See comment in demangle_args() */
1518 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
1520 forget_types (work
);
1522 success
= demangle_args (work
, mangled
, declp
);
1523 /* After picking off the function args, we expect to either
1524 find the function return type (preceded by an '_') or the
1525 end of the string. */
1526 if (success
&& (AUTO_DEMANGLING
|| EDG_DEMANGLING
) && **mangled
== '_')
1529 /* At this level, we do not care about the return type. */
1530 success
= do_type (work
, mangled
, &tname
);
1531 string_delete (&tname
);
1538 string_init(&trawname
);
1539 string_init(&tname
);
1540 if (oldmangled
== NULL
)
1542 oldmangled
= *mangled
;
1544 success
= demangle_template (work
, mangled
, &tname
,
1548 remember_type (work
, oldmangled
, *mangled
- oldmangled
);
1550 string_append (&tname
, SCOPE_STRING (work
));
1552 string_prepends(declp
, &tname
);
1553 if (work
-> destructor
& 1)
1555 string_prepend (&trawname
, "~");
1556 string_appends (declp
, &trawname
);
1557 work
->destructor
-= 1;
1559 if ((work
->constructor
& 1) || (work
->destructor
& 1))
1561 string_appends (declp
, &trawname
);
1562 work
->constructor
-= 1;
1564 string_delete(&trawname
);
1565 string_delete(&tname
);
1571 if ((AUTO_DEMANGLING
|| GNU_DEMANGLING
) && expect_return_type
)
1573 /* Read the return type. */
1577 success
= do_type (work
, mangled
, &return_type
);
1578 APPEND_BLANK (&return_type
);
1580 string_prepends (declp
, &return_type
);
1581 string_delete (&return_type
);
1585 /* At the outermost level, we cannot have a return type specified,
1586 so if we run into another '_' at this point we are dealing with
1587 a mangled name that is either bogus, or has been mangled by
1588 some algorithm we don't know how to deal with. So just
1589 reject the entire demangling. */
1590 /* However, "_nnn" is an expected suffix for alternate entry point
1591 numbered nnn for a function, with HP aCC, so skip over that
1592 without reporting failure. pai/1997-09-04 */
1596 while (**mangled
&& ISDIGIT ((unsigned char)**mangled
))
1604 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1606 /* A G++ template function. Read the template arguments. */
1607 success
= demangle_template (work
, mangled
, declp
, 0, 0,
1609 if (!(work
->constructor
& 1))
1610 expect_return_type
= 1;
1619 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1621 /* Assume we have stumbled onto the first outermost function
1622 argument token, and start processing args. */
1624 success
= demangle_args (work
, mangled
, declp
);
1628 /* Non-GNU demanglers use a specific token to mark the start
1629 of the outermost function argument tokens. Typically 'F',
1630 for ARM/HP-demangling, for example. So if we find something
1631 we are not prepared for, it must be an error. */
1637 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1640 if (success
&& expect_func
)
1643 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
)
1645 forget_types (work
);
1647 success
= demangle_args (work
, mangled
, declp
);
1648 /* Since template include the mangling of their return types,
1649 we must set expect_func to 0 so that we don't try do
1650 demangle more arguments the next time we get here. */
1655 if (success
&& !func_done
)
1657 if (AUTO_DEMANGLING
|| GNU_DEMANGLING
)
1659 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1660 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1661 first case, and need to ensure that the '(void)' gets added to
1662 the current declp. Note that with ARM/HP, the first case
1663 represents the name of a static data member 'foo::bar',
1664 which is in the current declp, so we leave it alone. */
1665 success
= demangle_args (work
, mangled
, declp
);
1668 if (success
&& PRINT_ARG_TYPES
)
1670 if (work
->static_type
)
1671 string_append (declp
, " static");
1672 if (work
->type_quals
!= TYPE_UNQUALIFIED
)
1674 APPEND_BLANK (declp
);
1675 string_append (declp
, qualifier_string (work
->type_quals
));
1685 demangle_method_args (struct work_stuff
*work
, const char **mangled
,
1690 if (work
-> static_type
)
1692 string_append (declp
, *mangled
+ 1);
1693 *mangled
+= strlen (*mangled
);
1698 success
= demangle_args (work
, mangled
, declp
);
1706 demangle_template_template_parm (struct work_stuff
*work
,
1707 const char **mangled
, string
*tname
)
1715 string_append (tname
, "template <");
1716 /* get size of template parameter list */
1717 if (get_count (mangled
, &r
))
1719 for (i
= 0; i
< r
; i
++)
1723 string_append (tname
, ", ");
1726 /* Z for type parameters */
1727 if (**mangled
== 'Z')
1730 string_append (tname
, "class");
1732 /* z for template parameters */
1733 else if (**mangled
== 'z')
1737 demangle_template_template_parm (work
, mangled
, tname
);
1745 /* temp is initialized in do_type */
1746 success
= do_type (work
, mangled
, &temp
);
1749 string_appends (tname
, &temp
);
1751 string_delete(&temp
);
1761 if (tname
->p
[-1] == '>')
1762 string_append (tname
, " ");
1763 string_append (tname
, "> class");
1768 demangle_expression (struct work_stuff
*work
, const char **mangled
,
1769 string
*s
, type_kind_t tk
)
1771 int need_operator
= 0;
1775 string_appendn (s
, "(", 1);
1777 while (success
&& **mangled
!= 'W' && **mangled
!= '\0')
1786 len
= strlen (*mangled
);
1788 for (i
= 0; i
< ARRAY_SIZE (optable
); ++i
)
1790 size_t l
= strlen (optable
[i
].in
);
1793 && memcmp (optable
[i
].in
, *mangled
, l
) == 0)
1795 string_appendn (s
, " ", 1);
1796 string_append (s
, optable
[i
].out
);
1797 string_appendn (s
, " ", 1);
1810 success
= demangle_template_value_parm (work
, mangled
, s
, tk
);
1813 if (**mangled
!= 'W')
1817 string_appendn (s
, ")", 1);
1825 demangle_integral_value (struct work_stuff
*work
,
1826 const char **mangled
, string
*s
)
1830 if (**mangled
== 'E')
1831 success
= demangle_expression (work
, mangled
, s
, tk_integral
);
1832 else if (**mangled
== 'Q' || **mangled
== 'K')
1833 success
= demangle_qualified (work
, mangled
, s
, 0, 1);
1838 /* By default, we let the number decide whether we shall consume an
1840 int multidigit_without_leading_underscore
= 0;
1841 int leave_following_underscore
= 0;
1845 if (**mangled
== '_')
1847 if (mangled
[0][1] == 'm')
1849 /* Since consume_count_with_underscores does not handle the
1850 `m'-prefix we must do it here, using consume_count and
1851 adjusting underscores: we have to consume the underscore
1852 matching the prepended one. */
1853 multidigit_without_leading_underscore
= 1;
1854 string_appendn (s
, "-", 1);
1859 /* Do not consume a following underscore;
1860 consume_count_with_underscores will consume what
1861 should be consumed. */
1862 leave_following_underscore
= 1;
1867 /* Negative numbers are indicated with a leading `m'. */
1868 if (**mangled
== 'm')
1870 string_appendn (s
, "-", 1);
1873 /* Since consume_count_with_underscores does not handle
1874 multi-digit numbers that do not start with an underscore,
1875 and this number can be an integer template parameter,
1876 we have to call consume_count. */
1877 multidigit_without_leading_underscore
= 1;
1878 /* These multi-digit numbers never end on an underscore,
1879 so if there is one then don't eat it. */
1880 leave_following_underscore
= 1;
1883 /* We must call consume_count if we expect to remove a trailing
1884 underscore, since consume_count_with_underscores expects
1885 the leading underscore (that we consumed) if it is to handle
1886 multi-digit numbers. */
1887 if (multidigit_without_leading_underscore
)
1888 value
= consume_count (mangled
);
1890 value
= consume_count_with_underscores (mangled
);
1894 char buf
[INTBUF_SIZE
];
1895 sprintf (buf
, "%d", value
);
1896 string_append (s
, buf
);
1898 /* Numbers not otherwise delimited, might have an underscore
1899 appended as a delimeter, which we should skip.
1901 ??? This used to always remove a following underscore, which
1902 is wrong. If other (arbitrary) cases are followed by an
1903 underscore, we need to do something more radical. */
1905 if ((value
> 9 || multidigit_without_leading_underscore
)
1906 && ! leave_following_underscore
1907 && **mangled
== '_')
1918 /* Demangle the real value in MANGLED. */
1921 demangle_real_value (struct work_stuff
*work
,
1922 const char **mangled
, string
*s
)
1924 if (**mangled
== 'E')
1925 return demangle_expression (work
, mangled
, s
, tk_real
);
1927 if (**mangled
== 'm')
1929 string_appendn (s
, "-", 1);
1932 while (ISDIGIT ((unsigned char)**mangled
))
1934 string_appendn (s
, *mangled
, 1);
1937 if (**mangled
== '.') /* fraction */
1939 string_appendn (s
, ".", 1);
1941 while (ISDIGIT ((unsigned char)**mangled
))
1943 string_appendn (s
, *mangled
, 1);
1947 if (**mangled
== 'e') /* exponent */
1949 string_appendn (s
, "e", 1);
1951 while (ISDIGIT ((unsigned char)**mangled
))
1953 string_appendn (s
, *mangled
, 1);
1962 demangle_template_value_parm (struct work_stuff
*work
, const char **mangled
,
1963 string
*s
, type_kind_t tk
)
1967 if (**mangled
== 'Y')
1969 /* The next argument is a template parameter. */
1973 idx
= consume_count_with_underscores (mangled
);
1975 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
1976 || consume_count_with_underscores (mangled
) == -1)
1978 if (work
->tmpl_argvec
)
1979 string_append (s
, work
->tmpl_argvec
[idx
]);
1981 string_append_template_idx (s
, idx
);
1983 else if (tk
== tk_integral
)
1984 success
= demangle_integral_value (work
, mangled
, s
);
1985 else if (tk
== tk_char
)
1989 if (**mangled
== 'm')
1991 string_appendn (s
, "-", 1);
1994 string_appendn (s
, "'", 1);
1995 val
= consume_count(mangled
);
2002 string_appendn (s
, &tmp
[0], 1);
2003 string_appendn (s
, "'", 1);
2006 else if (tk
== tk_bool
)
2008 int val
= consume_count (mangled
);
2010 string_appendn (s
, "false", 5);
2012 string_appendn (s
, "true", 4);
2016 else if (tk
== tk_real
)
2017 success
= demangle_real_value (work
, mangled
, s
);
2018 else if (tk
== tk_pointer
|| tk
== tk_reference
)
2020 if (**mangled
== 'Q')
2021 success
= demangle_qualified (work
, mangled
, s
,
2026 int symbol_len
= consume_count (mangled
);
2027 if (symbol_len
== -1)
2029 if (symbol_len
== 0)
2030 string_appendn (s
, "0", 1);
2033 char *p
= XNEWVEC (char, symbol_len
+ 1), *q
;
2034 strncpy (p
, *mangled
, symbol_len
);
2035 p
[symbol_len
] = '\0';
2036 /* We use cplus_demangle here, rather than
2037 internal_cplus_demangle, because the name of the entity
2038 mangled here does not make use of any of the squangling
2039 or type-code information we have built up thus far; it is
2040 mangled independently. */
2041 q
= cplus_demangle (p
, work
->options
);
2042 if (tk
== tk_pointer
)
2043 string_appendn (s
, "&", 1);
2044 /* FIXME: Pointer-to-member constants should get a
2045 qualifying class name here. */
2048 string_append (s
, q
);
2052 string_append (s
, p
);
2055 *mangled
+= symbol_len
;
2062 /* Demangle the template name in MANGLED. The full name of the
2063 template (e.g., S<int>) is placed in TNAME. The name without the
2064 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2065 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2066 not a function template. If both IS_TYPE and REMEMBER are nonzero,
2067 the template is remembered in the list of back-referenceable
2071 demangle_template (struct work_stuff
*work
, const char **mangled
,
2072 string
*tname
, string
*trawname
,
2073 int is_type
, int remember
)
2079 int is_java_array
= 0;
2085 /* get template name */
2086 if (**mangled
== 'z')
2092 idx
= consume_count_with_underscores (mangled
);
2094 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
2095 || consume_count_with_underscores (mangled
) == -1)
2098 if (work
->tmpl_argvec
)
2100 string_append (tname
, work
->tmpl_argvec
[idx
]);
2102 string_append (trawname
, work
->tmpl_argvec
[idx
]);
2106 string_append_template_idx (tname
, idx
);
2108 string_append_template_idx (trawname
, idx
);
2113 if ((r
= consume_count (mangled
)) <= 0
2114 || (int) strlen (*mangled
) < r
)
2118 is_java_array
= (work
-> options
& DMGL_JAVA
)
2119 && strncmp (*mangled
, "JArray1Z", 8) == 0;
2120 if (! is_java_array
)
2122 string_appendn (tname
, *mangled
, r
);
2125 string_appendn (trawname
, *mangled
, r
);
2130 string_append (tname
, "<");
2131 /* get size of template parameter list */
2132 if (!get_count (mangled
, &r
))
2138 /* Create an array for saving the template argument values. */
2139 work
->tmpl_argvec
= XNEWVEC (char *, r
);
2140 work
->ntmpl_args
= r
;
2141 for (i
= 0; i
< r
; i
++)
2142 work
->tmpl_argvec
[i
] = 0;
2144 for (i
= 0; i
< r
; i
++)
2148 string_append (tname
, ", ");
2150 /* Z for type parameters */
2151 if (**mangled
== 'Z')
2154 /* temp is initialized in do_type */
2155 success
= do_type (work
, mangled
, &temp
);
2158 string_appends (tname
, &temp
);
2162 /* Save the template argument. */
2163 int len
= temp
.p
- temp
.b
;
2164 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2165 memcpy (work
->tmpl_argvec
[i
], temp
.b
, len
);
2166 work
->tmpl_argvec
[i
][len
] = '\0';
2169 string_delete(&temp
);
2175 /* z for template parameters */
2176 else if (**mangled
== 'z')
2180 success
= demangle_template_template_parm (work
, mangled
, tname
);
2183 && (r2
= consume_count (mangled
)) > 0
2184 && (int) strlen (*mangled
) >= r2
)
2186 string_append (tname
, " ");
2187 string_appendn (tname
, *mangled
, r2
);
2190 /* Save the template argument. */
2192 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2193 memcpy (work
->tmpl_argvec
[i
], *mangled
, len
);
2194 work
->tmpl_argvec
[i
][len
] = '\0';
2208 /* otherwise, value parameter */
2210 /* temp is initialized in do_type */
2211 success
= do_type (work
, mangled
, &temp
);
2212 string_delete(&temp
);
2224 success
= demangle_template_value_parm (work
, mangled
, s
,
2225 (type_kind_t
) success
);
2237 int len
= s
->p
- s
->b
;
2238 work
->tmpl_argvec
[i
] = XNEWVEC (char, len
+ 1);
2239 memcpy (work
->tmpl_argvec
[i
], s
->b
, len
);
2240 work
->tmpl_argvec
[i
][len
] = '\0';
2242 string_appends (tname
, s
);
2250 string_append (tname
, "[]");
2254 if (tname
->p
[-1] == '>')
2255 string_append (tname
, " ");
2256 string_append (tname
, ">");
2259 if (is_type
&& remember
)
2261 const int bindex
= register_Btype (work
);
2262 remember_Btype (work
, tname
->b
, LEN_STRING (tname
), bindex
);
2266 if (work -> static_type)
2268 string_append (declp, *mangled + 1);
2269 *mangled += strlen (*mangled);
2274 success = demangle_args (work, mangled, declp);
2282 arm_pt (struct work_stuff
*work
, const char *mangled
,
2283 int n
, const char **anchor
, const char **args
)
2285 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2286 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2287 if ((ARM_DEMANGLING
|| HP_DEMANGLING
) && (*anchor
= strstr (mangled
, "__pt__")))
2290 *args
= *anchor
+ 6;
2291 len
= consume_count (args
);
2294 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2300 if (AUTO_DEMANGLING
|| EDG_DEMANGLING
)
2302 if ((*anchor
= strstr (mangled
, "__tm__"))
2303 || (*anchor
= strstr (mangled
, "__ps__"))
2304 || (*anchor
= strstr (mangled
, "__pt__")))
2307 *args
= *anchor
+ 6;
2308 len
= consume_count (args
);
2311 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2317 else if ((*anchor
= strstr (mangled
, "__S")))
2320 *args
= *anchor
+ 3;
2321 len
= consume_count (args
);
2324 if (*args
+ len
== mangled
+ n
&& **args
== '_')
2336 demangle_arm_hp_template (struct work_stuff
*work
, const char **mangled
,
2337 int n
, string
*declp
)
2341 const char *e
= *mangled
+ n
;
2344 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2346 if (HP_DEMANGLING
&& ((*mangled
)[n
] == 'X'))
2348 char *start_spec_args
= NULL
;
2351 /* First check for and omit template specialization pseudo-arguments,
2352 such as in "Spec<#1,#1.*>" */
2353 start_spec_args
= strchr (*mangled
, '<');
2354 if (start_spec_args
&& (start_spec_args
- *mangled
< n
))
2355 string_appendn (declp
, *mangled
, start_spec_args
- *mangled
);
2357 string_appendn (declp
, *mangled
, n
);
2358 (*mangled
) += n
+ 1;
2360 if (work
->temp_start
== -1) /* non-recursive call */
2361 work
->temp_start
= declp
->p
- declp
->b
;
2363 /* We want to unconditionally demangle parameter types in
2364 template parameters. */
2365 hold_options
= work
->options
;
2366 work
->options
|= DMGL_PARAMS
;
2368 string_append (declp
, "<");
2371 string_delete (&arg
);
2375 /* 'T' signals a type parameter */
2377 if (!do_type (work
, mangled
, &arg
))
2378 goto hpacc_template_args_done
;
2383 /* 'U' or 'S' signals an integral value */
2384 if (!do_hpacc_template_const_value (work
, mangled
, &arg
))
2385 goto hpacc_template_args_done
;
2389 /* 'A' signals a named constant expression (literal) */
2390 if (!do_hpacc_template_literal (work
, mangled
, &arg
))
2391 goto hpacc_template_args_done
;
2395 /* Today, 1997-09-03, we have only the above types
2396 of template parameters */
2397 /* FIXME: maybe this should fail and return null */
2398 goto hpacc_template_args_done
;
2400 string_appends (declp
, &arg
);
2401 /* Check if we're at the end of template args.
2402 0 if at end of static member of template class,
2403 _ if done with template args for a function */
2404 if ((**mangled
== '\000') || (**mangled
== '_'))
2407 string_append (declp
, ",");
2409 hpacc_template_args_done
:
2410 string_append (declp
, ">");
2411 string_delete (&arg
);
2412 if (**mangled
== '_')
2414 work
->options
= hold_options
;
2417 /* ARM template? (Also handles HP cfront extensions) */
2418 else if (arm_pt (work
, *mangled
, n
, &p
, &args
))
2424 string_appendn (declp
, *mangled
, p
- *mangled
);
2425 if (work
->temp_start
== -1) /* non-recursive call */
2426 work
->temp_start
= declp
->p
- declp
->b
;
2428 /* We want to unconditionally demangle parameter types in
2429 template parameters. */
2430 hold_options
= work
->options
;
2431 work
->options
|= DMGL_PARAMS
;
2433 string_append (declp
, "<");
2434 /* should do error checking here */
2436 string_delete (&arg
);
2438 /* Check for type or literal here */
2441 /* HP cfront extensions to ARM for template args */
2442 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2443 /* FIXME: We handle only numeric literals for HP cfront */
2445 /* A typed constant value follows */
2447 if (!do_type (work
, &args
, &type_str
))
2448 goto cfront_template_args_done
;
2449 string_append (&arg
, "(");
2450 string_appends (&arg
, &type_str
);
2451 string_delete (&type_str
);
2452 string_append (&arg
, ")");
2454 goto cfront_template_args_done
;
2456 /* Now snarf a literal value following 'L' */
2457 if (!snarf_numeric_literal (&args
, &arg
))
2458 goto cfront_template_args_done
;
2462 /* Snarf a literal following 'L' */
2464 if (!snarf_numeric_literal (&args
, &arg
))
2465 goto cfront_template_args_done
;
2468 /* Not handling other HP cfront stuff */
2470 const char* old_args
= args
;
2471 if (!do_type (work
, &args
, &arg
))
2472 goto cfront_template_args_done
;
2474 /* Fail if we didn't make any progress: prevent infinite loop. */
2475 if (args
== old_args
)
2477 work
->options
= hold_options
;
2482 string_appends (declp
, &arg
);
2483 string_append (declp
, ",");
2485 cfront_template_args_done
:
2486 string_delete (&arg
);
2488 --declp
->p
; /* remove extra comma */
2489 string_append (declp
, ">");
2490 work
->options
= hold_options
;
2492 else if (n
>10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
2493 && (*mangled
)[9] == 'N'
2494 && (*mangled
)[8] == (*mangled
)[10]
2495 && strchr (cplus_markers
, (*mangled
)[8]))
2497 /* A member of the anonymous namespace. */
2498 string_append (declp
, "{anonymous}");
2502 if (work
->temp_start
== -1) /* non-recursive call only */
2503 work
->temp_start
= 0; /* disable in recursive calls */
2504 string_appendn (declp
, *mangled
, n
);
2509 /* Extract a class name, possibly a template with arguments, from the
2510 mangled string; qualifiers, local class indicators, etc. have
2511 already been dealt with */
2514 demangle_class_name (struct work_stuff
*work
, const char **mangled
,
2520 n
= consume_count (mangled
);
2523 if ((int) strlen (*mangled
) >= n
)
2525 demangle_arm_hp_template (work
, mangled
, n
, declp
);
2536 demangle_class -- demangle a mangled class sequence
2541 demangle_class (struct work_stuff *work, const char **mangled,
2546 DECLP points to the buffer into which demangling is being done.
2548 *MANGLED points to the current token to be demangled. On input,
2549 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2550 On exit, it points to the next token after the mangled class on
2551 success, or the first unconsumed token on failure.
2553 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2554 we are demangling a constructor or destructor. In this case
2555 we prepend "class::class" or "class::~class" to DECLP.
2557 Otherwise, we prepend "class::" to the current DECLP.
2559 Reset the constructor/destructor flags once they have been
2560 "consumed". This allows demangle_class to be called later during
2561 the same demangling, to do normal class demangling.
2563 Returns 1 if demangling is successful, 0 otherwise.
2568 demangle_class (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2573 char *save_class_name_end
= 0;
2575 string_init (&class_name
);
2576 btype
= register_Btype (work
);
2577 if (demangle_class_name (work
, mangled
, &class_name
))
2579 save_class_name_end
= class_name
.p
;
2580 if ((work
->constructor
& 1) || (work
->destructor
& 1))
2582 /* adjust so we don't include template args */
2583 if (work
->temp_start
&& (work
->temp_start
!= -1))
2585 class_name
.p
= class_name
.b
+ work
->temp_start
;
2587 string_prepends (declp
, &class_name
);
2588 if (work
-> destructor
& 1)
2590 string_prepend (declp
, "~");
2591 work
-> destructor
-= 1;
2595 work
-> constructor
-= 1;
2598 class_name
.p
= save_class_name_end
;
2599 remember_Ktype (work
, class_name
.b
, LEN_STRING(&class_name
));
2600 remember_Btype (work
, class_name
.b
, LEN_STRING(&class_name
), btype
);
2601 string_prepend (declp
, SCOPE_STRING (work
));
2602 string_prepends (declp
, &class_name
);
2605 string_delete (&class_name
);
2610 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2611 the rightmost guess.
2613 Find the correct "__"-sequence where the function name ends and the
2614 signature starts, which is ambiguous with GNU mangling.
2615 Call demangle_signature here, so we can make sure we found the right
2616 one; *mangled will be consumed so caller will not make further calls to
2617 demangle_signature. */
2620 iterate_demangle_function (struct work_stuff
*work
, const char **mangled
,
2621 string
*declp
, const char *scan
)
2623 const char *mangle_init
= *mangled
;
2626 struct work_stuff work_init
;
2628 if (*(scan
+ 2) == '\0')
2631 /* Do not iterate for some demangling modes, or if there's only one
2632 "__"-sequence. This is the normal case. */
2633 if (ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
2634 || strstr (scan
+ 2, "__") == NULL
)
2635 return demangle_function_name (work
, mangled
, declp
, scan
);
2637 /* Save state so we can restart if the guess at the correct "__" was
2639 string_init (&decl_init
);
2640 string_appends (&decl_init
, declp
);
2641 memset (&work_init
, 0, sizeof work_init
);
2642 work_stuff_copy_to_from (&work_init
, work
);
2644 /* Iterate over occurrences of __, allowing names and types to have a
2645 "__" sequence in them. We must start with the first (not the last)
2646 occurrence, since "__" most often occur between independent mangled
2647 parts, hence starting at the last occurence inside a signature
2648 might get us a "successful" demangling of the signature. */
2652 if (demangle_function_name (work
, mangled
, declp
, scan
))
2654 success
= demangle_signature (work
, mangled
, declp
);
2659 /* Reset demangle state for the next round. */
2660 *mangled
= mangle_init
;
2661 string_clear (declp
);
2662 string_appends (declp
, &decl_init
);
2663 work_stuff_copy_to_from (work
, &work_init
);
2665 /* Leave this underscore-sequence. */
2668 /* Scan for the next "__" sequence. */
2669 while (*scan
&& (scan
[0] != '_' || scan
[1] != '_'))
2672 /* Move to last "__" in this sequence. */
2673 while (*scan
&& *scan
== '_')
2678 /* Delete saved state. */
2679 delete_work_stuff (&work_init
);
2680 string_delete (&decl_init
);
2689 demangle_prefix -- consume the mangled name prefix and find signature
2694 demangle_prefix (struct work_stuff *work, const char **mangled,
2699 Consume and demangle the prefix of the mangled name.
2700 While processing the function name root, arrange to call
2701 demangle_signature if the root is ambiguous.
2703 DECLP points to the string buffer into which demangled output is
2704 placed. On entry, the buffer is empty. On exit it contains
2705 the root function name, the demangled operator name, or in some
2706 special cases either nothing or the completely demangled result.
2708 MANGLED points to the current pointer into the mangled name. As each
2709 token of the mangled name is consumed, it is updated. Upon entry
2710 the current mangled name pointer points to the first character of
2711 the mangled name. Upon exit, it should point to the first character
2712 of the signature if demangling was successful, or to the first
2713 unconsumed character if demangling of the prefix was unsuccessful.
2715 Returns 1 on success, 0 otherwise.
2719 demangle_prefix (struct work_stuff
*work
, const char **mangled
,
2726 if (strlen(*mangled
) > 6
2727 && (strncmp(*mangled
, "_imp__", 6) == 0
2728 || strncmp(*mangled
, "__imp_", 6) == 0))
2730 /* it's a symbol imported from a PE dynamic library. Check for both
2731 new style prefix _imp__ and legacy __imp_ used by older versions
2734 work
->dllimported
= 1;
2736 else if (strlen(*mangled
) >= 11 && strncmp(*mangled
, "_GLOBAL_", 8) == 0)
2738 char *marker
= strchr (cplus_markers
, (*mangled
)[8]);
2739 if (marker
!= NULL
&& *marker
== (*mangled
)[10])
2741 if ((*mangled
)[9] == 'D')
2743 /* it's a GNU global destructor to be executed at program exit */
2745 work
->destructor
= 2;
2746 if (gnu_special (work
, mangled
, declp
))
2749 else if ((*mangled
)[9] == 'I')
2751 /* it's a GNU global constructor to be executed at program init */
2753 work
->constructor
= 2;
2754 if (gnu_special (work
, mangled
, declp
))
2759 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__std__", 7) == 0)
2761 /* it's a ARM global destructor to be executed at program exit */
2763 work
->destructor
= 2;
2765 else if ((ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
) && strncmp(*mangled
, "__sti__", 7) == 0)
2767 /* it's a ARM global constructor to be executed at program initial */
2769 work
->constructor
= 2;
2772 /* This block of code is a reduction in strength time optimization
2774 scan = strstr (*mangled, "__"); */
2780 scan
= strchr (scan
, '_');
2781 } while (scan
!= NULL
&& *++scan
!= '_');
2783 if (scan
!= NULL
) --scan
;
2788 /* We found a sequence of two or more '_', ensure that we start at
2789 the last pair in the sequence. */
2790 i
= strspn (scan
, "_");
2801 else if (work
-> static_type
)
2803 if (!ISDIGIT ((unsigned char)scan
[0]) && (scan
[0] != 't'))
2808 else if ((scan
== *mangled
)
2809 && (ISDIGIT ((unsigned char)scan
[2]) || (scan
[2] == 'Q')
2810 || (scan
[2] == 't') || (scan
[2] == 'K') || (scan
[2] == 'H')))
2812 /* The ARM says nothing about the mangling of local variables.
2813 But cfront mangles local variables by prepending __<nesting_level>
2814 to them. As an extension to ARM demangling we handle this case. */
2815 if ((LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
)
2816 && ISDIGIT ((unsigned char)scan
[2]))
2818 *mangled
= scan
+ 2;
2819 consume_count (mangled
);
2820 string_append (declp
, *mangled
);
2821 *mangled
+= strlen (*mangled
);
2826 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2827 names like __Q2_3foo3bar for nested type names. So don't accept
2828 this style of constructor for cfront demangling. A GNU
2829 style member-template constructor starts with 'H'. */
2830 if (!(LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
))
2831 work
-> constructor
+= 1;
2832 *mangled
= scan
+ 2;
2835 else if (ARM_DEMANGLING
&& scan
[2] == 'p' && scan
[3] == 't')
2837 /* Cfront-style parameterized type. Handled later as a signature. */
2841 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2843 else if (EDG_DEMANGLING
&& ((scan
[2] == 't' && scan
[3] == 'm')
2844 || (scan
[2] == 'p' && scan
[3] == 's')
2845 || (scan
[2] == 'p' && scan
[3] == 't')))
2847 /* EDG-style parameterized type. Handled later as a signature. */
2851 demangle_arm_hp_template (work
, mangled
, strlen (*mangled
), declp
);
2853 else if ((scan
== *mangled
) && !ISDIGIT ((unsigned char)scan
[2])
2854 && (scan
[2] != 't'))
2856 /* Mangled name starts with "__". Skip over any leading '_' characters,
2857 then find the next "__" that separates the prefix from the signature.
2859 if (!(ARM_DEMANGLING
|| LUCID_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
2860 || (arm_special (mangled
, declp
) == 0))
2862 while (*scan
== '_')
2866 if ((scan
= strstr (scan
, "__")) == NULL
|| (*(scan
+ 2) == '\0'))
2868 /* No separator (I.E. "__not_mangled"), or empty signature
2869 (I.E. "__not_mangled_either__") */
2873 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2876 else if (*(scan
+ 2) != '\0')
2878 /* Mangled name does not start with "__" but does have one somewhere
2879 in there with non empty stuff after it. Looks like a global
2880 function name. Iterate over all "__":s until the right
2882 return iterate_demangle_function (work
, mangled
, declp
, scan
);
2886 /* Doesn't look like a mangled name */
2890 if (!success
&& (work
->constructor
== 2 || work
->destructor
== 2))
2892 string_append (declp
, *mangled
);
2893 *mangled
+= strlen (*mangled
);
2903 gnu_special -- special handling of gnu mangled strings
2908 gnu_special (struct work_stuff *work, const char **mangled,
2914 Process some special GNU style mangling forms that don't fit
2915 the normal pattern. For example:
2917 _$_3foo (destructor for class foo)
2918 _vt$foo (foo virtual table)
2919 _vt$foo$bar (foo::bar virtual table)
2920 __vt_foo (foo virtual table, new style with thunks)
2921 _3foo$varname (static data member)
2922 _Q22rs2tu$vw (static data member)
2923 __t6vector1Zii (constructor with template)
2924 __thunk_4__$_7ostream (virtual function thunk)
2928 gnu_special (struct work_stuff
*work
, const char **mangled
, string
*declp
)
2934 if ((*mangled
)[0] == '_'
2935 && strchr (cplus_markers
, (*mangled
)[1]) != NULL
2936 && (*mangled
)[2] == '_')
2938 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2940 work
-> destructor
+= 1;
2942 else if ((*mangled
)[0] == '_'
2943 && (((*mangled
)[1] == '_'
2944 && (*mangled
)[2] == 'v'
2945 && (*mangled
)[3] == 't'
2946 && (*mangled
)[4] == '_')
2947 || ((*mangled
)[1] == 'v'
2948 && (*mangled
)[2] == 't'
2949 && strchr (cplus_markers
, (*mangled
)[3]) != NULL
)))
2951 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2952 and create the decl. Note that we consume the entire mangled
2953 input string, which means that demangle_signature has no work
2955 if ((*mangled
)[2] == 'v')
2956 (*mangled
) += 5; /* New style, with thunks: "__vt_" */
2958 (*mangled
) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2959 while (**mangled
!= '\0')
2965 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
2968 success
= demangle_template (work
, mangled
, declp
, 0, 1,
2972 if (ISDIGIT((unsigned char)*mangled
[0]))
2974 n
= consume_count(mangled
);
2975 /* We may be seeing a too-large size, or else a
2976 ".<digits>" indicating a static local symbol. In
2977 any case, declare victory and move on; *don't* try
2978 to use n to allocate. */
2979 if (n
> (int) strlen (*mangled
))
2987 n
= strcspn (*mangled
, cplus_markers
);
2989 string_appendn (declp
, *mangled
, n
);
2993 p
= strpbrk (*mangled
, cplus_markers
);
2994 if (success
&& ((p
== NULL
) || (p
== *mangled
)))
2998 string_append (declp
, SCOPE_STRING (work
));
3009 string_append (declp
, " virtual table");
3011 else if ((*mangled
)[0] == '_'
3012 && (strchr("0123456789Qt", (*mangled
)[1]) != NULL
)
3013 && (p
= strpbrk (*mangled
, cplus_markers
)) != NULL
)
3015 /* static data member, "_3foo$varname" for example */
3021 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3024 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3027 n
= consume_count (mangled
);
3028 if (n
< 0 || n
> (long) strlen (*mangled
))
3034 if (n
> 10 && strncmp (*mangled
, "_GLOBAL_", 8) == 0
3035 && (*mangled
)[9] == 'N'
3036 && (*mangled
)[8] == (*mangled
)[10]
3037 && strchr (cplus_markers
, (*mangled
)[8]))
3039 /* A member of the anonymous namespace. There's information
3040 about what identifier or filename it was keyed to, but
3041 it's just there to make the mangled name unique; we just
3043 string_append (declp
, "{anonymous}");
3046 /* Now p points to the marker before the N, so we need to
3047 update it to the first marker after what we consumed. */
3048 p
= strpbrk (*mangled
, cplus_markers
);
3052 string_appendn (declp
, *mangled
, n
);
3055 if (success
&& (p
== *mangled
))
3057 /* Consumed everything up to the cplus_marker, append the
3060 string_append (declp
, SCOPE_STRING (work
));
3061 n
= strlen (*mangled
);
3062 string_appendn (declp
, *mangled
, n
);
3070 else if (strncmp (*mangled
, "__thunk_", 8) == 0)
3075 delta
= consume_count (mangled
);
3080 char *method
= internal_cplus_demangle (work
, ++*mangled
);
3085 sprintf (buf
, "virtual function thunk (delta:%d) for ", -delta
);
3086 string_append (declp
, buf
);
3087 string_append (declp
, method
);
3089 n
= strlen (*mangled
);
3098 else if (strncmp (*mangled
, "__t", 3) == 0
3099 && ((*mangled
)[3] == 'i' || (*mangled
)[3] == 'f'))
3101 p
= (*mangled
)[3] == 'i' ? " type_info node" : " type_info function";
3107 success
= demangle_qualified (work
, mangled
, declp
, 0, 1);
3110 success
= demangle_template (work
, mangled
, declp
, 0, 1, 1);
3113 success
= do_type (work
, mangled
, declp
);
3116 if (success
&& **mangled
!= '\0')
3119 string_append (declp
, p
);
3129 recursively_demangle(struct work_stuff
*work
, const char **mangled
,
3130 string
*result
, int namelength
)
3132 char * recurse
= (char *)NULL
;
3133 char * recurse_dem
= (char *)NULL
;
3135 recurse
= XNEWVEC (char, namelength
+ 1);
3136 memcpy (recurse
, *mangled
, namelength
);
3137 recurse
[namelength
] = '\000';
3139 recurse_dem
= cplus_demangle (recurse
, work
->options
);
3143 string_append (result
, recurse_dem
);
3148 string_appendn (result
, *mangled
, namelength
);
3151 *mangled
+= namelength
;
3158 arm_special -- special handling of ARM/lucid mangled strings
3163 arm_special (const char **mangled,
3169 Process some special ARM style mangling forms that don't fit
3170 the normal pattern. For example:
3172 __vtbl__3foo (foo virtual table)
3173 __vtbl__3foo__3bar (bar::foo virtual table)
3178 arm_special (const char **mangled
, string
*declp
)
3184 if (strncmp (*mangled
, ARM_VTABLE_STRING
, ARM_VTABLE_STRLEN
) == 0)
3186 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3187 and create the decl. Note that we consume the entire mangled
3188 input string, which means that demangle_signature has no work
3190 scan
= *mangled
+ ARM_VTABLE_STRLEN
;
3191 while (*scan
!= '\0') /* first check it can be demangled */
3193 n
= consume_count (&scan
);
3196 return (0); /* no good */
3199 if (scan
[0] == '_' && scan
[1] == '_')
3204 (*mangled
) += ARM_VTABLE_STRLEN
;
3205 while (**mangled
!= '\0')
3207 n
= consume_count (mangled
);
3209 || n
> (long) strlen (*mangled
))
3211 string_prependn (declp
, *mangled
, n
);
3213 if ((*mangled
)[0] == '_' && (*mangled
)[1] == '_')
3215 string_prepend (declp
, "::");
3219 string_append (declp
, " virtual table");
3232 demangle_qualified -- demangle 'Q' qualified name strings
3237 demangle_qualified (struct work_stuff *, const char *mangled,
3238 string *result, int isfuncname, int append);
3242 Demangle a qualified name, such as "Q25Outer5Inner" which is
3243 the mangled form of "Outer::Inner". The demangled output is
3244 prepended or appended to the result string according to the
3245 state of the append flag.
3247 If isfuncname is nonzero, then the qualified name we are building
3248 is going to be used as a member function name, so if it is a
3249 constructor or destructor function, append an appropriate
3250 constructor or destructor name. I.E. for the above example,
3251 the result for use as a constructor is "Outer::Inner::Inner"
3252 and the result for use as a destructor is "Outer::Inner::~Inner".
3256 Numeric conversion is ASCII dependent (FIXME).
3261 demangle_qualified (struct work_stuff
*work
, const char **mangled
,
3262 string
*result
, int isfuncname
, int append
)
3269 int bindex
= register_Btype (work
);
3271 /* We only make use of ISFUNCNAME if the entity is a constructor or
3273 isfuncname
= (isfuncname
3274 && ((work
->constructor
& 1) || (work
->destructor
& 1)));
3276 string_init (&temp
);
3277 string_init (&last_name
);
3279 if ((*mangled
)[0] == 'K')
3281 /* Squangling qualified name reuse */
3284 idx
= consume_count_with_underscores (mangled
);
3285 if (idx
== -1 || idx
>= work
-> numk
)
3288 string_append (&temp
, work
-> ktypevec
[idx
]);
3291 switch ((*mangled
)[1])
3294 /* GNU mangled name with more than 9 classes. The count is preceded
3295 by an underscore (to distinguish it from the <= 9 case) and followed
3296 by an underscore. */
3298 qualifiers
= consume_count_with_underscores (mangled
);
3299 if (qualifiers
== -1)
3312 /* The count is in a single digit. */
3313 num
[0] = (*mangled
)[1];
3315 qualifiers
= atoi (num
);
3317 /* If there is an underscore after the digit, skip it. This is
3318 said to be for ARM-qualified names, but the ARM makes no
3319 mention of such an underscore. Perhaps cfront uses one. */
3320 if ((*mangled
)[2] == '_')
3335 /* Pick off the names and collect them in the temp buffer in the order
3336 in which they are found, separated by '::'. */
3338 while (qualifiers
-- > 0)
3341 string_clear (&last_name
);
3343 if (*mangled
[0] == '_')
3346 if (*mangled
[0] == 't')
3348 /* Here we always append to TEMP since we will want to use
3349 the template name without the template parameters as a
3350 constructor or destructor name. The appropriate
3351 (parameter-less) value is returned by demangle_template
3352 in LAST_NAME. We do not remember the template type here,
3353 in order to match the G++ mangling algorithm. */
3354 success
= demangle_template(work
, mangled
, &temp
,
3359 else if (*mangled
[0] == 'K')
3363 idx
= consume_count_with_underscores (mangled
);
3364 if (idx
== -1 || idx
>= work
->numk
)
3367 string_append (&temp
, work
->ktypevec
[idx
]);
3370 if (!success
) break;
3377 /* Now recursively demangle the qualifier
3378 * This is necessary to deal with templates in
3379 * mangling styles like EDG */
3380 namelength
= consume_count (mangled
);
3381 if (namelength
== -1)
3386 recursively_demangle(work
, mangled
, &temp
, namelength
);
3390 string_delete (&last_name
);
3391 success
= do_type (work
, mangled
, &last_name
);
3394 string_appends (&temp
, &last_name
);
3399 remember_Ktype (work
, temp
.b
, LEN_STRING (&temp
));
3402 string_append (&temp
, SCOPE_STRING (work
));
3405 remember_Btype (work
, temp
.b
, LEN_STRING (&temp
), bindex
);
3407 /* If we are using the result as a function name, we need to append
3408 the appropriate '::' separated constructor or destructor name.
3409 We do this here because this is the most convenient place, where
3410 we already have a pointer to the name and the length of the name. */
3414 string_append (&temp
, SCOPE_STRING (work
));
3415 if (work
-> destructor
& 1)
3416 string_append (&temp
, "~");
3417 string_appends (&temp
, &last_name
);
3420 /* Now either prepend the temp buffer to the result, or append it,
3421 depending upon the state of the append flag. */
3424 string_appends (result
, &temp
);
3427 if (!STRING_EMPTY (result
))
3428 string_append (&temp
, SCOPE_STRING (work
));
3429 string_prepends (result
, &temp
);
3432 string_delete (&last_name
);
3433 string_delete (&temp
);
3441 get_count -- convert an ascii count to integer, consuming tokens
3446 get_count (const char **type, int *count)
3450 Assume that *type points at a count in a mangled name; set
3451 *count to its value, and set *type to the next character after
3452 the count. There are some weird rules in effect here.
3454 If *type does not point at a string of digits, return zero.
3456 If *type points at a string of digits followed by an
3457 underscore, set *count to their value as an integer, advance
3458 *type to point *after the underscore, and return 1.
3460 If *type points at a string of digits not followed by an
3461 underscore, consume only the first digit. Set *count to its
3462 value as an integer, leave *type pointing after that digit,
3465 The excuse for this odd behavior: in the ARM and HP demangling
3466 styles, a type can be followed by a repeat count of the form
3469 `x' is a single digit specifying how many additional copies
3470 of the type to append to the argument list, and
3472 `y' is one or more digits, specifying the zero-based index of
3473 the first repeated argument in the list. Yes, as you're
3474 unmangling the name you can figure this out yourself, but
3477 So, for example, in `bar__3fooFPiN51', the first argument is a
3478 pointer to an integer (`Pi'), and then the next five arguments
3479 are the same (`N5'), and the first repeat is the function's
3480 second argument (`1').
3484 get_count (const char **type
, int *count
)
3489 if (!ISDIGIT ((unsigned char)**type
))
3493 *count
= **type
- '0';
3495 if (ISDIGIT ((unsigned char)**type
))
3505 while (ISDIGIT ((unsigned char)*p
));
3516 /* RESULT will be initialised here; it will be freed on failure. The
3517 value returned is really a type_kind_t. */
3520 do_type (struct work_stuff
*work
, const char **mangled
, string
*result
)
3526 const char *remembered_type
;
3528 type_kind_t tk
= tk_none
;
3530 string_init (&decl
);
3531 string_init (result
);
3535 while (success
&& !done
)
3541 /* A pointer type */
3545 if (! (work
-> options
& DMGL_JAVA
))
3546 string_prepend (&decl
, "*");
3551 /* A reference type */
3554 string_prepend (&decl
, "&");
3563 if (!STRING_EMPTY (&decl
)
3564 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3566 string_prepend (&decl
, "(");
3567 string_append (&decl
, ")");
3569 string_append (&decl
, "[");
3570 if (**mangled
!= '_')
3571 success
= demangle_template_value_parm (work
, mangled
, &decl
,
3573 if (**mangled
== '_')
3575 string_append (&decl
, "]");
3579 /* A back reference to a previously seen type */
3582 if (!get_count (mangled
, &n
) || n
>= work
-> ntypes
)
3588 remembered_type
= work
-> typevec
[n
];
3589 mangled
= &remembered_type
;
3596 if (!STRING_EMPTY (&decl
)
3597 && (decl
.b
[0] == '*' || decl
.b
[0] == '&'))
3599 string_prepend (&decl
, "(");
3600 string_append (&decl
, ")");
3602 /* After picking off the function args, we expect to either find the
3603 function return type (preceded by an '_') or the end of the
3605 if (!demangle_nested_args (work
, mangled
, &decl
)
3606 || (**mangled
!= '_' && **mangled
!= '\0'))
3611 if (success
&& (**mangled
== '_'))
3618 type_quals
= TYPE_UNQUALIFIED
;
3620 member
= **mangled
== 'M';
3623 string_append (&decl
, ")");
3625 /* We don't need to prepend `::' for a qualified name;
3626 demangle_qualified will do that for us. */
3627 if (**mangled
!= 'Q')
3628 string_prepend (&decl
, SCOPE_STRING (work
));
3630 if (ISDIGIT ((unsigned char)**mangled
))
3632 n
= consume_count (mangled
);
3634 || (int) strlen (*mangled
) < n
)
3639 string_prependn (&decl
, *mangled
, n
);
3642 else if (**mangled
== 'X' || **mangled
== 'Y')
3645 do_type (work
, mangled
, &temp
);
3646 string_prepends (&decl
, &temp
);
3647 string_delete (&temp
);
3649 else if (**mangled
== 't')
3652 string_init (&temp
);
3653 success
= demangle_template (work
, mangled
, &temp
,
3657 string_prependn (&decl
, temp
.b
, temp
.p
- temp
.b
);
3658 string_delete (&temp
);
3663 else if (**mangled
== 'Q')
3665 success
= demangle_qualified (work
, mangled
, &decl
,
3677 string_prepend (&decl
, "(");
3685 type_quals
|= code_for_qualifier (**mangled
);
3693 if (*(*mangled
)++ != 'F')
3699 if ((member
&& !demangle_nested_args (work
, mangled
, &decl
))
3700 || **mangled
!= '_')
3706 if (! PRINT_ANSI_QUALIFIERS
)
3710 if (type_quals
!= TYPE_UNQUALIFIED
)
3712 APPEND_BLANK (&decl
);
3713 string_append (&decl
, qualifier_string (type_quals
));
3724 if (PRINT_ANSI_QUALIFIERS
)
3726 if (!STRING_EMPTY (&decl
))
3727 string_prepend (&decl
, " ");
3729 string_prepend (&decl
, demangle_qualifier (**mangled
));
3744 if (success
) switch (**mangled
)
3746 /* A qualified name, such as "Outer::Inner". */
3750 success
= demangle_qualified (work
, mangled
, result
, 0, 1);
3754 /* A back reference to a previously seen squangled type */
3757 if (!get_count (mangled
, &n
) || n
>= work
-> numb
)
3760 string_append (result
, work
->btypevec
[n
]);
3765 /* A template parm. We substitute the corresponding argument. */
3770 idx
= consume_count_with_underscores (mangled
);
3773 || (work
->tmpl_argvec
&& idx
>= work
->ntmpl_args
)
3774 || consume_count_with_underscores (mangled
) == -1)
3780 if (work
->tmpl_argvec
)
3781 string_append (result
, work
->tmpl_argvec
[idx
]);
3783 string_append_template_idx (result
, idx
);
3790 success
= demangle_fund_type (work
, mangled
, result
);
3792 tk
= (type_kind_t
) success
;
3798 if (!STRING_EMPTY (&decl
))
3800 string_append (result
, " ");
3801 string_appends (result
, &decl
);
3805 string_delete (result
);
3806 string_delete (&decl
);
3809 /* Assume an integral type, if we're not sure. */
3810 return (int) ((tk
== tk_none
) ? tk_integral
: tk
);
3815 /* Given a pointer to a type string that represents a fundamental type
3816 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3817 string in which the demangled output is being built in RESULT, and
3818 the WORK structure, decode the types and add them to the result.
3823 "Sl" => "signed long"
3824 "CUs" => "const unsigned short"
3826 The value returned is really a type_kind_t. */
3829 demangle_fund_type (struct work_stuff
*work
,
3830 const char **mangled
, string
*result
)
3834 char buf
[INTBUF_SIZE
+ 5 /* 'int%u_t' */];
3835 unsigned int dec
= 0;
3836 type_kind_t tk
= tk_integral
;
3838 /* First pick off any type qualifiers. There can be more than one. */
3847 if (PRINT_ANSI_QUALIFIERS
)
3849 if (!STRING_EMPTY (result
))
3850 string_prepend (result
, " ");
3851 string_prepend (result
, demangle_qualifier (**mangled
));
3857 APPEND_BLANK (result
);
3858 string_append (result
, "unsigned");
3860 case 'S': /* signed char only */
3862 APPEND_BLANK (result
);
3863 string_append (result
, "signed");
3867 APPEND_BLANK (result
);
3868 string_append (result
, "__complex");
3876 /* Now pick off the fundamental type. There can be only one. */
3885 APPEND_BLANK (result
);
3886 string_append (result
, "void");
3890 APPEND_BLANK (result
);
3891 string_append (result
, "long long");
3895 APPEND_BLANK (result
);
3896 string_append (result
, "long");
3900 APPEND_BLANK (result
);
3901 string_append (result
, "int");
3905 APPEND_BLANK (result
);
3906 string_append (result
, "short");
3910 APPEND_BLANK (result
);
3911 string_append (result
, "bool");
3916 APPEND_BLANK (result
);
3917 string_append (result
, "char");
3922 APPEND_BLANK (result
);
3923 string_append (result
, "wchar_t");
3928 APPEND_BLANK (result
);
3929 string_append (result
, "long double");
3934 APPEND_BLANK (result
);
3935 string_append (result
, "double");
3940 APPEND_BLANK (result
);
3941 string_append (result
, "float");
3946 if (!ISDIGIT ((unsigned char)**mangled
))
3953 if (**mangled
== '_')
3958 i
< (long) sizeof (buf
) - 1 && **mangled
&& **mangled
!= '_';
3961 if (**mangled
!= '_')
3971 strncpy (buf
, *mangled
, 2);
3973 *mangled
+= min (strlen (*mangled
), 2);
3975 sscanf (buf
, "%x", &dec
);
3976 sprintf (buf
, "int%u_t", dec
);
3977 APPEND_BLANK (result
);
3978 string_append (result
, buf
);
3982 /* An explicit type, such as "6mytype" or "7integer" */
3994 int bindex
= register_Btype (work
);
3996 string_init (&btype
);
3997 if (demangle_class_name (work
, mangled
, &btype
)) {
3998 remember_Btype (work
, btype
.b
, LEN_STRING (&btype
), bindex
);
3999 APPEND_BLANK (result
);
4000 string_appends (result
, &btype
);
4004 string_delete (&btype
);
4010 string_init (&btype
);
4011 success
= demangle_template (work
, mangled
, &btype
, 0, 1, 1);
4012 string_appends (result
, &btype
);
4013 string_delete (&btype
);
4021 return success
? ((int) tk
) : 0;
4025 /* Handle a template's value parameter for HP aCC (extension from ARM)
4026 **mangled points to 'S' or 'U' */
4029 do_hpacc_template_const_value (struct work_stuff
*work ATTRIBUTE_UNUSED
,
4030 const char **mangled
, string
*result
)
4034 if (**mangled
!= 'U' && **mangled
!= 'S')
4037 unsigned_const
= (**mangled
== 'U');
4044 string_append (result
, "-");
4050 /* special case for -2^31 */
4051 string_append (result
, "-2147483648");
4058 /* We have to be looking at an integer now */
4059 if (!(ISDIGIT ((unsigned char)**mangled
)))
4062 /* We only deal with integral values for template
4063 parameters -- so it's OK to look only for digits */
4064 while (ISDIGIT ((unsigned char)**mangled
))
4066 char_str
[0] = **mangled
;
4067 string_append (result
, char_str
);
4072 string_append (result
, "U");
4074 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4075 with L or LL suffixes. pai/1997-09-03 */
4077 return 1; /* success */
4080 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4081 **mangled is pointing to the 'A' */
4084 do_hpacc_template_literal (struct work_stuff
*work
, const char **mangled
,
4087 int literal_len
= 0;
4091 if (**mangled
!= 'A')
4096 literal_len
= consume_count (mangled
);
4098 if (literal_len
<= 0)
4101 /* Literal parameters are names of arrays, functions, etc. and the
4102 canonical representation uses the address operator */
4103 string_append (result
, "&");
4105 /* Now recursively demangle the literal name */
4106 recurse
= XNEWVEC (char, literal_len
+ 1);
4107 memcpy (recurse
, *mangled
, literal_len
);
4108 recurse
[literal_len
] = '\000';
4110 recurse_dem
= cplus_demangle (recurse
, work
->options
);
4114 string_append (result
, recurse_dem
);
4119 string_appendn (result
, *mangled
, literal_len
);
4121 (*mangled
) += literal_len
;
4128 snarf_numeric_literal (const char **args
, string
*arg
)
4133 string_append (arg
, char_str
);
4136 else if (**args
== '+')
4139 if (!ISDIGIT ((unsigned char)**args
))
4142 while (ISDIGIT ((unsigned char)**args
))
4144 char_str
[0] = **args
;
4145 string_append (arg
, char_str
);
4152 /* Demangle the next argument, given by MANGLED into RESULT, which
4153 *should be an uninitialized* string. It will be initialized here,
4154 and free'd should anything go wrong. */
4157 do_arg (struct work_stuff
*work
, const char **mangled
, string
*result
)
4159 /* Remember where we started so that we can record the type, for
4160 non-squangling type remembering. */
4161 const char *start
= *mangled
;
4163 string_init (result
);
4165 if (work
->nrepeats
> 0)
4169 if (work
->previous_argument
== 0)
4172 /* We want to reissue the previous type in this argument list. */
4173 string_appends (result
, work
->previous_argument
);
4177 if (**mangled
== 'n')
4179 /* A squangling-style repeat. */
4181 work
->nrepeats
= consume_count(mangled
);
4183 if (work
->nrepeats
<= 0)
4184 /* This was not a repeat count after all. */
4187 if (work
->nrepeats
> 9)
4189 if (**mangled
!= '_')
4190 /* The repeat count should be followed by an '_' in this
4197 /* Now, the repeat is all set up. */
4198 return do_arg (work
, mangled
, result
);
4201 /* Save the result in WORK->previous_argument so that we can find it
4202 if it's repeated. Note that saving START is not good enough: we
4203 do not want to add additional types to the back-referenceable
4204 type vector when processing a repeated type. */
4205 if (work
->previous_argument
)
4206 string_delete (work
->previous_argument
);
4208 work
->previous_argument
= XNEW (string
);
4210 if (!do_type (work
, mangled
, work
->previous_argument
))
4213 string_appends (result
, work
->previous_argument
);
4215 remember_type (work
, start
, *mangled
- start
);
4220 remember_type (struct work_stuff
*work
, const char *start
, int len
)
4224 if (work
->forgetting_types
)
4227 if (work
-> ntypes
>= work
-> typevec_size
)
4229 if (work
-> typevec_size
== 0)
4231 work
-> typevec_size
= 3;
4232 work
-> typevec
= XNEWVEC (char *, work
->typevec_size
);
4236 work
-> typevec_size
*= 2;
4238 = XRESIZEVEC (char *, work
->typevec
, work
->typevec_size
);
4241 tem
= XNEWVEC (char, len
+ 1);
4242 memcpy (tem
, start
, len
);
4244 work
-> typevec
[work
-> ntypes
++] = tem
;
4248 /* Remember a K type class qualifier. */
4250 remember_Ktype (struct work_stuff
*work
, const char *start
, int len
)
4254 if (work
-> numk
>= work
-> ksize
)
4256 if (work
-> ksize
== 0)
4259 work
-> ktypevec
= XNEWVEC (char *, work
->ksize
);
4265 = XRESIZEVEC (char *, work
->ktypevec
, work
->ksize
);
4268 tem
= XNEWVEC (char, len
+ 1);
4269 memcpy (tem
, start
, len
);
4271 work
-> ktypevec
[work
-> numk
++] = tem
;
4274 /* Register a B code, and get an index for it. B codes are registered
4275 as they are seen, rather than as they are completed, so map<temp<char> >
4276 registers map<temp<char> > as B0, and temp<char> as B1 */
4279 register_Btype (struct work_stuff
*work
)
4283 if (work
-> numb
>= work
-> bsize
)
4285 if (work
-> bsize
== 0)
4288 work
-> btypevec
= XNEWVEC (char *, work
->bsize
);
4294 = XRESIZEVEC (char *, work
->btypevec
, work
->bsize
);
4297 ret
= work
-> numb
++;
4298 work
-> btypevec
[ret
] = NULL
;
4302 /* Store a value into a previously registered B code type. */
4305 remember_Btype (struct work_stuff
*work
, const char *start
,
4310 tem
= XNEWVEC (char, len
+ 1);
4311 memcpy (tem
, start
, len
);
4313 work
-> btypevec
[index
] = tem
;
4316 /* Lose all the info related to B and K type codes. */
4318 forget_B_and_K_types (struct work_stuff
*work
)
4322 while (work
-> numk
> 0)
4324 i
= --(work
-> numk
);
4325 if (work
-> ktypevec
[i
] != NULL
)
4327 free (work
-> ktypevec
[i
]);
4328 work
-> ktypevec
[i
] = NULL
;
4332 while (work
-> numb
> 0)
4334 i
= --(work
-> numb
);
4335 if (work
-> btypevec
[i
] != NULL
)
4337 free (work
-> btypevec
[i
]);
4338 work
-> btypevec
[i
] = NULL
;
4342 /* Forget the remembered types, but not the type vector itself. */
4345 forget_types (struct work_stuff
*work
)
4349 while (work
-> ntypes
> 0)
4351 i
= --(work
-> ntypes
);
4352 if (work
-> typevec
[i
] != NULL
)
4354 free (work
-> typevec
[i
]);
4355 work
-> typevec
[i
] = NULL
;
4360 /* Process the argument list part of the signature, after any class spec
4361 has been consumed, as well as the first 'F' character (if any). For
4364 "__als__3fooRT0" => process "RT0"
4365 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4367 DECLP must be already initialised, usually non-empty. It won't be freed
4370 Note that g++ differs significantly from ARM and lucid style mangling
4371 with regards to references to previously seen types. For example, given
4372 the source fragment:
4376 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4379 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4380 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4382 g++ produces the names:
4387 while lcc (and presumably other ARM style compilers as well) produces:
4389 foo__FiR3fooT1T2T1T2
4390 __ct__3fooFiR3fooT1T2T1T2
4392 Note that g++ bases its type numbers starting at zero and counts all
4393 previously seen types, while lucid/ARM bases its type numbers starting
4394 at one and only considers types after it has seen the 'F' character
4395 indicating the start of the function args. For lucid/ARM style, we
4396 account for this difference by discarding any previously seen types when
4397 we see the 'F' character, and subtracting one from the type number
4403 demangle_args (struct work_stuff
*work
, const char **mangled
,
4413 if (PRINT_ARG_TYPES
)
4415 string_append (declp
, "(");
4416 if (**mangled
== '\0')
4418 string_append (declp
, "void");
4422 while ((**mangled
!= '_' && **mangled
!= '\0' && **mangled
!= 'e')
4423 || work
->nrepeats
> 0)
4425 if ((**mangled
== 'N') || (**mangled
== 'T'))
4427 temptype
= *(*mangled
)++;
4429 if (temptype
== 'N')
4431 if (!get_count (mangled
, &r
))
4440 if ((HP_DEMANGLING
|| ARM_DEMANGLING
|| EDG_DEMANGLING
) && work
-> ntypes
>= 10)
4442 /* If we have 10 or more types we might have more than a 1 digit
4443 index so we'll have to consume the whole count here. This
4444 will lose if the next thing is a type name preceded by a
4445 count but it's impossible to demangle that case properly
4446 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4447 Pc, ...)" or "(..., type12, char *, ...)" */
4448 if ((t
= consume_count(mangled
)) <= 0)
4455 if (!get_count (mangled
, &t
))
4460 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4464 /* Validate the type index. Protect against illegal indices from
4465 malformed type strings. */
4466 if ((t
< 0) || (t
>= work
-> ntypes
))
4470 while (work
->nrepeats
> 0 || --r
>= 0)
4472 tem
= work
-> typevec
[t
];
4473 if (need_comma
&& PRINT_ARG_TYPES
)
4475 string_append (declp
, ", ");
4477 if (!do_arg (work
, &tem
, &arg
))
4481 if (PRINT_ARG_TYPES
)
4483 string_appends (declp
, &arg
);
4485 string_delete (&arg
);
4491 if (need_comma
&& PRINT_ARG_TYPES
)
4492 string_append (declp
, ", ");
4493 if (!do_arg (work
, mangled
, &arg
))
4495 if (PRINT_ARG_TYPES
)
4496 string_appends (declp
, &arg
);
4497 string_delete (&arg
);
4502 if (**mangled
== 'e')
4505 if (PRINT_ARG_TYPES
)
4509 string_append (declp
, ",");
4511 string_append (declp
, "...");
4515 if (PRINT_ARG_TYPES
)
4517 string_append (declp
, ")");
4522 /* Like demangle_args, but for demangling the argument lists of function
4523 and method pointers or references, not top-level declarations. */
4526 demangle_nested_args (struct work_stuff
*work
, const char **mangled
,
4529 string
* saved_previous_argument
;
4533 /* The G++ name-mangling algorithm does not remember types on nested
4534 argument lists, unless -fsquangling is used, and in that case the
4535 type vector updated by remember_type is not used. So, we turn
4536 off remembering of types here. */
4537 ++work
->forgetting_types
;
4539 /* For the repeat codes used with -fsquangling, we must keep track of
4540 the last argument. */
4541 saved_previous_argument
= work
->previous_argument
;
4542 saved_nrepeats
= work
->nrepeats
;
4543 work
->previous_argument
= 0;
4546 /* Actually demangle the arguments. */
4547 result
= demangle_args (work
, mangled
, declp
);
4549 /* Restore the previous_argument field. */
4550 if (work
->previous_argument
)
4552 string_delete (work
->previous_argument
);
4553 free ((char *) work
->previous_argument
);
4555 work
->previous_argument
= saved_previous_argument
;
4556 --work
->forgetting_types
;
4557 work
->nrepeats
= saved_nrepeats
;
4562 /* Returns 1 if a valid function name was found or 0 otherwise. */
4565 demangle_function_name (struct work_stuff
*work
, const char **mangled
,
4566 string
*declp
, const char *scan
)
4572 string_appendn (declp
, (*mangled
), scan
- (*mangled
));
4573 string_need (declp
, 1);
4574 *(declp
-> p
) = '\0';
4576 /* Consume the function name, including the "__" separating the name
4577 from the signature. We are guaranteed that SCAN points to the
4580 (*mangled
) = scan
+ 2;
4581 /* We may be looking at an instantiation of a template function:
4582 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4583 following _F marks the start of the function arguments. Handle
4584 the template arguments first. */
4586 if (HP_DEMANGLING
&& (**mangled
== 'X'))
4588 demangle_arm_hp_template (work
, mangled
, 0, declp
);
4589 /* This leaves MANGLED pointing to the 'F' marking func args */
4592 if (LUCID_DEMANGLING
|| ARM_DEMANGLING
|| HP_DEMANGLING
|| EDG_DEMANGLING
)
4595 /* See if we have an ARM style constructor or destructor operator.
4596 If so, then just record it, clear the decl, and return.
4597 We can't build the actual constructor/destructor decl until later,
4598 when we recover the class name from the signature. */
4600 if (strcmp (declp
-> b
, "__ct") == 0)
4602 work
-> constructor
+= 1;
4603 string_clear (declp
);
4606 else if (strcmp (declp
-> b
, "__dt") == 0)
4608 work
-> destructor
+= 1;
4609 string_clear (declp
);
4614 if (declp
->p
- declp
->b
>= 3
4615 && declp
->b
[0] == 'o'
4616 && declp
->b
[1] == 'p'
4617 && strchr (cplus_markers
, declp
->b
[2]) != NULL
)
4619 /* see if it's an assignment expression */
4620 if (declp
->p
- declp
->b
>= 10 /* op$assign_ */
4621 && memcmp (declp
->b
+ 3, "assign_", 7) == 0)
4623 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4625 int len
= declp
->p
- declp
->b
- 10;
4626 if ((int) strlen (optable
[i
].in
) == len
4627 && memcmp (optable
[i
].in
, declp
->b
+ 10, len
) == 0)
4629 string_clear (declp
);
4630 string_append (declp
, "operator");
4631 string_append (declp
, optable
[i
].out
);
4632 string_append (declp
, "=");
4639 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4641 int len
= declp
->p
- declp
->b
- 3;
4642 if ((int) strlen (optable
[i
].in
) == len
4643 && memcmp (optable
[i
].in
, declp
->b
+ 3, len
) == 0)
4645 string_clear (declp
);
4646 string_append (declp
, "operator");
4647 string_append (declp
, optable
[i
].out
);
4653 else if (declp
->p
- declp
->b
>= 5 && memcmp (declp
->b
, "type", 4) == 0
4654 && strchr (cplus_markers
, declp
->b
[4]) != NULL
)
4656 /* type conversion operator */
4658 if (do_type (work
, &tem
, &type
))
4660 string_clear (declp
);
4661 string_append (declp
, "operator ");
4662 string_appends (declp
, &type
);
4663 string_delete (&type
);
4666 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4667 && declp
->b
[2] == 'o' && declp
->b
[3] == 'p')
4670 /* type conversion operator. */
4672 if (do_type (work
, &tem
, &type
))
4674 string_clear (declp
);
4675 string_append (declp
, "operator ");
4676 string_appends (declp
, &type
);
4677 string_delete (&type
);
4680 else if (declp
->b
[0] == '_' && declp
->b
[1] == '_'
4681 && ISLOWER((unsigned char)declp
->b
[2])
4682 && ISLOWER((unsigned char)declp
->b
[3]))
4684 if (declp
->b
[4] == '\0')
4687 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4689 if (strlen (optable
[i
].in
) == 2
4690 && memcmp (optable
[i
].in
, declp
->b
+ 2, 2) == 0)
4692 string_clear (declp
);
4693 string_append (declp
, "operator");
4694 string_append (declp
, optable
[i
].out
);
4701 if (declp
->b
[2] == 'a' && declp
->b
[5] == '\0')
4704 for (i
= 0; i
< ARRAY_SIZE (optable
); i
++)
4706 if (strlen (optable
[i
].in
) == 3
4707 && memcmp (optable
[i
].in
, declp
->b
+ 2, 3) == 0)
4709 string_clear (declp
);
4710 string_append (declp
, "operator");
4711 string_append (declp
, optable
[i
].out
);
4719 /* If a function name was obtained but it's not valid, we were not
4721 if (LEN_STRING (declp
) == 1 && declp
->b
[0] == '.')
4727 /* a mini string-handling package */
4730 string_need (string
*s
, int n
)
4740 s
->p
= s
->b
= XNEWVEC (char, n
);
4743 else if (s
->e
- s
->p
< n
)
4748 s
->b
= XRESIZEVEC (char, s
->b
, n
);
4755 string_delete (string
*s
)
4760 s
->b
= s
->e
= s
->p
= NULL
;
4765 string_init (string
*s
)
4767 s
->b
= s
->p
= s
->e
= NULL
;
4771 string_clear (string
*s
)
4779 string_empty (string
*s
)
4781 return (s
->b
== s
->p
);
4787 string_append (string
*p
, const char *s
)
4790 if (s
== NULL
|| *s
== '\0')
4794 memcpy (p
->p
, s
, n
);
4799 string_appends (string
*p
, string
*s
)
4807 memcpy (p
->p
, s
->b
, n
);
4813 string_appendn (string
*p
, const char *s
, int n
)
4818 memcpy (p
->p
, s
, n
);
4824 string_prepend (string
*p
, const char *s
)
4826 if (s
!= NULL
&& *s
!= '\0')
4828 string_prependn (p
, s
, strlen (s
));
4833 string_prepends (string
*p
, string
*s
)
4837 string_prependn (p
, s
->b
, s
->p
- s
->b
);
4842 string_prependn (string
*p
, const char *s
, int n
)
4849 for (q
= p
->p
- 1; q
>= p
->b
; q
--)
4853 memcpy (p
->b
, s
, n
);
4859 string_append_template_idx (string
*s
, int idx
)
4861 char buf
[INTBUF_SIZE
+ 1 /* 'T' */];
4862 sprintf(buf
, "T%d", idx
);
4863 string_append (s
, buf
);